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

An option to use a feature property as ID for feature state #8987

Merged
merged 12 commits into from
Dec 2, 2019
Prev Previous commit
Next Next commit
promoteId: geojson support, better flow typing, v8 docs
  • Loading branch information
mourner committed Nov 29, 2019
commit 8271bd0a52d965dc8d3fd4d38537235f62515afc
2 changes: 2 additions & 0 deletions build/generate-flow-typed-style-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ export type FormattedSpecification = string;

export type ResolvedImageSpecification = string;

export type PromoteIdSpecification = {[string]: string} | string;

export type FilterSpecification =
| ['has', string]
| ['!has', string]
Expand Down
21 changes: 6 additions & 15 deletions debug/featurestate.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,7 @@

function resetFeatureState() {
if (selectedCounty) {
map.setFeatureState({
source: 'counties',
sourceLayer: 'original',
id: selectedCounty
}, {hover: false});
map.setFeatureState({source: 'counties', sourceLayer: 'original', id: selectedCounty}, {hover: false});
selectedCounty = null;
}
}
Expand All @@ -62,17 +58,12 @@
});

map.on("mousemove", "counties", (e) => {
for (const feature of e.features) {
if (selectedCounty !== feature.properties.COUNTY) {
resetFeatureState();
selectedCounty = feature.properties.COUNTY;
}
const feature = e.features[0];

map.setFeatureState({
source: 'counties',
sourceLayer: 'original',
id: selectedCounty
}, {hover: true});
if (selectedCounty !== feature.id) {
resetFeatureState();
map.setFeatureState({source: 'counties', sourceLayer: 'original', id: feature.id}, {hover: true});
selectedCounty = feature.id;
}
});
});
Expand Down
6 changes: 3 additions & 3 deletions src/data/feature_index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {polygonIntersectsBox} from '../util/intersection_tests';
import type StyleLayer from '../style/style_layer';
import type {FeatureFilter} from '../style-spec/feature_filter';
import type Transform from '../geo/transform';
import type {FilterSpecification} from '../style-spec/types';
import type {FilterSpecification, PromoteIdSpecification} from '../style-spec/types';

import {FeatureIndexArray} from './array_types';

