-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
RFC: Feature identity for interactivity #6019
Comments
Where a feature is not present contiguously in tiles, how would the set of tiles for a feature be computed? Does a tree of feature bounds need to be generated as tiles are loaded? |
I like option 2, which covers most use cases but with simplicity. In practice, I use tippecanoe to convert geojson to vector tiles. The geojson is generated with GDAL with the option I think we should chose the simplicity way than a complex one. The API of mapbox-gl-js provide a highlight feature based on |
@asheemmamoowala I'm not sure I understand the question, where would the set of tiles for a feature be used? @jingsam thanks for the feedback! |
I think this expense could well be insurmountable for some cases: in some datasets, each feature has a lot of property data. I lean towards option 4 -- i.e., add a new style-spec property for layers, |
@anandthakker interesting! I hadn't considered that default. What are the main use cases you see for custom id expressions? Would these expressions be set at the source level or the layer level? Would these merge features just for built-in hovering or also event listeners and queries? Would a combined feature have multiple sets of properties instead of just one? |
If we implement Option 1, 2, or 3 now, it'd be relatively easy to implement Option 4 down the road. |
@flippmoke and I have been talking about this in the context of revising the vector tile spec. There is (as far as I know) no implementation yet, but our general idea was to add a unique ID (distinct from the GeoJSON feature ID) to features that are split between tiles, with additional IDs or serial numbers at the nodes where features transition in or out of the tile boundaries, so the original complete geometry can be reconstructed from its tiled components. |
When re-constituting features across tiles:
@ericfischer not sure if your suggestion addresses the above problem. |
@asheemmamoowala I think what we were talking about would address the first need but not the second. We could add a complete bounding box as well as an ID to features when they are split though. |
I think we could check all visible tiles for whether they contain the feature. This way we wouldn't need to store the bounds
This would involve loading all the missing tiles, right? Since that could be a massive number the best solution here might be to just include the bbox in the features' properties when creating the custom tiles for that specific use |
This is going off on a tangent but labelling is probably the most common use case of using GeoJSON GeometryCollections to have both a Point (label) and Polygon as part of the same feature sharing the common properties. If data came in like this it would make it easier to support hover style on the label even when hovering over the polygon only. However MVT don't support GeometryCollections so these are split into different features and I presume get different IDs. |
One case for this would be performance-related, for dealing with datasets where each feature has a prohibitively large set of properties, most of which are not needed to identify the feature. E.g., a dataset that doesn't have Another use is one where the identity of 'features' users are interacting with is more dynamic -- e.g., maybe you want to switch, at runtime, whether hovering over a park represents the intent to focus on "this particular park (as opposed to other parks)" or "parks (as opposed to residences or businesses or schools)".
Good questions. Initial thoughts:
|
With Option 2 for updating the appearance, the properties may be modified dynamically. How would the |
Neat! Just a little drive-by comment... we're implementing a dedupe path in vtquery (mapbox/vtquery#51) which adds a couple more checks. Only deduping if features are from the same layer and are the same geometries type (since GeomCollections aren't allowed in the spec). If so, it uses the ID to dedupe first, but falls back on comparing the |
@mapsam thanks for the link. It's definitely helpful to read about similar problems. I think we can't use the tag integers in this case because they'll be different in different tiles. We talked about this last week and it seems like the consensus is to go with Option 2 ( |
For reference, the iOS and macOS SDKs effectively implement option 3 in mapbox/mapbox-gl-native#6559. (This affects direct calls to |
#6263 introduces new feature state APIs for updating the appearance of features using the top level While this works for some datasets, most of the datasets I used for demos/examples are missing the Results from Lines 1378 to 1383 in a09aeae
A layer-specific custom identifier would prevent results from being used among different layers (example(comment)). A feature should have a unique identifier per source that can be reused for any/all APIs regardless of layer. With a custom identifier, a new field would be needed for the complete feature identifier. Some name options: feature: {
id: string|number,
properties: {...},
state: {...},
// Use a new id field
query-id: { source: string, sourceLayer?: string, id: any } ,
// Generate hashed id from source, sourceLayer, custom id field
feature-id: string,
// Generate UUID for each feature and internally map to the feature using the cusotm identifier
feature-key: UUID
} |
@ansis @mollymerp and I discussed an alternative where GeoJSON sources generate internal feature IDs, or allow promotion of a property attribute to feature id. In conjunction with #6021, this could enable interactivity on a large portion of existing datasets. |
I wanted to mention that features created in the Mapbox Datasets Editor will automatically get a Feature ID assigned, I just discovered that when you export that Dataset to a Tileset, the Tileset Features get new and different IDs. This makes it harder to do feature interactivity when you're working with both (eg. have a list of features populated from the Datasets API and a corresponding set of features on the Map from the Tileset no longer share the same IDs) |
Hi! |
Tippecanoe will preserve integer feature IDs. Maybe your IDs that are being lost are strings (which can't be represented in the current vector tile format)? You can use |
You are right, making them integer instead of String fixed it, thanks! |
Hi ! I am currently generating MVT layer from Postgis, using ST_AsMVT. The generated features doesn't have id, but have id properties. Thx for your help ! |
I'm a new user of mapbox-gl.js and am having trouble see if this is resolved or not. I need to join a json table to with my own ID attribute to vector tiles with polygons that have the same ID attribute. The feature IDs used to join in the https://www.mapbox.com/mapbox-gl-js/example/data-join/ example are not going to work. The feature.id of the polygons I uploaded were generated automatically by Mapbox Studio when I created the vector tiles. Zooming in and out also changes the IDs of the polygons as found by Would someone mind linking the the resolution or let me know if it's open or closed. I'm very new to source control as well. |
@devPuppySim this this ticket will remain open until a solution has been built and merged. Until then, if you need a work around, try the latest release of tippecanoe to create vector tiles with the correct |
@asheemmamoowala thank you for the response. I will try tippecanoe then |
Does this ticket also address the issue where i do EDIT: |
@shayke That is correct - a feature should have a consistent ID across all tiles and zoom levels.
A MapDataEvent is fired for every tile load (and reload). Setting state for all the tile features requires knowing all their IDs. You could use |
@BBegouin did you manage to solve this problem? As far as I can see the Postgis team are working on this feature, but it is scheduled for release in 3.0 (https://trac.osgeo.org/postgis/ticket/4128). Until this is updated, I can't figure out a way to take advantage of the feature state functions. Thanks! |
I share @jacknkandy's problem, it would be massively helpful to promote Even if this is not currently supported as an option, is there a way to intercept the tiles on load to make this change? cc @lobenichou |
@waissbluth @jacknkandy Hey folks! There is a couple of things that come to mind:
So your best bet (I think) would be to export into a geoJSON instead of MVT using |
AFAIK, note that |
Hi @lobenichou, Thanks for your response and your suggestion. Unfortunately for us I don't think we will be able to move away from using the PostGIS MVT functions and generate our vector tiles using Tippecanoe. I have currently built a NodeJS + Postgres/PostGIS based tile server which generates vector tiles on the fly based on dynamic queries (various filters, etc.). Also the underlying datasets are quite massive (some have 3 million+ features). So we would not be able to pre-generate all tiles due to the extremely large data size as well as the fact that we are unable to predict all possible combinations of queries. From my brief reading of the Tippecanoe documentation it appears to be a command-line based tool (so it would be difficult to integrate with a NodeJS based server) but also appears that it would not be so effective at generating dynamic tile sets on the fly. Maybe mapbox/geojson-vt could be a possible alternative - but it seems to be more of a client-based library rather than server-side. I think I might just have to wait for the PostGIS 3.0 release. |
Is there a way to at least monkey patch the vector tile parser to promote |
I have geojson, no ID, no objectID, field. No other field could be unique value column. The hove-over failed to work. As of May 2019, 1 year and half later, have above genius made a magic? I temporary fix it by, add a new geojson-layer( create from the hove-overed-geojson). By the way,
now I get feature[0] as hove-overed-feature, |
Motivation
Vector tile sources split features across multiple tiles.
How do we tell if two features in different tiles are actually the same feature?
How do we highlight a feature across tile boundaries?
How do we only dispatch a feature event listener once, not once-per-tile?
We need some concept of what makes things "the same feature".
For GeoJSON sources we have access to whole features so we can assign them ids guaranteed to be unique.
Design Alternatives
Option 1: do nothing
Treat vector tile features from different tiles as different features (like we do currently).
Option 2: use the
id
fieldVector tile sources support an
id
field for features that SHOULD be unique. We could treat all features with the sameid
as the same feature. Users would need to provide this in order for interactivity to work well.It could be possible to have multiple features with the same
id
but differentproperties
, which could create some weird edge cases. How would a theoreticalmap.getFeatureProperties(sourceID, featureID)
handle this case?Would features with missing
id
fields get merged into one feature? Or never get merged?Option 3: use the combination of the
id
field andproperties
We could adapt the previous option and use the combination of the
id
andproperties
as a unique identifier. Features with the sameid
but differentproperties
would be treated as different features. The nice thing about this is that a combined feature always has a well-definedproperties
. Also, merging could mostly work in many cases even ifid
is not provided.Option 4: Using a user defined function
We could extend the style spec to let users specify an expression to calculate a unique id. This expression could default to
["id"]
. This would provide a way to merge features together but it would also add extra complexity to the style spec.This would have the same problem as Option 2, where a single combined feature could have multiple different
properties
objects.Also, would this apply to just vector tile sources, or also geojson?
Design
I think we should implement Option 3.
Option 2 could be fine too.
Advantages of Option 3 over Option 2:
properties
id
s don't get merged into one giant featureDisadvantages of Option 3 compared to Option 2:
properties
Option 4 provides extra power but also extra complexity. I think that users that need this could implement it with event listeners and data joining.
Mock-Up
vector tiles
geojson
Concepts
Hopefully this should be mostly intuitive. Users encountering unexpected behavior for vector tile interaction could be told to add a unique
id
to each of their features.@kkaefer @asheemmamoowala @mollymerp @anandthakker @mourner @lucaswoj
The text was updated successfully, but these errors were encountered: