Vector Tile Structure

Service version: 1
Last edit: 2023.09.28
TomTom Orbis Maps

Important notes:

Purpose

Vector Tiles are served in binary format, which uses Google Protocol Buffers as the method of serializing structured data. The serializing algorithm is very effective and as a result Vector Tiles are light-weight.

Vector Tile structure

Vector Tile diagram

The following diagram shows dependencies between the properties of vector tile.

vector tile property dependencies

Legend

Tile

Represents a vector tile as a whole entity. It consists of at least one TileLayer.
If the tile does not contain any relevant data, it contains one layer named empty.


TileLayer

Part of a Tile , representing one of the layers that can be rendered later. In the Traffic API it can represent all of the traffic flow or all of the traffic incidents.


Every TileLayer contains the following fields:

  • name

  • version

  • extent

It may also contain the following fields:

  • keys are an array of unique strings.

  • values are an array of unique TileValues.

  • features are an array of unique TileFeatures.

Arrays of keys and values contain the mapping for tags of TileFeature.


TileFeature

Member of an array of features stored in a TileLayer , containing a geometry representation that can be rendered.


It always contains the following fields:

  • type is a type of geometry. It can be point , linestring , or polygon.

  • geometry is an array of encoded geometry that can be used for rendering. See the Decoding tile geometry section for details.

It may also contain the following fields:

  • tags are an array containing properties of feature.

    • They are a TileFeature's detailed description which can be used for styling and later rendering the geometry.

    • They are encoded into an array of integers.
    • In order to decode them, the arrays of keys and values , from corresponding TileLayer must be used.

    • See the Decoding tile tags section for details.


TileValue

Encoded representation of a string, integer, floating point, or boolean value.

  • It is stored in a values array, in a TileLayer.

  • It is used for decoding tags of a TileFeature
    (together with the members of a keys array).

  • See the Decoding tile tags section for details.

Schema data

Formally, the structure of Vector Tile is described by the protocol buffer schema. It allows the generation of C++, Java, Python, Go, Ruby, Objective-C, and C# code based on proto file.

Schema proto file
1package vector_tile
2
3option optimize_for = SPEED;
4
5message Tile {
6
7 enum GeomType {
8 UNKNOWN = 0;
9 POINT = 1;
10 LINESTRING = 2;
11 POLYGON = 3;
12 }
13
14 message Value {
15 optional string string_value = 1;
16 optional float float_value = 2;
17 optional double double_value = 3;
18 optional int64 int_value = 4;
19 optional uint64 uint_value = 5;
20 optional sint64 sint_value = 6;
21 optional bool bool_value = 7;
22 extensions 8 to max;
23 }
24
25 message Feature {
26 optional uint64 id = 1 [ default = 0 ];
27 repeated uint32 tags = 2 [ packed = true ];
28 optional GeomType type = 3 [ default = UNKNOWN ];
29 repeated uint32 geometry = 4 [ packed = true ];
30 optional bytes raster = 5;
31 }
32
33 message Layer {
34 required uint32 version = 15 [ default = 1 ];
35 required string name = 1;
36 repeated Feature features = 2;
37 repeated string keys = 3;
38 repeated Value values = 4;
39 optional uint32 extent = 5 [ default = 4096 ];
40
41 extensions 16 to max;
42 }
43
44 repeated Layer layers = 3;
45
46 extensions 16 to 8191;
47}

Decoding Vector Tile

Decoding tile geometry

Vector Tile geometry uses the following coordinate system:

  • Coordinates are always integers.
  • The (0,0)point is located in the upper-left corner of the tile.
  • The X axis has positive values to the right of the tile.
  • The Y axis has positive values to the bottom of the tile.
  • The tile may have margin, which is a buffer around the tile in the shape of a square frame.
  • In the Traffic API, the size of the margin is by default equal to 0.1 of the width/length of the tile.
  • The extent is equal to 4096, so the value range for X and Y coordinates is from 0 to 4095.
  • If the tile has a margin, the coordinates values range is additionally extended with its value in both directions.

Vector Tile geometry is encoded as an array of 32 bit unsigned integers in the geometry field, belonging to the TileFeature.

Encoded format has the following structure:

