Zooming and Panning in .NET MAUI Maps

15 Jul 202624 minutes to read

You can zoom in and out on any layer to take a closer look at a specific region by pinching the map or scrolling the mouse wheel or trackpad. Pan the map to navigate across the regions. You can also customize the zoom level of the rendering.

The procedure for zooming and panning for both layers is very similar.

NOTE

Prerequisite: Ensure that the required NuGet package is installed, the necessary namespaces are imported, and the SfMaps control is properly configured in your application. For detailed setup and configuration instructions, refer to the Getting Started guide.

To learn more about the .NET MAUI Maps zoom and pan, you can check the following video.

Shape layer

<map:SfMaps>
     <map:SfMaps.Layer>
         <map:MapShapeLayer ShapesSource = "https://cdn.syncfusion.com/maps/map-data/world-map.json">
              <map:MapShapeLayer.ZoomPanBehavior>
                 <map:MapZoomPanBehavior ZoomLevel = "1" />
              </map:MapShapeLayer.ZoomPanBehavior>
         </map:MapShapeLayer>
     </map:SfMaps.Layer>
 </map:SfMaps>
SfMaps maps = new SfMaps();
MapShapeLayer layer = new MapShapeLayer();
layer.ShapesSource = MapSource.FromUri(new Uri("https://cdn.syncfusion.com/maps/map-data/world-map.json"));
MapZoomPanBehavior zoomPanBehavior = new MapZoomPanBehavior();
zoomPanBehavior.ZoomLevel = 1;
layer.ZoomPanBehavior = zoomPanBehavior;
maps.Layer = layer;
this.Content = maps;

Tile layer

<map:SfMaps>
    <map:SfMaps.Layer>
        <map:MapTileLayer UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png">
              <map:MapTileLayer.ZoomPanBehavior>
                 <map:MapZoomPanBehavior ZoomLevel = "1" />
              </map:MapTileLayer.ZoomPanBehavior>
        </map:MapTileLayer>
    </map:SfMaps.Layer>
</map:SfMaps>
SfMaps map = new SfMaps();
MapTileLayer tileLayer = new MapTileLayer();
tileLayer.UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
MapZoomPanBehavior zoomPanBehavior = new MapZoomPanBehavior();
zoomPanBehavior.ZoomLevel = 1;
tileLayer.ZoomPanBehavior = zoomPanBehavior;
map.Layer = tileLayer;
this.Content = map;

Default view in .NET MAUI Maps

Customizing the zoom level

You can set the zoom level of the map layer by using the MapZoomPanBehavior.ZoomLevel property.

The default MapZoomPanBehavior.ZoomLevel value is 1, which will show the whole map in the viewport for both MapTileLayer and MapShapeLayer.

<map:SfMaps>
   <map:SfMaps.Layer>
        <map:MapTileLayer UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png" >
              <map:MapTileLayer.Center>
                  <map:MapLatLng Latitude = "27.1751"
                                 Longitude = "78.0421">
                  </map:MapLatLng>
              </map:MapTileLayer.Center>
              <map:MapTileLayer.ZoomPanBehavior>
                  <map:MapZoomPanBehavior ZoomLevel = "5" />
              </map:MapTileLayer.ZoomPanBehavior>
        </map:MapTileLayer>
   </map:SfMaps.Layer>
</map:SfMaps>
SfMaps map = new SfMaps();
MapTileLayer tileLayer = new MapTileLayer();
tileLayer.UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
tileLayer.Center = new MapLatLng(27.1751, 78.0421);
MapZoomPanBehavior zoomPanBehavior = new MapZoomPanBehavior();
zoomPanBehavior.ZoomLevel = 5;
tileLayer.ZoomPanBehavior = zoomPanBehavior;
map.Layer = tileLayer;
this.Content = map;

Zoom level in .NET MAUI Maps

Enable zooming

The zooming feature enables you to zoom in and zoom out the maps to show in-depth information. To enable zooming, set the EnableZooming property to true. The default value of the EnableZooming is true.

