Xamarin - iOS地图上的多个多边形

时间:2017-09-11 04:49:40

标签: c# ios xamarin xamarin.ios xamarin.forms

我目前正在关注向地图添加多边形的this教程。我需要能够将多个多边形添加到我的地图中,因此我稍微更改了代码,以便我可以使用addOverlays,其中包含IMKOverlay个对象而不是addOverlay个对象的数组它只包含一个IMKOverlay个对象。

但这并不起作用......它只在地图上绘制第一个多边形!

void addPolygonsToMap()
        {
            overlayList = new List<IMKOverlay>();
            for (int i = 0; i < polygons.Count; i++)
            {

                    CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[polygons[i].Count];

                    int index=0;
                    foreach (var position in polygons[i])
                    {
                        coords[index] = new CLLocationCoordinate2D(position.Latitude, position.Longitude);
                        index++;
                    }
                    var blockOverlay = MKPolygon.FromCoordinates(coords);
                    overlayList.Add(blockOverlay);

            }
            IMKOverlay[] imko = overlayList.ToArray();
            nativeMap.AddOverlays(imko);

        }

this讨论中,每次我需要在地图上添加另一个多边形时,我必须调用MKPolygonRenderer的新实例,但我不确定这个例子是怎么做的转换为我的代码。这是我的MKPolygonRenderer函数:

MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlayWrapper)
  {
      if (polygonRenderer == null && !Equals(overlayWrapper, null)) {
          var overlay = Runtime.GetNSObject(overlayWrapper.Handle) as IMKOverlay;
          polygonRenderer = new MKPolygonRenderer(overlay as MKPolygon) {
              FillColor = UIColor.Red,
              StrokeColor = UIColor.Blue,
              Alpha = 0.4f,
              LineWidth = 9
          };
      }
      return polygonRenderer;
  }

2 个答案:

答案 0 :(得分:4)

每次调用OverlayRenderer时都创建一个新的渲染器实例,不需要在类级变量中缓存渲染器,因为MKMapView将根据需要缓存渲染器。

子类MKMapViewDelegate

class MyMapDelegate : MKMapViewDelegate
{
    public override MKOverlayRenderer OverlayRenderer(MKMapView mapView, IMKOverlay overlay)
    {
        switch (overlay)
        {
            case MKPolygon polygon:
                var prenderer = new MKPolygonRenderer(polygon)
                {
                    FillColor = UIColor.Red,
                    StrokeColor = UIColor.Blue,
                    Alpha = 0.4f,
                    LineWidth = 9
                };
                return prenderer;
            default:
                throw new Exception($"Not supported: {overlay.GetType()}");
        }
    }
}

实例并将代理人分配到您的地图:

mapDelegate = new MyMapDelegate();
map.Delegate = mapDelegate;

注意:将MyMapDelegate的实例存储在班级变量中,因为您不希望获得GC&#39; d

更新

MKMapView包含两个步骤,可在其地图上显示叠加层。

1. Calling `AddOverlay` and `AddOverlays`

首先,在地图上添加符合IMKOverlay的叠加层。有基本的内置类型,如MKCircleMKPolygon等......但您也可以设计自己的叠加层;即定义恶劣天气(闪电,暴风云,龙卷风等)位置的覆盖层。这些MKOverlay描述了项目的地理位置但不是如何绘制它。

2. Responding to `OverlayRenderer` requests

当地图的显示区域与其中一个叠加层相交时,地图需要在屏幕上绘制它。调用地图的委托(您的MKMapViewDelegate子类)以提供MKOverlayRenderer,该MKOverlayRenderer定义绘制例程以在地图上绘制叠加层。

此绘图涉及使用Core Graphics例程将叠加层的地理坐标转换为本地显示坐标(辅助方法可用)(UIKit可以使用某些限制)。 MKCircleRenderer,MKPolygonRenderer等有基本的内置渲染器,可以使用,也可以编写自己的MKCircle子类。

您可以提供自定义方式来渲染MKPolygon叠加层,也可以是目标样式的红色/白色多环形靶心,而不是默认圆形渲染器绘制它的方式,或者是绘制严重风暴的自定义渲染器MKPolygon范围内的符号,以匹配您的自定义严重风暴叠加。

我的示例代码:

由于您使用MKPolygonRenderer来构建叠加层,因此您可以使用en来显示它们。在我的示例中,我提供了一个模式匹配开关(C#6),它为添加到地图中的每个 MKPolygon返回一个半透明的Red / Blue MKPolygonRenderer(如果添加了非基于MKPolygon的叠加层)它会引发异常)。

答案 1 :(得分:0)

我也陷入了这个问题,并且找到了创建MKPolygon子类的方法。

我已经通过示例检查了它,它的工作原理就像一个魅力。但不确定苹果是否可以拒绝我的应用。

public class CvPolyon : MKPolygon
    {
        public CustomObject BoundaryOption { get; }

        public CvPolyon1(MKPolygon polygon, CustomObject  boundaryOption)
            :base(polygon.Handle)
        {
            BoundaryOption = boundaryOption;
        }
    }

我们可以在地图上添加多边形。

var polygon = MKPolygon.FromCoordinates(coordinates);
                    var overlay = new CvPolyon(polygon, new CustomObject());
                    mapView.AddOverlay(overlay);

我们可以在扩展MKMapViewDelegate的类中识别出我们的多边形。

public override MKOverlayRenderer OverlayRenderer(MKMapView mapView, IMKOverlay overlay)
        {
            if (overlay is CvPolyon polygon)
            {
                var polygonRenderer = new MKPolygonRenderer(polygon)
                {
                    FillColor   = polygon.BoundaryOption.AreaColor,
                    StrokeColor = polygon.BoundaryOption.LineColor,
                    Alpha       = polygon.BoundaryOption.Alpha,
                    LineWidth   = polygon.BoundaryOption.LineWidth
                };

                if (polygon.BoundaryOption.IsDashedLine)
                    polygonRenderer.LineDashPattern = new[] { new NSNumber(2), new NSNumber(5) };

                return polygonRenderer;
            }

            return mapView.RendererForOverlay(overlay);
        }