Introduction

This documentation describes Mapillary tiles. With Mapillay tiles, developers are able to show Mapillary geographic data on map platforms such as Mapbox GL, Esri ArcGIS Online, Leaflet, and OpenLayers.

Tile types

Mapillary provides two types of tiles:

  1. vector tiles in MapBox's protocal buffer format (.mvt), and
  2. pre-rendered raster tiles in image format (.png).

Attribution

Suggested attribution string for using Mapillary coverage tiles:

Mapillary, CC BY

Here Mapillary should link to https://www.mapillary.com.

Client ID

Some requests require a client ID. See API documentation for details on how to obtain a client ID for your application.

Errors

For coverage vector tiles and coverage raster tiles, the following HTTP status codes are recognized as errors:

  • 403: the requested tile does not exist. It is safe to ignore these errors.

Update frequency

Tiles are updated every hour. If updates are not reflected on the map within this timeframe, please report issues to our GitHub repository.

Mapbox GL JS

Mapbox GL is a suite of libraries with a focus on vector maps, and Mapbox GL JS is a specific JavaScript library for rendering vector tiles. Making a map with Mapillary vector tiles in Mapbox GL JS is simple and easy. We recommend starting by creating a variable that contains the vector tiles as a source:

var mapillarySource = {
    type: 'vector',
    tiles: ['https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt'],
    minzoom: 0,
    maxzoom: 14
};

Notice the maxzoom is 14—this is where Mapillary vector tiles stop changing according to zoom level. You can zoom past 14, but the tiles will remain rendered the same. Assuming your map container is called map, the following code will add the vector tiles to your map as a source, called ‘mapillary’ and linked to the mapillarySource variable:

map.addSource('mapillary', mapillarySource);

Next, the layer can be visualized by adding it to the map, linked to the source, and styled as you see fit. Below we see a simple way to style the vector tiles:

map.addLayer({
    'id': 'mapillary',
    'type': 'line',
    'source': 'mapillary',
    'source-layer': 'mapillary-sequences',
    'layout': {
        'line-cap': 'round',
        'line-join': 'round'
    },
    'paint': {
        'line-opacity': 0.6,
        'line-color': 'rgb(53, 175, 109)',
        'line-width': 2
    }
});

In addition to this simple styling, filters can be applied in order to display only specific sequences, whether it is customized by date, user, camera angle, or other attributes. To see a complete example of how to use Mapillary vector tiles with Mapbox GL JS, click here.

Esri ArcGIS API for JS

Vector Tiles with Esri ArcGIS API for JavaScript currently exists in two parallel versions—3.x and 4.x. While both are very similar, the 4.x version is expanded to support 3D mapping. We will demonstrate an integration of Mapillary vector tiles in 4.1, which works similarly in any 3.x version. To get started, we’ll reference the necessary scripts in the <head> of your HTML document:

<link rel="stylesheet" href="https://js.arcgis.com/4.1/esri/css/main.css">
<script src="https://js.arcgis.com/4.1/"></script>

Getting started with the Esri map requires a basic shell, as seen below. After adding this, we’ll fill in the necessary details. Our function will take three arguments, which we will later define in variables: Map, MapView, and VectorTileLayer:

require([
    "esri/Map",
    "esri/views/MapView",
    "esri/layers/VectorTileLayer",
    "dojo/domReady!"
], function(Map, MapView, VectorTileLayer) {
    // set up your map here
});

Remove the // set up your map here comment, and instead replace it with the first line of code needed to initiate the map with a supported Esri basemap:

var map = new Map({
    basemap: "osm"
});

Next, we need to configure the view of the map, including the center, zoom , and container. In the following lines, we are assuming you have a <div id="map"></div> in the <body> of your document, so that the container refers to this:

var view = new MapView({
    container: "map",
    map: map,
    center: [-75.57, 6.24],
    zoom: 12
});

Be aware also that the code above requires longitude first, latitude second when setting the center. Once complete, the initial map is set, and we’re ready to add a Mapillary vector tile layer. To accomplish this, we’ll need to configure our Mapillary style in a separate JSON file. open a blank document, and save it as mapillary.json. For a basic Mapillary visualization it can contain the following code:

{
    "version": 8,
    "sources": {
        "mapillary-source": {
            "tiles": [
                "https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt"
            ],
            "type": "vector"
        }
    },
    "layers": [
        {
            "id": "mapillary-lines",
            "type": "line",
            "source": "mapillary-source",
            "source-layer": "mapillary-sequences",
            "interactive": true,
            "minzoom": 0,
            "maxzoom": 14,
            "layout": {
                "line-join": "round",
                "line-cap":  "round",
                "visibility": "visible"
            },
            "paint": {
                "line-opacity": 0.6,
                "line-color": "#39AF64",
                "line-width": 2
            }
        }
    ]
}

