Crate pmtiles

Source
Expand description

§PMTiles (for Rust)

GitHub crates.io version docs.rs docs crates.io version CI build Codecov

This crate implements the PMTiles v3 spec, originally created by Brandon Liu for Protomaps.

§Features

  • Opening and validating PMTile archives
  • Querying tiles
  • Backends supported:
    • Async mmap (Tokio) for local files
    • Async http and https (Reqwest + Tokio) for URLs
    • Async s3 (Rust-S3 + Tokio) for S3-compatible buckets
  • Creating PMTile archives

§Plans & TODOs

  • Documentation and example code
  • Support conversion to and from MBTiles + x/y/z
  • Support additional backends (sync mmap and http at least)
  • Support additional async styles (e.g., async-std)

PRs welcome!

§Usage examples

§Reading from a local PMTiles file

use bytes::Bytes;
use pmtiles::async_reader::AsyncPmTilesReader;

async fn get_tile(z: u8, x: u64, y: u64) -> Option<Bytes> {
  let file = "example.pmtiles";
  // Use `new_with_cached_path` for better performance
  let reader = AsyncPmTilesReader::new_with_path(file).await.unwrap();
  reader.get_tile(z, x, y).await.unwrap()
}

§Reading from a URL with a simple directory cache

This example uses a simple hashmap-based cache to optimize reads from a PMTiles source. The same caching is available for all other methods. Note that HashMapCache is a rudimentary cache without eviction. You may want to build a more sophisticated cache for production use by implementing the DirectoryCache trait.

use bytes::Bytes;
use pmtiles::async_reader::AsyncPmTilesReader;
use pmtiles::cache::HashMapCache;
use pmtiles::reqwest::Client;  // Re-exported Reqwest crate

async fn get_tile(z: u8, x: u64, y: u64) -> Option<Bytes> {
  let cache = HashMapCache::default();
  let client = Client::builder().use_rustls_tls().build().unwrap();
  let url = "https://protomaps.github.io/PMTiles/protomaps(vector)ODbL_firenze.pmtiles";
  let reader = AsyncPmTilesReader::new_with_cached_url(cache, client, url).await.unwrap();
  reader.get_tile(z, x, y).await.unwrap()
}

§Reading from an S3 bucket with a directory cache

AWS client configuration is fairly none-trivial to document here. See AWS SDK documentation for more details.

use bytes::Bytes;
use pmtiles::async_reader::AsyncPmTilesReader;
use pmtiles::aws_sdk_s3::Client; // Re-exported AWS SDK S3 client
use pmtiles::cache::HashMapCache;

async fn get_tile(client: Client, z: u8, x: u64, y: u64) -> Option<Bytes> {
  let cache = HashMapCache::default();
  let bucket = "https://s3.example.com".to_string();
  let key = "example.pmtiles".to_string();
  let reader = AsyncPmTilesReader::new_with_cached_client_bucket_and_path(cache, client, bucket, key).await.unwrap();
  reader.get_tile(z, x, y).await.unwrap()
}

§Writing to a PMTiles file

use pmtiles::{PmTilesWriter, TileType};
use std::fs::File;

let file = File::create("example.pmtiles").unwrap();
let mut writer = PmTilesWriter::new(TileType::Mvt).create(file).unwrap();
writer.add_tile(0, 0, 0, &[/*...*/]).unwrap();
writer.finalize().unwrap();

§Development

  • This project is easier to develop with just, a modern alternative to make. Install it with cargo install just.
  • To get a list of available commands, run just.
  • To run tests, use just test.

§License

Licensed under either of

§Test Data License

Some PMTile fixtures copied from official PMTiles repository.

§Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Re-exports§

pub use aws_sdk_s3;
pub use reqwest;
pub use s3;
pub use tilejson;

Modules§

async_reader
cache

Structs§

AwsS3Backend
DirEntry
Directory
Header
HttpBackend
MmapBackend
PmTilesStreamWriter
PMTiles streaming writer.
PmTilesWriter
Builder for creating a new writer.
S3Backend

Enums§

Compression
PmtError
Errors that can occur while reading PMTiles files.
TileType

Type Aliases§

PmtResult
A specialized Result type for PMTiles operations.