[command_and_count][x0][y0]..[xn][yn][command_and_count][x0][y0]..
  • command_and_count contains encoded values of command and count.
  • [x0][y0]..[xn][yn] are encoded coordinate (x,y) pairs.

Command

The value of command is decoded as follows:

command = command_and_count & 0x7
  • It can be interpreted as "paint brush movement" during rendering, in relation to point (0.0) and previous commands.
  • In the first TileFeature command "paint brush" starts at point (0,0).

Command types

CommandValueCoordinatesDescription

MoveTo

1

x,y

  • It defines the (x,y) coordinate.

    • In the case of a point type geometry, the coordinate is a new point.

    • In the case of a linestring type geometry, the coordinate is the start vertex of a new line.

    • In the case of a polygon type geometry, the coordinate is the start vertex of new linear ring.

  • It moves "paint brush" to a newly defined coordinate.

LineTo

2

x,y

  • It defines a segment, starting at the current position of the cursor and ending at (x,y) coordinate.

    • In the case of a linestring type geometry, the segment extends the current line.

    • In the case of a polygon type geometry, the segment extends the current linear ring.

  • It moves "paint brush" to a newly defined coordinate.

ClosePath

7

none
  • It closes the current linear ring of a polygon type geometry.

  • It starts and ends at the start vertex of a current linear ring.

  • It does not move "paint brush" to any coordinate, because it has none.

Count

The value of count is decoded as follows:

count = command_and_count >> 0x3
  • It defines the n number of [xn][yn] encoded coordinate pairs following the command_and_count value.
  • These coordinate pairs must be interpreted according to the preceding command type.

Coordinates

Coordinates [x0][y0]..[xn][yn] are encoded in zigzag encoding and are relative to the previous coordinate pair and previous commands. This means that only the first coordinate pair [x0][y0] in first command in every TileFeature stores absolute values.

The coordinates are decoded as follows:

Decoded coordinates values
1decode(x0) = ((x0 >> 0x1) ^ (-(x0 & 0x1)))
2decode(y0) = ((y0 >> 0x1) ^ (-(y0 & 0x1)))
3
4decode(x1) = decode(x0) + ((x1 >> 0x1) ^ (-(x1 & 0x1)))
5decode(y1) = decode(y0) + ((y1 >> 0x1) ^ (-(y1 & 0x1)))
6
7...
8
9decode(xn) = decode(xn-1) + ((xn >> 0x1) ^ (-(xn & 0x1)))
10decode(yn) = decode(yn-1) + ((yn >> 0x1) ^ (-(yn & 0x1)))
Example of decoded coordinates
1input :
2layer : 0 :
3 feature : 0 :
4 type : POINT
5 geometry : [9, 1136, 6564]
6
7processing :
8 geometry :
9 command_and_count = 9
10
11 command = 9 & 0x7 = 1
12 count = 9 >> 0x3 = 1
13
14 x0 = 1136, y0 = 6564
15 decode(x0) = ((1136 >> 0x1) ^ (-(1136 & 0x1))) = 568
16 decode(y0) = ((6564 >> 0x1) ^ (-(6564 & 0x1))) = 3282
17
18output :
19layer : 0 :
20 feature : 0
21 geometry : POINT(561, 3282)

Decoding tile tags

In order to reduce tile size, the properties of each feature are encoded in a tags array.

  • The tags array contains integer values which are indexes of keys and values arrays belonging to the corresponding layer.
  • The size of a tags array is always even.
  • The content of a tags array can be grouped into a list of pairs. Each odd element of an array is the first element of a pair, and each even element of an array is the second element of a pair.
  • The first element of each pair should be mapped to a keys array.
  • The second element of each pair should be mapped to a values array.
  • As a result, we get a decoded list of tags where the first element is the tag name and the second element is the tag value in the form of TileValue.
Example
1input :
2layer : 0 :
3 "keys" : ["road_type", "traffic_road_coverage"],
4 "values" : ["Motorway", "full"]
5 feature : 0 :
6 "tags" : [0,0,1,1]
7
8output :
9layer : 0 :
10 feature : 0 :
11 properties :
12 "road_type" : "Motorway"
13 "traffic_road_coverage" : "full"