I want to fill the map with hard coded coordinates to display the pin markers with custom map using Xamarin.Forms.Maps
My HardcodeLocations class is:
public class HardcodedLocations
{
public static List<Position> Positions = new List<Position>
{
new Position(41.19197, 25.33719 ),
new Position(41.26352, 25.1471 ),
new Position(41.26365, 25.24215 ),
new Position(41.26369, 25.33719 ),
new Position(41.26365, 25.43224 ),
};
}
In the constructor class I trying to load the markers like that:
public AboutPage()
{
InitializeComponent();
for (int i = 0; i < HardcodedLocations.Positions.Count; i++)
{
CustomPin pin = new CustomPin
{
Type = PinType.Place,
Position = HardcodedLocations.Positions[i],
Label = "Xamarin San Francisco Office",
Address = "394 Pacific Ave, San Francisco CA",
Name = "Xamarin",
Url = "http://xamarin.com/about/"
};
customMap.CustomPins = new List<CustomPin> { pin };
customMap.Pins.Add(pin);
customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(42.8742, 25.3187), Distance.FromMiles(1.0)));
}
}
but I receive error here in CustomMapRender class in iOS project:
var customPin = GetCustomPin(annotation as MKPointAnnotation);
if (customPin == null)
{
throw new Exception("Custom pin not found");
}
This is all code in the GetViewForAnnotation method in the same class:
protected override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
{
MKAnnotationView annotationView = null;
if (annotation is MKUserLocation)
return null;
var customPin = GetCustomPin(annotation as MKPointAnnotation);
if (customPin == null)
{
throw new Exception("Custom pin not found");
}
annotationView = mapView.DequeueReusableAnnotation(customPin.Name);
if (annotationView == null)
{
annotationView = new CustomMKAnnotationView(annotation, customPin.Name);
annotationView.Image = UIImage.FromFile("pin.png");
annotationView.CalloutOffset = new CGPoint(0, 0);
annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile("monkey.png"));
annotationView.RightCalloutAccessoryView = UIButton.FromType(UIButtonType.DetailDisclosure);
((CustomMKAnnotationView)annotationView).Name = customPin.Name;
((CustomMKAnnotationView)annotationView).Url = customPin.Url;
}
annotationView.CanShowCallout = true;
return annotationView;
}
I don't know how to fix this error because when I use basic xamarin.forms.maps (without customizing) I just fill the map like that:
for (int i = 0; i < HardcodedLocations.Positions.Count; i++)
{
Pin pin = new Pin
{
//Label = $"{i + 1}",
Label = $"{i + 1}",
Address = "Кликни тук за да видиш прогнозата.",
Type = PinType.Place,
Position = HardcodedLocations.Positions[i]
};
map.Pins.Add(pin);
}
This is the method of GetCustomPin
:
CustomPin GetCustomPin(MKPointAnnotation annotation)
{
var position = new Position(annotation.Coordinate.Latitude, annotation.Coordinate.Longitude);
foreach (var pin in customPins)
{
if (pin.Position == position)
{
return pin;
}
}
return null;
}
This is the CustomPin
code:
public class CustomPin : Pin
{
public string Name { get; set; }
public string Url { get; set; }
}
To change the pin, the entire code had to be refactoring with creating CustomMap
and CustomPin
classes in the basic project and creating CustomMapRenderer
and CustomMKAnnotationView
classes in iOS and Android project.
Reference: https://github.com/xamarin/xamarin-forms-samples/tree/main/CustomRenderers/Map
Is there a way to clear this error?
=================================== UPDATE
In this method I trying to compare two Position properties like that:
CustomPin GetCustomPin(MKPointAnnotation annotation)
{
var position = new Position(annotation.Coordinate.Latitude, annotation.Coordinate.Longitude);
foreach (var pin in customPins)
{
if (pin.Position.Latitude == position.Latitude && pin.Position.Longitude == position.Longitude)
{
return pin;
}
}
return null;
}
But I still receive the same error ;(
As Jason points out in the comments you need to change how you add items to the map.
You were overwriting CustomPins with a new list with a single item every iteration of your loop.