MapLibreNative.Maui 3.2.6

There is a newer version of this package available.
See the version list below for details.
dotnet add package MapLibreNative.Maui --version 3.2.6
                    
NuGet\Install-Package MapLibreNative.Maui -Version 3.2.6
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MapLibreNative.Maui" Version="3.2.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MapLibreNative.Maui" Version="3.2.6" />
                    
Directory.Packages.props
<PackageReference Include="MapLibreNative.Maui" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MapLibreNative.Maui --version 3.2.6
                    
#r "nuget: MapLibreNative.Maui, 3.2.6"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MapLibreNative.Maui@3.2.6
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MapLibreNative.Maui&version=3.2.6
                    
Install as a Cake Addin
#tool nuget:?package=MapLibreNative.Maui&version=3.2.6
                    
Install as a Cake Tool

maplibre-maui

License CI

.NET MAUI library for rendering interactive maps with MapLibre Native on Android, iOS, macCatalyst, and Windows.


Architecture

This library takes a pure C ABI approach rather than wrapping the platform-native MapLibre SDKs:

MapLibre Native (C++)
       │
       ▼
mln-cabi  (C++ native library — flat C ABI)
       │  P/Invoke
       ▼
MapLibreNative.Maui  (C# typed wrappers: MbglMap, MbglStyle, MbglFrontend …)
       │
       ▼
MapLibreNative.Maui.Handlers  (MAUI controls, handlers, sources, layers)

The mln-cabi native library is compiled per-platform:

Platform Renderer CI
Android OpenGL ES (EGL + ANativeWindow) native-android.yml
Android Vulkan native-android-vulkan.yml
iOS / macCatalyst Metal (MTKView) native-apple.yml
Windows OpenGL (WGL) native-windows.yml
Windows Vulkan native-windows-vulkan.yml

MapLibre Native is included as a git submodule at dependencies/maplibre-native.


Getting Started

Add the map to a page

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:maplibre="clr-namespace:Maui.MapLibre.Handlers;assembly=MapLibreNative.Maui.Handlers"
             xmlns:layers="clr-namespace:Maui.MapLibre.Handlers.Layers;assembly=MapLibreNative.Maui.Handlers"
             xmlns:sources="clr-namespace:Maui.MapLibre.Handlers.Sources;assembly=MapLibreNative.Maui.Handlers"
             x:Class="MyApp.MainPage">

    <maplibre:MapLibreMap StyleUrl="https://demotiles.maplibre.org/style.json"
                          MyLocationEnabled="True">

        
        <sources:GeoJsonSource SourceName="my-source" FeatureCollection="{Binding GeoJson}" />
        <layers:LineLayer SourceName="my-source"
                          LayerName="my-line"
                          Properties="{Binding LineProperties}" />
    </maplibre:MapLibreMap>

</ContentPage>

Register the handler in MauiProgram.cs

using Maui.MapLibre.Handlers;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMaui()
            .ConfigureMauiHandlers(handlers =>
            {
                handlers.AddMapLibreHandlers();
            });
        return builder.Build();
    }
}

MapLibreMap Properties

Property Type Description
StyleUrl string MapLibre style URL or inline JSON
MinZoom float Minimum zoom level
MaxZoom float Maximum zoom level
MyLocationEnabled bool Show user location dot
MyLocationTrackingMode int Location tracking mode
MyLocationRenderMode int Location indicator render mode
RotateGesturesEnabled bool Enable rotation gesture
ScrollGesturesEnabled bool Enable pan gesture
TiltGesturesEnabled bool Enable pitch gesture
ZoomGesturesEnabled bool Enable pinch-to-zoom
CompassEnabled bool Show compass

Events (as ICommand bindable properties)

Property Fired when
MapReadyCommand Native map is initialised
StyleLoadedCommand Style has finished loading
DidBecomeIdleCommand Map has finished all pending operations
CameraMoveCommand Camera is moving
CameraIdleCommand Camera has stopped
MapClickCommand User taps the map (LatLng)
MapLongClickCommand User long-presses the map (LatLng)
UserLocationUpdateCommand Device location has changed

Sources

Declare sources as child elements of MapLibreMap, or add them programmatically via the controller.

XAML type Description
GeoJsonSource Inline GeoJSON FeatureCollection or URL
VectorSource Vector tile URL or TileJSON
RasterSource Raster tile URL or TileJSON
RasterDemSource Raster DEM tile source (for hillshade)
ImageSource Image overlay bound to LatLngQuad coordinates
<sources:GeoJsonSource SourceName="points" FeatureCollection="{Binding PointsJson}" />
<sources:VectorSource SourceName="roads" TileUrl="https://example.com/tiles.json" />

