Mapbox-gl-js: querySourceFeatures returns empty for "invisible" features

Created on 16 Nov 2017  ·  3Comments  ·  Source: mapbox/mapbox-gl-js

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.

docs

Most helpful comment

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.

All 3 comments

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.

Was this page helpful?
0 / 5 - 0 ratings