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

Add separate apis for geometry and rendered feature queries #2106

Closed
ansis opened this issue Feb 11, 2016 · 11 comments
Closed

Add separate apis for geometry and rendered feature queries #2106

ansis opened this issue Feb 11, 2016 · 11 comments

Comments

@ansis
Copy link
Contributor

ansis commented Feb 11, 2016

The current featuresAt matches features based on their geometries instead of their rendered representations. #2052 changes that. With that pr, queries match features in symbol layers if they match the actual symbols that are rendered. They match lines if the query matches the buffered line that is rendered.

@peterqliu pointed out that it's still useful to have a way to get the geometries from vector tiles.

We could either add a parameter to featuresAt to switch between the two query types or we could make two separate methods: one for interacting with features on the map and one for getting raw features from vector tiles.

I'm leaning towards two separate methods because:

  • geometries and rendered features need to be indexed differently. This currently only applies to symbols but it will also apply to 3d things made by extruding 2d polygons.
  • conceptually the two methods are matching different things, not the same thing in different ways
  • the "rendered feature" queries should maybe return something other than geojson:
    • the query is matching a rendered thing, not a geographic feature
    • there is currently no way to get the geometry of the rendered symbol (where is it anchored? how big is it?)
    • there isn't a 1:1 relationship between rendered features and source geometries
      • line symbols can be made for multiple merged vector tile features
      • a single vector tile feature can have multiple line symbols
  • If the raw feature query doesn't depend on paint properties why should it depend on style layer definitions? Why not pass the source-layer and filter as part of the query? This would let you query data not used by the style.

This question is blocking #2052

What do you think? @peterqliu @jfirebaugh @lucaswoj @mourner

@peterqliu
Copy link
Contributor

+1 for separate methods. For raw feature querying, it would be helpful if we could just expose the raw tile geoJSONs as they get decoded from the buffer. Any subsequent filtering (like radial search in featuresAt()) can be done purely on the data side, with tools like turf.

This way, we can draw a clear delineation between the underlying data (best handled by data tools) and their visual representation (the realm of gl-js).

@lucaswoj
Copy link
Contributor

@peterqliu Any naming ideas for names for the two APIs?

@jfirebaugh
Copy link
Contributor

I agree with making featuresAt a query on the rendered representation only, and adding a bulk "tile data" API for raw geometry. We'd:

@peterqliu
Copy link
Contributor

Any naming ideas for names for the two APIs?

it depends how we want to expose the tile data-- as an array of separate tile geojsons, or a single featureCollection with all data currently loaded and cached? Combining them provides the best user experience (won't have to bust out tile-cover to identify the tile you need), but will have to figure out how to distinguish data from different zooms.

@ansis
Copy link
Contributor Author

ansis commented Feb 11, 2016

map.getSourceTileData("sourceID", {
    "source-layer": "roads",
    "filter": ["in", "class", "street_major", "street_minor", "street_limited"], // optional
    "coord": { z: 1, x: 10, y: 4 } // optionally only request one tile
}, function(err, featureCollections) {
});

The callback would be called with an array of geojson FeatureCollections. One for each tile. Each FeatureCollection would have a "coord": { z: 1, x: 10, y: 4 } property.

Does the general idea look good?
Any ideas for better names?
Should it be map.getSource("sourceID").getTileData(...) instead?

@kristfal
Copy link

This is a very interesting feature. How do you expect getSourceTileData handle a tile that has not yet been downloaded?

If the tile could be downloaded on-demand, and provide the source data upon a query, then this feature opens up a whole lot of great use-cases.

@mcwhittemore
Copy link
Contributor

Is the main different between these apis how we are collecting the data or what data we are collecting?

If I'm not mistaken the current featuresAt changed how we are selecting features. This move was from selecting by where features are before styling to selecting by where features are after styling. Is that correct?

With that question out there, is the goal of the second api to select the same data as featuresAt differently or to select a different type of data? Before featuresAt was really for getting the ids and properties of features in an area. The docs said you could get geometry but they discouraged it and for a long time this was broken. I haven't looked too deeply to see if this is even still possible with the featuresAt changes just released.

@peterqliu
Copy link
Contributor

How do you expect getSourceTileData handle a tile that has not yet been downloaded?

@kristfal we don't, yet.

Is the main different between these apis how we are collecting the data or what data we are collecting?

@mcwhittemore both, if I'm understanding you. featuresAt() will retrieve only rendered features within a radius of a certain location. the proposed getSourceTileData() would access the raw vector data for whole tiles, decoupled from styling considerations like collisions and filtering (though this query can have its own filter).

@jfirebaugh
Copy link
Contributor

@mcwhittemore We haven't released any major featuresAt changes yet. Just bugfixes for overscaled tiles, non-4096 extent tiles, etc.

Under this proposal, we would likely remove the radius option from featuresAt. It would return the set of features whose rendered representation covers the queried pixel (or would cover it if the rendering was not covered by other features).

getSourceTileData would return raw tile data (possibly raster pixels as well as vector data) independent of any styling. It's undecided whether it would be able to retrieve tiles that are not in view.

@mcwhittemore
Copy link
Contributor

@jfirebaugh & @peterqliu thanks for clearing things up for me. If featuresAt only selected the things that make up the pixel clicked on that would be great from a mapbox-gl-draw perspective. I think this would be good in Studio too. The big pain point being solved here being trying to click in data rich areas and then needing to sort though a bunch of features.

I don't have any use cases (that I can think of) that require querying for raw tile data in Studio or mapbox-gl-draw right now. I'll think about this more though.

ansis added a commit that referenced this issue Feb 13, 2016
`getSourceTileData` calls the callback with an array of GeoJSON
FeatureCollections (one for each tile).

fixes #2106
@ansis
Copy link
Contributor Author

ansis commented Feb 13, 2016

getSourceTileData is implemented in 6c1b03c

I didn't add the coord param because the concept of tile coords isn't really exposed anywhere yet. Originally I was thinking that someone could listen for tile load events and query based on those but that event isn't documented yet. I'm thinking that we should keep it simple and improve it when we see how it's used.

It doesn't return anything for raster tiles. Should it? How does this fit in with the GeoJSON returned by vector sources?

ansis added a commit that referenced this issue Feb 13, 2016
`getSourceTileData` calls the callback with an array of GeoJSON
FeatureCollections (one for each tile).

fixes #2106
ansis added a commit that referenced this issue Feb 23, 2016
`getSourceTileData` calls the callback with an array of GeoJSON
FeatureCollections (one for each tile).

fixes #2106
ansis added a commit that referenced this issue Mar 9, 2016
`getSourceTileData` calls the callback with an array of GeoJSON
FeatureCollections (one for each tile).

fixes #2106
@lucaswoj lucaswoj changed the title separate apis for geometry and rendered feature queries? Add separate apis for geometry and rendered feature queries Mar 10, 2016
ansis added a commit that referenced this issue Mar 16, 2016
`getSourceTileData` calls the callback with an array of GeoJSON
FeatureCollections (one for each tile).

fixes #2106
ansis added a commit that referenced this issue Mar 17, 2016
`getSourceTileData` calls the callback with an array of GeoJSON
FeatureCollections (one for each tile).

fixes #2106
ansis added a commit that referenced this issue Mar 21, 2016
`getSourceTileData` calls the callback with an array of GeoJSON
FeatureCollections (one for each tile).

fixes #2106
@ansis ansis closed this as completed in 7b0a381 Mar 24, 2016
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