Notice above that the three crucial sections are version, sources, and layers. Keep version set to 8. For sources, we are simply referring to the Mapillary vector tile endpoint, which is located at https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt, and designating it’s type as a vector. In layers we are able to set the style, and refer to a specific Mapillary layer, which in this case is the sequence layer. For a more advanced option, you can see a JSON that styles multiple Mapillary layers by clicking here.

Once you’ve saved the above code as mapillary.json, it’s time to integrate it into your map. Below the view variable, we will add another variable for Mapillary:

var mapillary = new VectorTileLayer({
    url: "mapillary.json"
});

Next, we simply add this layer to the map:

map.add(mapillary);

With this code, you’ve used two separate files—a primary document with your map code and an associated JSON for Mapillary style—to add Mapillary vector tiles to your map with Esri ArcGIS API for JavaScript. You can see a complete code example of this simple map by clicking here.

Leaflet

Leaflet is a simple and powerful open-source JavaScript library for creating interactive web maps. Using Mapillary vector tiles with a Leaflet map requires an external plugin—Leaflet.MapboxVectorTile. This plugin comes in the form of a script, which you can download here in its full size or compressed size. If you plan on doing advanced debugging, be sure to use the full size version in order to properly read error messages.

Once you’ve found the plugin above, you can save it locally in the same folder as the HTML file where you’ll start creating your Leaflet web map. You can also just take note of the URl where the plugin is hosted. In the <head></head> tag you’ll need to reference the script, alongside referencing leaflet. Below we’ve referenced it in the local folder:

<script src="Leaflet.MapboxVectorTile.js"></script>

The foundation has been laid, and you’re ready to move forward. To get started with implementing Mapillary vector tiles into your Leaflet map, you’ll now want to create a variable for the Mapillary configuration:

var mlyVectorLayerConfig = {
    url: 'https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt',
    maxZoom: 14,
    style: function (feature) {
        var style = {}
        style.color = 'rgba(53, 175, 109, 0.7)'
        style.size = 3

        return style
    }
};

Above we’ve designated a generic style, using opacity of 0.7 and Mapillary’s typical color scheme, but you can modify this as you like. The maxZoom is set to 14 because Mapillary doesn’t render any additional detail beyond this zoom level, but zooming in further is still possible.

Next, you’ll need to add the Mapillary source to the map:

var mvtSource = new L.TileLayer.MVTSource(mlyVectorLayerConfig);

The source is stored as a variable called mvtSource and uses the MVTSource() method from the plugin to cast the Mapillary vector tile configuration into a Leaflet tile layer. Once this variable has been created, simply add it to the map:

map.addLayer(mvtSource);

Opening your map in the browser, you will now see Mapillary vector tiles. Click here to see a full code example of this method.

OpenLayers

OpenLayers is an open source JavaScript library for creating dynamic web maps. OpenLayers supports a wide variety of data inputs, including vector tiles. This makes it easy to get Mapillary up and running in your OpenLayers project.

Adding a new vector tile layer in OpenLayers requires listing it within the layers section of a new map variable. Before adding your vector tiles, you may have something like the following code to add a map with a baselayer:

This OpenLayers code above has added a map variable, targeted it for display in a div with id as map, added a tile layer as a basemap using ol.source.XYZ , then oriented the map by setting several parameters in view .

Adding a Mapillary vector tile layer to this means simply inserting it between the [ ] brackets that contain the layers information. It also requires some styling to be set. As a first step, add a new variable to your map that sets some style information for your anticipated Mapillary layer, like below or modified to your needs:

var strokestyle = new ol.style.Style({
    stroke: new ol.style.Stroke({
        color: 'rgba(53, 175, 109,0.7)',
        width:  4
    })
});

This style is for a stroke, which refers to the Mapillary sequence lines. We have set the color to be a typical Mapillary green, with opacity of 0.7, and the width of the stroke is 4. Now we include this variable when we add the vector tile layer to layers:

new ol.layer.VectorTile({
    source: new ol.source.VectorTile({
        attributions: '© Mapillary',
        format: new ol.format.MVT(),
        tileGrid: ol.tilegrid.createXYZ({maxZoom: 22}),
        tilePixelRatio: 16,
        opacity: 0.7,
        url: 'https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt'
    }),
    style: strokestyle
})

