Skip to content

RFC: Feature identity for interactivity #6019

Closed
@ansis

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 ids 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

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions