Skip to content

Commit

Permalink
Fix using within expression with complex filter (#9611)
Browse files Browse the repository at this point in the history
* Fix within usage with othere expressions in the same filter

* Add render tests

* Fix filter operator checking for nested condition
  • Loading branch information
zmiao authored and karimnaaji committed May 13, 2020
1 parent 8de5d36 commit 2547bce
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 3 deletions.
12 changes: 11 additions & 1 deletion src/style-spec/feature_filter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ function createFilter(filter: any): FeatureFilter {
if (compiled.result === 'error') {
throw new Error(compiled.value.map(err => `${err.key}: ${err.message}`).join(', '));
} else {
const needGeometry = Array.isArray(filter) && filter.length !== 0 && filter[0] === 'within';
const needGeometry = geometryNeeded(filter);
return {filter: (globalProperties: GlobalProperties, feature: Feature, canonical?: CanonicalTileID) => compiled.value.evaluate(globalProperties, feature, {}, canonical),
needGeometry};
}
Expand All @@ -96,6 +96,15 @@ function compare(a, b) {
return a < b ? -1 : a > b ? 1 : 0;
}

function geometryNeeded(filter) {
if (!Array.isArray(filter)) return false;
if (filter[0] === 'within') return true;
for (let index = 1; index < filter.length; index++) {
if (geometryNeeded(filter[index])) return true;
}
return false;
}

function convertFilter(filter: ?Array<any>): mixed {
if (!filter) return true;
const op = filter[0];
Expand All @@ -114,6 +123,7 @@ function convertFilter(filter: ?Array<any>): mixed {
op === '!in' ? convertNegation(convertInOp(filter[1], filter.slice(2))) :
op === 'has' ? convertHasOp(filter[1]) :
op === '!has' ? convertNegation(convertHasOp(filter[1])) :
op === 'within' ? filter :
true;
return converted;
}
Expand Down
3 changes: 3 additions & 0 deletions src/style-spec/reference/v8.json
Original file line number Diff line number Diff line change
Expand Up @@ -2450,6 +2450,9 @@
},
"!has": {
"doc": "`[\"!has\", key]` `feature[key]` does not exist"
},
"within": {
"doc": "`[\"within\", object]` feature geometry is within object geometry"
}
},
"doc": "The filter operator."
Expand Down
10 changes: 8 additions & 2 deletions src/style-spec/validate/validate_filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,14 @@ function validateNonExpressionFilter(options) {
errors.push(new ValidationError(`${key}[1]`, value[1], `string expected, ${type} found`));
}
break;

case 'within':
type = getType(value[1]);
if (value.length !== 2) {
errors.push(new ValidationError(key, value, `filter array for "${value[0]}" operator must have 2 elements`));
} else if (type !== 'object') {
errors.push(new ValidationError(`${key}[1]`, value[1], `object expected, ${type} found`));
}
break;
}

return errors;
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"version": 8,
"metadata": {
"test": {
"width": 64,
"height": 64
}
},
"zoom": 3,
"center": [2.5, 2.5],
"sources": {
"points": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"number": [5]
},
"geometry": {
"type": "Point",
"coordinates": [
1.9775390625,
2.3284603685731593
]
}
},
{
"type": "Feature",
"properties": {
"number": [5]
},
"geometry": {
"type": "Point",
"coordinates": [
1.7138671875,
-1.7136116598836224
]
}
}
]
}
},
"polygon": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[[0, 0],
[0, 5],
[5, 5],
[5, 0],
[0, 0]]
]
}
}
]
}
}
},
"layers": [
{
"id": "border",
"type": "fill",
"source": "polygon",
"paint": {
"fill-color": "black",
"fill-opacity": 0.5
}
},
{
"id": "circle",
"type": "circle",
"source": "points",
"filter": ["all", ["in", 5, ["get", "number"]], ["==", ["within", {
"type": "Polygon",
"coordinates": [
[
[0, 0],
[0, 5],
[5, 5],
[5, 0],
[0, 0]
]
]
}], true]
],
"paint": {
"circle-radius": 5,
"circle-color": "red"
}
}
]
}

0 comments on commit 2547bce

Please sign in to comment.