In this code snippet, we’ve specified the format of the layer as MVT (Mapbox vector tile), set the opacity again (which matches the style setting), specified the endpoint url , and set the style to match our variable.

With this added to your layers, your map is now good to go! Click here for a full code example of a basic web map using open layers.

Filtering with Vector Tiles

Mapillary vector tiles are able to be filtered when adding the layer, as part of the styling specifications. For example, consider the following map of Seattle, showing Mapillary vector tiles with no filters.

Unfiltered sequences

The code which styles the Mapillary layer has been added to a Mapbox map, but as mentioned, does not apply a filter:

map.addLayer({
    'id': 'mapillary',
    'type': 'line',
    'source': 'mapillary',
    'source-layer': 'mapillary-sequences',
    'layout': {
        'line-cap': 'round',
        'line-join': 'round'
    },
    'paint': {
        'line-opacity': 0.6,
        'line-color':   'rgb(53, 175, 109)',
        'line-width':   2
    }
});

This displays all Mapillary sequences, but can be tweaked. For example, perhaps we want to show only data captured since January 1st, 2016. We can create a variable for this date which converts from a traditional date display to EPOCH milliseconds:

var mindate = new Date('01/01/2016').getTime();

The milliseconds time will be 1451602800000, but it’s easier to store as a variable. The filter will use these milliseconds to query Mapillary for the date we want. The following is a demonstration of this filter:

{
    filter: ['>=', 'captured_at', mindate],
}

This is saying that the date the photo was captured should be greater than or equal to January 1st, 2016. Now the map will only display these photos! The code will fit into the overall styling as seen below on line 6:

map.addLayer({
    'id': 'mapillary',
    'type': 'line',
    'source': 'mapillary',
    'source-layer': 'mapillary-sequences',
    "filter":   ['>=', 'captured_at', mindate],
    'layout': {
        'line-cap': 'round',
        'line-join': 'round'
    },
    'paint': {
        'line-opacity': 0.6,
        'line-color':   'rgb(53, 175, 109)',
        'line-width':   2
    }
});

And the map is now filtered, showing fewer routes. The visual of the map doesn’t appear altogether too different, so before we compare them, let’s add a few more filters. First, we’ll add another variable to set a maximum date. Let’s see what was captured between January 1st, 2016 and the start of summer—how about June 22nd?

var maxdate = new Date('06/22/2016').getTime();

The filter format changes for multiple filters:

{
    filter: ['all',
             ['>=', 'captured_at', mindate],
             ['<=', 'captured_at', maxdate]]
}

Don’t forget to add a comma after the last filter on line 8 when inserting it before other code. This fits into the styling like so:

map.addLayer({
    'id': 'mapillary',
    'type': 'line',
    'source': 'mapillary',
    'source-layer': 'mapillary-sequences',
    'filter': ['all',
               ['>=', 'captured_at', mindate],
               ['<=', 'captured_at', maxdate]],
    'layout': {
        'line-cap': 'round',
        'line-join': 'round'
    },
    'paint': {
        'line-opacity': 0.6,
        'line-color':   'rgb(53, 175, 109)',
        'line-width':   2
    }
});

The result is a map of only sequences captured during that first half of the year. Notice the lower density of Mapillary vector tiles this time around:

Filtered sequences

You can see a full code example of this method by clicking here. There are plenty more options for filtering, including use with the sequence layer as shown here, as well as the image layer and the sequence overview layer.

OsmAnd

OsmAnd is an offline mobile map app for navigation and editing OSM data. Nuno Caldeira has written a nice blog post on how to add Mapillary raster coverage tiles to the app.

Coverage

Coverage tiles are available in three different vector tile layers: overview layer, sequence layer, and image layer. Overview layers show the aggregated coverage information (the number of contributors, latest captured sequence, etc.) at the least detailed level. Sequence layers show coverage as sequences. Image layers show image information (location, compass angle, captured time, etc.) at the most detailed level.

Get coverage tiles

Coverage tiles don't require any URL parameter.

GET
https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt

Overview layer

Overview layers show aggregated information on coverage in a heat map style. These are available for the lowest zoom levels (0-5). In overview layers, a tile is divided into 256x256 cells (cell extent is therefore 16). Each cell is associated with the latest captured sequence within the cell. Geometries represent center points of the cells within which there is at least one image or sequence captured.

  • Available at levels: 0-5
  • Extent: 4096
  • Geometry type: circle (or Point in GeoJSON)
  • Layer name: mapillary-sequence-overview

Overview layer

Features in the overview layer have the following properties:

