maplibre-rs

repository·main·Indexed 23 days ago

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

A portable and performant vector map rendering library written in Rust. It leverages WebGPU to target web, mobile, and desktop platforms (Linux, Android, iOS, macOS) with a single codebase. Key capabilities include rendering vector tile datasets, multithreading support, and feature data querying.

Tokens
26.9K
Snippets
53
Records
146
Agent score
81%

What's inside maplibre-rs

  1. Overview of maplibre-rs capabilities

    main

    maplibre-rs is a portable, high-performance vector map renderer written in Rust. It uses WebGPU to provide cross-platform support across Web, Mobile, and Desktop (Linux, Android, iOS, macOS).

    Current Capabilities

    • Rendering vector tile datasets.
    • Simple navigation (powered by winit).
    • Multithreading support on all platforms.
    • Querying feature data.

    Limitations & Missing Features

    • Rendering: Does not yet support Text, Labels, Symbols, Raster data, 3D terrain, or Hill-shade (DEM).
    • Data: No support for GeoJSON or per-feature rendering.
    • Interoperability: No official APIs for TypeScript, Swift, or Java/Kotlin yet.
    • Collision: Collision detection is not yet implemented.
  2. Packaging maplibre-rs for the Web

    main

    When packaging maplibre-rs as an npm package, several requirements must be met to ensure compatibility with modern web environments:

    • WASM Bundling: The WebAssembly binary must be accessible to users.
    • WebWorker Bundling/Inlining: WebWorkers must be available, either as separate files or inlined as strings.
    • Predictable Paths: Assets must be at predictable locations so users can reference them directly from node_modules if necessary.
    • ESM Support: The standard module format is preferred as it allows bundlers to resolve WebAssembly files and WebWorkers dynamically using import.meta.url.

    Resolving Assets in ESM

    To resolve WebWorkers or WASM files in an ESM module, use the following syntax:

    // Resolving a WebWorker
    new Worker(new URL("./multithreaded-pool.worker.ts", import.meta.url), {
        type: 'module'
    });
    
    // Resolving a WASM file
    new URL('index_bg.wasm', import.meta.url);
  3. Understand maplibre-rs Apple packaging formats

    main

    On Apple platforms, maplibre-rs is distributed in three ways:

    1. Multiple .xcarchive packages: Each package contains a framework for a specific architecture and platform.
    2. A single .xcframework package: A unified package containing multiple frameworks for different architectures and platforms.
    3. A Swift Package: A wrapper that references the .xcframework package to simplify distribution.
  4. Profile frames using the Tracy profiler

    main

    maplibre-rs uses the Tracy profiler for frame profiling. The integration connects Tracy to the Rust tracing crate via the rust_tracy_client project (comprising tracing-tracy, tracy-client, and tracy-client-sys).

    Note that Tracy does not follow semantic versioning, so you must ensure the versions of the Rust client crates match the specific version of the Tracy binary you are running.

  5. Understand font rendering approaches in maplibre-rs

    main

    Because no single font rendering solution is perfect for all environments, maplibre-rs considers several different architectural approaches. When choosing or implementing a rendering path, consider the following methods:

    1. Tessellate Fonts: Converting glyphs into meshes (e.g., using tools like ttf2mesh). This allows for high-performance rendering but requires generating geometry for glyphs.
    2. SDF (Signed Distance Field) Font Rendering: Using Signed Distance Fields to represent glyphs. This is a common technique in map engines (like Mapbox GL) that allows for sharp text at various scales. Tools like msdfgen are often used as a foundation.
    3. GPU Text Rendering from Bezier Curves: Rendering text directly from vector data on the GPU. This provides high fidelity but is mathematically complex. Examples include implementations like gllabel or the (patented) Slug library algorithm.
    4. Web Canvas Rendering: Drawing text onto a Web Canvas and then uploading the resulting texture to the GPU. This is simpler but lacks the ability to dynamically scale fonts based on zoom levels without re-rendering.
  6. How caching works in maplibre-rs

    main

    Caching in maplibre-rs is implemented at the networking layer rather than through a custom serialization format. The library caches data in the same format as the original network requests. This approach allows the library to honor standard HTTP headers (such as expiry dates), which is critical for managing tile expiration.

    Caching behavior depends on the target platform:

    • Web: Relies on the browser's native automatic caching of raw tiles.
    • Linux, macOS, iOS, and Android: Utilizes the reqwest-middleware-cache crate to write raw network requests to disk.
  7. Using maplibre-rs via IIFE (Script Tags)

    main

    The IIFE (immediately-invoked function expression) format is used when including maplibre-rs directly in a <script> tag for quick prototyping or playgrounds.

    In this mode, the library is attached to the window or global object. Because there is no active bundler to manage assets, you must ensure that the WASM file and any non-inlined WebWorkers are deployed at a predictable path. Users may need to manually specify the location of these assets.

  8. Package an .xcframework

    main

    You can create an .xcframework by combining multiple frameworks using xcodebuild.

    Note on Fat Binaries: You cannot bundle multiple architectures for the same platform (e.g., macOS-arm64 and macOS-x86_64) directly into an .xcframework. For these cases, you must first create a fat binary using lipo, then package the resulting framework.

    Steps for Fat Binaries:

    1. Create a fat binary: lipo -create binA binB -output binfat
    2. Copy the fat binary into a new framework and manually add the .swiftmodule definitions from the original architectures.
    xargs xcodebuild -create-xcframework -framework ./a -framework ./b -output out.xcframework
  9. Set up the Rust environment for maplibre-rs

    main
    The project requires the Rust toolchain. It is recommended to install rustup to manage toolchains. The specific toolchain required by this project is defined in the ./rust-toolchain.toml file and will be automatically downloaded when you build the project.