@orbat-mapper/tactical-draw-adapter-maplibre 0.2.0-alpha.15 → 0.2.0-alpha.16
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/dist/index.mjs +118 -12
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -139,19 +139,29 @@ function buildTextSizeExpression(text) {
|
|
|
139
139
|
14
|
|
140
140
|
];
|
|
141
141
|
const sizeAtZoom = (zoom) => {
|
|
142
|
+
const groundPx = [
|
|
143
|
+
"*",
|
|
144
|
+
["get", "textSizeMeters"],
|
|
145
|
+
Math.pow(2, zoom + 9) / WEB_MERCATOR_CIRCUMFERENCE
|
|
146
|
+
];
|
|
142
147
|
return [
|
|
143
148
|
"case",
|
|
144
149
|
["has", "textSizeMeters"],
|
|
145
150
|
[
|
|
146
|
-
"
|
|
147
|
-
|
|
151
|
+
"case",
|
|
152
|
+
["has", "textMaxSizePixels"],
|
|
148
153
|
[
|
|
149
|
-
"
|
|
150
|
-
|
|
154
|
+
"min",
|
|
155
|
+
["get", "textMaxSizePixels"],
|
|
156
|
+
groundPx
|
|
157
|
+
],
|
|
158
|
+
[
|
|
159
|
+
"min",
|
|
160
|
+
maxPx,
|
|
151
161
|
[
|
|
152
|
-
"
|
|
153
|
-
|
|
154
|
-
|
|
162
|
+
"max",
|
|
163
|
+
minPx,
|
|
164
|
+
groundPx
|
|
155
165
|
]
|
|
156
166
|
]
|
|
157
167
|
],
|
|
@@ -166,6 +176,50 @@ function buildTextSizeExpression(text) {
|
|
|
166
176
|
];
|
|
167
177
|
}
|
|
168
178
|
/**
|
|
179
|
+
* Companion to `buildTextSizeExpression` (ADR-0037): drives `text-opacity` to
|
|
180
|
+
* 0 once a ground-anchored Text graphic's derived on-screen size exceeds its
|
|
181
|
+
* `textMaxSizePixels` threshold, 1 otherwise (including every feature without
|
|
182
|
+
* a threshold, e.g. amplifier labels). Layout properties like `text-size`
|
|
183
|
+
* cannot represent "hidden", so hiding is a paint-property concern; `step`
|
|
184
|
+
* (rather than `interpolate`) is enough since opacity only ever needs to
|
|
185
|
+
* flip at a stop, evaluated at the same per-zoom granularity as the size
|
|
186
|
+
* expression.
|
|
187
|
+
*/
|
|
188
|
+
const TEXT_OPACITY_EXPRESSION = (() => {
|
|
189
|
+
const opacityAtZoom = (zoom) => {
|
|
190
|
+
return [
|
|
191
|
+
"case",
|
|
192
|
+
[
|
|
193
|
+
"all",
|
|
194
|
+
["has", "textSizeMeters"],
|
|
195
|
+
["has", "textMaxSizePixels"]
|
|
196
|
+
],
|
|
197
|
+
[
|
|
198
|
+
"case",
|
|
199
|
+
[
|
|
200
|
+
">",
|
|
201
|
+
[
|
|
202
|
+
"*",
|
|
203
|
+
["get", "textSizeMeters"],
|
|
204
|
+
Math.pow(2, zoom + 9) / WEB_MERCATOR_CIRCUMFERENCE
|
|
205
|
+
],
|
|
206
|
+
["get", "textMaxSizePixels"]
|
|
207
|
+
],
|
|
208
|
+
0,
|
|
209
|
+
1
|
|
210
|
+
],
|
|
211
|
+
1
|
|
212
|
+
];
|
|
213
|
+
};
|
|
214
|
+
const stops = Array.from({ length: 25 }, (_, zoom) => zoom);
|
|
215
|
+
return [
|
|
216
|
+
"step",
|
|
217
|
+
["zoom"],
|
|
218
|
+
opacityAtZoom(0),
|
|
219
|
+
...stops.slice(1).flatMap((zoom) => [zoom, opacityAtZoom(zoom)])
|
|
220
|
+
];
|
|
221
|
+
})();
|
|
222
|
+
/**
|
|
169
223
|
* Per-feature icon size, same zoom-stop scheme as `buildTextSizeExpression`:
|
|
170
224
|
* a ground-sized point symbol carries `iconSizeMeters`/`iconOctagonSize` (and
|
|
171
225
|
* optional `iconMinPixels`/`iconMaxPixels`), so the meters→pixels clamp is
|
|
@@ -224,6 +278,26 @@ function buildIconSizeExpression() {
|
|
|
224
278
|
* `properties.style.fillColor` overlay. Mirrors `buildCirclePaint`.
|
|
225
279
|
*/
|
|
226
280
|
/**
|
|
281
|
+
* Per-feature `text-field` value: the layer's literal text, or the feature's
|
|
282
|
+
* `labelProperty` value, uppercased when the feature's `textStyle` is
|
|
283
|
+
* `"caps"`. Factored out of `buildSymbolLayer` so `setLayerStyle`'s
|
|
284
|
+
* incremental `text-field` update (below) can reuse it instead of
|
|
285
|
+
* regressing to a caps-unaware plain `["get", ...]`.
|
|
286
|
+
*/
|
|
287
|
+
function buildTextFieldExpression(text) {
|
|
288
|
+
const rawTextField = text.labelProperty ? ["get", text.labelProperty] : text.text ?? "";
|
|
289
|
+
return text.labelProperty ? [
|
|
290
|
+
"case",
|
|
291
|
+
[
|
|
292
|
+
"==",
|
|
293
|
+
["get", "textStyle"],
|
|
294
|
+
"caps"
|
|
295
|
+
],
|
|
296
|
+
["upcase", rawTextField],
|
|
297
|
+
rawTextField
|
|
298
|
+
] : rawTextField;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
227
301
|
* Build the layout and paint objects for a symbol (text) layer.
|
|
228
302
|
* Centralises the rotation convention so `createLayer` and `setLayerStyle`
|
|
229
303
|
* stay in sync. Rotation follows the OpenLayers convention: `π − r` radians
|
|
@@ -277,16 +351,48 @@ function buildSymbolLayer(symbolId, sourceId, text) {
|
|
|
277
351
|
"right",
|
|
278
352
|
"center"
|
|
279
353
|
] : "center";
|
|
354
|
+
const textJustify = text.labelProperty ? [
|
|
355
|
+
"case",
|
|
356
|
+
[
|
|
357
|
+
"==",
|
|
358
|
+
["get", "textJustify"],
|
|
359
|
+
"left"
|
|
360
|
+
],
|
|
361
|
+
"left",
|
|
362
|
+
[
|
|
363
|
+
"==",
|
|
364
|
+
["get", "textJustify"],
|
|
365
|
+
"right"
|
|
366
|
+
],
|
|
367
|
+
"right",
|
|
368
|
+
"center"
|
|
369
|
+
] : "center";
|
|
280
370
|
return {
|
|
281
371
|
id: symbolId,
|
|
282
372
|
type: "symbol",
|
|
283
373
|
source: sourceId,
|
|
284
374
|
layout: {
|
|
285
|
-
"text-field": text
|
|
286
|
-
"text-font":
|
|
375
|
+
"text-field": buildTextFieldExpression(text),
|
|
376
|
+
"text-font": text.labelProperty ? [
|
|
377
|
+
"case",
|
|
378
|
+
[
|
|
379
|
+
"==",
|
|
380
|
+
["get", "textStyle"],
|
|
381
|
+
"italic"
|
|
382
|
+
],
|
|
383
|
+
["literal", ["Open Sans Italic"]],
|
|
384
|
+
[
|
|
385
|
+
"==",
|
|
386
|
+
["get", "textStyle"],
|
|
387
|
+
"light"
|
|
388
|
+
],
|
|
389
|
+
["literal", ["Open Sans Light"]],
|
|
390
|
+
["literal", ["Open Sans Regular"]]
|
|
391
|
+
] : ["Open Sans Regular"],
|
|
287
392
|
"text-size": buildTextSizeExpression(text),
|
|
288
393
|
"text-rotate": textRotate,
|
|
289
394
|
"text-anchor": textAnchor,
|
|
395
|
+
"text-justify": textJustify,
|
|
290
396
|
"text-max-width": 9999,
|
|
291
397
|
"text-rotation-alignment": "map",
|
|
292
398
|
"text-pitch-alignment": "map",
|
|
@@ -305,7 +411,8 @@ function buildSymbolLayer(symbolId, sourceId, text) {
|
|
|
305
411
|
hasTextBackground,
|
|
306
412
|
3,
|
|
307
413
|
0
|
|
308
|
-
]
|
|
414
|
+
],
|
|
415
|
+
"text-opacity": TEXT_OPACITY_EXPRESSION
|
|
309
416
|
}
|
|
310
417
|
};
|
|
311
418
|
}
|
|
@@ -795,8 +902,7 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
795
902
|
this.map.setPaintProperty(mlId, "circle-stroke-width", paint["circle-stroke-width"]);
|
|
796
903
|
this.map.setFilter(mlId, buildCirclePointFilter(style));
|
|
797
904
|
} else if (type === "symbol" && style.text) {
|
|
798
|
-
if (style.text.text) this.map.setLayoutProperty(mlId, "text-field", style.text
|
|
799
|
-
else if (style.text.labelProperty) this.map.setLayoutProperty(mlId, "text-field", ["get", style.text.labelProperty]);
|
|
905
|
+
if (style.text.text || style.text.labelProperty) this.map.setLayoutProperty(mlId, "text-field", buildTextFieldExpression(style.text));
|
|
800
906
|
if (style.text.fillColor) this.map.setPaintProperty(mlId, "text-color", style.text.fillColor);
|
|
801
907
|
if (style.text.strokeColor) this.map.setPaintProperty(mlId, "text-halo-color", style.text.strokeColor);
|
|
802
908
|
if (style.text.strokeWidth !== void 0) this.map.setPaintProperty(mlId, "text-halo-width", style.text.strokeWidth);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orbat-mapper/tactical-draw-adapter-maplibre",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.16",
|
|
4
4
|
"description": "MapLibre GL JS engine adapter for @orbat-mapper/tactical-draw. Draw and edit tactical control measures (MIL-STD-2525 / APP-6) on a MapLibre map.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Orbat Mapper",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@orbat-mapper/control-measures": "^0.2.0-alpha.
|
|
41
|
-
"@orbat-mapper/tactical-draw": "^0.2.0-alpha.
|
|
40
|
+
"@orbat-mapper/control-measures": "^0.2.0-alpha.24",
|
|
41
|
+
"@orbat-mapper/tactical-draw": "^0.2.0-alpha.31"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"maplibre-gl": ">=4.0.0 <6.0.0"
|