mapbox/mapbox-gl-js

querySourceFeatures not working as expected

Closed this issue · 8 comments

It seems that querySourceFeatures only considers features within the current map bounds.

Is this the expected behavior? The documentation suggests it considers all the source data, regardless of bounds. I believe it would be more useful to query all source data, since queryRenderedFeatures exists for querying within bounds.

This is the expected behaviour. querySourceFeatures only operates on currently-visible vector tiles.

We will update our docs to clarify this behaviour.

OK, then does it make sense to combine the 2 methods? There is really little difference expect that queryRenderedFeatures has an optional bounding box and a source is not required (does this query all sources then) ? Unless I'm misunderstanding something.

queryRenderedFeatures({
    pointOrBox: Mixed
    sourceId: String,
    layers: Mixed 
    filter: Array, 
})

I still believe it would be useful to add another method which queried across all tiles (even non-visible). Although the client can still do this by filtering on map._data.

OK, then does it make sense to combine the 2 methods? There is really little difference expect that queryRenderedFeatures has an optional bounding box and a source is not required (does this query all sources then) ?

  • queryRenderedFeatures is concerned with what's rendered on the map, accounting for the shape of labels, symbols, translated geometries, etc
  • querySourceFeatures is concerned with raw feature geometries

I still believe it would be useful to add another method which queried across all tiles (even non-visible). Although the client can still do this by filtering on map._data.

This feature is not possible. querySourceFeatures must work for both GeoJSON and vector tile sources. To query across all times in a vector tile source could easily require downloading hundreds of gigabytes of data. If you need access to the entire GeoJSON file, you should use the GeoJSON file.

I have an instance where I need to query features that are within the maps current bounding box, but are on layer which is currently not visible. Is this possible with either? Or is there another workaround that you suggest?

@facultymatt querySourceFeatures should work for your use case

Thanks @lucaswoj, querySourceFeatures - I'm still confused with the behavior and not sure what you mean by "currently-visible vector tiles". The behavior that I observe with querySourceFeatures is that it queries geometry which IS VISIBLE and IS WITHIN MAP BOUNDING BOX. So in the case of my layer which is not visible no data is returned.

Maybe you can help with the outcome I need:

  • I have 2 layers, Points which are not visible and Lines which are visible.
  • Starting zoomed out to the max, all geometry is visible in map bounding box
  • I zoom in so only a few geometries are within the map bounding box.
  • I want to filter points (which are not visible) within the map bounding box, optionally using filters.

Any suggestions? I know that I could always querySourceFeatures and then use turf within to filter inside the map bounds, but ideally I would not need the additional dependency.

Thanks for helping with this! Obviously querySourceFeatures and queryRenderedFeatures are very powerful once they are understood!

It sounds to me like you should use turf within

The docs still misleads people into thinking this filters against all features.

Returns an array of GeoJSON Feature objects representing features within the specified vector tile or GeoJSON source that satisfy the query parameters.

No mention of the fact that it seems to be filtering against the visible map area and the visible state of the features themselves.

Why have a method named in this way when you have queryRenderedFeatures if it behaves in the same way? For my use case I am trying to do this for GeoJSON.

Further down in the docs it says:

In contrast to Map#queryRenderedFeatures, this function returns all features matching the query parameters, whether or not they are rendered by the current style (in other words, are visible). 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.