<map:SfMaps>
   <map:SfMaps.Layer>
        <map:MapTileLayer UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png" >
              <map:MapTileLayer.ZoomPanBehavior>
                  <map:MapZoomPanBehavior ZoomLevel = "2" EnableZooming = "True" />
              </map:MapTileLayer.ZoomPanBehavior>
        </map:MapTileLayer>
   </map:SfMaps.Layer>
</map:SfMaps>
SfMaps map = new SfMaps();
MapTileLayer tileLayer = new MapTileLayer();
tileLayer.UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
MapZoomPanBehavior zoomPanBehavior = new MapZoomPanBehavior();
zoomPanBehavior.ZoomLevel = 2;
zoomPanBehavior.EnableZooming = true;
tileLayer.ZoomPanBehavior = zoomPanBehavior;
map.Layer = tileLayer;
this.Content = map;

Enable panning

The panning feature allows you to move the visible area of the maps when it is zoomed in. To enable panning, set the EnablePanning property to true. The default value of the EnablePanning is true.

NOTE

It is applicable for both tile layer and shape layer.

<map:SfMaps>
   <map:SfMaps.Layer>
        <map:MapTileLayer UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png" >
              <map:MapTileLayer.ZoomPanBehavior>
                  <map:MapZoomPanBehavior ZoomLevel = "2" EnablePanning = "True"/>
              </map:MapTileLayer.ZoomPanBehavior>
        </map:MapTileLayer>
   </map:SfMaps.Layer>
</map:SfMaps>
SfMaps map = new SfMaps();
MapTileLayer tileLayer = new MapTileLayer();
tileLayer.UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
MapZoomPanBehavior zoomPanBehavior = new MapZoomPanBehavior();
zoomPanBehavior.ZoomLevel = 2;
zoomPanBehavior.EnablePanning = true;
tileLayer.ZoomPanBehavior = zoomPanBehavior;
map.Layer = tileLayer;
this.Content = map;

Customizing min and max zoom level

You can set the min and max zoom level of the map layer by setting the value to MapZoomPanBehavior.MinZoomLevel and MapZoomPanBehavior.MaxZoomLevel properties. The minimum and maximum zooming levels can be restricted using these properties, respectively. The default values of MapZoomPanBehavior.MinZoomLevel and MapZoomPanBehavior.MaxZoomLevel are 1 and 15, respectively.

However, for MapTileLayer, the MapZoomPanBehavior.MaxZoomLevel may vary slightly depending on the providers. Kindly check the respective official website of the map tile providers to know about the maximum zoom level it supports.

<map:SfMaps>
   <map:SfMaps.Layer>
        <map:MapTileLayer UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png" >
              <map:MapTileLayer.Center>
                  <map:MapLatLng Latitude = "27.1751"
                                 Longitude = "78.0421">
                  </map:MapLatLng>
              </map:MapTileLayer.Center>
              <map:MapTileLayer.ZoomPanBehavior>
                  <map:MapZoomPanBehavior ZoomLevel = "5" 
                                          MinZoomLevel = "3"
                                          MaxZoomLevel = "10" />
              </map:MapTileLayer.ZoomPanBehavior>
        </map:MapTileLayer>
   </map:SfMaps.Layer>
</map:SfMaps>
SfMaps map = new SfMaps();
MapTileLayer tileLayer = new MapTileLayer();
tileLayer.UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
tileLayer.Center = new MapLatLng(27.1751, 78.0421);
MapZoomPanBehavior zoomPanBehavior = new MapZoomPanBehavior();
zoomPanBehavior.ZoomLevel = 5;
zoomPanBehavior.MinZoomLevel = 3;
zoomPanBehavior.MaxZoomLevel = 10;
tileLayer.ZoomPanBehavior = zoomPanBehavior;
map.Layer = tileLayer;
this.Content = map;

Calculate a zoom level based on map geo-bounds or distance

This feature is used to calculate the zoom level automatically in two ways:

  • Distance in radius (Meter/Kilometer/Mile)
  • Geo-bounds (Northeast, Southwest)

Distance in radius

Calculate the zoom level automatically based on the Radius and DistanceType properties of the MapTileLayer class.

