Skip to content

Commit b8a1820

Browse files
jfversluisCopilot
andauthored
Update Maps documentation for .NET 11 features (#3212)
* Update Maps documentation for .NET 11 features Document all new Maps APIs added in .NET 11 via the Maps epic (dotnet/maui#33787): - Pin clustering (IsClusteringEnabled, ClusterClicked, ClusteringIdentifier) - Custom pin icons (Pin.ImageSource) - MoveToRegion animated overload and MapSpan.FromLocations - Pin.ShowInfoWindow() and Pin.HideInfoWindow() - MapLongClicked event - MapElementClick event for Circle/Polygon/Polyline - UserLocationChanged event and LastUserLocation property - Map.MapStyle for custom JSON styling (Android) - MapElement.IsVisible and MapElement.ZIndex - XAML TypeConverters (LocationTypeConverter, MapSpanTypeConverter) - Map.Region bindable property All new content gated with >=net-maui-11.0 moniker ranges. Closes #3208 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove undefined net-maui-11.0 moniker zones from map.md The net-maui-11.0 moniker is not yet registered in the build system, causing validation errors. Remove the zone markers while keeping all .NET 11 content inline. Moniker zones can be re-added once the moniker is defined. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revert "Remove undefined net-maui-11.0 moniker zones from map.md" This reverts commit 5c7f63e. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 89615d7 commit b8a1820

1 file changed

Lines changed: 267 additions & 0 deletions

File tree

  • docs/user-interface/controls

docs/user-interface/controls/map.md

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,15 @@ The <xref:Microsoft.Maui.Controls.Maps.Map> class defines the following properti
165165
- `Pins`, of type `IList<Pin>`, represents the list of pins on the map.
166166
- `VisibleRegion`, of type `MapSpan`, returns the currently displayed region of the map.
167167
168+
::: moniker range=">=net-maui-11.0"
169+
170+
- `IsClusteringEnabled`, of type `bool`, determines whether nearby pins are automatically grouped into clusters. Default is `false`.
171+
- `LastUserLocation`, of type `Location`, returns the most recent user location, or `null` if not yet available. Requires `IsShowingUser` to be `true`.
172+
- `MapStyle`, of type `string`, accepts a JSON style string for customizing the visual appearance of the map. Android only.
173+
- `Region`, of type `MapSpan`, sets the initial map region declaratively. Supports XAML type conversion with the format `"latitude,longitude,latitudeDegrees,longitudeDegrees"`.
174+
175+
::: moniker-end
176+
168177
These properties, with the exception of the `MapElements`, `Pins`, and `VisibleRegion` properties, are backed by <xref:Microsoft.Maui.Controls.BindableProperty> objects, which mean they can be targets of data bindings.
169178
170179
The <xref:Microsoft.Maui.Controls.Maps.Map> class also defines a `MapClicked` event that's fired when the map is tapped. The `MapClickedEventArgs` object that accompanies the event has a single property named `Location`, of type `Location`. When the event is fired, the `Location` property is set to the map location that was tapped. For information about the `Location` class, see [Location and distance](#location-and-distance).
@@ -277,6 +286,24 @@ The result is that when the map is displayed, it's centered on a specific locati
277286
278287
:::image type="content" source="media/map/map-region.png" alt-text="Screenshot of map control with specified location.":::
279288
289+
::: moniker range=">=net-maui-11.0"
290+
291+
In .NET 11, you can use the `Region` bindable property with XAML type converters for a more concise syntax:
292+
293+
```xaml
294+
<maps:Map Region="36.9628066,-122.0194722,0.01,0.01" />
295+
```
296+
297+
The `MapSpanTypeConverter` parses the string as `"latitude,longitude,latitudeDegrees,longitudeDegrees"`. Similarly, the `LocationTypeConverter` enables specifying `Location` values as `"latitude,longitude"` strings:
298+
299+
```xaml
300+
<maps:Pin Location="36.9628066,-122.0194722" Label="Santa Cruz" />
301+
```
302+
303+
These type converters eliminate the need for verbose `x:Arguments` markup when defining map regions and pin locations in XAML.
304+
305+
::: moniker-end
306+
280307
### Create a MapSpan object
281308
282309
There are a number of approaches for creating `MapSpan` objects. A common approach is supply the required arguments to the `MapSpan` constructor. These are a latitude and longitude represented by a `Location` object, and `double` values that represent the degrees of latitude and longitude that are spanned by the `MapSpan`. For information about the `Location` class, see [Location and distance](#location-and-distance).
@@ -287,6 +314,25 @@ Alternatively, there are three methods in the `MapSpan` class that return new `M
287314
1. `FromCenterAndRadius` returns a `MapSpan` that is defined by its `Location` and `Distance` arguments.
288315
1. `WithZoom` returns a `MapSpan` with the same center as the method's class instance, but with a radius multiplied by its `double` argument.
289316
317+
::: moniker range=">=net-maui-11.0"
318+
319+
In .NET 11, the `MapSpan` class also includes a `FromLocations` method that creates a `MapSpan` that encompasses all the specified locations with appropriate padding:
320+
321+
```csharp
322+
var locations = new[]
323+
{
324+
new Location(36.9628066, -122.0194722),
325+
new Location(37.7749295, -122.4194155),
326+
new Location(36.1699412, -115.1398296)
327+
};
328+
MapSpan span = MapSpan.FromLocations(locations);
329+
map.MoveToRegion(span);
330+
```
331+
332+
This is useful for implementing "best-fit zoom" scenarios where the map should display all pins or points of interest. The method handles edge cases such as antimeridian crossing.
333+
334+
::: moniker-end
335+
290336
For information about the `Distance` struct, see [Location and distance](#location-and-distance).
291337
292338
Once a `MapSpan` has been created, the following properties can be accessed to retrieve data about it:
@@ -311,6 +357,22 @@ MapSpan mapSpan = MapSpan.FromCenterAndRadius(location, Distance.FromKilometers(
311357
map.MoveToRegion(mapSpan);
312358
```
313359
360+
::: moniker range=">=net-maui-11.0"
361+
362+
In .NET 11, an overload of `MoveToRegion` accepts a `bool animated` parameter to control whether the map transition is animated:
363+
364+
```csharp
365+
// Move to region without animation (instant transition)
366+
map.MoveToRegion(mapSpan, animated: false);
367+
368+
// Move to region with animation (smooth transition, default behavior)
369+
map.MoveToRegion(mapSpan, animated: true);
370+
```
371+
372+
This is useful for setting an initial map region without the default fly-in animation.
373+
374+
::: moniker-end
375+
314376
### Zoom the map
315377
316378
The zoom level of a <xref:Microsoft.Maui.Controls.Maps.Map> can be changed without altering its location. This can be accomplished using the map UI, or programatically by calling the `MoveToRegion` method with a `MapSpan` argument that uses the current location as the `Location` argument:
@@ -407,6 +469,31 @@ Map map = new Map
407469
> [!IMPORTANT]
408470
> Accessing the user's location requires location permissions to have been granted to the application. For more information, see [Platform configuration](#platform-configuration).
409471
472+
::: moniker range=">=net-maui-11.0"
473+
474+
In .NET 11, when `IsShowingUser` is `true`, the map provides additional user location capabilities:
475+
476+
- The `UserLocationChanged` event fires whenever the user's location is updated on the map. The `UserLocationChangedEventArgs` contains a `Location` property with the updated coordinates.
477+
- The `LastUserLocation` property returns the most recent user location, or `null` if no location has been received yet.
478+
479+
```csharp
480+
Map map = new Map
481+
{
482+
IsShowingUser = true
483+
};
484+
485+
map.UserLocationChanged += (sender, args) =>
486+
{
487+
System.Diagnostics.Debug.WriteLine(
488+
$"User location: {args.Location.Latitude}, {args.Location.Longitude}");
489+
};
490+
491+
// Access the last known user location at any time
492+
Location? lastLocation = map.LastUserLocation;
493+
```
494+
495+
::: moniker-end
496+
410497
#### Map clicks
411498
412499
The <xref:Microsoft.Maui.Controls.Maps.Map> class defines a `MapClicked` event that's fired when the map is tapped. The `MapClickedEventArgs` object that accompanies the event has a single property named `Location`, of type `Location`. When the event is fired, the `Location` property is set to the map location that was tapped. For information about the `Location` class, see [Location and distance](#location-and-distance).
@@ -433,6 +520,40 @@ Map map = new Map();
433520
map.MapClicked += OnMapClicked;
434521
```
435522
523+
::: moniker range=">=net-maui-11.0"
524+
525+
In .NET 11, the <xref:Microsoft.Maui.Controls.Maps.Map> class defines additional interaction events:
526+
527+
##### Map long click
528+
529+
The `MapLongClicked` event is fired when the user performs a long press/hold gesture on the map. Like `MapClicked`, the event provides the location of the long press through `MapClickedEventArgs`:
530+
531+
```csharp
532+
map.MapLongClicked += (sender, args) =>
533+
{
534+
// Add a pin at the long-pressed location
535+
map.Pins.Add(new Pin
536+
{
537+
Label = "Dropped Pin",
538+
Location = args.Location
539+
});
540+
};
541+
```
542+
543+
##### Map element click
544+
545+
The `MapElementClick` event is fired when a user taps on a `Circle`, `Polygon`, or `Polyline` on the map. The `MapElementClickEventArgs` provides the tapped `MapElement`:
546+
547+
```csharp
548+
map.MapElementClick += (sender, args) =>
549+
{
550+
MapElement clickedElement = args.MapElement;
551+
System.Diagnostics.Debug.WriteLine($"Tapped a {clickedElement.GetType().Name}");
552+
};
553+
```
554+
555+
::: moniker-end
556+
436557
## Location and distance
437558
438559
The `Microsoft.Maui.Devices.Sensors` namespace contains a `Location` class that's typically used when positioning a map and its pins. The `Microsoft.Maui.Maps` namespace contains a `Distance` struct that can optionally be used when positioning a map.
@@ -503,6 +624,13 @@ The `Pin` class has the following properties:
503624
- `Location`, of type `Location`, which represents the latitude and longitude of the pin.
504625
- `Type`, of type `PinType`, which represents the type of pin.
505626
627+
::: moniker range=">=net-maui-11.0"
628+
629+
- `ImageSource`, of type `ImageSource`, which sets a custom image for the pin marker.
630+
- `ClusteringIdentifier`, of type `string`, which groups pins for clustering. Default is `"maui_default_cluster"`.
631+
632+
::: moniker-end
633+
506634
These properties are backed by <xref:Microsoft.Maui.Controls.BindableProperty> objects, which means a `Pin` can be the target of data bindings. For more information about data binding `Pin` objects, see [Display a pin collection](#display-a-pin-collection).
507635
508636
In addition, the `Pin` class defines `MarkerClicked` and `InfoWindowClicked` events. The `MarkerClicked` event is fired when a pin is tapped, and the `InfoWindowClicked` event is fired when the information window is tapped. The `PinClickedEventArgs` object that accompanies both events has a single `HideInfoWindow` property, of type `bool`.
@@ -669,6 +797,24 @@ wharfPin.InfoWindowClicked += async (s, args) =>
669797
670798
The `PinClickedEventArgs` object that accompanies both events has a single `HideInfoWindow` property, of type `bool`. When this property is set to `true` inside an event handler, the information window will be hidden.
671799
800+
::: moniker range=">=net-maui-11.0"
801+
802+
#### Show and hide info windows programmatically
803+
804+
In .NET 11, the `Pin` class includes `ShowInfoWindow` and `HideInfoWindow` methods for programmatic control of pin info windows:
805+
806+
```csharp
807+
// Show the info window for a specific pin
808+
pin.ShowInfoWindow();
809+
810+
// Hide the info window
811+
pin.HideInfoWindow();
812+
```
813+
814+
The pin must be added to a map before calling these methods. This is useful for scenarios where you want to automatically display a pin's info window without requiring the user to tap on it.
815+
816+
::: moniker-end
817+
672818
### Pin types
673819
674820
`Pin` objects include a `Type` property, of type `PinType`, which represents the type of pin. The `PinType` enumeration defines the following members:
@@ -680,6 +826,69 @@ The `PinClickedEventArgs` object that accompanies both events has a single `Hide
680826
681827
However, setting the `Pin.Type` property to any `PinType` member does not change the appearance of the rendered pin. Instead, you must customize the `Pin` handler to customize pin appearance. For more information about handler customization, see [Customize controls with handlers](~/user-interface/handlers/customize.md).
682828
829+
::: moniker range=">=net-maui-11.0"
830+
831+
### Custom pin icons
832+
833+
By default, pins use the platform's default marker image. In .NET 11, pins can display a custom image by setting the `ImageSource` property:
834+
835+
```csharp
836+
Pin pin = new Pin
837+
{
838+
Location = new Location(36.9628066, -122.0194722),
839+
Label = "Santa Cruz",
840+
ImageSource = ImageSource.FromFile("custom_pin.png")
841+
};
842+
```
843+
844+
Or in XAML:
845+
846+
```xaml
847+
<maps:Pin Location="36.9628066,-122.0194722"
848+
Label="Santa Cruz"
849+
ImageSource="custom_pin.png" />
850+
```
851+
852+
Any `ImageSource` type is supported, including file, URI, resource, and stream sources. The image is automatically scaled to the platform's default pin size.
853+
854+
### Pin clustering
855+
856+
When displaying many pins on a map, they can overlap and make the map difficult to read. Pin clustering automatically groups nearby pins into a single cluster marker. In .NET 11, you can enable clustering by setting the `IsClusteringEnabled` property:
857+
858+
```xaml
859+
<maps:Map IsClusteringEnabled="true" />
860+
```
861+
862+
The equivalent C# code is:
863+
864+
```csharp
865+
Map map = new Map
866+
{
867+
IsClusteringEnabled = true
868+
};
869+
```
870+
871+
When clustering is enabled, pins that are close together are automatically combined into a cluster marker that displays the count of grouped pins. As the user zooms in, clusters expand to reveal individual pins.
872+
873+
You can control which pins are grouped together by setting the `ClusteringIdentifier` property on `Pin`. Pins with the same identifier are grouped into the same cluster. The default value is `"maui_default_cluster"`.
874+
875+
The `ClusterClicked` event is raised when a cluster marker is tapped. The `ClusterClickedEventArgs` provides the list of pins in the cluster, the location of the cluster, and a `Handled` property to suppress the default zoom behavior:
876+
877+
```csharp
878+
map.ClusterClicked += (sender, args) =>
879+
{
880+
System.Diagnostics.Debug.WriteLine($"Cluster with {args.Pins.Count} pins tapped");
881+
882+
// Set Handled to true to prevent the default zoom-to-cluster behavior
883+
args.Handled = true;
884+
};
885+
```
886+
887+
> [!NOTE]
888+
> Pin clustering is supported on iOS, Mac Catalyst, and Android.
889+
890+
::: moniker-end
891+
683892
### Display a pin collection
684893
685894
The <xref:Microsoft.Maui.Controls.Maps.Map> class defines the following bindable properties:
@@ -797,6 +1006,31 @@ The `Polygon`, `Polyline`, and `Circle` classes derive from the `MapElement` cla
7971006
- `StrokeColor` is a <xref:Microsoft.Maui.Graphics.Color> object that determines the line color.
7981007
- `StrokeWidth` is a `float` object that determines the line width.
7991008
1009+
::: moniker range=">=net-maui-11.0"
1010+
1011+
In .NET 11, the `MapElement` class includes additional properties:
1012+
1013+
- `IsVisible`, of type `bool`, determines whether the map element is visible. Default is `true`. This allows hiding and showing map elements without removing them from the `MapElements` collection.
1014+
- `ZIndex`, of type `int`, controls the draw order of the map element. Elements with higher `ZIndex` values are drawn on top of elements with lower values. Default is `0`.
1015+
1016+
```csharp
1017+
Polygon polygon = new Polygon
1018+
{
1019+
StrokeColor = Colors.Blue,
1020+
FillColor = Color.FromArgb("#8800FF00"),
1021+
IsVisible = true,
1022+
ZIndex = 1
1023+
};
1024+
1025+
// Toggle visibility
1026+
polygon.IsVisible = false;
1027+
1028+
// Bring to front
1029+
polygon.ZIndex = 10;
1030+
```
1031+
1032+
::: moniker-end
1033+
8001034
The `Polygon` class defines an additional bindable property:
8011035
8021036
- `FillColor` is a <xref:Microsoft.Maui.Graphics.Color> object that determines the polygon's background color.
@@ -1000,6 +1234,39 @@ The location of the `Circle` on the Map is determined by the value of the `Cente
10001234
> [!NOTE]
10011235
> The `GeographyUtils` class has a `ToCircumferencePositions` extension method that converts a `Circle` object (that defines `Center` and `Radius` property values) to a list of `Location` objects that make up the latitude and longitude coordinates of the circle perimeter.
10021236
1237+
::: moniker range=">=net-maui-11.0"
1238+
1239+
## Map styling
1240+
1241+
In .NET 11, the `Map` control supports custom visual styling through the `MapStyle` property. On Android, this accepts a Google Maps JSON style string for customizing the appearance of map features such as roads, parks, water, and labels.
1242+
1243+
```csharp
1244+
Map map = new Map
1245+
{
1246+
MapStyle = """
1247+
[
1248+
{
1249+
"featureType": "water",
1250+
"elementType": "geometry.fill",
1251+
"stylers": [{ "color": "#0077be" }]
1252+
},
1253+
{
1254+
"featureType": "road",
1255+
"elementType": "geometry",
1256+
"stylers": [{ "color": "#ffffff" }]
1257+
}
1258+
]
1259+
"""
1260+
};
1261+
```
1262+
1263+
You can create custom styles using the [Google Maps Platform Styling Wizard](https://mapstyle.withgoogle.com/).
1264+
1265+
> [!IMPORTANT]
1266+
> Custom JSON map styling is only supported on Android. On iOS, Mac Catalyst, and Windows, the `MapStyle` property has no effect. Apple MapKit does not support custom JSON map styling.
1267+
1268+
::: moniker-end
1269+
10031270
## Geocoding and geolocation
10041271
10051272
The `Geocoding` class, in the `Microsoft.Maui.Devices.Sensors` namespace, can be used to geocode a placemark to positional coordinates and reverse geocode coordinates to a placemark. For more information, see [Geocoding](~/platform-integration/device/geocoding.md).

0 commit comments

Comments
 (0)