@mapbox/mapbox-gl-style-spec 14.28.0 → 14.29.0-rc.1
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/composite.ts +5 -5
- package/diff.ts +38 -40
- package/dist/index.cjs +339 -238
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +75 -13
- package/dist/index.es.js +339 -238
- package/dist/index.es.js.map +1 -1
- package/expression/compound_expression.ts +6 -6
- package/expression/definitions/assertion.ts +9 -12
- package/expression/definitions/at.ts +1 -1
- package/expression/definitions/at_interpolated.ts +1 -1
- package/expression/definitions/case.ts +1 -2
- package/expression/definitions/coalesce.ts +1 -1
- package/expression/definitions/coercion.ts +10 -12
- package/expression/definitions/collator.ts +8 -8
- package/expression/definitions/comparison.ts +0 -1
- package/expression/definitions/distance.ts +135 -73
- package/expression/definitions/format.ts +10 -13
- package/expression/definitions/image.ts +8 -8
- package/expression/definitions/index.ts +92 -90
- package/expression/definitions/interpolate.ts +18 -19
- package/expression/definitions/let.ts +1 -2
- package/expression/definitions/literal.ts +1 -1
- package/expression/definitions/match.ts +7 -8
- package/expression/definitions/number_format.ts +7 -8
- package/expression/definitions/step.ts +11 -11
- package/expression/definitions/within.ts +23 -24
- package/expression/evaluation_context.ts +4 -4
- package/expression/expression.ts +1 -1
- package/expression/index.ts +43 -21
- package/expression/parsing_context.ts +2 -2
- package/expression/stops.ts +2 -2
- package/expression/values.ts +2 -2
- package/feature_filter/index.ts +3 -3
- package/function/convert.ts +8 -8
- package/function/index.ts +4 -2
- package/group_by_layout.ts +6 -4
- package/package.json +1 -1
- package/read_style.ts +2 -2
- package/reference/v8.json +63 -5
- package/types/config_options.ts +1 -1
- package/types.ts +10 -5
- package/util/properties.ts +1 -1
- package/validate/validate.ts +15 -5
- package/validate/validate_appearance.ts +7 -7
- package/validate/validate_array.ts +7 -7
- package/validate/validate_enum.ts +2 -3
- package/validate/validate_fog.ts +2 -2
- package/validate/validate_function.ts +14 -13
- package/validate/validate_layer.ts +10 -9
- package/validate/validate_light.ts +2 -2
- package/validate/validate_lights.ts +3 -3
- package/validate/validate_number.ts +10 -7
- package/validate/validate_object.ts +11 -10
- package/validate/validate_option.ts +24 -9
- package/validate/validate_property.ts +4 -4
- package/validate/validate_rain.ts +1 -1
- package/validate/validate_snow.ts +1 -1
- package/validate/validate_style.ts +2 -1
- package/validate/validate_terrain.ts +2 -2
- package/validate_mapbox_api_supported.ts +5 -6
- package/validate_style.min.ts +2 -1
- package/visit.ts +11 -10
package/dist/index.es.js
CHANGED
|
@@ -369,6 +369,16 @@ var option = {
|
|
|
369
369
|
},
|
|
370
370
|
color: {
|
|
371
371
|
doc: "The result will be coerced to a color."
|
|
372
|
+
},
|
|
373
|
+
object: {
|
|
374
|
+
doc: "The result will be coerced to an object.",
|
|
375
|
+
"sdk-support": {
|
|
376
|
+
"basic functionality": {
|
|
377
|
+
js: "3.29.0",
|
|
378
|
+
android: "11.29.0",
|
|
379
|
+
ios: "11.29.0"
|
|
380
|
+
}
|
|
381
|
+
}
|
|
372
382
|
}
|
|
373
383
|
}
|
|
374
384
|
},
|
|
@@ -3000,6 +3010,7 @@ var layout_symbol = {
|
|
|
3000
3010
|
experimental: true,
|
|
3001
3011
|
"sdk-support": {
|
|
3002
3012
|
"basic functionality": {
|
|
3013
|
+
js: "3.7.0",
|
|
3003
3014
|
android: "11.9.0",
|
|
3004
3015
|
ios: "11.9.0"
|
|
3005
3016
|
}
|
|
@@ -5473,13 +5484,18 @@ var expression_name = {
|
|
|
5473
5484
|
}
|
|
5474
5485
|
},
|
|
5475
5486
|
distance: {
|
|
5476
|
-
doc: "Returns the shortest distance in meters between the evaluated feature and the input geometry. The input value can be a valid GeoJSON of type `Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`, `Feature`, or `FeatureCollection
|
|
5487
|
+
doc: "Returns the shortest distance in meters between the evaluated feature and the input geometry. The input value can be a valid GeoJSON of type `Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`, `Feature`, or `FeatureCollection`, or expression that returns a valid GeoJSON. Distance values returned may vary in precision due to loss in precision from encoding geometries, particularly below zoom level 13.",
|
|
5477
5488
|
group: "Math",
|
|
5478
5489
|
"sdk-support": {
|
|
5479
5490
|
"basic functionality": {
|
|
5480
5491
|
js: "3.0.0",
|
|
5481
5492
|
android: "9.2.0",
|
|
5482
5493
|
ios: "5.9.0"
|
|
5494
|
+
},
|
|
5495
|
+
"expressions support": {
|
|
5496
|
+
js: "3.29.0",
|
|
5497
|
+
android: "11.29.0",
|
|
5498
|
+
ios: "11.29.0"
|
|
5483
5499
|
}
|
|
5484
5500
|
}
|
|
5485
5501
|
},
|
|
@@ -9449,7 +9465,6 @@ var paint_symbol = {
|
|
|
9449
9465
|
"default": 0,
|
|
9450
9466
|
minimum: 0,
|
|
9451
9467
|
transition: true,
|
|
9452
|
-
experimental: true,
|
|
9453
9468
|
appearance: true,
|
|
9454
9469
|
"sdk-support": {
|
|
9455
9470
|
"basic functionality": {
|
|
@@ -9503,7 +9518,7 @@ var paint_raster = {
|
|
|
9503
9518
|
},
|
|
9504
9519
|
"raster-color": {
|
|
9505
9520
|
type: "color",
|
|
9506
|
-
doc: "Defines
|
|
9521
|
+
doc: "Defines the color ramp used to colorize a raster layer, parameterized by the `[\"raster-value\"]` expression and evaluated over the range specified by `raster-color-range`. Raster values are spaced evenly across the range by default.",
|
|
9507
9522
|
"use-theme": true,
|
|
9508
9523
|
transition: false,
|
|
9509
9524
|
"sdk-support": {
|
|
@@ -9544,7 +9559,7 @@ var paint_raster = {
|
|
|
9544
9559
|
"zoom"
|
|
9545
9560
|
]
|
|
9546
9561
|
},
|
|
9547
|
-
doc: "When `raster-color` is active, specifies the
|
|
9562
|
+
doc: "When `raster-color` is active, specifies how the raster value is computed from a non-`rasterarray` source's channels, using the equation `mix.r * src.r + mix.g * src.g + mix.b * src.b + mix.a`. The first three components weight the source's red, green, and blue channels; the fourth is a constant offset and is not multiplied by source alpha. Source alpha is carried through and applied as opacity to the colorized result. The default corresponds to RGB luminosity. `rasterarray` sources ignore this property, as their raster value is decoded directly from the source data.",
|
|
9548
9563
|
example: [
|
|
9549
9564
|
0.2126,
|
|
9550
9565
|
0.7152,
|
|
@@ -9574,7 +9589,7 @@ var paint_raster = {
|
|
|
9574
9589
|
"zoom"
|
|
9575
9590
|
]
|
|
9576
9591
|
},
|
|
9577
|
-
doc: "When `raster-color` is active, specifies the range
|
|
9592
|
+
doc: "When `raster-color` is active, specifies the range of raster values mapped onto the color ramp, from the start of the ramp (low bound) to its end (high bound). For `rasterarray` sources the raster value is the decoded source data in the source's own units, and the source's stated data range is used when this property is unspecified. For other raster sources the raster value is computed from the source's channels via `raster-color-mix`. Defaults to `[0, 1]` when no range is otherwise available.",
|
|
9578
9593
|
example: [
|
|
9579
9594
|
0.5,
|
|
9580
9595
|
10
|
|
@@ -9587,6 +9602,37 @@ var paint_raster = {
|
|
|
9587
9602
|
}
|
|
9588
9603
|
}
|
|
9589
9604
|
},
|
|
9605
|
+
"raster-color-scale": {
|
|
9606
|
+
type: "enum",
|
|
9607
|
+
doc: "When `raster-color` is active, specifies how raster values are distributed across the color ramp over the range specified by `raster-color-range`.",
|
|
9608
|
+
values: {
|
|
9609
|
+
linear: {
|
|
9610
|
+
doc: "Raster values are spaced evenly across the color ramp."
|
|
9611
|
+
},
|
|
9612
|
+
log: {
|
|
9613
|
+
doc: "Raster values are spaced logarithmically, giving more of the color ramp to smaller values. Useful for data concentrated near the low end of a wide range."
|
|
9614
|
+
}
|
|
9615
|
+
},
|
|
9616
|
+
"default": "linear",
|
|
9617
|
+
requires: [
|
|
9618
|
+
"raster-color",
|
|
9619
|
+
{
|
|
9620
|
+
source: "raster-array"
|
|
9621
|
+
}
|
|
9622
|
+
],
|
|
9623
|
+
expression: {
|
|
9624
|
+
interpolated: false,
|
|
9625
|
+
parameters: [
|
|
9626
|
+
]
|
|
9627
|
+
},
|
|
9628
|
+
"property-type": "data-constant",
|
|
9629
|
+
experimental: true,
|
|
9630
|
+
"sdk-support": {
|
|
9631
|
+
"basic functionality": {
|
|
9632
|
+
js: "3.29.0"
|
|
9633
|
+
}
|
|
9634
|
+
}
|
|
9635
|
+
},
|
|
9590
9636
|
"raster-hue-rotate": {
|
|
9591
9637
|
type: "number",
|
|
9592
9638
|
"default": 0,
|
|
@@ -9840,6 +9886,21 @@ var paint_raster = {
|
|
|
9840
9886
|
interpolated: false
|
|
9841
9887
|
},
|
|
9842
9888
|
"property-type": "data-constant"
|
|
9889
|
+
},
|
|
9890
|
+
"raster-allow-draping": {
|
|
9891
|
+
type: "boolean",
|
|
9892
|
+
"default": true,
|
|
9893
|
+
experimental: true,
|
|
9894
|
+
doc: "Whether the raster layer is allowed to drape over terrain and globe. When disabled, the layer is rendered after all draped layers, which can change its position in the layer order. Disabling draping has a performance cost, since the terrain/globe geometry must be rendered again for each such layer.",
|
|
9895
|
+
transition: false,
|
|
9896
|
+
"property-type": "data-constant",
|
|
9897
|
+
"sdk-support": {
|
|
9898
|
+
"basic functionality": {
|
|
9899
|
+
js: "3.28.0",
|
|
9900
|
+
android: "11.28.0",
|
|
9901
|
+
ios: "11.28.0"
|
|
9902
|
+
}
|
|
9903
|
+
}
|
|
9843
9904
|
}
|
|
9844
9905
|
};
|
|
9845
9906
|
var paint_hillshade = {
|
|
@@ -14875,6 +14936,189 @@ class TinyQueue {
|
|
|
14875
14936
|
|
|
14876
14937
|
var EXTENT = 8192;
|
|
14877
14938
|
|
|
14939
|
+
const FQIDSeparator = "";
|
|
14940
|
+
function makeConfigFQID(id, ownScope, contextScope) {
|
|
14941
|
+
return [id, ownScope, contextScope].filter(Boolean).join(FQIDSeparator);
|
|
14942
|
+
}
|
|
14943
|
+
function coerceValue(type, value) {
|
|
14944
|
+
switch (type) {
|
|
14945
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
14946
|
+
case "string":
|
|
14947
|
+
return toString(value);
|
|
14948
|
+
case "number":
|
|
14949
|
+
return +value;
|
|
14950
|
+
case "boolean":
|
|
14951
|
+
return !!value;
|
|
14952
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
14953
|
+
case "color":
|
|
14954
|
+
return Color.parse(value);
|
|
14955
|
+
case "formatted": {
|
|
14956
|
+
return Formatted.fromString(toString(value));
|
|
14957
|
+
}
|
|
14958
|
+
case "resolvedImage": {
|
|
14959
|
+
return ResolvedImage.build(toString(value));
|
|
14960
|
+
}
|
|
14961
|
+
}
|
|
14962
|
+
return value;
|
|
14963
|
+
}
|
|
14964
|
+
function clampToAllowedNumber(value, min, max, step) {
|
|
14965
|
+
if (step !== void 0) {
|
|
14966
|
+
value = step * Math.round(value / step);
|
|
14967
|
+
}
|
|
14968
|
+
if (min !== void 0 && value < min) {
|
|
14969
|
+
value = min;
|
|
14970
|
+
}
|
|
14971
|
+
if (max !== void 0 && value > max) {
|
|
14972
|
+
value = max;
|
|
14973
|
+
}
|
|
14974
|
+
return value;
|
|
14975
|
+
}
|
|
14976
|
+
class Config {
|
|
14977
|
+
constructor(type, key, scope, featureConstant = false) {
|
|
14978
|
+
this.type = type;
|
|
14979
|
+
this.key = key;
|
|
14980
|
+
this.scope = scope;
|
|
14981
|
+
this.featureConstant = featureConstant;
|
|
14982
|
+
}
|
|
14983
|
+
static parse(args, context) {
|
|
14984
|
+
let type = context.expectedType;
|
|
14985
|
+
type ?? (type = ValueType);
|
|
14986
|
+
if (args.length < 2 || args.length > 3) {
|
|
14987
|
+
return context.error(`Invalid number of arguments for 'config' expression.`);
|
|
14988
|
+
}
|
|
14989
|
+
const configKey = context.parse(args[1], 1);
|
|
14990
|
+
if (!(configKey instanceof Literal)) {
|
|
14991
|
+
return context.error(`Key name of 'config' expression must be a string literal.`);
|
|
14992
|
+
}
|
|
14993
|
+
let featureConstant = true;
|
|
14994
|
+
let configScopeValue;
|
|
14995
|
+
const configKeyValue = toString(configKey.value);
|
|
14996
|
+
if (args.length >= 3) {
|
|
14997
|
+
const configScope = context.parse(args[2], 2);
|
|
14998
|
+
if (!(configScope instanceof Literal)) {
|
|
14999
|
+
return context.error(`Scope of 'config' expression must be a string literal.`);
|
|
15000
|
+
}
|
|
15001
|
+
configScopeValue = toString(configScope.value);
|
|
15002
|
+
}
|
|
15003
|
+
if (context.options) {
|
|
15004
|
+
const fqid = makeConfigFQID(configKeyValue, configScopeValue, context._scope);
|
|
15005
|
+
const config = context.options.get(fqid);
|
|
15006
|
+
if (config) {
|
|
15007
|
+
featureConstant = isFeatureConstant(config.value || config.default);
|
|
15008
|
+
}
|
|
15009
|
+
}
|
|
15010
|
+
return new Config(type, configKeyValue, configScopeValue, featureConstant);
|
|
15011
|
+
}
|
|
15012
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15013
|
+
evaluate(ctx) {
|
|
15014
|
+
const fqid = makeConfigFQID(this.key, this.scope, ctx.scope);
|
|
15015
|
+
const config = ctx.getConfig(fqid);
|
|
15016
|
+
if (!config) return null;
|
|
15017
|
+
const { type, value, values, minValue, maxValue, stepValue } = config;
|
|
15018
|
+
const defaultValue = config.default.evaluate(ctx);
|
|
15019
|
+
let result = defaultValue;
|
|
15020
|
+
if (value) {
|
|
15021
|
+
const originalScope = ctx.scope;
|
|
15022
|
+
ctx.scope = (originalScope || "").split(FQIDSeparator).slice(1).join(FQIDSeparator);
|
|
15023
|
+
result = value.evaluate(ctx);
|
|
15024
|
+
ctx.scope = originalScope;
|
|
15025
|
+
}
|
|
15026
|
+
if (type) {
|
|
15027
|
+
result = coerceValue(type, result);
|
|
15028
|
+
}
|
|
15029
|
+
if (result !== void 0 && (minValue !== void 0 || maxValue !== void 0 || stepValue !== void 0)) {
|
|
15030
|
+
if (typeof result === "number") {
|
|
15031
|
+
result = clampToAllowedNumber(result, minValue, maxValue, stepValue);
|
|
15032
|
+
} else if (Array.isArray(result)) {
|
|
15033
|
+
result = result.map((item) => typeof item === "number" ? clampToAllowedNumber(item, minValue, maxValue, stepValue) : item);
|
|
15034
|
+
}
|
|
15035
|
+
}
|
|
15036
|
+
if (value !== void 0 && result !== void 0 && values && !values.includes(result)) {
|
|
15037
|
+
result = defaultValue;
|
|
15038
|
+
if (type) {
|
|
15039
|
+
result = coerceValue(type, result);
|
|
15040
|
+
}
|
|
15041
|
+
}
|
|
15042
|
+
if (type && type !== this.type || result !== void 0 && !typeEquals(typeOf(result), this.type)) {
|
|
15043
|
+
result = coerceValue(this.type.kind, result);
|
|
15044
|
+
}
|
|
15045
|
+
return result;
|
|
15046
|
+
}
|
|
15047
|
+
eachChild() {
|
|
15048
|
+
}
|
|
15049
|
+
outputDefined() {
|
|
15050
|
+
return false;
|
|
15051
|
+
}
|
|
15052
|
+
serialize() {
|
|
15053
|
+
const res = ["config", this.key];
|
|
15054
|
+
if (this.scope) {
|
|
15055
|
+
res.concat(this.scope);
|
|
15056
|
+
}
|
|
15057
|
+
return res;
|
|
15058
|
+
}
|
|
15059
|
+
}
|
|
15060
|
+
|
|
15061
|
+
function isFeatureConstant(e) {
|
|
15062
|
+
if (e instanceof CompoundExpression) {
|
|
15063
|
+
if (e.name === "get" && e.args.length === 1) {
|
|
15064
|
+
return false;
|
|
15065
|
+
} else if (e.name === "feature-state") {
|
|
15066
|
+
return false;
|
|
15067
|
+
} else if (e.name === "has" && e.args.length === 1) {
|
|
15068
|
+
return false;
|
|
15069
|
+
} else if (e.name === "properties" || e.name === "geometry-type" || e.name === "id") {
|
|
15070
|
+
return false;
|
|
15071
|
+
} else if (e.name.startsWith("filter-")) {
|
|
15072
|
+
return false;
|
|
15073
|
+
}
|
|
15074
|
+
}
|
|
15075
|
+
if (e instanceof Within) {
|
|
15076
|
+
return false;
|
|
15077
|
+
}
|
|
15078
|
+
if (e instanceof Distance) {
|
|
15079
|
+
return false;
|
|
15080
|
+
}
|
|
15081
|
+
if (e instanceof Config) {
|
|
15082
|
+
return e.featureConstant;
|
|
15083
|
+
}
|
|
15084
|
+
let result = true;
|
|
15085
|
+
e.eachChild((arg) => {
|
|
15086
|
+
if (result && !isFeatureConstant(arg)) {
|
|
15087
|
+
result = false;
|
|
15088
|
+
}
|
|
15089
|
+
});
|
|
15090
|
+
return result;
|
|
15091
|
+
}
|
|
15092
|
+
function isStateConstant(e) {
|
|
15093
|
+
if (e instanceof CompoundExpression) {
|
|
15094
|
+
if (e.name === "feature-state") {
|
|
15095
|
+
return false;
|
|
15096
|
+
}
|
|
15097
|
+
}
|
|
15098
|
+
let result = true;
|
|
15099
|
+
e.eachChild((arg) => {
|
|
15100
|
+
if (result && !isStateConstant(arg)) {
|
|
15101
|
+
result = false;
|
|
15102
|
+
}
|
|
15103
|
+
});
|
|
15104
|
+
return result;
|
|
15105
|
+
}
|
|
15106
|
+
function isGlobalPropertyConstantSet(e, properties) {
|
|
15107
|
+
if (e instanceof CompoundExpression && properties.has(e.name)) {
|
|
15108
|
+
return false;
|
|
15109
|
+
}
|
|
15110
|
+
let result = true;
|
|
15111
|
+
e.eachChild((arg) => {
|
|
15112
|
+
if (result && !isGlobalPropertyConstantSet(arg, properties)) {
|
|
15113
|
+
result = false;
|
|
15114
|
+
}
|
|
15115
|
+
});
|
|
15116
|
+
return result;
|
|
15117
|
+
}
|
|
15118
|
+
function isGlobalPropertyConstant(e, properties) {
|
|
15119
|
+
return isGlobalPropertyConstantSet(e, new Set(properties));
|
|
15120
|
+
}
|
|
15121
|
+
|
|
14878
15122
|
const RE = 6378.137;
|
|
14879
15123
|
const FE = 1 / 298.257223563;
|
|
14880
15124
|
const E2 = FE * (2 - FE);
|
|
@@ -15410,245 +15654,94 @@ function polygonsToGeometryDistance(originGeometry, canonical, geometry) {
|
|
|
15410
15654
|
function isTypeValid(type) {
|
|
15411
15655
|
return type === "Point" || type === "MultiPoint" || type === "LineString" || type === "MultiLineString" || type === "Polygon" || type === "MultiPolygon";
|
|
15412
15656
|
}
|
|
15413
|
-
|
|
15414
|
-
|
|
15415
|
-
this.type = NumberType;
|
|
15416
|
-
this.geojson = geojson;
|
|
15417
|
-
this.geometries = geometries;
|
|
15418
|
-
}
|
|
15419
|
-
static parse(args, context) {
|
|
15420
|
-
if (args.length !== 2) {
|
|
15421
|
-
return context.error(`'distance' expression requires either one argument, but found ' ${args.length - 1} instead.`);
|
|
15422
|
-
}
|
|
15423
|
-
if (isValue(args[1])) {
|
|
15424
|
-
const geojson = args[1];
|
|
15425
|
-
if (geojson.type === "FeatureCollection") {
|
|
15426
|
-
for (let i = 0; i < geojson.features.length; ++i) {
|
|
15427
|
-
if (isTypeValid(geojson.features[i].geometry.type)) {
|
|
15428
|
-
return new Distance(geojson, geojson.features[i].geometry);
|
|
15429
|
-
}
|
|
15430
|
-
}
|
|
15431
|
-
} else if (geojson.type === "Feature") {
|
|
15432
|
-
if (isTypeValid(geojson.geometry.type)) {
|
|
15433
|
-
return new Distance(geojson, geojson.geometry);
|
|
15434
|
-
}
|
|
15435
|
-
} else if (isTypeValid(geojson.type)) {
|
|
15436
|
-
return new Distance(geojson, geojson);
|
|
15437
|
-
}
|
|
15438
|
-
}
|
|
15439
|
-
return context.error(
|
|
15440
|
-
"'distance' expression needs to be an array with format ['Distance', GeoJSONObj]."
|
|
15441
|
-
);
|
|
15442
|
-
}
|
|
15443
|
-
evaluate(ctx) {
|
|
15444
|
-
const geometry = ctx.geometry();
|
|
15445
|
-
const canonical = ctx.canonicalID();
|
|
15446
|
-
if (geometry != null && canonical != null) {
|
|
15447
|
-
if (ctx.geometryType() === "Point") {
|
|
15448
|
-
return pointsToGeometryDistance(geometry, canonical, this.geometries);
|
|
15449
|
-
}
|
|
15450
|
-
if (ctx.geometryType() === "LineString") {
|
|
15451
|
-
return linesToGeometryDistance(geometry, canonical, this.geometries);
|
|
15452
|
-
}
|
|
15453
|
-
if (ctx.geometryType() === "Polygon") {
|
|
15454
|
-
return polygonsToGeometryDistance(geometry, canonical, this.geometries);
|
|
15455
|
-
}
|
|
15456
|
-
console.warn("Distance Expression: currently only evaluates valid Point/LineString/Polygon geometries.");
|
|
15457
|
-
} else {
|
|
15458
|
-
console.warn("Distance Expression: requires valid feature and canonical information.");
|
|
15459
|
-
}
|
|
15657
|
+
function extractDistanceGeometry(value) {
|
|
15658
|
+
if (!isValue(value) || typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
15460
15659
|
return null;
|
|
15461
15660
|
}
|
|
15462
|
-
|
|
15463
|
-
|
|
15464
|
-
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
|
|
15468
|
-
|
|
15469
|
-
}
|
|
15470
|
-
}
|
|
15471
|
-
|
|
15472
|
-
function isFeatureConstant(e) {
|
|
15473
|
-
if (e instanceof CompoundExpression) {
|
|
15474
|
-
if (e.name === "get" && e.args.length === 1) {
|
|
15475
|
-
return false;
|
|
15476
|
-
} else if (e.name === "feature-state") {
|
|
15477
|
-
return false;
|
|
15478
|
-
} else if (e.name === "has" && e.args.length === 1) {
|
|
15479
|
-
return false;
|
|
15480
|
-
} else if (e.name === "properties" || e.name === "geometry-type" || e.name === "id") {
|
|
15481
|
-
return false;
|
|
15482
|
-
} else if (e.name.startsWith("filter-")) {
|
|
15483
|
-
return false;
|
|
15661
|
+
const geojson = value;
|
|
15662
|
+
if (geojson.type === "FeatureCollection") {
|
|
15663
|
+
if (geojson.features.length === 0) return null;
|
|
15664
|
+
const geometries = [];
|
|
15665
|
+
for (const feature of geojson.features) {
|
|
15666
|
+
if (!isTypeValid(feature.geometry.type)) return null;
|
|
15667
|
+
geometries.push(feature.geometry);
|
|
15484
15668
|
}
|
|
15669
|
+
return geometries;
|
|
15485
15670
|
}
|
|
15486
|
-
if (
|
|
15487
|
-
return
|
|
15671
|
+
if (geojson.type === "Feature") {
|
|
15672
|
+
return isTypeValid(geojson.geometry.type) ? [geojson.geometry] : null;
|
|
15488
15673
|
}
|
|
15489
|
-
if (
|
|
15490
|
-
return
|
|
15674
|
+
if (isTypeValid(geojson.type)) {
|
|
15675
|
+
return [geojson];
|
|
15491
15676
|
}
|
|
15492
|
-
|
|
15493
|
-
return e.featureConstant;
|
|
15494
|
-
}
|
|
15495
|
-
let result = true;
|
|
15496
|
-
e.eachChild((arg) => {
|
|
15497
|
-
if (result && !isFeatureConstant(arg)) {
|
|
15498
|
-
result = false;
|
|
15499
|
-
}
|
|
15500
|
-
});
|
|
15501
|
-
return result;
|
|
15502
|
-
}
|
|
15503
|
-
function isStateConstant(e) {
|
|
15504
|
-
if (e instanceof CompoundExpression) {
|
|
15505
|
-
if (e.name === "feature-state") {
|
|
15506
|
-
return false;
|
|
15507
|
-
}
|
|
15508
|
-
}
|
|
15509
|
-
let result = true;
|
|
15510
|
-
e.eachChild((arg) => {
|
|
15511
|
-
if (result && !isStateConstant(arg)) {
|
|
15512
|
-
result = false;
|
|
15513
|
-
}
|
|
15514
|
-
});
|
|
15515
|
-
return result;
|
|
15516
|
-
}
|
|
15517
|
-
function isGlobalPropertyConstantSet(e, properties) {
|
|
15518
|
-
if (e instanceof CompoundExpression && properties.has(e.name)) {
|
|
15519
|
-
return false;
|
|
15520
|
-
}
|
|
15521
|
-
let result = true;
|
|
15522
|
-
e.eachChild((arg) => {
|
|
15523
|
-
if (result && !isGlobalPropertyConstantSet(arg, properties)) {
|
|
15524
|
-
result = false;
|
|
15525
|
-
}
|
|
15526
|
-
});
|
|
15527
|
-
return result;
|
|
15528
|
-
}
|
|
15529
|
-
function isGlobalPropertyConstant(e, properties) {
|
|
15530
|
-
return isGlobalPropertyConstantSet(e, new Set(properties));
|
|
15531
|
-
}
|
|
15532
|
-
|
|
15533
|
-
const FQIDSeparator = "";
|
|
15534
|
-
function makeConfigFQID(id, ownScope, contextScope) {
|
|
15535
|
-
return [id, ownScope, contextScope].filter(Boolean).join(FQIDSeparator);
|
|
15536
|
-
}
|
|
15537
|
-
function coerceValue(type, value) {
|
|
15538
|
-
switch (type) {
|
|
15539
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
15540
|
-
case "string":
|
|
15541
|
-
return toString(value);
|
|
15542
|
-
case "number":
|
|
15543
|
-
return +value;
|
|
15544
|
-
case "boolean":
|
|
15545
|
-
return !!value;
|
|
15546
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
15547
|
-
case "color":
|
|
15548
|
-
return Color.parse(value);
|
|
15549
|
-
case "formatted": {
|
|
15550
|
-
return Formatted.fromString(toString(value));
|
|
15551
|
-
}
|
|
15552
|
-
case "resolvedImage": {
|
|
15553
|
-
return ResolvedImage.build(toString(value));
|
|
15554
|
-
}
|
|
15555
|
-
}
|
|
15556
|
-
return value;
|
|
15557
|
-
}
|
|
15558
|
-
function clampToAllowedNumber(value, min, max, step) {
|
|
15559
|
-
if (step !== void 0) {
|
|
15560
|
-
value = step * Math.round(value / step);
|
|
15561
|
-
}
|
|
15562
|
-
if (min !== void 0 && value < min) {
|
|
15563
|
-
value = min;
|
|
15564
|
-
}
|
|
15565
|
-
if (max !== void 0 && value > max) {
|
|
15566
|
-
value = max;
|
|
15567
|
-
}
|
|
15568
|
-
return value;
|
|
15677
|
+
return null;
|
|
15569
15678
|
}
|
|
15570
|
-
class
|
|
15571
|
-
constructor(
|
|
15572
|
-
this.type =
|
|
15573
|
-
this.
|
|
15574
|
-
this.scope = scope;
|
|
15575
|
-
this.featureConstant = featureConstant;
|
|
15679
|
+
class Distance {
|
|
15680
|
+
constructor(geojson) {
|
|
15681
|
+
this.type = NumberType;
|
|
15682
|
+
this.geojson = geojson;
|
|
15576
15683
|
}
|
|
15577
15684
|
static parse(args, context) {
|
|
15578
|
-
|
|
15579
|
-
|
|
15580
|
-
if (args.length < 2 || args.length > 3) {
|
|
15581
|
-
return context.error(`Invalid number of arguments for 'config' expression.`);
|
|
15582
|
-
}
|
|
15583
|
-
const configKey = context.parse(args[1], 1);
|
|
15584
|
-
if (!(configKey instanceof Literal)) {
|
|
15585
|
-
return context.error(`Key name of 'config' expression must be a string literal.`);
|
|
15685
|
+
if (args.length !== 2) {
|
|
15686
|
+
return context.error(`'distance' expression requires either one argument, but found ' ${args.length - 1} instead.`);
|
|
15586
15687
|
}
|
|
15587
|
-
|
|
15588
|
-
|
|
15589
|
-
const
|
|
15590
|
-
if (
|
|
15591
|
-
|
|
15592
|
-
|
|
15593
|
-
|
|
15688
|
+
const arg = args[1];
|
|
15689
|
+
const isBareGeoJSON = isValue(arg) && !Array.isArray(arg);
|
|
15690
|
+
const parsed = context.parse(isBareGeoJSON ? ["literal", arg] : arg, 1, ValueType);
|
|
15691
|
+
if (!parsed) return null;
|
|
15692
|
+
for (const [globalProperties, name] of [
|
|
15693
|
+
[["measure-light"], "brightness"],
|
|
15694
|
+
[["pitch"], "pitch"],
|
|
15695
|
+
[["distance-from-center"], "distance-from-center"]
|
|
15696
|
+
]) {
|
|
15697
|
+
if (!isGlobalPropertyConstant(parsed, globalProperties)) {
|
|
15698
|
+
return context.error(`'distance' expression may not depend on ${name}.`);
|
|
15594
15699
|
}
|
|
15595
|
-
configScopeValue = toString(configScope.value);
|
|
15596
15700
|
}
|
|
15597
|
-
if (
|
|
15598
|
-
|
|
15599
|
-
const config = context.options.get(fqid);
|
|
15600
|
-
if (config) {
|
|
15601
|
-
featureConstant = isFeatureConstant(config.value || config.default);
|
|
15602
|
-
}
|
|
15701
|
+
if (!isStateConstant(parsed)) {
|
|
15702
|
+
return context.error(`'distance' expression may not depend on feature-state.`);
|
|
15603
15703
|
}
|
|
15604
|
-
|
|
15704
|
+
if (parsed instanceof Literal && !extractDistanceGeometry(parsed.value)) {
|
|
15705
|
+
return context.error(
|
|
15706
|
+
"'distance' expression needs to be an array with format ['Distance', GeoJSONObj]."
|
|
15707
|
+
);
|
|
15708
|
+
}
|
|
15709
|
+
return new Distance(parsed);
|
|
15605
15710
|
}
|
|
15606
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15607
15711
|
evaluate(ctx) {
|
|
15608
|
-
const
|
|
15609
|
-
|
|
15610
|
-
|
|
15611
|
-
|
|
15612
|
-
const defaultValue = config.default.evaluate(ctx);
|
|
15613
|
-
let result = defaultValue;
|
|
15614
|
-
if (value) {
|
|
15615
|
-
const originalScope = ctx.scope;
|
|
15616
|
-
ctx.scope = (originalScope || "").split(FQIDSeparator).slice(1).join(FQIDSeparator);
|
|
15617
|
-
result = value.evaluate(ctx);
|
|
15618
|
-
ctx.scope = originalScope;
|
|
15619
|
-
}
|
|
15620
|
-
if (type) {
|
|
15621
|
-
result = coerceValue(type, result);
|
|
15712
|
+
const geometries = extractDistanceGeometry(this.geojson.evaluate(ctx));
|
|
15713
|
+
if (!geometries) {
|
|
15714
|
+
console.warn("Distance Expression: could not resolve a valid Point/LineString/Polygon GeoJSON geometry.");
|
|
15715
|
+
return null;
|
|
15622
15716
|
}
|
|
15623
|
-
|
|
15624
|
-
|
|
15625
|
-
|
|
15626
|
-
|
|
15627
|
-
|
|
15628
|
-
}
|
|
15717
|
+
const geometry = ctx.geometry();
|
|
15718
|
+
const canonical = ctx.canonicalID();
|
|
15719
|
+
if (geometry == null || canonical == null) {
|
|
15720
|
+
console.warn("Distance Expression: requires valid feature and canonical information.");
|
|
15721
|
+
return null;
|
|
15629
15722
|
}
|
|
15630
|
-
|
|
15631
|
-
|
|
15632
|
-
|
|
15633
|
-
|
|
15634
|
-
|
|
15723
|
+
const geometryType = ctx.geometryType();
|
|
15724
|
+
const distanceTo = geometryType === "Point" ? pointsToGeometryDistance : geometryType === "LineString" ? linesToGeometryDistance : geometryType === "Polygon" ? polygonsToGeometryDistance : null;
|
|
15725
|
+
if (!distanceTo) {
|
|
15726
|
+
console.warn("Distance Expression: currently only evaluates valid Point/LineString/Polygon geometries.");
|
|
15727
|
+
return null;
|
|
15635
15728
|
}
|
|
15636
|
-
|
|
15637
|
-
|
|
15729
|
+
let dist = Infinity;
|
|
15730
|
+
for (const g of geometries) {
|
|
15731
|
+
const tempDist = distanceTo(geometry, canonical, g);
|
|
15732
|
+
if (tempDist == null || isNaN(tempDist)) return tempDist;
|
|
15733
|
+
if ((dist = Math.min(dist, tempDist)) === 0) break;
|
|
15638
15734
|
}
|
|
15639
|
-
return
|
|
15735
|
+
return dist;
|
|
15640
15736
|
}
|
|
15641
|
-
eachChild() {
|
|
15737
|
+
eachChild(fn) {
|
|
15738
|
+
fn(this.geojson);
|
|
15642
15739
|
}
|
|
15643
15740
|
outputDefined() {
|
|
15644
|
-
return
|
|
15741
|
+
return true;
|
|
15645
15742
|
}
|
|
15646
15743
|
serialize() {
|
|
15647
|
-
|
|
15648
|
-
if (this.scope) {
|
|
15649
|
-
res.concat(this.scope);
|
|
15650
|
-
}
|
|
15651
|
-
return res;
|
|
15744
|
+
return ["distance", this.geojson.serialize()];
|
|
15652
15745
|
}
|
|
15653
15746
|
}
|
|
15654
15747
|
|
|
@@ -17886,7 +17979,7 @@ function createFunction(parameters, propertySpec) {
|
|
|
17886
17979
|
kind: "composite",
|
|
17887
17980
|
interpolationType,
|
|
17888
17981
|
interpolationFactor: Interpolate.interpolationFactor.bind(void 0, interpolationType),
|
|
17889
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
17982
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
17890
17983
|
zoomStops: featureFunctionStops.map((s) => s[0]),
|
|
17891
17984
|
evaluate({ zoom }, properties) {
|
|
17892
17985
|
return evaluateExponentialFunction({
|
|
@@ -18017,15 +18110,16 @@ class StyleExpression {
|
|
|
18017
18110
|
this.isIndoorDependent = isIndoorDependent(expression);
|
|
18018
18111
|
}
|
|
18019
18112
|
evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection, featureTileCoord, featureDistanceData) {
|
|
18020
|
-
this._evaluator
|
|
18021
|
-
|
|
18022
|
-
|
|
18023
|
-
|
|
18024
|
-
|
|
18025
|
-
|
|
18026
|
-
|
|
18027
|
-
|
|
18028
|
-
|
|
18113
|
+
const evaluator = this._evaluator;
|
|
18114
|
+
evaluator.globals = globals;
|
|
18115
|
+
evaluator.feature = feature;
|
|
18116
|
+
evaluator.featureState = featureState;
|
|
18117
|
+
evaluator.canonical = canonical || null;
|
|
18118
|
+
evaluator.availableImages = availableImages || null;
|
|
18119
|
+
evaluator.formattedSection = formattedSection;
|
|
18120
|
+
evaluator.featureTileCoord = featureTileCoord || null;
|
|
18121
|
+
evaluator.featureDistanceData = featureDistanceData || null;
|
|
18122
|
+
return this.expression.evaluate(evaluator);
|
|
18029
18123
|
}
|
|
18030
18124
|
evaluate(globals, feature, featureState, canonical, availableImages, formattedSection, featureTileCoord, featureDistanceData, iconImageUseTheme) {
|
|
18031
18125
|
if (!this._evaluator) {
|
|
@@ -18243,7 +18337,8 @@ function getExpectedType(spec) {
|
|
|
18243
18337
|
enum: StringType,
|
|
18244
18338
|
boolean: BooleanType,
|
|
18245
18339
|
formatted: FormattedType,
|
|
18246
|
-
resolvedImage: ResolvedImageType
|
|
18340
|
+
resolvedImage: ResolvedImageType,
|
|
18341
|
+
object: ObjectType
|
|
18247
18342
|
};
|
|
18248
18343
|
if (spec.type === "array") {
|
|
18249
18344
|
return array$1(types[spec.value] || ValueType, spec.length);
|
|
@@ -19507,17 +19602,23 @@ function validateOption(options) {
|
|
|
19507
19602
|
const optionValue = options.value;
|
|
19508
19603
|
const isArrayOption = isObject(optionValue) && unbundle(optionValue.array) === true;
|
|
19509
19604
|
const declaredType = !isArrayOption && isObject(optionValue) ? unbundle(optionValue.type) : void 0;
|
|
19605
|
+
const validateDefault = (elementOptions) => {
|
|
19606
|
+
const defaultValue = elementOptions.value;
|
|
19607
|
+
if (isObject(defaultValue)) {
|
|
19608
|
+
return validate({ ...elementOptions, valueSpec: { ...elementOptions.valueSpec, type: "*", expression: void 0 } });
|
|
19609
|
+
}
|
|
19610
|
+
if (declaredType && Array.isArray(defaultValue)) {
|
|
19611
|
+
return validate({ ...elementOptions, valueSpec: { ...elementOptions.valueSpec, type: declaredType } });
|
|
19612
|
+
}
|
|
19613
|
+
return validate(elementOptions);
|
|
19614
|
+
};
|
|
19510
19615
|
return validateObject({
|
|
19511
19616
|
...options,
|
|
19512
19617
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
19513
19618
|
valueSpec: styleSpec.option,
|
|
19514
|
-
objectElementValidators:
|
|
19515
|
-
|
|
19516
|
-
|
|
19517
|
-
// permissive validation, mirroring the runtime parser's narrowing
|
|
19518
|
-
// in style.ts/parser.cpp.
|
|
19519
|
-
default: (elementOptions) => Array.isArray(elementOptions.value) ? validate({ ...elementOptions, valueSpec: { ...elementOptions.valueSpec, type: declaredType } }) : validate(elementOptions)
|
|
19520
|
-
} : void 0
|
|
19619
|
+
objectElementValidators: {
|
|
19620
|
+
default: validateDefault
|
|
19621
|
+
}
|
|
19521
19622
|
});
|
|
19522
19623
|
}
|
|
19523
19624
|
|