Property Type Description
captured_at number When the latest sequence was captured, expressed as UTC epoch time in milliseconds. Must be non-negative integer; 0 if not found.
ikey Key The first image key of the latest sequence. Empty if not found.
image_count number The number of images taken within the square. Must be an non-negative integer.
key Key Sequence key of the latest sequence.
pano number Whether the latest sequence is panorama ( 1 ), or not ( 0 ).
user_count number The number of contributing users within the square. Must be Non-negative integer.
userkey Key User key of the latest sequence. Empty if not found.

Example request

curl -s https://d25uarhxywzl1j.cloudfront.net/v0.1/3/5/1.mvt

Example response (truncated)

{
  "mapillary-sequence-overview": {
    "version": 1,
    "features": [
      {
        "geometry": [
          [
            1192,
            504
          ]
        ],
        "type": 1,
        "properties": {
          "ikey": "JGJ5oSVHUjxI6y9gdDePgg",
          "user_count": 1,
          "image_count": 440,
          "key": "ev4-wPgWoQ9cVbJW7LP3hA",
          "userkey": "BSE9PQu8kENiUh9-3O3A4A",
          "pano": 0,
          "captured_at": 1443260089200
        },
        "id": 347086
      },
      {
        "geometry": [
          [
            3928,
            696
          ]
        ],
        "type": 1,
        "properties": {
          "ikey": "Q3mJ7TsGrfrd53xXNz395g",
          "user_count": 1,
          "image_count": 2,
          "key": "CaQpRSLWhbPMQ4SZ215GDA",
          "userkey": "ZmJSgn19-RVp_J59FPJStw",
          "pano": 0,
          "captured_at": 1435779228416
        },
        "id": 245563
      }
    ],
    "extent": 4096
  }
}

Sequence Layer

Sequence layers show coverage as sequences (green lines on the map) for zoom levels 6-14.

  • Available at levels: 6-14
  • Extent: 4096
  • Geometry type: line (or LineString in GeoJSON)
  • Layer name: mapillary-sequences

Sequence layer

Features in the sequence layer have the following properties:

Property Type Description
captured_at integer When was the sequence captured, expressed as UTC epoch time in milliseconds. Must be non-negative integer; 0 if not found.
ikey Key The first image key. Empty if not found.
key Key Sequence key. Must be non-empty string.
pano integer Indicates if the sequence is a panorama ( 1 ) sequence, or not ( 0 ).
userkey Key User key. Empty if not found.

Example request

curl -s https://d25uarhxywzl1j.cloudfront.net/v0.1/13/5339/2006.mvt

Example response (truncated)

{
  "mapillary-sequences": {
    "version": 1,
    "features": [
      {
        "geometry": [
          [
            2556,
            3652
          ],
          [
            2557,
            3653
          ]
        ],
        "type": 2,
        "properties": {
          "userkey": "mIjXaDsq5Y39vLOJjbnYGA",
          "ikey": "hgotDF9v7HsX8OPh1kkLKw",
          "pano": 0,
          "captured_at": 1458127926134,
          "key": "DfRnrpqspVATl3OIO_OI4A"
        },
        "id": 465401
      },
      {
        "geometry": [
          [
            2557,
            3672
          ],
          [
            2558,
            3673
          ]
        ],
        "type": 2,
        "properties": {
          "userkey": "mIjXaDsq5Y39vLOJjbnYGA",
          "ikey": "ZNTV4wKqRPTjeDIil86NSQ",
          "pano": 0,
          "captured_at": 1458127546578,
          "key": "blS9FDdy3gfMqG4c5S9KkQ"
        },
        "id": 465404
      }
    ],
    "extent": 4096
  }
}

Image Layer

Image layers show the individual image locations (green dots on the map) within a sequence with some basic image specific properties.

  • Available at levels: 14
  • Extent: 4096
  • Geometry type: circle (or Point in GeoJSON)
  • Layer name: mapillary-images

Image layer

Features in the image layer have the following properties:

Property Type Description
ca number Camera heading. -1 if not found.
captured_at number When the image was captured, expressed as UTC epoch time in milliseconds. Must be non-negative integer; 0 if not found.
key Key Image key.
pano number Whether the image is panorama ( 1 ), or not ( 0 ).
skey Key Sequence key.
userkey Key User key. Empty if not found.

Example request

curl -s https://d25uarhxywzl1j.cloudfront.net/v0.1/14/10679/4012.mvt

Example response (truncated)

