MapLibre Compose

repository·main·Indexed 19 days ago

https://github.com/maplibre/maplibre-compose

A Compose Multiplatform wrapper for MapLibre SDKs that enables interactive map rendering across Android, iOS, Desktop, and Web. The desktop implementation utilizes a Native FFI architecture requiring Java 25 and supports Vulkan (Linux, Windows) and Metal (macOS) backends. It includes a Desktop Host SPI for custom graphics integration, a dedicated threading model for graphics contexts, and support for offline map packs.

Tokens
8.5K
Snippets
20
Records
46
Agent score
67%

What's inside MapLibre Compose

  1. Introduction to MapLibre for Compose Multiplatform

    main
    MapLibre Compose is a Compose Multiplatform wrapper around the MapLibre SDKs. It allows developers to integrate interactive maps into Compose-based user interfaces across multiple platforms, including Android, iOS, Desktop, and Web.
  2. Overview of MapLibre Compose Multiplatform

    main

    MapLibre Compose is a Compose Multiplatform wrapper around the MapLibre SDKs. It allows developers to integrate interactive maps into Compose-based user interfaces across multiple platforms.

    Supported Platforms:

    • Android: Uses MapLibre Native.
    • iOS: Uses MapLibre Native.
    • Desktop (JVM): Uses MapLibre Native.
    • Web (JS): Uses MapLibre GL JS.
    • Web (Wasm): Currently not supported.
  3. Current platform support and roadmap

    main

    MapLibre Compose currently provides support for Android and iOS.

    Development is actively working towards parity for other platforms. Key upcoming features include:

    • Desktop Parity: Support for macOS, Windows, and Linux (via Kotlin JVM bindings to MapLibre Native).
    • JS Parity: Support for Compose apps in the browser using Kotlin JS (backed by MapLibre GL JS).
    • WASM Parity: Support for Compose apps in the browser using Kotlin WASM.

    Note that features like programmatic layer styling, offline management, and platform location services may vary in availability depending on the target platform and its current development status.

  4. Use the core MapLibre Compose APIs

    main

    The library is organized into the following functional areas:

    • Core Map Components: Use org.maplibre.compose.map for the primary map composable and its fundamental components.
    • Camera Control: Use org.maplibre.compose.camera to manage camera positioning, movement, and utilities.
    • Offline Management: Use org.maplibre.compose.offline to handle offline map data and caching strategies.
    • Layers and Sources: Use org.maplibre.compose.layers and org.maplibre.compose.sources to declaratively add map layers and data sources to your map view.
    • Map Expressions: For styling and data-driven logic, use the expression system:
      • DSL (Recommended): Use org.maplibre.compose.expressions.dsl as your primary API for creating MapLibre expressions using a Kotlin DSL.
      • AST: Use org.maplibre.compose.expressions.ast to interact with the underlying Abstract Syntax Tree.
      • Value System: Use org.maplibre.compose.expressions.value to access the type system, interfaces, and enums that define expression values.
  5. Manage Map Styles, Sources, and Layers via FFI

    main

    The Desktop implementation uses a generic JSON style API.

    Source Objects

    Sources act as live descriptors:

    • Before attachment: They store the source ID, type, data, and options.
    • After attachment: Mutable operations call the FFI immediately on the owner thread.
    • Supported types: GeoJSON, vector, raster, raster DEM, image, and custom/computed sources.

    Layer Objects

    Layers store ID, type, source ID, source layer, zoom range, visibility, filter, layout properties, and paint properties.

    • Before attachment: Setters update the descriptor. Adding a layer emits one complete layer JSON object.
    • After attachment: Setters use setLayerProperty, setLayerFilter, and layer move/remove APIs.

    Images

    To add images, convert Compose ImageBitmap pixels to tightly packed premultiplied RGBA8 and use setStyleImage. Note that ImageResizeOptions (stretch metadata) are currently a known limitation in the FFI boundary.

  6. Desktop MapLibre Native FFI Architecture Overview

    main

    The desktop implementation of MapLibre for Compose Multiplatform is transitioning from a JNI-based architecture to a Native FFI (Foreign Function Interface) architecture. This rewrite requires Java 25 as the minimum runtime for desktop compilation, execution, and packaging.

    Key architectural components include:

    • Host SPI (Service Provider Interface): A public interface that allows the default Skiko host to be replaced by alternative hosts (e.g., a compose-glfw fixture).
    • DesktopMapSession: Manages the runtime pumping, event translation, camera operations, frame scheduling, and teardown.
    • Native Render Paths: Supports Linux Vulkan, Windows Vulkan, and macOS Metal via FFI.
    • Resource Boundary: Uses a specific runtime resource boundary for loading Compose resources.
  7. How location tracking and visualization work in MapLibre Compose

    main

    Location support is composed of three main functional parts that work together to track and visualize user position:

    1. Providers: Collect raw data. rememberDefaultLocationProvider provides GPS/position data, and rememberDefaultOrientationProvider provides sensor-based orientation data.
    2. LocationPuck: A visual component that draws the user's current position and bearing on the map.
    3. LocationTrackingEffect: A Composable effect used to subscribe to updates and optionally keep the camera in sync with the user's movement or orientation.

    Note on Platforms: Android and iOS include default providers. On Desktop and Web, you must supply a custom LocationProvider or OrientationProvider as the defaults will throw an error.

  8. Check platform support and progress

    main
    Support levels vary by platform. Android and iOS currently have the most complete support (approximately 90%), while Web (20%) and Desktop (15%) are still in development. Before starting a project, verify the current status of specific features on your target platform in the official status table.
  9. Manage camera bearing with LocationTrackingEffect

    main

    The LocationTrackingEffect controls how the camera rotates in response to location and orientation updates. You can choose from several bearing update modes:

    Bearing update modeCamera behavior
    IGNOREKeep the current camera bearing.
    ALWAYS_NORTHReset the camera to north.
    TRACK_COURSERotate the camera with the user's direction of movement.
    TRACK_ORIENTATIONRotate the camera with the device orientation.
    TRACK_AUTOMATICUse the more accurate course or orientation measurement.

    Note that LocationPuck(bearing = ...) only rotates the visual indicator on the map, whereas LocationTrackingEffect controls the actual camera rotation.

  10. Understand the Desktop Host Integration SPI

    main

    MapLibre Compose provides a Desktop Host SPI in org.maplibre.compose.desktop that allows applications to replace the default Skiko-based graphics integration with a custom host. This is useful for providing custom GPU contexts or render-target access (e.g., using compose-glfw).

    Key SPI Concepts

    • DesktopMapHostFactory: Reports supported backend combinations and creates a host surface.
    • DesktopMapHost: Owns host graphics objects and provides a composable drawing surface.
    • DesktopMapFrame: Describes a renderable target (extent, scale factor, timestamp, etc.).
    • DesktopRenderTarget: Provides backend-neutral wrappers around native handles.
    • DesktopMapRenderer: Handles surface availability, extent changes, and frames.
    • LocalDesktopMapHostFactory: A CompositionLocal used to provide the host factory. The default implementation is the Skiko host.

    By providing a custom implementation of these interfaces, you can decouple MapLibre's map behavior from the specific Compose host used.