András Tóth‘s professional blog
banditoth.net

Hey there 👋, I’m banditoth a .NET MAUI developer from Hungary.
I write about software development with .NET technologies.

You can find me on:
LinkedIn | Github | StackOverflow | X / Twitter | Threads

Tag: maps

  • Customizing .NET MAUI Map’s pin Z-Order, Rotation, and Anchor point – Android

    This post will build upon the excellent tutorial on customizing map pins in .NET MAUI by Vladislav Antonyuk, and focus on adding these specific adjustments for Android.

    • Z-order: This determines the drawing order of the pins. Pins with higher Z-order values appear on top of those with lower values.
    • Rotation: Controls the rotation angle of the pin in degrees.
    • Anchor: Defines the point on the pin image that corresponds to the pin’s location on the map. The anchor is defined in terms of a normalized coordinate system where (0, 0) is the top-left corner and (1, 1) is the bottom-right corner of the image.

    Define the Anchor Points enum, get a method to return anchor floats

    We start by defining an enum to represent the different anchor points. A helper method, GetAnchorPoint, will return the appropriate anchor coordinates based on the chosen enum value.

    public enum AnchorPointType
    {
        TopLeft,
        TopCenter,
        TopRight,
        Center,
        BottomLeft,
        BottomCenter,
        BottomRight,
        LeftCenter,
        RightCenter
    }
    

    This method returns the normalized coordinates for each anchor point, which can then be applied to the pin’s icon.

    private static (float, float) GetAnchorPoint(AnchorPointType anchor)
    {
        return anchor switch
        {
            AnchorPointType.TopLeft => (0.0f, 0.0f),
            AnchorPointType.TopCenter => (0.5f, 0.0f),
            AnchorPointType.TopRight => (1.0f, 0.0f),
            AnchorPointType.Center => (0.5f, 0.5f),
            AnchorPointType.BottomLeft => (0.0f, 1.0f),
            AnchorPointType.BottomCenter => (0.5f, 1.0f),
            AnchorPointType.BottomRight => (1.0f, 1.0f),
            AnchorPointType.LeftCenter => (0.0f, 0.5f),
            AnchorPointType.RightCenter => (1.0f, 0.5f),
            _ => (0.5f, 0.5f)  // Default to center if undefined
        };
    }
    

    Modifications to the Custom Map Handler

    Now, let’s focus on the custom map handler, where you’ll need to modify how each pin is added to the map. Following the setup from Vladislav’s tutorial, you only need to adjust the following parts in the OnMapReady method for Android:

    cp.ImageSource.LoadImage(MauiContext, result =>
    {
        if (result?.Value is BitmapDrawable bitmapDrawable)
        {
            var originalBitmap = bitmapDrawable.Bitmap;
    
            // Set the custom icon for the pin
            markerOption.SetIcon(BitmapDescriptorFactory.FromBitmap(originalBitmap));
    
            // Set the rotation of the pin
            markerOption.SetRotation((float)cp.Rotation);
    
            // Set the anchor of the pin based on the chosen AnchorPointType
            var anchor = GetAnchorPoint(cp.Anchor);
            markerOption.Anchor(anchor.Item1, anchor.Item2);
    
            // Set the Z-order to bring this pin to the top
            markerOption.InvokeZIndex(cp.ZOrder);
        }
    
        AddMarker(Map, pin, Markers, markerOption);
    });
    
    
  • Disabling Map Zoom Controls and Other Buttons in .NET MAUI Android

    In this post, we’ll guide you through the process of disabling these UI elements (zoom controls, compass, and location buttons) in your Android map implementation using a custom map handler. This approach gives you more control over the user experience and map functionality in your mobile app.

    Creating a Custom Map Handler

    To disable these controls, we need to customize how the map is rendered on Android. This involves creating a custom map handler that intercepts the way the map is displayed and adjusts its settings.

    A detailed tutorial for creating custom map handlers can be found in this great guide by Vladislav Antonyuk. We will extend that concept here.

    First, we need to implement a MapCallbackHandler that disables specific controls when the map is ready. This is done in the OnMapReady method, which is triggered when the map is fully loaded and ready for interaction.

    using Android.Gms.Maps;
    using Android.Gms.Maps.Model;
    using Microsoft.Maui.Handlers;
    using Microsoft.Maui.Controls.Compatibility.Maps.Android;
    
    class MapCallbackHandler : Java.Lang.Object, IOnMapReadyCallback
    {
        private readonly IMapHandler mapHandler;
    
        public MapCallbackHandler(IMapHandler mapHandler)
        {
            this.mapHandler = mapHandler;
        }
    
        public void OnMapReady(GoogleMap googleMap)
        {
            // Update map with any pins or map state changes
            mapHandler.UpdateValue(nameof(IMap.Pins));
            
            // Disable zoom controls
            googleMap.UiSettings.ZoomControlsEnabled = false;
            
            // Disable the "My Location" button
            googleMap.UiSettings.MyLocationButtonEnabled = false;
            
            // Disable the compass
            googleMap.UiSettings.CompassEnabled = false;
    
            // Additional settings can be adjusted here, such as disabling tilt or gestures.
        }
    }
    
    

    In the OnMapReady method, we access the googleMap.UiSettings property, which contains several settings that control the map’s UI. In our example, we set the following to false:

    • ZoomControlsEnabled: Disables the zoom buttons.
    • MyLocationButtonEnabled: Removes the My Location button that appears when location services are enabled.
    • CompassEnabled: Hides the compass that appears when the user rotates the map.

    You can also adjust other settings here, such as disabling tilt gestures or zoom gestures if needed.