Closed meetar closed 6 years ago
/cc @burritojustice
@nvkelso 🤫
Can you say a bit more about the intended use cases? Since it only covers the layers in currently visible tiles, it is a very specific feature.
I just want to understand more because while it's a small code scope, I don't think a core purpose of Tangram should be to explore unknown data (vs. styling known data). If you don't know what the layers are, you won't be able to see them anyway.
It also may make sense to do this as a sub-case of queryFeatures()
(e.g. group by layer) instead, without expanding the public API surface more.
Again it's a fairly small addition but I do think we should be focusing library scope (obviously we have not in the past! :) with an eye towards managing and improving library size etc.
@bcamper Sure, it could definitely be something included as an option in queryFeatures()
– that would probably make more sense.
The primary use case would be for adding a "layers" interface in style-creation apps such as Tangram Play. It would also be useful in situations where you have an un- or poorly-documented datasource in a non-human-readable format, and you'd like to know which layers are available in the current view. This information is already decoded by the tiles-processing mechanism but not exposed anywhere.
Right, I think there are some interesting things that could be gleaned from it, I guess I just think it's of questionable value for something like Play, where you essentially have to say "here are the layers we've seen so far, but there might be more, who knows!"
TileJSON is a more comprehensive/intentional way of solving that problem, and Play could support that.
Separately, it also just occurred to me that however this kind of thing is implemented, it should specify which source name the layer belongs to, since scenes can have multiple sources and there could even be layer name collisions between them.
I took a stab at adding support for this (and more!) in queryFeatures()
, which results in a smaller code change footprint and API change:
https://github.com/tangrams/tangram/compare/query-layers
This adds properties for $source
, $layer
, and $geometry
to the features returned by queryFeatures()
. You could already filter
these in queryFeatures()
calls (using the same filter syntax we use in the scene file), but this allows you to also use the group_by
feature with them. In addition, a $visible
property was added. While this property (by definition!) doesn't exist for a scene file filter
, it's a logical extension here.
You can do some neat things with these options, such as:
Features grouped by layer (with feature count for each):
scene.queryFeatures({ group_by: '$layer' })
Features grouped by layer and kind
:
scene.queryFeatures({ group_by: ['$layer', 'kind'] })
Features grouped by layer and geometry type:
scene.queryFeatures({ group_by: ['$layer', '$geometry'] })
Features grouped by layer and visibility:
scene.queryFeatures({ group_by: ['$layer', '$visible'] })
Or even a more granular breakdown:
scene.queryFeatures({ group_by: ['$layer', '$geometry', '$visible'] })
💯 to including the layer in the query results! I've wanted to include that in the debug UX for a long while :)
The only potential oddity with the above branch is that these "special" properties are added directly to the properties
in the returned GeoJSON objects. When filtering source data in the scene file, these properties are implied, but not actually in the same namespace as the feature properties themselves. If you had source data that contained any of these property names, currently those properties would be overridden when accessed via queryFeatures()
. Another option would be to put them outside the properties
on the GeoJSON, but then they wouldn't be accessible to any standard GeoJSON-reading software. It was also faster/smaller to code it this way.
Hmm @nvkelso that's a different call entirely, scene.getFeatureAt()
for "what is the feature at this specific point" vs. scene.queryFeatures()
which is a broader syntax to query all the features in the current visible tile set. It's relevant to my point above though because getFeatureAt()
does have data source name and layer included, though as separate properties, like this:
The difference is that getFeatureAt()
doesn't return a real GeoJSON object, just a plain JSON. Anyway maybe trying to normalize these makes sense... or maybe it's not worth it. Overall I think it's more useful to have actual GeoJSON-styles results, but it would be a breaking change to getFeatureAt()
.
Cool! That works for me. I access them with $source_layer
and $source_name
?
Yep but no need for the leading $
:)
Closing this and replacing with #676. I brought come of the comments over as well.
Similar to queryFeatures() but just a list of available layer names from the datasource, rather than from the scene file as in
scene.config.layers
.Allows simple querying in cases when the data isn't human-readable or already known. Also allows run-time style building in these cases, as well as dynamic "layers" UI construction.