# MVT: Mapbox Vector Tiles

Starting with GDAL 2.3, the MVT driver can read and write Mapbox Vector Tile files, as standalone files, uncompressed or gzip-compressed (typical extensions are .pbf, .mvt, .mvt.gz), or a tileset at a given zoom level of such files. Write support requires GDAL to be built with libsqlite3 and GEOS support.

Mapbox Vector Tiles stored within a SQLite container conforming to the MBTiles format are handled by the MBTiles driver.

Tilesets of MVT files can for example be generated by tippecanoe or tileserver-gl. The output file hierarchy will contain a metadata.json file at its root and {z}/{x}/{y}.pbf files with the tiles, where z is the zoom level and (x, y) the coordinate of the tile in a given zoom level. The origin of the tiling system is the top-left tile(XYZ convention). For example, for zoom levels 0 and 1 :

    /metadata.json
    /0/
       0/
         0.pbf
    /1/
       0/
         0.pbf
         1.pbf
       1/
         0.pbf
         1.pbf

The driver will assume by default EPSG:3857 (WebMercator) spatial reference system and Z/X/Y tiling structure, if opening a filename with {Z}/{X}/{Y}.pbf or {Z}-{X}-{Y}.pbf name, or a zoom level of a tileset. Otherwise integer coordinates will be reported.

Note: When opening a zoom level of a tileset, the driver will make no effort of stiching together geometries for features that overlap several tiles.

## Connection strings

The following connection strings are supported:

- /path/to/some.pbf
- MVT:http[s]://path/to/some.pbf
- /path/to/{Z}: where {Z} is a zoom level between 0 and 30, tiles are in /path/to/{Z}/{X}/{Y}.pbf files, and /path/to/metadata.json or /path/to.json should typically exist.
- MVT:http[s]://path/to/{Z]

The MVT: prefix may be added before the filename or directory name to help forcing identification of datasets in some rare cases where non-guided identification would fail.

## metadata.json

This file is typically generated by tippecanoe and has the following content:

    {
        "name": "my_layername",
        "description": "my_layername",
        "version": "2",
        "minzoom": "0",
        "maxzoom": "0",
        "center": "2.500000,49.500000,0",
        "bounds": "2.000000,49.000000,3.000000,50.000000",
        "type": "overlay",
        "format": "pbf",
        "json": "{
            \"vector_layers\": [ {
                \"id\": \"my_layername\",
                \"description\": \"\",
                \"minzoom\": 0,
                \"maxzoom\": 0,
                \"fields\": {
                    \"bool_false\": \"Boolean\",
                    \"bool_true\": \"Boolean\",
                    \"float_value\": \"Number\",
                    \"pos_int_value\": \"Number\",
                    \"pos_int64_value\": \"Number\",
                    \"neg_int_value\": \"Number\",
                    \"neg_int64_value\": \"Number\",
                    \"pos_sint_value\": \"Number\",
                    \"pos_sint64_value\": \"Number\",
                    \"neg_sint_value\": \"Number\",
                    \"neg_sint64_value\": \"Number\",
                    \"real_value\": \"Number\",
                    \"string_value\": \"String\",
                    \"uint_value\": \"Number\",
                    \"uint64_value\": \"Number\"
                }
            } ],
            \"tilestats\": {
                \"layerCount\": 1,
                \"layers\": [
                    {
                    \"layer\": \"my_layername\",
                    \"count\": 2,
                    \"geometry\": \"Point\",
                    \"attributeCount\": 0,
                    \"attributes\": []
                    }
                ]
            }
        }}"
    }

The MVT driver only uses the "json" key to retrieve the layer names, their fields and the geometry type, and the "bounds" key for the layer extent.

If this file cannot be found, the layer schema is established by scanning the features of the tile(s).

As an extension, OGR handles in reading and writing custom tiling schemes by using the crs, tile_origin_upper_left_x, tile_origin_upper_left_y and tile_dimension_zoom_0 metadata items. For example, for the Finnish ETRS-TM35FIN (EPSG:3067) tiling scheme:

    {
     ...
      "crs":"EPSG:3067",
      "tile_origin_upper_left_x":-548576.0,
      "tile_origin_upper_left_y":8388608.0,
      "tile_dimension_zoom_0":2097152.0,
    }

## Opening options

The following open options are available:

- X=int_value: X coordinate of the EPSG:3857 tile.
- Y=int_value: Y coordinate of the EPSG:3857 tile.
- Z=int_value: Z coordinate of the EPSG:3857 tile.
- METADATA_FILE=filename: Filename of a metadata.json-like file. If opening a /path/to/{Z}/{X}/{Y}.pbf file, the driver will by default try to find /path/to/metadata.json. Setting the value to the empty string is a way of avoid the metadata.json file to be used.
- CLIP=YES/NO: Whether to clip geometries of vector features to tile extent. Generators of vector files will typically create geometries with a small buffer beyond the tile extent so that geometries intersecting several tiles can be unioned back. Defaults to YES so that that buffer is removed and geometries are clipped exactly to the tile extent.
- TILE_EXTENSION=string: For tilesets, extension of tiles. Defaults to pbf.
- TILE_COUNT_TO_ESTABLISH_FEATURE_DEFN=int_value: For tilesets without metadata file, maximum number of tiles to use to establish the layer schemas. Defaults to 1000.
<lib>JSON_FIELD=YES/NO: For tilesets, whether to put all attributes as a serialized JSon dictionary.

## Creation issues

Tiles are generated with WebMercator (EPSG:3857) projection by default ( custom tiling schemes can be defined with the TILING_SCHEME option). Several layers can be written. It is possible to decide at which zoom level ranges a given layer is written.

