I am currently following this tutorial for adding a polygon to a map. I need to be able to add multiple polygons to my map, so I have slightly altered the code so that I can use addOverlays
which takes in an array of IMKOverlay
objects instead of one addOverlay
which just takes in a single IMKOverlay
object.
This doesn't work however... It only draws the first polygon on the map!
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);
}
In this discussion, it would appear that I have to call a new instance of MKPolygonRenderer
each time I need to add another polygon to my map, but I'm unsure how this example translates to my code. Here is my MKPolygonRenderer
function:
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;
}
Create a new renderer instance each time
OverlayRenderer
is called, there is no need to cache the renderer in a class level variable as theMKMapView
will cache the renderers as needed.Subclass
MKMapViewDelegate
:Instance and assign the delegate to your map:
Note: Store the instance of your
MyMapDelegate
in a class level variable as you do not want to get GC'dUpdate:
MKMapView
has two steps involved to display an overlay on its map.First you add overlays to the map that conform to
IMKOverlay
. There are basic built-in types such asMKCircle
,MKPolygon
, etc... but you can also design your own overlays; i.e. overlays that define the location of severe weather (lightning, storm clouds, tornados, etc..). These MKOverlays describe the geo-location of the item but not how to draw it.When the display area of the map intersects with one of the overlays, the map need to draw it on the screen. The map's delegate (your
MKMapViewDelegate
subclass) is called to supply aMKOverlayRenderer
that defines the drawing routines to paint the overlay on the map.This drawing involves converting the geo-coordinates of the overlay to local display coordinates (helper methods are available) using Core Graphics routines (UIKit can be used with some limitations). There are basic built-in renderers for MKCircleRenderer, MKPolygonRenderer, etc.. that can be used or you can write your own
MKOverlayRenderer
subclass.You could supply a custom way to renderer a
MKCircle
overlay, maybe a target-style red/white multi-ringed bullseye, instead of the way the default circle renderer draws it, or custom renderers that draw severe storm symbols within the bounds of aMKPolygon
to match your custom severe storm overlays.My Example code:
Since you are using
MKPolygon
to build your overlays, you can use theMKPolygonRenderer
to display them. In my example, I provide a pattern matching switch (C# 6) that returns a semi-transparent Red/Blue MKPolygonRenderer for every MKPolygon that you added to the map (if you added a non-MKPolygon based overlay it will throw an exception).