I'm extending the example provided @ https://developer.xamarin.com/recipes/cross-platform/xamarin-forms/maps/map-overlay/polyline/ to add multiple polylines to my map.
Everything works fine with a single polyline, but when I add the second, or add a polyline alongside an annotation, GetOverlayRenderer errors out with the error
"Value cannot be null.Parameter name: polyline"
It's erring out on line:
polylineRenderer = new MKPolylineRenderer (overlay as MKPolyline);
And when I look at the overlay object, it is:
{MapKit.MKOverlayWrapper}
BoundingMapRect: {{{62634939.7333333, 111606556.311973}, {745654.044444449, 848491.772016793}}}
Coordinate: {CoreLocation.CLLocationCoordinate2D}
Handle: 0x791ca560
Non-public members:
I don't understand why it works with one polyline, but when I add anything else to the map, it fails (first time through the method, also)
Here's the entire method where the error is occurring. I can provide more code but it works FINE with one line, just not with two. (I loop through a list of objects... if there's 1, it's fine.. if there is 2, it fails).
MKOverlayRenderer GetOverlayRenderer (MKMapView mapView, IMKOverlay overlay)
{
if (polylineRenderer == null) {
try
{
polylineRenderer = new MKPolylineRenderer (overlay as MKPolyline);
polylineRenderer.FillColor = UIColor.Blue;
polylineRenderer.StrokeColor = UIColor.Red;
polylineRenderer.LineWidth = 3;
polylineRenderer.Alpha = 0.4f;
}
catch (Exception ex) {
}
}
return polylineRenderer;
}
For the delegate your setting for the
nativeMap.OverlayRenderer
remember that this is called for every overlay that you add.When this delegate is invoked it will be passed the
IMKOverlay
it relates to.Of which then you can either return a previously stored
MKOverlayRenderer
, or create a new one.The reason your code is failing, when you attempt to add two overlays, is because you are trying to return the same renderer for both overlays, i.e.
polylineRenderer
variable in your code.Just for demonstration purposes I've modified your
GetOverlayRenderer
to the following. This isn't a good design, but illustrates the point I'm making above.When you run this now, you will see one of your
MKPolyline
inRed
, and the other in aYellow
color.Add this in at class scope:-
and then modify your
GetOverlayRenderer
to the following:-Update 1:-
As mentioned above, the code is not good design, and is to illustrate a point only.
Yes - you can re-use
MKOverlayRenderer
's, however remember renderers are assigned to a specificIMKOverlay
that is passed into your delegate.You are trying to use the same renderer for multiple
IMKOverlay
's. It's just not possible.Although you have an existing renderer, you can't assign it to a different
IMKOverlay
that is passed into your delgate as theOverlay
property of theMKOverlayRenderer
is read-only, and that's the reason why.HTH.
Please try this:
@Pete, now I get it, and that did the trick. For my ugly demo, here's what I landed at. It creates a new renderer every time it's called... not good form, but it demonstrates the code you made - essentially I moved my renderer from being scoped across the class to being recreated every time it's requested... bad form, and I'll clean this up to reuse renderers down the road, but it gets the job done for demonstration / understanding.
And there they are!![Multiple Overlays](https://i.stack.imgur.com/MeaI7.png)
The end result here was that the overlay passed to the method is a wrapper of sorts, and you need to get the "handle" property to get the actual overlay.
The source of this came from https://forums.xamarin.com/discussion/31616/what-is-mkoverlaywrapper-its-breaking-my-map-renderer