@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.
@@ -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.4", ngImport: i0, type: InteractionStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
137
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: InteractionStateService });
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.4", ngImport: i0, type: InteractionStateService, decorators: [{
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', (_e) => {
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.4", ngImport: i0, type: SelectInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
236
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SelectInteractionService });
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.4", ngImport: i0, type: SelectInteractionService, decorators: [{
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: config.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.4", ngImport: i0, type: DrawInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
311
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DrawInteractionService });
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.4", ngImport: i0, type: DrawInteractionService, decorators: [{
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.4", ngImport: i0, type: ModifyInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
381
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ModifyInteractionService });
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.4", ngImport: i0, type: ModifyInteractionService, decorators: [{
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.4", ngImport: i0, type: OlInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
532
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: OlInteractionService });
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.4", ngImport: i0, type: OlInteractionService, decorators: [{
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 };