Creating outlined map polygons in .NET MAUI

I was playing around with porting my Xamarin.Forms app over to .NET MAUI with the release of .NET 7 RC 1, which includes the Map control for MAUI. The app uses open data from my local municipality and shows the different parking zones around town. It also shows additional info like how long you can park and if you are allowed to park there at all. I posted a screenshot to Twitter with my progress, and I was asked if I can share how I created the outlined polygons that made up the parking zones on the map. So, here’s how I did it.

Upgrading to .NET 7

I won’t go into much detail on how I ported my app. I will mention that I had to upgrade my work-in-progress .NET MAUI project to .NET 7. The steps for how to do this is listed in the link I provided at the start, so I won’t go into detail on how to do that here. Link for the lazy.

Then I added a Map control to my XAML page and gave it an x:Name of map. I also wanted the map to start at the location of my municipality, so I used the same code as in the example article and just replaced the coordinates in the Location property.

Parsing the data

The data set for the parking zones is stored as a GeoJSON file. I load the file from a URL and deserialize the result as a FeatureCollection, which is the root object of a GeoJSON file.

using var httpClient = new HttpClient();

var stringResult = await httpClient.GetStringAsync(geoJsonUrl);
var jsonResult = JsonConvert.DeserializeObject<FeatureCollection>(stringResult);

Then I iterate over the resulting Features list from the jsonResult. Each feature in this case represents a parking zone. Each feature contains a list of coordinates, which makes up the “outline” of the parking zones if you were to draw lines between them.

foreach (var parkingZone in jsonResult.Features)
{
    if (parkingZone.Geometry is not Polygon polygon) continue;
    var points = polygon.Coordinates.First().Coordinates;
    ...   
}

To represent these parking zones in the map, I create a Polygon from the Maui.Controls.Maps namespace. I start by setting the stroke width, the stroke color and the fill color. I want the parking zone to have a distinct “outline”, since these parking zones often are very close to one another and I want them to be distinguishable, so I set the fill color to be just a bit more transparent than the stroke color:

var mapPolygon = new Microsoft.Maui.Controls.Maps.Polygon
{
    StrokeWidth = 8,
    StrokeColor = Color.Parse("#1BA1E2"),
    FillColor = Color.Parse("#881BA1E2"),
    ClassId = parkingZone.Properties.ElementAt(4).Value.ToString()
};

I use the ClassId property to handle click events on individual parking zones, but I won’t cover that in this post.

Now I iterate over the list of coordinates and add it to the mapPolygon I just created:

foreach (var p in points)
{
    mapPolygon.Geopath.Add(new Location(p.Latitude, p.Longitude));
}

Finally, I add the mapPolygon to the MapElements property of my map:

map.MapElements.Add(mapPolygon);

The complete code would look like this:

And that’s how it was done! Like I mentioned, I do have some functionality for when you click a parking zone as well, which will highlight the selected parking zone and show some additional info. If you want to know how I did this, feel free to reach out and I might make a follow-up on this.

4 thoughts on “Creating outlined map polygons in .NET MAUI”

    1. Hi Gagan, glad it was helpful!
      Yes there is, I didn’t show it in this post but I am doing that in my app. You can add a MapClicked event handler where you check where the user has clicked. You can then loop through your polygons and check if the user has clicked the polygon. See code example below:


      var location = e.Location;

      bool isPointInPolygon = false;
      Feature selectedParkingZone = null;

      foreach (var parkingZone in jsonResult.Features)
      {
      if (parkingZone.Geometry is not Polygon polygon) continue;
      var points = polygon.Coordinates.First().Coordinates;
      isPointInPolygon = PolygonUtility.PointInPolygon(location.Longitude, location.Latitude, points.ToList());
      if (isPointInPolygon)
      {
      selectedParkingZone = parkingZone;
      break;
      }
      }

      The PolygonUtility.PointInPolygon()-method uses this code to determine whether a point is inside a polygon: http://csharphelper.com/howtos/howto_polygon_geometry_point_inside.html

      In this case I do a null-check on the selectedParkingZone further down to show an overlay with the parking zone details.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.