@mapbox/mapbox-gl-style-spec 13.22.0-beta.1 → 13.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/diff.js +8 -1
- package/dist/index.cjs +475 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +475 -64
- package/dist/index.es.js.map +1 -1
- package/expression/definitions/index.js +10 -0
- package/expression/evaluation_context.js +30 -0
- package/expression/index.js +9 -3
- package/expression/parsing_context.js +1 -1
- package/feature_filter/index.js +183 -22
- package/package.json +1 -1
- package/reference/v8.json +190 -11
- package/style-spec.js +1 -1
- package/types.js +7 -0
- package/validate/validate.js +3 -1
- package/validate/validate_expression.js +33 -2
- package/validate/validate_filter.js +3 -1
- package/validate/validate_layer.js +3 -1
- package/validate/validate_projection.js +30 -0
package/dist/index.cjs
CHANGED
|
@@ -99,6 +99,21 @@
|
|
|
99
99
|
delay: 0
|
|
100
100
|
}
|
|
101
101
|
},
|
|
102
|
+
projection: {
|
|
103
|
+
type: "projection",
|
|
104
|
+
doc: "The projection the map should be rendered in. Suported projections are Albers, Equal Earth, Equirectangular (WGS84), Lambert conformal conic, Mercator, Natural Earth, and Winkel Tripel. Terrain, fog, sky and CustomLayerInterface are not supported for projections other than mercator.",
|
|
105
|
+
example: {
|
|
106
|
+
name: "albers",
|
|
107
|
+
center: [
|
|
108
|
+
-154,
|
|
109
|
+
50
|
|
110
|
+
],
|
|
111
|
+
parallels: [
|
|
112
|
+
55,
|
|
113
|
+
65
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
},
|
|
102
117
|
layers: {
|
|
103
118
|
required: true,
|
|
104
119
|
type: "array",
|
|
@@ -657,7 +672,7 @@
|
|
|
657
672
|
},
|
|
658
673
|
filter: {
|
|
659
674
|
type: "filter",
|
|
660
|
-
doc: "
|
|
675
|
+
doc: "An expression specifying conditions on source features. Only features that match the filter are displayed. Zoom expressions in filters are only evaluated at integer zoom levels. The `[\"feature-state\", ...]` expression is not supported in filter expressions. The `[\"pitch\"]` and `[\"distance-from-center\"]` expressions are supported only for filter expressions on the symbol layer."
|
|
661
676
|
},
|
|
662
677
|
layout: {
|
|
663
678
|
type: "layout",
|
|
@@ -2481,6 +2496,78 @@
|
|
|
2481
2496
|
value: "*",
|
|
2482
2497
|
doc: "A filter selects specific features from a layer."
|
|
2483
2498
|
};
|
|
2499
|
+
var filter_symbol = {
|
|
2500
|
+
type: "boolean",
|
|
2501
|
+
doc: "Expression which determines whether or not to display a symbol. Symbols support dynamic filtering, meaning this expression can use the `[\"pitch\"]` and `[\"distance-from-center\"]` expressions to reference the current state of the view.",
|
|
2502
|
+
"default": false,
|
|
2503
|
+
transition: false,
|
|
2504
|
+
"property-type": "data-driven",
|
|
2505
|
+
expression: {
|
|
2506
|
+
interpolated: false,
|
|
2507
|
+
parameters: [
|
|
2508
|
+
"zoom",
|
|
2509
|
+
"feature",
|
|
2510
|
+
"pitch",
|
|
2511
|
+
"distance-from-center"
|
|
2512
|
+
]
|
|
2513
|
+
}
|
|
2514
|
+
};
|
|
2515
|
+
var filter_fill = {
|
|
2516
|
+
type: "boolean",
|
|
2517
|
+
doc: "Expression which determines whether or not to display a polygon. Fill layer does NOT support dynamic filtering, meaning this expression can NOT use the `[\"pitch\"]` and `[\"distance-from-center\"]` expressions to reference the current state of the view.",
|
|
2518
|
+
"default": false,
|
|
2519
|
+
transition: false,
|
|
2520
|
+
"property-type": "data-driven",
|
|
2521
|
+
expression: {
|
|
2522
|
+
interpolated: false,
|
|
2523
|
+
parameters: [
|
|
2524
|
+
"zoom",
|
|
2525
|
+
"feature"
|
|
2526
|
+
]
|
|
2527
|
+
}
|
|
2528
|
+
};
|
|
2529
|
+
var filter_line = {
|
|
2530
|
+
type: "boolean",
|
|
2531
|
+
doc: "Expression which determines whether or not to display a Polygon or LineString. Line layer does NOT support dynamic filtering, meaning this expression can NOT use the `[\"pitch\"]` and `[\"distance-from-center\"]` expressions to reference the current state of the view.",
|
|
2532
|
+
"default": false,
|
|
2533
|
+
transition: false,
|
|
2534
|
+
"property-type": "data-driven",
|
|
2535
|
+
expression: {
|
|
2536
|
+
interpolated: false,
|
|
2537
|
+
parameters: [
|
|
2538
|
+
"zoom",
|
|
2539
|
+
"feature"
|
|
2540
|
+
]
|
|
2541
|
+
}
|
|
2542
|
+
};
|
|
2543
|
+
var filter_circle = {
|
|
2544
|
+
type: "boolean",
|
|
2545
|
+
doc: "Expression which determines whether or not to display a circle. Circle layer does NOT support dynamic filtering, meaning this expression can NOT use the `[\"pitch\"]` and `[\"distance-from-center\"]` expressions to reference the current state of the view.",
|
|
2546
|
+
"default": false,
|
|
2547
|
+
transition: false,
|
|
2548
|
+
"property-type": "data-driven",
|
|
2549
|
+
expression: {
|
|
2550
|
+
interpolated: false,
|
|
2551
|
+
parameters: [
|
|
2552
|
+
"zoom",
|
|
2553
|
+
"feature"
|
|
2554
|
+
]
|
|
2555
|
+
}
|
|
2556
|
+
};
|
|
2557
|
+
var filter_heatmap = {
|
|
2558
|
+
type: "boolean",
|
|
2559
|
+
doc: "Expression used to determine whether a point is being displayed or not. Heatmap layer does NOT support dynamic filtering, meaning this expression can NOT use the `[\"pitch\"]` and `[\"distance-from-center\"]` expressions to reference the current state of the view.",
|
|
2560
|
+
"default": false,
|
|
2561
|
+
transition: false,
|
|
2562
|
+
"property-type": "data-driven",
|
|
2563
|
+
expression: {
|
|
2564
|
+
interpolated: false,
|
|
2565
|
+
parameters: [
|
|
2566
|
+
"zoom",
|
|
2567
|
+
"feature"
|
|
2568
|
+
]
|
|
2569
|
+
}
|
|
2570
|
+
};
|
|
2484
2571
|
var filter_operator = {
|
|
2485
2572
|
type: "enum",
|
|
2486
2573
|
values: {
|
|
@@ -3010,7 +3097,7 @@
|
|
|
3010
3097
|
}
|
|
3011
3098
|
},
|
|
3012
3099
|
length: {
|
|
3013
|
-
doc: "
|
|
3100
|
+
doc: "Returns the length of an array or string.",
|
|
3014
3101
|
group: "Lookup",
|
|
3015
3102
|
"sdk-support": {
|
|
3016
3103
|
"basic functionality": {
|
|
@@ -3022,7 +3109,7 @@
|
|
|
3022
3109
|
}
|
|
3023
3110
|
},
|
|
3024
3111
|
properties: {
|
|
3025
|
-
doc: "
|
|
3112
|
+
doc: "Returns the feature properties object. Note that in some cases, it may be more efficient to use `[\"get\", \"property_name\"]` directly.",
|
|
3026
3113
|
group: "Feature data",
|
|
3027
3114
|
"sdk-support": {
|
|
3028
3115
|
"basic functionality": {
|
|
@@ -3043,7 +3130,7 @@
|
|
|
3043
3130
|
}
|
|
3044
3131
|
},
|
|
3045
3132
|
"geometry-type": {
|
|
3046
|
-
doc: "
|
|
3133
|
+
doc: "Returns the feature's geometry type: `Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`. `Multi*` feature types are only returned in GeoJSON sources. When working with vector tile sources, use the singular forms.",
|
|
3047
3134
|
group: "Feature data",
|
|
3048
3135
|
"sdk-support": {
|
|
3049
3136
|
"basic functionality": {
|
|
@@ -3055,7 +3142,7 @@
|
|
|
3055
3142
|
}
|
|
3056
3143
|
},
|
|
3057
3144
|
id: {
|
|
3058
|
-
doc: "
|
|
3145
|
+
doc: "Returns the feature's id, if it has one.",
|
|
3059
3146
|
group: "Feature data",
|
|
3060
3147
|
"sdk-support": {
|
|
3061
3148
|
"basic functionality": {
|
|
@@ -3067,8 +3154,8 @@
|
|
|
3067
3154
|
}
|
|
3068
3155
|
},
|
|
3069
3156
|
zoom: {
|
|
3070
|
-
doc: "
|
|
3071
|
-
group: "
|
|
3157
|
+
doc: "Returns the current zoom level. Note that in style layout and paint properties, [\"zoom\"] may only appear as the input to a top-level \"step\" or \"interpolate\" expression.",
|
|
3158
|
+
group: "Camera",
|
|
3072
3159
|
"sdk-support": {
|
|
3073
3160
|
"basic functionality": {
|
|
3074
3161
|
js: "0.41.0",
|
|
@@ -3078,8 +3165,26 @@
|
|
|
3078
3165
|
}
|
|
3079
3166
|
}
|
|
3080
3167
|
},
|
|
3168
|
+
pitch: {
|
|
3169
|
+
doc: "Returns the current pitch in degrees. `[\"pitch\"]` may only be used in the `filter` expression for a `symbol` layer.",
|
|
3170
|
+
group: "Camera",
|
|
3171
|
+
"sdk-support": {
|
|
3172
|
+
"basic functionality": {
|
|
3173
|
+
js: "2.6.0"
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3176
|
+
},
|
|
3177
|
+
"distance-from-center": {
|
|
3178
|
+
doc: "Returns the distance of a `symbol` instance from the center of the map. The distance is measured in pixels divided by the height of the map container. It measures 0 at the center, decreases towards the camera and increase away from the camera. For example, if the height of the map is 1000px, a value of -1 means 1000px away from the center towards the camera, and a value of 1 means a distance of 1000px away from the camera from the center. `[\"distance-from-center\"]` may only be used in the `filter` expression for a `symbol` layer.",
|
|
3179
|
+
group: "Camera",
|
|
3180
|
+
"sdk-support": {
|
|
3181
|
+
"basic functionality": {
|
|
3182
|
+
js: "2.6.0"
|
|
3183
|
+
}
|
|
3184
|
+
}
|
|
3185
|
+
},
|
|
3081
3186
|
"heatmap-density": {
|
|
3082
|
-
doc: "
|
|
3187
|
+
doc: "Returns the kernel density estimation of a pixel in a heatmap layer, which is a relative measure of how many data points are crowded around a particular pixel. Can only be used in the `heatmap-color` property.",
|
|
3083
3188
|
group: "Heatmap",
|
|
3084
3189
|
"sdk-support": {
|
|
3085
3190
|
"basic functionality": {
|
|
@@ -3091,7 +3196,7 @@
|
|
|
3091
3196
|
}
|
|
3092
3197
|
},
|
|
3093
3198
|
"line-progress": {
|
|
3094
|
-
doc: "
|
|
3199
|
+
doc: "Returns the progress along a gradient line. Can only be used in the `line-gradient` property.",
|
|
3095
3200
|
group: "Feature data",
|
|
3096
3201
|
"sdk-support": {
|
|
3097
3202
|
"basic functionality": {
|
|
@@ -3103,7 +3208,7 @@
|
|
|
3103
3208
|
}
|
|
3104
3209
|
},
|
|
3105
3210
|
"sky-radial-progress": {
|
|
3106
|
-
doc: "
|
|
3211
|
+
doc: "Returns the distance of a point on the sky from the sun position. Returns 0 at sun position and 1 when the distance reaches `sky-gradient-radius`. Can only be used in the `sky-gradient` property.",
|
|
3107
3212
|
group: "sky",
|
|
3108
3213
|
"sdk-support": {
|
|
3109
3214
|
"basic functionality": {
|
|
@@ -3114,7 +3219,7 @@
|
|
|
3114
3219
|
}
|
|
3115
3220
|
},
|
|
3116
3221
|
accumulated: {
|
|
3117
|
-
doc: "
|
|
3222
|
+
doc: "Returns the value of a cluster property accumulated so far. Can only be used in the `clusterProperties` option of a clustered GeoJSON source.",
|
|
3118
3223
|
group: "Feature data",
|
|
3119
3224
|
"sdk-support": {
|
|
3120
3225
|
"basic functionality": {
|
|
@@ -3793,6 +3898,92 @@
|
|
|
3793
3898
|
}
|
|
3794
3899
|
}
|
|
3795
3900
|
};
|
|
3901
|
+
var projection = {
|
|
3902
|
+
name: {
|
|
3903
|
+
type: "enum",
|
|
3904
|
+
values: {
|
|
3905
|
+
albers: {
|
|
3906
|
+
doc: "An Albers equal-area projection centered on the continental United States. You can configure the projection for a different region by setting `center` and `parallels` properties. You may want to set max bounds to constrain the map to the relevant region."
|
|
3907
|
+
},
|
|
3908
|
+
equalEarth: {
|
|
3909
|
+
doc: "An Equal Earth projection."
|
|
3910
|
+
},
|
|
3911
|
+
equirectangular: {
|
|
3912
|
+
doc: "An Equirectangular projection. This projection is very similar to the Plate Carrée projection."
|
|
3913
|
+
},
|
|
3914
|
+
lambertConformalConic: {
|
|
3915
|
+
doc: "A Lambert conformal conic projection. You can configure the projection for a region by setting `center` and `parallels` properties. You may want to set max bounds to constrain the map to the relevant region."
|
|
3916
|
+
},
|
|
3917
|
+
mercator: {
|
|
3918
|
+
doc: "The Mercator projection is the default projection."
|
|
3919
|
+
},
|
|
3920
|
+
naturalEarth: {
|
|
3921
|
+
doc: "A Natural Earth projection."
|
|
3922
|
+
},
|
|
3923
|
+
winkelTripel: {
|
|
3924
|
+
doc: "A Winkel Tripel projection."
|
|
3925
|
+
}
|
|
3926
|
+
},
|
|
3927
|
+
"default": "mercator",
|
|
3928
|
+
doc: "The name of the projection to be used for rendering the map.",
|
|
3929
|
+
required: true,
|
|
3930
|
+
"sdk-support": {
|
|
3931
|
+
"basic functionality": {
|
|
3932
|
+
js: "2.6.0"
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3935
|
+
},
|
|
3936
|
+
center: {
|
|
3937
|
+
type: "array",
|
|
3938
|
+
length: 2,
|
|
3939
|
+
value: "number",
|
|
3940
|
+
"property-type": "data-constant",
|
|
3941
|
+
transition: false,
|
|
3942
|
+
doc: "The reference longitude and latitude of the projection. `center` takes the form of [lng, lat]. This property is only configurable for conic projections (Albers and Lambert Conformal Conic). All other projections are centered on [0, 0].",
|
|
3943
|
+
example: [
|
|
3944
|
+
-96,
|
|
3945
|
+
37.5
|
|
3946
|
+
],
|
|
3947
|
+
requires: [
|
|
3948
|
+
{
|
|
3949
|
+
name: [
|
|
3950
|
+
"albers",
|
|
3951
|
+
"lambertConformalConic"
|
|
3952
|
+
]
|
|
3953
|
+
}
|
|
3954
|
+
],
|
|
3955
|
+
"sdk-support": {
|
|
3956
|
+
"basic functionality": {
|
|
3957
|
+
js: "2.6.0"
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3960
|
+
},
|
|
3961
|
+
parallels: {
|
|
3962
|
+
type: "array",
|
|
3963
|
+
length: 2,
|
|
3964
|
+
value: "number",
|
|
3965
|
+
"property-type": "data-constant",
|
|
3966
|
+
transition: false,
|
|
3967
|
+
doc: "The standard parallels of the projection, denoting the desired latitude range with minimal distortion. `parallels` takes the form of [lat0, lat1]. This property is only configurable for conic projections (Albers and Lambert Conformal Conic).",
|
|
3968
|
+
example: [
|
|
3969
|
+
29.5,
|
|
3970
|
+
45.5
|
|
3971
|
+
],
|
|
3972
|
+
requires: [
|
|
3973
|
+
{
|
|
3974
|
+
name: [
|
|
3975
|
+
"albers",
|
|
3976
|
+
"lambertConformalConic"
|
|
3977
|
+
]
|
|
3978
|
+
}
|
|
3979
|
+
],
|
|
3980
|
+
"sdk-support": {
|
|
3981
|
+
"basic functionality": {
|
|
3982
|
+
js: "2.6.0"
|
|
3983
|
+
}
|
|
3984
|
+
}
|
|
3985
|
+
}
|
|
3986
|
+
};
|
|
3796
3987
|
var terrain = {
|
|
3797
3988
|
source: {
|
|
3798
3989
|
type: "string",
|
|
@@ -6048,6 +6239,25 @@
|
|
|
6048
6239
|
layout_raster: layout_raster,
|
|
6049
6240
|
layout_hillshade: layout_hillshade,
|
|
6050
6241
|
filter: filter,
|
|
6242
|
+
filter_symbol: filter_symbol,
|
|
6243
|
+
filter_fill: filter_fill,
|
|
6244
|
+
filter_line: filter_line,
|
|
6245
|
+
filter_circle: filter_circle,
|
|
6246
|
+
"filter_fill-extrusion": {
|
|
6247
|
+
type: "boolean",
|
|
6248
|
+
doc: "Expression which determines whether or not to display a Polygon. Fill-extrusion layer does NOT support dynamic filtering, meaning this expression can NOT use the `[\"pitch\"]` and `[\"distance-from-center\"]` expressions to reference the current state of the view.",
|
|
6249
|
+
"default": false,
|
|
6250
|
+
transition: false,
|
|
6251
|
+
"property-type": "data-driven",
|
|
6252
|
+
expression: {
|
|
6253
|
+
interpolated: false,
|
|
6254
|
+
parameters: [
|
|
6255
|
+
"zoom",
|
|
6256
|
+
"feature"
|
|
6257
|
+
]
|
|
6258
|
+
}
|
|
6259
|
+
},
|
|
6260
|
+
filter_heatmap: filter_heatmap,
|
|
6051
6261
|
filter_operator: filter_operator,
|
|
6052
6262
|
geometry_type: geometry_type,
|
|
6053
6263
|
"function": {
|
|
@@ -6117,6 +6327,7 @@
|
|
|
6117
6327
|
expression_name: expression_name,
|
|
6118
6328
|
fog: fog,
|
|
6119
6329
|
light: light,
|
|
6330
|
+
projection: projection,
|
|
6120
6331
|
terrain: terrain,
|
|
6121
6332
|
paint: paint,
|
|
6122
6333
|
paint_fill: paint_fill,
|
|
@@ -9060,6 +9271,8 @@
|
|
|
9060
9271
|
this._parseColorCache = {};
|
|
9061
9272
|
this.availableImages = null;
|
|
9062
9273
|
this.canonical = null;
|
|
9274
|
+
this.featureTileCoord = null;
|
|
9275
|
+
this.featureDistanceData = null;
|
|
9063
9276
|
}
|
|
9064
9277
|
id() {
|
|
9065
9278
|
return this.feature && 'id' in this.feature ? this.feature.id : null;
|
|
@@ -9076,6 +9289,20 @@
|
|
|
9076
9289
|
properties() {
|
|
9077
9290
|
return this.feature && this.feature.properties || {};
|
|
9078
9291
|
}
|
|
9292
|
+
distanceFromCenter() {
|
|
9293
|
+
if (this.featureTileCoord && this.featureDistanceData) {
|
|
9294
|
+
const c = this.featureDistanceData.center;
|
|
9295
|
+
const scale = this.featureDistanceData.scale;
|
|
9296
|
+
const {x, y} = this.featureTileCoord;
|
|
9297
|
+
const dX = x * scale - c[0];
|
|
9298
|
+
const dY = y * scale - c[1];
|
|
9299
|
+
const bX = this.featureDistanceData.bearing[0];
|
|
9300
|
+
const bY = this.featureDistanceData.bearing[1];
|
|
9301
|
+
const dist = bX * dX + bY * dY;
|
|
9302
|
+
return dist;
|
|
9303
|
+
}
|
|
9304
|
+
return 0;
|
|
9305
|
+
}
|
|
9079
9306
|
parseColor(input) {
|
|
9080
9307
|
let cached = this._parseColorCache[input];
|
|
9081
9308
|
if (!cached) {
|
|
@@ -9769,7 +9996,9 @@
|
|
|
9769
9996
|
'line-progress',
|
|
9770
9997
|
'sky-radial-progress',
|
|
9771
9998
|
'accumulated',
|
|
9772
|
-
'is-supported-script'
|
|
9999
|
+
'is-supported-script',
|
|
10000
|
+
'pitch',
|
|
10001
|
+
'distance-from-center'
|
|
9773
10002
|
]);
|
|
9774
10003
|
}
|
|
9775
10004
|
|
|
@@ -11251,6 +11480,16 @@
|
|
|
11251
11480
|
[],
|
|
11252
11481
|
ctx => ctx.globals.zoom
|
|
11253
11482
|
],
|
|
11483
|
+
'pitch': [
|
|
11484
|
+
NumberType,
|
|
11485
|
+
[],
|
|
11486
|
+
ctx => ctx.globals.pitch || 0
|
|
11487
|
+
],
|
|
11488
|
+
'distance-from-center': [
|
|
11489
|
+
NumberType,
|
|
11490
|
+
[],
|
|
11491
|
+
ctx => ctx.distanceFromCenter()
|
|
11492
|
+
],
|
|
11254
11493
|
'heatmap-density': [
|
|
11255
11494
|
NumberType,
|
|
11256
11495
|
[],
|
|
@@ -11897,22 +12136,26 @@
|
|
|
11897
12136
|
this._defaultValue = propertySpec ? getDefaultValue(propertySpec) : null;
|
|
11898
12137
|
this._enumValues = propertySpec && propertySpec.type === 'enum' ? propertySpec.values : null;
|
|
11899
12138
|
}
|
|
11900
|
-
evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection) {
|
|
12139
|
+
evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection, featureTileCoord, featureDistanceData) {
|
|
11901
12140
|
this._evaluator.globals = globals;
|
|
11902
12141
|
this._evaluator.feature = feature;
|
|
11903
12142
|
this._evaluator.featureState = featureState;
|
|
11904
12143
|
this._evaluator.canonical = canonical;
|
|
11905
12144
|
this._evaluator.availableImages = availableImages || null;
|
|
11906
12145
|
this._evaluator.formattedSection = formattedSection;
|
|
12146
|
+
this._evaluator.featureTileCoord = featureTileCoord || null;
|
|
12147
|
+
this._evaluator.featureDistanceData = featureDistanceData || null;
|
|
11907
12148
|
return this.expression.evaluate(this._evaluator);
|
|
11908
12149
|
}
|
|
11909
|
-
evaluate(globals, feature, featureState, canonical, availableImages, formattedSection) {
|
|
12150
|
+
evaluate(globals, feature, featureState, canonical, availableImages, formattedSection, featureTileCoord, featureDistanceData) {
|
|
11910
12151
|
this._evaluator.globals = globals;
|
|
11911
12152
|
this._evaluator.feature = feature || null;
|
|
11912
12153
|
this._evaluator.featureState = featureState || null;
|
|
11913
12154
|
this._evaluator.canonical = canonical;
|
|
11914
12155
|
this._evaluator.availableImages = availableImages || null;
|
|
11915
12156
|
this._evaluator.formattedSection = formattedSection || null;
|
|
12157
|
+
this._evaluator.featureTileCoord = featureTileCoord || null;
|
|
12158
|
+
this._evaluator.featureDistanceData = featureDistanceData || null;
|
|
11916
12159
|
try {
|
|
11917
12160
|
const val = this.expression.evaluate(this._evaluator);
|
|
11918
12161
|
if (val === null || val === undefined || typeof val === 'number' && val !== val) {
|
|
@@ -11989,7 +12232,11 @@
|
|
|
11989
12232
|
if (!isFeatureConstant$1 && !supportsPropertyExpression(propertySpec)) {
|
|
11990
12233
|
return error([new ParsingError('', 'data expressions not supported')]);
|
|
11991
12234
|
}
|
|
11992
|
-
const isZoomConstant = isGlobalPropertyConstant(parsed, [
|
|
12235
|
+
const isZoomConstant = isGlobalPropertyConstant(parsed, [
|
|
12236
|
+
'zoom',
|
|
12237
|
+
'pitch',
|
|
12238
|
+
'distance-from-center'
|
|
12239
|
+
]);
|
|
11993
12240
|
if (!isZoomConstant && !supportsZoomExpression(propertySpec)) {
|
|
11994
12241
|
return error([new ParsingError('', 'zoom expressions not supported')]);
|
|
11995
12242
|
}
|
|
@@ -12397,6 +12644,26 @@
|
|
|
12397
12644
|
return result;
|
|
12398
12645
|
}
|
|
12399
12646
|
|
|
12647
|
+
function unbundle(value) {
|
|
12648
|
+
if (value instanceof Number || value instanceof String || value instanceof Boolean) {
|
|
12649
|
+
return value.valueOf();
|
|
12650
|
+
} else {
|
|
12651
|
+
return value;
|
|
12652
|
+
}
|
|
12653
|
+
}
|
|
12654
|
+
function deepUnbundle(value) {
|
|
12655
|
+
if (Array.isArray(value)) {
|
|
12656
|
+
return value.map(deepUnbundle);
|
|
12657
|
+
} else if (value instanceof Object && !(value instanceof Number || value instanceof String || value instanceof Boolean)) {
|
|
12658
|
+
const unbundledValue = {};
|
|
12659
|
+
for (const key in value) {
|
|
12660
|
+
unbundledValue[key] = deepUnbundle(value[key]);
|
|
12661
|
+
}
|
|
12662
|
+
return unbundledValue;
|
|
12663
|
+
}
|
|
12664
|
+
return unbundle(value);
|
|
12665
|
+
}
|
|
12666
|
+
|
|
12400
12667
|
function isExpressionFilter(filter) {
|
|
12401
12668
|
if (filter === true || filter === false) {
|
|
12402
12669
|
return true;
|
|
@@ -12432,39 +12699,145 @@
|
|
|
12432
12699
|
return true;
|
|
12433
12700
|
}
|
|
12434
12701
|
}
|
|
12435
|
-
|
|
12436
|
-
'type': 'boolean',
|
|
12437
|
-
'default': false,
|
|
12438
|
-
'transition': false,
|
|
12439
|
-
'property-type': 'data-driven',
|
|
12440
|
-
'expression': {
|
|
12441
|
-
'interpolated': false,
|
|
12442
|
-
'parameters': [
|
|
12443
|
-
'zoom',
|
|
12444
|
-
'feature'
|
|
12445
|
-
]
|
|
12446
|
-
}
|
|
12447
|
-
};
|
|
12448
|
-
function createFilter(filter) {
|
|
12702
|
+
function createFilter(filter, layerType = 'fill') {
|
|
12449
12703
|
if (filter === null || filter === undefined) {
|
|
12450
12704
|
return {
|
|
12451
12705
|
filter: () => true,
|
|
12452
|
-
needGeometry: false
|
|
12706
|
+
needGeometry: false,
|
|
12707
|
+
needFeature: false
|
|
12453
12708
|
};
|
|
12454
12709
|
}
|
|
12455
12710
|
if (!isExpressionFilter(filter)) {
|
|
12456
12711
|
filter = convertFilter(filter);
|
|
12457
12712
|
}
|
|
12458
|
-
const
|
|
12459
|
-
|
|
12460
|
-
|
|
12713
|
+
const filterExp = filter;
|
|
12714
|
+
let staticFilter = true;
|
|
12715
|
+
try {
|
|
12716
|
+
staticFilter = extractStaticFilter(filterExp);
|
|
12717
|
+
} catch (e) {
|
|
12718
|
+
console.warn(`Failed to extract static filter. Filter will continue working, but at higher memory usage and slower framerate.
|
|
12719
|
+
This is most likely a bug, please report this via https://github.com/mapbox/mapbox-gl-js/issues/new?assignees=&labels=&template=Bug_report.md
|
|
12720
|
+
and paste the contents of this message in the report.
|
|
12721
|
+
Thank you!
|
|
12722
|
+
Filter Expression:
|
|
12723
|
+
${ JSON.stringify(filterExp, null, 2) }
|
|
12724
|
+
`);
|
|
12725
|
+
}
|
|
12726
|
+
const filterSpec = v8[`filter_${ layerType }`];
|
|
12727
|
+
const compiledStaticFilter = createExpression(staticFilter, filterSpec);
|
|
12728
|
+
let filterFunc = null;
|
|
12729
|
+
if (compiledStaticFilter.result === 'error') {
|
|
12730
|
+
throw new Error(compiledStaticFilter.value.map(err => `${ err.key }: ${ err.message }`).join(', '));
|
|
12461
12731
|
} else {
|
|
12462
|
-
|
|
12463
|
-
|
|
12464
|
-
|
|
12465
|
-
|
|
12466
|
-
|
|
12732
|
+
filterFunc = (globalProperties, feature, canonical) => compiledStaticFilter.value.evaluate(globalProperties, feature, {}, canonical);
|
|
12733
|
+
}
|
|
12734
|
+
let dynamicFilterFunc = null;
|
|
12735
|
+
let needFeature = null;
|
|
12736
|
+
if (staticFilter !== filterExp) {
|
|
12737
|
+
const compiledDynamicFilter = createExpression(filterExp, filterSpec);
|
|
12738
|
+
if (compiledDynamicFilter.result === 'error') {
|
|
12739
|
+
throw new Error(compiledDynamicFilter.value.map(err => `${ err.key }: ${ err.message }`).join(', '));
|
|
12740
|
+
} else {
|
|
12741
|
+
dynamicFilterFunc = (globalProperties, feature, canonical, featureTileCoord, featureDistanceData) => compiledDynamicFilter.value.evaluate(globalProperties, feature, {}, canonical, undefined, undefined, featureTileCoord, featureDistanceData);
|
|
12742
|
+
needFeature = !isFeatureConstant(compiledDynamicFilter.value.expression);
|
|
12743
|
+
}
|
|
12467
12744
|
}
|
|
12745
|
+
filterFunc = filterFunc;
|
|
12746
|
+
const needGeometry = geometryNeeded(staticFilter);
|
|
12747
|
+
return {
|
|
12748
|
+
filter: filterFunc,
|
|
12749
|
+
dynamicFilter: dynamicFilterFunc ? dynamicFilterFunc : undefined,
|
|
12750
|
+
needGeometry,
|
|
12751
|
+
needFeature: !!needFeature
|
|
12752
|
+
};
|
|
12753
|
+
}
|
|
12754
|
+
function extractStaticFilter(filter) {
|
|
12755
|
+
if (!isDynamicFilter(filter)) {
|
|
12756
|
+
return filter;
|
|
12757
|
+
}
|
|
12758
|
+
let result = deepUnbundle(filter);
|
|
12759
|
+
unionDynamicBranches(result);
|
|
12760
|
+
result = collapseDynamicBooleanExpressions(result);
|
|
12761
|
+
return result;
|
|
12762
|
+
}
|
|
12763
|
+
function collapseDynamicBooleanExpressions(expression) {
|
|
12764
|
+
if (!Array.isArray(expression)) {
|
|
12765
|
+
return expression;
|
|
12766
|
+
}
|
|
12767
|
+
const collapsed = collapsedExpression(expression);
|
|
12768
|
+
if (collapsed === true) {
|
|
12769
|
+
return collapsed;
|
|
12770
|
+
} else {
|
|
12771
|
+
return collapsed.map(subExpression => collapseDynamicBooleanExpressions(subExpression));
|
|
12772
|
+
}
|
|
12773
|
+
}
|
|
12774
|
+
function unionDynamicBranches(filter) {
|
|
12775
|
+
let isBranchingDynamically = false;
|
|
12776
|
+
const branches = [];
|
|
12777
|
+
if (filter[0] === 'case') {
|
|
12778
|
+
for (let i = 1; i < filter.length - 1; i += 2) {
|
|
12779
|
+
isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[i]);
|
|
12780
|
+
branches.push(filter[i + 1]);
|
|
12781
|
+
}
|
|
12782
|
+
branches.push(filter[filter.length - 1]);
|
|
12783
|
+
} else if (filter[0] === 'match') {
|
|
12784
|
+
isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[1]);
|
|
12785
|
+
for (let i = 2; i < filter.length - 1; i += 2) {
|
|
12786
|
+
branches.push(filter[i + 1]);
|
|
12787
|
+
}
|
|
12788
|
+
branches.push(filter[filter.length - 1]);
|
|
12789
|
+
} else if (filter[0] === 'step') {
|
|
12790
|
+
isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[1]);
|
|
12791
|
+
for (let i = 1; i < filter.length - 1; i += 2) {
|
|
12792
|
+
branches.push(filter[i + 1]);
|
|
12793
|
+
}
|
|
12794
|
+
}
|
|
12795
|
+
if (isBranchingDynamically) {
|
|
12796
|
+
filter.length = 0;
|
|
12797
|
+
filter.push('any', ...branches);
|
|
12798
|
+
}
|
|
12799
|
+
for (let i = 1; i < filter.length; i++) {
|
|
12800
|
+
unionDynamicBranches(filter[i]);
|
|
12801
|
+
}
|
|
12802
|
+
}
|
|
12803
|
+
function isDynamicFilter(filter) {
|
|
12804
|
+
if (!Array.isArray(filter)) {
|
|
12805
|
+
return false;
|
|
12806
|
+
}
|
|
12807
|
+
if (isRootExpressionDynamic(filter[0])) {
|
|
12808
|
+
return true;
|
|
12809
|
+
}
|
|
12810
|
+
for (let i = 1; i < filter.length; i++) {
|
|
12811
|
+
const child = filter[i];
|
|
12812
|
+
if (isDynamicFilter(child)) {
|
|
12813
|
+
return true;
|
|
12814
|
+
}
|
|
12815
|
+
}
|
|
12816
|
+
return false;
|
|
12817
|
+
}
|
|
12818
|
+
function isRootExpressionDynamic(expression) {
|
|
12819
|
+
return expression === 'pitch' || expression === 'distance-from-center';
|
|
12820
|
+
}
|
|
12821
|
+
const dynamicConditionExpressions = new Set([
|
|
12822
|
+
'in',
|
|
12823
|
+
'==',
|
|
12824
|
+
'!=',
|
|
12825
|
+
'>',
|
|
12826
|
+
'>=',
|
|
12827
|
+
'<',
|
|
12828
|
+
'<=',
|
|
12829
|
+
'to-boolean'
|
|
12830
|
+
]);
|
|
12831
|
+
function collapsedExpression(expression) {
|
|
12832
|
+
if (dynamicConditionExpressions.has(expression[0])) {
|
|
12833
|
+
for (let i = 1; i < expression.length; i++) {
|
|
12834
|
+
const param = expression[i];
|
|
12835
|
+
if (isDynamicFilter(param)) {
|
|
12836
|
+
return true;
|
|
12837
|
+
}
|
|
12838
|
+
}
|
|
12839
|
+
}
|
|
12840
|
+
return expression;
|
|
12468
12841
|
}
|
|
12469
12842
|
function compare(a, b) {
|
|
12470
12843
|
return a < b ? -1 : a > b ? 1 : 0;
|
|
@@ -12923,7 +13296,8 @@
|
|
|
12923
13296
|
setTransition: 'setTransition',
|
|
12924
13297
|
setLight: 'setLight',
|
|
12925
13298
|
setTerrain: 'setTerrain',
|
|
12926
|
-
setFog: 'setFog'
|
|
13299
|
+
setFog: 'setFog',
|
|
13300
|
+
setProjection: 'setProjection'
|
|
12927
13301
|
};
|
|
12928
13302
|
function addSource(sourceId, after, commands) {
|
|
12929
13303
|
commands.push({
|
|
@@ -13230,6 +13604,12 @@
|
|
|
13230
13604
|
args: [after.fog]
|
|
13231
13605
|
});
|
|
13232
13606
|
}
|
|
13607
|
+
if (!deepEqual(before.projection, after.projection)) {
|
|
13608
|
+
commands.push({
|
|
13609
|
+
command: operations.setProjection,
|
|
13610
|
+
args: [after.projection]
|
|
13611
|
+
});
|
|
13612
|
+
}
|
|
13233
13613
|
const sourcesRemoved = {};
|
|
13234
13614
|
const removeOrAddSourceCommands = [];
|
|
13235
13615
|
diffSources(before.sources, after.sources, removeOrAddSourceCommands, sourcesRemoved);
|
|
@@ -13304,26 +13684,6 @@
|
|
|
13304
13684
|
}
|
|
13305
13685
|
}
|
|
13306
13686
|
|
|
13307
|
-
function unbundle(value) {
|
|
13308
|
-
if (value instanceof Number || value instanceof String || value instanceof Boolean) {
|
|
13309
|
-
return value.valueOf();
|
|
13310
|
-
} else {
|
|
13311
|
-
return value;
|
|
13312
|
-
}
|
|
13313
|
-
}
|
|
13314
|
-
function deepUnbundle(value) {
|
|
13315
|
-
if (Array.isArray(value)) {
|
|
13316
|
-
return value.map(deepUnbundle);
|
|
13317
|
-
} else if (value instanceof Object && !(value instanceof Number || value instanceof String || value instanceof Boolean)) {
|
|
13318
|
-
const unbundledValue = {};
|
|
13319
|
-
for (const key in value) {
|
|
13320
|
-
unbundledValue[key] = deepUnbundle(value[key]);
|
|
13321
|
-
}
|
|
13322
|
-
return unbundledValue;
|
|
13323
|
-
}
|
|
13324
|
-
return unbundle(value);
|
|
13325
|
-
}
|
|
13326
|
-
|
|
13327
13687
|
function validateObject(options) {
|
|
13328
13688
|
const key = options.key;
|
|
13329
13689
|
const object = options.value;
|
|
@@ -13628,8 +13988,8 @@
|
|
|
13628
13988
|
if (options.expressionContext === 'property' && options.propertyType === 'layout' && !isStateConstant(expressionObj)) {
|
|
13629
13989
|
return [new ValidationError(options.key, options.value, '"feature-state" data expressions are not supported with layout properties.')];
|
|
13630
13990
|
}
|
|
13631
|
-
if (options.expressionContext === 'filter'
|
|
13632
|
-
return
|
|
13991
|
+
if (options.expressionContext === 'filter') {
|
|
13992
|
+
return disallowedFilterParameters(expressionObj, options);
|
|
13633
13993
|
}
|
|
13634
13994
|
if (options.expressionContext && options.expressionContext.indexOf('cluster') === 0) {
|
|
13635
13995
|
if (!isGlobalPropertyConstant(expressionObj, [
|
|
@@ -13644,6 +14004,30 @@
|
|
|
13644
14004
|
}
|
|
13645
14005
|
return [];
|
|
13646
14006
|
}
|
|
14007
|
+
function disallowedFilterParameters(e, options) {
|
|
14008
|
+
const disallowedParameters = new Set([
|
|
14009
|
+
'zoom',
|
|
14010
|
+
'feature-state',
|
|
14011
|
+
'pitch',
|
|
14012
|
+
'distance-from-center'
|
|
14013
|
+
]);
|
|
14014
|
+
for (const param of options.valueSpec.expression.parameters) {
|
|
14015
|
+
disallowedParameters.delete(param);
|
|
14016
|
+
}
|
|
14017
|
+
if (disallowedParameters.size === 0) {
|
|
14018
|
+
return [];
|
|
14019
|
+
}
|
|
14020
|
+
const errors = [];
|
|
14021
|
+
if (e instanceof CompoundExpression) {
|
|
14022
|
+
if (disallowedParameters.has(e.name)) {
|
|
14023
|
+
return [new ValidationError(options.key, options.value, `["${ e.name }"] expression is not supported in a filter for a ${ options.object.type } layer with id: ${ options.object.id }`)];
|
|
14024
|
+
}
|
|
14025
|
+
}
|
|
14026
|
+
e.eachChild(arg => {
|
|
14027
|
+
errors.push(...disallowedFilterParameters(arg, options));
|
|
14028
|
+
});
|
|
14029
|
+
return errors;
|
|
14030
|
+
}
|
|
13647
14031
|
|
|
13648
14032
|
function validateBoolean(options) {
|
|
13649
14033
|
const value = options.value;
|
|
@@ -13687,9 +14071,10 @@
|
|
|
13687
14071
|
|
|
13688
14072
|
function validateFilter(options) {
|
|
13689
14073
|
if (isExpressionFilter(deepUnbundle(options.value))) {
|
|
14074
|
+
const layerType = deepUnbundle(options.layerType);
|
|
13690
14075
|
return validateExpression(extend({}, options, {
|
|
13691
14076
|
expressionContext: 'filter',
|
|
13692
|
-
valueSpec: {
|
|
14077
|
+
valueSpec: options.styleSpec[`filter_${ layerType || 'fill' }`]
|
|
13693
14078
|
}));
|
|
13694
14079
|
} else {
|
|
13695
14080
|
return validateNonExpressionFilter(options);
|
|
@@ -13925,7 +14310,9 @@
|
|
|
13925
14310
|
objectKey: 'type'
|
|
13926
14311
|
});
|
|
13927
14312
|
},
|
|
13928
|
-
filter
|
|
14313
|
+
filter(options) {
|
|
14314
|
+
return validateFilter(extend({ layerType: type }, options));
|
|
14315
|
+
},
|
|
13929
14316
|
layout(options) {
|
|
13930
14317
|
return validateObject({
|
|
13931
14318
|
layer,
|
|
@@ -14221,6 +14608,29 @@
|
|
|
14221
14608
|
return validateExpression(options);
|
|
14222
14609
|
}
|
|
14223
14610
|
|
|
14611
|
+
function validateProjection(options) {
|
|
14612
|
+
const projection = options.value;
|
|
14613
|
+
const styleSpec = options.styleSpec;
|
|
14614
|
+
const projectionSpec = styleSpec.projection;
|
|
14615
|
+
const style = options.style;
|
|
14616
|
+
let errors = [];
|
|
14617
|
+
const rootType = getType(projection);
|
|
14618
|
+
if (rootType === 'object') {
|
|
14619
|
+
for (const key in projection) {
|
|
14620
|
+
errors = errors.concat(validate({
|
|
14621
|
+
key,
|
|
14622
|
+
value: projection[key],
|
|
14623
|
+
valueSpec: projectionSpec[key],
|
|
14624
|
+
style,
|
|
14625
|
+
styleSpec
|
|
14626
|
+
}));
|
|
14627
|
+
}
|
|
14628
|
+
} else if (rootType !== 'string') {
|
|
14629
|
+
errors = errors.concat([new ValidationError('projection', projection, `object or string expected, ${ rootType } found`)]);
|
|
14630
|
+
}
|
|
14631
|
+
return errors;
|
|
14632
|
+
}
|
|
14633
|
+
|
|
14224
14634
|
const VALIDATORS = {
|
|
14225
14635
|
'*'() {
|
|
14226
14636
|
return [];
|
|
@@ -14241,7 +14651,8 @@
|
|
|
14241
14651
|
'fog': validateFog,
|
|
14242
14652
|
'string': validateString,
|
|
14243
14653
|
'formatted': validateFormatted,
|
|
14244
|
-
'resolvedImage': validateImage
|
|
14654
|
+
'resolvedImage': validateImage,
|
|
14655
|
+
'projection': validateProjection
|
|
14245
14656
|
};
|
|
14246
14657
|
function validate(options) {
|
|
14247
14658
|
const value = options.value;
|