@orbat-mapper/tactical-draw-adapter-maplibre 0.2.0-alpha.17 → 0.2.0-alpha.19
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 +102 -29
- package/package.json +6 -5
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { project, unproject } from "@orbat-mapper/control-measures";
|
|
2
|
-
import { BaseMapAdapter, DEFAULT_TEXT_SIZE_MAX_PIXELS, DEFAULT_TEXT_SIZE_MIN_PIXELS, HATCH_PATTERNS, PointerCallbackHub, TOUCH_HIT_TOLERANCE_PX, bindAbortable, evaluatePickCandidates, fillPatternImageId, makeFillPatternImage, mergeNativeAndCachedPickFeatures, nearestWorldCopyLng, pickHitTolerance, pickPointerType } from "@orbat-mapper/tactical-draw";
|
|
2
|
+
import { BaseMapAdapter, DEFAULT_TEXT_SIZE_MAX_PIXELS, DEFAULT_TEXT_SIZE_MIN_PIXELS, HATCH_PATTERNS, PointerCallbackHub, TEXT_HALO_COLOR, TOUCH_HIT_TOLERANCE_PX, bindAbortable, evaluatePickCandidates, fillPatternImageId, makeFillPatternImage, mergeNativeAndCachedPickFeatures, nearestWorldCopyLng, pickHitTolerance, pickPointerType } from "@orbat-mapper/tactical-draw";
|
|
3
3
|
//#region src/ml-adapter.ts
|
|
4
4
|
/** Feature property key for the resolved hatch-pattern image id (see `promoteFeature`). */
|
|
5
5
|
const FILL_PATTERN_IMAGE_ID_PROPERTY = "_fillPatternImageId";
|
|
@@ -103,7 +103,8 @@ function buildIconLayer(id, source) {
|
|
|
103
103
|
"icon-rotation-alignment": "viewport",
|
|
104
104
|
"icon-pitch-alignment": "viewport",
|
|
105
105
|
"icon-allow-overlap": true,
|
|
106
|
-
"icon-ignore-placement": true
|
|
106
|
+
"icon-ignore-placement": true,
|
|
107
|
+
"symbol-z-order": "source"
|
|
107
108
|
},
|
|
108
109
|
paint: { "icon-opacity": [
|
|
109
110
|
"coalesce",
|
|
@@ -299,6 +300,74 @@ function buildTextFieldExpression(text) {
|
|
|
299
300
|
rawTextField
|
|
300
301
|
] : rawTextField;
|
|
301
302
|
}
|
|
303
|
+
const HAS_TEXT_HALO = [
|
|
304
|
+
"boolean",
|
|
305
|
+
["get", "textHalo"],
|
|
306
|
+
false
|
|
307
|
+
];
|
|
308
|
+
const HAS_TEXT_BACKGROUND = [
|
|
309
|
+
"boolean",
|
|
310
|
+
["get", "textBackground"],
|
|
311
|
+
false
|
|
312
|
+
];
|
|
313
|
+
/**
|
|
314
|
+
* Per-feature `text-halo-color` value: `textHalo` wins over both the layer's
|
|
315
|
+
* `text.strokeColor` and the `textBackground` halo, matching the OL/Leaflet
|
|
316
|
+
* adapters' precedence. Factored out so `setLayerStyle`'s incremental
|
|
317
|
+
* `text-halo-color` update (below) can reuse it instead of dropping the
|
|
318
|
+
* `textHalo` case.
|
|
319
|
+
*/
|
|
320
|
+
function buildTextHaloColorExpression(text) {
|
|
321
|
+
const fallback = text.strokeColor ? text.strokeColor : [
|
|
322
|
+
"case",
|
|
323
|
+
HAS_TEXT_BACKGROUND,
|
|
324
|
+
"#ffffff",
|
|
325
|
+
"rgba(255,255,255,0)"
|
|
326
|
+
];
|
|
327
|
+
return [
|
|
328
|
+
"case",
|
|
329
|
+
HAS_TEXT_HALO,
|
|
330
|
+
[
|
|
331
|
+
"coalesce",
|
|
332
|
+
["get", "textHaloColor"],
|
|
333
|
+
TEXT_HALO_COLOR
|
|
334
|
+
],
|
|
335
|
+
fallback
|
|
336
|
+
];
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Per-feature `text-halo-width` value, mirroring
|
|
340
|
+
* `buildTextHaloColorExpression`'s precedence. MapLibre's `text-halo-width`
|
|
341
|
+
* already extends outward from the glyph edge, matching
|
|
342
|
+
* `resolveTextHaloWidth`'s own outward-depth semantics, so the `textHalo`
|
|
343
|
+
* case uses its formula directly (unlike OpenLayers's straddling canvas
|
|
344
|
+
* stroke, which must double it).
|
|
345
|
+
*/
|
|
346
|
+
function buildTextHaloWidthExpression(text) {
|
|
347
|
+
return [
|
|
348
|
+
"case",
|
|
349
|
+
HAS_TEXT_HALO,
|
|
350
|
+
[
|
|
351
|
+
"max",
|
|
352
|
+
1.5,
|
|
353
|
+
[
|
|
354
|
+
"/",
|
|
355
|
+
[
|
|
356
|
+
"coalesce",
|
|
357
|
+
["get", "textSizePixels"],
|
|
358
|
+
24
|
|
359
|
+
],
|
|
360
|
+
8
|
|
361
|
+
]
|
|
362
|
+
],
|
|
363
|
+
text.strokeColor ? text.strokeWidth ?? 1 : [
|
|
364
|
+
"case",
|
|
365
|
+
HAS_TEXT_BACKGROUND,
|
|
366
|
+
3,
|
|
367
|
+
0
|
|
368
|
+
]
|
|
369
|
+
];
|
|
370
|
+
}
|
|
302
371
|
/**
|
|
303
372
|
* Build the layout and paint objects for a symbol (text) layer.
|
|
304
373
|
* Centralises the rotation convention so `createLayer` and `setLayerStyle`
|
|
@@ -332,11 +401,6 @@ function buildSymbolLayer(symbolId, sourceId, text) {
|
|
|
332
401
|
],
|
|
333
402
|
"#000"
|
|
334
403
|
];
|
|
335
|
-
const hasTextBackground = [
|
|
336
|
-
"boolean",
|
|
337
|
-
["get", "textBackground"],
|
|
338
|
-
false
|
|
339
|
-
];
|
|
340
404
|
const textAnchor = text.labelProperty ? [
|
|
341
405
|
"case",
|
|
342
406
|
[
|
|
@@ -398,22 +462,13 @@ function buildSymbolLayer(symbolId, sourceId, text) {
|
|
|
398
462
|
"text-max-width": 9999,
|
|
399
463
|
"text-rotation-alignment": "map",
|
|
400
464
|
"text-pitch-alignment": "map",
|
|
401
|
-
"text-allow-overlap": true
|
|
465
|
+
"text-allow-overlap": true,
|
|
466
|
+
"symbol-z-order": "source"
|
|
402
467
|
},
|
|
403
468
|
paint: {
|
|
404
469
|
"text-color": textColor,
|
|
405
|
-
"text-halo-color": text
|
|
406
|
-
|
|
407
|
-
hasTextBackground,
|
|
408
|
-
"#ffffff",
|
|
409
|
-
"rgba(255,255,255,0)"
|
|
410
|
-
],
|
|
411
|
-
"text-halo-width": text.strokeColor ? text.strokeWidth ?? 1 : [
|
|
412
|
-
"case",
|
|
413
|
-
hasTextBackground,
|
|
414
|
-
3,
|
|
415
|
-
0
|
|
416
|
-
],
|
|
470
|
+
"text-halo-color": buildTextHaloColorExpression(text),
|
|
471
|
+
"text-halo-width": buildTextHaloWidthExpression(text),
|
|
417
472
|
"text-opacity": TEXT_OPACITY_EXPRESSION
|
|
418
473
|
}
|
|
419
474
|
};
|
|
@@ -490,14 +545,25 @@ const FILL_PATTERN_PAINT = {
|
|
|
490
545
|
"fill-pattern": ["get", FILL_PATTERN_IMAGE_ID_PROPERTY],
|
|
491
546
|
"fill-opacity": 1
|
|
492
547
|
};
|
|
548
|
+
const SOLID_LINE_DASH = [1, 0];
|
|
493
549
|
function buildLinePaint(style) {
|
|
494
550
|
const colorDefault = style?.strokeColor ?? DEFAULT_LINE_COLOR;
|
|
495
551
|
const widthDefault = style?.strokeWidth ?? DEFAULT_LINE_WIDTH;
|
|
552
|
+
const dashDefault = style?.strokeDash?.length ? [...style.strokeDash] : SOLID_LINE_DASH;
|
|
496
553
|
const styleObj = [
|
|
497
554
|
"coalesce",
|
|
498
555
|
["get", "style"],
|
|
499
556
|
["literal", {}]
|
|
500
557
|
];
|
|
558
|
+
const dashExpr = [
|
|
559
|
+
"coalesce",
|
|
560
|
+
[
|
|
561
|
+
"get",
|
|
562
|
+
"strokeDash",
|
|
563
|
+
styleObj
|
|
564
|
+
],
|
|
565
|
+
["literal", dashDefault]
|
|
566
|
+
];
|
|
501
567
|
return {
|
|
502
568
|
"line-color": [
|
|
503
569
|
"coalesce",
|
|
@@ -517,7 +583,16 @@ function buildLinePaint(style) {
|
|
|
517
583
|
],
|
|
518
584
|
widthDefault
|
|
519
585
|
],
|
|
520
|
-
|
|
586
|
+
"line-dasharray": [
|
|
587
|
+
"case",
|
|
588
|
+
[
|
|
589
|
+
">",
|
|
590
|
+
["length", dashExpr],
|
|
591
|
+
0
|
|
592
|
+
],
|
|
593
|
+
dashExpr,
|
|
594
|
+
["literal", SOLID_LINE_DASH]
|
|
595
|
+
]
|
|
521
596
|
};
|
|
522
597
|
}
|
|
523
598
|
var MapLibreAdapter = class extends BaseMapAdapter {
|
|
@@ -890,12 +965,10 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
890
965
|
if (mlId.endsWith("-fill-pattern")) continue;
|
|
891
966
|
this.map.setPaintProperty(mlId, "fill-color", buildFillPaint(style)["fill-color"]);
|
|
892
967
|
} else if (type === "line") {
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
}
|
|
898
|
-
if (style.strokeDash) this.map.setPaintProperty(mlId, "line-dasharray", style.strokeDash);
|
|
968
|
+
const paint = buildLinePaint(style);
|
|
969
|
+
if (style.strokeColor !== void 0) this.map.setPaintProperty(mlId, "line-color", paint["line-color"]);
|
|
970
|
+
if (style.strokeWidth !== void 0) this.map.setPaintProperty(mlId, "line-width", paint["line-width"]);
|
|
971
|
+
if (style.strokeDash !== void 0) this.map.setPaintProperty(mlId, "line-dasharray", paint["line-dasharray"]);
|
|
899
972
|
} else if (type === "circle") {
|
|
900
973
|
const paint = buildCirclePaint(style);
|
|
901
974
|
this.map.setPaintProperty(mlId, "circle-radius", paint["circle-radius"]);
|
|
@@ -906,8 +979,8 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
906
979
|
} else if (type === "symbol" && style.text) {
|
|
907
980
|
if (style.text.text || style.text.labelProperty) this.map.setLayoutProperty(mlId, "text-field", buildTextFieldExpression(style.text));
|
|
908
981
|
if (style.text.fillColor) this.map.setPaintProperty(mlId, "text-color", style.text.fillColor);
|
|
909
|
-
if (style.text.strokeColor) this.map.setPaintProperty(mlId, "text-halo-color", style.text
|
|
910
|
-
if (style.text.strokeWidth !== void 0) this.map.setPaintProperty(mlId, "text-halo-width", style.text
|
|
982
|
+
if (style.text.strokeColor) this.map.setPaintProperty(mlId, "text-halo-color", buildTextHaloColorExpression(style.text));
|
|
983
|
+
if (style.text.strokeWidth !== void 0) this.map.setPaintProperty(mlId, "text-halo-width", buildTextHaloWidthExpression(style.text));
|
|
911
984
|
}
|
|
912
985
|
}
|
|
913
986
|
if (style.text && !handle.mlLayerIds.some((id) => id.endsWith("-symbol"))) {
|
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.19",
|
|
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,17 +37,18 @@
|
|
|
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.25",
|
|
41
|
+
"@orbat-mapper/tactical-draw": "^0.2.0-alpha.34"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"maplibre-gl": ">=
|
|
44
|
+
"maplibre-gl": ">=5.8.0 <6.0.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@arethetypeswrong/core": "^0.18.3",
|
|
48
|
+
"@maplibre/maplibre-gl-style-spec": "^24.10.0",
|
|
48
49
|
"@types/geojson": "^7946.0.16",
|
|
49
50
|
"jsdom": "^27.4.0",
|
|
50
|
-
"maplibre-gl": "^5.
|
|
51
|
+
"maplibre-gl": "^5.24.0",
|
|
51
52
|
"publint": "^0.3.21",
|
|
52
53
|
"tsdown": "^0.22.2",
|
|
53
54
|
"typescript": "~5.9.3",
|