pmtiles

package
v1.147.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package pmtiles reads and writes PMTiles version 3 archives, and extracts the part of one that covers a bounding box and a zoom range (#2068).

It exists rather than github.com/protomaps/go-pmtiles because the platform fetches a basemap through its own HTTP client (internal/outbound, so the fetch is traced and counted) and writes the result straight into object storage. go-pmtiles' Extract opens its source with http.DefaultClient and writes to a local file path, and its one package imports the Google Cloud, Azure and SQLite SDKs. The format is small: a 127-byte header, varint directories, and tile data addressed by Hilbert tile id.

The specification is https://github.com/protomaps/PMTiles/blob/main/spec/v3/spec.md.

Index

Constants

View Source
const HeaderLen = 127

HeaderLen is the fixed size of a version 3 header.

View Source
const MaxZoom = 15

MaxZoom is the deepest zoom an extract may ask for. Tile ids are uint64 and the specification allows deeper, but no basemap is built past 15 and the cover's work grows with the zoom.

View Source
const RootFetchLen = 16384

RootFetchLen is how much of an archive holds its header and root directory: the specification requires both inside the first 16 KiB, so one read of this length answers both.

Variables

View Source
var ErrNoOverlap = errors.New("pmtiles: the requested area or zooms are not in the source archive")

ErrNoOverlap is returned when the request's box or zooms share nothing with the source archive.

View Source
var ErrNotPMTiles = errors.New("pmtiles: not a PMTiles version 3 archive")

ErrNotPMTiles is returned for bytes that do not begin a version 3 archive.

Functions

func DecodeMetadata

func DecodeMetadata(raw []byte, c Compression) (map[string]any, error)

DecodeMetadata decodes an archive's metadata section.

func SerializeDirectory

func SerializeDirectory(entries []Entry, c Compression) ([]byte, error)

SerializeDirectory encodes entries, which must be in tile id order, under the given internal compression.

func ZxyToID

func ZxyToID(z uint8, x, y uint32) uint64

ZxyToID returns the tile id of tile (z, x, y): the tiles of every shallower zoom, then the tile's position along the zoom's Hilbert curve.

Types

type Bounds

type Bounds struct {
	MinLon float64 `json:"min_lon"`
	MinLat float64 `json:"min_lat"`
	MaxLon float64 `json:"max_lon"`
	MaxLat float64 `json:"max_lat"`
}

Bounds is a bounding box in degrees.

func (Bounds) Intersect

func (b Bounds) Intersect(o Bounds) (Bounds, bool)

Intersect returns the overlap of two boxes and whether there is one.

func (Bounds) Validate

func (b Bounds) Validate() error

Validate refuses a box that is not one: out of range, or with a minimum that is not below its maximum. A box crossing the antimeridian is two boxes.

type Compression

type Compression uint8

Compression is the compression of an archive's directories, metadata or tiles.

const (
	CompressionUnknown Compression = 0
	CompressionNone    Compression = 1
	CompressionGzip    Compression = 2
	CompressionBrotli  Compression = 3
	CompressionZstd    Compression = 4
)

The compressions the specification defines.

type Entry

type Entry struct {
	TileID    uint64
	Offset    uint64
	Length    uint32
	RunLength uint32
}

Entry is one directory entry. RunLength 0 marks a pointer to a leaf directory, whose Offset is relative to the archive's leaf section; otherwise Offset is relative to the tile data section and the entry addresses RunLength consecutive tile ids holding the same content.

func ParseDirectory

func ParseDirectory(data []byte, c Compression) ([]Entry, error)

ParseDirectory decodes one directory as stored, under the archive's internal compression.

type Header struct {
	RootOffset          uint64
	RootLength          uint64
	MetadataOffset      uint64
	MetadataLength      uint64
	LeafOffset          uint64
	LeafLength          uint64
	TileDataOffset      uint64
	TileDataLength      uint64
	AddressedTiles      uint64
	TileEntries         uint64
	TileContents        uint64
	Clustered           bool
	InternalCompression Compression
	TileCompression     Compression
	TileType            TileType
	MinZoom             uint8
	MaxZoom             uint8
	MinLonE7            int32
	MinLatE7            int32
	MaxLonE7            int32
	MaxLatE7            int32
	CenterZoom          uint8
	CenterLonE7         int32
	CenterLatE7         int32
}

Header is a version 3 header. Bounds and center are in degrees times 10^7, as the format stores them.

func ParseHeader

func ParseHeader(b []byte) (Header, error)

ParseHeader reads the header from the first HeaderLen bytes of an archive.

func (Header) Bounds

func (h Header) Bounds() Bounds

Bounds returns the header's bounds in degrees.

func (Header) Bytes

func (h Header) Bytes() []byte

Bytes serializes the header.

type Plan

type Plan struct {
	// contains filtered or unexported fields
}

Plan is an extract whose directories are built and whose size is known, and whose tile data has not yet been copied. Planning reads the source's header, metadata and the directories that address the requested tiles; writing reads the tiles.

func NewPlan

func NewPlan(ctx context.Context, src Source, req Request) (*Plan, error)

NewPlan reads what an extract of src needs to know before its tiles are copied.

func (*Plan) Header

func (p *Plan) Header() Header

Header returns the header the extract will be written with.

func (*Plan) Metadata

func (p *Plan) Metadata() (map[string]any, error)

Metadata returns the source archive's metadata, decoded: the JSON object the format stores, which for a Protomaps build carries its attribution, schema version and OpenStreetMap replication time.

func (*Plan) Size

func (p *Plan) Size() uint64

Size returns the extract's size in bytes.

func (*Plan) WriteTo

func (p *Plan) WriteTo(ctx context.Context, src Source, w io.Writer, progress func(written uint64)) error

WriteTo writes the extract to w: the header, directories and metadata, then every tile content copied from src in the extract's order. progress, when set, is called with the bytes written so far after each read is written.

type Range

type Range struct {
	Start uint64
	End   uint64
}

Range is a half-open run of tile ids, [Start, End).

func Cover

func Cover(b Bounds, minZoom, maxZoom uint8) []Range

Cover returns the tile ids a box touches at every zoom from minZoom to maxZoom, as sorted, merged ranges.

A Hilbert curve visits each quadtree cell's tiles consecutively, so a cell entirely inside the box is one range, and the cover recurses only along the box's edge: the number of ranges grows with the box's perimeter in tiles, not its area.

type Request

type Request struct {
	Bounds  Bounds
	MinZoom uint8
	MaxZoom uint8
}

Request names the part of an archive an extract keeps.

type Source

type Source interface {
	ReadRange(ctx context.Context, offset, length uint64) ([]byte, error)
}

Source reads byte ranges of an archive. A read past the end returns what there is.

type TileType

type TileType uint8

TileType is the format of an archive's tiles.

const (
	TileTypeUnknown TileType = 0
	TileTypeMVT     TileType = 1
	TileTypePNG     TileType = 2
	TileTypeJPEG    TileType = 3
	TileTypeWebP    TileType = 4
	TileTypeAVIF    TileType = 5
)

The tile types the specification defines.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL