ol 7.5.1 → 8.0.0-dev.1692053484481
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/DataTile.d.ts +2 -2
- package/DataTile.d.ts.map +1 -1
- package/DataTile.js +3 -2
- package/Image.d.ts +139 -40
- package/Image.d.ts.map +1 -1
- package/Image.js +194 -96
- package/ImageCanvas.d.ts +2 -2
- package/ImageCanvas.d.ts.map +1 -1
- package/ImageCanvas.js +2 -2
- package/Object.d.ts +7 -0
- package/Object.d.ts.map +1 -1
- package/Object.js +8 -0
- package/dist/ol.js +2 -2
- package/dist/ol.js.map +1 -1
- package/expr/cpu.d.ts +71 -0
- package/expr/cpu.d.ts.map +1 -0
- package/expr/cpu.js +312 -0
- package/expr/expression.d.ts +97 -0
- package/expr/expression.d.ts.map +1 -0
- package/expr/expression.js +373 -0
- package/has.d.ts +5 -0
- package/has.d.ts.map +1 -1
- package/has.js +6 -0
- package/index.d.ts +1 -2
- package/index.js +1 -1
- package/layer/Base.d.ts +12 -8
- package/layer/Base.d.ts.map +1 -1
- package/layer/Base.js +12 -8
- package/layer/BaseVector.d.ts.map +1 -1
- package/layer/BaseVector.js +67 -33
- package/layer/Heatmap.d.ts.map +1 -1
- package/layer/Heatmap.js +16 -55
- package/layer/Layer.d.ts +2 -2
- package/layer/Layer.d.ts.map +1 -1
- package/layer/Layer.js +1 -1
- package/layer/WebGLPoints.d.ts +7 -12
- package/layer/WebGLPoints.d.ts.map +1 -1
- package/layer/WebGLPoints.js +7 -12
- package/package.json +1 -1
- package/render/Feature.d.ts +8 -0
- package/render/Feature.d.ts.map +1 -1
- package/render/Feature.js +9 -0
- package/render/canvas/Immediate.d.ts.map +1 -1
- package/render/canvas/Immediate.js +5 -3
- package/render/canvas/TextBuilder.js +2 -2
- package/render/canvas/style.d.ts +69 -0
- package/render/canvas/style.d.ts.map +1 -0
- package/render/canvas/style.js +1192 -0
- package/render/canvas.js +1 -1
- package/render/webgl/VectorStyleRenderer.d.ts.map +1 -1
- package/render/webgl/VectorStyleRenderer.js +4 -0
- package/renderer/Layer.d.ts +2 -2
- package/renderer/Layer.d.ts.map +1 -1
- package/renderer/Layer.js +1 -1
- package/renderer/canvas/ImageLayer.d.ts +4 -4
- package/renderer/canvas/ImageLayer.d.ts.map +1 -1
- package/renderer/canvas/ImageLayer.js +17 -12
- package/renderer/canvas/Layer.d.ts +2 -2
- package/renderer/canvas/Layer.d.ts.map +1 -1
- package/renderer/canvas/Layer.js +1 -1
- package/renderer/canvas/VectorImageLayer.d.ts.map +1 -1
- package/renderer/canvas/VectorImageLayer.js +3 -2
- package/renderer/webgl/VectorLayer.d.ts +1 -2
- package/renderer/webgl/VectorLayer.d.ts.map +1 -1
- package/reproj/Image.d.ts +5 -5
- package/reproj/Image.d.ts.map +1 -1
- package/reproj/Image.js +6 -6
- package/reproj.d.ts +2 -2
- package/reproj.d.ts.map +1 -1
- package/reproj.js +1 -1
- package/resolution.d.ts +13 -0
- package/resolution.d.ts.map +1 -0
- package/resolution.js +18 -0
- package/source/Image.d.ts +44 -7
- package/source/Image.d.ts.map +1 -1
- package/source/Image.js +97 -8
- package/source/ImageArcGISRest.d.ts +0 -23
- package/source/ImageArcGISRest.d.ts.map +1 -1
- package/source/ImageArcGISRest.js +18 -120
- package/source/ImageMapGuide.d.ts +0 -24
- package/source/ImageMapGuide.d.ts.map +1 -1
- package/source/ImageMapGuide.js +21 -113
- package/source/ImageStatic.d.ts +2 -27
- package/source/ImageStatic.d.ts.map +1 -1
- package/source/ImageStatic.js +20 -70
- package/source/ImageWMS.d.ts +2 -46
- package/source/ImageWMS.d.ts.map +1 -1
- package/source/ImageWMS.js +43 -201
- package/source/{Stamen.d.ts → StadiaMaps.d.ts} +17 -7
- package/source/StadiaMaps.d.ts.map +1 -0
- package/source/{Stamen.js → StadiaMaps.js} +85 -38
- package/source/TileArcGISRest.d.ts.map +1 -1
- package/source/TileArcGISRest.js +11 -22
- package/source/TileWMS.d.ts +0 -1
- package/source/TileWMS.d.ts.map +1 -1
- package/source/TileWMS.js +43 -106
- package/source/arcgisRest.d.ts +88 -0
- package/source/arcgisRest.d.ts.map +1 -0
- package/source/arcgisRest.js +131 -0
- package/source/common.d.ts +5 -0
- package/source/common.d.ts.map +1 -1
- package/source/common.js +6 -0
- package/source/mapguide.d.ts +52 -0
- package/source/mapguide.d.ts.map +1 -0
- package/source/mapguide.js +116 -0
- package/source/static.d.ts +45 -0
- package/source/static.d.ts.map +1 -0
- package/source/static.js +44 -0
- package/source/wms.d.ts +109 -1
- package/source/wms.d.ts.map +1 -1
- package/source/wms.js +170 -0
- package/source.d.ts +5 -1
- package/source.d.ts.map +1 -1
- package/source.js +5 -1
- package/style/flat.d.ts +332 -173
- package/style/flat.d.ts.map +1 -1
- package/style/flat.js +176 -248
- package/style/literal.d.ts +27 -72
- package/style/literal.d.ts.map +1 -1
- package/style/literal.js +14 -35
- package/util.d.ts.map +1 -1
- package/util.js +1 -1
- package/webgl/Helper.d.ts +7 -2
- package/webgl/Helper.d.ts.map +1 -1
- package/webgl/Helper.js +16 -27
- package/webgl/ShaderBuilder.d.ts +4 -14
- package/webgl/ShaderBuilder.d.ts.map +1 -1
- package/webgl/ShaderBuilder.js +72 -72
- package/webgl/styleparser.d.ts +3 -9
- package/webgl/styleparser.d.ts.map +1 -1
- package/webgl/styleparser.js +503 -88
- package/ImageBase.d.ts +0 -65
- package/ImageBase.d.ts.map +0 -1
- package/ImageBase.js +0 -98
- package/source/Stamen.d.ts.map +0 -1
|
@@ -0,0 +1,1192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ol/render/canvas/style
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import Circle from '../../style/Circle.js';
|
|
6
|
+
import Fill from '../../style/Fill.js';
|
|
7
|
+
import Icon from '../../style/Icon.js';
|
|
8
|
+
import RegularShape from '../../style/RegularShape.js';
|
|
9
|
+
import Stroke from '../../style/Stroke.js';
|
|
10
|
+
import Style from '../../style/Style.js';
|
|
11
|
+
import Text from '../../style/Text.js';
|
|
12
|
+
import {
|
|
13
|
+
BooleanType,
|
|
14
|
+
ColorType,
|
|
15
|
+
NumberArrayType,
|
|
16
|
+
NumberType,
|
|
17
|
+
StringType,
|
|
18
|
+
newParsingContext,
|
|
19
|
+
} from '../../expr/expression.js';
|
|
20
|
+
import {buildExpression, newEvaluationContext} from '../../expr/cpu.js';
|
|
21
|
+
import {toSize} from '../../size.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @fileoverview This module includes functions to build styles for the canvas renderer. Building
|
|
25
|
+
* is composed of two steps: parsing and compiling. The parsing step takes an encoded expression
|
|
26
|
+
* and returns an instance of one of the expression classes. The compiling step takes the
|
|
27
|
+
* expression instance and returns a function that can be evaluated to return a literal value. The
|
|
28
|
+
* evaluator function should do as little allocation and work as possible.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @typedef {import("../../style/flat.js").FlatStyle} FlatStyle
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @typedef {import("../../expr/expression.js").EncodedExpression} EncodedExpression
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @typedef {import("../../expr/expression.js").ParsingContext} ParsingContext
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {import("../../expr/expression.js").CallExpression} CallExpression
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @typedef {import("../../expr/cpu.js").EvaluationContext} EvaluationContext
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @typedef {import("../../expr/cpu.js").ExpressionEvaluator} ExpressionEvaluator
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {EvaluationContext} context The evaluation context.
|
|
57
|
+
* @return {boolean} Always true.
|
|
58
|
+
*/
|
|
59
|
+
function always(context) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* This function adapts a rule evaluator to the existing style function interface.
|
|
65
|
+
* After we have deprecated the style function, we can use the compiled rules directly
|
|
66
|
+
* and pass a more complete evaluation context (variables, zoom, time, etc.).
|
|
67
|
+
*
|
|
68
|
+
* @param {Array<import('../../style/flat.js').Rule>} rules The rules.
|
|
69
|
+
* @return {import('../../style/Style.js').StyleFunction} A style function.
|
|
70
|
+
*/
|
|
71
|
+
export function rulesToStyleFunction(rules) {
|
|
72
|
+
const parsingContext = newParsingContext();
|
|
73
|
+
const evaluator = buildRuleSet(rules, parsingContext);
|
|
74
|
+
const evaluationContext = newEvaluationContext();
|
|
75
|
+
return function (feature, resolution) {
|
|
76
|
+
evaluationContext.properties = feature.getPropertiesInternal();
|
|
77
|
+
evaluationContext.resolution = resolution;
|
|
78
|
+
return evaluator(evaluationContext);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* This function adapts a style evaluator to the existing style function interface.
|
|
84
|
+
* After we have deprecated the style function, we can use the compiled rules directly
|
|
85
|
+
* and pass a more complete evaluation context (variables, zoom, time, etc.).
|
|
86
|
+
*
|
|
87
|
+
* @param {Array<import('../../style/flat.js').FlatStyle>} flatStyles The flat styles.
|
|
88
|
+
* @return {import('../../style/Style.js').StyleFunction} A style function.
|
|
89
|
+
*/
|
|
90
|
+
export function flatStylesToStyleFunction(flatStyles) {
|
|
91
|
+
const parsingContext = newParsingContext();
|
|
92
|
+
const length = flatStyles.length;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @type {Array<StyleEvaluator>}
|
|
96
|
+
*/
|
|
97
|
+
const evaluators = new Array(length);
|
|
98
|
+
for (let i = 0; i < length; ++i) {
|
|
99
|
+
evaluators[i] = buildStyle(flatStyles[i], parsingContext);
|
|
100
|
+
}
|
|
101
|
+
const evaluationContext = newEvaluationContext();
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @type {Array<Style>}
|
|
105
|
+
*/
|
|
106
|
+
const styles = new Array(length);
|
|
107
|
+
|
|
108
|
+
return function (feature, resolution) {
|
|
109
|
+
evaluationContext.properties = feature.getPropertiesInternal();
|
|
110
|
+
evaluationContext.resolution = resolution;
|
|
111
|
+
for (let i = 0; i < length; ++i) {
|
|
112
|
+
styles[i] = evaluators[i](evaluationContext);
|
|
113
|
+
}
|
|
114
|
+
return styles;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @typedef {function(EvaluationContext):Array<Style>} RuleSetEvaluator
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @typedef {Object} CompiledRule
|
|
124
|
+
* @property {ExpressionEvaluator} filter The compiled filter evaluator.
|
|
125
|
+
* @property {Array<StyleEvaluator>} styles The list of compiled style evaluators.
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @param {Array<import('../../style/flat.js').Rule>} rules The rules.
|
|
130
|
+
* @param {ParsingContext} context The parsing context.
|
|
131
|
+
* @return {RuleSetEvaluator} The evaluator function.
|
|
132
|
+
*/
|
|
133
|
+
export function buildRuleSet(rules, context) {
|
|
134
|
+
const length = rules.length;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @type {Array<CompiledRule>}
|
|
138
|
+
*/
|
|
139
|
+
const compiledRules = new Array(length);
|
|
140
|
+
|
|
141
|
+
for (let i = 0; i < length; ++i) {
|
|
142
|
+
const rule = rules[i];
|
|
143
|
+
const filter =
|
|
144
|
+
'filter' in rule
|
|
145
|
+
? buildExpression(rule.filter, BooleanType, context)
|
|
146
|
+
: always;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @type {Array<StyleEvaluator>}
|
|
150
|
+
*/
|
|
151
|
+
let styles;
|
|
152
|
+
if (Array.isArray(rule.style)) {
|
|
153
|
+
const styleLength = rule.style.length;
|
|
154
|
+
styles = new Array(styleLength);
|
|
155
|
+
for (let j = 0; j < styleLength; ++j) {
|
|
156
|
+
styles[j] = buildStyle(rule.style[j], context);
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
styles = [buildStyle(rule.style, context)];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
compiledRules[i] = {filter, styles};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return function (context) {
|
|
166
|
+
/**
|
|
167
|
+
* @type {Array<Style>}
|
|
168
|
+
*/
|
|
169
|
+
const styles = [];
|
|
170
|
+
|
|
171
|
+
let someMatched = false;
|
|
172
|
+
for (let i = 0; i < length; ++i) {
|
|
173
|
+
const filterEvaluator = compiledRules[i].filter;
|
|
174
|
+
if (!filterEvaluator(context)) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (rules[i].else && someMatched) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
someMatched = true;
|
|
181
|
+
for (const styleEvaluator of compiledRules[i].styles) {
|
|
182
|
+
styles.push(styleEvaluator(context));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return styles;
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @typedef {function(EvaluationContext):Style} StyleEvaluator
|
|
192
|
+
*/
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* @param {FlatStyle} flatStyle A flat style literal.
|
|
196
|
+
* @param {ParsingContext} context The parsing context.
|
|
197
|
+
* @return {StyleEvaluator} A function that evaluates to a style. The style returned by
|
|
198
|
+
* this function will be reused between invocations.
|
|
199
|
+
*/
|
|
200
|
+
export function buildStyle(flatStyle, context) {
|
|
201
|
+
const evaluateFill = buildFill(flatStyle, '', context);
|
|
202
|
+
const evaluateStroke = buildStroke(flatStyle, '', context);
|
|
203
|
+
const evaluateText = buildText(flatStyle, context);
|
|
204
|
+
const evaluateImage = buildImage(flatStyle, context);
|
|
205
|
+
const evaluateZIndex = numberEvaluator(flatStyle, 'z-index', context);
|
|
206
|
+
|
|
207
|
+
const style = new Style();
|
|
208
|
+
return function (context) {
|
|
209
|
+
if (evaluateFill) {
|
|
210
|
+
style.setFill(evaluateFill(context));
|
|
211
|
+
}
|
|
212
|
+
if (evaluateStroke) {
|
|
213
|
+
style.setStroke(evaluateStroke(context));
|
|
214
|
+
}
|
|
215
|
+
if (evaluateText) {
|
|
216
|
+
style.setText(evaluateText(context));
|
|
217
|
+
}
|
|
218
|
+
if (evaluateImage) {
|
|
219
|
+
style.setImage(evaluateImage(context));
|
|
220
|
+
}
|
|
221
|
+
if (evaluateZIndex) {
|
|
222
|
+
style.setZIndex(evaluateZIndex(context));
|
|
223
|
+
}
|
|
224
|
+
return style;
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @typedef {function(EvaluationContext):Fill} FillEvaluator
|
|
230
|
+
*/
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
234
|
+
* @param {string} prefix The property prefix.
|
|
235
|
+
* @param {ParsingContext} context The parsing context.
|
|
236
|
+
* @return {FillEvaluator?} A function that evaluates to a fill.
|
|
237
|
+
*/
|
|
238
|
+
function buildFill(flatStyle, prefix, context) {
|
|
239
|
+
const evaluateColor = colorLikeEvaluator(
|
|
240
|
+
flatStyle,
|
|
241
|
+
prefix + 'fill-color',
|
|
242
|
+
context
|
|
243
|
+
);
|
|
244
|
+
if (!evaluateColor) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const fill = new Fill();
|
|
249
|
+
return function (context) {
|
|
250
|
+
const color = evaluateColor(context);
|
|
251
|
+
if (color === 'none') {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
fill.setColor(color);
|
|
255
|
+
return fill;
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @typedef {function(EvaluationContext):Stroke} StrokeEvaluator
|
|
261
|
+
*/
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
265
|
+
* @param {string} prefix The property prefix.
|
|
266
|
+
* @param {ParsingContext} context The parsing context.
|
|
267
|
+
* @return {StrokeEvaluator?} A function the evaluates to a stroke.
|
|
268
|
+
*/
|
|
269
|
+
function buildStroke(flatStyle, prefix, context) {
|
|
270
|
+
const evaluateWidth = numberEvaluator(
|
|
271
|
+
flatStyle,
|
|
272
|
+
prefix + 'stroke-width',
|
|
273
|
+
context
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
const evaluateColor = colorLikeEvaluator(
|
|
277
|
+
flatStyle,
|
|
278
|
+
prefix + 'stroke-color',
|
|
279
|
+
context
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
if (!evaluateWidth && !evaluateColor) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const evaluateLineCap = stringEvaluator(
|
|
287
|
+
flatStyle,
|
|
288
|
+
prefix + 'stroke-line-cap',
|
|
289
|
+
context
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
const evaluateLineJoin = stringEvaluator(
|
|
293
|
+
flatStyle,
|
|
294
|
+
prefix + 'stroke-line-join',
|
|
295
|
+
context
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
const evaluateLineDash = numberArrayEvaluator(
|
|
299
|
+
flatStyle,
|
|
300
|
+
prefix + 'stroke-line-dash',
|
|
301
|
+
context
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
const evaluateLineDashOffset = numberEvaluator(
|
|
305
|
+
flatStyle,
|
|
306
|
+
prefix + 'stroke-line-dash-offset',
|
|
307
|
+
context
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
const evaluateMiterLimit = numberEvaluator(
|
|
311
|
+
flatStyle,
|
|
312
|
+
prefix + 'stroke-miter-limit',
|
|
313
|
+
context
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
const stroke = new Stroke();
|
|
317
|
+
return function (context) {
|
|
318
|
+
if (evaluateWidth) {
|
|
319
|
+
stroke.setWidth(evaluateWidth(context));
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (evaluateColor) {
|
|
323
|
+
stroke.setColor(evaluateColor(context));
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (evaluateLineCap) {
|
|
327
|
+
const lineCap = evaluateLineCap(context);
|
|
328
|
+
if (lineCap !== 'butt' && lineCap !== 'round' && lineCap !== 'square') {
|
|
329
|
+
throw new Error('Expected butt, round, or square line cap');
|
|
330
|
+
}
|
|
331
|
+
stroke.setLineCap(lineCap);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (evaluateLineJoin) {
|
|
335
|
+
const lineJoin = evaluateLineJoin(context);
|
|
336
|
+
if (
|
|
337
|
+
lineJoin !== 'bevel' &&
|
|
338
|
+
lineJoin !== 'round' &&
|
|
339
|
+
lineJoin !== 'miter'
|
|
340
|
+
) {
|
|
341
|
+
throw new Error('Expected bevel, round, or miter line join');
|
|
342
|
+
}
|
|
343
|
+
stroke.setLineJoin(lineJoin);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (evaluateLineDash) {
|
|
347
|
+
stroke.setLineDash(evaluateLineDash(context));
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (evaluateLineDashOffset) {
|
|
351
|
+
stroke.setLineDashOffset(evaluateLineDashOffset(context));
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (evaluateMiterLimit) {
|
|
355
|
+
stroke.setMiterLimit(evaluateMiterLimit(context));
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return stroke;
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* @typedef {function(EvaluationContext):Text} TextEvaluator
|
|
364
|
+
*/
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
368
|
+
* @param {ParsingContext} context The parsing context.
|
|
369
|
+
* @return {TextEvaluator?} A function that evaluates to a text symbolizer.
|
|
370
|
+
*/
|
|
371
|
+
function buildText(flatStyle, context) {
|
|
372
|
+
const prefix = 'text-';
|
|
373
|
+
|
|
374
|
+
// Currently, an Array<string> may be used for rich text support. This doesn't
|
|
375
|
+
// work with our expression syntax where arrays of strings are interpreted as
|
|
376
|
+
// call expressions. To support rich text, we could add a 'strings' operator
|
|
377
|
+
// where all the following arguments would be string values.
|
|
378
|
+
const evaluateValue = stringEvaluator(flatStyle, prefix + 'value', context);
|
|
379
|
+
if (!evaluateValue) {
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const evaluateFill = buildFill(flatStyle, prefix, context);
|
|
384
|
+
|
|
385
|
+
const evaluateBackgroundFill = buildFill(
|
|
386
|
+
flatStyle,
|
|
387
|
+
prefix + 'background-',
|
|
388
|
+
context
|
|
389
|
+
);
|
|
390
|
+
|
|
391
|
+
const evaluateStroke = buildStroke(flatStyle, prefix, context);
|
|
392
|
+
|
|
393
|
+
const evaluateBackgroundStroke = buildStroke(
|
|
394
|
+
flatStyle,
|
|
395
|
+
prefix + 'background-',
|
|
396
|
+
context
|
|
397
|
+
);
|
|
398
|
+
|
|
399
|
+
const evaluateFont = stringEvaluator(flatStyle, prefix + 'font', context);
|
|
400
|
+
|
|
401
|
+
const evaluateMaxAngle = numberEvaluator(
|
|
402
|
+
flatStyle,
|
|
403
|
+
prefix + 'max-angle',
|
|
404
|
+
context
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
const evaluateOffsetX = numberEvaluator(
|
|
408
|
+
flatStyle,
|
|
409
|
+
prefix + 'offset-x',
|
|
410
|
+
context
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
const evaluateOffsetY = numberEvaluator(
|
|
414
|
+
flatStyle,
|
|
415
|
+
prefix + 'offset-y',
|
|
416
|
+
context
|
|
417
|
+
);
|
|
418
|
+
|
|
419
|
+
const evaluateOverflow = booleanEvaluator(
|
|
420
|
+
flatStyle,
|
|
421
|
+
prefix + 'overflow',
|
|
422
|
+
context
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
const evaluatePlacement = stringEvaluator(
|
|
426
|
+
flatStyle,
|
|
427
|
+
prefix + 'placement',
|
|
428
|
+
context
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
const evaluateRepeat = numberEvaluator(flatStyle, prefix + 'repeat', context);
|
|
432
|
+
|
|
433
|
+
const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + 'scale', context);
|
|
434
|
+
|
|
435
|
+
const evaluateRotateWithView = booleanEvaluator(
|
|
436
|
+
flatStyle,
|
|
437
|
+
prefix + 'rotate-with-view',
|
|
438
|
+
context
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
const evaluateRotation = numberEvaluator(
|
|
442
|
+
flatStyle,
|
|
443
|
+
prefix + 'rotation',
|
|
444
|
+
context
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
const evaluateAlign = stringEvaluator(flatStyle, prefix + 'align', context);
|
|
448
|
+
|
|
449
|
+
const evaluateJustify = stringEvaluator(
|
|
450
|
+
flatStyle,
|
|
451
|
+
prefix + 'justify',
|
|
452
|
+
context
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
const evaluateBaseline = stringEvaluator(
|
|
456
|
+
flatStyle,
|
|
457
|
+
prefix + 'baseline',
|
|
458
|
+
context
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
const evaluatePadding = numberArrayEvaluator(
|
|
462
|
+
flatStyle,
|
|
463
|
+
prefix + 'padding',
|
|
464
|
+
context
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
const text = new Text({});
|
|
468
|
+
return function (context) {
|
|
469
|
+
text.setText(evaluateValue(context));
|
|
470
|
+
|
|
471
|
+
if (evaluateFill) {
|
|
472
|
+
text.setFill(evaluateFill(context));
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
if (evaluateBackgroundFill) {
|
|
476
|
+
text.setBackgroundFill(evaluateBackgroundFill(context));
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (evaluateStroke) {
|
|
480
|
+
text.setStroke(evaluateStroke(context));
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if (evaluateBackgroundStroke) {
|
|
484
|
+
text.setBackgroundStroke(evaluateBackgroundStroke(context));
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (evaluateFont) {
|
|
488
|
+
text.setFont(evaluateFont(context));
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (evaluateMaxAngle) {
|
|
492
|
+
text.setMaxAngle(evaluateMaxAngle(context));
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
if (evaluateOffsetX) {
|
|
496
|
+
text.setOffsetX(evaluateOffsetX(context));
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
if (evaluateOffsetY) {
|
|
500
|
+
text.setOffsetY(evaluateOffsetY(context));
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
if (evaluateOverflow) {
|
|
504
|
+
text.setOverflow(evaluateOverflow(context));
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (evaluatePlacement) {
|
|
508
|
+
const placement = evaluatePlacement(context);
|
|
509
|
+
if (placement !== 'point' && placement !== 'line') {
|
|
510
|
+
throw new Error('Expected point or line for text-placement');
|
|
511
|
+
}
|
|
512
|
+
text.setPlacement(placement);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (evaluateRepeat) {
|
|
516
|
+
text.setRepeat(evaluateRepeat(context));
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
if (evaluateScale) {
|
|
520
|
+
text.setScale(evaluateScale(context));
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
if (evaluateRotateWithView) {
|
|
524
|
+
text.setRotateWithView(evaluateRotateWithView(context));
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
if (evaluateRotation) {
|
|
528
|
+
text.setRotation(evaluateRotation(context));
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
if (evaluateAlign) {
|
|
532
|
+
const textAlign = evaluateAlign(context);
|
|
533
|
+
if (
|
|
534
|
+
textAlign !== 'left' &&
|
|
535
|
+
textAlign !== 'center' &&
|
|
536
|
+
textAlign !== 'right' &&
|
|
537
|
+
textAlign !== 'end' &&
|
|
538
|
+
textAlign !== 'start'
|
|
539
|
+
) {
|
|
540
|
+
throw new Error(
|
|
541
|
+
'Expected left, right, center, start, or end for text-align'
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
text.setTextAlign(textAlign);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
if (evaluateJustify) {
|
|
548
|
+
const justify = evaluateJustify(context);
|
|
549
|
+
if (justify !== 'left' && justify !== 'right' && justify !== 'center') {
|
|
550
|
+
throw new Error('Expected left, right, or center for text-justify');
|
|
551
|
+
}
|
|
552
|
+
text.setJustify(justify);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
if (evaluateBaseline) {
|
|
556
|
+
const textBaseline = evaluateBaseline(context);
|
|
557
|
+
if (
|
|
558
|
+
textBaseline !== 'bottom' &&
|
|
559
|
+
textBaseline !== 'top' &&
|
|
560
|
+
textBaseline !== 'middle' &&
|
|
561
|
+
textBaseline !== 'alphabetic' &&
|
|
562
|
+
textBaseline !== 'hanging'
|
|
563
|
+
) {
|
|
564
|
+
throw new Error(
|
|
565
|
+
'Expected bottom, top, middle, alphabetic, or hanging for text-baseline'
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
text.setTextBaseline(textBaseline);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
if (evaluatePadding) {
|
|
572
|
+
text.setPadding(evaluatePadding(context));
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
return text;
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* @typedef {function(EvaluationContext):import("../../style/Image.js").default} ImageEvaluator
|
|
581
|
+
*/
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
585
|
+
* @param {ParsingContext} context The parsing context.
|
|
586
|
+
* @return {ImageEvaluator?} A function that evaluates to an image symbolizer.
|
|
587
|
+
*/
|
|
588
|
+
function buildImage(flatStyle, context) {
|
|
589
|
+
if ('icon-src' in flatStyle) {
|
|
590
|
+
return buildIcon(flatStyle, context);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
if ('shape-points' in flatStyle) {
|
|
594
|
+
return buildShape(flatStyle, context);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if ('circle-radius' in flatStyle) {
|
|
598
|
+
return buildCircle(flatStyle, context);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
return null;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
606
|
+
* @param {ParsingContext} context The parsing context.
|
|
607
|
+
* @return {ImageEvaluator} A function that evaluates to an image symbolizer.
|
|
608
|
+
*/
|
|
609
|
+
function buildIcon(flatStyle, context) {
|
|
610
|
+
const prefix = 'icon-';
|
|
611
|
+
|
|
612
|
+
// required property
|
|
613
|
+
const srcName = prefix + 'src';
|
|
614
|
+
const src = requireString(flatStyle[srcName], srcName);
|
|
615
|
+
|
|
616
|
+
// settable properties
|
|
617
|
+
const evaluateAnchor = coordinateEvaluator(
|
|
618
|
+
flatStyle,
|
|
619
|
+
prefix + 'anchor',
|
|
620
|
+
context
|
|
621
|
+
);
|
|
622
|
+
|
|
623
|
+
const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + 'scale', context);
|
|
624
|
+
|
|
625
|
+
const evaluateOpacity = numberEvaluator(
|
|
626
|
+
flatStyle,
|
|
627
|
+
prefix + 'opacity',
|
|
628
|
+
context
|
|
629
|
+
);
|
|
630
|
+
|
|
631
|
+
const evaluateDisplacement = coordinateEvaluator(
|
|
632
|
+
flatStyle,
|
|
633
|
+
prefix + 'displacement',
|
|
634
|
+
context
|
|
635
|
+
);
|
|
636
|
+
|
|
637
|
+
const evaluateRotation = numberEvaluator(
|
|
638
|
+
flatStyle,
|
|
639
|
+
prefix + 'rotation',
|
|
640
|
+
context
|
|
641
|
+
);
|
|
642
|
+
|
|
643
|
+
const evaluateRotateWithView = booleanEvaluator(
|
|
644
|
+
flatStyle,
|
|
645
|
+
prefix + 'rotate-with-view',
|
|
646
|
+
context
|
|
647
|
+
);
|
|
648
|
+
|
|
649
|
+
// the remaining symbolizer properties are not currently settable
|
|
650
|
+
const anchorOrigin = optionalIconOrigin(flatStyle, prefix + 'anchor-origin');
|
|
651
|
+
const anchorXUnits = optionalIconAnchorUnits(
|
|
652
|
+
flatStyle,
|
|
653
|
+
prefix + 'anchor-x-units'
|
|
654
|
+
);
|
|
655
|
+
const anchorYUnits = optionalIconAnchorUnits(
|
|
656
|
+
flatStyle,
|
|
657
|
+
prefix + 'anchor-y-units'
|
|
658
|
+
);
|
|
659
|
+
const color = optionalColorLike(flatStyle, prefix + 'color');
|
|
660
|
+
const crossOrigin = optionalString(flatStyle, prefix + 'cross-origin');
|
|
661
|
+
const offset = optionalNumberArray(flatStyle, prefix + 'offset');
|
|
662
|
+
const offsetOrigin = optionalIconOrigin(flatStyle, prefix + 'offset-origin');
|
|
663
|
+
const width = optionalNumber(flatStyle, prefix + 'width');
|
|
664
|
+
const height = optionalNumber(flatStyle, prefix + 'height');
|
|
665
|
+
const size = optionalSize(flatStyle, prefix + 'size');
|
|
666
|
+
const declutterMode = optionalDeclutterMode(flatStyle, prefix + 'declutter');
|
|
667
|
+
|
|
668
|
+
const icon = new Icon({
|
|
669
|
+
src,
|
|
670
|
+
anchorOrigin,
|
|
671
|
+
anchorXUnits,
|
|
672
|
+
anchorYUnits,
|
|
673
|
+
color,
|
|
674
|
+
crossOrigin,
|
|
675
|
+
offset,
|
|
676
|
+
offsetOrigin,
|
|
677
|
+
height,
|
|
678
|
+
width,
|
|
679
|
+
size,
|
|
680
|
+
declutterMode,
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
return function (context) {
|
|
684
|
+
if (evaluateOpacity) {
|
|
685
|
+
icon.setOpacity(evaluateOpacity(context));
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
if (evaluateDisplacement) {
|
|
689
|
+
icon.setDisplacement(evaluateDisplacement(context));
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
if (evaluateRotation) {
|
|
693
|
+
icon.setRotation(evaluateRotation(context));
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
if (evaluateRotateWithView) {
|
|
697
|
+
icon.setRotateWithView(evaluateRotateWithView(context));
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
if (evaluateScale) {
|
|
701
|
+
icon.setScale(evaluateScale(context));
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
if (evaluateAnchor) {
|
|
705
|
+
icon.setAnchor(evaluateAnchor(context));
|
|
706
|
+
}
|
|
707
|
+
return icon;
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
713
|
+
* @param {ParsingContext} context The parsing context.
|
|
714
|
+
* @return {ImageEvaluator} A function that evaluates to an icon symbolizer.
|
|
715
|
+
*/
|
|
716
|
+
function buildShape(flatStyle, context) {
|
|
717
|
+
const prefix = 'shape-';
|
|
718
|
+
|
|
719
|
+
// required property
|
|
720
|
+
const pointsName = prefix + 'points';
|
|
721
|
+
const points = requireNumber(flatStyle[pointsName], pointsName);
|
|
722
|
+
|
|
723
|
+
// settable properties
|
|
724
|
+
const evaluateFill = buildFill(flatStyle, prefix, context);
|
|
725
|
+
const evaluateStroke = buildStroke(flatStyle, prefix, context);
|
|
726
|
+
const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + 'scale', context);
|
|
727
|
+
const evaluateDisplacement = coordinateEvaluator(
|
|
728
|
+
flatStyle,
|
|
729
|
+
prefix + 'displacement',
|
|
730
|
+
context
|
|
731
|
+
);
|
|
732
|
+
const evaluateRotation = numberEvaluator(
|
|
733
|
+
flatStyle,
|
|
734
|
+
prefix + 'rotation',
|
|
735
|
+
context
|
|
736
|
+
);
|
|
737
|
+
const evaluateRotateWithView = booleanEvaluator(
|
|
738
|
+
flatStyle,
|
|
739
|
+
prefix + 'rotate-with-view',
|
|
740
|
+
context
|
|
741
|
+
);
|
|
742
|
+
|
|
743
|
+
// the remaining properties are not currently settable
|
|
744
|
+
const radius = optionalNumber(flatStyle, prefix + 'radius');
|
|
745
|
+
const radius1 = optionalNumber(flatStyle, prefix + 'radius1');
|
|
746
|
+
const radius2 = optionalNumber(flatStyle, prefix + 'radius2');
|
|
747
|
+
const angle = optionalNumber(flatStyle, prefix + 'angle');
|
|
748
|
+
const declutterMode = optionalDeclutterMode(
|
|
749
|
+
flatStyle,
|
|
750
|
+
prefix + 'declutter-mode'
|
|
751
|
+
);
|
|
752
|
+
|
|
753
|
+
const shape = new RegularShape({
|
|
754
|
+
points,
|
|
755
|
+
radius,
|
|
756
|
+
radius1,
|
|
757
|
+
radius2,
|
|
758
|
+
angle,
|
|
759
|
+
declutterMode,
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
return function (context) {
|
|
763
|
+
if (evaluateFill) {
|
|
764
|
+
shape.setFill(evaluateFill(context));
|
|
765
|
+
}
|
|
766
|
+
if (evaluateStroke) {
|
|
767
|
+
shape.setStroke(evaluateStroke(context));
|
|
768
|
+
}
|
|
769
|
+
if (evaluateDisplacement) {
|
|
770
|
+
shape.setDisplacement(evaluateDisplacement(context));
|
|
771
|
+
}
|
|
772
|
+
if (evaluateRotation) {
|
|
773
|
+
shape.setRotation(evaluateRotation(context));
|
|
774
|
+
}
|
|
775
|
+
if (evaluateRotateWithView) {
|
|
776
|
+
shape.setRotateWithView(evaluateRotateWithView(context));
|
|
777
|
+
}
|
|
778
|
+
if (evaluateScale) {
|
|
779
|
+
shape.setScale(evaluateScale(context));
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
return shape;
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
788
|
+
* @param {ParsingContext} context The parsing context.
|
|
789
|
+
* @return {ImageEvaluator} A function that evaluates to a circle symbolizer.
|
|
790
|
+
*/
|
|
791
|
+
function buildCircle(flatStyle, context) {
|
|
792
|
+
const prefix = 'circle-';
|
|
793
|
+
|
|
794
|
+
// settable properties
|
|
795
|
+
const evaluateFill = buildFill(flatStyle, prefix, context);
|
|
796
|
+
const evaluateStroke = buildStroke(flatStyle, prefix, context);
|
|
797
|
+
const evaluateRadius = numberEvaluator(flatStyle, prefix + 'radius', context);
|
|
798
|
+
const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + 'scale', context);
|
|
799
|
+
const evaluateDisplacement = coordinateEvaluator(
|
|
800
|
+
flatStyle,
|
|
801
|
+
prefix + 'displacement',
|
|
802
|
+
context
|
|
803
|
+
);
|
|
804
|
+
const evaluateRotation = numberEvaluator(
|
|
805
|
+
flatStyle,
|
|
806
|
+
prefix + 'rotation',
|
|
807
|
+
context
|
|
808
|
+
);
|
|
809
|
+
const evaluateRotateWithView = booleanEvaluator(
|
|
810
|
+
flatStyle,
|
|
811
|
+
prefix + 'rotate-with-view',
|
|
812
|
+
context
|
|
813
|
+
);
|
|
814
|
+
|
|
815
|
+
// the remaining properties are not currently settable
|
|
816
|
+
const declutterMode = optionalDeclutterMode(
|
|
817
|
+
flatStyle,
|
|
818
|
+
prefix + 'declutter-mode'
|
|
819
|
+
);
|
|
820
|
+
|
|
821
|
+
const circle = new Circle({
|
|
822
|
+
radius: 5, // this is arbitrary, but required - the evaluated radius is used below
|
|
823
|
+
declutterMode,
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
return function (context) {
|
|
827
|
+
if (evaluateRadius) {
|
|
828
|
+
circle.setRadius(evaluateRadius(context));
|
|
829
|
+
}
|
|
830
|
+
if (evaluateFill) {
|
|
831
|
+
circle.setFill(evaluateFill(context));
|
|
832
|
+
}
|
|
833
|
+
if (evaluateStroke) {
|
|
834
|
+
circle.setStroke(evaluateStroke(context));
|
|
835
|
+
}
|
|
836
|
+
if (evaluateDisplacement) {
|
|
837
|
+
circle.setDisplacement(evaluateDisplacement(context));
|
|
838
|
+
}
|
|
839
|
+
if (evaluateRotation) {
|
|
840
|
+
circle.setRotation(evaluateRotation(context));
|
|
841
|
+
}
|
|
842
|
+
if (evaluateRotateWithView) {
|
|
843
|
+
circle.setRotateWithView(evaluateRotateWithView(context));
|
|
844
|
+
}
|
|
845
|
+
if (evaluateScale) {
|
|
846
|
+
circle.setScale(evaluateScale(context));
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
return circle;
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
855
|
+
* @param {string} name The property name.
|
|
856
|
+
* @param {ParsingContext} context The parsing context.
|
|
857
|
+
* @return {import('../../expr/cpu.js').NumberEvaluator|undefined} The expression evaluator or undefined.
|
|
858
|
+
*/
|
|
859
|
+
function numberEvaluator(flatStyle, name, context) {
|
|
860
|
+
if (!(name in flatStyle)) {
|
|
861
|
+
return undefined;
|
|
862
|
+
}
|
|
863
|
+
const evaluator = buildExpression(flatStyle[name], NumberType, context);
|
|
864
|
+
return function (context) {
|
|
865
|
+
return requireNumber(evaluator(context), name);
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
871
|
+
* @param {string} name The property name.
|
|
872
|
+
* @param {ParsingContext} context The parsing context.
|
|
873
|
+
* @return {import('../../expr/cpu.js').StringEvaluator?} The expression evaluator.
|
|
874
|
+
*/
|
|
875
|
+
function stringEvaluator(flatStyle, name, context) {
|
|
876
|
+
if (!(name in flatStyle)) {
|
|
877
|
+
return null;
|
|
878
|
+
}
|
|
879
|
+
const evaluator = buildExpression(flatStyle[name], StringType, context);
|
|
880
|
+
return function (context) {
|
|
881
|
+
return requireString(evaluator(context), name);
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
887
|
+
* @param {string} name The property name.
|
|
888
|
+
* @param {ParsingContext} context The parsing context.
|
|
889
|
+
* @return {import('../../expr/cpu.js').BooleanEvaluator?} The expression evaluator.
|
|
890
|
+
*/
|
|
891
|
+
function booleanEvaluator(flatStyle, name, context) {
|
|
892
|
+
if (!(name in flatStyle)) {
|
|
893
|
+
return null;
|
|
894
|
+
}
|
|
895
|
+
const evaluator = buildExpression(flatStyle[name], BooleanType, context);
|
|
896
|
+
return function (context) {
|
|
897
|
+
const value = evaluator(context);
|
|
898
|
+
if (typeof value !== 'boolean') {
|
|
899
|
+
throw new Error(`Expected a boolean for ${name}`);
|
|
900
|
+
}
|
|
901
|
+
return value;
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
/**
|
|
906
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
907
|
+
* @param {string} name The property name.
|
|
908
|
+
* @param {ParsingContext} context The parsing context.
|
|
909
|
+
* @return {import('../../expr/cpu.js').ColorLikeEvaluator?} The expression evaluator.
|
|
910
|
+
*/
|
|
911
|
+
function colorLikeEvaluator(flatStyle, name, context) {
|
|
912
|
+
if (!(name in flatStyle)) {
|
|
913
|
+
return null;
|
|
914
|
+
}
|
|
915
|
+
const evaluator = buildExpression(
|
|
916
|
+
flatStyle[name],
|
|
917
|
+
ColorType | StringType,
|
|
918
|
+
context
|
|
919
|
+
);
|
|
920
|
+
return function (context) {
|
|
921
|
+
return requireColorLike(evaluator(context), name);
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
927
|
+
* @param {string} name The property name.
|
|
928
|
+
* @param {ParsingContext} context The parsing context.
|
|
929
|
+
* @return {import('../../expr/cpu.js').NumberArrayEvaluator?} The expression evaluator.
|
|
930
|
+
*/
|
|
931
|
+
function numberArrayEvaluator(flatStyle, name, context) {
|
|
932
|
+
if (!(name in flatStyle)) {
|
|
933
|
+
return null;
|
|
934
|
+
}
|
|
935
|
+
const evaluator = buildExpression(flatStyle[name], NumberArrayType, context);
|
|
936
|
+
return function (context) {
|
|
937
|
+
return requireNumberArray(evaluator(context), name);
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
/**
|
|
942
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
943
|
+
* @param {string} name The property name.
|
|
944
|
+
* @param {ParsingContext} context The parsing context.
|
|
945
|
+
* @return {import('../../expr/cpu.js').CoordinateEvaluator?} The expression evaluator.
|
|
946
|
+
*/
|
|
947
|
+
function coordinateEvaluator(flatStyle, name, context) {
|
|
948
|
+
if (!(name in flatStyle)) {
|
|
949
|
+
return null;
|
|
950
|
+
}
|
|
951
|
+
const evaluator = buildExpression(flatStyle[name], NumberArrayType, context);
|
|
952
|
+
return function (context) {
|
|
953
|
+
const array = requireNumberArray(evaluator(context), name);
|
|
954
|
+
if (array.length !== 2) {
|
|
955
|
+
throw new Error(`Expected two numbers for ${name}`);
|
|
956
|
+
}
|
|
957
|
+
return array;
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
/**
|
|
962
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
963
|
+
* @param {string} name The property name.
|
|
964
|
+
* @param {ParsingContext} context The parsing context.
|
|
965
|
+
* @return {import('../../expr/cpu.js').SizeLikeEvaluator?} The expression evaluator.
|
|
966
|
+
*/
|
|
967
|
+
function sizeLikeEvaluator(flatStyle, name, context) {
|
|
968
|
+
if (!(name in flatStyle)) {
|
|
969
|
+
return null;
|
|
970
|
+
}
|
|
971
|
+
const evaluator = buildExpression(flatStyle[name], NumberArrayType, context);
|
|
972
|
+
return function (context) {
|
|
973
|
+
return requireSizeLike(evaluator(context), name);
|
|
974
|
+
};
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
979
|
+
* @param {string} property The symbolizer property.
|
|
980
|
+
* @return {number|undefined} A number or undefined.
|
|
981
|
+
*/
|
|
982
|
+
function optionalNumber(flatStyle, property) {
|
|
983
|
+
const value = flatStyle[property];
|
|
984
|
+
if (value === undefined) {
|
|
985
|
+
return undefined;
|
|
986
|
+
}
|
|
987
|
+
if (typeof value !== 'number') {
|
|
988
|
+
throw new Error(`Expected a number for ${property}`);
|
|
989
|
+
}
|
|
990
|
+
return value;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
/**
|
|
994
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
995
|
+
* @param {string} property The symbolizer property.
|
|
996
|
+
* @return {import("../../size.js").Size|undefined} A size or undefined.
|
|
997
|
+
*/
|
|
998
|
+
function optionalSize(flatStyle, property) {
|
|
999
|
+
const encoded = flatStyle[property];
|
|
1000
|
+
if (encoded === undefined) {
|
|
1001
|
+
return undefined;
|
|
1002
|
+
}
|
|
1003
|
+
if (typeof encoded === 'number') {
|
|
1004
|
+
return toSize(encoded);
|
|
1005
|
+
}
|
|
1006
|
+
if (!Array.isArray(encoded)) {
|
|
1007
|
+
throw new Error(`Expected a number or size array for ${property}`);
|
|
1008
|
+
}
|
|
1009
|
+
if (
|
|
1010
|
+
encoded.length !== 2 ||
|
|
1011
|
+
typeof encoded[0] !== 'number' ||
|
|
1012
|
+
typeof encoded[1] !== 'number'
|
|
1013
|
+
) {
|
|
1014
|
+
throw new Error(`Expected a number or size array for ${property}`);
|
|
1015
|
+
}
|
|
1016
|
+
return encoded;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
/**
|
|
1020
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
1021
|
+
* @param {string} property The symbolizer property.
|
|
1022
|
+
* @return {string|undefined} A string or undefined.
|
|
1023
|
+
*/
|
|
1024
|
+
function optionalString(flatStyle, property) {
|
|
1025
|
+
const encoded = flatStyle[property];
|
|
1026
|
+
if (encoded === undefined) {
|
|
1027
|
+
return undefined;
|
|
1028
|
+
}
|
|
1029
|
+
if (typeof encoded !== 'string') {
|
|
1030
|
+
throw new Error(`Expected a string for ${property}`);
|
|
1031
|
+
}
|
|
1032
|
+
return encoded;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
/**
|
|
1036
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
1037
|
+
* @param {string} property The symbolizer property.
|
|
1038
|
+
* @return {import("../../style/Icon.js").IconOrigin|undefined} An icon origin or undefined.
|
|
1039
|
+
*/
|
|
1040
|
+
function optionalIconOrigin(flatStyle, property) {
|
|
1041
|
+
const encoded = flatStyle[property];
|
|
1042
|
+
if (encoded === undefined) {
|
|
1043
|
+
return undefined;
|
|
1044
|
+
}
|
|
1045
|
+
if (
|
|
1046
|
+
encoded !== 'bottom-left' &&
|
|
1047
|
+
encoded !== 'bottom-right' &&
|
|
1048
|
+
encoded !== 'top-left' &&
|
|
1049
|
+
encoded !== 'top-right'
|
|
1050
|
+
) {
|
|
1051
|
+
throw new Error(
|
|
1052
|
+
`Expected bottom-left, bottom-right, top-left, or top-right for ${property}`
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
1055
|
+
return encoded;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
/**
|
|
1059
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
1060
|
+
* @param {string} property The symbolizer property.
|
|
1061
|
+
* @return {import("../../style/Icon.js").IconAnchorUnits|undefined} Icon anchor units or undefined.
|
|
1062
|
+
*/
|
|
1063
|
+
function optionalIconAnchorUnits(flatStyle, property) {
|
|
1064
|
+
const encoded = flatStyle[property];
|
|
1065
|
+
if (encoded === undefined) {
|
|
1066
|
+
return undefined;
|
|
1067
|
+
}
|
|
1068
|
+
if (encoded !== 'pixels' && encoded !== 'fraction') {
|
|
1069
|
+
throw new Error(`Expected pixels or fraction for ${property}`);
|
|
1070
|
+
}
|
|
1071
|
+
return encoded;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
1076
|
+
* @param {string} property The symbolizer property.
|
|
1077
|
+
* @return {Array<number>|undefined} An array of numbers or undefined.
|
|
1078
|
+
*/
|
|
1079
|
+
function optionalNumberArray(flatStyle, property) {
|
|
1080
|
+
const encoded = flatStyle[property];
|
|
1081
|
+
if (encoded === undefined) {
|
|
1082
|
+
return undefined;
|
|
1083
|
+
}
|
|
1084
|
+
return requireNumberArray(encoded, property);
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
/**
|
|
1088
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
1089
|
+
* @param {string} property The symbolizer property.
|
|
1090
|
+
* @return {"declutter"|"obstacle"|"none"|undefined} Icon declutter mode.
|
|
1091
|
+
*/
|
|
1092
|
+
function optionalDeclutterMode(flatStyle, property) {
|
|
1093
|
+
const encoded = flatStyle[property];
|
|
1094
|
+
if (encoded === undefined) {
|
|
1095
|
+
return undefined;
|
|
1096
|
+
}
|
|
1097
|
+
if (typeof encoded !== 'string') {
|
|
1098
|
+
throw new Error(`Expected a string for ${property}`);
|
|
1099
|
+
}
|
|
1100
|
+
if (encoded !== 'declutter' && encoded !== 'obstacle' && encoded !== 'none') {
|
|
1101
|
+
throw new Error(`Expected declutter, obstacle, or none for ${property}`);
|
|
1102
|
+
}
|
|
1103
|
+
return encoded;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* @param {FlatStyle} flatStyle The flat style.
|
|
1108
|
+
* @param {string} property The symbolizer property.
|
|
1109
|
+
* @return {string|Array<number>|undefined} A string or an array of color values or undefined.
|
|
1110
|
+
*/
|
|
1111
|
+
function optionalColorLike(flatStyle, property) {
|
|
1112
|
+
const encoded = flatStyle[property];
|
|
1113
|
+
if (encoded === undefined) {
|
|
1114
|
+
return undefined;
|
|
1115
|
+
}
|
|
1116
|
+
return requireColorLike(encoded, property);
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
/**
|
|
1120
|
+
* @param {any} value The value.
|
|
1121
|
+
* @param {string} property The property.
|
|
1122
|
+
* @return {Array<number>} An array of numbers.
|
|
1123
|
+
*/
|
|
1124
|
+
function requireNumberArray(value, property) {
|
|
1125
|
+
if (!Array.isArray(value)) {
|
|
1126
|
+
throw new Error(`Expected an array for ${property}`);
|
|
1127
|
+
}
|
|
1128
|
+
const length = value.length;
|
|
1129
|
+
for (let i = 0; i < length; ++i) {
|
|
1130
|
+
if (typeof value[i] !== 'number') {
|
|
1131
|
+
throw new Error(`Expected an array of numbers for ${property}`);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
return value;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
/**
|
|
1138
|
+
* @param {any} value The value.
|
|
1139
|
+
* @param {string} property The property.
|
|
1140
|
+
* @return {string} A string.
|
|
1141
|
+
*/
|
|
1142
|
+
function requireString(value, property) {
|
|
1143
|
+
if (typeof value !== 'string') {
|
|
1144
|
+
throw new Error(`Expected a string for ${property}`);
|
|
1145
|
+
}
|
|
1146
|
+
return value;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
/**
|
|
1150
|
+
* @param {any} value The value.
|
|
1151
|
+
* @param {string} property The property.
|
|
1152
|
+
* @return {number} A number.
|
|
1153
|
+
*/
|
|
1154
|
+
function requireNumber(value, property) {
|
|
1155
|
+
if (typeof value !== 'number') {
|
|
1156
|
+
throw new Error(`Expected a number for ${property}`);
|
|
1157
|
+
}
|
|
1158
|
+
return value;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
/**
|
|
1162
|
+
* @param {any} value The value.
|
|
1163
|
+
* @param {string} property The property.
|
|
1164
|
+
* @return {Array<number>|string} A color.
|
|
1165
|
+
*/
|
|
1166
|
+
function requireColorLike(value, property) {
|
|
1167
|
+
if (typeof value === 'string') {
|
|
1168
|
+
return value;
|
|
1169
|
+
}
|
|
1170
|
+
const array = requireNumberArray(value, property);
|
|
1171
|
+
const length = array.length;
|
|
1172
|
+
if (length < 3 || length > 4) {
|
|
1173
|
+
throw new Error(`Expected a color with 3 or 4 values for ${property}`);
|
|
1174
|
+
}
|
|
1175
|
+
return array;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
/**
|
|
1179
|
+
* @param {any} value The value.
|
|
1180
|
+
* @param {string} property The property.
|
|
1181
|
+
* @return {number|Array<number>} A number or an array of two numbers.
|
|
1182
|
+
*/
|
|
1183
|
+
function requireSizeLike(value, property) {
|
|
1184
|
+
if (typeof value === 'number') {
|
|
1185
|
+
return value;
|
|
1186
|
+
}
|
|
1187
|
+
const size = requireNumberArray(value, property);
|
|
1188
|
+
if (size.length !== 2) {
|
|
1189
|
+
throw new Error(`Expected an array of two numbers for ${property}`);
|
|
1190
|
+
}
|
|
1191
|
+
return size;
|
|
1192
|
+
}
|