Skip to content

VersaTiles Container Format Specification v2.0

1. Preamble

This document defines the VersaTiles Container Format v2.0, which describes the structure and encoding mechanisms for efficiently storing large numbers of map tiles.

2. General Guidelines

  • Byte order: All numeric values are encoded in big-endian byte order.
  • Tile organisation: Tiles are organised according to the XYZ scheme, with the origin (x=0, y=0) at the top left (northwest) corner.

3. File Structure

The VersaTiles container format consists of four main components:

  1. File Header: Introduces the container file, details its global properties, and indicates the locations of the Metadata and Block Index.
  2. Metadata: Provides detailed information about the tileset, including attribution and layer definitions.
  3. Blocks: Aggregates tiles into larger units (Blocks) for efficient storage and access, each containing Tile Blobs and Tile Index.
  4. Block Index: Acts as a parent directory for all blocks within the file.
File Format
File Format

3.1. File Header

  • Length: 66 bytes.
  • Position: At the beginning of the file.
  • Purpose: Outlines essential file properties and indicates subsequent section locations.
  • All offsets are relative to the beginning of the file.
OffsetLengthTypeDescription
014stringFile identifier ("versatiles_v02")
141u8tile_format value
151u8precompression value
161u8minimum zoom level
171u8maximum zoom level
184i32bbox min x (10⁷ × lon)
224i32bbox min y (10⁷ × lat)
264i32bbox max x (10⁷ × lon)
304i32bbox max y (10⁷ × lat)
348u64offset of Metadata
428u64length of Metadata
508u64offset of Block Index
588u64length of Block Index

3.1.1. Value tile_format

Value hexValue decTypeMime
0x000binapplication/octet-stream
0x1016pngimage/png
0x1117jpgimage/jpeg
0x1218webpimage/webp
0x1319avifimage/avif
0x1420svgimage/svg+xml
0x2032pbfapplication/x-protobuf
0x2133geojsonapplication/geo+json
0x2234topojsonapplication/topo+json
0x2335jsonapplication/json

3.1.2. Value precompression

Metadata and all Tile Blobs are pre-compressed with:

ValueMethod
0Uncompressed
1gzip
2Brotli

3.2. Metadata Chunk

  • Content: Encapsulates tiles.json, detailing tileset metadata.
  • Encoding: UTF-8.
  • Compression: Defined by the precompression flag in the File Header.
  • Note: The absence of Metadata is indicated by zero offsets and lengths in the File Header.

3.3. Blocks

  • Structure: Blocks act as aggregators for up to 256×256 tiles.
  • Zoom Levels: Individual Blocks can span entire zoom levels (0-8). Higher zoom levels (>8) may require multiple Blocks.
  • Maximum number of Blocks per zoom level: pow(4, max(0, level - 8)).
Blocks per level
Level Blocks
  • Each Block contains concatenated Tile Blobs and ends with a Tile Index.
  • Neither the Tile Blobs in a Block nor the Blocks in the file need to follow any particular order.

3.3.1. Tile Blobs

  • Tile Blobs are concatenated binary data, each containing one tile. All tiles have the same format and are pre-compressed.
  • Format: Each Tile Blob has the same file format, determined by the tile_format code in the File Header.
  • Compression: Each Tile Blob is compressed according to the precompression flag in the File Header.

3.3.2. Tile Index

  • Compression: Brotli.
  • Purpose: Maps the coordinates of tiles within a block to their respective binary position and length.
  • Tiles are ordered horizontally, then vertically
  • index = (row - row_min) * (col_max - col_min + 1) + (col - col_min)
  • (col_min, row_min, col_max, row_max are specified in Block Index)
  • Identical Tile Blobs can be stored once and referenced multiple times to save storage space.
  • If a tile does not exist, the length of the Tile Blob is 0.
  • The offsets of Tile Blobs are relative to the beginning of the Block. So the offset of the first Tile Blob should always be 0.
OffsetLengthTypeDescription
12*i8u64offset of Tile Blob in Block
12*i+84u32length of Tile Blob
index of Tile Blobs
Block Tiles

3.4. Block Index

  • Compression: Brotli.
  • Function: Provides a directory for locating Blocks within the container file.
  • Empty Blocks are not saved.
  • Each 33-byte entry within the Block Index is structured as follows:
OffsetLengthTypeDescription
0 + 33*i1u8level
1 + 33*i4u32column/256
5 + 33*i4u32row/256
9 + 33*i1u8col_min (0..255)
10 + 33*i1u8row_min (0..255)
11 + 33*i1u8col_max (0..255)
12 + 33*i1u8row_max (0..255)
13 + 33*i8u64offset of Block in file
21 + 33*i8u64length of Tile Blobs
29 + 33*i4u32length of Tile Index
  • Since a Block consists only of Tile Blobs appended by a Tile Index, the length of Block must be the sum of the lengths of the Tile Blobs and the Tile Index.
  • Note: To efficiently find the Block containing the tile you are looking for, use a data structure such as a "map", "dictionary" or "associative array" and fill it with the data from the Block Index.

4. Glossary

  • Blob: A chunk of binary data. Object storage on Wikipedia
  • Block: A composite unit containing up to 256×256 tiles.
  • Brotli: A compression algorithm known for its efficiency and performance. It provides better compression than gzip. Brotli on Wikipedia
  • Tile: A square geographic area at a given zoom level containing map information as an image or as vector data.

Released under Unlicense