PMTiles¶
This module provides a pure Java implementation of the PMTiles v3 specification, a single-file archive format for cloud-optimized tiled data.
This library is focused on efficient, cloud-optimized reading of PMTiles archives. For creating archives, use one of the existing tools such as pmtiles or Tippecanoe.
Features¶
- Cloud-Optimized Reads: Range-based access tuned for archives served from object storage.
- Storage Agnostic: Works with any
RangeReaderbackend fromtileverse-storage(S3, HTTP, Local File, Azure Blob, GCS). - Spatial Indexing: Implements Hilbert curve indexing for O(log N) tile lookups.
- Vector and Raster Tiles:
PMTilesReaderreturns the raw tile bytes for any tile type (MVT, PNG, JPEG, WebP, AVIF). For decoded results, the higher-levelPMTilesVectorTileStorereturns parsedVectorTileobjects andPMTilesRasterTileStorereturns decodedjava.awt.image.RenderedImages. WebP decoding is enabled by default through a bundledImageIOplugin.
Core concepts¶
A PMTiles archive contains three regions:
- Header: tileset metadata (bounds, zoom levels, tile format, compression).
- Directory: spatial index built on the Hilbert space-filling curve.
- Tiles: the compressed tile bodies.
Tiles are addressed with the standard XYZ scheme: zoom level, column (west to east), and row (top to bottom in PMTiles' XYZ-with-top-left convention). The tileType byte in the header tells you whether the bodies are MVT, PNG, JPEG, WebP, or AVIF; PMTilesHeader.tileMimeType() and isRasterTileType() give a convenient view of the same.
PMTiles archives can hold either Mapbox Vector Tiles or raster tiles in any of those formats. PMTilesReader.getTile(...) returns raw bytes for either case; the high-level PMTilesVectorTileStore and PMTilesRasterTileStore wrappers decode on the fly to VectorTile and RenderedImage respectively. WebP decoding is bundled - no extra ImageIO plugin needed. See the Tile Stores Reference for the API surface.
Installation¶
<dependency>
<groupId>io.tileverse.pmtiles</groupId>
<artifactId>tileverse-pmtiles</artifactId>
</dependency>
Usage¶
The PMTilesReader accepts either a RangeReader or a Supplier<SeekableByteChannel>. The RangeReader can provide this via its asByteChannel() method.
import io.tileverse.pmtiles.PMTilesHeader;
import io.tileverse.pmtiles.PMTilesReader;
import java.nio.file.Path;
try (PMTilesReader reader = PMTilesReader.open(Path.of("data/map.pmtiles").toUri())) {
// Get metadata
PMTilesHeader header = reader.getHeader();
System.out.println("Min Zoom: " + header.minZoom());
// Fetch tile (z, x, y)
reader.getTile(0, 0, 0).ifPresent(buffer -> {
buffer.flip(); // Important: flip the buffer before reading
// Process tile bytes...
});
}
Component view¶
PMTilesReader is the low-level type: it reads the header, walks the directory using HilbertCurve for index lookup, and returns raw tile bytes (or streams them through a caller-supplied IOFunction). PMTilesVectorTileStore and PMTilesRasterTileStore are higher-level wrappers built on PMTilesReader that decode tiles to VectorTile and RenderedImage respectively. See the Tile Stores Reference for the full API surface.