aur-openlayers 19.6.4 → 19.6.5
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/fesm2022/aur-openlayers.mjs +150 -3
- package/fesm2022/aur-openlayers.mjs.map +1 -1
- package/lib/map-framework/public/types.d.ts +39 -0
- package/lib/map-framework/runtime/decorations/arrow-decoration-manager.d.ts +27 -0
- package/lib/map-framework/runtime/layer-manager.d.ts +1 -0
- package/package.json +1 -1
|
@@ -9,6 +9,8 @@ import Collection from 'ol/Collection';
|
|
|
9
9
|
import DragPan from 'ol/interaction/DragPan';
|
|
10
10
|
import Modify from 'ol/interaction/Modify';
|
|
11
11
|
import * as Observable from 'ol/Observable';
|
|
12
|
+
import { unByKey } from 'ol/Observable';
|
|
13
|
+
import { LineString, MultiLineString, Point } from 'ol/geom';
|
|
12
14
|
|
|
13
15
|
class LibService {
|
|
14
16
|
constructor() { }
|
|
@@ -1585,7 +1587,7 @@ class StyleCache {
|
|
|
1585
1587
|
}
|
|
1586
1588
|
}
|
|
1587
1589
|
|
|
1588
|
-
const resolveMaybeFn = (value, args) => {
|
|
1590
|
+
const resolveMaybeFn$1 = (value, args) => {
|
|
1589
1591
|
if (typeof value === 'function') {
|
|
1590
1592
|
return value(...args);
|
|
1591
1593
|
}
|
|
@@ -1620,7 +1622,7 @@ const createStyleFunction = (options) => {
|
|
|
1620
1622
|
resolution,
|
|
1621
1623
|
zoom: map?.getView().getZoom(),
|
|
1622
1624
|
};
|
|
1623
|
-
let opts = resolveMaybeFn(style.base, [model, view]);
|
|
1625
|
+
let opts = resolveMaybeFn$1(style.base, [model, view]);
|
|
1624
1626
|
if (style.states) {
|
|
1625
1627
|
const featureStates = orderStates(getFeatureStates(feature), style.statePriority);
|
|
1626
1628
|
featureStates.forEach((state) => {
|
|
@@ -1628,7 +1630,7 @@ const createStyleFunction = (options) => {
|
|
|
1628
1630
|
if (!patchFactory) {
|
|
1629
1631
|
return;
|
|
1630
1632
|
}
|
|
1631
|
-
const patch = resolveMaybeFn(patchFactory, [model, view]);
|
|
1633
|
+
const patch = resolveMaybeFn$1(patchFactory, [model, view]);
|
|
1632
1634
|
opts = applyPatch(opts, patch);
|
|
1633
1635
|
});
|
|
1634
1636
|
}
|
|
@@ -2292,6 +2294,140 @@ class PopupHost {
|
|
|
2292
2294
|
}
|
|
2293
2295
|
}
|
|
2294
2296
|
|
|
2297
|
+
const resolveMaybeFn = (value, args) => typeof value === 'function' ? value(...args) : value;
|
|
2298
|
+
/**
|
|
2299
|
+
* Extracts flat coordinate arrays from a feature's geometry.
|
|
2300
|
+
* Supports LineString and MultiLineString; returns empty array for others.
|
|
2301
|
+
*/
|
|
2302
|
+
function extractLineCoords(geometry) {
|
|
2303
|
+
if (geometry instanceof LineString) {
|
|
2304
|
+
return [geometry.getCoordinates()];
|
|
2305
|
+
}
|
|
2306
|
+
if (geometry instanceof MultiLineString) {
|
|
2307
|
+
return geometry.getCoordinates();
|
|
2308
|
+
}
|
|
2309
|
+
return [];
|
|
2310
|
+
}
|
|
2311
|
+
/**
|
|
2312
|
+
* Generate arrow points along a polyline at a given interval (meters in EPSG:3857).
|
|
2313
|
+
*/
|
|
2314
|
+
function generateArrowPoints(coords, intervalMeters, offsetRatio) {
|
|
2315
|
+
if (coords.length < 2 || intervalMeters <= 0)
|
|
2316
|
+
return [];
|
|
2317
|
+
const arrows = [];
|
|
2318
|
+
let accumulated = intervalMeters * offsetRatio;
|
|
2319
|
+
for (let i = 0; i < coords.length - 1; i++) {
|
|
2320
|
+
const ax = coords[i][0], ay = coords[i][1];
|
|
2321
|
+
const bx = coords[i + 1][0], by = coords[i + 1][1];
|
|
2322
|
+
const segLen = Math.hypot(bx - ax, by - ay);
|
|
2323
|
+
const rotation = Math.atan2(bx - ax, by - ay);
|
|
2324
|
+
while (accumulated <= segLen) {
|
|
2325
|
+
const t = accumulated / segLen;
|
|
2326
|
+
arrows.push({
|
|
2327
|
+
coordinate: [ax + t * (bx - ax), ay + t * (by - ay)],
|
|
2328
|
+
rotation,
|
|
2329
|
+
});
|
|
2330
|
+
accumulated += intervalMeters;
|
|
2331
|
+
}
|
|
2332
|
+
accumulated -= segLen;
|
|
2333
|
+
}
|
|
2334
|
+
return arrows;
|
|
2335
|
+
}
|
|
2336
|
+
class ArrowDecorationManager {
|
|
2337
|
+
source = new VectorSource();
|
|
2338
|
+
layer;
|
|
2339
|
+
config;
|
|
2340
|
+
map;
|
|
2341
|
+
parentLayer;
|
|
2342
|
+
parentApi;
|
|
2343
|
+
moveEndKey;
|
|
2344
|
+
unsubCollection;
|
|
2345
|
+
unsubChanges;
|
|
2346
|
+
rafId = null;
|
|
2347
|
+
constructor(options) {
|
|
2348
|
+
this.config = options.config;
|
|
2349
|
+
this.map = options.map;
|
|
2350
|
+
this.parentLayer = options.parentLayer;
|
|
2351
|
+
this.parentApi = options.parentApi;
|
|
2352
|
+
const parentZ = this.parentLayer.getZIndex() ?? 0;
|
|
2353
|
+
this.layer = new VectorLayer({
|
|
2354
|
+
source: this.source,
|
|
2355
|
+
zIndex: parentZ + 1,
|
|
2356
|
+
});
|
|
2357
|
+
this.layer.set('id', `__decoration_arrows`);
|
|
2358
|
+
this.map.addLayer(this.layer);
|
|
2359
|
+
this.syncVisibility();
|
|
2360
|
+
this.syncOpacity();
|
|
2361
|
+
this.moveEndKey = this.map.on('moveend', () => this.scheduleUpdate());
|
|
2362
|
+
this.unsubCollection = this.parentApi.onModelsCollectionChanged(() => this.scheduleUpdate());
|
|
2363
|
+
this.unsubChanges = this.parentApi.onModelsChanged?.(() => this.scheduleUpdate());
|
|
2364
|
+
}
|
|
2365
|
+
scheduleUpdate() {
|
|
2366
|
+
if (this.rafId !== null)
|
|
2367
|
+
return;
|
|
2368
|
+
this.rafId = requestAnimationFrame(() => {
|
|
2369
|
+
this.rafId = null;
|
|
2370
|
+
this.rebuild();
|
|
2371
|
+
});
|
|
2372
|
+
}
|
|
2373
|
+
rebuild() {
|
|
2374
|
+
this.syncVisibility();
|
|
2375
|
+
this.syncOpacity();
|
|
2376
|
+
if (!this.parentLayer.getVisible()) {
|
|
2377
|
+
this.source.clear();
|
|
2378
|
+
return;
|
|
2379
|
+
}
|
|
2380
|
+
const view = this.map.getView();
|
|
2381
|
+
const resolution = view.getResolution() ?? 1;
|
|
2382
|
+
const styleView = { resolution, zoom: view.getZoom() };
|
|
2383
|
+
const interval = resolveMaybeFn(this.config.interval, [styleView]);
|
|
2384
|
+
const offsetRatio = this.config.offsetRatio ?? 0.5;
|
|
2385
|
+
const parentSource = this.parentLayer.getSource();
|
|
2386
|
+
if (!parentSource) {
|
|
2387
|
+
this.source.clear();
|
|
2388
|
+
return;
|
|
2389
|
+
}
|
|
2390
|
+
const allArrows = [];
|
|
2391
|
+
parentSource.getFeatures().forEach((feature) => {
|
|
2392
|
+
const geom = feature.getGeometry();
|
|
2393
|
+
if (!geom)
|
|
2394
|
+
return;
|
|
2395
|
+
const lines = extractLineCoords(geom);
|
|
2396
|
+
for (const coords of lines) {
|
|
2397
|
+
const arrows = generateArrowPoints(coords, interval, offsetRatio);
|
|
2398
|
+
allArrows.push(...arrows);
|
|
2399
|
+
}
|
|
2400
|
+
});
|
|
2401
|
+
const features = allArrows.map((arrow, i) => {
|
|
2402
|
+
const f = new Feature({ geometry: new Point(arrow.coordinate) });
|
|
2403
|
+
f.setId(`__arrow_${i}`);
|
|
2404
|
+
const styleResult = this.config.style({ rotation: arrow.rotation, view: styleView });
|
|
2405
|
+
f.setStyle(Array.isArray(styleResult) ? styleResult : [styleResult]);
|
|
2406
|
+
return f;
|
|
2407
|
+
});
|
|
2408
|
+
this.source.clear();
|
|
2409
|
+
if (features.length > 0) {
|
|
2410
|
+
this.source.addFeatures(features);
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
syncVisibility() {
|
|
2414
|
+
this.layer.setVisible(this.parentLayer.getVisible());
|
|
2415
|
+
}
|
|
2416
|
+
syncOpacity() {
|
|
2417
|
+
this.layer.setOpacity(this.parentLayer.getOpacity());
|
|
2418
|
+
}
|
|
2419
|
+
dispose() {
|
|
2420
|
+
if (this.rafId !== null) {
|
|
2421
|
+
cancelAnimationFrame(this.rafId);
|
|
2422
|
+
this.rafId = null;
|
|
2423
|
+
}
|
|
2424
|
+
unByKey(this.moveEndKey);
|
|
2425
|
+
this.unsubCollection();
|
|
2426
|
+
this.unsubChanges?.();
|
|
2427
|
+
this.map.removeLayer(this.layer);
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2295
2431
|
class LayerManager {
|
|
2296
2432
|
map;
|
|
2297
2433
|
layers = {};
|
|
@@ -2300,6 +2436,7 @@ class LayerManager {
|
|
|
2300
2436
|
scheduler;
|
|
2301
2437
|
popupHost;
|
|
2302
2438
|
ctx;
|
|
2439
|
+
decorationManagers = [];
|
|
2303
2440
|
constructor(map, schema) {
|
|
2304
2441
|
this.map = map;
|
|
2305
2442
|
const popupHost = schema.options?.popupHost ? new PopupHost(schema.options.popupHost) : undefined;
|
|
@@ -2347,6 +2484,15 @@ class LayerManager {
|
|
|
2347
2484
|
this.layers[descriptor.id] = layer;
|
|
2348
2485
|
this.apis[descriptor.id] = api;
|
|
2349
2486
|
this.map.addLayer(layer);
|
|
2487
|
+
if (descriptor.feature.decorations?.arrows) {
|
|
2488
|
+
const decorationManager = new ArrowDecorationManager({
|
|
2489
|
+
map: this.map,
|
|
2490
|
+
parentLayer: layer,
|
|
2491
|
+
parentApi: api,
|
|
2492
|
+
config: descriptor.feature.decorations.arrows,
|
|
2493
|
+
});
|
|
2494
|
+
this.decorationManagers.push(decorationManager);
|
|
2495
|
+
}
|
|
2350
2496
|
});
|
|
2351
2497
|
this.interactions = new InteractionManager({
|
|
2352
2498
|
ctx,
|
|
@@ -2378,6 +2524,7 @@ class LayerManager {
|
|
|
2378
2524
|
this.interactions.dispose();
|
|
2379
2525
|
this.popupHost?.dispose();
|
|
2380
2526
|
this.scheduler.dispose();
|
|
2527
|
+
this.decorationManagers.forEach((dm) => dm.dispose());
|
|
2381
2528
|
Object.values(this.layers).forEach((layer) => this.map.removeLayer(layer));
|
|
2382
2529
|
}
|
|
2383
2530
|
}
|