@orbat-mapper/tactical-draw-adapter-maplibre 0.2.0-alpha.10 → 0.2.0-alpha.12
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.d.mts +5 -0
- package/dist/index.mjs +58 -4
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -25,12 +25,17 @@ declare class MapLibreAdapter extends BaseMapAdapter<MapLibreLayerHandle, MapLib
|
|
|
25
25
|
private map;
|
|
26
26
|
private readonly viewChangeMode;
|
|
27
27
|
private readonly pendingIconImages;
|
|
28
|
+
private readonly pendingLayerUpdates;
|
|
29
|
+
private readonly deferredLayerRemovals;
|
|
28
30
|
readonly scalesGroundPointSymbolsNatively = true;
|
|
29
31
|
constructor(map: maplibregl.Map, options?: MapLibreAdapterOptions);
|
|
30
32
|
private toContinuousLng;
|
|
31
33
|
protected createLayer(layerId: LayerId, style?: StyleOptions): MapLibreLayerHandle;
|
|
32
34
|
protected destroyLayer(handle: MapLibreLayerHandle): void;
|
|
33
35
|
protected applyFeatureOps(layerId: LayerId, ops: FeatureOps): void;
|
|
36
|
+
private updateSourceData;
|
|
37
|
+
private flushDeferredLayerRemoval;
|
|
38
|
+
deferLayerRemovalUntilLayerUpdate(layerId: LayerId, updatedLayerId: LayerId): void;
|
|
34
39
|
protected applyIconResources(resources: readonly IconResource[]): void;
|
|
35
40
|
protected removeIconResource(id: string): void;
|
|
36
41
|
protected attachNativeEvent(type: "click" | "pointermove" | "dblclick", onEvent: (lonLat: Position, pixel: PixelCoordinate, originalEvent: unknown) => void): NativeEventEntry<MapLibreEventToken>;
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { project, unproject } from "@orbat-mapper/control-measures";
|
|
2
2
|
import { BaseMapAdapter, DEFAULT_TEXT_SIZE_MAX_PIXELS, DEFAULT_TEXT_SIZE_MIN_PIXELS, PointerCallbackHub, TOUCH_HIT_TOLERANCE_PX, bindAbortable, nearestWorldCopyLng, pickHitTolerance, tryControlMeasureIdFromFeature } from "@orbat-mapper/tactical-draw";
|
|
3
3
|
//#region src/ml-adapter.ts
|
|
4
|
+
function isPromiseLike(value) {
|
|
5
|
+
return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
|
|
6
|
+
}
|
|
4
7
|
function emptyFC() {
|
|
5
8
|
return {
|
|
6
9
|
type: "FeatureCollection",
|
|
@@ -274,6 +277,7 @@ function buildSymbolLayer(symbolId, sourceId, text) {
|
|
|
274
277
|
"text-size": buildTextSizeExpression(text),
|
|
275
278
|
"text-rotate": textRotate,
|
|
276
279
|
"text-anchor": textAnchor,
|
|
280
|
+
"text-max-width": 9999,
|
|
277
281
|
"text-rotation-alignment": "map",
|
|
278
282
|
"text-pitch-alignment": "map",
|
|
279
283
|
"text-allow-overlap": true
|
|
@@ -339,6 +343,8 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
339
343
|
map;
|
|
340
344
|
viewChangeMode;
|
|
341
345
|
pendingIconImages = /* @__PURE__ */ new Set();
|
|
346
|
+
pendingLayerUpdates = /* @__PURE__ */ new Map();
|
|
347
|
+
deferredLayerRemovals = /* @__PURE__ */ new Map();
|
|
342
348
|
scalesGroundPointSymbolsNatively = true;
|
|
343
349
|
constructor(map, options = {}) {
|
|
344
350
|
super();
|
|
@@ -418,25 +424,73 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
418
424
|
};
|
|
419
425
|
}
|
|
420
426
|
destroyLayer(handle) {
|
|
427
|
+
for (const [layerId, layerHandle] of this.layers) {
|
|
428
|
+
if (layerHandle !== handle) continue;
|
|
429
|
+
this.pendingLayerUpdates.get(layerId)?.cancel();
|
|
430
|
+
this.pendingLayerUpdates.delete(layerId);
|
|
431
|
+
this.deferredLayerRemovals.delete(layerId);
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
421
434
|
for (const mlId of handle.mlLayerIds) if (this.map.getLayer(mlId)) this.map.removeLayer(mlId);
|
|
422
435
|
if (this.map.getSource(handle.sourceId)) this.map.removeSource(handle.sourceId);
|
|
423
436
|
}
|
|
424
437
|
applyFeatureOps(layerId, ops) {
|
|
438
|
+
const deferred = this.deferredLayerRemovals.get(layerId);
|
|
439
|
+
const isPureRemoval = ops.adds.length === 0 && ops.updates.length === 0 && (ops.removes?.length ?? 0) > 0;
|
|
440
|
+
if (deferred && isPureRemoval) {
|
|
441
|
+
deferred.after.then(() => this.flushDeferredLayerRemoval(layerId, deferred), () => this.flushDeferredLayerRemoval(layerId, deferred));
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
if (deferred) this.deferredLayerRemovals.delete(layerId);
|
|
445
|
+
this.updateSourceData(layerId, ops.full);
|
|
446
|
+
}
|
|
447
|
+
updateSourceData(layerId, features) {
|
|
425
448
|
const handle = this.layers.get(layerId);
|
|
426
449
|
if (!handle) return;
|
|
427
450
|
const source = this.map.getSource(handle.sourceId);
|
|
428
451
|
if (!source) return;
|
|
429
|
-
const
|
|
452
|
+
const promotedFeatures = features.map((f) => f.id !== void 0 ? {
|
|
430
453
|
...f,
|
|
431
454
|
properties: {
|
|
432
455
|
...f.properties ?? {},
|
|
433
456
|
_fid: f.id
|
|
434
457
|
}
|
|
435
458
|
} : f);
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
459
|
+
let resolveSourceData;
|
|
460
|
+
const sourceDataCompletion = new Promise((resolve) => {
|
|
461
|
+
resolveSourceData = resolve;
|
|
439
462
|
});
|
|
463
|
+
const onSourceData = (event) => {
|
|
464
|
+
if (event.sourceDataType !== "content") return;
|
|
465
|
+
source.off("data", onSourceData);
|
|
466
|
+
resolveSourceData();
|
|
467
|
+
};
|
|
468
|
+
source.on("data", onSourceData);
|
|
469
|
+
const result = source.setData({
|
|
470
|
+
type: "FeatureCollection",
|
|
471
|
+
features: promotedFeatures
|
|
472
|
+
}, true);
|
|
473
|
+
const supportsCompletionPromise = isPromiseLike(result);
|
|
474
|
+
if (supportsCompletionPromise) source.off("data", onSourceData);
|
|
475
|
+
const completion = supportsCompletionPromise ? Promise.resolve(result) : sourceDataCompletion;
|
|
476
|
+
const pending = {
|
|
477
|
+
completion,
|
|
478
|
+
cancel() {
|
|
479
|
+
source.off("data", onSourceData);
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
this.pendingLayerUpdates.set(layerId, pending);
|
|
483
|
+
completion.catch(() => {});
|
|
484
|
+
}
|
|
485
|
+
flushDeferredLayerRemoval(layerId, deferred) {
|
|
486
|
+
if (this.deferredLayerRemovals.get(layerId) !== deferred) return;
|
|
487
|
+
this.deferredLayerRemovals.delete(layerId);
|
|
488
|
+
this.updateSourceData(layerId, this.getLayerFeatures(layerId));
|
|
489
|
+
}
|
|
490
|
+
deferLayerRemovalUntilLayerUpdate(layerId, updatedLayerId) {
|
|
491
|
+
const pending = this.pendingLayerUpdates.get(updatedLayerId);
|
|
492
|
+
if (!pending || !this.layers.has(layerId)) return;
|
|
493
|
+
this.deferredLayerRemovals.set(layerId, { after: pending.completion });
|
|
440
494
|
}
|
|
441
495
|
applyIconResources(resources) {
|
|
442
496
|
if (typeof Image === "undefined") return;
|
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.12",
|
|
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/
|
|
41
|
-
"@orbat-mapper/
|
|
40
|
+
"@orbat-mapper/tactical-draw": "^0.2.0-alpha.27",
|
|
41
|
+
"@orbat-mapper/control-measures": "^0.2.0-alpha.16"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"maplibre-gl": ">=4.0.0 <6.0.0"
|