@mapbox/mapbox-gl-style-spec 13.28.0 → 14.0.0-beta.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/bin/gl-style-composite.js +2 -2
- package/bin/gl-style-format.js +2 -2
- package/bin/gl-style-migrate.js +2 -2
- package/bin/gl-style-validate.js +2 -2
- package/data/extent.js +18 -0
- package/deref.js +1 -1
- package/diff.js +36 -15
- package/dist/index.cjs +5810 -1995
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +5808 -1991
- package/dist/index.es.js.map +1 -1
- package/expression/compound_expression.js +2 -1
- package/expression/definitions/assertion.js +2 -2
- package/expression/definitions/coercion.js +54 -15
- package/expression/definitions/comparison.js +2 -0
- package/expression/definitions/distance.js +597 -0
- package/expression/definitions/format.js +2 -2
- package/expression/definitions/image.js +34 -14
- package/expression/definitions/index.js +122 -8
- package/expression/definitions/interpolate.js +1 -1
- package/expression/definitions/match.js +2 -2
- package/expression/definitions/within.js +21 -92
- package/expression/evaluation_context.js +12 -1
- package/expression/index.js +74 -43
- package/expression/is_constant.js +19 -1
- package/expression/parsing_context.js +20 -16
- package/expression/types/formatted.js +2 -2
- package/expression/types/resolved_image.js +19 -8
- package/expression/types.js +2 -1
- package/expression/values.js +25 -0
- package/feature_filter/convert.js +1 -1
- package/feature_filter/index.js +4 -4
- package/flow-typed/cheap-ruler.js +25 -0
- package/flow-typed/geojson.js +8 -7
- package/flow-typed/gl-matrix.js +4 -2
- package/flow-typed/kdbush.js +9 -0
- package/function/convert.js +23 -12
- package/group_by_layout.js +2 -2
- package/migrate/expressions.js +3 -0
- package/package.json +5 -2
- package/reference/v8.json +1772 -112
- package/style-spec.js +4 -3
- package/types.js +190 -24
- package/util/color.js +31 -0
- package/util/geometry_util.js +145 -0
- package/util/properties.js +10 -2
- package/util/random.js +12 -0
- package/validate/validate.js +17 -7
- package/validate/validate_array.js +1 -1
- package/validate/validate_filter.js +4 -12
- package/validate/validate_function.js +2 -2
- package/validate/validate_import.js +31 -0
- package/validate/validate_layer.js +3 -2
- package/validate/validate_lights.js +84 -0
- package/validate/validate_model.js +38 -0
- package/validate/validate_property.js +17 -3
- package/validate/validate_source.js +3 -2
- package/validate/validate_style.js +29 -0
- package/validate_mapbox_api_supported.js +55 -11
- package/validate_style.js +4 -0
- package/validate_style.min.js +11 -19
- package/visit.js +3 -2
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
toString as typeToString
|
|
15
15
|
} from '../types.js';
|
|
16
16
|
|
|
17
|
-
import {typeOf, Color, validateRGBA, toString as valueToString} from '../values.js';
|
|
17
|
+
import {typeOf, Color, validateRGBA, validateHSLA, toString as valueToString} from '../values.js';
|
|
18
18
|
import CompoundExpression from '../compound_expression.js';
|
|
19
19
|
import RuntimeError from '../runtime_error.js';
|
|
20
20
|
import Let from './let.js';
|
|
@@ -45,9 +45,12 @@ import FormatExpression from './format.js';
|
|
|
45
45
|
import ImageExpression from './image.js';
|
|
46
46
|
import Length from './length.js';
|
|
47
47
|
import Within from './within.js';
|
|
48
|
+
import Distance from './distance.js';
|
|
48
49
|
|
|
50
|
+
import type EvaluationContext from '../evaluation_context.js';
|
|
49
51
|
import type {Varargs} from '../compound_expression.js';
|
|
50
|
-
import type {ExpressionRegistry} from '../expression.js';
|
|
52
|
+
import type {Expression, ExpressionRegistry} from '../expression.js';
|
|
53
|
+
import {mulberry32} from '../../util/random.js';
|
|
51
54
|
|
|
52
55
|
const expressions: ExpressionRegistry = {
|
|
53
56
|
// special forms
|
|
@@ -57,38 +60,60 @@ const expressions: ExpressionRegistry = {
|
|
|
57
60
|
'<': LessThan,
|
|
58
61
|
'>=': GreaterThanOrEqual,
|
|
59
62
|
'<=': LessThanOrEqual,
|
|
63
|
+
// $FlowFixMe[method-unbinding]
|
|
60
64
|
'array': Assertion,
|
|
65
|
+
// $FlowFixMe[method-unbinding]
|
|
61
66
|
'at': At,
|
|
62
67
|
'boolean': Assertion,
|
|
68
|
+
// $FlowFixMe[method-unbinding]
|
|
63
69
|
'case': Case,
|
|
70
|
+
// $FlowFixMe[method-unbinding]
|
|
64
71
|
'coalesce': Coalesce,
|
|
72
|
+
// $FlowFixMe[method-unbinding]
|
|
65
73
|
'collator': CollatorExpression,
|
|
74
|
+
// $FlowFixMe[method-unbinding]
|
|
66
75
|
'format': FormatExpression,
|
|
76
|
+
// $FlowFixMe[method-unbinding]
|
|
67
77
|
'image': ImageExpression,
|
|
78
|
+
// $FlowFixMe[method-unbinding]
|
|
68
79
|
'in': In,
|
|
80
|
+
// $FlowFixMe[method-unbinding]
|
|
69
81
|
'index-of': IndexOf,
|
|
82
|
+
// $FlowFixMe[method-unbinding]
|
|
70
83
|
'interpolate': Interpolate,
|
|
71
84
|
'interpolate-hcl': Interpolate,
|
|
72
85
|
'interpolate-lab': Interpolate,
|
|
86
|
+
// $FlowFixMe[method-unbinding]
|
|
73
87
|
'length': Length,
|
|
88
|
+
// $FlowFixMe[method-unbinding]
|
|
74
89
|
'let': Let,
|
|
90
|
+
// $FlowFixMe[method-unbinding]
|
|
75
91
|
'literal': Literal,
|
|
92
|
+
// $FlowFixMe[method-unbinding]
|
|
76
93
|
'match': Match,
|
|
77
94
|
'number': Assertion,
|
|
95
|
+
// $FlowFixMe[method-unbinding]
|
|
78
96
|
'number-format': NumberFormat,
|
|
79
97
|
'object': Assertion,
|
|
98
|
+
// $FlowFixMe[method-unbinding]
|
|
80
99
|
'slice': Slice,
|
|
100
|
+
// $FlowFixMe[method-unbinding]
|
|
81
101
|
'step': Step,
|
|
82
102
|
'string': Assertion,
|
|
103
|
+
// $FlowFixMe[method-unbinding]
|
|
83
104
|
'to-boolean': Coercion,
|
|
84
105
|
'to-color': Coercion,
|
|
85
106
|
'to-number': Coercion,
|
|
86
107
|
'to-string': Coercion,
|
|
108
|
+
// $FlowFixMe[method-unbinding]
|
|
87
109
|
'var': Var,
|
|
88
|
-
|
|
110
|
+
// $FlowFixMe[method-unbinding]
|
|
111
|
+
'within': Within,
|
|
112
|
+
// $FlowFixMe[method-unbinding]
|
|
113
|
+
'distance': Distance
|
|
89
114
|
};
|
|
90
115
|
|
|
91
|
-
function rgba(ctx, [r, g, b, a]) {
|
|
116
|
+
function rgba(ctx: EvaluationContext, [r, g, b, a]: Array<Expression>) {
|
|
92
117
|
r = r.evaluate(ctx);
|
|
93
118
|
g = g.evaluate(ctx);
|
|
94
119
|
b = b.evaluate(ctx);
|
|
@@ -98,16 +123,37 @@ function rgba(ctx, [r, g, b, a]) {
|
|
|
98
123
|
return new Color(r / 255 * alpha, g / 255 * alpha, b / 255 * alpha, alpha);
|
|
99
124
|
}
|
|
100
125
|
|
|
101
|
-
function
|
|
126
|
+
function hsla(ctx: EvaluationContext, [h, s, l, a]: Array<Expression>) {
|
|
127
|
+
h = h.evaluate(ctx);
|
|
128
|
+
s = s.evaluate(ctx);
|
|
129
|
+
l = l.evaluate(ctx);
|
|
130
|
+
const alpha = a ? a.evaluate(ctx) : 1;
|
|
131
|
+
const error = validateHSLA(h, s, l, alpha);
|
|
132
|
+
if (error) throw new RuntimeError(error);
|
|
133
|
+
const colorFunction = `hsla(${h}, ${s}%, ${l}%, ${alpha})`;
|
|
134
|
+
const color = Color.parse(colorFunction);
|
|
135
|
+
if (!color) throw new RuntimeError(`Failed to parse HSLA color: ${colorFunction}`);
|
|
136
|
+
return color;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function has(key: string, obj: {[string]: any}): boolean {
|
|
102
140
|
return key in obj;
|
|
103
141
|
}
|
|
104
142
|
|
|
105
|
-
function get(key, obj) {
|
|
143
|
+
function get(key: string, obj: {[string]: any}) {
|
|
106
144
|
const v = obj[key];
|
|
107
145
|
return typeof v === 'undefined' ? null : v;
|
|
108
146
|
}
|
|
109
147
|
|
|
110
|
-
function
|
|
148
|
+
function getConfig(ctx: EvaluationContext, key: string, scope: string) {
|
|
149
|
+
if (scope.length) {
|
|
150
|
+
key += `\u{1f}${scope}`;
|
|
151
|
+
}
|
|
152
|
+
const v = ctx.getConfig(key);
|
|
153
|
+
return v ? v.evaluate(ctx) : null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function binarySearch(v: any, a: {[number]: any}, i: number, j: number) {
|
|
111
157
|
while (i <= j) {
|
|
112
158
|
const m = (i + j) >> 1;
|
|
113
159
|
if (a[m] === v)
|
|
@@ -124,6 +170,19 @@ function varargs(type: Type): Varargs {
|
|
|
124
170
|
return {type};
|
|
125
171
|
}
|
|
126
172
|
|
|
173
|
+
function hashString(str: string) {
|
|
174
|
+
let hash = 0;
|
|
175
|
+
if (str.length === 0) {
|
|
176
|
+
return hash;
|
|
177
|
+
}
|
|
178
|
+
for (let i = 0; i < str.length; i++) {
|
|
179
|
+
const char = str.charCodeAt(i);
|
|
180
|
+
hash = ((hash << 5) - hash) + char;
|
|
181
|
+
hash = hash & hash;
|
|
182
|
+
}
|
|
183
|
+
return hash;
|
|
184
|
+
}
|
|
185
|
+
|
|
127
186
|
CompoundExpression.register(expressions, {
|
|
128
187
|
'error': [
|
|
129
188
|
ErrorType,
|
|
@@ -152,6 +211,16 @@ CompoundExpression.register(expressions, {
|
|
|
152
211
|
[NumberType, NumberType, NumberType, NumberType],
|
|
153
212
|
rgba
|
|
154
213
|
],
|
|
214
|
+
'hsl': [
|
|
215
|
+
ColorType,
|
|
216
|
+
[NumberType, NumberType, NumberType],
|
|
217
|
+
hsla
|
|
218
|
+
],
|
|
219
|
+
'hsla': [
|
|
220
|
+
ColorType,
|
|
221
|
+
[NumberType, NumberType, NumberType, NumberType],
|
|
222
|
+
hsla
|
|
223
|
+
],
|
|
155
224
|
'has': {
|
|
156
225
|
type: BooleanType,
|
|
157
226
|
overloads: [
|
|
@@ -176,6 +245,18 @@ CompoundExpression.register(expressions, {
|
|
|
176
245
|
]
|
|
177
246
|
]
|
|
178
247
|
},
|
|
248
|
+
'config': {
|
|
249
|
+
type: ValueType,
|
|
250
|
+
overloads: [
|
|
251
|
+
[
|
|
252
|
+
[StringType],
|
|
253
|
+
(ctx, [key]) => getConfig(ctx, key.evaluate(ctx), '')
|
|
254
|
+
], [
|
|
255
|
+
[StringType, StringType],
|
|
256
|
+
(ctx, [key, scope]) => getConfig(ctx, key.evaluate(ctx), scope.evaluate(ctx))
|
|
257
|
+
]
|
|
258
|
+
]
|
|
259
|
+
},
|
|
179
260
|
'feature-state': [
|
|
180
261
|
ValueType,
|
|
181
262
|
[StringType],
|
|
@@ -211,6 +292,11 @@ CompoundExpression.register(expressions, {
|
|
|
211
292
|
[],
|
|
212
293
|
(ctx) => ctx.distanceFromCenter()
|
|
213
294
|
],
|
|
295
|
+
'measure-light': [
|
|
296
|
+
NumberType,
|
|
297
|
+
[StringType],
|
|
298
|
+
(ctx, [s]) => ctx.measureLight(s.evaluate(ctx))
|
|
299
|
+
],
|
|
214
300
|
'heatmap-density': [
|
|
215
301
|
NumberType,
|
|
216
302
|
[],
|
|
@@ -221,6 +307,11 @@ CompoundExpression.register(expressions, {
|
|
|
221
307
|
[],
|
|
222
308
|
(ctx) => ctx.globals.lineProgress || 0
|
|
223
309
|
],
|
|
310
|
+
'raster-value': [
|
|
311
|
+
NumberType,
|
|
312
|
+
[],
|
|
313
|
+
(ctx) => ctx.globals.rasterValue || 0
|
|
314
|
+
],
|
|
224
315
|
'sky-radial-progress': [
|
|
225
316
|
NumberType,
|
|
226
317
|
[],
|
|
@@ -574,7 +665,30 @@ CompoundExpression.register(expressions, {
|
|
|
574
665
|
StringType,
|
|
575
666
|
[CollatorType],
|
|
576
667
|
(ctx, [collator]) => collator.evaluate(ctx).resolvedLocale()
|
|
577
|
-
]
|
|
668
|
+
],
|
|
669
|
+
'random': [
|
|
670
|
+
NumberType,
|
|
671
|
+
[NumberType, NumberType, ValueType],
|
|
672
|
+
(ctx, args) => {
|
|
673
|
+
const [min, max, seed] = args.map(arg => arg.evaluate(ctx));
|
|
674
|
+
if (min > max) {
|
|
675
|
+
return min;
|
|
676
|
+
}
|
|
677
|
+
if (min === max) {
|
|
678
|
+
return min;
|
|
679
|
+
}
|
|
680
|
+
let seedVal;
|
|
681
|
+
if (typeof seed === 'string') {
|
|
682
|
+
seedVal = hashString(seed);
|
|
683
|
+
} else if (typeof seed === 'number') {
|
|
684
|
+
seedVal = seed;
|
|
685
|
+
} else {
|
|
686
|
+
throw new RuntimeError(`Invalid seed input: ${seed}`);
|
|
687
|
+
}
|
|
688
|
+
const random = mulberry32(seedVal)();
|
|
689
|
+
return min + random * (max - min);
|
|
690
|
+
}
|
|
691
|
+
],
|
|
578
692
|
});
|
|
579
693
|
|
|
580
694
|
export default expressions;
|
|
@@ -252,7 +252,7 @@ class Interpolate implements Expression {
|
|
|
252
252
|
*
|
|
253
253
|
* @private
|
|
254
254
|
*/
|
|
255
|
-
function exponentialInterpolation(input, base, lowerValue, upperValue) {
|
|
255
|
+
function exponentialInterpolation(input: number, base: number, lowerValue: number, upperValue: number) {
|
|
256
256
|
const difference = upperValue - lowerValue;
|
|
257
257
|
const progress = input - lowerValue;
|
|
258
258
|
|
|
@@ -37,7 +37,7 @@ class Match implements Expression {
|
|
|
37
37
|
return context.error(`Expected an even number of arguments.`);
|
|
38
38
|
|
|
39
39
|
let inputType;
|
|
40
|
-
let outputType;
|
|
40
|
+
let outputType: ?Type;
|
|
41
41
|
if (context.expectedType && context.expectedType.kind !== 'value') {
|
|
42
42
|
outputType = context.expectedType;
|
|
43
43
|
}
|
|
@@ -138,7 +138,7 @@ class Match implements Expression {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
const coerceLabel = (label) => this.inputType.kind === 'number' ? Number(label) : label;
|
|
141
|
+
const coerceLabel = (label: number | string) => this.inputType.kind === 'number' ? Number(label) : label;
|
|
142
142
|
|
|
143
143
|
for (const [outputIndex, labels] of groupedByOutput) {
|
|
144
144
|
if (labels.length === 1) {
|
|
@@ -6,22 +6,16 @@ import {BooleanType} from '../types.js';
|
|
|
6
6
|
import type {Expression, SerializedExpression} from '../expression.js';
|
|
7
7
|
import type ParsingContext from '../parsing_context.js';
|
|
8
8
|
import type EvaluationContext from '../evaluation_context.js';
|
|
9
|
-
import type
|
|
9
|
+
import type Point from '@mapbox/point-geometry';
|
|
10
|
+
import type {GeoJSON, GeoJSONPosition, GeoJSONPolygon, GeoJSONMultiPolygon} from '@mapbox/geojson-types';
|
|
10
11
|
import type {CanonicalTileID} from '../../../source/tile_id.js';
|
|
12
|
+
import {updateBBox, boxWithinBox, pointWithinPolygon, segmentIntersectSegment} from '../../util/geometry_util.js';
|
|
13
|
+
import type {BBox} from '../../util/geometry_util.js';
|
|
11
14
|
|
|
12
15
|
type GeoJSONPolygons =| GeoJSONPolygon | GeoJSONMultiPolygon;
|
|
13
16
|
|
|
14
|
-
// minX, minY, maxX, maxY
|
|
15
|
-
type BBox = [number, number, number, number];
|
|
16
17
|
const EXTENT = 8192;
|
|
17
18
|
|
|
18
|
-
function updateBBox(bbox: BBox, coord: [number, number]) {
|
|
19
|
-
bbox[0] = Math.min(bbox[0], coord[0]);
|
|
20
|
-
bbox[1] = Math.min(bbox[1], coord[1]);
|
|
21
|
-
bbox[2] = Math.max(bbox[2], coord[0]);
|
|
22
|
-
bbox[3] = Math.max(bbox[3], coord[1]);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
19
|
function mercatorXfromLng(lng: number) {
|
|
26
20
|
return (180 + lng) / 360;
|
|
27
21
|
}
|
|
@@ -30,92 +24,27 @@ function mercatorYfromLat(lat: number) {
|
|
|
30
24
|
return (180 - (180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)))) / 360;
|
|
31
25
|
}
|
|
32
26
|
|
|
33
|
-
function
|
|
34
|
-
if (bbox1[0] <= bbox2[0]) return false;
|
|
35
|
-
if (bbox1[2] >= bbox2[2]) return false;
|
|
36
|
-
if (bbox1[1] <= bbox2[1]) return false;
|
|
37
|
-
if (bbox1[3] >= bbox2[3]) return false;
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function getTileCoordinates(p, canonical: CanonicalTileID) {
|
|
27
|
+
function getTileCoordinates(p: GeoJSONPosition, canonical: CanonicalTileID) {
|
|
42
28
|
const x = mercatorXfromLng(p[0]);
|
|
43
29
|
const y = mercatorYfromLat(p[1]);
|
|
44
30
|
const tilesAtZoom = Math.pow(2, canonical.z);
|
|
45
31
|
return [Math.round(x * tilesAtZoom * EXTENT), Math.round(y * tilesAtZoom * EXTENT)];
|
|
46
32
|
}
|
|
47
33
|
|
|
48
|
-
function
|
|
49
|
-
const x1 = p[0] - p1[0];
|
|
50
|
-
const y1 = p[1] - p1[1];
|
|
51
|
-
const x2 = p[0] - p2[0];
|
|
52
|
-
const y2 = p[1] - p2[1];
|
|
53
|
-
return (x1 * y2 - x2 * y1 === 0) && (x1 * x2 <= 0) && (y1 * y2 <= 0);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function rayIntersect(p, p1, p2) {
|
|
57
|
-
return ((p1[1] > p[1]) !== (p2[1] > p[1])) && (p[0] < (p2[0] - p1[0]) * (p[1] - p1[1]) / (p2[1] - p1[1]) + p1[0]);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// ray casting algorithm for detecting if point is in polygon
|
|
61
|
-
function pointWithinPolygon(point, rings) {
|
|
62
|
-
let inside = false;
|
|
63
|
-
for (let i = 0, len = rings.length; i < len; i++) {
|
|
64
|
-
const ring = rings[i];
|
|
65
|
-
for (let j = 0, len2 = ring.length; j < len2 - 1; j++) {
|
|
66
|
-
if (onBoundary(point, ring[j], ring[j + 1])) return false;
|
|
67
|
-
if (rayIntersect(point, ring[j], ring[j + 1])) inside = !inside;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return inside;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function pointWithinPolygons(point, polygons) {
|
|
34
|
+
function pointWithinPolygons(point: GeoJSONPosition, polygons: Array<Array<Array<GeoJSONPosition>>>) {
|
|
74
35
|
for (let i = 0; i < polygons.length; i++) {
|
|
75
36
|
if (pointWithinPolygon(point, polygons[i])) return true;
|
|
76
37
|
}
|
|
77
38
|
return false;
|
|
78
39
|
}
|
|
79
40
|
|
|
80
|
-
function
|
|
81
|
-
return (v1[0] * v2[1] - v1[1] * v2[0]);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// check if p1 and p2 are in different sides of line segment q1->q2
|
|
85
|
-
function twoSided(p1, p2, q1, q2) {
|
|
86
|
-
// q1->p1 (x1, y1), q1->p2 (x2, y2), q1->q2 (x3, y3)
|
|
87
|
-
const x1 = p1[0] - q1[0];
|
|
88
|
-
const y1 = p1[1] - q1[1];
|
|
89
|
-
const x2 = p2[0] - q1[0];
|
|
90
|
-
const y2 = p2[1] - q1[1];
|
|
91
|
-
const x3 = q2[0] - q1[0];
|
|
92
|
-
const y3 = q2[1] - q1[1];
|
|
93
|
-
const det1 = (x1 * y3 - x3 * y1);
|
|
94
|
-
const det2 = (x2 * y3 - x3 * y2);
|
|
95
|
-
if ((det1 > 0 && det2 < 0) || (det1 < 0 && det2 > 0)) return true;
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
// a, b are end points for line segment1, c and d are end points for line segment2
|
|
99
|
-
function lineIntersectLine(a, b, c, d) {
|
|
100
|
-
// check if two segments are parallel or not
|
|
101
|
-
// precondition is end point a, b is inside polygon, if line a->b is
|
|
102
|
-
// parallel to polygon edge c->d, then a->b won't intersect with c->d
|
|
103
|
-
const vectorP = [b[0] - a[0], b[1] - a[1]];
|
|
104
|
-
const vectorQ = [d[0] - c[0], d[1] - c[1]];
|
|
105
|
-
if (perp(vectorQ, vectorP) === 0) return false;
|
|
106
|
-
|
|
107
|
-
// If lines are intersecting with each other, the relative location should be:
|
|
108
|
-
// a and b lie in different sides of segment c->d
|
|
109
|
-
// c and d lie in different sides of segment a->b
|
|
110
|
-
if (twoSided(a, b, c, d) && twoSided(c, d, a, b)) return true;
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function lineIntersectPolygon(p1, p2, polygon) {
|
|
41
|
+
function lineIntersectPolygon(p1: GeoJSONPosition, p2: GeoJSONPosition, polygon: Array<Array<GeoJSONPosition>>) {
|
|
115
42
|
for (const ring of polygon) {
|
|
116
43
|
// loop through every edge of the ring
|
|
117
|
-
for (let j = 0
|
|
118
|
-
|
|
44
|
+
for (let j = 0, len = ring.length, k = len - 1; j < len; k = j++) {
|
|
45
|
+
const q1 = ring[k];
|
|
46
|
+
const q2 = ring[j];
|
|
47
|
+
if (segmentIntersectSegment(p1, p2, q1, q2)) {
|
|
119
48
|
return true;
|
|
120
49
|
}
|
|
121
50
|
}
|
|
@@ -123,7 +52,7 @@ function lineIntersectPolygon(p1, p2, polygon) {
|
|
|
123
52
|
return false;
|
|
124
53
|
}
|
|
125
54
|
|
|
126
|
-
function lineStringWithinPolygon(line
|
|
55
|
+
function lineStringWithinPolygon(line: Array<GeoJSONPosition>, polygon: Array<Array<GeoJSONPosition>>) {
|
|
127
56
|
// First, check if geometry points of line segments are all inside polygon
|
|
128
57
|
for (let i = 0; i < line.length; ++i) {
|
|
129
58
|
if (!pointWithinPolygon(line[i], polygon)) {
|
|
@@ -140,14 +69,14 @@ function lineStringWithinPolygon(line, polygon) {
|
|
|
140
69
|
return true;
|
|
141
70
|
}
|
|
142
71
|
|
|
143
|
-
function lineStringWithinPolygons(line
|
|
72
|
+
function lineStringWithinPolygons(line: Array<GeoJSONPosition>, polygons: Array<Array<Array<GeoJSONPosition>>>) {
|
|
144
73
|
for (let i = 0; i < polygons.length; i++) {
|
|
145
74
|
if (lineStringWithinPolygon(line, polygons[i])) return true;
|
|
146
75
|
}
|
|
147
76
|
return false;
|
|
148
77
|
}
|
|
149
78
|
|
|
150
|
-
function getTilePolygon(coordinates
|
|
79
|
+
function getTilePolygon(coordinates: Array<Array<GeoJSONPosition>>, bbox: BBox, canonical: CanonicalTileID) {
|
|
151
80
|
const polygon = [];
|
|
152
81
|
for (let i = 0; i < coordinates.length; i++) {
|
|
153
82
|
const ring = [];
|
|
@@ -161,7 +90,7 @@ function getTilePolygon(coordinates, bbox: BBox, canonical: CanonicalTileID) {
|
|
|
161
90
|
return polygon;
|
|
162
91
|
}
|
|
163
92
|
|
|
164
|
-
function getTilePolygons(coordinates
|
|
93
|
+
function getTilePolygons(coordinates: Array<Array<Array<GeoJSONPosition>>>, bbox: BBox, canonical: CanonicalTileID) {
|
|
165
94
|
const polygons = [];
|
|
166
95
|
for (let i = 0; i < coordinates.length; i++) {
|
|
167
96
|
const polygon = getTilePolygon(coordinates[i], bbox, canonical);
|
|
@@ -170,7 +99,7 @@ function getTilePolygons(coordinates, bbox, canonical: CanonicalTileID) {
|
|
|
170
99
|
return polygons;
|
|
171
100
|
}
|
|
172
101
|
|
|
173
|
-
function updatePoint(p, bbox, polyBBox
|
|
102
|
+
function updatePoint(p: GeoJSONPosition, bbox: BBox, polyBBox: Array<number>, worldSize: number) {
|
|
174
103
|
if (p[0] < polyBBox[0] || p[0] > polyBBox[2]) {
|
|
175
104
|
const halfWorldSize = worldSize * 0.5;
|
|
176
105
|
let shift = (p[0] - polyBBox[0] > halfWorldSize) ? -worldSize : (polyBBox[0] - p[0] > halfWorldSize) ? worldSize : 0;
|
|
@@ -182,12 +111,12 @@ function updatePoint(p, bbox, polyBBox, worldSize) {
|
|
|
182
111
|
updateBBox(bbox, p);
|
|
183
112
|
}
|
|
184
113
|
|
|
185
|
-
function resetBBox(bbox) {
|
|
114
|
+
function resetBBox(bbox: BBox) {
|
|
186
115
|
bbox[0] = bbox[1] = Infinity;
|
|
187
116
|
bbox[2] = bbox[3] = -Infinity;
|
|
188
117
|
}
|
|
189
118
|
|
|
190
|
-
function getTilePoints(geometry
|
|
119
|
+
function getTilePoints(geometry: ?Array<Array<Point>>, pointBBox: BBox, polyBBox: Array<number>, canonical: CanonicalTileID) {
|
|
191
120
|
const worldSize = Math.pow(2, canonical.z) * EXTENT;
|
|
192
121
|
const shifts = [canonical.x * EXTENT, canonical.y * EXTENT];
|
|
193
122
|
const tilePoints = [];
|
|
@@ -202,15 +131,15 @@ function getTilePoints(geometry, pointBBox, polyBBox, canonical: CanonicalTileID
|
|
|
202
131
|
return tilePoints;
|
|
203
132
|
}
|
|
204
133
|
|
|
205
|
-
function getTileLines(geometry
|
|
134
|
+
function getTileLines(geometry: ?Array<Array<Point>>, lineBBox: BBox, polyBBox: Array<number>, canonical: CanonicalTileID) {
|
|
206
135
|
const worldSize = Math.pow(2, canonical.z) * EXTENT;
|
|
207
136
|
const shifts = [canonical.x * EXTENT, canonical.y * EXTENT];
|
|
208
|
-
const tileLines = [];
|
|
137
|
+
const tileLines: Array<Array<GeoJSONPosition>> = [];
|
|
209
138
|
if (!geometry) return tileLines;
|
|
210
139
|
for (const line of geometry) {
|
|
211
140
|
const tileLine = [];
|
|
212
141
|
for (const point of line) {
|
|
213
|
-
const p = [point.x + shifts[0], point.y + shifts[1]];
|
|
142
|
+
const p: GeoJSONPosition = [point.x + shifts[0], point.y + shifts[1]];
|
|
214
143
|
updateBBox(lineBBox, p);
|
|
215
144
|
tileLine.push(p);
|
|
216
145
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
3
|
import {Color} from './values.js';
|
|
4
|
+
import type {Expression} from './expression.js';
|
|
4
5
|
|
|
5
6
|
import type Point from '@mapbox/point-geometry';
|
|
6
7
|
import type {FormattedSection} from './types/formatted.js';
|
|
@@ -19,10 +20,11 @@ class EvaluationContext {
|
|
|
19
20
|
canonical: null | CanonicalTileID;
|
|
20
21
|
featureTileCoord: ?Point;
|
|
21
22
|
featureDistanceData: ?FeatureDistanceData;
|
|
23
|
+
options: ?Map<string, Expression>;
|
|
22
24
|
|
|
23
25
|
_parseColorCache: {[_: string]: ?Color};
|
|
24
26
|
|
|
25
|
-
constructor() {
|
|
27
|
+
constructor(options?: ?Map<string, Expression>) {
|
|
26
28
|
this.globals = (null: any);
|
|
27
29
|
this.feature = null;
|
|
28
30
|
this.featureState = null;
|
|
@@ -32,6 +34,7 @@ class EvaluationContext {
|
|
|
32
34
|
this.canonical = null;
|
|
33
35
|
this.featureTileCoord = null;
|
|
34
36
|
this.featureDistanceData = null;
|
|
37
|
+
this.options = options;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
id(): number | null {
|
|
@@ -54,6 +57,10 @@ class EvaluationContext {
|
|
|
54
57
|
return (this.feature && this.feature.properties) || {};
|
|
55
58
|
}
|
|
56
59
|
|
|
60
|
+
measureLight(_: string): number {
|
|
61
|
+
return this.globals.brightness || 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
57
64
|
distanceFromCenter(): number {
|
|
58
65
|
if (this.featureTileCoord && this.featureDistanceData) {
|
|
59
66
|
|
|
@@ -84,6 +91,10 @@ class EvaluationContext {
|
|
|
84
91
|
}
|
|
85
92
|
return cached;
|
|
86
93
|
}
|
|
94
|
+
|
|
95
|
+
getConfig(id: string): ?Expression {
|
|
96
|
+
return this.options ? this.options.get(id) : null;
|
|
97
|
+
}
|
|
87
98
|
}
|
|
88
99
|
|
|
89
100
|
export default EvaluationContext;
|