Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

queryRenderedFeatures returns duplicate results #3099

Closed
sleepycat opened this issue Aug 30, 2016 · 5 comments
Closed

queryRenderedFeatures returns duplicate results #3099

sleepycat opened this issue Aug 30, 2016 · 5 comments

Comments

@sleepycat
Copy link

Please see the JSbin that reproduces this issue.

mapbox-gl-js version: 0.23.0

Steps to Trigger Behavior

  1. Pan and zoom the map to focus on Mapbox DC.
  2. Look at the console to see the number of features reported by queryRenderedFeatures

Expected Behavior

With a single feature rendered, the expected behaviour is that queryRenderedFeatures returns a single copy of that feature.

Actual Behavior

QueryRenderedFeatures returns between 0 and 4 copies of the same feature.

This issue may be related to #2647. That issue is reporting that sometimes no data is returned. At issue here is that when data is returned, it's multiple copies of the same data.

If you feel this is a duplicate (oh the irony) feel free to close or fold it into #2647 .

@davidtheclark
Copy link
Contributor

@sleepycat There's a caveat mentioned in the docs that may be the reason you're seeing this:

Because features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature geometries are clipped at tile boundaries and, as a result, features may appear multiple times in query results when they span multiple tiles. For example, suppose there is a highway running through the bounding rectangle of a query. The results of the query will be those parts of the highway that lie within the map tiles covering the bounding rectangle, even if the highway extends into other tiles, and the portion of the highway within each map tile will be returned as a separate feature.

@sleepycat
Copy link
Author

@davidtheclark: Thanks for pointing that out. I had read that at some point and it had slipped my mind.

These are just single points, so I wouldn't expect them to span tiles. If I turn on showTileBoundaries it doesn't look like the bounds ever really get close to these particular markers. So at least at first glance it looks like something else is going on.

@lucaswoj
Copy link
Contributor

lucaswoj commented Sep 2, 2016

@sleepycat The intent of queryRenderedFeatures is to query the geometry of the rendered shapes on the map (including labels) rather than the underlying source geometry. Labels are 2 dimensional shapes that do span tile boundaries.

@lucaswoj lucaswoj closed this as completed Sep 2, 2016
@sleepycat
Copy link
Author

With 65 points in bounds in my "markers" layer and 5 rendered I get:

map.querySourceFeatures("markers", {filter: ["has", "address"]}).length
Array[258]
map.queryRenderedFeatures({layers: ["markers"]}).length
14

I'm expecting querySourceFeatures to return 65 and queryRenderedFeatures to return 5.

The fact that the features are sometimes split across tiles and therefore shows up multiple times seems to be a detail/side-effect of the underlying implementation.

I guess what's being questioned here is the value of exposing those implementation details to the callers of queryRenderedFeatures and querySourceFeatures.

Does having the same point show up 2-4 times in the results array impart some information that they can act on?

My particular usecase (you can decide how representative of the average that is), is that I want to generate a summary chart of the various types of markers within the current bounds.

If the current behaviour of queryRenderedFeatures and querySourceFeatures makes sense in some other context, perhaps there could be an option or another method which would return a non-duplicated array?

Thoughts?

@jfirebaugh
Copy link
Contributor

The reasons that query*Features doesn't do deduplication automatically:

  • It would have to require that every source feature have a unique identifier, in order to have a key on which to base deduplication. Not all sources do.
  • For lines and polygons, it would be expected to union the feature geometries, an expensive and algorithmically-difficult operation. There are no good JS implementations of geometry union; this is something we are working on with turf but it's a difficult problem.
  • It still wouldn't solve the issue that if a feature is partially offscreen, those tiles aren't loaded, and therefore the geometry will necessarily be incomplete. Therefore even if deduplicating and merging were done automatically, it would still have the caveat that it's a lossy operation.

Mapbox GL JS is primarily a rendering library. The implementation of query*Features is provided as a convenience accessor to the tile data backing the rendering, and is not intended to be a general purpose GIS query tool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants