@angular-helpers/openlayers 0.1.0 → 0.2.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/fesm2022/angular-helpers-openlayers-controls.mjs +496 -107
- package/fesm2022/angular-helpers-openlayers-core.mjs +130 -32
- package/fesm2022/angular-helpers-openlayers-interactions.mjs +583 -10
- package/fesm2022/angular-helpers-openlayers-layers.mjs +318 -49
- package/package.json +2 -1
- package/types/angular-helpers-openlayers-controls.d.ts +161 -23
- package/types/angular-helpers-openlayers-core.d.ts +72 -7
- package/types/angular-helpers-openlayers-interactions.d.ts +315 -6
- package/types/angular-helpers-openlayers-layers.d.ts +61 -10
|
@@ -1,15 +1,521 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable } from '@angular/core';
|
|
3
|
-
import {
|
|
2
|
+
import { signal, computed, Injectable, inject } from '@angular/core';
|
|
3
|
+
import { OlMapService, OlZoneHelper } from '@angular-helpers/openlayers/core';
|
|
4
|
+
import { Subject } from 'rxjs';
|
|
5
|
+
import Select from 'ol/interaction/Select';
|
|
6
|
+
import Draw from 'ol/interaction/Draw';
|
|
7
|
+
import Snap from 'ol/interaction/Snap';
|
|
8
|
+
import VectorSource from 'ol/source/Vector';
|
|
9
|
+
import { OlLayerService } from '@angular-helpers/openlayers/layers';
|
|
10
|
+
import Modify from 'ol/interaction/Modify';
|
|
4
11
|
|
|
5
|
-
//
|
|
12
|
+
// Interaction state management service
|
|
13
|
+
/**
|
|
14
|
+
* Service responsible for managing the reactive state of interactions.
|
|
15
|
+
* Provides signals for interaction state and observables for events.
|
|
16
|
+
*/
|
|
17
|
+
class InteractionStateService {
|
|
18
|
+
// Internal signals
|
|
19
|
+
interactions = signal([], ...(ngDevMode ? [{ debugName: "interactions" }] : /* istanbul ignore next */ []));
|
|
20
|
+
selectedFeaturesInternal = signal([], ...(ngDevMode ? [{ debugName: "selectedFeaturesInternal" }] : /* istanbul ignore next */ []));
|
|
21
|
+
// Event subjects
|
|
22
|
+
drawStartSubject = new Subject();
|
|
23
|
+
drawEndSubject = new Subject();
|
|
24
|
+
modifySubject = new Subject();
|
|
25
|
+
// Public readonly signals
|
|
26
|
+
selectedFeatures = computed(() => this.selectedFeaturesInternal(), ...(ngDevMode ? [{ debugName: "selectedFeatures" }] : /* istanbul ignore next */ []));
|
|
27
|
+
selectionCount = computed(() => this.selectedFeaturesInternal().length, ...(ngDevMode ? [{ debugName: "selectionCount" }] : /* istanbul ignore next */ []));
|
|
28
|
+
hasSelection = computed(() => this.selectedFeaturesInternal().length > 0, ...(ngDevMode ? [{ debugName: "hasSelection" }] : /* istanbul ignore next */ []));
|
|
29
|
+
activeInteractions = computed(() => this.interactions().filter((i) => i.config.active !== false), ...(ngDevMode ? [{ debugName: "activeInteractions" }] : /* istanbul ignore next */ []));
|
|
30
|
+
// Public observables
|
|
31
|
+
drawStart$ = this.drawStartSubject.asObservable();
|
|
32
|
+
drawEnd$ = this.drawEndSubject.asObservable();
|
|
33
|
+
modify$ = this.modifySubject.asObservable();
|
|
34
|
+
/**
|
|
35
|
+
* Adds a managed interaction to the state.
|
|
36
|
+
* @param interaction - The interaction to add
|
|
37
|
+
*/
|
|
38
|
+
addInteraction(interaction) {
|
|
39
|
+
this.interactions.update((list) => [...list, interaction]);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Removes an interaction by id.
|
|
43
|
+
* @param id - The interaction identifier to remove
|
|
44
|
+
*/
|
|
45
|
+
removeInteraction(id) {
|
|
46
|
+
this.interactions.update((list) => list.filter((i) => i.id !== id));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Gets all managed interactions.
|
|
50
|
+
* @returns Array of managed interactions
|
|
51
|
+
*/
|
|
52
|
+
getInteractions() {
|
|
53
|
+
return this.interactions();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Finds an interaction by id.
|
|
57
|
+
* @param id - The interaction identifier
|
|
58
|
+
* @returns The managed interaction or undefined
|
|
59
|
+
*/
|
|
60
|
+
findInteraction(id) {
|
|
61
|
+
return this.interactions().find((i) => i.id === id);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Sets the currently selected features.
|
|
65
|
+
* @param features - Array of selected features
|
|
66
|
+
*/
|
|
67
|
+
setSelectedFeatures(features) {
|
|
68
|
+
this.selectedFeaturesInternal.set(features);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Clears the current selection.
|
|
72
|
+
*/
|
|
73
|
+
clearSelection() {
|
|
74
|
+
this.selectedFeaturesInternal.set([]);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Emits a draw start event.
|
|
78
|
+
* @param event - The draw start event data
|
|
79
|
+
*/
|
|
80
|
+
emitDrawStart(event) {
|
|
81
|
+
this.drawStartSubject.next(event);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Emits a draw end event.
|
|
85
|
+
* @param event - The draw end event data
|
|
86
|
+
*/
|
|
87
|
+
emitDrawEnd(event) {
|
|
88
|
+
this.drawEndSubject.next(event);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Emits a modify event.
|
|
92
|
+
* @param event - The modify event data
|
|
93
|
+
*/
|
|
94
|
+
emitModify(event) {
|
|
95
|
+
this.modifySubject.next(event);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Gets the current interaction state summary.
|
|
99
|
+
* @returns Array of interaction state objects
|
|
100
|
+
*/
|
|
101
|
+
getInteractionState() {
|
|
102
|
+
return this.interactions().map((i) => ({
|
|
103
|
+
id: i.id,
|
|
104
|
+
type: i.type,
|
|
105
|
+
active: i.config.active !== false,
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Checks if an interaction is currently active.
|
|
110
|
+
* @param id - The interaction identifier
|
|
111
|
+
* @returns True if the interaction exists and is active
|
|
112
|
+
*/
|
|
113
|
+
isActive(id) {
|
|
114
|
+
const interaction = this.findInteraction(id);
|
|
115
|
+
return interaction ? interaction.config.active !== false : false;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Clears all interactions from state.
|
|
119
|
+
* Note: This only clears the state tracking, not the actual OL interactions.
|
|
120
|
+
*/
|
|
121
|
+
clearAll() {
|
|
122
|
+
this.interactions.set([]);
|
|
123
|
+
this.selectedFeaturesInternal.set([]);
|
|
124
|
+
}
|
|
125
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: InteractionStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
126
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: InteractionStateService });
|
|
127
|
+
}
|
|
128
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: InteractionStateService, decorators: [{
|
|
129
|
+
type: Injectable
|
|
130
|
+
}] });
|
|
131
|
+
|
|
132
|
+
// Feature conversion utilities for OpenLayers interactions
|
|
133
|
+
/**
|
|
134
|
+
* Converts an OpenLayers feature to the internal Feature format.
|
|
135
|
+
* Handles coordinate extraction and geometry type mapping.
|
|
136
|
+
*
|
|
137
|
+
* @param olFeature - The OpenLayers feature to convert
|
|
138
|
+
* @returns The converted Feature with normalized structure
|
|
139
|
+
*/
|
|
140
|
+
function olFeatureToFeature(olFeature) {
|
|
141
|
+
const geometry = olFeature.getGeometry();
|
|
142
|
+
const geomType = geometry?.getType() ?? 'Point';
|
|
143
|
+
// Convert coordinates based on geometry type
|
|
144
|
+
let coordinates;
|
|
145
|
+
if (geomType === 'Circle') {
|
|
146
|
+
// ol/geom/Circle has no getCoordinates() — use getCenter() instead
|
|
147
|
+
const circle = geometry;
|
|
148
|
+
coordinates = circle.getCenter();
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// oxlint-disable-next-line no-explicit-any
|
|
152
|
+
const olCoords = geometry.getCoordinates();
|
|
153
|
+
if (Array.isArray(olCoords) && Array.isArray(olCoords[0])) {
|
|
154
|
+
// Multi-coordinate structures (LineString, Polygon, etc.)
|
|
155
|
+
coordinates = olCoords;
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// Single point
|
|
159
|
+
coordinates = olCoords;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
id: olFeature.getId()?.toString() ?? `feature-${Math.random().toString(36).slice(2)}`,
|
|
164
|
+
geometry: {
|
|
165
|
+
type: geomType,
|
|
166
|
+
coordinates,
|
|
167
|
+
},
|
|
168
|
+
properties: olFeature.getProperties(),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Select interaction creation service
|
|
173
|
+
/**
|
|
174
|
+
* Service responsible for creating and managing Select interactions.
|
|
175
|
+
*/
|
|
176
|
+
class SelectInteractionService {
|
|
177
|
+
mapService = inject(OlMapService);
|
|
178
|
+
stateService = inject(InteractionStateService);
|
|
179
|
+
zoneHelper = inject(OlZoneHelper);
|
|
180
|
+
/**
|
|
181
|
+
* Creates and configures a Select interaction.
|
|
182
|
+
* @param id - Unique identifier for the interaction
|
|
183
|
+
* @param config - Select interaction configuration
|
|
184
|
+
* @param map - OpenLayers map instance
|
|
185
|
+
* @returns Promise that resolves when the interaction is created
|
|
186
|
+
*/
|
|
187
|
+
createSelectInteraction(id, config, map) {
|
|
188
|
+
this.zoneHelper.runOutsideAngular(() => {
|
|
189
|
+
const select = new Select({
|
|
190
|
+
layers: config.layers
|
|
191
|
+
? (layer) => {
|
|
192
|
+
const layerId = layer.get('id');
|
|
193
|
+
return config.layers?.includes(layerId) ?? false;
|
|
194
|
+
}
|
|
195
|
+
: undefined,
|
|
196
|
+
multi: config.multi ?? false,
|
|
197
|
+
hitTolerance: config.hitTolerance ?? 0,
|
|
198
|
+
});
|
|
199
|
+
// Listen to selection changes — use getFeatures().getArray() for the full
|
|
200
|
+
// accumulated collection, not e.selected which only contains newly added ones
|
|
201
|
+
select.on('select', (_e) => {
|
|
202
|
+
this.zoneHelper.runInsideAngular(() => {
|
|
203
|
+
const allSelected = select
|
|
204
|
+
.getFeatures()
|
|
205
|
+
.getArray()
|
|
206
|
+
.map((f) => olFeatureToFeature(f));
|
|
207
|
+
this.stateService.setSelectedFeatures(allSelected);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
map.addInteraction(select);
|
|
211
|
+
const managed = {
|
|
212
|
+
id,
|
|
213
|
+
type: 'select',
|
|
214
|
+
olInteraction: select,
|
|
215
|
+
config,
|
|
216
|
+
cleanup: () => {
|
|
217
|
+
map.removeInteraction(select);
|
|
218
|
+
select.dispose();
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
this.stateService.addInteraction(managed);
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SelectInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
225
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SelectInteractionService });
|
|
226
|
+
}
|
|
227
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SelectInteractionService, decorators: [{
|
|
228
|
+
type: Injectable
|
|
229
|
+
}] });
|
|
230
|
+
|
|
231
|
+
// Draw interaction creation service
|
|
232
|
+
/**
|
|
233
|
+
* Service responsible for creating and managing Draw interactions.
|
|
234
|
+
*/
|
|
235
|
+
class DrawInteractionService {
|
|
236
|
+
mapService = inject(OlMapService);
|
|
237
|
+
layerService = inject(OlLayerService);
|
|
238
|
+
stateService = inject(InteractionStateService);
|
|
239
|
+
zoneHelper = inject(OlZoneHelper);
|
|
240
|
+
/**
|
|
241
|
+
* Creates and configures a Draw interaction.
|
|
242
|
+
* @param id - Unique identifier for the interaction
|
|
243
|
+
* @param config - Draw interaction configuration
|
|
244
|
+
* @param map - OpenLayers map instance
|
|
245
|
+
* @returns True if the interaction was created successfully
|
|
246
|
+
*/
|
|
247
|
+
createDrawInteraction(id, config, map) {
|
|
248
|
+
let source;
|
|
249
|
+
// Get source from layer if specified
|
|
250
|
+
if (config.source) {
|
|
251
|
+
const layer = this.layerService.getLayer(config.source);
|
|
252
|
+
source = layer?.getSource() ?? undefined;
|
|
253
|
+
}
|
|
254
|
+
// Create a temporary source if none provided
|
|
255
|
+
if (!source) {
|
|
256
|
+
source = new VectorSource();
|
|
257
|
+
}
|
|
258
|
+
this.zoneHelper.runOutsideAngular(() => {
|
|
259
|
+
const draw = new Draw({
|
|
260
|
+
source,
|
|
261
|
+
type: config.type,
|
|
262
|
+
freehand: config.freehand ?? false,
|
|
263
|
+
snapTolerance: config.snapTolerance ?? 12,
|
|
264
|
+
});
|
|
265
|
+
const snap = new Snap({ source });
|
|
266
|
+
// Handle draw start event
|
|
267
|
+
draw.on('drawstart', (e) => {
|
|
268
|
+
this.zoneHelper.runInsideAngular(() => {
|
|
269
|
+
const feature = olFeatureToFeature(e.feature);
|
|
270
|
+
this.stateService.emitDrawStart({ feature });
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
// Handle draw end event
|
|
274
|
+
draw.on('drawend', (e) => {
|
|
275
|
+
this.zoneHelper.runInsideAngular(() => {
|
|
276
|
+
const feature = olFeatureToFeature(e.feature);
|
|
277
|
+
const event = { feature, type: config.type };
|
|
278
|
+
this.stateService.emitDrawEnd(event);
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
map.addInteraction(draw);
|
|
282
|
+
map.addInteraction(snap);
|
|
283
|
+
const managed = {
|
|
284
|
+
id,
|
|
285
|
+
type: 'draw',
|
|
286
|
+
olInteraction: draw,
|
|
287
|
+
config,
|
|
288
|
+
cleanup: () => {
|
|
289
|
+
map.removeInteraction(draw);
|
|
290
|
+
map.removeInteraction(snap);
|
|
291
|
+
draw.dispose();
|
|
292
|
+
snap.dispose();
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
this.stateService.addInteraction(managed);
|
|
296
|
+
});
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DrawInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
300
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DrawInteractionService });
|
|
301
|
+
}
|
|
302
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DrawInteractionService, decorators: [{
|
|
303
|
+
type: Injectable
|
|
304
|
+
}] });
|
|
305
|
+
|
|
306
|
+
// Modify interaction creation service
|
|
307
|
+
/**
|
|
308
|
+
* Service responsible for creating and managing Modify interactions.
|
|
309
|
+
*/
|
|
310
|
+
class ModifyInteractionService {
|
|
311
|
+
layerService = inject(OlLayerService);
|
|
312
|
+
stateService = inject(InteractionStateService);
|
|
313
|
+
zoneHelper = inject(OlZoneHelper);
|
|
314
|
+
/**
|
|
315
|
+
* Creates and configures a Modify interaction.
|
|
316
|
+
* @param id - Unique identifier for the interaction
|
|
317
|
+
* @param config - Modify interaction configuration
|
|
318
|
+
* @param map - OpenLayers map instance
|
|
319
|
+
*/
|
|
320
|
+
createModifyInteraction(id, config, map) {
|
|
321
|
+
this.zoneHelper.runOutsideAngular(() => {
|
|
322
|
+
let source;
|
|
323
|
+
if (config.source) {
|
|
324
|
+
const layer = this.layerService.getLayer(config.source);
|
|
325
|
+
source = layer?.getSource() ?? undefined;
|
|
326
|
+
}
|
|
327
|
+
if (!source) {
|
|
328
|
+
// No source available, cannot create modify interaction
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
const modify = new Modify({
|
|
332
|
+
source,
|
|
333
|
+
pixelTolerance: config.snapTolerance ?? 10,
|
|
334
|
+
});
|
|
335
|
+
const snap = new Snap({ source: source });
|
|
336
|
+
// Handle modify start event
|
|
337
|
+
modify.on('modifystart', (e) => {
|
|
338
|
+
this.zoneHelper.runInsideAngular(() => {
|
|
339
|
+
const features = e.features.getArray().map((f) => olFeatureToFeature(f));
|
|
340
|
+
const event = { features, type: 'modifystart' };
|
|
341
|
+
this.stateService.emitModify(event);
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
// Handle modify end event
|
|
345
|
+
modify.on('modifyend', (e) => {
|
|
346
|
+
this.zoneHelper.runInsideAngular(() => {
|
|
347
|
+
const features = e.features.getArray().map((f) => olFeatureToFeature(f));
|
|
348
|
+
const event = { features, type: 'modifyend' };
|
|
349
|
+
this.stateService.emitModify(event);
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
map.addInteraction(modify);
|
|
353
|
+
map.addInteraction(snap);
|
|
354
|
+
const managed = {
|
|
355
|
+
id,
|
|
356
|
+
type: 'modify',
|
|
357
|
+
olInteraction: modify,
|
|
358
|
+
config,
|
|
359
|
+
cleanup: () => {
|
|
360
|
+
map.removeInteraction(modify);
|
|
361
|
+
map.removeInteraction(snap);
|
|
362
|
+
modify.dispose();
|
|
363
|
+
snap.dispose();
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
this.stateService.addInteraction(managed);
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ModifyInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
370
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ModifyInteractionService });
|
|
371
|
+
}
|
|
372
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ModifyInteractionService, decorators: [{
|
|
373
|
+
type: Injectable
|
|
374
|
+
}] });
|
|
375
|
+
|
|
376
|
+
// OlInteractionService - Main orchestrator for OpenLayers interactions
|
|
377
|
+
/**
|
|
378
|
+
* Main service for managing OpenLayers map interactions.
|
|
379
|
+
* Orchestrates specialized interaction services and exposes unified API.
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* ```typescript
|
|
383
|
+
* const interactionService = inject(OlInteractionService);
|
|
384
|
+
*
|
|
385
|
+
* // Enable select interaction
|
|
386
|
+
* interactionService.enableSelect('select-1', { layers: ['cities'], multi: true });
|
|
387
|
+
*
|
|
388
|
+
* // React to selection changes
|
|
389
|
+
* effect(() => {
|
|
390
|
+
* const selected = interactionService.selectedFeatures();
|
|
391
|
+
* console.log('Selected:', selected);
|
|
392
|
+
* });
|
|
393
|
+
* ```
|
|
394
|
+
*/
|
|
6
395
|
class OlInteractionService {
|
|
7
|
-
|
|
8
|
-
|
|
396
|
+
mapService = inject(OlMapService);
|
|
397
|
+
stateService = inject(InteractionStateService);
|
|
398
|
+
zoneHelper = inject(OlZoneHelper);
|
|
399
|
+
// Specialized interaction services (injected, not instantiated)
|
|
400
|
+
selectService = inject(SelectInteractionService);
|
|
401
|
+
drawService = inject(DrawInteractionService);
|
|
402
|
+
modifyService = inject(ModifyInteractionService);
|
|
403
|
+
// Public signals and observables delegated to state service
|
|
404
|
+
selectedFeatures = this.stateService.selectedFeatures;
|
|
405
|
+
selectionCount = this.stateService.selectionCount;
|
|
406
|
+
hasSelection = this.stateService.hasSelection;
|
|
407
|
+
activeInteractions = this.stateService.activeInteractions;
|
|
408
|
+
drawStart$ = this.stateService.drawStart$;
|
|
409
|
+
drawEnd$ = this.stateService.drawEnd$;
|
|
410
|
+
modify$ = this.stateService.modify$;
|
|
411
|
+
/**
|
|
412
|
+
* Enable a select interaction on the map.
|
|
413
|
+
* @param id - Unique identifier for this interaction
|
|
414
|
+
* @param config - Selection configuration
|
|
415
|
+
* @returns Object with cleanup method
|
|
416
|
+
*/
|
|
417
|
+
enableSelect(id, config = {}) {
|
|
418
|
+
if (this.stateService.findInteraction(id)) {
|
|
419
|
+
return { cleanup: () => this.disableInteraction(id) };
|
|
420
|
+
}
|
|
421
|
+
this.mapService.onReady((map) => {
|
|
422
|
+
this.selectService.createSelectInteraction(id, config, map);
|
|
423
|
+
});
|
|
424
|
+
return { cleanup: () => this.disableInteraction(id) };
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Enable a draw interaction on the map.
|
|
428
|
+
* @param id - Unique identifier for this interaction
|
|
429
|
+
* @param config - Draw configuration
|
|
430
|
+
* @returns Object with cleanup method and isActive signal
|
|
431
|
+
*/
|
|
432
|
+
enableDraw(id, config) {
|
|
433
|
+
if (this.stateService.findInteraction(id)) {
|
|
434
|
+
return { cleanup: () => this.disableInteraction(id), isActive: () => false };
|
|
435
|
+
}
|
|
436
|
+
let isActive = false;
|
|
437
|
+
this.mapService.onReady((map) => {
|
|
438
|
+
isActive = this.drawService.createDrawInteraction(id, config, map);
|
|
439
|
+
});
|
|
440
|
+
return {
|
|
441
|
+
cleanup: () => this.disableInteraction(id),
|
|
442
|
+
isActive: () => isActive,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Enable a modify interaction on the map.
|
|
447
|
+
* @param id - Unique identifier for this interaction
|
|
448
|
+
* @param config - Modify configuration
|
|
449
|
+
* @returns Object with cleanup method
|
|
450
|
+
*/
|
|
451
|
+
enableModify(id, config = {}) {
|
|
452
|
+
if (this.stateService.findInteraction(id)) {
|
|
453
|
+
return { cleanup: () => this.disableInteraction(id) };
|
|
454
|
+
}
|
|
455
|
+
this.mapService.onReady((map) => {
|
|
456
|
+
this.modifyService.createModifyInteraction(id, config, map);
|
|
457
|
+
});
|
|
458
|
+
return { cleanup: () => this.disableInteraction(id) };
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Disable and remove an interaction by id.
|
|
462
|
+
* @param id - The interaction identifier
|
|
463
|
+
*/
|
|
464
|
+
disableInteraction(id) {
|
|
465
|
+
const interaction = this.stateService.findInteraction(id);
|
|
466
|
+
if (!interaction)
|
|
467
|
+
return;
|
|
468
|
+
// Run cleanup outside Angular zone
|
|
469
|
+
this.zoneHelper.runOutsideAngular(() => {
|
|
470
|
+
interaction.cleanup();
|
|
471
|
+
});
|
|
472
|
+
// Remove from state
|
|
473
|
+
this.stateService.removeInteraction(id);
|
|
474
|
+
// Clear selection if this was a select interaction
|
|
475
|
+
if (interaction.type === 'select') {
|
|
476
|
+
this.stateService.clearSelection();
|
|
477
|
+
}
|
|
9
478
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
479
|
+
/**
|
|
480
|
+
* Disable all active interactions.
|
|
481
|
+
*/
|
|
482
|
+
disableAll() {
|
|
483
|
+
const ids = this.stateService.getInteractions().map((i) => i.id);
|
|
484
|
+
for (const id of ids) {
|
|
485
|
+
this.disableInteraction(id);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Clear the current selection.
|
|
490
|
+
* Also clears the OL Select interaction's internal feature collection so the
|
|
491
|
+
* visual selection is removed from the map.
|
|
492
|
+
*/
|
|
493
|
+
clearSelection() {
|
|
494
|
+
const interactions = this.stateService.getInteractions();
|
|
495
|
+
for (const managed of interactions) {
|
|
496
|
+
if (managed.type === 'select') {
|
|
497
|
+
this.zoneHelper.runOutsideAngular(() => {
|
|
498
|
+
const olSelect = managed.olInteraction;
|
|
499
|
+
olSelect.getFeatures?.()?.clear();
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
this.stateService.clearSelection();
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Check if an interaction is currently active.
|
|
507
|
+
* @param id - The interaction identifier
|
|
508
|
+
* @returns True if active, false otherwise
|
|
509
|
+
*/
|
|
510
|
+
isActive(id) {
|
|
511
|
+
return this.stateService.isActive(id);
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Get current interaction state.
|
|
515
|
+
* @returns Array of interaction state summaries
|
|
516
|
+
*/
|
|
517
|
+
getInteractionState() {
|
|
518
|
+
return this.stateService.getInteractionState();
|
|
13
519
|
}
|
|
14
520
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: OlInteractionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
15
521
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: OlInteractionService });
|
|
@@ -18,17 +524,84 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
18
524
|
type: Injectable
|
|
19
525
|
}] });
|
|
20
526
|
|
|
527
|
+
/**
|
|
528
|
+
* Provide the interactions feature with OlInteractionService and all specialized services.
|
|
529
|
+
* Note: ZoneHelper is inherited from core's provideOpenLayers.
|
|
530
|
+
* @returns OlFeature configuration for interactions
|
|
531
|
+
*/
|
|
21
532
|
function withInteractions() {
|
|
22
|
-
return {
|
|
533
|
+
return {
|
|
534
|
+
kind: 'interactions',
|
|
535
|
+
providers: [
|
|
536
|
+
OlInteractionService,
|
|
537
|
+
InteractionStateService,
|
|
538
|
+
SelectInteractionService,
|
|
539
|
+
DrawInteractionService,
|
|
540
|
+
ModifyInteractionService,
|
|
541
|
+
],
|
|
542
|
+
};
|
|
23
543
|
}
|
|
544
|
+
/**
|
|
545
|
+
* Alias for withInteractions().
|
|
546
|
+
* @returns OlFeature configuration for interactions
|
|
547
|
+
*/
|
|
24
548
|
function provideInteractions() {
|
|
25
549
|
return withInteractions();
|
|
26
550
|
}
|
|
551
|
+
/**
|
|
552
|
+
* Enable select interaction when providing the interactions feature.
|
|
553
|
+
* @param id Unique identifier for this interaction
|
|
554
|
+
* @param config Select interaction configuration
|
|
555
|
+
* @returns Provider function that enables select interaction
|
|
556
|
+
*/
|
|
557
|
+
function withSelectInteraction(id, config = {}) {
|
|
558
|
+
return {
|
|
559
|
+
provide: 'SELECT_INTERACTION_CONFIG',
|
|
560
|
+
useFactory: (service) => {
|
|
561
|
+
service.enableSelect(id, config);
|
|
562
|
+
return { id, config };
|
|
563
|
+
},
|
|
564
|
+
deps: [OlInteractionService],
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Enable draw interaction when providing the interactions feature.
|
|
569
|
+
* @param id Unique identifier for this interaction
|
|
570
|
+
* @param config Draw interaction configuration
|
|
571
|
+
* @returns Provider function that enables draw interaction
|
|
572
|
+
*/
|
|
573
|
+
function withDrawInteraction(id, config) {
|
|
574
|
+
return {
|
|
575
|
+
provide: 'DRAW_INTERACTION_CONFIG',
|
|
576
|
+
useFactory: (service) => {
|
|
577
|
+
service.enableDraw(id, config);
|
|
578
|
+
return { id, config };
|
|
579
|
+
},
|
|
580
|
+
deps: [OlInteractionService],
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Enable modify interaction when providing the interactions feature.
|
|
585
|
+
* @param id Unique identifier for this interaction
|
|
586
|
+
* @param config Modify interaction configuration
|
|
587
|
+
* @returns Provider function that enables modify interaction
|
|
588
|
+
*/
|
|
589
|
+
function withModifyInteraction(id, config = {}) {
|
|
590
|
+
return {
|
|
591
|
+
provide: 'MODIFY_INTERACTION_CONFIG',
|
|
592
|
+
useFactory: (service) => {
|
|
593
|
+
service.enableModify(id, config);
|
|
594
|
+
return { id, config };
|
|
595
|
+
},
|
|
596
|
+
deps: [OlInteractionService],
|
|
597
|
+
};
|
|
598
|
+
}
|
|
27
599
|
|
|
28
600
|
// @angular-helpers/openlayers/interactions
|
|
601
|
+
// Main orchestrator service
|
|
29
602
|
|
|
30
603
|
/**
|
|
31
604
|
* Generated bundle index. Do not edit.
|
|
32
605
|
*/
|
|
33
606
|
|
|
34
|
-
export { OlInteractionService, provideInteractions, withInteractions };
|
|
607
|
+
export { DrawInteractionService, InteractionStateService, ModifyInteractionService, OlInteractionService, SelectInteractionService, olFeatureToFeature, provideInteractions, withDrawInteraction, withInteractions, withModifyInteraction, withSelectInteraction };
|