c# - Xamarin Forms - 使用自定义 map 渲染器在 map 上创建多个多边形

标签 c# xamarin xamarin.ios xamarin.forms

我关注了this关于使用自定义 map 渲染器在 map 上突出显示区域的 Xamarin 表单教程。本教程介绍如何将一个多边形添加到 Xamarin Forms 中的 map ,但不说明如何扩展代码以允许在 map 上添加多个多边形。

如何调整此实现以允许 iOS map 上出现多个多边形?这是我的 iOS 代码:

[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace MapOverlay.iOS
{
    public class CustomMapRenderer : MapRenderer
    {
        MKPolygonRenderer polygonRenderer;

        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null) {
                var nativeMap = Control as MKMapView;
                if (nativeMap != null) {
                    nativeMap.RemoveOverlays(nativeMap.Overlays);
                    nativeMap.OverlayRenderer = null;
                    polygonRenderer = null;
                }
            }

            if (e.NewElement != null) {
                var formsMap = (CustomMap)e.NewElement;
                var nativeMap = Control as MKMapView;

                nativeMap.OverlayRenderer = GetOverlayRenderer;

                CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[formsMap.ShapeCoordinates.Count];

                int index = 0;
                foreach (var position in formsMap.ShapeCoordinates)
                {
                    coords[index] = new CLLocationCoordinate2D(position.Latitude, position.Longitude);
                    index++;
                }

                var blockOverlay = MKPolygon.FromCoordinates(coords);
                nativeMap.AddOverlay(blockOverlay);
            }
        }




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

    }
}

最佳答案

您的代码有两个问题:

  1. 第一个问题在你的if (e.NewElement != null){...}代码。如果你想要多个多边形,formsMap.ShapeCoordinates应该是 List<List<Position>>类型。所以它可以有多个多边形的坐标组。如您的代码所示,它使用 List<Position> .你的代码触发 nativeMap.AddOverlay(blockOverlay); only once 这只会将一个叠加层添加到您的 map 中。

  2. 更改 if (polygonRenderer == null && !Equals(overlayWrapper, null))GetOverlayRendererif (!Equals(overlayWrapper, null)) .否则每次 map 添加overlay触发方法,都会返回第一个polygonRenderer .

例如,这是我的代码:

  1. PCL MainPage.xaml 中的代码:

    <ContentPage.Content>
        <local:CustomMap x:Name="customMap" MapType="Street" WidthRequest="{x:Static local:App.ScreenWidth}" HeightRequest="{x:Static local:App.ScreenHeight}" />
    </ContentPage.Content>
    
  2. 我在 PCL 的 MainPage.xaml.cs 中添加了两个多边形的位置列表:

    List<Position> pos = new List<Position> { new Position(39.939889, 116.423493), new Position(39.930622, 116.423924), new Position(39.930733,116.441135), new Position(39.939944, 116.44056) };
    List<Position> posi = new List<Position> { new Position(39.934633, 116.399921), new Position(39.929709, 116.400208), new Position(39.929792, 116.405994), new Position(39.934689,116.405526) };
    customMap.ShapeCoordinates.Add(pos);
    customMap.ShapeCoordinates.Add(posi);
    customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(39.934689, 116.405526), Distance.FromMiles(1.5)));
    
  3. PCL 中 CustomMap.cs 中的代码:

    public class CustomMap : Map
    {
        public List<List<Position>> ShapeCoordinates { get; set; }
    
        public CustomMap()
        {
            ShapeCoordinates = new List<List<Position>>();
        }
    }
    
  4. iOS平台CustomMapRenderer.cs中的代码:

    class CustomMapRenderer : MapRenderer
    {
        MKPolygonRenderer polygonRenderer;
    
        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged(e);
    
            if (e.OldElement != null)
            {
                var nativeMap = Control as MKMapView;
                if (nativeMap != null)
                {
                    nativeMap.RemoveOverlays(nativeMap.Overlays);
                    nativeMap.OverlayRenderer = null;
                    polygonRenderer = null;
                }
            }
    
            if (e.NewElement != null)
            {
                var formsMap = (CustomMap)e.NewElement;
                var nativeMap = Control as MKMapView;
                nativeMap.OverlayRenderer = GetOverlayRenderer;
    
                foreach (List<Position> positionList in formsMap.ShapeCoordinates)
                {
    
                    CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[positionList.Count];
    
                    int index = 0;
                    foreach (var position in positionList)
                    {
                        coords[index] = new CLLocationCoordinate2D(position.Latitude, position.Longitude);
                        Console.WriteLine(position.Latitude +" : "+ position.Longitude);
    
                        index++;
                    }
    
    
    
                    var blockOverlay = MKPolygon.FromCoordinates(coords);
                    nativeMap.AddOverlay(blockOverlay);
    
                }
            }
        }
    
    
    
        MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlayWrapper)
        {
            if (!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;
        }
    }
    

它的工作原理是这样的:

enter image description here

关于c# - Xamarin Forms - 使用自定义 map 渲染器在 map 上创建多个多边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46292850/

相关文章:

c# - 将 Listview 项目计数绑定(bind)到 Xamarin Forms 中的标签可见性

c# - Monotouch 使用哪种数据访问技术

ios - 如何在 Xamarin.Forms ios 中更改工具栏图标颜色

Xamarin:使用具有 UICompletion 处理程序的 Notify 方法不可用

c# - 检查上传图片的尺寸

c# - 生成具有少量唯一值的数据集

c# - Xamarin。 X509Certificate 和 ClientBase

c# - 如何访问多个 Xamarin "Picker"内的选定参数

c# - 使用 IComparer 随机播放

c# - 如果字符串长度为 2 且包含 1 个字母和 1 个数字,则正则表达式匹配