mapbox-gl-js
mapbox-gl-js copied to clipboard
querySourceFeatures returns empty for "invisible" features
mapbox-gl-js version: 0.42.0
Steps to Trigger Behavior
- add a few point features as a geojson source
- add a layer from the source, with
visibility: 'none':
this.map.addLayer({
id: 'foobar',
type: 'circle',
source: 'foobar-points',
layout: {
visibility: 'none',
},
paint: {
'circle-color': '#222',
'circle-radius': 6,
},
});
- use querySourceFeatures on the source and examine the returned array
const sourceFeatures = map.querySourceFeatures('foobar-points');
Expected Behavior
As per the docs: returns all features matching the query parameters, whether or not they are rendered by the current style (i.e. visible).
Actual Behavior
querySourceFeatures returns an empty array.
However if you leave the layer visible but hide everything with a filter, querySourceFeatures does return the expected output (all of the features in the viewport)
this.map.addLayer({
id: 'foobar',
type: 'circle',
source: 'foobar-points',
filter: ['has', 'nothingHasThis'],
paint: {
'circle-color': '#222',
'circle-radius': 6,
},
});
The other thing I didn't expect from the API documentation is the fact that you need to add a layer at all. I thought you could simply add a source and then query it without having to put it in a layer. This is so I can get the source features within a radius so I can try to predict what is inside a supercluster.
This behavior is due to the fact that GL JS does not load tiles for sources that are not used, i.e. have no visible layers. In such a situation, the following caveat for querySourceFeatures applies:
The domain of the query includes all currently-loaded vector tiles and GeoJSON source tiles: this function does not check tiles outside the currently visible viewport.
That makes sense! I think a minor tweak of the documentation language could clarify that pretty well.
Yeah, we can definitely clarify the docs. I wonder how feasible it would be change this behavior for GeoJSON sources specifically (since the data is all client-side)... not sure.
Hi, this issue solved?
I think this function is misnamed. It does not query the source features, it queries features that are on visible tiles in the current viewport.
It doesn't help that the doc is contradicting itself, either.
This function returns all features ... whether or not they are rendered ... (in other words, are visible)
vs.
This function does not check tiles outside the currently visible viewport.
Where "does not check tiles" means "does not return features", I guess.
(For BC's sake) I would suggest to add a flag that makes the function do what it's name implies: Return all source features that pass the filter query. Something like parameters.includeInvisbleFeatures.
what is the resolution of that ? what happen if I can get all features (visibles and not visible) from a source ? can this be posible with this or other function ?
https://gist.github.com/musterknabe/cf9a1d32fa6eda37b0f7f709f6944315
This is what I'm using as a workaround. No guarantees, tho.
thanks, but it work only for geojson and I am using vector tiles