Description
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
field
Vector tile sources support an id
field for features that SHOULD be unique. We could treat all features with the same id
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 different properties
, which could create some weird edge cases. How would a theoretical map.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 and properties
We could adapt the previous option and use the combination of the id
and properties
as a unique identifier. Features with the same id
but different properties
would be treated as different features. The nice thing about this is that a combined feature always has a well-defined properties
. Also, merging could mostly work in many cases even if id
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:
- the combined feature has a well-defined set of
properties
- features without
id
s don't get merged into one giant feature
Disadvantages of Option 3 compared to Option 2:
- calculating the id could be more expensive since it has to process all the
properties
- 3 could be harder to explain than option 2
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
TileA contains: [ { id: 123, type: 'multipoint', coords: [[10, 20]], properties: { key: value }]
TileB contains: [ { id: 123, type: 'multipoint', coords: [[40, 30]], properties: { key: value }]
mouseover the feature in TileA
both the feature in TileA and in TileB get highlighted
geojson
Source contains [{
id: 123,
geometry: { type: 'Point', coordinates: [10, 20] },
properties: { key: 'value' }
}, {
id: 123,
geometry: { type: 'Point', coordinates: [40, 30] },
properties: { key: 'value' }
}
mouseover the first feature
only the first feature gets highlighted
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