将多条折线添加到 MKMapView (Xamarin)

Adding multiple polylines to an MKMapView (Xamarin)

我正在扩展 @ https://developer.xamarin.com/recipes/cross-platform/xamarin-forms/maps/map-overlay/polyline/ 提供的示例以将多条折线添加到我的地图。

使用一条多段线一切正常,但是当我添加第二条多段线或在注释旁边添加一条多段线时,GetOverlayRenderer 出错并显示错误

"Value cannot be null.Parameter name: polyline"

在线出错:

polylineRenderer = new MKPolylineRenderer (overlay as MKPolyline);

当我查看覆盖对象时,它是:

{MapKit.MKOverlayWrapper}
BoundingMapRect: {{{62634939.7333333, 111606556.311973}, {745654.044444449, 848491.772016793}}}
Coordinate: {CoreLocation.CLLocationCoordinate2D}
Handle: 0x791ca560
Non-public members: 

我不明白为什么它适用于一条折线,但是当我向地图添加任何其他内容时,它失败了(也是第一次通过该方法)

这是发生错误的整个方法。我可以提供更多代码,但它只用一行就可以正常工作,但不能用两行。 (我遍历了一个对象列表……如果有 1 个,没问题。如果有 2 个,它就失败了)。

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

请试试这个:

public override MKOverlayView GetViewForOverlay(MKMapView mapView, IMKOverlay overlay)
        {
            if (overlay is MKPolyline)
            {
                // return a view for the polygon
                MKPolyline l_polyline = overlay as MKPolyline;
                MKPolylineView l_polylineView = new MKPolylineView(l_polyline);
                MKPolylineRenderer l_polylineRenderer = new MKPolylineRenderer(l_polyline);

                l_polylineView.FillColor = UIColor.Blue;
                l_polylineView.StrokeColor = UIColor.Red;

                return l_polylineView;
            }

            return null;
        }

对于委托,您对 nativeMap.OverlayRenderer 的设置请记住,这是针对您添加的 每个 叠加层调用的。

调用此委托时,它将传递给它相关的 IMKOverlay

然后您可以 return 一个以前存储的 MKOverlayRenderer,或者创建一个新的。

当您尝试添加两个叠加层时,您的代码失败的原因是因为您正在尝试 return 相同的 渲染器 两者 覆盖,即代码中的 polylineRenderer 变量。

出于演示目的,我已将您的 GetOverlayRenderer 修改为以下内容。这不是一个好的设计,但说明了我在上面提出的观点。

当你现在 运行 时,你会看到你的一个 MKPolyline 颜色为 Red,另一个颜色为 Yellow

将此添加到 class 范围:-

private bool cblnIsTest = false;

然后将您的 GetOverlayRenderer 修改为以下内容:-

MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlay)
{
    MKPolylineRenderer polylineRenderer2 = new MKPolylineRenderer(overlay as MKPolyline);

    if (!cblnIsTest)
    {
        cblnIsTest = true;
        //
        polylineRenderer2.StrokeColor = UIColor.Yellow;
    }
    else
    {
        polyline Renderer.StrokeColor = UIColor.Red;
    }
    polylineRenderer2.LineWidth = 3;
    polylineRenderer2.Alpha = 0.4f;
    //
    return polylineRenderer2;
}

更新一:-

如前所述,代码设计不佳,只是为了说明一点。

是的 - 您可以重复使用 MKOverlayRenderer,但请记住渲染器被分配给传递给您的委托的特定 IMKOverlay

您正在尝试对多个 IMKOverlay 使用相同 渲染器。这是不可能的。

虽然您有一个现有的渲染器,但您不能将它分配给作为 Overlay [ MKOverlayRenderer 的 =74=] 是 只读,这就是原因。

HTH.

@Pete,现在我明白了,那就成功了。对于我丑陋的演示,这就是我的目标。它每次被调用时都会创建一个新的渲染器......不是很好的形式,但它演示了你制作的代码 - 本质上我将我的渲染器从 class 范围内移动到每次被请求时重新创建......不好形式,我将清理它以在以后重用渲染器,但它完成了演示/理解的工作。

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

他们就在那里!

这里的最终结果是传递给该方法的叠加层是某种包装器,您需要获取 "handle" 属性 才能获得实际的叠加层。

public override MKOverlayView GetViewForOverlay (MKMapView mapView, IMKOverlay overlayWrapper)
    {
    if (overlayWrapper != null) {
    var overlay = Runtime.GetNSObject(overlayWrapper.Handle) as MKOverlay;
    // Do Overlay Functions here
    }

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