@orbat-mapper/tactical-draw-adapter-maplibre 0.2.0-alpha.17 → 0.2.0-alpha.18

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.
Files changed (2) hide show
  1. package/dist/index.mjs +88 -27
  2. package/package.json +5 -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";
@@ -299,6 +299,74 @@ function buildTextFieldExpression(text) {
299
299
  rawTextField
300
300
  ] : rawTextField;
301
301
  }
302
+ const HAS_TEXT_HALO = [
303
+ "boolean",
304
+ ["get", "textHalo"],
305
+ false
306
+ ];
307
+ const HAS_TEXT_BACKGROUND = [
308
+ "boolean",
309
+ ["get", "textBackground"],
310
+ false
311
+ ];
312
+ /**
313
+ * Per-feature `text-halo-color` value: `textHalo` wins over both the layer's
314
+ * `text.strokeColor` and the `textBackground` halo, matching the OL/Leaflet
315
+ * adapters' precedence. Factored out so `setLayerStyle`'s incremental
316
+ * `text-halo-color` update (below) can reuse it instead of dropping the
317
+ * `textHalo` case.
318
+ */
319
+ function buildTextHaloColorExpression(text) {
320
+ const fallback = text.strokeColor ? text.strokeColor : [
321
+ "case",
322
+ HAS_TEXT_BACKGROUND,
323
+ "#ffffff",
324
+ "rgba(255,255,255,0)"
325
+ ];
326
+ return [
327
+ "case",
328
+ HAS_TEXT_HALO,
329
+ [
330
+ "coalesce",
331
+ ["get", "textHaloColor"],
332
+ TEXT_HALO_COLOR
333
+ ],
334
+ fallback
335
+ ];
336
+ }
337
+ /**
338
+ * Per-feature `text-halo-width` value, mirroring
339
+ * `buildTextHaloColorExpression`'s precedence. MapLibre's `text-halo-width`
340
+ * already extends outward from the glyph edge, matching
341
+ * `resolveTextHaloWidth`'s own outward-depth semantics, so the `textHalo`
342
+ * case uses its formula directly (unlike OpenLayers's straddling canvas
343
+ * stroke, which must double it).
344
+ */
345
+ function buildTextHaloWidthExpression(text) {
346
+ return [
347
+ "case",
348
+ HAS_TEXT_HALO,
349
+ [
350
+ "max",
351
+ 1.5,
352
+ [
353
+ "/",
354
+ [
355
+ "coalesce",
356
+ ["get", "textSizePixels"],
357
+ 24
358
+ ],
359
+ 8
360
+ ]
361
+ ],
362
+ text.strokeColor ? text.strokeWidth ?? 1 : [
363
+ "case",
364
+ HAS_TEXT_BACKGROUND,
365
+ 3,
366
+ 0
367
+ ]
368
+ ];
369
+ }
302
370
  /**
303
371
  * Build the layout and paint objects for a symbol (text) layer.
304
372
  * Centralises the rotation convention so `createLayer` and `setLayerStyle`
@@ -332,11 +400,6 @@ function buildSymbolLayer(symbolId, sourceId, text) {
332
400
  ],
333
401
  "#000"
334
402
  ];
335
- const hasTextBackground = [
336
- "boolean",
337
- ["get", "textBackground"],
338
- false
339
- ];
340
403
  const textAnchor = text.labelProperty ? [
341
404
  "case",
342
405
  [
@@ -402,18 +465,8 @@ function buildSymbolLayer(symbolId, sourceId, text) {
402
465
  },
403
466
  paint: {
404
467
  "text-color": textColor,
405
- "text-halo-color": text.strokeColor ? text.strokeColor : [
406
- "case",
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
- ],
468
+ "text-halo-color": buildTextHaloColorExpression(text),
469
+ "text-halo-width": buildTextHaloWidthExpression(text),
417
470
  "text-opacity": TEXT_OPACITY_EXPRESSION
418
471
  }
419
472
  };
@@ -490,9 +543,11 @@ const FILL_PATTERN_PAINT = {
490
543
  "fill-pattern": ["get", FILL_PATTERN_IMAGE_ID_PROPERTY],
491
544
  "fill-opacity": 1
492
545
  };
546
+ const SOLID_LINE_DASH = [1, 0];
493
547
  function buildLinePaint(style) {
494
548
  const colorDefault = style?.strokeColor ?? DEFAULT_LINE_COLOR;
495
549
  const widthDefault = style?.strokeWidth ?? DEFAULT_LINE_WIDTH;
550
+ const dashDefault = style?.strokeDash?.length ? [...style.strokeDash] : SOLID_LINE_DASH;
496
551
  const styleObj = [
497
552
  "coalesce",
498
553
  ["get", "style"],
@@ -517,7 +572,15 @@ function buildLinePaint(style) {
517
572
  ],
518
573
  widthDefault
519
574
  ],
520
- ...style?.strokeDash ? { "line-dasharray": style.strokeDash } : {}
575
+ "line-dasharray": [
576
+ "coalesce",
577
+ [
578
+ "get",
579
+ "strokeDash",
580
+ styleObj
581
+ ],
582
+ ["literal", dashDefault]
583
+ ]
521
584
  };
522
585
  }
523
586
  var MapLibreAdapter = class extends BaseMapAdapter {
@@ -890,12 +953,10 @@ var MapLibreAdapter = class extends BaseMapAdapter {
890
953
  if (mlId.endsWith("-fill-pattern")) continue;
891
954
  this.map.setPaintProperty(mlId, "fill-color", buildFillPaint(style)["fill-color"]);
892
955
  } else if (type === "line") {
893
- if (style.strokeColor !== void 0 || style.strokeWidth !== void 0) {
894
- const paint = buildLinePaint(style);
895
- if (style.strokeColor !== void 0) this.map.setPaintProperty(mlId, "line-color", paint["line-color"]);
896
- if (style.strokeWidth !== void 0) this.map.setPaintProperty(mlId, "line-width", paint["line-width"]);
897
- }
898
- if (style.strokeDash) this.map.setPaintProperty(mlId, "line-dasharray", style.strokeDash);
956
+ const paint = buildLinePaint(style);
957
+ if (style.strokeColor !== void 0) this.map.setPaintProperty(mlId, "line-color", paint["line-color"]);
958
+ if (style.strokeWidth !== void 0) this.map.setPaintProperty(mlId, "line-width", paint["line-width"]);
959
+ if (style.strokeDash !== void 0) this.map.setPaintProperty(mlId, "line-dasharray", paint["line-dasharray"]);
899
960
  } else if (type === "circle") {
900
961
  const paint = buildCirclePaint(style);
901
962
  this.map.setPaintProperty(mlId, "circle-radius", paint["circle-radius"]);
@@ -906,8 +967,8 @@ var MapLibreAdapter = class extends BaseMapAdapter {
906
967
  } else if (type === "symbol" && style.text) {
907
968
  if (style.text.text || style.text.labelProperty) this.map.setLayoutProperty(mlId, "text-field", buildTextFieldExpression(style.text));
908
969
  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.strokeColor);
910
- if (style.text.strokeWidth !== void 0) this.map.setPaintProperty(mlId, "text-halo-width", style.text.strokeWidth);
970
+ if (style.text.strokeColor) this.map.setPaintProperty(mlId, "text-halo-color", buildTextHaloColorExpression(style.text));
971
+ if (style.text.strokeWidth !== void 0) this.map.setPaintProperty(mlId, "text-halo-width", buildTextHaloWidthExpression(style.text));
911
972
  }
912
973
  }
913
974
  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.17",
3
+ "version": "0.2.0-alpha.18",
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,17 @@
37
37
  "access": "public"
38
38
  },
39
39
  "dependencies": {
40
- "@orbat-mapper/control-measures": "^0.2.0-alpha.24",
41
- "@orbat-mapper/tactical-draw": "^0.2.0-alpha.32"
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": ">=4.0.0 <6.0.0"
44
+ "maplibre-gl": ">=5.8.0 <6.0.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@arethetypeswrong/core": "^0.18.3",
48
48
  "@types/geojson": "^7946.0.16",
49
49
  "jsdom": "^27.4.0",
50
- "maplibre-gl": "^5.18.0",
50
+ "maplibre-gl": "^5.24.0",
51
51
  "publint": "^0.3.21",
52
52
  "tsdown": "^0.22.2",
53
53
  "typescript": "~5.9.3",