0
# Feature Filtering
1
2
Feature filtering system for creating efficient layer filters based on geometry properties and feature attributes. Enables selective rendering of map features using expression-based and legacy filter formats.
3
4
## Capabilities
5
6
### Feature Filter Creation
7
8
Creates optimized filter functions from filter specifications for efficient feature evaluation.
9
10
```typescript { .api }
11
/**
12
* Creates a feature filter from a filter specification
13
* @param filter - Filter specification (expression or legacy format)
14
* @returns FeatureFilter object with evaluation function and metadata
15
*/
16
function featureFilter(filter: FilterSpecification): FeatureFilter;
17
18
interface FeatureFilter {
19
/** Main filter evaluation function */
20
filter: FilterExpression;
21
/** Optional dynamic filter for runtime properties */
22
dynamicFilter?: FilterExpression;
23
/** Whether filter requires feature geometry */
24
needGeometry: boolean;
25
/** Whether filter requires feature properties */
26
needFeature: boolean;
27
}
28
29
type FilterExpression = (
30
globals: EvaluationContext,
31
feature: any,
32
canonical?: any
33
) => boolean;
34
```
35
36
**Usage Examples:**
37
38
```typescript
39
import { featureFilter } from "@mapbox/mapbox-gl-style-spec";
40
41
// Expression-based filter
42
const filter1 = featureFilter([
43
'all',
44
['==', ['get', 'class'], 'primary'],
45
['>', ['get', 'population'], 50000]
46
]);
47
48
// Legacy format filter
49
const filter2 = featureFilter([
50
'all',
51
['==', 'class', 'primary'],
52
['>', 'population', 50000]
53
]);
54
55
// Test features against filter
56
const feature = {
57
properties: {
58
class: 'primary',
59
population: 75000
60
},
61
geometry: { /* ... */ }
62
};
63
64
const passes = filter1.filter({ zoom: 10 }, feature);
65
console.log(passes); // true
66
```
67
68
### Filter Type Detection
69
70
Utilities for identifying filter format and requirements.
71
72
```typescript { .api }
73
/**
74
* Tests whether a filter uses expression syntax
75
* @param filter - Filter specification to test
76
* @returns True if filter uses expression format
77
*/
78
function isExpressionFilter(filter: FilterSpecification): boolean;
79
```
80
81
**Usage Examples:**
82
83
```typescript
84
import { isExpressionFilter } from "@mapbox/mapbox-gl-style-spec";
85
86
const expressionFilter = ['==', ['get', 'type'], 'restaurant'];
87
const legacyFilter = ['==', 'type', 'restaurant'];
88
89
console.log(isExpressionFilter(expressionFilter)); // true
90
console.log(isExpressionFilter(legacyFilter)); // false
91
```
92
93
### Filter Conversion
94
95
Converts legacy filter formats to modern expression syntax.
96
97
```typescript { .api }
98
/**
99
* Converts legacy filter format to expression syntax
100
* @param filter - Legacy filter specification
101
* @returns Expression-format filter specification
102
*/
103
function convertFilter(filter: FilterSpecification): ExpressionSpecification;
104
```
105
106
**Usage Examples:**
107
108
```typescript
109
import { convertFilter } from "@mapbox/mapbox-gl-style-spec";
110
111
// Convert legacy to expression format
112
const legacyFilter = ['all', ['==', 'class', 'primary'], ['>', 'rank', 5]];
113
const expressionFilter = convertFilter(legacyFilter);
114
115
console.log(expressionFilter);
116
// Result: ['all', ['==', ['get', 'class'], 'primary'], ['>', ['get', 'rank'], 5]]
117
```
118
119
## Filter Specification Types
120
121
### Expression-Based Filters
122
123
Modern filter format using expression syntax for maximum flexibility.
124
125
```typescript { .api }
126
type FilterSpecification =
127
| ExpressionFilterSpecification
128
| LegacyFilterSpecification;
129
130
type ExpressionFilterSpecification =
131
| boolean
132
| ExpressionSpecification;
133
134
// Common expression filter patterns
135
type ComparisonFilter = [
136
'==' | '!=' | '<' | '<=' | '>' | '>=',
137
ExpressionSpecification,
138
ExpressionSpecification
139
];
140
141
type LogicalFilter =
142
| ['all', ...ExpressionSpecification[]]
143
| ['any', ...ExpressionSpecification[]]
144
| ['none', ...ExpressionSpecification[]];
145
146
type MembershipFilter =
147
| ['in', ExpressionSpecification, ExpressionSpecification]
148
| ['!in', ExpressionSpecification, ExpressionSpecification];
149
150
type ExistentialFilter =
151
| ['has', string | ExpressionSpecification]
152
| ['!has', string | ExpressionSpecification];
153
```
154
155
### Legacy Filter Format
156
157
Backward-compatible filter format for older styles.
158
159
```typescript { .api }
160
type LegacyFilterSpecification =
161
| LegacyComparisonFilter
162
| LegacyLogicalFilter
163
| LegacyMembershipFilter
164
| LegacyExistentialFilter;
165
166
type LegacyComparisonFilter = [
167
'==' | '!=' | '<' | '<=' | '>' | '>=',
168
string,
169
string | number | boolean
170
];
171
172
type LegacyLogicalFilter =
173
| ['all', ...LegacyFilterSpecification[]]
174
| ['any', ...LegacyFilterSpecification[]]
175
| ['none', ...LegacyFilterSpecification[]];
176
177
type LegacyMembershipFilter =
178
| ['in', string, ...Array<string | number | boolean>]
179
| ['!in', string, ...Array<string | number | boolean>];
180
181
type LegacyExistentialFilter =
182
| ['has', string]
183
| ['!has', string];
184
```
185
186
## Advanced Filter Patterns
187
188
### Geometric Filters
189
190
Filters based on feature geometry properties.
191
192
```typescript { .api }
193
// Geometry type filters
194
type GeometryTypeFilter = ['==', ['geometry-type'], 'Point' | 'LineString' | 'Polygon'];
195
196
// Geometry ID filters
197
type GeometryIdFilter = ['==', ['id'], string | number];
198
```
199
200
**Usage Examples:**
201
202
```typescript
203
// Filter by geometry type
204
const pointFilter = featureFilter(['==', ['geometry-type'], 'Point']);
205
206
// Filter by feature ID
207
const idFilter = featureFilter(['==', ['id'], 123]);
208
209
// Complex geometric filter
210
const complexFilter = featureFilter([
211
'all',
212
['==', ['geometry-type'], 'Polygon'],
213
['>', ['get', 'area'], 1000000]
214
]);
215
```
216
217
### Distance-Based Filters
218
219
Filters using distance calculations for proximity-based rendering.
220
221
```typescript { .api }
222
interface FeatureDistanceData {
223
center: [number, number];
224
bearing: [number, number];
225
scale: number;
226
}
227
228
// Distance filter example
229
type DistanceFilter = ['<', ['distance', ['literal', [lng, lat]]], number];
230
```
231
232
### State-Based Filters
233
234
Filters using feature state for dynamic styling.
235
236
```typescript { .api }
237
// Feature state filters
238
type FeatureStateFilter = [
239
'==',
240
['feature-state', string],
241
string | number | boolean
242
];
243
```
244
245
**Usage Examples:**
246
247
```typescript
248
// Filter by feature state
249
const stateFilter = featureFilter([
250
'==',
251
['feature-state', 'hover'],
252
true
253
]);
254
255
// Combine with property filters
256
const combinedFilter = featureFilter([
257
'all',
258
['==', ['get', 'type'], 'building'],
259
['==', ['feature-state', 'selected'], true]
260
]);
261
```
262
263
## Types
264
265
```typescript { .api }
266
interface EvaluationContext {
267
zoom: number;
268
heatmapDensity?: number;
269
lineProgress?: number;
270
distanceFromCenter?: number;
271
}
272
273
type FilterExpression = (
274
globals: EvaluationContext,
275
feature: GeoJSONFeature,
276
canonical?: CanonicalTileID
277
) => boolean;
278
279
interface GeoJSONFeature {
280
type: 'Feature';
281
id?: string | number;
282
properties: { [key: string]: any };
283
geometry: GeoJSONGeometry;
284
}
285
286
type GeoJSONGeometry =
287
| { type: 'Point'; coordinates: [number, number] }
288
| { type: 'LineString'; coordinates: Array<[number, number]> }
289
| { type: 'Polygon'; coordinates: Array<Array<[number, number]>> }
290
| { type: 'MultiPoint'; coordinates: Array<[number, number]> }
291
| { type: 'MultiLineString'; coordinates: Array<Array<[number, number]>> }
292
| { type: 'MultiPolygon'; coordinates: Array<Array<Array<[number, number]>>> };
293
```