Layers

Declare layers as child elements of MapLibreMap. Each layer references a SourceName and accepts a Properties dictionary of MapLibre style paint/layout properties.

XAML type MapLibre layer type
FillLayer fill
LineLayer line
CircleLayer circle
SymbolLayer symbol
RasterLayer raster
HeatmapLayer heatmap
FillExtrusionLayer fill-extrusion
HillshadeLayer hillshade
ColorReliefLayer color-relief
<layers:FillLayer SourceName="polygons"
                  LayerName="polygons-fill"
                  Properties="{Binding FillProperties}" />

<layers:LineLayer SourceName="roads"
                  LayerName="roads-line"
                  SourceLayer="transportation"
                  Properties="{Binding LineProperties}" />

Property dictionaries

Properties are a IDictionary<string, object?> mapping MapLibre style property names to values or expressions:

public IDictionary<string, object?> LineProperties => new Dictionary<string, object?>
{
    ["line-color"] = "#e55e5e",
    ["line-width"] = 3.0,
};

Camera

Use the controller (obtained from MapReadyCommand or StyleLoadedCommand) to manipulate the camera:

// Instant jump
controller.JumpTo(latitude: 51.5, longitude: -0.1, zoom: 12);

// Animated ease
controller.EaseTo(51.5, -0.1, zoom: 14, bearing: 0, pitch: 45, durationMs: 800);

// Animated fly-to
controller.FlyTo(51.5, -0.1, zoom: 14, bearing: 0, pitch: 0, durationMs: 1500);

// Fit bounds with padding
controller.SetBounds(latSw: 51.4, lonSw: -0.2, latNe: 51.6, lonNe: 0.0);

// Coordinate conversion
var (x, y) = controller.PixelForLatLng(51.5, -0.1);
var (lat, lon) = controller.LatLngForPixel(x, y);

Feature Queries

// Query features at a tapped screen position
string? geojson = controller.QueryRenderedFeaturesAtPoint(x, y, layerIds: "my-layer");

// Query features in a bounding box
string? geojson = controller.QueryRenderedFeaturesInBox(x1, y1, x2, y2);

The return value is a GeoJSON FeatureCollection string, or null if the renderer is not ready.


Feature State

Per-feature state lets you change the visual appearance of individual features (e.g. hover effects) without re-loading the style:

// Set state — stateJson is a JSON object
controller.SetFeatureState(sourceId: "my-source", featureId: "123", stateJson: "{\"hover\":true}");

// With an explicit source layer (required for vector tile sources)
controller.SetFeatureState("my-source", "123", "{\"hover\":true}", sourceLayerId: "my-layer");

// Read state back (returns JSON string or null)
string? state = controller.GetFeatureState("my-source", "123");

// Remove a single state key
controller.RemoveFeatureState("my-source", featureId: "123", stateKey: "hover");

// Remove all state for a feature
controller.RemoveFeatureState("my-source", featureId: "123");

// Remove all state for every feature in a source
controller.RemoveFeatureState("my-source");

Viewport Bounds

// Get the lat-lng bounding box of the current camera view
var (latSW, lonSW, latNE, lonNE) = controller.GetVisibleBounds();

Memory Management

// Ask the renderer to release cached GPU resources
controller.ReduceMemoryUse();

// Write renderer diagnostics to the log
controller.DumpDebugLogs();

Generic JSON Sources and Layers

In addition to the typed XAML source/layer elements you can add sources and layers from raw MapLibre style-spec JSON:

// Add any source type by spec JSON
controller.AddSourceJson("my-source",
    "{\"type\":\"geojson\",\"data\":{\"type\":\"FeatureCollection\",\"features\": []}}");

// Add any layer type by spec JSON
controller.AddLayerJson(
    "{\"id\":\"my-fill\",\"type\":\"fill\",\"source\":\"my-source\"," +
    "\"paint\":{\"fill-color\":\"#ff0000\",\"fill-opacity\":0.5}}");

// Insert before an existing layer
controller.AddLayerJson(layerJson, beforeLayerId: "labels");

Style & Layer Inspection

Once a style is loaded, you can inspect and modify it via the controller:

// Enumerate the loaded style
string   url     = controller.GetStyleUrl();
string[] sources = controller.GetStyleSourceIds();
string[] layers  = controller.GetStyleLayerIds();

// Read layer properties (returns JSON-encoded value, or null if not set)
string? color = controller.GetLayerPaintProperty("my-layer", "line-color");
string? vis   = controller.GetLayerLayoutProperty("my-layer", "visibility");

// Show / hide a layer
bool visible = controller.GetLayerVisibility("my-layer");
controller.SetLayerVisibility("my-layer", !visible);

