Skip to content
EpistatesPublic

About

Rust toolkit for OpenStreetMap PBF parsing, spatial indexing, vector tile generation, rendering, and serving.

Topics

Resources

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Repository files navigation

osmic

Crates.io docs.rs License: MIT MSRV 1.94

OpenStreetMap to vector tiles in Rust, plus the pieces around it: reading PBF with exact coordinates, assembling multipolygons, classifying features, generating PMTiles archives, serving them, keeping the source data current from replication diffs, extracting entities, and rendering with MapLibre styles.

Status: 0.2.x, pre-1.0 — APIs may still change. See CHANGELOG.md.

What it does

  • Tiles from any extract up to the planet's scale, in bounded memory. Features are rendered while the PBF is read (each feature projected once, simplified per zoom, sliced into tiles by recursive band clipping) and spilled to a parallel external sort; tiles are then assembled, encoded and gzipped in parallel. Memory is set by --memory-mb, not by the input.
  • Exact data. Node locations keep OSM's 1e-7° precision; a sparse node index needs about 9 bytes per node. Multipolygons and boundaries are assembled the way libosmium does it (role-agnostic rings, exact point-in-ring nesting, touching rings split, invalid and incomplete relations counted and reported).
  • Reproducible archives. PMTiles output is Hilbert-ordered (clustered), byte-for-byte identical across runs and thread counts, written atomically, and its metadata lists the layers and fields actually present. Tiles over the size budget drop their least important features first.
  • Serving. An HTTP server with strong ETags, gzip passthrough, CORS, timeouts, load shedding, graceful shutdown, health probes, TileJSON, a MapLibre style and a built-in viewer.
  • Staying current. osmic update applies minutely/hourly/daily diffs from any replication server to a PBF file (pyosmium-up-to-date model: state lives in the PBF header, files are replaced atomically).
  • Styling and rendering. A typed MapLibre style subset with an expression evaluator, a software renderer (tiny-skia), lyon tessellation, collision-aware labels and a wgpu viewer.

Performance

United States extract (10.8 GB PBF, 1.51 billion nodes, 152 million ways) to a z0–14 archive, on a 16-core Apple Silicon machine with 128 GB of RAM that was otherwise heavily loaded during the run:

Wall time 5 min 43 s
CPU time 22.6 min
Peak memory 23 GB (13.1 GiB of it the node index)
Features 163,084,065
Tiles 4,508,486 (11.5 GiB)

Command line

cargo install osmic-cli          # installs the `osmic` binary
# Vector tiles (all layers, z0-14) plus a MapLibre style for them
osmic generate-tiles region.osm.pbf region.pmtiles --style style.json

# Only some layers or zooms, or only features matching a tag filter
osmic generate-tiles region.osm.pbf roads.pmtiles --layers highway --zoom 6-14
osmic generate-tiles region.osm.pbf cafes.pmtiles --tags "amenity=cafe"

# Serve with a map viewer at http://127.0.0.1:3000/
osmic serve region.pmtiles

# Element counts, features per layer and data-quality report
osmic inspect region.osm.pbf

# Businesses and POIs to CSV, JSON or GeoJSON
osmic extract region.osm.pbf shops.csv --tags "shop=* office=*"

# Apply replication diffs (the PBF header carries the replication state)
osmic update region.osm.pbf

Every command has --help. Outputs are never overwritten without --force; usage errors exit with code 2 and runtime errors with code 1; --log-format json emits structured logs.

Layers: highway, building, water, natural, landuse, railway, amenity, leisure, boundary, place, shop, tourism, office, healthcare, craft, historic, club, emergency, education.

Library

Use the umbrella crate, or depend on individual crates:

[dependencies]
osmic = "0.2"

Stream a PBF file into a PMTiles archive:

use std::path::Path;
use std::sync::Arc;

use osmic::osm::{PbfProcessor, PipelineConfig, TagRetention, TagStore};
use osmic::tiles::{ArchiveInfo, MvtEncoder, TileGenerator, TileGeneratorConfig};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let tags = Arc::new(TagStore::new());
    let tiles = TileGenerator::new(
        TileGeneratorConfig::default(),
        Box::new(MvtEncoder),
        Arc::clone(&tags),
    )?;
    let config = PipelineConfig::new().tag_retention(TagRetention::Curated);
    // Features go straight from the PBF reader into the tile renderer.
    PbfProcessor::with_tag_store(config, tags).run(Path::new("region.osm.pbf"), &tiles)?;
    let summary = tiles.write_pmtiles(Path::new("region.pmtiles"), &ArchiveInfo::default(), false)?;
    println!("{} tiles", summary.tiles);
    Ok(())
}

Or compose an application from plugins, here a tile server:

use osmic::prelude::*;

fn main() -> Result<(), AppError> {
    // Serve a PMTiles archive (with a MapLibre viewer at /) until Ctrl-C.
    App::new()
        .add_plugin(TileServerPlugin::new("tiles.pmtiles"))
        .run()
}
Crate Description
osmic Umbrella: re-exports and prelude
osmic-core Fixed-precision coordinates, typed OSM ids, geometry, Web Mercator, clipping, simplification
osmic-osm PBF reading and writing, classification, multipolygon assembly, the two-pass feature pipeline
osmic-index Node location storage: sparse index and dense (memory or file) store
osmic-geo Projection, simplification and ring orientation helpers
osmic-tiles Tile rendering, external sort, MVT/MLT encoding and decoding, PMTiles archives
osmic-serve HTTP tile server
osmic-repl Replication: change-file parsing and keeping PBF files current
osmic-extract Entity extraction with tag filters, locations and deduplication
osmic-style Typed MapLibre style subset (parser, expression evaluator) and the default osmic style
osmic-render Style-driven scene building, software renderer, lyon tessellation, Mercator camera
osmic-text Shaping, collision-aware label placement, line labels
osmic-app Plugins, typed resources, events and a runner
osmic-accel Opt-in Metal (Apple Silicon) geometry clipping with a CPU reference
osmic-cli The osmic command
osmic-viewer Interactive wgpu map viewer for PMTiles archives

The examples/ directory has runnable programs:

cargo run --release -p load-pbf -- region.osm.pbf
cargo run --release -p render-static -- region.pmtiles map.png --bbox -122.52,37.70,-122.35,37.82
cargo run --release -p tile-server -- region.pmtiles --bind 127.0.0.1:3000
cargo run -p custom-plugin
cargo run --release -p osmic-viewer -- region.pmtiles

Optional features

  • osmic-cli/mlt, osmic-tiles/mlt: MapLibre Tile (MLT) output. Needs Rust 1.98, above the workspace MSRV.
  • osmic-osm/native (enabled by the binaries): PBF reading. Without it, osmic-osm provides only the data model, without osmpbf or rayon.

Building

cargo build --workspace
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings

The minimum supported Rust version is 1.94. See CONTRIBUTING.md for the full check list and SECURITY.md for reporting vulnerabilities.

License

MIT, see LICENSE. Map data © OpenStreetMap contributors, available under the ODbL.

About

Rust toolkit for OpenStreetMap PBF parsing, spatial indexing, vector tile generation, rendering, and serving.

Topics

Resources

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages