{"id":45315,"date":"2023-04-25T09:30:00","date_gmt":"2023-04-25T16:30:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=45315"},"modified":"2023-04-25T09:09:10","modified_gmt":"2023-04-25T16:09:10","slug":"drawing-on-maps-with-dotnet-maui","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/drawing-on-maps-with-dotnet-maui\/","title":{"rendered":"Drawing Elements on Maps with .NET MAUI"},"content":{"rendered":"<p>Did you know that <a href=\"https:\/\/dot.net\/maui\">.NET MAUI<\/a> features a full <code>Map<\/code> control for iOS, Android, and MacCatalyst apps? It came with the launch of .NET 7 and it allows you to not only display a map with pins, but it also allows for full drawing with polygons, polylines, and circles! Lets take a look today at the <code>Map<\/code> control, how to display pins, and how to draw outlines and walking paths on the Microsoft campus in Redmond!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2023\/04\/maps-in-dotnetmaui.png\" alt=\"Multiple maps showing different capabilities in .NET MAUI\" \/> <\/p>\n<h2>Pins on a Map<\/h2>\n<p>The <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/microsoft.maui.controls.maps.map\"><code>Map<\/code><\/a> controls in .NET MAUI offers a wide arrange of customization of how to display the map. One of the basic elements that people place on a map is a <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/microsoft.maui.controls.maps.pin\"><code>Pin<\/code><\/a> that displays a marker with text. The  <code>Pins<\/code> property on the <code>Map<\/code> control is an <code>IList<\/code> that we can populate dynamically to put as many pins on the map. This can be accomplished in XAML:<\/p>\n<pre><code class=\"language-xaml\">&lt;ContentPage ...\r\n             xmlns:maps=\"clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.Maps\"\r\n             xmlns:sensors=\"clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials\"&gt;\r\n    &lt;maps:Map x:Name=\"map\"&gt;\r\n        &lt;x:Arguments&gt;\r\n            &lt;MapSpan&gt;\r\n                &lt;x:Arguments&gt;\r\n                    ...\r\n                &lt;\/x:Arguments&gt;\r\n            &lt;\/MapSpan&gt;\r\n        &lt;\/x:Arguments&gt;\r\n        &lt;maps:Map.Pins&gt;\r\n            &lt;maps:Pin Label=\"Santa Cruz\"\r\n                      Address=\"The city with a boardwalk\"\r\n                      Type=\"Place\"&gt;\r\n                &lt;maps:Pin.Location&gt;\r\n                    &lt;sensors:Location&gt;\r\n                        &lt;x:Arguments&gt;\r\n                            &lt;x:Double&gt;36.9628066&lt;\/x:Double&gt;\r\n                            &lt;x:Double&gt;-122.0194722&lt;\/x:Double&gt;\r\n                        &lt;\/x:Arguments&gt;\r\n                    &lt;\/sensors:Location&gt;\r\n                &lt;\/maps:Pin.Location&gt;\r\n            &lt;\/maps:Pin&gt;\r\n        &lt;\/maps:Map.Pins&gt;\r\n    &lt;\/maps:Map&gt;\r\n&lt;\/ContentPage&gt;<\/code><\/pre>\n<p>You can specify the pins directly in the XAML or you can use data binding to a list of <code>Pin<\/code> using the <code>ItemsSource<\/code> property similar to a <code>ListView<\/code> or <code>CollectionView<\/code>.<\/p>\n<p>You can also do this directly in C# code:<\/p>\n<pre><code class=\"language-csharp\">using Microsoft.Maui.Controls.Maps;\r\nusing Microsoft.Maui.Maps;\r\n\r\n\/\/...\r\n\r\nvar pin = new Pin\r\n{\r\n  Label = \"Santa Cruz\",\r\n  Address = \"The city with a boardwalk\",\r\n  Type = PinType.Place,\r\n  Location = new Location(36.9628066, -122.0194722)\r\n};\r\n\r\nmap.Pins.Add(pin);<\/code><\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2023\/04\/pin-and-information-window.png\" alt=\"A map with a pin on Santa Cruz open\" \/><\/p>\n<p>Better yet, you can add events to the <code>Pin<\/code> to see when it was clicked or when the info window was clicked with the <code>MarkerClicked<\/code> and <code>InfoWindowClicked<\/code> events on the <code>Pin<\/code>.<\/p>\n<h2>Drawing Elements on a Map<\/h2>\n<p>Now, let&#8217;s get into some fun and actually draw some lines and polygons on a map! The <code>MapElements<\/code> property on a <code>Map<\/code> takes in a list of <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/microsoft.maui.controls.maps.mapelement\"><code>MapElement<\/code><\/a> that can be drawn on the map. Built into .NET MAUI are three elements:<\/p>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/microsoft.maui.controls.maps.circle\">Circle<\/a>: A circle drawn from a center point with a specified radius<\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/microsoft.maui.controls.maps.polygon\">Polygon<\/a>: A fully enclosed shape. The first &amp; last points are automatically connected.<\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/microsoft.maui.controls.maps.polyline\">Polyline<\/a>: A series of points connected by drawn lines<\/li>\n<\/ul>\n<p>With these three elements you can do just about anything on a map! Like drawing an overlay over the Microsoft Campus in Redmond with a line showing the walkway between the East and West campus:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2023\/04\/redmond-map.png\" alt=\"A map showing two regions and a line\" \/><\/p>\n<p>First, let&#8217;s draw two <code>Polygon<\/code> elements that represent our West and East campus. Each of them will take in a list of <code>Location<\/code> on the <code>Geopath<\/code> property that will define the outline points. The <code>Polygon<\/code> will automatically connect each of these points together with a <code>Stroke<\/code> that you can define and a full background <code>FillColor<\/code>. All of this can be created directly in XAML with our without data binding or directly in C# like I prefer when dealing with maps.<\/p>\n<pre><code class=\"language-csharp\">var msWest = new Polygon\r\n{\r\n    StrokeColor = Color.FromArgb(\"#FF9900\"),\r\n    StrokeWidth = 8,\r\n    FillColor = Color.FromArgb(\"#88FF9900\"),\r\n    Geopath =\r\n    {\r\n        new Location(47.6458676, -122.1356007),\r\n        new Location(47.6458097, -122.142789),\r\n        new Location(47.6367593, -122.1428104),\r\n        new Location(47.6368027, -122.1398707),\r\n        new Location(47.6380172, -122.1376177),\r\n        new Location(47.640663, -122.1352359),\r\n        new Location(47.6426148, -122.1347209),\r\n        new Location(47.6458676, -122.1356007)\r\n    }\r\n};\r\n\r\nvar msEast = new Polygon\r\n{\r\n    StrokeColor = Color.FromArgb(\"#1BA1E2\"),\r\n    StrokeWidth = 8,\r\n    FillColor = Color.FromArgb(\"#881BA1E2\"),\r\n    Geopath =\r\n    {\r\n        new Location(47.6368678, -122.137305),\r\n        new Location(47.6368894, -122.134655),\r\n        new Location(47.6359424, -122.134655),\r\n        new Location(47.6359496, -122.1325521),\r\n        new Location(47.6424124, -122.1325199),\r\n        new Location(47.642463, -122.1338932),\r\n        new Location(47.6406414, -122.1344833),\r\n        new Location(47.6384943, -122.1361248),\r\n        new Location(47.6372943, -122.1376912),\r\n        new Location(47.6368678, -122.137305),\r\n    }\r\n};<\/code><\/pre>\n<p>With our two <code>Polygon<\/code> regions defined now, all we need to do is create a <code>Polyline<\/code> to represent the bridge that connects the two parts of the campus. A <code>Polyline<\/code> is extremely similar to a <code>Polygon<\/code>, but it does not automatically &#8220;connect&#8221; the start and end points, and there is no background fill. It is simply points on a map that are connected by a line. <\/p>\n<pre><code class=\"language-csharp\">var interstateBridge = new Polyline\r\n{\r\n    StrokeColor = Colors.Black,\r\n    StrokeWidth = 12,\r\n    Geopath =\r\n    {\r\n        new Location(47.6381401, -122.1317367),\r\n        new Location(47.6381473, -122.1350841),\r\n        new Location(47.6382847, -122.1353094),\r\n        new Location(47.6384582, -122.1354703),\r\n        new Location(47.6401136, -122.1360819),\r\n        new Location(47.6403883, -122.1364681),\r\n        new Location(47.6407426, -122.1377019),\r\n        new Location(47.6412558, -122.1404056),\r\n        new Location(47.6414148, -122.1418647),\r\n        new Location(47.6414654, -122.1432702)\r\n    }\r\n};<\/code><\/pre>\n<p>Now it is time to load these elements into our <code>Map<\/code> control&#8217;s <code>MapElements<\/code> property and of course zoom the map to the position above the campus:<\/p>\n<pre><code class=\"language-csharp\">map.MapElements.Add(msWest);\r\nmap.MapElements.Add(msEast);\r\nmap.MapElements.Add(interstateBridge);\r\n\r\nmap.MoveToRegion(MapSpan.FromCenterAndRadius(\r\n                new Location(47.640663, -122.1376177), Distance.FromMiles(1)));<\/code><\/pre>\n<p>There you have it! Our map is now fully displaying our two regions and a line that represent the bridge walkway between the campus! You can always add and remove as many <code>MapElement<\/code>s as you would like!<\/p>\n<h2>Learn More<\/h2>\n<p>There is so much more to learn about the <code>Map<\/code> control! I recently did a short <a href=\"https:\/\/www.youtube.com\/watch?v=jkEWltr6Aq0\">overview video<\/a> that I highly recommend watching:<\/p>\n<p><iframe width=\"752\" height=\"423\" src=\"https:\/\/www.youtube.com\/embed\/jkEWltr6Aq0\" allowfullscreen><\/iframe><\/p>\n<p>Additionally, read through the entire <a href=\"https:\/\/learn.microsoft.com\/dotnet\/maui\/user-interface\/controls\/map\">documention<\/a> where you will find the full source code for this sample and so much more!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>.NET MAUI now features a Map control that allows you not only to display a position with pins, but also render full geometry to essentially draw on a map! In this post I show you how to do it.<\/p>\n","protected":false},"author":544,"featured_media":45316,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,7233],"tags":[7611,7733,7732,7731],"class_list":["post-45315","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-maui","tag-dotnet-7","tag-drawing","tag-geometry","tag-maps"],"acf":[],"blog_post_summary":"<p>.NET MAUI now features a Map control that allows you not only to display a position with pins, but also render full geometry to essentially draw on a map! In this post I show you how to do it.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/45315","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/544"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=45315"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/45315\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/45316"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=45315"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=45315"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=45315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}