@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.cjs
CHANGED
|
@@ -375,6 +375,16 @@
|
|
|
375
375
|
},
|
|
376
376
|
color: {
|
|
377
377
|
doc: "The result will be coerced to a color."
|
|
378
|
+
},
|
|
379
|
+
object: {
|
|
380
|
+
doc: "The result will be coerced to an object.",
|
|
381
|
+
"sdk-support": {
|
|
382
|
+
"basic functionality": {
|
|
383
|
+
js: "3.29.0",
|
|
384
|
+
android: "11.29.0",
|
|
385
|
+
ios: "11.29.0"
|
|
386
|
+
}
|
|
387
|
+
}
|
|
378
388
|
}
|
|
379
389
|
}
|
|
380
390
|
},
|
|
@@ -3006,6 +3016,7 @@
|
|
|
3006
3016
|
experimental: true,
|
|
3007
3017
|
"sdk-support": {
|
|
3008
3018
|
"basic functionality": {
|
|
3019
|
+
js: "3.7.0",
|
|
3009
3020
|
android: "11.9.0",
|
|
3010
3021
|
ios: "11.9.0"
|
|
3011
3022
|
}
|
|
@@ -5479,13 +5490,18 @@
|
|
|
5479
5490
|
}
|
|
5480
5491
|
},
|
|
5481
5492
|
distance: {
|
|
5482
|
-
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
|
|
5493
|
+
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.",
|
|
5483
5494
|
group: "Math",
|
|
5484
5495
|
"sdk-support": {
|
|
5485
5496
|
"basic functionality": {
|
|
5486
5497
|
js: "3.0.0",
|
|
5487
5498
|
android: "9.2.0",
|
|
5488
5499
|
ios: "5.9.0"
|
|
5500
|
+
},
|
|
5501
|
+
"expressions support": {
|
|
5502
|
+
js: "3.29.0",
|
|
5503
|
+
android: "11.29.0",
|
|
5504
|
+
ios: "11.29.0"
|
|
5489
5505
|
}
|
|
5490
5506
|
}
|
|
5491
5507
|
},
|
|
@@ -9455,7 +9471,6 @@
|
|
|
9455
9471
|
"default": 0,
|
|
9456
9472
|
minimum: 0,
|
|
9457
9473
|
transition: true,
|
|
9458
|
-
experimental: true,
|
|
9459
9474
|
appearance: true,
|
|
9460
9475
|
"sdk-support": {
|
|
9461
9476
|
"basic functionality": {
|
|
@@ -9509,7 +9524,7 @@
|
|
|
9509
9524
|
},
|
|
9510
9525
|
"raster-color": {
|
|
9511
9526
|
type: "color",
|
|
9512
|
-
doc: "Defines
|
|
9527
|
+
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.",
|
|
9513
9528
|
"use-theme": true,
|
|
9514
9529
|
transition: false,
|
|
9515
9530
|
"sdk-support": {
|
|
@@ -9550,7 +9565,7 @@
|
|
|
9550
9565
|
"zoom"
|
|
9551
9566
|
]
|
|
9552
9567
|
},
|
|
9553
|
-
doc: "When `raster-color` is active, specifies the
|
|
9568
|
+
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.",
|
|
9554
9569
|
example: [
|
|
9555
9570
|
0.2126,
|
|
9556
9571
|
0.7152,
|
|
@@ -9580,7 +9595,7 @@
|
|
|
9580
9595
|
"zoom"
|
|
9581
9596
|
]
|
|
9582
9597
|
},
|
|
9583
|
-
doc: "When `raster-color` is active, specifies the range
|
|
9598
|
+
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.",
|
|
9584
9599
|
example: [
|
|
9585
9600
|
0.5,
|
|
9586
9601
|
10
|
|
@@ -9593,6 +9608,37 @@
|
|
|
9593
9608
|
}
|
|
9594
9609
|
}
|
|
9595
9610
|
},
|
|
9611
|
+
"raster-color-scale": {
|
|
9612
|
+
type: "enum",
|
|
9613
|
+
doc: "When `raster-color` is active, specifies how raster values are distributed across the color ramp over the range specified by `raster-color-range`.",
|
|
9614
|
+
values: {
|
|
9615
|
+
linear: {
|
|
9616
|
+
doc: "Raster values are spaced evenly across the color ramp."
|
|
9617
|
+
},
|
|
9618
|
+
log: {
|
|
9619
|
+
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."
|
|
9620
|
+
}
|
|
9621
|
+
},
|
|
9622
|
+
"default": "linear",
|
|
9623
|
+
requires: [
|
|
9624
|
+
"raster-color",
|
|
9625
|
+
{
|
|
9626
|
+
source: "raster-array"
|
|
9627
|
+
}
|
|
9628
|
+
],
|
|
9629
|
+
expression: {
|
|
9630
|
+
interpolated: false,
|
|
9631
|
+
parameters: [
|
|
9632
|
+
]
|
|
9633
|
+
},
|
|
9634
|
+
"property-type": "data-constant",
|
|
9635
|
+
experimental: true,
|
|
9636
|
+
"sdk-support": {
|
|
9637
|
+
"basic functionality": {
|
|
9638
|
+
js: "3.29.0"
|
|
9639
|
+
}
|
|
9640
|
+
}
|
|
9641
|
+
},
|
|
9596
9642
|
"raster-hue-rotate": {
|
|
9597
9643
|
type: "number",
|
|
9598
9644
|
"default": 0,
|
|
@@ -9846,6 +9892,21 @@
|
|
|
9846
9892
|
interpolated: false
|
|
9847
9893
|
},
|
|
9848
9894
|
"property-type": "data-constant"
|
|
9895
|
+
},
|
|
9896
|
+
"raster-allow-draping": {
|
|
9897
|
+
type: "boolean",
|
|
9898
|
+
"default": true,
|
|
9899
|
+
experimental: true,
|
|
9900
|
+
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.",
|
|
9901
|
+
transition: false,
|
|
9902
|
+
"property-type": "data-constant",
|
|
9903
|
+
"sdk-support": {
|
|
9904
|
+
"basic functionality": {
|
|
9905
|
+
js: "3.28.0",
|
|
9906
|
+
android: "11.28.0",
|
|
9907
|
+
ios: "11.28.0"
|
|
9908
|
+
}
|
|
9909
|
+
}
|
|
9849
9910
|
}
|
|
9850
9911
|
};
|
|
9851
9912
|
var paint_hillshade = {
|
|
@@ -14881,6 +14942,189 @@
|
|
|
14881
14942
|
|
|
14882
14943
|
var EXTENT = 8192;
|
|
14883
14944
|
|
|
14945
|
+
const FQIDSeparator = "";
|
|
14946
|
+
function makeConfigFQID(id, ownScope, contextScope) {
|
|
14947
|
+
return [id, ownScope, contextScope].filter(Boolean).join(FQIDSeparator);
|
|
14948
|
+
}
|
|
14949
|
+
function coerceValue(type, value) {
|
|
14950
|
+
switch (type) {
|
|
14951
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
14952
|
+
case "string":
|
|
14953
|
+
return toString(value);
|
|
14954
|
+
case "number":
|
|
14955
|
+
return +value;
|
|
14956
|
+
case "boolean":
|
|
14957
|
+
return !!value;
|
|
14958
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
14959
|
+
case "color":
|
|
14960
|
+
return Color.parse(value);
|
|
14961
|
+
case "formatted": {
|
|
14962
|
+
return Formatted.fromString(toString(value));
|
|
14963
|
+
}
|
|
14964
|
+
case "resolvedImage": {
|
|
14965
|
+
return ResolvedImage.build(toString(value));
|
|
14966
|
+
}
|
|
14967
|
+
}
|
|
14968
|
+
return value;
|
|
14969
|
+
}
|
|
14970
|
+
function clampToAllowedNumber(value, min, max, step) {
|
|
14971
|
+
if (step !== void 0) {
|
|
14972
|
+
value = step * Math.round(value / step);
|
|
14973
|
+
}
|
|
14974
|
+
if (min !== void 0 && value < min) {
|
|
14975
|
+
value = min;
|
|
14976
|
+
}
|
|
14977
|
+
if (max !== void 0 && value > max) {
|
|
14978
|
+
value = max;
|
|
14979
|
+
}
|
|
14980
|
+
return value;
|
|
14981
|
+
}
|
|
14982
|
+
class Config {
|
|
14983
|
+
constructor(type, key, scope, featureConstant = false) {
|
|
14984
|
+
this.type = type;
|
|
14985
|
+
this.key = key;
|
|
14986
|
+
this.scope = scope;
|
|
14987
|
+
this.featureConstant = featureConstant;
|
|
14988
|
+
}
|
|
14989
|
+
static parse(args, context) {
|
|
14990
|
+
let type = context.expectedType;
|
|
14991
|
+
type ?? (type = ValueType);
|
|
14992
|
+
if (args.length < 2 || args.length > 3) {
|
|
14993
|
+
return context.error(`Invalid number of arguments for 'config' expression.`);
|
|
14994
|
+
}
|
|
14995
|
+
const configKey = context.parse(args[1], 1);
|
|
14996
|
+
if (!(configKey instanceof Literal)) {
|
|
14997
|
+
return context.error(`Key name of 'config' expression must be a string literal.`);
|
|
14998
|
+
}
|
|
14999
|
+
let featureConstant = true;
|
|
15000
|
+
let configScopeValue;
|
|
15001
|
+
const configKeyValue = toString(configKey.value);
|
|
15002
|
+
if (args.length >= 3) {
|
|
15003
|
+
const configScope = context.parse(args[2], 2);
|
|
15004
|
+
if (!(configScope instanceof Literal)) {
|
|
15005
|
+
return context.error(`Scope of 'config' expression must be a string literal.`);
|
|
15006
|
+
}
|
|
15007
|
+
configScopeValue = toString(configScope.value);
|
|
15008
|
+
}
|
|
15009
|
+
if (context.options) {
|
|
15010
|
+
const fqid = makeConfigFQID(configKeyValue, configScopeValue, context._scope);
|
|
15011
|
+
const config = context.options.get(fqid);
|
|
15012
|
+
if (config) {
|
|
15013
|
+
featureConstant = isFeatureConstant(config.value || config.default);
|
|
15014
|
+
}
|
|
15015
|
+
}
|
|
15016
|
+
return new Config(type, configKeyValue, configScopeValue, featureConstant);
|
|
15017
|
+
}
|
|
15018
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15019
|
+
evaluate(ctx) {
|
|
15020
|
+
const fqid = makeConfigFQID(this.key, this.scope, ctx.scope);
|
|
15021
|
+
const config = ctx.getConfig(fqid);
|
|
15022
|
+
if (!config) return null;
|
|
15023
|
+
const { type, value, values, minValue, maxValue, stepValue } = config;
|
|
15024
|
+
const defaultValue = config.default.evaluate(ctx);
|
|
15025
|
+
let result = defaultValue;
|
|
15026
|
+
if (value) {
|
|
15027
|
+
const originalScope = ctx.scope;
|
|
15028
|
+
ctx.scope = (originalScope || "").split(FQIDSeparator).slice(1).join(FQIDSeparator);
|
|
15029
|
+
result = value.evaluate(ctx);
|
|
15030
|
+
ctx.scope = originalScope;
|
|
15031
|
+
}
|
|
15032
|
+
if (type) {
|
|
15033
|
+
result = coerceValue(type, result);
|
|
15034
|
+
}
|
|
15035
|
+
if (result !== void 0 && (minValue !== void 0 || maxValue !== void 0 || stepValue !== void 0)) {
|
|
15036
|
+
if (typeof result === "number") {
|
|
15037
|
+
result = clampToAllowedNumber(result, minValue, maxValue, stepValue);
|
|
15038
|
+
} else if (Array.isArray(result)) {
|
|
15039
|
+
result = result.map((item) => typeof item === "number" ? clampToAllowedNumber(item, minValue, maxValue, stepValue) : item);
|
|
15040
|
+
}
|
|
15041
|
+
}
|
|
15042
|
+
if (value !== void 0 && result !== void 0 && values && !values.includes(result)) {
|
|
15043
|
+
result = defaultValue;
|
|
15044
|
+
if (type) {
|
|
15045
|
+
result = coerceValue(type, result);
|
|
15046
|
+
}
|
|
15047
|
+
}
|
|
15048
|
+
if (type && type !== this.type || result !== void 0 && !typeEquals(typeOf(result), this.type)) {
|
|
15049
|
+
result = coerceValue(this.type.kind, result);
|
|
15050
|
+
}
|
|
15051
|
+
return result;
|
|
15052
|
+
}
|
|
15053
|
+
eachChild() {
|
|
15054
|
+
}
|
|
15055
|
+
outputDefined() {
|
|
15056
|
+
return false;
|
|
15057
|
+
}
|
|
15058
|
+
serialize() {
|
|
15059
|
+
const res = ["config", this.key];
|
|
15060
|
+
if (this.scope) {
|
|
15061
|
+
res.concat(this.scope);
|
|
15062
|
+
}
|
|
15063
|
+
return res;
|
|
15064
|
+
}
|
|
15065
|
+
}
|
|
15066
|
+
|
|
15067
|
+
function isFeatureConstant(e) {
|
|
15068
|
+
if (e instanceof CompoundExpression) {
|
|
15069
|
+
if (e.name === "get" && e.args.length === 1) {
|
|
15070
|
+
return false;
|
|
15071
|
+
} else if (e.name === "feature-state") {
|
|
15072
|
+
return false;
|
|
15073
|
+
} else if (e.name === "has" && e.args.length === 1) {
|
|
15074
|
+
return false;
|
|
15075
|
+
} else if (e.name === "properties" || e.name === "geometry-type" || e.name === "id") {
|
|
15076
|
+
return false;
|
|
15077
|
+
} else if (e.name.startsWith("filter-")) {
|
|
15078
|
+
return false;
|
|
15079
|
+
}
|
|
15080
|
+
}
|
|
15081
|
+
if (e instanceof Within) {
|
|
15082
|
+
return false;
|
|
15083
|
+
}
|
|
15084
|
+
if (e instanceof Distance) {
|
|
15085
|
+
return false;
|
|
15086
|
+
}
|
|
15087
|
+
if (e instanceof Config) {
|
|
15088
|
+
return e.featureConstant;
|
|
15089
|
+
}
|
|
15090
|
+
let result = true;
|
|
15091
|
+
e.eachChild((arg) => {
|
|
15092
|
+
if (result && !isFeatureConstant(arg)) {
|
|
15093
|
+
result = false;
|
|
15094
|
+
}
|
|
15095
|
+
});
|
|
15096
|
+
return result;
|
|
15097
|
+
}
|
|
15098
|
+
function isStateConstant(e) {
|
|
15099
|
+
if (e instanceof CompoundExpression) {
|
|
15100
|
+
if (e.name === "feature-state") {
|
|
15101
|
+
return false;
|
|
15102
|
+
}
|
|
15103
|
+
}
|
|
15104
|
+
let result = true;
|
|
15105
|
+
e.eachChild((arg) => {
|
|
15106
|
+
if (result && !isStateConstant(arg)) {
|
|
15107
|
+
result = false;
|
|
15108
|
+
}
|
|
15109
|
+
});
|
|
15110
|
+
return result;
|
|
15111
|
+
}
|
|
15112
|
+
function isGlobalPropertyConstantSet(e, properties) {
|
|
15113
|
+
if (e instanceof CompoundExpression && properties.has(e.name)) {
|
|
15114
|
+
return false;
|
|
15115
|
+
}
|
|
15116
|
+
let result = true;
|
|
15117
|
+
e.eachChild((arg) => {
|
|
15118
|
+
if (result && !isGlobalPropertyConstantSet(arg, properties)) {
|
|
15119
|
+
result = false;
|
|
15120
|
+
}
|
|
15121
|
+
});
|
|
15122
|
+
return result;
|
|
15123
|
+
}
|
|
15124
|
+
function isGlobalPropertyConstant(e, properties) {
|
|
15125
|
+
return isGlobalPropertyConstantSet(e, new Set(properties));
|
|
15126
|
+
}
|
|
15127
|
+
|
|
14884
15128
|
const RE = 6378.137;
|
|
14885
15129
|
const FE = 1 / 298.257223563;
|
|
14886
15130
|
const E2 = FE * (2 - FE);
|
|
@@ -15416,245 +15660,94 @@
|
|
|
15416
15660
|
function isTypeValid(type) {
|
|
15417
15661
|
return type === "Point" || type === "MultiPoint" || type === "LineString" || type === "MultiLineString" || type === "Polygon" || type === "MultiPolygon";
|
|
15418
15662
|
}
|
|
15419
|
-
|
|
15420
|
-
|
|
15421
|
-
this.type = NumberType;
|
|
15422
|
-
this.geojson = geojson;
|
|
15423
|
-
this.geometries = geometries;
|
|
15424
|
-
}
|
|
15425
|
-
static parse(args, context) {
|
|
15426
|
-
if (args.length !== 2) {
|
|
15427
|
-
return context.error(`'distance' expression requires either one argument, but found ' ${args.length - 1} instead.`);
|
|
15428
|
-
}
|
|
15429
|
-
if (isValue(args[1])) {
|
|
15430
|
-
const geojson = args[1];
|
|
15431
|
-
if (geojson.type === "FeatureCollection") {
|
|
15432
|
-
for (let i = 0; i < geojson.features.length; ++i) {
|
|
15433
|
-
if (isTypeValid(geojson.features[i].geometry.type)) {
|
|
15434
|
-
return new Distance(geojson, geojson.features[i].geometry);
|
|
15435
|
-
}
|
|
15436
|
-
}
|
|
15437
|
-
} else if (geojson.type === "Feature") {
|
|
15438
|
-
if (isTypeValid(geojson.geometry.type)) {
|
|
15439
|
-
return new Distance(geojson, geojson.geometry);
|
|
15440
|
-
}
|
|
15441
|
-
} else if (isTypeValid(geojson.type)) {
|
|
15442
|
-
return new Distance(geojson, geojson);
|
|
15443
|
-
}
|
|
15444
|
-
}
|
|
15445
|
-
return context.error(
|
|
15446
|
-
"'distance' expression needs to be an array with format ['Distance', GeoJSONObj]."
|
|
15447
|
-
);
|
|
15448
|
-
}
|
|
15449
|
-
evaluate(ctx) {
|
|
15450
|
-
const geometry = ctx.geometry();
|
|
15451
|
-
const canonical = ctx.canonicalID();
|
|
15452
|
-
if (geometry != null && canonical != null) {
|
|
15453
|
-
if (ctx.geometryType() === "Point") {
|
|
15454
|
-
return pointsToGeometryDistance(geometry, canonical, this.geometries);
|
|
15455
|
-
}
|
|
15456
|
-
if (ctx.geometryType() === "LineString") {
|
|
15457
|
-
return linesToGeometryDistance(geometry, canonical, this.geometries);
|
|
15458
|
-
}
|
|
15459
|
-
if (ctx.geometryType() === "Polygon") {
|
|
15460
|
-
return polygonsToGeometryDistance(geometry, canonical, this.geometries);
|
|
15461
|
-
}
|
|
15462
|
-
console.warn("Distance Expression: currently only evaluates valid Point/LineString/Polygon geometries.");
|
|
15463
|
-
} else {
|
|
15464
|
-
console.warn("Distance Expression: requires valid feature and canonical information.");
|
|
15465
|
-
}
|
|
15663
|
+
function extractDistanceGeometry(value) {
|
|
15664
|
+
if (!isValue(value) || typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
15466
15665
|
return null;
|
|
15467
15666
|
}
|
|
15468
|
-
|
|
15469
|
-
|
|
15470
|
-
|
|
15471
|
-
|
|
15472
|
-
|
|
15473
|
-
|
|
15474
|
-
|
|
15475
|
-
}
|
|
15476
|
-
}
|
|
15477
|
-
|
|
15478
|
-
function isFeatureConstant(e) {
|
|
15479
|
-
if (e instanceof CompoundExpression) {
|
|
15480
|
-
if (e.name === "get" && e.args.length === 1) {
|
|
15481
|
-
return false;
|
|
15482
|
-
} else if (e.name === "feature-state") {
|
|
15483
|
-
return false;
|
|
15484
|
-
} else if (e.name === "has" && e.args.length === 1) {
|
|
15485
|
-
return false;
|
|
15486
|
-
} else if (e.name === "properties" || e.name === "geometry-type" || e.name === "id") {
|
|
15487
|
-
return false;
|
|
15488
|
-
} else if (e.name.startsWith("filter-")) {
|
|
15489
|
-
return false;
|
|
15667
|
+
const geojson = value;
|
|
15668
|
+
if (geojson.type === "FeatureCollection") {
|
|
15669
|
+
if (geojson.features.length === 0) return null;
|
|
15670
|
+
const geometries = [];
|
|
15671
|
+
for (const feature of geojson.features) {
|
|
15672
|
+
if (!isTypeValid(feature.geometry.type)) return null;
|
|
15673
|
+
geometries.push(feature.geometry);
|
|
15490
15674
|
}
|
|
15675
|
+
return geometries;
|
|
15491
15676
|
}
|
|
15492
|
-
if (
|
|
15493
|
-
return
|
|
15677
|
+
if (geojson.type === "Feature") {
|
|
15678
|
+
return isTypeValid(geojson.geometry.type) ? [geojson.geometry] : null;
|
|
15494
15679
|
}
|
|
15495
|
-
if (
|
|
15496
|
-
return
|
|
15680
|
+
if (isTypeValid(geojson.type)) {
|
|
15681
|
+
return [geojson];
|
|
15497
15682
|
}
|
|
15498
|
-
|
|
15499
|
-
return e.featureConstant;
|
|
15500
|
-
}
|
|
15501
|
-
let result = true;
|
|
15502
|
-
e.eachChild((arg) => {
|
|
15503
|
-
if (result && !isFeatureConstant(arg)) {
|
|
15504
|
-
result = false;
|
|
15505
|
-
}
|
|
15506
|
-
});
|
|
15507
|
-
return result;
|
|
15508
|
-
}
|
|
15509
|
-
function isStateConstant(e) {
|
|
15510
|
-
if (e instanceof CompoundExpression) {
|
|
15511
|
-
if (e.name === "feature-state") {
|
|
15512
|
-
return false;
|
|
15513
|
-
}
|
|
15514
|
-
}
|
|
15515
|
-
let result = true;
|
|
15516
|
-
e.eachChild((arg) => {
|
|
15517
|
-
if (result && !isStateConstant(arg)) {
|
|
15518
|
-
result = false;
|
|
15519
|
-
}
|
|
15520
|
-
});
|
|
15521
|
-
return result;
|
|
15522
|
-
}
|
|
15523
|
-
function isGlobalPropertyConstantSet(e, properties) {
|
|
15524
|
-
if (e instanceof CompoundExpression && properties.has(e.name)) {
|
|
15525
|
-
return false;
|
|
15526
|
-
}
|
|
15527
|
-
let result = true;
|
|
15528
|
-
e.eachChild((arg) => {
|
|
15529
|
-
if (result && !isGlobalPropertyConstantSet(arg, properties)) {
|
|
15530
|
-
result = false;
|
|
15531
|
-
}
|
|
15532
|
-
});
|
|
15533
|
-
return result;
|
|
15534
|
-
}
|
|
15535
|
-
function isGlobalPropertyConstant(e, properties) {
|
|
15536
|
-
return isGlobalPropertyConstantSet(e, new Set(properties));
|
|
15537
|
-
}
|
|
15538
|
-
|
|
15539
|
-
const FQIDSeparator = "";
|
|
15540
|
-
function makeConfigFQID(id, ownScope, contextScope) {
|
|
15541
|
-
return [id, ownScope, contextScope].filter(Boolean).join(FQIDSeparator);
|
|
15542
|
-
}
|
|
15543
|
-
function coerceValue(type, value) {
|
|
15544
|
-
switch (type) {
|
|
15545
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
15546
|
-
case "string":
|
|
15547
|
-
return toString(value);
|
|
15548
|
-
case "number":
|
|
15549
|
-
return +value;
|
|
15550
|
-
case "boolean":
|
|
15551
|
-
return !!value;
|
|
15552
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
15553
|
-
case "color":
|
|
15554
|
-
return Color.parse(value);
|
|
15555
|
-
case "formatted": {
|
|
15556
|
-
return Formatted.fromString(toString(value));
|
|
15557
|
-
}
|
|
15558
|
-
case "resolvedImage": {
|
|
15559
|
-
return ResolvedImage.build(toString(value));
|
|
15560
|
-
}
|
|
15561
|
-
}
|
|
15562
|
-
return value;
|
|
15563
|
-
}
|
|
15564
|
-
function clampToAllowedNumber(value, min, max, step) {
|
|
15565
|
-
if (step !== void 0) {
|
|
15566
|
-
value = step * Math.round(value / step);
|
|
15567
|
-
}
|
|
15568
|
-
if (min !== void 0 && value < min) {
|
|
15569
|
-
value = min;
|
|
15570
|
-
}
|
|
15571
|
-
if (max !== void 0 && value > max) {
|
|
15572
|
-
value = max;
|
|
15573
|
-
}
|
|
15574
|
-
return value;
|
|
15683
|
+
return null;
|
|
15575
15684
|
}
|
|
15576
|
-
class
|
|
15577
|
-
constructor(
|
|
15578
|
-
this.type =
|
|
15579
|
-
this.
|
|
15580
|
-
this.scope = scope;
|
|
15581
|
-
this.featureConstant = featureConstant;
|
|
15685
|
+
class Distance {
|
|
15686
|
+
constructor(geojson) {
|
|
15687
|
+
this.type = NumberType;
|
|
15688
|
+
this.geojson = geojson;
|
|
15582
15689
|
}
|
|
15583
15690
|
static parse(args, context) {
|
|
15584
|
-
|
|
15585
|
-
|
|
15586
|
-
if (args.length < 2 || args.length > 3) {
|
|
15587
|
-
return context.error(`Invalid number of arguments for 'config' expression.`);
|
|
15588
|
-
}
|
|
15589
|
-
const configKey = context.parse(args[1], 1);
|
|
15590
|
-
if (!(configKey instanceof Literal)) {
|
|
15591
|
-
return context.error(`Key name of 'config' expression must be a string literal.`);
|
|
15691
|
+
if (args.length !== 2) {
|
|
15692
|
+
return context.error(`'distance' expression requires either one argument, but found ' ${args.length - 1} instead.`);
|
|
15592
15693
|
}
|
|
15593
|
-
|
|
15594
|
-
|
|
15595
|
-
const
|
|
15596
|
-
if (
|
|
15597
|
-
|
|
15598
|
-
|
|
15599
|
-
|
|
15694
|
+
const arg = args[1];
|
|
15695
|
+
const isBareGeoJSON = isValue(arg) && !Array.isArray(arg);
|
|
15696
|
+
const parsed = context.parse(isBareGeoJSON ? ["literal", arg] : arg, 1, ValueType);
|
|
15697
|
+
if (!parsed) return null;
|
|
15698
|
+
for (const [globalProperties, name] of [
|
|
15699
|
+
[["measure-light"], "brightness"],
|
|
15700
|
+
[["pitch"], "pitch"],
|
|
15701
|
+
[["distance-from-center"], "distance-from-center"]
|
|
15702
|
+
]) {
|
|
15703
|
+
if (!isGlobalPropertyConstant(parsed, globalProperties)) {
|
|
15704
|
+
return context.error(`'distance' expression may not depend on ${name}.`);
|
|
15600
15705
|
}
|
|
15601
|
-
configScopeValue = toString(configScope.value);
|
|
15602
15706
|
}
|
|
15603
|
-
if (
|
|
15604
|
-
|
|
15605
|
-
const config = context.options.get(fqid);
|
|
15606
|
-
if (config) {
|
|
15607
|
-
featureConstant = isFeatureConstant(config.value || config.default);
|
|
15608
|
-
}
|
|
15707
|
+
if (!isStateConstant(parsed)) {
|
|
15708
|
+
return context.error(`'distance' expression may not depend on feature-state.`);
|
|
15609
15709
|
}
|
|
15610
|
-
|
|
15710
|
+
if (parsed instanceof Literal && !extractDistanceGeometry(parsed.value)) {
|
|
15711
|
+
return context.error(
|
|
15712
|
+
"'distance' expression needs to be an array with format ['Distance', GeoJSONObj]."
|
|
15713
|
+
);
|
|
15714
|
+
}
|
|
15715
|
+
return new Distance(parsed);
|
|
15611
15716
|
}
|
|
15612
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15613
15717
|
evaluate(ctx) {
|
|
15614
|
-
const
|
|
15615
|
-
|
|
15616
|
-
|
|
15617
|
-
|
|
15618
|
-
const defaultValue = config.default.evaluate(ctx);
|
|
15619
|
-
let result = defaultValue;
|
|
15620
|
-
if (value) {
|
|
15621
|
-
const originalScope = ctx.scope;
|
|
15622
|
-
ctx.scope = (originalScope || "").split(FQIDSeparator).slice(1).join(FQIDSeparator);
|
|
15623
|
-
result = value.evaluate(ctx);
|
|
15624
|
-
ctx.scope = originalScope;
|
|
15625
|
-
}
|
|
15626
|
-
if (type) {
|
|
15627
|
-
result = coerceValue(type, result);
|
|
15718
|
+
const geometries = extractDistanceGeometry(this.geojson.evaluate(ctx));
|
|
15719
|
+
if (!geometries) {
|
|
15720
|
+
console.warn("Distance Expression: could not resolve a valid Point/LineString/Polygon GeoJSON geometry.");
|
|
15721
|
+
return null;
|
|
15628
15722
|
}
|
|
15629
|
-
|
|
15630
|
-
|
|
15631
|
-
|
|
15632
|
-
|
|
15633
|
-
|
|
15634
|
-
}
|
|
15723
|
+
const geometry = ctx.geometry();
|
|
15724
|
+
const canonical = ctx.canonicalID();
|
|
15725
|
+
if (geometry == null || canonical == null) {
|
|
15726
|
+
console.warn("Distance Expression: requires valid feature and canonical information.");
|
|
15727
|
+
return null;
|
|
15635
15728
|
}
|
|
15636
|
-
|
|
15637
|
-
|
|
15638
|
-
|
|
15639
|
-
|
|
15640
|
-
|
|
15729
|
+
const geometryType = ctx.geometryType();
|
|
15730
|
+
const distanceTo = geometryType === "Point" ? pointsToGeometryDistance : geometryType === "LineString" ? linesToGeometryDistance : geometryType === "Polygon" ? polygonsToGeometryDistance : null;
|
|
15731
|
+
if (!distanceTo) {
|
|
15732
|
+
console.warn("Distance Expression: currently only evaluates valid Point/LineString/Polygon geometries.");
|
|
15733
|
+
return null;
|
|
15641
15734
|
}
|
|
15642
|
-
|
|
15643
|
-
|
|
15735
|
+
let dist = Infinity;
|
|
15736
|
+
for (const g of geometries) {
|
|
15737
|
+
const tempDist = distanceTo(geometry, canonical, g);
|
|
15738
|
+
if (tempDist == null || isNaN(tempDist)) return tempDist;
|
|
15739
|
+
if ((dist = Math.min(dist, tempDist)) === 0) break;
|
|
15644
15740
|
}
|
|
15645
|
-
return
|
|
15741
|
+
return dist;
|
|
15646
15742
|
}
|
|
15647
|
-
eachChild() {
|
|
15743
|
+
eachChild(fn) {
|
|
15744
|
+
fn(this.geojson);
|
|
15648
15745
|
}
|
|
15649
15746
|
outputDefined() {
|
|
15650
|
-
return
|
|
15747
|
+
return true;
|
|
15651
15748
|
}
|
|
15652
15749
|
serialize() {
|
|
15653
|
-
|
|
15654
|
-
if (this.scope) {
|
|
15655
|
-
res.concat(this.scope);
|
|
15656
|
-
}
|
|
15657
|
-
return res;
|
|
15750
|
+
return ["distance", this.geojson.serialize()];
|
|
15658
15751
|
}
|
|
15659
15752
|
}
|
|
15660
15753
|
|
|
@@ -17892,7 +17985,7 @@
|
|
|
17892
17985
|
kind: "composite",
|
|
17893
17986
|
interpolationType,
|
|
17894
17987
|
interpolationFactor: Interpolate.interpolationFactor.bind(void 0, interpolationType),
|
|
17895
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
17988
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
17896
17989
|
zoomStops: featureFunctionStops.map((s) => s[0]),
|
|
17897
17990
|
evaluate({ zoom }, properties) {
|
|
17898
17991
|
return evaluateExponentialFunction({
|
|
@@ -18023,15 +18116,16 @@
|
|
|
18023
18116
|
this.isIndoorDependent = isIndoorDependent(expression);
|
|
18024
18117
|
}
|
|
18025
18118
|
evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection, featureTileCoord, featureDistanceData) {
|
|
18026
|
-
this._evaluator
|
|
18027
|
-
|
|
18028
|
-
|
|
18029
|
-
|
|
18030
|
-
|
|
18031
|
-
|
|
18032
|
-
|
|
18033
|
-
|
|
18034
|
-
|
|
18119
|
+
const evaluator = this._evaluator;
|
|
18120
|
+
evaluator.globals = globals;
|
|
18121
|
+
evaluator.feature = feature;
|
|
18122
|
+
evaluator.featureState = featureState;
|
|
18123
|
+
evaluator.canonical = canonical || null;
|
|
18124
|
+
evaluator.availableImages = availableImages || null;
|
|
18125
|
+
evaluator.formattedSection = formattedSection;
|
|
18126
|
+
evaluator.featureTileCoord = featureTileCoord || null;
|
|
18127
|
+
evaluator.featureDistanceData = featureDistanceData || null;
|
|
18128
|
+
return this.expression.evaluate(evaluator);
|
|
18035
18129
|
}
|
|
18036
18130
|
evaluate(globals, feature, featureState, canonical, availableImages, formattedSection, featureTileCoord, featureDistanceData, iconImageUseTheme) {
|
|
18037
18131
|
if (!this._evaluator) {
|
|
@@ -18249,7 +18343,8 @@
|
|
|
18249
18343
|
enum: StringType,
|
|
18250
18344
|
boolean: BooleanType,
|
|
18251
18345
|
formatted: FormattedType,
|
|
18252
|
-
resolvedImage: ResolvedImageType
|
|
18346
|
+
resolvedImage: ResolvedImageType,
|
|
18347
|
+
object: ObjectType
|
|
18253
18348
|
};
|
|
18254
18349
|
if (spec.type === "array") {
|
|
18255
18350
|
return array$1(types[spec.value] || ValueType, spec.length);
|
|
@@ -19513,17 +19608,23 @@ ${JSON.stringify(filterExp, null, 2)}
|
|
|
19513
19608
|
const optionValue = options.value;
|
|
19514
19609
|
const isArrayOption = isObject(optionValue) && unbundle(optionValue.array) === true;
|
|
19515
19610
|
const declaredType = !isArrayOption && isObject(optionValue) ? unbundle(optionValue.type) : void 0;
|
|
19611
|
+
const validateDefault = (elementOptions) => {
|
|
19612
|
+
const defaultValue = elementOptions.value;
|
|
19613
|
+
if (isObject(defaultValue)) {
|
|
19614
|
+
return validate({ ...elementOptions, valueSpec: { ...elementOptions.valueSpec, type: "*", expression: void 0 } });
|
|
19615
|
+
}
|
|
19616
|
+
if (declaredType && Array.isArray(defaultValue)) {
|
|
19617
|
+
return validate({ ...elementOptions, valueSpec: { ...elementOptions.valueSpec, type: declaredType } });
|
|
19618
|
+
}
|
|
19619
|
+
return validate(elementOptions);
|
|
19620
|
+
};
|
|
19516
19621
|
return validateObject({
|
|
19517
19622
|
...options,
|
|
19518
19623
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
19519
19624
|
valueSpec: styleSpec.option,
|
|
19520
|
-
objectElementValidators:
|
|
19521
|
-
|
|
19522
|
-
|
|
19523
|
-
// permissive validation, mirroring the runtime parser's narrowing
|
|
19524
|
-
// in style.ts/parser.cpp.
|
|
19525
|
-
default: (elementOptions) => Array.isArray(elementOptions.value) ? validate({ ...elementOptions, valueSpec: { ...elementOptions.valueSpec, type: declaredType } }) : validate(elementOptions)
|
|
19526
|
-
} : void 0
|
|
19625
|
+
objectElementValidators: {
|
|
19626
|
+
default: validateDefault
|
|
19627
|
+
}
|
|
19527
19628
|
});
|
|
19528
19629
|
}
|
|
19529
19630
|
|