1

The documentation for Map.querySourceFeatures says it takes a parameter for sourceID - the ID of the vector tile or GeoJSON source. In their example, they add a source manually:

map.addSource('counties', {
    "type": "vector",
    "url": "mapbox://mapbox.82pkq93d"
});

And so the sourceID is counties.

If I create a Mapbox style in Mapbox Studio and publish it with a url, say:

mapbox://styles/mycoolcompany/mycoolmap123

and pass that directly to the Map constructor like this:

this.map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mycoolcompany/mycoolmap123',
    center: [-123.12, 49.28],
    zoom: 5,
});

How can I get (or set?) the styleID programatically? I'm trying different combinations of things from Mapbox Studio but querySourceFeatures returns an empty array every time with no exceptions or indication of what it's missing.

More succinctly: how do I use querySourceFeatures on a home-made Mapbox Studio Style?

(mapbox-gl 0.36.0)

4

There isn't a public API to get all source IDs from a map, but

this.map.style.sourceCaches

will return an object wherein each key is a source ID and its value is a source cache (the class responsible for managing an individual source).

Note that Mapbox Studio automatically composites sources — so, if you've added a custom vector source, rather than having multiple vector sources you'll likely see just one (composite), and if you were to download the JSON stylesheet its URL would be something like

"url": "mapbox://mapbox.mapbox-streets-v7,mycoolcompany.randomsha"

so you'll probably be looking for a source called composite.

2
  • Thank you, that answers my question and I was able to get querySourceFeatures returning values. For anyone else puzzling over querySourceFeatures returning empty arrays, you will probably need to dive into map.style.sourceCaches described above and make a note of the source and sourceLayer names. – DMack Apr 25 '17 at 18:50
  • I think a more correct way would be Object.keys(this.map.getStyle().sources). No need to go anywhere near sourceCaches. – Steve Bennett Feb 22 at 1:33
1

I understand it's an old post but putting the notes for someone it can help!

So, how do I get the source for querySourceFeatures()?

Here's the one-liner:

map.querySourceFeatures('composite', {sourceLayer: 'source-name', filter: [filters]})

So - what is composite, what is sourceLayer, what is filter?

Well first, we need to get to the composite source id and pass that to source param. Then we get the tileset id of the layer we are working on and pass that to sourceLayer param. And finally, get the applied filters on the layer we are working on and pass that to filter param.

To start with, we need to have the composite source id from the layer or the layer that you are working with:

// get the source from the layer, `mapLayerId` is the layer id
// this can be found in Mapbox Studio's styles editor
// or use your layer id if you created in the code 
var compositeSource = map.getLayer(mapLayerId.toString()).source;

Then to get the tileset id, we need to get what it's called the vectorlayer from that source, so:

console.log(map.getSource(compositeSource).vectorLayers);

The vectorslayers is essentially an JS object and contains all the tilesets that we have in Mapbox Studio.

Now, if we are dealing with only the latest vector layer, like me - because in my Mapbox Studio that's the tileset I created and all other tilesets are default ones and I am not using them, it will appear on the last element of the object. In this case, we can grab the last element of the returned object of vectorslayers and get its id, this id is the actual tileset id.

var compositeVectorLayerLength = map.getSource(compositeSource).vectorLayers.length - 1;
console.log(compositeVectorLayerLength);
// sourceId === tileset id which is known as vector layer id
var sourceId = map.getSource(compositeSource).vectorLayers[compositeVectorLayerLength].id;

We then get all the filters that were already applied on the layer we are working with:

var appliedFilters = map.getFilter(mapLayerId.toString());
console.log(appliedFilters);

Now, we call querySourceFeatures() passing all these values:

var resultFeatures = map.querySourceFeatures(compositeSource, {sourceLayer: sourceId, filter: appliedFilters});

The resultFeatures will be a JS object which will have all the features on the map.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.