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

Evaluate query results #9282

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/data/feature_index.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class FeatureIndex {
}

// Finds non-symbol features in this tile at a particular position.
query(args: QueryParameters, styleLayers: {[string]: StyleLayer}, sourceFeatureState: SourceFeatureState): {[string]: Array<{ featureIndex: number, feature: GeoJSONFeature }>} {
query(args: QueryParameters, styleLayers: {[string]: StyleLayer}, serializedLayers: {[string]: Object}, sourceFeatureState: SourceFeatureState): {[string]: Array<{ featureIndex: number, feature: GeoJSONFeature }>} {
this.loadVTLayers();

const params = args.params || {},
Expand Down Expand Up @@ -146,6 +146,7 @@ class FeatureIndex {
filter,
params.layers,
styleLayers,
serializedLayers,
(feature: VectorTileFeature, styleLayer: StyleLayer, id: string | number | void) => {
if (!featureGeometry) {
featureGeometry = loadGeometry(feature);
Expand All @@ -171,6 +172,7 @@ class FeatureIndex {
filter: FeatureFilter,
filterLayerIDs: Array<string>,
styleLayers: {[string]: StyleLayer},
serializedLayers: {[string]: Object},
intersectionTest?: (feature: VectorTileFeature, styleLayer: StyleLayer, id: string | number | void) => boolean | number) {

const layerIDs = this.bucketLayerIDs[bucketIndex];
Expand Down Expand Up @@ -202,19 +204,21 @@ class FeatureIndex {
continue;
}

const serializedLayer = serializedLayers[layerID];
const geojsonFeature = new GeoJSONFeature(feature, this.z, this.x, this.y, id);
(geojsonFeature: any).layer = styleLayer.serialize();
(geojsonFeature: any).layer = serializedLayer;
let layerResult = result[layerID];
if (layerResult === undefined) {
layerResult = result[layerID] = [];
}
layerResult.push({featureIndex, feature: geojsonFeature, intersectionZ});
layerResult.push({featureIndex, feature: geojsonFeature, vtFeature: feature, intersectionZ});
}
}

// Given a set of symbol indexes that have already been looked up,
// return a matching set of GeoJSONFeatures
lookupSymbolFeatures(symbolFeatureIndexes: Array<number>,
serializedLayers: {[string]: Object},
bucketIndex: number,
sourceLayerIndex: number,
filterSpec: FilterSpecification,
Expand All @@ -233,7 +237,8 @@ class FeatureIndex {
symbolFeatureIndex,
filter,
filterLayerIDs,
styleLayers
styleLayers,
serializedLayers
);

}
Expand Down
4 changes: 4 additions & 0 deletions src/source/query_features.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function queryIncludes3DLayer(layers?: Array<string>, styleLayers: {[string]: St

export function queryRenderedFeatures(sourceCache: SourceCache,
styleLayers: {[string]: StyleLayer},
serializedLayers: {[string]: Object},
queryGeometry: Array<Point>,
params: { filter: FilterSpecification, layers: Array<string> },
transform: Transform) {
Expand All @@ -57,6 +58,7 @@ export function queryRenderedFeatures(sourceCache: SourceCache,
wrappedTileID: tileIn.tileID.wrapped().key,
queryResults: tileIn.tile.queryRenderedFeatures(
styleLayers,
serializedLayers,
sourceCache._state,
tileIn.queryGeometry,
tileIn.cameraQueryGeometry,
Expand Down Expand Up @@ -86,6 +88,7 @@ export function queryRenderedFeatures(sourceCache: SourceCache,
}

export function queryRenderedSymbols(styleLayers: {[string]: StyleLayer},
serializedLayers: {[string]: Object},
sourceCaches: {[string]: SourceCache},
queryGeometry: Array<Point>,
params: { filter: FilterSpecification, layers: Array<string> },
Expand All @@ -102,6 +105,7 @@ export function queryRenderedSymbols(styleLayers: {[string]: StyleLayer},
for (const queryData of bucketQueryData) {
const bucketSymbols = queryData.featureIndex.lookupSymbolFeatures(
renderedSymbols[queryData.bucketInstanceId],
serializedLayers,
queryData.bucketIndex,
queryData.sourceLayerIndex,
params.filter,
Expand Down
3 changes: 2 additions & 1 deletion src/source/tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ class Tile {
// Queries non-symbol features rendered for this tile.
// Symbol features are queried globally
queryRenderedFeatures(layers: {[string]: StyleLayer},
serializedLayers: {[string]: Object},
sourceFeatureState: SourceFeatureState,
queryGeometry: Array<Point>,
cameraQueryGeometry: Array<Point>,
Expand All @@ -285,7 +286,7 @@ class Tile {
transform,
params,
queryPadding: this.queryPadding * maxPitchScaleFactor
}, layers, sourceFeatureState);
}, layers, serializedLayers, sourceFeatureState);
}

querySourceFeatures(result: Array<GeoJSONFeature>, params: any) {
Expand Down
55 changes: 47 additions & 8 deletions src/style/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import PauseablePlacement from './pauseable_placement';
import ZoomHistory from './zoom_history';
import CrossTileSymbolIndex from '../symbol/cross_tile_symbol_index';
import {validateCustomStyleLayer} from './style_layer/custom_style_layer';
import {PossiblyEvaluated} from './properties';

// We're skipping validation errors with the `source.canvas` identifier in order
// to continue to allow canvas sources to be added at runtime/updated in
Expand Down Expand Up @@ -1055,6 +1056,38 @@ class Style extends Evented {
return features;
}

evaluateQueryResults(queryResults, featureState) {
const availableImages = this.imageManager.listImages();
if (Object.keys(queryResults).length) {
for (const layerName in queryResults) {
const layer = this._layers[layerName];
const layoutValues = layer.layout._values;
const paintValues = layer.paint._values;

queryResults[layerName].forEach(result => {
if (layoutValues) {
const evaluatedLayout = {};
Object.getOwnPropertyNames(layoutValues).forEach(property => {
const possiblyEvaluatedProperty = layoutValues[property];
evaluatedLayout[property] = possiblyEvaluatedProperty && possiblyEvaluatedProperty.evaluate ? possiblyEvaluatedProperty.evaluate(result.vtFeature, featureState, availableImages) : possiblyEvaluatedProperty;
});
result.feature.layer.layout = evaluatedLayout;
}

if (paintValues) {
const evaluatedPaint = {};
Object.getOwnPropertyNames(paintValues).forEach(property => {
const possiblyEvaluatedProperty = paintValues[property]
evaluatedPaint[property] = possiblyEvaluatedProperty && possiblyEvaluatedProperty.evaluate ? possiblyEvaluatedProperty.evaluate(result.vtFeature, featureState, availableImages) : possiblyEvaluatedProperty;
});
result.feature.layer.paint = evaluatedPaint;
}
});
}
}
return queryResults;
}

queryRenderedFeatures(queryGeometry: any, params: any, transform: Transform) {
if (params && params.filter) {
this._validate(validateStyle.filter, 'queryRenderedFeatures.filter', params.filter, null, params);
Expand All @@ -1078,17 +1111,22 @@ class Style extends Evented {
}

const sourceResults = [];
const serializedLayers = {};
for (const layer in this._layers) {
serializedLayers[layer] = this._layers[layer].serialize();
}

for (const id in this.sourceCaches) {
if (params.layers && !includedSources[id]) continue;
sourceResults.push(
queryRenderedFeatures(
this.sourceCaches[id],
this._layers,
queryGeometry,
params,
transform)
);
let queryResults = queryRenderedFeatures(
this.sourceCaches[id],
this._layers,
serializedLayers,
queryGeometry,
params,
transform);
queryResults = this.evaluateQueryResults(queryResults, this.sourceCaches[id]._state);
sourceResults.push(queryResults);
}

if (this.placement) {
Expand All @@ -1097,6 +1135,7 @@ class Style extends Evented {
sourceResults.push(
queryRenderedSymbols(
this._layers,
serializedLayers,
this.sourceCaches,
queryGeometry,
params,
Expand Down