我已经按照this Xamarin表格教程使用自定义地图渲染器突出显示地图上的某个区域。本教程将向您展示如何在Xamarin Forms中向地图添加一个多边形,但不解释如何扩展代码以允许地图上的多个多边形。
如何调整此实现以允许iOS地图上的多个多边形?这是我的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;
}
}
}
答案 0 :(得分:5)
您的代码存在两个问题:
第一个问题出在您的if (e.NewElement != null){...}
代码中。如果您想要多个多边形,formsMap.ShapeCoordinates
应该是List<List<Position>>
类型。所以它可以有多个多边形&#39;坐标组。代码显示时,它使用List<Position>
。并且您的代码只触发nativeMap.AddOverlay(blockOverlay);
一次,只会在地图中添加一个叠加层。
将if (polygonRenderer == null && !Equals(overlayWrapper, null))
中的GetOverlayRenderer
更改为if (!Equals(overlayWrapper, null))
。否则,每次地图添加叠加层并触发方法时,它都会返回第一个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>
我添加了两个多边形&#39; 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;
}
}
它的工作原理如下:
答案 1 :(得分:1)
在编写自己的自定义渲染器时,我通常会参考此扩展地图控件。
查看多边形的iOS渲染器,他们只需在Forms Map上遍历多边形,然后在iOS Map中添加另一个叠加层即可。
foreach (var position in formsMap.ShapeCoordinates)
{
coords[index] = new CLLocationCoordinate2D(position.Latitude, position.Longitude);
var blockOverlay = MKPolygon.FromCoordinates(coords);
nativeMap.AddOverlay(blockOverlay);
}