Adding a Polyline overlay to a map

ChetCromerChetCromer USMember ✭✭
edited February 2016 in Xamarin.iOS

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;
    }
Tagged:

Posts

  • MichelangeloFrancoMichelangeloFranco ITUniversity ✭✭

    Same problem. Have You resolved?

  • ChetCromerChetCromer USMember ✭✭
    edited March 2016

    I did. What I discovered was that the "overlay" that is sent to the function is not an "MKPolyline" at all but rather a type of wrapper that needed to be further casted to get the MKPolyline... at least I think that's the right terminology. Below is my code that's now working, and here are a few other links to articles I used to get to this solution:

    https://forums.xamarin.com/discussion/31616/what-is-mkoverlaywrapper-its-breaking-my-map-renderer

    http://stackoverflow.com/questions/35468177/adding-multiple-polylines-to-an-mkmapview-xamarin

    MKOverlayRenderer GetOverlayRenderer (MKMapView mapView, IMKOverlay overlay)
    {
    MKPolylineRenderer polylineRenderer= new MKPolylineRenderer (overlay as MKPolyline);
    polylineRenderer.FillColor = UIColor.Blue;
    polylineRenderer.StrokeColor = UIColor.Red;
    polylineRenderer.LineWidth = 3;
    polylineRenderer.Alpha = 0.4f;
    return polylineRenderer;
    }

  • MichelangeloFrancoMichelangeloFranco ITUniversity ✭✭

    Thanks Chet, but the problem still here.... Can you help me please understand? This is my Class:

    public class CustomMapRenderer : MapRenderer 
    {
        protected override void OnElementChanged (ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged (e);
    
            if (e.OldElement != null) {
                var nativeMap = Control as MKMapView;
                nativeMap.OverlayRenderer = null;
            }
    
            if (e.NewElement != null) {
                var formsMap = (CustomMap)e.NewElement;
                var nativeMap = Control as MKMapView;
                //var circle = formsMap.Circle;
    
                nativeMap.OverlayRenderer = GetOverlayRenderer;
    
                CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[formsMap.RouteCoordinates.Count];
    
                int index = 0;
                foreach (var position in formsMap.RouteCoordinates) {
                    coords [index] = new CLLocationCoordinate2D (position.Latitude, position.Longitude);
                    index++;
                }
    
                var routeOverlay = MKPolyline.FromCoordinates (coords);
                nativeMap.AddOverlay (routeOverlay);
    
    
            }
        }
    
    
        MKOverlayRenderer GetOverlayRenderer (MKMapView mapView, IMKOverlay overlay)
        {
            //Moved the renderer here instead of being scoped at the class
            MKPolylineRenderer polylineRenderer= new MKPolylineRenderer (overlay as MKPolyline);
            polylineRenderer.FillColor = UIColor.Blue;
            polylineRenderer.StrokeColor = UIColor.Red;
            polylineRenderer.LineWidth = 3;
            polylineRenderer.Alpha = 0.4f;
            return polylineRenderer;
        }
    
    }
    
  • ChetCromerChetCromer USMember ✭✭

    Someone (me) didn't updated my post after finding the true solution to my problem... sorry about that!

    Here's what my code looks like now:


    MKOverlayRenderer GetOverlayRenderer (MKMapView mapView, IMKOverlay overlayWrapper)
    {
    IMKOverlay overlay = Runtime.GetNSObject (overlayWrapper.Handle) as IMKOverlay;

    The GetOverlayRenderer method is sent an IMKOverlay that's actually a wrapper - you need to get it's "Handle" to get the actual IMKOverlay.

    Let me know if this helps!

  • MichelangeloFrancoMichelangeloFranco ITUniversity ✭✭

    YES!! Thank you thousand Chet. I have solved my problem.

  • ChetCromerChetCromer USMember ✭✭

    Awesome! It's great to see it when the lines finally appear like they should.

  • Thank you for posting your solution! I was running into the same problems trying to add multiple overlays.

  • AlexTam.7016AlexTam.7016 USMember ✭✭

    how do u guys cleanup the circles after that, i have a refresh data button at my map that re-update lat and long of some stations. which will refresh the pins as well as the "circle radius of 100m" right below them

  • Abhir9702Abhir9702 INMember ✭✭

    any way to use with xamarin forms with custom renderers

Sign In or Register to comment.