@orbat-mapper/tactical-draw-adapter-maplibre 0.8.0 → 0.8.2
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 +6 -0
- package/dist/index.mjs +67 -30
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -315,6 +315,12 @@ declare class MapLibreAdapter extends BaseMapAdapter<MapLibreLayerHandle, MapLib
|
|
|
315
315
|
* (ADR-0057).
|
|
316
316
|
*/
|
|
317
317
|
private insertionAnchor;
|
|
318
|
+
private unvalidatedStyle;
|
|
319
|
+
private addStyleSource;
|
|
320
|
+
private addStyleLayer;
|
|
321
|
+
private setStyleFilter;
|
|
322
|
+
private setStylePaint;
|
|
323
|
+
private setStyleLayout;
|
|
318
324
|
private toContinuousLng;
|
|
319
325
|
protected createLayer(layerId: LayerId, style?: StyleOptions): MapLibreLayerHandle;
|
|
320
326
|
protected destroyLayer(handle: MapLibreLayerHandle): void;
|
package/dist/index.mjs
CHANGED
|
@@ -1486,6 +1486,12 @@ function buildIconSizing(props) {
|
|
|
1486
1486
|
const FILL_PATTERN_IMAGE_ID_PROPERTY = "_fillPatternImageId";
|
|
1487
1487
|
const DEFAULT_LINE_COLOR = "#000";
|
|
1488
1488
|
const DEFAULT_LINE_WIDTH = 2;
|
|
1489
|
+
/**
|
|
1490
|
+
* MapLibre validates each style mutation against a fresh serialization of the
|
|
1491
|
+
* whole style, making bulk adds O(N²) (#569). The adapter builds every source,
|
|
1492
|
+
* layer, and property value itself, so it skips that validation.
|
|
1493
|
+
*/
|
|
1494
|
+
const UNVALIDATED = { validate: false };
|
|
1489
1495
|
function isHatchPattern(value) {
|
|
1490
1496
|
return HATCH_PATTERNS.includes(value);
|
|
1491
1497
|
}
|
|
@@ -2194,19 +2200,50 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2194
2200
|
insertionAnchor(handle, draped) {
|
|
2195
2201
|
return this.terrainActive && !draped ? handle.overlayAnchorId : handle.mlLayerIds[0];
|
|
2196
2202
|
}
|
|
2203
|
+
unvalidatedStyle() {
|
|
2204
|
+
const style = this.map.style;
|
|
2205
|
+
return typeof style?.addSource === "function" && typeof style.addLayer === "function" && typeof this.map._update === "function" ? style : void 0;
|
|
2206
|
+
}
|
|
2207
|
+
addStyleSource(id, source) {
|
|
2208
|
+
const style = this.unvalidatedStyle();
|
|
2209
|
+
if (!style) {
|
|
2210
|
+
this.map.addSource(id, source);
|
|
2211
|
+
return;
|
|
2212
|
+
}
|
|
2213
|
+
style.addSource(id, source, UNVALIDATED);
|
|
2214
|
+
this.map._update(true);
|
|
2215
|
+
}
|
|
2216
|
+
addStyleLayer(layer, beforeId) {
|
|
2217
|
+
const style = this.unvalidatedStyle();
|
|
2218
|
+
if (!style) {
|
|
2219
|
+
this.map.addLayer(layer, beforeId);
|
|
2220
|
+
return;
|
|
2221
|
+
}
|
|
2222
|
+
style.addLayer(layer, beforeId, UNVALIDATED);
|
|
2223
|
+
this.map._update(true);
|
|
2224
|
+
}
|
|
2225
|
+
setStyleFilter(layerId, filter) {
|
|
2226
|
+
this.map.setFilter(layerId, filter, UNVALIDATED);
|
|
2227
|
+
}
|
|
2228
|
+
setStylePaint(layerId, name, value) {
|
|
2229
|
+
this.map.setPaintProperty(layerId, name, value, UNVALIDATED);
|
|
2230
|
+
}
|
|
2231
|
+
setStyleLayout(layerId, name, value) {
|
|
2232
|
+
this.map.setLayoutProperty(layerId, name, value, UNVALIDATED);
|
|
2233
|
+
}
|
|
2197
2234
|
toContinuousLng(lng) {
|
|
2198
2235
|
return nearestWorldCopyLng(lng, this.map.getCenter().lng);
|
|
2199
2236
|
}
|
|
2200
2237
|
createLayer(layerId, style) {
|
|
2201
2238
|
const sourceId = `${layerId}-src`;
|
|
2202
|
-
this.
|
|
2239
|
+
this.addStyleSource(sourceId, {
|
|
2203
2240
|
type: "geojson",
|
|
2204
2241
|
data: emptyFC(),
|
|
2205
2242
|
promoteId: "_fid"
|
|
2206
2243
|
});
|
|
2207
2244
|
const mlLayerIds = [];
|
|
2208
2245
|
const fillId = `${layerId}-fill`;
|
|
2209
|
-
this.
|
|
2246
|
+
this.addStyleLayer(hiddenLayer({
|
|
2210
2247
|
id: fillId,
|
|
2211
2248
|
type: "fill",
|
|
2212
2249
|
source: sourceId,
|
|
@@ -2215,7 +2252,7 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2215
2252
|
}));
|
|
2216
2253
|
mlLayerIds.push(fillId);
|
|
2217
2254
|
const fillPatternId = `${layerId}-fill-pattern`;
|
|
2218
|
-
this.
|
|
2255
|
+
this.addStyleLayer(hiddenLayer({
|
|
2219
2256
|
id: fillPatternId,
|
|
2220
2257
|
type: "fill",
|
|
2221
2258
|
source: sourceId,
|
|
@@ -2224,7 +2261,7 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2224
2261
|
}));
|
|
2225
2262
|
mlLayerIds.push(fillPatternId);
|
|
2226
2263
|
const lineId = `${layerId}-line`;
|
|
2227
|
-
this.
|
|
2264
|
+
this.addStyleLayer(hiddenLayer({
|
|
2228
2265
|
id: lineId,
|
|
2229
2266
|
type: "line",
|
|
2230
2267
|
source: sourceId,
|
|
@@ -2249,7 +2286,7 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2249
2286
|
}));
|
|
2250
2287
|
mlLayerIds.push(lineId);
|
|
2251
2288
|
const circleId = `${layerId}-circle`;
|
|
2252
|
-
this.
|
|
2289
|
+
this.addStyleLayer(hiddenLayer({
|
|
2253
2290
|
id: circleId,
|
|
2254
2291
|
type: "circle",
|
|
2255
2292
|
source: sourceId,
|
|
@@ -2258,11 +2295,11 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2258
2295
|
}));
|
|
2259
2296
|
mlLayerIds.push(circleId);
|
|
2260
2297
|
const iconId = `${layerId}-icon`;
|
|
2261
|
-
this.
|
|
2298
|
+
this.addStyleLayer(hiddenLayer(buildIconLayer(iconId, sourceId)));
|
|
2262
2299
|
mlLayerIds.push(iconId);
|
|
2263
2300
|
if (style?.text) {
|
|
2264
2301
|
const symbolId = `${layerId}-symbol`;
|
|
2265
|
-
this.
|
|
2302
|
+
this.addStyleLayer(hiddenLayer(buildSymbolLayer(symbolId, sourceId, style.text)));
|
|
2266
2303
|
mlLayerIds.push(symbolId);
|
|
2267
2304
|
}
|
|
2268
2305
|
return {
|
|
@@ -2384,7 +2421,7 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2384
2421
|
}
|
|
2385
2422
|
createGroupBundle(layerId, handle) {
|
|
2386
2423
|
const sourceId = `${layerId}-group-${++handle.nextGroupBundleId}-src`;
|
|
2387
|
-
this.
|
|
2424
|
+
this.addStyleSource(sourceId, {
|
|
2388
2425
|
type: "geojson",
|
|
2389
2426
|
data: emptyFC(),
|
|
2390
2427
|
promoteId: "_fid"
|
|
@@ -2428,12 +2465,12 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2428
2465
|
const suffix = `${bundle.sourceId}-${encodeURIComponent(overlay.id)}`;
|
|
2429
2466
|
const sourceId = `${suffix}-image-src`;
|
|
2430
2467
|
const layerId = `${suffix}-image`;
|
|
2431
|
-
this.
|
|
2468
|
+
this.addStyleSource(sourceId, {
|
|
2432
2469
|
type: "image",
|
|
2433
2470
|
url,
|
|
2434
2471
|
coordinates: overlay.coordinates
|
|
2435
2472
|
});
|
|
2436
|
-
this.
|
|
2473
|
+
this.addStyleLayer({
|
|
2437
2474
|
id: layerId,
|
|
2438
2475
|
type: "raster",
|
|
2439
2476
|
source: sourceId,
|
|
@@ -2459,7 +2496,7 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2459
2496
|
coordinates: overlay.coordinates.map((point) => [...point])
|
|
2460
2497
|
});
|
|
2461
2498
|
else if (coordinatesChanged) source?.setCoordinates?.(overlay.coordinates.map((point) => [...point]));
|
|
2462
|
-
if (opacityChanged) this.
|
|
2499
|
+
if (opacityChanged) this.setStylePaint(existing.layerId, "raster-opacity", overlay.opacity);
|
|
2463
2500
|
existing.url = url;
|
|
2464
2501
|
existing.opacity = overlay.opacity;
|
|
2465
2502
|
existing.coordinates = overlay.coordinates;
|
|
@@ -2513,7 +2550,7 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2513
2550
|
featureId
|
|
2514
2551
|
]
|
|
2515
2552
|
};
|
|
2516
|
-
this.
|
|
2553
|
+
this.addStyleLayer(layer, this.insertionAnchor(handle, isDrapedChannel(channel)));
|
|
2517
2554
|
bundle.paintSurfaces.set(key, {
|
|
2518
2555
|
layerId,
|
|
2519
2556
|
channel,
|
|
@@ -2532,17 +2569,17 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2532
2569
|
surface.sizingKey = sizingKey;
|
|
2533
2570
|
if (channel === "icon") {
|
|
2534
2571
|
const size = buildIconSizing(props);
|
|
2535
|
-
if (size !== void 0) this.
|
|
2572
|
+
if (size !== void 0) this.setStyleLayout(surface.layerId, "icon-size", size);
|
|
2536
2573
|
return;
|
|
2537
2574
|
}
|
|
2538
2575
|
const next = buildTextSizing(style.text, props);
|
|
2539
2576
|
const previous = surface.textSizing;
|
|
2540
|
-
if (JSON.stringify(previous?.size) !== JSON.stringify(next.size)) this.
|
|
2577
|
+
if (JSON.stringify(previous?.size) !== JSON.stringify(next.size)) this.setStyleLayout(surface.layerId, "text-size", next.size);
|
|
2541
2578
|
for (const [key, property] of [
|
|
2542
2579
|
["haloWidth", "text-halo-width"],
|
|
2543
2580
|
["haloBlur", "text-halo-blur"],
|
|
2544
2581
|
["opacity", "text-opacity"]
|
|
2545
|
-
]) if (JSON.stringify(previous?.[key]) !== JSON.stringify(next[key])) this.
|
|
2582
|
+
]) if (JSON.stringify(previous?.[key]) !== JSON.stringify(next[key])) this.setStylePaint(surface.layerId, property, next[key]);
|
|
2546
2583
|
surface.textSizing = next;
|
|
2547
2584
|
}
|
|
2548
2585
|
buildGroupLayer(id, sourceId, channel, style, textSizing, iconSizing) {
|
|
@@ -2887,7 +2924,7 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2887
2924
|
for (const bundle of handle.groupBundles.values()) for (const surface of bundle.paintSurfaces.values()) this.applyChannelStyle(surface.layerId, surface.channel, style, resolvedStyle, surface.featureId);
|
|
2888
2925
|
if (style.text && !handle.mlLayerIds.some((id) => id.endsWith("-symbol"))) {
|
|
2889
2926
|
const symbolId = `${layerId}-symbol`;
|
|
2890
|
-
this.
|
|
2927
|
+
this.addStyleLayer(hiddenLayer(buildSymbolLayer(symbolId, handle.sourceId, resolvedStyle.text)));
|
|
2891
2928
|
handle.mlLayerIds.push(symbolId);
|
|
2892
2929
|
}
|
|
2893
2930
|
}
|
|
@@ -2904,24 +2941,24 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2904
2941
|
switch (channel) {
|
|
2905
2942
|
case "fill":
|
|
2906
2943
|
if (styleUpdate.fillColor === void 0) break;
|
|
2907
|
-
this.
|
|
2944
|
+
this.setStylePaint(layerId, "fill-color", buildFillPaint(resolvedStyle)["fill-color"]);
|
|
2908
2945
|
break;
|
|
2909
2946
|
case "fill-pattern": break;
|
|
2910
2947
|
case "line": {
|
|
2911
2948
|
const paint = buildLinePaint(resolvedStyle);
|
|
2912
|
-
if (styleUpdate.strokeColor !== void 0) this.
|
|
2913
|
-
if (styleUpdate.strokeWidth !== void 0) this.
|
|
2914
|
-
if (styleUpdate.strokeDash !== void 0) this.
|
|
2949
|
+
if (styleUpdate.strokeColor !== void 0) this.setStylePaint(layerId, "line-color", paint["line-color"]);
|
|
2950
|
+
if (styleUpdate.strokeWidth !== void 0) this.setStylePaint(layerId, "line-width", paint["line-width"]);
|
|
2951
|
+
if (styleUpdate.strokeDash !== void 0) this.setStylePaint(layerId, "line-dasharray", paint["line-dasharray"]);
|
|
2915
2952
|
break;
|
|
2916
2953
|
}
|
|
2917
2954
|
case "circle": {
|
|
2918
2955
|
if (!(styleUpdate.pointRadius !== void 0 || styleUpdate.pointFillColor !== void 0 || styleUpdate.fillColor !== void 0 || styleUpdate.strokeColor !== void 0 || styleUpdate.strokeWidth !== void 0 || styleUpdate.text !== void 0)) break;
|
|
2919
2956
|
const paint = buildCirclePaint(resolvedStyle);
|
|
2920
|
-
this.
|
|
2921
|
-
this.
|
|
2922
|
-
this.
|
|
2923
|
-
this.
|
|
2924
|
-
this.
|
|
2957
|
+
this.setStylePaint(layerId, "circle-radius", paint["circle-radius"]);
|
|
2958
|
+
this.setStylePaint(layerId, "circle-color", paint["circle-color"]);
|
|
2959
|
+
this.setStylePaint(layerId, "circle-stroke-color", paint["circle-stroke-color"]);
|
|
2960
|
+
this.setStylePaint(layerId, "circle-stroke-width", paint["circle-stroke-width"]);
|
|
2961
|
+
this.setStyleFilter(layerId, featureId === void 0 ? buildCirclePointFilter(resolvedStyle) : [
|
|
2925
2962
|
"==",
|
|
2926
2963
|
"_fid",
|
|
2927
2964
|
featureId
|
|
@@ -2931,13 +2968,13 @@ var MapLibreAdapter = class extends BaseMapAdapter {
|
|
|
2931
2968
|
case "icon": break;
|
|
2932
2969
|
case "text":
|
|
2933
2970
|
if (!styleUpdate.text || !resolvedStyle.text) break;
|
|
2934
|
-
if (styleUpdate.text.text || styleUpdate.text.labelProperty) this.
|
|
2935
|
-
if (styleUpdate.text.fillColor) this.
|
|
2936
|
-
if (styleUpdate.text.strokeColor) this.
|
|
2971
|
+
if (styleUpdate.text.text || styleUpdate.text.labelProperty) this.setStyleLayout(layerId, "text-field", buildTextFieldExpression(resolvedStyle.text));
|
|
2972
|
+
if (styleUpdate.text.fillColor) this.setStylePaint(layerId, "text-color", resolvedStyle.text.fillColor);
|
|
2973
|
+
if (styleUpdate.text.strokeColor) this.setStylePaint(layerId, "text-halo-color", buildTextHaloColorExpression(resolvedStyle.text));
|
|
2937
2974
|
if (featureId === void 0) {
|
|
2938
2975
|
const sizing = buildTextSizing(resolvedStyle.text, null);
|
|
2939
|
-
this.
|
|
2940
|
-
this.
|
|
2976
|
+
this.setStylePaint(layerId, "text-halo-width", sizing.haloWidth);
|
|
2977
|
+
this.setStylePaint(layerId, "text-halo-blur", sizing.haloBlur);
|
|
2941
2978
|
}
|
|
2942
2979
|
break;
|
|
2943
2980
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orbat-mapper/tactical-draw-adapter-maplibre",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
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.
|
|
41
|
-
"@orbat-mapper/tactical-draw": "^0.
|
|
40
|
+
"@orbat-mapper/control-measures": "^0.32.0",
|
|
41
|
+
"@orbat-mapper/tactical-draw": "^0.13.2"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"maplibre-gl": ">=5.8.0 <7.0.0"
|