{
  "mapillary-images": {
    "version": 1,
    "features": [
      {
        "geometry": [
          [
            1017,
            3207
          ]
        ],
        "type": 1,
        "properties": {
          "skey": "DfRnrpqspVATl3OIO_OI4A",
          "ca": 65.0285205841064,
          "key": "hgotDF9v7HsX8OPh1kkLKw",
          "userkey": "mIjXaDsq5Y39vLOJjbnYGA",
          "pano": 0,
          "captured_at": 1458127926134
        },
        "id": 465401
      },
      {
        "geometry": [
          [
            1018,
            3249
          ]
        ],
        "type": 1,
        "properties": {
          "skey": "blS9FDdy3gfMqG4c5S9KkQ",
          "ca": 176.592336654663,
          "key": "ZNTV4wKqRPTjeDIil86NSQ",
          "userkey": "mIjXaDsq5Y39vLOJjbnYGA",
          "pano": 0,
          "captured_at": 1458127546578
        },
        "id": 465404
      }
    ],
    "extent": 4096
  }
}

Coverage (raster)

For clients that require raster tiles, Coverage tiles are also available as pre-rendered image tiles.

Get coverage raster tiles

Coverage raster tiles don't require any URL parameter.

GET
https://d6a1v2w10ny40.cloudfront.net/v0.1/{z}/{x}/{y}.png

Layers

On level 0-13 only sequences (green lines) are shown. On level 14-17 both sequences and images (green dots) are shown.

  • Available at levels: 0-17
  • Color: #36AF6D (green)
  • Image format: PNG
  • Image size: 256x256 px

Map objects

Note: map object tiles are available under a commercial license through data requests. Please refer to our pricing or contact sales. Map objects are also available for editing OSM for free under OSM foundation contributor terms.

Map object tiles show objects automatically recognized and detected in images, or objects manually added by users. It could be trees, traffic signs, a segment of road. Currently Mapillary only support traffic signs.

Map object tiles correspond to map objects API which provides developers more flexible access to map objects.

Get map object tiles

Map object tiles support the following URL parameters:

URL Parameter Type Description
layers string[] Comma-separated list of layer names.
client_id (required) string Client ID of the application. See the API documentation for how to create an application.
GET
https://a.mapillary.com/v3/tiles/objects/{z}/{x}/{y}.mvt

Map object layer

Image detection layers that show map objects. While a map object is possible to be any type of geometry, currently we only support Point geometry.

  • Available at levels: 14 and higher
  • Extent: 4096
  • Geometry type: circle (or Point in GeoJSON)

Map object layer

Features in the map object layer have the following properties:

Property Type Description
accuracy number The accuracy of the objects location.
altitude number The altitude of the object.
detections object[] Detection objects. See below.
first_seen_at number When the object was first seen, expressed as UTC epoch time in milliseconds. Must be non-negative integer.
last_seen_at number When the object was last seen, expressed as UTC epoch time in milliseconds. Must be non-negative integer.
nbr_detections number Number of detections used to construct the object.
user_keys Key[] A list of users that contributed images with detections object is constructed from.
value string Type of object, specific according to selected object layer. See the API documentation for the corresponding value.

A detection object has follow properties:

Property Type Description
captured_at number When the image was captured, expressed as UTC epoch time in milliseconds. Must be non-negative integer.
detection_key string Image detection key.
image_key Key Image key.
user Key User key.

Image detections

Note: image detection tiles are available under a commercial license through data requests. Please refer to our pricing or contact sales. Image detections are also available for editing OSM for free under OSM foundation contributor terms.

Image detection tiles show image detections as a map layer with location of the detections equal to the image location. It is meant to show where something has been observed. For detections where a location of the detected object can be calculated, this location is available in object tiles(#map-objects).

Image detection tiles correspond to the image detections API which provides developers more flexible access to image detections.

Get image detection tiles

Image detection tiles support the following URL parameters:

URL parameter Type Description
layers string[] Comma-separated list of layer names.
client_id (required) string Client ID of the application. See the API documentation for how to create an application.
GET
https://a.mapillary.com/v3/tiles/detections/{z}/{x}/{y}.mvt

Image detection layer

Image detection layers that show image detections.

  • Available at levels: 14 and higher
  • Extent: 4096
  • Geometry type: circle (or Point in GeoJSON)

Features in the image detection layer have the following properties:

Property Type Description
accuracy number The accuracy of the detection.
area number Area that the detection occupies of the image.
captured_at number When this detection was seen, expressed as UTC epoch time in milliseconds. Must be non-negative integer; 0 if not found.
image_key Key The key for the image this detection was found in.
key Key Detection key.
value string TODO Type of detection, specific to selected detection layer. See the API documentation for the corresponding value.
Mapillary Tiles Documentation