Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
ESRI JS API Vector Tile Implementation with Multiple Sources

Bug Overview

ESRI has adopted the Mapbox Vector Tile Spec & associated Mapbox Style Spec for implementing vector tiles. The Mapbox Style Spec has the 'sources' property that defines the sources of different tile sets. This enables the ability to combine tile sets from multiple sources into a single vector tile layer. For example, vector tiles provided by ESRI can be merged with vector tiles published separately into the same layer. This works in various mapping libraries that support vector tiles (tested with mapbox-gl), but ESRI's JS API has an issue. The JS API will only load a single source of vector tiles, even when multiple are specified. And even then, the behavior is inconsistent.

If there is a source named 'esri', that will be the only source loaded via the API. If there is a source with the string 'street' in it's name, the API will throw an error and fail to load the layer. If there are neither layers named 'esri' or contain 'street', only the first layer in the source list is loaded. This was done using the 4.6 version of the API.

Bug Example

This fiddle demonstrates the inconsistencies with how the ESRI JS API handles vector tile sources. By changing the sourceAlias variable to either 'esri', 'street' (or anything containing 'street'), and something else like 'test' the results of the maps change. Remember, this has no bearing on the source dataset, just how the API loads the sources. Compare this to the Mapbox API map which is loading the exact same style object and displays both vector tile sources in the same layer.

Expected Outcome

I would expect both sources to be loaded by the API, and tiles from both sources rendered on the map. See fiddle for Mapbox example.

Suspected Cause

From what I can glean, the root of the problem is within the VectorTileImpl.js file, specifically the function below.

function n(a, c) {
	if (!a.sources) return null;
	var d = a.sources;
	a = null;
	if (d.esri) {
		a = d.esri, c && a.url && !f.isAbsolute(a.url) && (d = c.path.substring(0, c.path.lastIndexOf("/")), a.url = f.join(d, a.url));
	else {
		for (var b = 0, g = Object.keys(d); b < g.length; b++)
			if (c = g[b], -1 !== c.toLocaleLowerCase().indexOf("street") && "vector" === a.type) {
				a = d[c];
    	if (!a)
      		for (b = 0, g = Object.keys(d); b < g.length && (c = g[b], a = d[c], "vector" !== a.type); b++);
  	return a;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.