NOTE

The DistanceType property default value is Kilometer. The MapDistanceType enum has the following values: Meter, Kilometer (default), and Mile.

<ContentPage.Resources>
    <ResourceDictionary>
        <DataTemplate x:Key = "MapMarkerTemplate">
            <VerticalStackLayout HorizontalOptions = "StartAndExpand"
                         VerticalOptions = "Center">
                <Image Source = "map.png"
                       Scale = "1"
                       Aspect = "AspectFit"
                       HorizontalOptions = "StartAndExpand"
                       VerticalOptions = "Center"
                       HeightRequest = "35"
                       WidthRequest = "25" />
            </VerticalStackLayout>
        </DataTemplate>
    </ResourceDictionary>
</ContentPage.Resources>

<map:SfMaps>
    <map:SfMaps.Layer>
        <map:MapTileLayer Radius = "5"
                           DistanceType = "Kilometer"
                           MarkerTemplate = "{StaticResource MapMarkerTemplate}"
                           UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png">
            
            <map:MapTileLayer.Center>
                <map:MapLatLng Latitude = "38.909804"
                                Longitude = "-77.043442">
                </map:MapLatLng>
            </map:MapTileLayer.Center>
            
            <map:MapTileLayer.ZoomPanBehavior>
                <map:MapZoomPanBehavior ZoomLevel = "1" />
            </map:MapTileLayer.ZoomPanBehavior>
            
            <map:MapTileLayer.Markers>
                <map:MapMarkerCollection>
                    <map:MapMarker Latitude = "38.909804"
                                    Longitude = "-77.043442" />
                </map:MapMarkerCollection>
            </map:MapTileLayer.Markers>
        </map:MapTileLayer>
    </map:SfMaps.Layer>
</map:SfMaps>
public LatLngBoundsPage()
{
	InitializeComponent();
    SfMaps map = new SfMaps();
    MapTileLayer tileLayer = new MapTileLayer();
    tileLayer.UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
    tileLayer.Radius = 5;
    tileLayer.DistanceType = MapDistanceType.Kilometer;
    MapZoomPanBehavior zoomPanBehavior = new MapZoomPanBehavior();
    zoomPanBehavior.ZoomLevel = 1;
    tileLayer.Center = new MapLatLng(38.909804, -77.043442);
    tileLayer.ZoomPanBehavior = zoomPanBehavior;
    MapMarker mapMarker = new MapMarker();
    mapMarker.Latitude = 38.909804;
    mapMarker.Longitude = -77.043442;
    MapMarkerCollection mapMarkers = new MapMarkerCollection();
    mapMarkers.Add(mapMarker);
    tileLayer.Markers = mapMarkers;
    tileLayer.MarkerTemplate = CreateDataTemplate();
    map.Layer = tileLayer;
    this.Content = map;
}
private DataTemplate CreateDataTemplate()
{
    return new DataTemplate(() =>
    {
        var stackLayout = new VerticalStackLayout();
        stackLayout.HorizontalOptions = LayoutOptions.StartAndExpand;
        stackLayout.VerticalOptions = LayoutOptions.Center;
        var image = new Image
        {
            Source = "map.png",
            Scale = 1,
            Aspect = Aspect.AspectFit,
            WidthRequest = 25,
            HeightRequest = 35,
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        };
        stackLayout.Add(image);
        return new ViewCell { View = stackLayout };
    });
}

Zoom level changed in .NET MAUI Maps

NOTE

The map.png image used in the marker template must be added to your project (for example, in the Resources/Images/ folder) and referenced as Source = "map.png".

Geo-bounds

Calculate the zoom level automatically based on the MapTileLayer.LatLngBounds property (Northeast and Southwest coordinates) of the MapTileLayer class.

<ContentPage.Resources>
    <ResourceDictionary>
        <DataTemplate x:Key = "MapMarkerTemplate">
            <VerticalStackLayout HorizontalOptions = "StartAndExpand"
                         VerticalOptions = "Center">
                <Image Source = "map.png"
                       Scale = "1"
                       Aspect = "AspectFit"
                       HorizontalOptions = "StartAndExpand"
                       VerticalOptions = "Center"
                       HeightRequest = "35"
                       WidthRequest = "25" />
            </VerticalStackLayout>
        </DataTemplate>
    </ResourceDictionary>
