mapbox-gl-js icon indicating copy to clipboard operation
mapbox-gl-js copied to clipboard

querySourceFeatures returns empty for "invisible" features

Open foundryspatial-duncan opened this issue 8 years ago • 8 comments
trafficstars

mapbox-gl-js version: 0.42.0

Steps to Trigger Behavior

  1. add a few point features as a geojson source
  2. 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,
    },
});
  1. 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.

foundryspatial-duncan avatar Nov 16 '17 00:11 foundryspatial-duncan

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.

jfirebaugh avatar Dec 12 '17 00:12 jfirebaugh

That makes sense! I think a minor tweak of the documentation language could clarify that pretty well.

foundryspatial-duncan avatar Dec 12 '17 01:12 foundryspatial-duncan

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.

jfirebaugh avatar Dec 12 '17 01:12 jfirebaugh

Hi, this issue solved?

elgabato avatar Feb 04 '22 01:02 elgabato

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.

musterknabe avatar Feb 21 '24 17:02 musterknabe

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 ?

manu2495 avatar Apr 30 '24 20:04 manu2495

https://gist.github.com/musterknabe/cf9a1d32fa6eda37b0f7f709f6944315

This is what I'm using as a workaround. No guarantees, tho.

musterknabe avatar May 01 '24 09:05 musterknabe

thanks, but it work only for geojson and I am using vector tiles

manu2495 avatar May 01 '24 16:05 manu2495