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

Diagram to illustrate difference between queryRenderedFeatures and querySourceFeatures #3751

Closed
kronick opened this issue Dec 6, 2016 · 9 comments
Assignees

Comments

@kronick
Copy link

kronick commented Dec 6, 2016

Proposing to add a diagram to the docs to more clearly illustrate the different between what queryRenderedFeatures() and querySourceFeatures() do, to clear up confusion as in #3744. I can follow the visual style set in https://www.mapbox.com/vector-tiles/specification/. Open to opinions on how to integrate raster images if I go that route, or I can build these as inline SVGs.

cc/ @lyzidiamond @tmcw @danswick

@lucaswoj
Copy link
Contributor

lucaswoj commented Dec 6, 2016

🙌 Thank you @kronick! I'm excited about this. If the docs are destined for https://www.mapbox.com/mapbox-gl-js/api you can drop any raster images in docs/assets.

@kronick
Copy link
Author

kronick commented Dec 9, 2016

Here is my first pass at these diagrams:

queryrenderedfeatures

querysourcefeatures

@kronick
Copy link
Author

kronick commented Dec 9, 2016

Here are some past issues from users confused by the behavior of these functions. These diagrams should attempt to clarify such confusion:
#2481 #3744 #3666 #2400 #2378 #3099 #3147

Also linking to past efforts to improve the documentation text: #2429

@tmcw
Copy link
Contributor

tmcw commented Dec 9, 2016

Okay, thanks for taking a whack at this @kronick .

In terms of getting this live, a few things:

  • You're going to be writing for the medium: so roughly here. These images are something like a 1x3 aspect ratio right now, so they'd take up a full screenful of API documentation. That would likely be awkward. Similarly, this text will only get smaller when it's added to the docs.
  • Are you sure that you want to integrate text and graphics like this, rather than having body text and the graphic be explained by one text chunk? Otherwise you'll have to deal with percentage-based text sizing on the embedded graphic, which is both technically and aesthetically challenging.
  • In the second example, the results of querySourceFeatures don't add up to the inputs. While this isn't an exact science, if the idea is that querySourceFeatures includes things outside of the viewport, we will need to explicitly show them outside of the viewport. Similarly with queryRenderedFeatures: the things that it retrieves also aren't shown as inputs: there are two diamonds out and one diamond in.
  • Uppercase as emphasis (NOT) is not part of Mapbox's house style. These diagrams also use italic for emphasis. I would say styled emphasis isn't required here.
  • "Features on vector tiles outside the current viewport" can be interpreted in two ways
    • Features on (vector tiles outside the current viewport)
    • (Features on vector tiles) outside the current viewport
  • The first is correct and the second is not, and both are valid readings: the documentation should avoid this type of ambiguity.

@lucaswoj
Copy link
Contributor

lucaswoj commented Dec 9, 2016

Looks like a great start @kronick.

Another important distinction between queryRenderedFeatures and querySourceFeatures (perhaps even the raison d'être of qRF) is that the size and position of the rendered feature may differ significantly than the size and position of the source feature.

Take, for example, a GeoJSON point at [0, 0]. This source feature has an infinitesimal size and is positioned at [0, 0]. A corresponding rendered symbol feature with an offset of [100, 100] and an icon size of 50 will have a size of 50px by 50px and centered around [100, 100].

The differences between query options are hopefully going to go away in the near future 😄.

@kronick
Copy link
Author

kronick commented Dec 9, 2016

@tmcw: In the second example, the results of querySourceFeatures don't add up to the inputs. While this isn't an exact science, if the idea is that querySourceFeatures includes things outside of the viewport, we will need to explicitly show them outside of the viewport. Similarly with queryRenderedFeatures: the things that it retrieves also aren't shown as inputs: there are two diamonds out and one diamond in.

This is the confusion (i.e. #3147) I'm trying to clear up and I believe what I'm diagramming is the real, though somewhat counterintuitive, behavior: points will be duplicated in the result set if they occur in more than one VT, accounting for label size in qRF and VT buffer zone in qSF. So yes, in real life one diamond near the border of tiles in => two diamonds out. If the diagrams make a reader think "something strange is happening here, I better read this more carefully," I think they are doing their job. Let me know if you think I could make this more clear.

@lucaswoj That's a good distinction too and if I understand correctly, it's what makes querying with a point geometry work— qRF returns all features with rendered bounding boxes that collide with your query geometry, not just those included completely within the query bounding box, right? I am not showing point queries here or features that are partially included in the query bounding box... maybe I should.

In the end, I don't think we'll capture all the subtleties and features of these functions in a couple of diagrams, but these are the big questions I hope to clear up with a visual aid:

  1. Why are some points from my data not returned by queryRenderedFeatures()? Reason: qRF() does not return features hidden due to collisions; it only returns features that are actually rendered
  2. Why does query*Features() give me duplicate features? Reason: These functions are querying the underlying vector tiles where for various reasons features near tile borders may be duplicated
  3. Why does query*Features() split my lines and polygons into fragments? Reason: Similar to (2), geometry is split between VTs
  4. Why doesn't querySourceFeatures() give me all my data points? Reason: querySourceFeatures() only gives you results from currently loaded vector tiles. If you want all data, use another method.

@arethasamuel
Copy link

How do we get all data from the vector tiles ? (This is in reference to previous answer: "If you want all data, use another method" --> what is the other method?

@lucaswoj
Copy link
Contributor

@arethasamuel The answer to that question depends highly on your use case.

If you're doing serious data processing, you might want to use something like https://wiki.openstreetmap.org/wiki/Overpass_API to access OSM data directly. Our vector tiles are optimized for rendering rather than data processing.

@StavroMueller
Copy link

StavroMueller commented Mar 15, 2018

I am having some issues with this as well, and it seems like there may be a way to accomplish what I want simply, but it is hard to find the correct way with the docs and API.

I am building an overlap UI, where we use the clicked point (from the click event) to get the list of overlapping features on the map, and then clipping the geometry of all the features together in order to show the area that overlaps. This works fine if you are zoomed out to the full bounds of all geometries, but if you zoom in close to where the geometry fills the current view area, only the vector tile's geometry is given in both the event and queryRenderedFeatures.

This results in, when you zoom out, the clipped geometry being the size of the viewport when it should actually include the whole geometry of that feature, even if it is bigger in area than the viewport. It is a bit frustrating not having a direct way to access the full geometry of the features that are clicked. I am not sure that this need constitutes "serious data processing", as all I need is the full geometry to be returned from these functions.

Right now, I am having to take a round trip back to the original source of each layer and filter for that specific feature.

Edit: This explanation is a bit confusing, so here is a jsFiddle: http://jsfiddle.net/t6s4yrdz/11/

All you need to do is click, then zoom out.

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

No branches or pull requests

6 participants