Part of the conversion is multi-threaded by default, using as many threads as they are cores. The number of threads used can be controlled with the GDAL_NUM_THREADS configuration option.

## Dataset creation options

- NAME=string: Tileset name. Defaults to the basename of the output file/directory. Used to fill metadata records.
- DESCRIPTION=string: A description of the tileset. Used to fill metadata records.
- TYPE=overlay/baselayer: Layer type. Used to fill metadata records.
- FORMAT=DIRECTORY/MBTILES: Format into which tiles are written. DIRECTORY means that tiles are written in a hierarchy like out_dir/{z}/{x}/{y}.pbf. MBTILES is for a MBTILES container. Defaults to DIRECTORY, unless the output filename has a .mbtiles extension
- TILE_EXTENSION=string: For tilesets as directories of files, extension of tiles. Defaults to pbf.
- MINZOOM=integer: Minimum zoom level at which tiles are generated. Defaults to 0.
- MAXZOOM=integer: Maximum zoom level at which tiles are generated. Defaults to 5. Maximum supported value is 22
- CONF=string: Layer configuration as a JSon serialized string.
- SIMPLIFICATION=float: Simplification factor for linear or polygonal geometries. The unit is the integer unit of tiles after quantification of geometry coordinates to tile coordinates. Applies to all zoom levels, unless SIMPLIFICATION_MAX_ZOOM is also defined.
- SIMPLIFICATION_MAX_ZOOM=float: Simplification factor for linear or polygonal geometries, that applies only for the maximum zoom level.
- EXTENT=positive_integer. Number of units in a tile. The greater, the more accurate geometry coordinates (at the expense of tile byte size). Defaults to 4096
- BUFFER=positive_integer. Number of units for geometry buffering. This value corresponds to a buffer around each side of a tile into which geometries are fetched and clipped. This is used for proper rendering of geometries that spread over tile boundaries by some rendering clients. Defaults to 80 if EXTENT=4096.
- COMPRESS=YES/NO. Whether to compress tiles with the Deflate/GZip algorithm. Defaults to YES. Should be left to YES for FORMAT=MBTILES.
- TEMPORARY_DB=string. Filename with path for the temporary database used for tile generation. By default, this will be a file in the same directory as the output file/directory.
- MAX_SIZE=integer. Maximum size of a tile in bytes (after compression). Defaults to 500 000. If a tile is greater than this threshold, features will be written with reduced precision, or discarded.
- MAX_FEATURES=integer. Maximum number of features per tile. Defaults to 200 000.
- BOUNDS=min_long,min_lat,max_long,max_lat. Override default value for bounds metadata item which is computed from the extent of features written.
- CENTER=long,lat,zoom_level. Override default value for center metadata item, which is the center of BOUNDS at minimum zoom level.
- TILING_SCHEME=crs,tile_origin_upper_left_x,tile_origin_upper_left_y, tile_dimension_zoom_0: Define a custom tiling scheme with a CRS (typically given as EPSG:XXXX), the coordinates of the upper-left corner of the upper-left tile (0,0) in the CRS, and the dimension of the tile at zoom level 0. Only available for FORMAT=DIRECTORY. The standard WebMercator tiling scheme would be defined by "EPSG:3857,-20037508.343,20037508.343,40075016.686". A tiling scheme for WGS84 geodetic could be "EPSG:4326,-180,180,360". The tiling scheme for Finnish ETRS-TM35FIN (EPSG:3067) is "EPSG:3067,-548576,8388608,2097152". When using such as custom tiling scheme, the 'crs', 'tile_origin_upper_left_x', 'tile_origin_upper_left_y' and 'tile_dimension_zoom_0' entries are added to the metadata.json, and are honoured by the OGR MVT reader.

## Layer configuration

The above mentioned CONF dataset creation option can be set to a string whose value is a JSon serialized document such as the below one:

            {
                "boundaries_lod0": {
                    "target_name": "boundaries",
                    "description": "Country boundaries",
                    "minzoom": 0,
                    "maxzoom": 2
                },
                "boundaries_lod1": {
                    "target_name": "boundaries",
                    "minzoom": 3,
                    "maxzoom": 5
                }
            }

boundaries_lod0 and boundaries_lod1 are the name of the OGR layers that are created into the target MVT dataset. They are mapped to the MVT target layer boundaries.

It is also possible to get the same behaviour with the below layer creation options, although that is not convenient in the ogr2ogr use case.

## Layer creation options

- MINZOOM=integer: Minimum zoom level at which tiles are generated. Defaults to the dataset creation option MINZOOM value.
- MAXZOOM=integer: Minimum zoom level at which tiles are generated. Defaults to the dataset creation option MAXZOOM value. Maximum supported value is 22
- NAME=string: Target layer name. Defaults to the layer name, but can be overridden so that several OGR layers map to a single target MVT layer. The typical use case is to have different OGR layers for mutually exclusive zoom level ranges.
- DESCRIPTION=string: A description of the layer.

## Examples

    ogrinfo MVT:https://free.tilehosting.com/data/v3/1 -oo tile_extension="pbf.pict?key=${YOUR_KEY}" --debug on -oo metadata_file="https://free.tilehosting.com/data/v3.json?key=${YOUR_KEY}"

    ogr2ogr -f MVT mytileset source.gpkg -dsco MAXZOOM=10

See Also:

- Mapbox Vector Tile Specification
- MBTiles driver
- tippecanoe: Builds vector tilesets from large (or small) collections of GeoJSON, Geobuf, or CSV features
- Links to tools dealing with Mapbox Vector Tiles