mapbox/mapbox-gl-js

Improve tile URL normalization for better support for custom vector source support

Closed this issue · 1 comments

mapbox-gl-js version: 0.47.0 and master branch

browser: Any

Steps to Trigger Behavior

  1. Try to use a non mapbox URL as style source (e.g. ESRI or an own OpenMapTiles server )

Link to Demonstration

https://jsfiddle.net/ef7qwb1c/

Expected Behavior

MapBox should load the tiles form the given URL and display them.

Actual Behavior

MapBox constructs an invalid TileURL resulting in a failed XMLHttpRequest to load the data resulting in a an empty map and a lot of JS errors.

How to fix

Issue is the normalizeTileURL function which does not consider the sourceURL in this scenario:

if (!sourceURL || !isMapboxURL(sourceURL)) return tileURL;

In the provided fiddle the tileURL is set to /tile/6/26/15.pbf and sourceURL is https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer. Together they form a correct URL but mapbox only returns the tileURL.

I made a simple change to the function and the 3rd party source is working as expected.

export const normalizeTileURL = function(tileURL: string, sourceURL?: ?string, tileSize?: ?number): string {
    if (!sourceURL) return tileURL;
    if (!isMapboxURL(sourceURL)) {
        const sourceUrlObject = parseURL(sourceURL);
        sourceUrlObject.path += tileURL;
        return formatUrl(sourceUrlObject);
    }
    ...

An actual fix might need to consider certain formats (trailing&leading slashes, placeholders etc.) but considering a compatible format mapbox properly loads and displays the tiles with this change.

The TileJSON at https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer isn't valid. Entires in the tiles property array must be complete URLs, not relative paths. This will need to be corrected on the server side.