Debug Overlays

MapLibre Native has built-in debug overlays controlled by a bitmask:

// Enable tile borders + collision boxes
controller.SetDebugOptions(0x02 | 0x10);

// Read current state
int current = controller.GetDebugOptions();

// Disable all
controller.SetDebugOptions(0);

The MbglDebugOptions enum in MapLibreNative.Maui names the individual bits (TileBorders, ParseStatus, Timestamps, Collision, Overdraw, StencilClip, DepthBuffer).


WPF Usage

For WPF apps (not MAUI), use MlnMapHost from MapLibreNative.Maui.WPF:

xmlns:mlwpf="clr-namespace:Maui.MapLibre.WPF;assembly=MapLibreNative.Maui.WPF"

<mlwpf:MlnMapHost x:Name="MapHost"
                  StyleUrl="https://demotiles.maplibre.org/style.json"
                  ShowNavigationControls="True"
                  MapReady="MapHost_MapReady"
                  StyleLoaded="MapHost_StyleLoaded"
                  CameraIdle="MapHost_CameraIdle" />

MlnMapHost is a HwndHost that owns a child HWND rendered with OpenGL (WGL). It supports the same camera, source, layer, and query operations as the MAUI handler. See sample/WpfExample for a full working example.


Building from Source

Prerequisites

  • .NET 9 SDK
  • CMake ≥ 3.21
  • Android: Android NDK r26+, ANDROID_NDK env var set
  • Apple: Xcode 15+, macOS host
  • Windows: Visual Studio 2022 with C++ workload

Clone with submodules

git clone --recurse-submodules https://github.com/acalcutt/maplibre-maui.git

Or if you already cloned without submodules:

git submodule update --init --recursive

Build native library

Each platform's CI workflow documents the exact CMake invocation. The native build output (libmln-cabi.so / libmln-cabi.a / mln-cabi.dll) must be placed under bindings/ before packing.

# Example: Windows
cmake -B build/windows -DCMAKE_BUILD_TYPE=Release
cmake --build build/windows --config Release

Build and run the sample

dotnet build sample/MauiSample.csproj -f net9.0-android

License

This project is BSD 2-Clause licensed — see LICENSE.

Dependency License Notes
MapLibre Native BSD 2-Clause Linked natively via mln-cabi
maplibre-native-ffi BSD 2-Clause Reference only — no code included; project structure and C ABI conventions (typed handles, status codes, log callback) informed the design of mln-cabi
Original maplibre-maui by Benjamin Trounson MIT Portions adapted
Product Compatible and additional computed target framework versions.
.NET net9.0-android35.0 is compatible.  net9.0-ios18.0 is compatible.  net9.0-maccatalyst18.0 is compatible.  net9.0-windows10.0.19041 is compatible.  net10.0-android was computed.  net10.0-android36.0 is compatible.  net10.0-ios was computed.  net10.0-ios26.0 is compatible.  net10.0-maccatalyst was computed.  net10.0-maccatalyst26.0 is compatible.  net10.0-windows was computed.  net10.0-windows10.0.19041 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0-android36.0

    • No dependencies.
  • net10.0-ios26.0

    • No dependencies.
  • net10.0-maccatalyst26.0

    • No dependencies.
  • net10.0-windows10.0.19041

    • No dependencies.
  • net9.0-android35.0

    • No dependencies.
  • net9.0-ios18.0

    • No dependencies.
  • net9.0-maccatalyst18.0

    • No dependencies.
  • net9.0-windows10.0.19041

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on MapLibreNative.Maui:

Package Downloads
MapLibreNative.Maui.Handlers

Package Description

MapLibreNative.Maui.WPF

WPF map control (MlnMapImage) backed by MapLibre Native (mln-cabi). Renders the map as an ordinary in-tree WPF Image — no HwndHost, no airspace — for WPF applications without requiring a MAUI dependency. MapLibreNative.Maui is pulled in automatically as a dependency.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.5.1 0 8/28/2026
4.5.0 162 7/16/2026
4.4.0 155 7/13/2026
4.2.2 128 7/12/2026
4.2.1 151 7/11/2026
4.2.0 153 7/10/2026
4.1.3 166 7/9/2026
4.1.2 136 7/7/2026
4.1.0 217 7/5/2026
4.0.0 125 7/5/2026
3.2.10 157 6/30/2026
3.2.9 155 6/29/2026
3.2.8 202 6/25/2026
3.2.7 125 6/25/2026
3.2.6 121 6/23/2026
3.2.5 145 6/22/2026
3.2.4 114 6/22/2026
3.2.3 131 6/20/2026
3.2.2 113 6/20/2026
3.2.1 121 6/20/2026
Loading failed