Expand All @@ -46,15 +46,15 @@ class FeatureIndex {
grid: Grid;
grid3D: Grid;
featureIndexArray: FeatureIndexArray;
promoteId: ?{[string]: string} | string;
promoteId: ?PromoteIdSpecification;

rawTileData: ArrayBuffer;
bucketLayerIDs: Array<Array<string>>;

vtLayers: {[string]: VectorTileLayer};
sourceLayerCoder: DictionaryCoder;

constructor(tileID: OverscaledTileID, promoteId?: ?{[string]: string} | string) {
constructor(tileID: OverscaledTileID, promoteId?: ?PromoteIdSpecification) {
this.tileID = tileID;
this.x = tileID.canonical.x;
this.y = tileID.canonical.y;
Expand Down
7 changes: 5 additions & 2 deletions src/source/geojson_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type Tile from './tile';
import type Actor from '../util/actor';
import type {Callback} from '../types/callback';
import type {GeoJSON, GeoJSONFeature} from '@mapbox/geojson-types';
import type {GeoJSONSourceSpecification} from '../style-spec/types';
import type {GeoJSONSourceSpecification, PromoteIdSpecification} from '../style-spec/types';

/**
* A source containing GeoJSON.
Expand Down Expand Up @@ -69,6 +69,7 @@ class GeoJSONSource extends Evented implements Source {
maxzoom: number;
tileSize: number;
attribution: string;
promoteId: ?PromoteIdSpecification;

isTileClipped: boolean;
reparseOverscaled: boolean;
Expand Down Expand Up @@ -114,6 +115,7 @@ class GeoJSONSource extends Evented implements Source {
if (options.maxzoom !== undefined) this.maxzoom = options.maxzoom;
if (options.type) this.type = options.type;
if (options.attribution) this.attribution = options.attribution;
this.promoteId = options.promoteId;

const scale = EXTENT / this.tileSize;

Expand Down Expand Up @@ -295,7 +297,8 @@ class GeoJSONSource extends Evented implements Source {
tileSize: this.tileSize,
source: this.id,
pixelRatio: browser.devicePixelRatio,
showCollisionBoxes: this.map.showCollisionBoxes
showCollisionBoxes: this.map.showCollisionBoxes,
promoteId: this.promoteId
};

tile.request = this.actor.send(message, params, (err, data) => {
Expand Down
4 changes: 2 additions & 2 deletions src/source/vector_tile_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type Dispatcher from '../util/dispatcher';
import type Tile from './tile';
import type {Callback} from '../types/callback';
import type {Cancelable} from '../types/cancelable';
import type {VectorSourceSpecification} from '../style-spec/types';
import type {VectorSourceSpecification, PromoteIdSpecification} from '../style-spec/types';

class VectorTileSource extends Evented implements Source {
type: 'vector';
Expand All @@ -28,7 +28,7 @@ class VectorTileSource extends Evented implements Source {
url: string;
scheme: string;
tileSize: number;
promoteId: ?{[string]: string};
promoteId: ?PromoteIdSpecification;

_options: VectorSourceSpecification;
_collectResourceTiming: boolean;
Expand Down
3 changes: 2 additions & 1 deletion src/source/worker_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {CollisionBoxArray} from '../data/array_types';
import type DEMData from '../data/dem_data';
import type {StyleGlyph} from '../style/style_glyph';
import type {StyleImage} from '../style/style_image';
import type {PromoteIdSpecification} from '../style-spec/types';

export type TileParameters = {
source: string,
Expand All @@ -23,7 +24,7 @@ export type WorkerTileParameters = TileParameters & {
zoom: number,
maxZoom: number,
tileSize: number,
promoteId: ?{[string]: string} | string,
promoteId: ?PromoteIdSpecification,
pixelRatio: number,
showCollisionBoxes: boolean,
collectResourceTiming?: boolean,
Expand Down
3 changes: 2 additions & 1 deletion src/source/worker_tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import type {
WorkerTileParameters,
WorkerTileCallback,
} from '../source/worker_source';
import type {PromoteIdSpecification} from '../style-spec/types';

class WorkerTile {
tileID: OverscaledTileID;
Expand All @@ -34,7 +35,7 @@ class WorkerTile {
pixelRatio: number;
tileSize: number;
source: string;
promoteId: ?{[string]: string} | string;
promoteId: ?PromoteIdSpecification;
overscaling: number;
showCollisionBoxes: boolean;
collectResourceTiming: boolean;
Expand Down
14 changes: 11 additions & 3 deletions src/style-spec/reference/v8.json
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@
"default": "mapbox",
"doc": "The encoding used by this source. Mapbox Terrain RGB is used by default"
},
"promoteId": {
"type": "promoteId",
"doc": "A property to use as a feature id (for feature state). Either a property name, or an object of the form `{<sourceLayer>: <propertyName>}`."
},
"*": {
"type": "*",
"doc": "Other keys to configure the data source."
Expand Down Expand Up @@ -383,9 +387,13 @@
"doc": "Whether to calculate line distance metrics. This is required for line layers that specify `line-gradient` values."
},
"generateId": {
"type": "boolean",
"default": false,
"doc": "Whether to generate ids for the geojson features. When enabled, the `feature.id` property will be auto assigned based on its index in the `features` array, over-writing any previous values."
"type": "boolean",
"default": false,
"doc": "Whether to generate ids for the geojson features. When enabled, the `feature.id` property will be auto assigned based on its index in the `features` array, over-writing any previous values."
},
"promoteId": {
"type": "promoteId",
"doc": "A property to use as a feature id (for feature state). Either a property name, or an object of the form `{<sourceLayer>: <propertyName>}`."
}
},
"source_video": {
Expand Down
8 changes: 6 additions & 2 deletions src/style-spec/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export type FormattedSpecification = string;

export type ResolvedImageSpecification = string;

export type PromoteIdSpecification = {[string]: string} | string;

export type FilterSpecification =
| ['has', string]
| ['!has', string]
Expand Down Expand Up @@ -110,7 +112,8 @@ export type RasterDEMSourceSpecification = {
"maxzoom"?: number,
"tileSize"?: number,
"attribution"?: string,
"encoding"?: "terrarium" | "mapbox"
"encoding"?: "terrarium" | "mapbox",
"promoteId"?: PromoteIdSpecification
}

export type GeoJSONSourceSpecification = {|
Expand All @@ -125,7 +128,8 @@ export type GeoJSONSourceSpecification = {|
"clusterMaxZoom"?: number,
"clusterProperties"?: mixed,
"lineMetrics"?: boolean,
"generateId"?: boolean
"generateId"?: boolean,
"promoteId"?: PromoteIdSpecification
|}

export type VideoSourceSpecification = {|
Expand Down