</ContentPage.Resources>
    
   <map:SfMaps>
    <map:SfMaps.Layer>
        <map:MapTileLayer MarkerTemplate = "{StaticResource MapMarkerTemplate}"
                           UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png">
            <map:MapTileLayer.ZoomPanBehavior>
                <map:MapZoomPanBehavior MaxZoomLevel = "19" />
            </map:MapTileLayer.ZoomPanBehavior>
            <map:MapTileLayer.Markers>
                <map:MapMarkerCollection>
                    <map:MapMarker Latitude = "38.909804"
                                    Longitude = "-77.043442" />
                    <map:MapMarker Latitude = "38.909148"
                                    Longitude = "-77.043610" />
                </map:MapMarkerCollection>
            </map:MapTileLayer.Markers>
            <map:MapTileLayer.LatLngBounds>
                <map:MapLatLngBounds>
                    <map:MapLatLngBounds.Northeast>
                        <map:MapLatLng>
                            <x:Arguments>
                                <x:Double>38.909804</x:Double>
                                <x:Double>-77.043442</x:Double>
                            </x:Arguments>
                        </map:MapLatLng>
                    </map:MapLatLngBounds.Northeast>
                    <map:MapLatLngBounds.Southwest>
                        <map:MapLatLng>
                            <x:Arguments>
                                <x:Double>38.909148</x:Double>
                                <x:Double>-77.043610</x:Double>
                            </x:Arguments>
                        </map:MapLatLng>
                    </map:MapLatLngBounds.Southwest>
                </map:MapLatLngBounds>
            </map:MapTileLayer.LatLngBounds>
        </map:MapTileLayer>
    </map:SfMaps.Layer>
</map:SfMaps>
public LatLngBoundsPage()
{
	InitializeComponent();
    SfMaps map = new SfMaps();
    MapTileLayer tileLayer = new MapTileLayer();
    tileLayer.UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
    MapZoomPanBehavior zoomPanBehavior = new MapZoomPanBehavior();
    zoomPanBehavior.MaxZoomLevel = 19;
    tileLayer.ZoomPanBehavior = zoomPanBehavior;
    MapMarker mapMarker = new MapMarker();
    mapMarker.Latitude = 38.909804;
    mapMarker.Longitude = -77.043442;
    MapMarker mapMarker1 = new MapMarker();
    mapMarker1.Latitude = 38.909148;
    mapMarker1.Longitude = -77.043610;
    MapMarkerCollection mapMarkers = new MapMarkerCollection();
    mapMarkers.Add(mapMarker);
    mapMarkers.Add(mapMarker1);
    tileLayer.Markers = mapMarkers;
    tileLayer.MarkerTemplate = CreateDataTemplate();
    MapLatLngBounds bounds = new MapLatLngBounds();
    bounds.Northeast = new MapLatLng(38.909804, -77.043442);
    bounds.Southwest = new MapLatLng(38.909148, -77.043610);
    tileLayer.LatLngBounds = bounds;
    map.Layer = tileLayer;
    this.Content = map;
}

private DataTemplate CreateDataTemplate()
{
    return new DataTemplate(() =>
    {
        var stackLayout = new VerticalStackLayout();
        stackLayout.HorizontalOptions = LayoutOptions.StartAndExpand;
        stackLayout.VerticalOptions = LayoutOptions.Center;
        var image = new Image
        {
            Source = "map.png",
            Scale = 1,
            Aspect = Aspect.AspectFit,
            WidthRequest = 25,
            HeightRequest = 35,
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        };
        stackLayout.Add(image);
        return new ViewCell { View = stackLayout };
    });
}

NOTE

When setting LatLngBounds and DistanceType at the same time, the priority is Radius and so the zoom level is calculated based on the radius value. If neither Radius nor LatLngBounds is set, the zoom level is determined by the MapZoomPanBehavior.ZoomLevel property.

Zoom level changed based on geo-bounds in .NET MAUI Maps

Double tap zooming

Double tap zooming can be enabled using EnableDoubleTapZooming property. The default value of the EnableDoubleTapZooming is false.

NOTE

It is applicable for both tile layer and shape layer.

<map:SfMaps>
    <map:SfMaps.Layer>
        <map:MapTileLayer UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png">
            <map:MapTileLayer.ZoomPanBehavior>
                <map:MapZoomPanBehavior ZoomLevel = "2" EnableDoubleTapZooming = "True"/>
            </map:MapTileLayer.ZoomPanBehavior>
        </map:MapTileLayer>
    </map:SfMaps.Layer>
</map:SfMaps>
SfMaps map = new SfMaps();
MapTileLayer tileLayer = new MapTileLayer();
tileLayer.UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
MapZoomPanBehavior zoomPanBehavior = new MapZoomPanBehavior();
zoomPanBehavior.ZoomLevel = 2;
zoomPanBehavior.EnableDoubleTapZooming = true;
tileLayer.ZoomPanBehavior = zoomPanBehavior;
map.Layer = tileLayer;
this.Content = map;

Double tap zooming in .NET MAUI Maps

Animation

Zoom level animation

To perform the animation on zoom level changing using the MapTileLayer.EnableZoomingAnimation property. The default value of the EnableZoomingAnimation is true.

NOTE

It is applicable for both tile layer and shape layer.

<map:SfMaps>
    <map:SfMaps.Layer>
        <map:MapTileLayer UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
                          EnableZoomingAnimation = "True" >
        </map:MapTileLayer>
    </map:SfMaps.Layer>
</map:SfMaps>
SfMaps map = new SfMaps();
MapTileLayer tileLayer = new MapTileLayer();
tileLayer.UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
tileLayer.EnableZoomingAnimation = true;
map.Layer = tileLayer;
this.Content = map;

Zoom animation in .NET MAUI Maps

Center animation

To perform the animation on center value changing using the MapTileLayer.EnableCenterAnimation property. The default value of the EnableCenterAnimation is true.

NOTE

It is applicable only for tile layer.

<map:SfMaps>
    <map:SfMaps.Layer>
        <map:MapTileLayer UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
                          EnableCenterAnimation = "True" >
        </map:MapTileLayer>
    </map:SfMaps.Layer>
</map:SfMaps>
SfMaps map = new SfMaps();
MapTileLayer tileLayer = new MapTileLayer();
tileLayer.UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
tileLayer.EnableCenterAnimation = true;
map.Layer = tileLayer;
this.Content = map;

Center animation in .NET MAUI Maps

Event

Zoom level changing event

The ZoomLevelChanging event triggers when the zoom level is changing. It is applicable for both tile layer and shape layer. The following arguments can be obtained from the ZoomLevelChanging event.

  • Cancel : Used to cancel the zooming.
  • OldZoomLevel : Returns the previous level before the zooming.
  • NewZoomLevel : Returns the current level to be zoomed.
<map:SfMaps>
    <map:SfMaps.Layer>
        <map:MapTileLayer UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
                          ZoomLevelChanging = "MapTileLayer_ZoomLevelChanging" />
    </map:SfMaps.Layer>
</map:SfMaps>
SfMaps map = new SfMaps();
MapTileLayer tileLayer = new MapTileLayer();
tileLayer.UrlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
tileLayer.ZoomLevelChanging += MapTileLayer_ZoomLevelChanging;
map.Layer = tileLayer;
this.Content = map;

private void MapTileLayer_ZoomLevelChanging(object sender, ZoomLevelChangingEventArgs e)
{
    if (e.OldZoomLevel == 10) // Returns the previous zoom level
    {
        e.Cancel = true; // Cancels the zooming event
        var newZoomLevel = e.NewZoomLevel; // Returns the current zoomed level
    }
}

NOTE

You can refer to our .NET MAUI Maps feature tour page for its groundbreaking feature representations. You can also explore our .NET MAUI Maps Zoom & Pan example that shows how to configure Maps in .NET MAUI.