我关注了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;
}
}
}
最佳答案
您的代码有两个问题:
第一个问题在你的
if (e.NewElement != null){...}
代码。如果你想要多个多边形,formsMap.ShapeCoordinates
应该是List<List<Position>>
类型。所以它可以有多个多边形的坐标组。如您的代码所示,它使用List<Position>
.你的代码触发nativeMap.AddOverlay(blockOverlay);
only once 这只会将一个叠加层添加到您的 map 中。更改
if (polygonRenderer == null && !Equals(overlayWrapper, null))
在GetOverlayRenderer
至if (!Equals(overlayWrapper, null))
.否则每次 map 添加overlay触发方法,都会返回第一个polygonRenderer
.
例如,这是我的代码:
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>
我在 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)));
PCL 中 CustomMap.cs 中的代码:
public class CustomMap : Map { public List<List<Position>> ShapeCoordinates { get; set; } public CustomMap() { ShapeCoordinates = new List<List<Position>>(); } }
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; } }
它的工作原理是这样的:
关于c# - Xamarin Forms - 使用自定义 map 渲染器在 map 上创建多个多边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46292850/