[Maps] Simplify IDynamicStyle-api (#79217)
This commit is contained in:
parent
85528d0ecd
commit
86cb97adf6
|
@ -6,7 +6,8 @@
|
|||
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import { Feature } from 'geojson';
|
||||
import { Feature, FeatureCollection } from 'geojson';
|
||||
import { FeatureIdentifier, Map as MbMap } from 'mapbox-gl';
|
||||
import { AbstractStyleProperty, IStyleProperty } from './style_property';
|
||||
import { DEFAULT_SIGMA } from '../vector_style_defaults';
|
||||
import {
|
||||
|
@ -44,20 +45,14 @@ export interface IDynamicStyleProperty<T> extends IStyleProperty<T> {
|
|||
isOrdinal(): boolean;
|
||||
supportsFieldMeta(): boolean;
|
||||
getFieldMetaRequest(): Promise<unknown>;
|
||||
supportsMbFeatureState(): boolean;
|
||||
getMbLookupFunction(): MB_LOOKUP_FUNCTION;
|
||||
pluckOrdinalStyleMetaFromFeatures(features: Feature[]): RangeFieldMeta | null;
|
||||
pluckCategoricalStyleMetaFromFeatures(features: Feature[]): CategoryFieldMeta | null;
|
||||
getValueSuggestions(query: string): Promise<string[]>;
|
||||
|
||||
// Returns the name that should be used for accessing the data from the mb-style rule
|
||||
// Depending on
|
||||
// - whether the field is used for labeling, icon-orientation, or other properties (color, size, ...), `feature-state` and or `get` is used
|
||||
// - whether the field was run through a field-formatter, a new dynamic field is created with the formatted-value
|
||||
// The combination of both will inform what field-name (e.g. the "raw" field name from the properties, the "computed field-name" for an on-the-fly created property (e.g. for feature-state or field-formatting).
|
||||
// todo: There is an existing limitation to .mvt backed sources, where the field-formatters are not applied. Here, the raw-data needs to be accessed.
|
||||
getMbPropertyName(): string;
|
||||
getMbPropertyValue(value: RawValue): RawValue;
|
||||
enrichGeoJsonAndMbFeatureState(
|
||||
featureCollection: FeatureCollection,
|
||||
mbMap: MbMap,
|
||||
mbSourceId: string
|
||||
): boolean;
|
||||
}
|
||||
|
||||
export class DynamicStyleProperty<T>
|
||||
|
@ -356,6 +351,12 @@ export class DynamicStyleProperty<T>
|
|||
);
|
||||
}
|
||||
|
||||
// Returns the name that should be used for accessing the data from the mb-style rule
|
||||
// Depending on
|
||||
// - whether the field is used for labeling, icon-orientation, or other properties (color, size, ...), `feature-state` and or `get` is used
|
||||
// - whether the field was run through a field-formatter, a new dynamic field is created with the formatted-value
|
||||
// The combination of both will inform what field-name (e.g. the "raw" field name from the properties, the "computed field-name" for an on-the-fly created property (e.g. for feature-state or field-formatting).
|
||||
// todo: There is an existing limitation to .mvt backed sources, where the field-formatters are not applied. Here, the raw-data needs to be accessed.
|
||||
getMbPropertyName() {
|
||||
if (!this._field) {
|
||||
return '';
|
||||
|
@ -385,6 +386,35 @@ export class DynamicStyleProperty<T>
|
|||
// Calling `isOrdinal` would be equivalent.
|
||||
return this.supportsMbFeatureState() ? getNumericalMbFeatureStateValue(rawValue) : rawValue;
|
||||
}
|
||||
|
||||
enrichGeoJsonAndMbFeatureState(
|
||||
featureCollection: FeatureCollection,
|
||||
mbMap: MbMap,
|
||||
mbSourceId: string
|
||||
): boolean {
|
||||
const supportsFeatureState = this.supportsMbFeatureState();
|
||||
const featureIdentifier: FeatureIdentifier = {
|
||||
source: mbSourceId,
|
||||
id: undefined,
|
||||
};
|
||||
const featureState: Record<string, RawValue> = {};
|
||||
const targetMbName = this.getMbPropertyName();
|
||||
for (let i = 0; i < featureCollection.features.length; i++) {
|
||||
const feature = featureCollection.features[i];
|
||||
const rawValue = feature.properties ? feature.properties[this.getFieldName()] : undefined;
|
||||
const targetMbValue = this.getMbPropertyValue(rawValue);
|
||||
if (supportsFeatureState) {
|
||||
featureState[targetMbName] = targetMbValue; // the same value will be potentially overridden multiple times, if the name remains identical
|
||||
featureIdentifier.id = feature.id;
|
||||
mbMap.setFeatureState(featureIdentifier, featureState);
|
||||
} else {
|
||||
if (feature.properties) {
|
||||
feature.properties[targetMbName] = targetMbValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return supportsFeatureState;
|
||||
}
|
||||
}
|
||||
|
||||
export function getNumericalMbFeatureStateValue(value: RawValue) {
|
||||
|
|
|
@ -641,7 +641,7 @@ export class VectorStyle implements IVectorStyle {
|
|||
featureCollection: FeatureCollection,
|
||||
mbMap: MbMap,
|
||||
mbSourceId: string
|
||||
) {
|
||||
): boolean {
|
||||
if (!featureCollection) {
|
||||
return false;
|
||||
}
|
||||
|
@ -651,40 +651,24 @@ export class VectorStyle implements IVectorStyle {
|
|||
return false;
|
||||
}
|
||||
|
||||
const tmpFeatureIdentifier: FeatureIdentifier = {
|
||||
source: '',
|
||||
id: undefined,
|
||||
};
|
||||
const tmpFeatureState: any = {};
|
||||
|
||||
for (let i = 0; i < featureCollection.features.length; i++) {
|
||||
const feature = featureCollection.features[i];
|
||||
|
||||
for (let j = 0; j < dynamicStyleProps.length; j++) {
|
||||
const dynamicStyleProp = dynamicStyleProps[j];
|
||||
const targetMbName = dynamicStyleProp.getMbPropertyName();
|
||||
const rawValue = feature.properties
|
||||
? feature.properties[dynamicStyleProp.getFieldName()]
|
||||
: undefined;
|
||||
const targetMbValue = dynamicStyleProp.getMbPropertyValue(rawValue);
|
||||
if (dynamicStyleProp.supportsMbFeatureState()) {
|
||||
tmpFeatureState[targetMbName] = targetMbValue; // the same value will be potentially overridden multiple times, if the name remains identical
|
||||
} else {
|
||||
if (feature.properties) {
|
||||
feature.properties[targetMbName] = targetMbValue;
|
||||
}
|
||||
}
|
||||
let shouldResetAllData = false;
|
||||
for (let j = 0; j < dynamicStyleProps.length; j++) {
|
||||
const dynamicStyleProp = dynamicStyleProps[j];
|
||||
const usedFeatureState = dynamicStyleProp.enrichGeoJsonAndMbFeatureState(
|
||||
featureCollection,
|
||||
mbMap,
|
||||
mbSourceId
|
||||
);
|
||||
if (!usedFeatureState) {
|
||||
shouldResetAllData = true;
|
||||
}
|
||||
tmpFeatureIdentifier.source = mbSourceId;
|
||||
tmpFeatureIdentifier.id = feature.id;
|
||||
mbMap.setFeatureState(tmpFeatureIdentifier, tmpFeatureState);
|
||||
}
|
||||
|
||||
// returns boolean indicating if styles do not support feature-state and some values are stored in geojson properties
|
||||
// this return-value is used in an optimization for style-updates with mapbox-gl.
|
||||
// `true` indicates the entire data needs to reset on the source (otherwise the style-rules will not be reapplied)
|
||||
// `false` indicates the data does not need to be reset on the store, because styles are re-evaluated if they use featureState
|
||||
return dynamicStyleProps.some((dynamicStyleProp) => !dynamicStyleProp.supportsMbFeatureState());
|
||||
return shouldResetAllData;
|
||||
}
|
||||
|
||||
arePointsSymbolizedAsCircles() {
|
||||
|
|
Loading…
Reference in a new issue