@angular-helpers/openlayers 0.4.0 → 0.5.0
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/README.md +14 -6
- package/fesm2022/angular-helpers-openlayers-controls.mjs +289 -36
- package/fesm2022/angular-helpers-openlayers-core.mjs +197 -16
- package/fesm2022/angular-helpers-openlayers-interactions.mjs +414 -23
- package/fesm2022/angular-helpers-openlayers-layers.mjs +634 -83
- package/fesm2022/angular-helpers-openlayers-military.mjs +244 -144
- package/fesm2022/angular-helpers-openlayers-overlays.mjs +9 -9
- package/package.json +2 -2
- package/types/angular-helpers-openlayers-controls.d.ts +24 -4
- package/types/angular-helpers-openlayers-core.d.ts +126 -4
- package/types/angular-helpers-openlayers-interactions.d.ts +120 -23
- package/types/angular-helpers-openlayers-layers.d.ts +152 -7
- package/types/angular-helpers-openlayers-military.d.ts +84 -94
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, computed, Injectable, inject } from '@angular/core';
|
|
2
|
+
import { signal, computed, Injectable, inject, DestroyRef, input, effect, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
import { OlMapService, OlZoneHelper } from '@angular-helpers/openlayers/core';
|
|
4
4
|
import { Subject } from 'rxjs';
|
|
5
5
|
import Select from 'ol/interaction/Select';
|
|
6
|
+
import { pointerMove, click } from 'ol/events/condition';
|
|
6
7
|
import Draw from 'ol/interaction/Draw';
|
|
7
8
|
import Snap from 'ol/interaction/Snap';
|
|
8
9
|
import VectorSource from 'ol/source/Vector';
|
|
10
|
+
import { Polygon, LineString } from 'ol/geom';
|
|
9
11
|
import { OlLayerService } from '@angular-helpers/openlayers/layers';
|
|
10
12
|
import Modify from 'ol/interaction/Modify';
|
|
13
|
+
import VectorLayer from 'ol/layer/Vector';
|
|
14
|
+
import Overlay from 'ol/Overlay';
|
|
15
|
+
import { getLength, getArea } from 'ol/sphere';
|
|
16
|
+
import { unByKey } from 'ol/Observable';
|
|
17
|
+
import { Style, Circle, Fill, Stroke } from 'ol/style';
|
|
18
|
+
import { outputFromObservable } from '@angular/core/rxjs-interop';
|
|
19
|
+
import { filter } from 'rxjs/operators';
|
|
11
20
|
|
|
12
21
|
// Interaction state management service
|
|
13
22
|
/**
|
|
@@ -22,6 +31,7 @@ class InteractionStateService {
|
|
|
22
31
|
drawStartSubject = new Subject();
|
|
23
32
|
drawEndSubject = new Subject();
|
|
24
33
|
modifySubject = new Subject();
|
|
34
|
+
selectSubject = new Subject();
|
|
25
35
|
// Public readonly signals
|
|
26
36
|
selectedFeatures = computed(() => this.selectedFeaturesInternal(), ...(ngDevMode ? [{ debugName: "selectedFeatures" }] : /* istanbul ignore next */ []));
|
|
27
37
|
selectionCount = computed(() => this.selectedFeaturesInternal().length, ...(ngDevMode ? [{ debugName: "selectionCount" }] : /* istanbul ignore next */ []));
|
|
@@ -31,6 +41,7 @@ class InteractionStateService {
|
|
|
31
41
|
drawStart$ = this.drawStartSubject.asObservable();
|
|
32
42
|
drawEnd$ = this.drawEndSubject.asObservable();
|
|
33
43
|
modify$ = this.modifySubject.asObservable();
|
|
44
|
+
select$ = this.selectSubject.asObservable();
|
|
34
45
|
/**
|
|
35
46
|
* Adds a managed interaction to the state.
|
|
36
47
|
* If the interaction is marked as exclusive, it disables other exclusive interactions.
|
|
@@ -105,6 +116,13 @@ class InteractionStateService {
|
|
|
105
116
|
emitModify(event) {
|
|
106
117
|
this.modifySubject.next(event);
|
|
107
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Emits a select event.
|
|
121
|
+
* @param event - The select event data
|
|
122
|
+
*/
|
|
123
|
+
emitSelect(event) {
|
|
124
|
+
this.selectSubject.next(event);
|
|
125
|
+
}
|
|
108
126
|
/**
|
|
109
127
|
* Gets the current interaction state summary.
|
|
110
128
|
* @returns Array of interaction state objects
|
|
@@ -133,10 +151,10 @@ class InteractionStateService {
|
|
|
133
151
|
this.interactions.set([]);
|
|
134
152
|
this.selectedFeaturesInternal.set([]);
|
|
135
153
|
}
|
|
136
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
137
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
154
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: InteractionStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
155
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: InteractionStateService });
|
|
138
156
|
}
|
|
139
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
157
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: InteractionStateService, decorators: [{
|
|
140
158
|
type: Injectable
|
|
141
159
|
}] });
|
|
142
160
|
|
|
@@ -206,16 +224,22 @@ class SelectInteractionService {
|
|
|
206
224
|
: undefined,
|
|
207
225
|
multi: config.multi ?? false,
|
|
208
226
|
hitTolerance: config.hitTolerance ?? 0,
|
|
227
|
+
condition: config.condition === 'pointerMove' ? pointerMove : click,
|
|
209
228
|
});
|
|
210
229
|
// Listen to selection changes — use getFeatures().getArray() for the full
|
|
211
230
|
// accumulated collection, not e.selected which only contains newly added ones
|
|
212
|
-
select.on('select', (
|
|
231
|
+
select.on('select', (e) => {
|
|
213
232
|
this.zoneHelper.runInsideAngular(() => {
|
|
214
233
|
const allSelected = select
|
|
215
234
|
.getFeatures()
|
|
216
235
|
.getArray()
|
|
217
236
|
.map((f) => olFeatureToFeature(f));
|
|
218
237
|
this.stateService.setSelectedFeatures(allSelected);
|
|
238
|
+
this.stateService.emitSelect({
|
|
239
|
+
interactionId: id,
|
|
240
|
+
selected: e.selected.map((f) => olFeatureToFeature(f)),
|
|
241
|
+
deselected: e.deselected.map((f) => olFeatureToFeature(f)),
|
|
242
|
+
});
|
|
219
243
|
});
|
|
220
244
|
});
|
|
221
245
|
map.addInteraction(select);
|
|
@@ -232,10 +256,10 @@ class SelectInteractionService {
|
|
|
232
256
|
this.stateService.addInteraction(managed);
|
|
233
257
|
});
|
|
234
258
|
}
|
|
235
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
236
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
259
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: SelectInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
260
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: SelectInteractionService });
|
|
237
261
|
}
|
|
238
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
262
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: SelectInteractionService, decorators: [{
|
|
239
263
|
type: Injectable
|
|
240
264
|
}] });
|
|
241
265
|
|
|
@@ -267,9 +291,69 @@ class DrawInteractionService {
|
|
|
267
291
|
source = new VectorSource();
|
|
268
292
|
}
|
|
269
293
|
this.zoneHelper.runOutsideAngular(() => {
|
|
294
|
+
let drawType = config.type;
|
|
295
|
+
let geometryFunction;
|
|
296
|
+
if (config.type === 'Ellipse') {
|
|
297
|
+
drawType = 'Circle';
|
|
298
|
+
geometryFunction = (coords, geom) => {
|
|
299
|
+
if (!geom) {
|
|
300
|
+
geom = new Polygon([]);
|
|
301
|
+
}
|
|
302
|
+
const center = coords[0];
|
|
303
|
+
const last = coords[1];
|
|
304
|
+
const dx = last[0] - center[0];
|
|
305
|
+
const dy = last[1] - center[1];
|
|
306
|
+
const semiMajor = Math.sqrt(dx * dx + dy * dy);
|
|
307
|
+
const semiMinor = semiMajor * 0.7; // Default ratio
|
|
308
|
+
const rotation = Math.atan2(dy, dx);
|
|
309
|
+
const ring = [];
|
|
310
|
+
const segments = 64;
|
|
311
|
+
for (let i = 0; i < segments; i++) {
|
|
312
|
+
const theta = (i / segments) * Math.PI * 2;
|
|
313
|
+
const ax = Math.cos(theta) * semiMajor;
|
|
314
|
+
const ay = Math.sin(theta) * semiMinor;
|
|
315
|
+
const rx = ax * Math.cos(rotation) - ay * Math.sin(rotation);
|
|
316
|
+
const ry = ax * Math.sin(rotation) + ay * Math.cos(rotation);
|
|
317
|
+
ring.push([center[0] + rx, center[1] + ry]);
|
|
318
|
+
}
|
|
319
|
+
ring.push(ring[0]);
|
|
320
|
+
geom.setCoordinates([ring]);
|
|
321
|
+
return geom;
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
else if (config.type === 'Donut') {
|
|
325
|
+
drawType = 'Circle';
|
|
326
|
+
geometryFunction = (coords, geom) => {
|
|
327
|
+
if (!geom) {
|
|
328
|
+
geom = new Polygon([]);
|
|
329
|
+
}
|
|
330
|
+
const center = coords[0];
|
|
331
|
+
const last = coords[1];
|
|
332
|
+
const dx = last[0] - center[0];
|
|
333
|
+
const dy = last[1] - center[1];
|
|
334
|
+
const outerRadius = Math.sqrt(dx * dx + dy * dy);
|
|
335
|
+
const innerRadius = outerRadius * 0.6; // Default ratio
|
|
336
|
+
const outer = [];
|
|
337
|
+
const inner = [];
|
|
338
|
+
const segments = 64;
|
|
339
|
+
for (let i = 0; i < segments; i++) {
|
|
340
|
+
const theta = (i / segments) * Math.PI * 2;
|
|
341
|
+
const cosT = Math.cos(theta);
|
|
342
|
+
const sinT = Math.sin(theta);
|
|
343
|
+
outer.push([center[0] + cosT * outerRadius, center[1] + sinT * outerRadius]);
|
|
344
|
+
inner.push([center[0] + cosT * innerRadius, center[1] + sinT * innerRadius]);
|
|
345
|
+
}
|
|
346
|
+
inner.reverse();
|
|
347
|
+
outer.push(outer[0]);
|
|
348
|
+
inner.push(inner[0]);
|
|
349
|
+
geom.setCoordinates([outer, inner]);
|
|
350
|
+
return geom;
|
|
351
|
+
};
|
|
352
|
+
}
|
|
270
353
|
const draw = new Draw({
|
|
271
354
|
source,
|
|
272
|
-
type:
|
|
355
|
+
type: drawType,
|
|
356
|
+
geometryFunction,
|
|
273
357
|
freehand: config.freehand ?? false,
|
|
274
358
|
snapTolerance: config.snapTolerance ?? 12,
|
|
275
359
|
});
|
|
@@ -278,14 +362,14 @@ class DrawInteractionService {
|
|
|
278
362
|
draw.on('drawstart', (e) => {
|
|
279
363
|
this.zoneHelper.runInsideAngular(() => {
|
|
280
364
|
const feature = olFeatureToFeature(e.feature);
|
|
281
|
-
this.stateService.emitDrawStart({ feature });
|
|
365
|
+
this.stateService.emitDrawStart({ interactionId: id, feature });
|
|
282
366
|
});
|
|
283
367
|
});
|
|
284
368
|
// Handle draw end event
|
|
285
369
|
draw.on('drawend', (e) => {
|
|
286
370
|
this.zoneHelper.runInsideAngular(() => {
|
|
287
371
|
const feature = olFeatureToFeature(e.feature);
|
|
288
|
-
const event = { feature, type: config.type };
|
|
372
|
+
const event = { interactionId: id, feature, type: config.type };
|
|
289
373
|
this.stateService.emitDrawEnd(event);
|
|
290
374
|
});
|
|
291
375
|
});
|
|
@@ -307,10 +391,10 @@ class DrawInteractionService {
|
|
|
307
391
|
});
|
|
308
392
|
return true;
|
|
309
393
|
}
|
|
310
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
311
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
394
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: DrawInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
395
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: DrawInteractionService });
|
|
312
396
|
}
|
|
313
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
397
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: DrawInteractionService, decorators: [{
|
|
314
398
|
type: Injectable
|
|
315
399
|
}] });
|
|
316
400
|
|
|
@@ -348,7 +432,7 @@ class ModifyInteractionService {
|
|
|
348
432
|
modify.on('modifystart', (e) => {
|
|
349
433
|
this.zoneHelper.runInsideAngular(() => {
|
|
350
434
|
const features = e.features.getArray().map((f) => olFeatureToFeature(f));
|
|
351
|
-
const event = { features, type: 'modifystart' };
|
|
435
|
+
const event = { interactionId: id, features, type: 'modifystart' };
|
|
352
436
|
this.stateService.emitModify(event);
|
|
353
437
|
});
|
|
354
438
|
});
|
|
@@ -356,7 +440,7 @@ class ModifyInteractionService {
|
|
|
356
440
|
modify.on('modifyend', (e) => {
|
|
357
441
|
this.zoneHelper.runInsideAngular(() => {
|
|
358
442
|
const features = e.features.getArray().map((f) => olFeatureToFeature(f));
|
|
359
|
-
const event = { features, type: 'modifyend' };
|
|
443
|
+
const event = { interactionId: id, features, type: 'modifyend' };
|
|
360
444
|
this.stateService.emitModify(event);
|
|
361
445
|
});
|
|
362
446
|
});
|
|
@@ -377,10 +461,10 @@ class ModifyInteractionService {
|
|
|
377
461
|
this.stateService.addInteraction(managed);
|
|
378
462
|
});
|
|
379
463
|
}
|
|
380
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
381
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
464
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ModifyInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
465
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ModifyInteractionService });
|
|
382
466
|
}
|
|
383
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
467
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ModifyInteractionService, decorators: [{
|
|
384
468
|
type: Injectable
|
|
385
469
|
}] });
|
|
386
470
|
|
|
@@ -419,6 +503,7 @@ class OlInteractionService {
|
|
|
419
503
|
drawStart$ = this.stateService.drawStart$;
|
|
420
504
|
drawEnd$ = this.stateService.drawEnd$;
|
|
421
505
|
modify$ = this.stateService.modify$;
|
|
506
|
+
select$ = this.stateService.select$;
|
|
422
507
|
/**
|
|
423
508
|
* Enable a select interaction on the map.
|
|
424
509
|
* @param id - Unique identifier for this interaction
|
|
@@ -528,13 +613,305 @@ class OlInteractionService {
|
|
|
528
613
|
getInteractionState() {
|
|
529
614
|
return this.stateService.getInteractionState();
|
|
530
615
|
}
|
|
531
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
532
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
616
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: OlInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
617
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: OlInteractionService });
|
|
533
618
|
}
|
|
534
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
619
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: OlInteractionService, decorators: [{
|
|
535
620
|
type: Injectable
|
|
536
621
|
}] });
|
|
537
622
|
|
|
623
|
+
class MeasurementInteractionService {
|
|
624
|
+
mapService = inject(OlMapService);
|
|
625
|
+
zoneHelper = inject(OlZoneHelper);
|
|
626
|
+
draw;
|
|
627
|
+
source = new VectorSource();
|
|
628
|
+
vectorLayer;
|
|
629
|
+
map;
|
|
630
|
+
sketch = null;
|
|
631
|
+
measureTooltipElement = null;
|
|
632
|
+
measureTooltip = null;
|
|
633
|
+
listener = null;
|
|
634
|
+
isMeasuring = false;
|
|
635
|
+
startMeasuring(type) {
|
|
636
|
+
if (this.isMeasuring)
|
|
637
|
+
this.stopMeasuring();
|
|
638
|
+
this.map = this.mapService.getMap() ?? undefined;
|
|
639
|
+
if (!this.map)
|
|
640
|
+
return;
|
|
641
|
+
this.zoneHelper.runOutsideAngular(() => {
|
|
642
|
+
this.vectorLayer = new VectorLayer({
|
|
643
|
+
source: this.source,
|
|
644
|
+
style: new Style({
|
|
645
|
+
fill: new Fill({ color: 'rgba(255, 255, 255, 0.2)' }),
|
|
646
|
+
stroke: new Stroke({ color: '#ffcc33', width: 2 }),
|
|
647
|
+
image: new Circle({ radius: 7, fill: new Fill({ color: '#ffcc33' }) }),
|
|
648
|
+
}),
|
|
649
|
+
zIndex: 9999,
|
|
650
|
+
});
|
|
651
|
+
this.map.addLayer(this.vectorLayer);
|
|
652
|
+
this.draw = new Draw({
|
|
653
|
+
source: this.source,
|
|
654
|
+
type,
|
|
655
|
+
style: new Style({
|
|
656
|
+
fill: new Fill({ color: 'rgba(255, 255, 255, 0.2)' }),
|
|
657
|
+
stroke: new Stroke({ color: 'rgba(0, 0, 0, 0.5)', lineDash: [10, 10], width: 2 }),
|
|
658
|
+
image: new Circle({
|
|
659
|
+
radius: 5,
|
|
660
|
+
stroke: new Stroke({ color: 'rgba(0, 0, 0, 0.7)' }),
|
|
661
|
+
fill: new Fill({ color: 'rgba(255, 255, 255, 0.2)' }),
|
|
662
|
+
}),
|
|
663
|
+
}),
|
|
664
|
+
});
|
|
665
|
+
this.map.addInteraction(this.draw);
|
|
666
|
+
this.createMeasureTooltip();
|
|
667
|
+
this.draw.on('drawstart', (evt) => {
|
|
668
|
+
this.sketch = evt.feature;
|
|
669
|
+
let tooltipCoord = evt.coordinate;
|
|
670
|
+
const geometry = this.sketch?.getGeometry();
|
|
671
|
+
if (geometry) {
|
|
672
|
+
this.listener = geometry.on('change', (e) => {
|
|
673
|
+
const geom = e.target;
|
|
674
|
+
let output;
|
|
675
|
+
if (geom instanceof Polygon) {
|
|
676
|
+
output = this.formatArea(geom);
|
|
677
|
+
tooltipCoord = geom.getInteriorPoint().getCoordinates();
|
|
678
|
+
}
|
|
679
|
+
else if (geom instanceof LineString) {
|
|
680
|
+
output = this.formatLength(geom);
|
|
681
|
+
tooltipCoord = geom.getLastCoordinate();
|
|
682
|
+
}
|
|
683
|
+
else {
|
|
684
|
+
output = '';
|
|
685
|
+
}
|
|
686
|
+
if (this.measureTooltipElement) {
|
|
687
|
+
this.measureTooltipElement.innerHTML = output;
|
|
688
|
+
this.measureTooltip?.setPosition(tooltipCoord);
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
this.draw.on('drawend', () => {
|
|
694
|
+
if (this.measureTooltipElement) {
|
|
695
|
+
this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-static';
|
|
696
|
+
this.measureTooltip?.setOffset([0, -7]);
|
|
697
|
+
this.sketch = null;
|
|
698
|
+
this.measureTooltipElement = null;
|
|
699
|
+
this.createMeasureTooltip();
|
|
700
|
+
}
|
|
701
|
+
if (this.listener)
|
|
702
|
+
unByKey(this.listener);
|
|
703
|
+
});
|
|
704
|
+
this.isMeasuring = true;
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
stopMeasuring() {
|
|
708
|
+
if (!this.isMeasuring)
|
|
709
|
+
return;
|
|
710
|
+
this.zoneHelper.runOutsideAngular(() => {
|
|
711
|
+
if (this.draw && this.map)
|
|
712
|
+
this.map.removeInteraction(this.draw);
|
|
713
|
+
if (this.vectorLayer && this.map)
|
|
714
|
+
this.map.removeLayer(this.vectorLayer);
|
|
715
|
+
this.source.clear();
|
|
716
|
+
// Remove all tooltips
|
|
717
|
+
const overlays = this.map
|
|
718
|
+
?.getOverlays()
|
|
719
|
+
.getArray()
|
|
720
|
+
.filter((o) => o.getElement()?.classList.contains('ol-tooltip'));
|
|
721
|
+
overlays?.forEach((o) => this.map?.removeOverlay(o));
|
|
722
|
+
this.isMeasuring = false;
|
|
723
|
+
this.measureTooltipElement = null;
|
|
724
|
+
this.measureTooltip = null;
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
isActive() {
|
|
728
|
+
return this.isMeasuring;
|
|
729
|
+
}
|
|
730
|
+
createMeasureTooltip() {
|
|
731
|
+
if (!this.map)
|
|
732
|
+
return;
|
|
733
|
+
if (this.measureTooltipElement) {
|
|
734
|
+
this.measureTooltipElement.parentNode?.removeChild(this.measureTooltipElement);
|
|
735
|
+
}
|
|
736
|
+
this.measureTooltipElement = document.createElement('div');
|
|
737
|
+
this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
|
|
738
|
+
this.measureTooltipElement.style.backgroundColor = 'rgba(0,0,0,0.7)';
|
|
739
|
+
this.measureTooltipElement.style.color = 'white';
|
|
740
|
+
this.measureTooltipElement.style.padding = '4px 8px';
|
|
741
|
+
this.measureTooltipElement.style.borderRadius = '4px';
|
|
742
|
+
this.measureTooltipElement.style.fontSize = '12px';
|
|
743
|
+
this.measureTooltipElement.style.whiteSpace = 'nowrap';
|
|
744
|
+
this.measureTooltipElement.style.pointerEvents = 'none';
|
|
745
|
+
this.measureTooltip = new Overlay({
|
|
746
|
+
element: this.measureTooltipElement,
|
|
747
|
+
offset: [0, -15],
|
|
748
|
+
positioning: 'bottom-center',
|
|
749
|
+
stopEvent: false,
|
|
750
|
+
});
|
|
751
|
+
this.map.addOverlay(this.measureTooltip);
|
|
752
|
+
}
|
|
753
|
+
formatLength(line) {
|
|
754
|
+
const length = getLength(line);
|
|
755
|
+
let output;
|
|
756
|
+
if (length > 100) {
|
|
757
|
+
output = Math.round((length / 1000) * 100) / 100 + ' km';
|
|
758
|
+
}
|
|
759
|
+
else {
|
|
760
|
+
output = Math.round(length * 100) / 100 + ' m';
|
|
761
|
+
}
|
|
762
|
+
return output;
|
|
763
|
+
}
|
|
764
|
+
formatArea(polygon) {
|
|
765
|
+
const area = getArea(polygon);
|
|
766
|
+
let output;
|
|
767
|
+
if (area > 10000) {
|
|
768
|
+
output = Math.round((area / 1000000) * 100) / 100 + ' km<sup>2</sup>';
|
|
769
|
+
}
|
|
770
|
+
else {
|
|
771
|
+
output = Math.round(area * 100) / 100 + ' m<sup>2</sup>';
|
|
772
|
+
}
|
|
773
|
+
return output;
|
|
774
|
+
}
|
|
775
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: MeasurementInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
776
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: MeasurementInteractionService });
|
|
777
|
+
}
|
|
778
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: MeasurementInteractionService, decorators: [{
|
|
779
|
+
type: Injectable
|
|
780
|
+
}] });
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Declarative component to configure an OpenLayers Draw Interaction.
|
|
784
|
+
*/
|
|
785
|
+
class OlDrawInteractionComponent {
|
|
786
|
+
interactionService = inject(OlInteractionService);
|
|
787
|
+
destroyRef = inject(DestroyRef);
|
|
788
|
+
id = input.required(...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
789
|
+
type = input.required(...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
790
|
+
source = input(...(ngDevMode ? [undefined, { debugName: "source" }] : /* istanbul ignore next */ []));
|
|
791
|
+
freehand = input(...(ngDevMode ? [undefined, { debugName: "freehand" }] : /* istanbul ignore next */ []));
|
|
792
|
+
snapTolerance = input(...(ngDevMode ? [undefined, { debugName: "snapTolerance" }] : /* istanbul ignore next */ []));
|
|
793
|
+
active = input(true, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
|
|
794
|
+
drawStartFiltered$ = this.interactionService.drawStart$.pipe(filter((e) => e.interactionId === this.id()));
|
|
795
|
+
drawEndFiltered$ = this.interactionService.drawEnd$.pipe(filter((e) => e.interactionId === this.id()));
|
|
796
|
+
drawStart = outputFromObservable(this.drawStartFiltered$);
|
|
797
|
+
drawEnd = outputFromObservable(this.drawEndFiltered$);
|
|
798
|
+
constructor() {
|
|
799
|
+
effect(() => {
|
|
800
|
+
if (this.active()) {
|
|
801
|
+
this.interactionService.enableDraw(this.id(), {
|
|
802
|
+
type: this.type(),
|
|
803
|
+
source: this.source(),
|
|
804
|
+
freehand: this.freehand(),
|
|
805
|
+
snapTolerance: this.snapTolerance(),
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
else {
|
|
809
|
+
this.interactionService.disableInteraction(this.id());
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
this.destroyRef.onDestroy(() => {
|
|
813
|
+
this.interactionService.disableInteraction(this.id());
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: OlDrawInteractionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
817
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", type: OlDrawInteractionComponent, isStandalone: true, selector: "ol-draw-interaction", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null }, freehand: { classPropertyName: "freehand", publicName: "freehand", isSignal: true, isRequired: false, transformFunction: null }, snapTolerance: { classPropertyName: "snapTolerance", publicName: "snapTolerance", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { drawStart: "drawStart", drawEnd: "drawEnd" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
818
|
+
}
|
|
819
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: OlDrawInteractionComponent, decorators: [{
|
|
820
|
+
type: Component,
|
|
821
|
+
args: [{
|
|
822
|
+
selector: 'ol-draw-interaction',
|
|
823
|
+
standalone: true,
|
|
824
|
+
template: '',
|
|
825
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
826
|
+
}]
|
|
827
|
+
}], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: true }] }], source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: false }] }], freehand: [{ type: i0.Input, args: [{ isSignal: true, alias: "freehand", required: false }] }], snapTolerance: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapTolerance", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], drawStart: [{ type: i0.Output, args: ["drawStart"] }], drawEnd: [{ type: i0.Output, args: ["drawEnd"] }] } });
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* Declarative component to configure an OpenLayers Modify Interaction.
|
|
831
|
+
*/
|
|
832
|
+
class OlModifyInteractionComponent {
|
|
833
|
+
interactionService = inject(OlInteractionService);
|
|
834
|
+
destroyRef = inject(DestroyRef);
|
|
835
|
+
id = input.required(...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
836
|
+
source = input(...(ngDevMode ? [undefined, { debugName: "source" }] : /* istanbul ignore next */ []));
|
|
837
|
+
snapTolerance = input(...(ngDevMode ? [undefined, { debugName: "snapTolerance" }] : /* istanbul ignore next */ []));
|
|
838
|
+
active = input(true, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
|
|
839
|
+
modifyFiltered$ = this.interactionService.modify$.pipe(filter((e) => e.interactionId === this.id()));
|
|
840
|
+
modifyEvent = outputFromObservable(this.modifyFiltered$);
|
|
841
|
+
constructor() {
|
|
842
|
+
effect(() => {
|
|
843
|
+
if (this.active()) {
|
|
844
|
+
this.interactionService.enableModify(this.id(), {
|
|
845
|
+
source: this.source(),
|
|
846
|
+
snapTolerance: this.snapTolerance(),
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
this.interactionService.disableInteraction(this.id());
|
|
851
|
+
}
|
|
852
|
+
});
|
|
853
|
+
this.destroyRef.onDestroy(() => {
|
|
854
|
+
this.interactionService.disableInteraction(this.id());
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: OlModifyInteractionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
858
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", type: OlModifyInteractionComponent, isStandalone: true, selector: "ol-modify-interaction", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null }, snapTolerance: { classPropertyName: "snapTolerance", publicName: "snapTolerance", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modifyEvent: "modifyEvent" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
859
|
+
}
|
|
860
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: OlModifyInteractionComponent, decorators: [{
|
|
861
|
+
type: Component,
|
|
862
|
+
args: [{
|
|
863
|
+
selector: 'ol-modify-interaction',
|
|
864
|
+
standalone: true,
|
|
865
|
+
template: '',
|
|
866
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
867
|
+
}]
|
|
868
|
+
}], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: false }] }], snapTolerance: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapTolerance", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], modifyEvent: [{ type: i0.Output, args: ["modifyEvent"] }] } });
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* Declarative component to configure an OpenLayers Select Interaction.
|
|
872
|
+
*/
|
|
873
|
+
class OlSelectInteractionComponent {
|
|
874
|
+
interactionService = inject(OlInteractionService);
|
|
875
|
+
destroyRef = inject(DestroyRef);
|
|
876
|
+
id = input.required(...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
877
|
+
layers = input(...(ngDevMode ? [undefined, { debugName: "layers" }] : /* istanbul ignore next */ []));
|
|
878
|
+
multi = input(...(ngDevMode ? [undefined, { debugName: "multi" }] : /* istanbul ignore next */ []));
|
|
879
|
+
hitTolerance = input(...(ngDevMode ? [undefined, { debugName: "hitTolerance" }] : /* istanbul ignore next */ []));
|
|
880
|
+
condition = input(...(ngDevMode ? [undefined, { debugName: "condition" }] : /* istanbul ignore next */ []));
|
|
881
|
+
active = input(true, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
|
|
882
|
+
selectFiltered$ = this.interactionService.select$.pipe(filter((e) => e.interactionId === this.id()));
|
|
883
|
+
selectEvent = outputFromObservable(this.selectFiltered$);
|
|
884
|
+
constructor() {
|
|
885
|
+
effect(() => {
|
|
886
|
+
if (this.active()) {
|
|
887
|
+
this.interactionService.enableSelect(this.id(), {
|
|
888
|
+
layers: this.layers(),
|
|
889
|
+
multi: this.multi(),
|
|
890
|
+
hitTolerance: this.hitTolerance(),
|
|
891
|
+
condition: this.condition(),
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
else {
|
|
895
|
+
this.interactionService.disableInteraction(this.id());
|
|
896
|
+
}
|
|
897
|
+
});
|
|
898
|
+
this.destroyRef.onDestroy(() => {
|
|
899
|
+
this.interactionService.disableInteraction(this.id());
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: OlSelectInteractionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
903
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", type: OlSelectInteractionComponent, isStandalone: true, selector: "ol-select-interaction", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, layers: { classPropertyName: "layers", publicName: "layers", isSignal: true, isRequired: false, transformFunction: null }, multi: { classPropertyName: "multi", publicName: "multi", isSignal: true, isRequired: false, transformFunction: null }, hitTolerance: { classPropertyName: "hitTolerance", publicName: "hitTolerance", isSignal: true, isRequired: false, transformFunction: null }, condition: { classPropertyName: "condition", publicName: "condition", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectEvent: "selectEvent" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
904
|
+
}
|
|
905
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: OlSelectInteractionComponent, decorators: [{
|
|
906
|
+
type: Component,
|
|
907
|
+
args: [{
|
|
908
|
+
selector: 'ol-select-interaction',
|
|
909
|
+
standalone: true,
|
|
910
|
+
template: '',
|
|
911
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
912
|
+
}]
|
|
913
|
+
}], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], layers: [{ type: i0.Input, args: [{ isSignal: true, alias: "layers", required: false }] }], multi: [{ type: i0.Input, args: [{ isSignal: true, alias: "multi", required: false }] }], hitTolerance: [{ type: i0.Input, args: [{ isSignal: true, alias: "hitTolerance", required: false }] }], condition: [{ type: i0.Input, args: [{ isSignal: true, alias: "condition", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], selectEvent: [{ type: i0.Output, args: ["selectEvent"] }] } });
|
|
914
|
+
|
|
538
915
|
/**
|
|
539
916
|
* Provide the interactions feature with OlInteractionService and all specialized services.
|
|
540
917
|
* Note: ZoneHelper is inherited from core's provideOpenLayers.
|
|
@@ -550,6 +927,7 @@ function withInteractions() {
|
|
|
550
927
|
SelectInteractionService,
|
|
551
928
|
DrawInteractionService,
|
|
552
929
|
ModifyInteractionService,
|
|
930
|
+
MeasurementInteractionService,
|
|
553
931
|
],
|
|
554
932
|
};
|
|
555
933
|
}
|
|
@@ -608,6 +986,19 @@ function withModifyInteraction(id, config = {}) {
|
|
|
608
986
|
deps: [OlInteractionService],
|
|
609
987
|
};
|
|
610
988
|
}
|
|
989
|
+
/**
|
|
990
|
+
* Enable measurement interaction when providing the interactions feature.
|
|
991
|
+
* @returns Provider function that enables measurement interaction
|
|
992
|
+
*/
|
|
993
|
+
function withMeasurementInteraction() {
|
|
994
|
+
return {
|
|
995
|
+
provide: 'MEASUREMENT_INTERACTION_CONFIG',
|
|
996
|
+
useFactory: (service) => {
|
|
997
|
+
return service;
|
|
998
|
+
},
|
|
999
|
+
deps: [MeasurementInteractionService],
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
611
1002
|
|
|
612
1003
|
// @angular-helpers/openlayers/interactions
|
|
613
1004
|
// Main orchestrator service
|
|
@@ -616,4 +1007,4 @@ function withModifyInteraction(id, config = {}) {
|
|
|
616
1007
|
* Generated bundle index. Do not edit.
|
|
617
1008
|
*/
|
|
618
1009
|
|
|
619
|
-
export { DrawInteractionService, InteractionStateService, ModifyInteractionService, OlInteractionService, SelectInteractionService, olFeatureToFeature, provideInteractions, withDrawInteraction, withInteractions, withModifyInteraction, withSelectInteraction };
|
|
1010
|
+
export { DrawInteractionService, InteractionStateService, MeasurementInteractionService, ModifyInteractionService, OlDrawInteractionComponent, OlInteractionService, OlModifyInteractionComponent, OlSelectInteractionComponent, SelectInteractionService, olFeatureToFeature, provideInteractions, withDrawInteraction, withInteractions, withMeasurementInteraction, withModifyInteraction, withSelectInteraction };
|