@regionerne/gis-komponent 0.0.21 → 0.0.23
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/regionerne-gis-komponent.mjs +801 -257
- package/fesm2022/regionerne-gis-komponent.mjs.map +1 -1
- package/lib/components/active-objects/activeObjects.component.d.ts +3 -0
- package/lib/components/confirm-dialog/confirm-dialog.component.d.ts +18 -0
- package/lib/components/gis-komponent/gis-komponent.component.d.ts +1 -0
- package/lib/components/layer-selector/layer-selector.component.d.ts +1 -3
- package/lib/components/legends-list/legends-list.component.d.ts +1 -1
- package/lib/components/map-search/map-search.component.d.ts +15 -3
- package/lib/components/toolbox/toolbox.component.d.ts +9 -33
- package/lib/models/GisKomponentSettings.d.ts +8 -0
- package/lib/models/ILayer.d.ts +3 -0
- package/lib/models/ILayerGroup.d.ts +1 -8
- package/lib/models/profile.d.ts +1 -0
- package/lib/services/centerPoint.service.d.ts +14 -0
- package/lib/services/confirm-dialog.service.d.ts +11 -0
- package/lib/services/featureHelper.service.d.ts +0 -1
- package/lib/services/highlight.service.d.ts +6 -5
- package/lib/services/layerError.service.d.ts +1 -0
- package/lib/services/layerHelper.service.d.ts +6 -3
- package/lib/services/overlap.service.d.ts +12 -0
- package/lib/services/printDrawLayerSource.service.d.ts +1 -2
- package/lib/services/searchProvider.service.d.ts +25 -0
- package/lib/services/wfsSearch.service.d.ts +34 -0
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import * as i1$
|
|
1
|
+
import * as i1$3 from '@angular/common';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { InjectionToken, inject, Injectable, Component, Input, ViewChild } from '@angular/core';
|
|
5
|
-
import * as
|
|
4
|
+
import { InjectionToken, inject, Injectable, Component, Input, ViewChild, Inject } from '@angular/core';
|
|
5
|
+
import * as i3 from '@angular/material/icon';
|
|
6
6
|
import { MatIconModule } from '@angular/material/icon';
|
|
7
7
|
import Map$1 from 'ol/Map';
|
|
8
8
|
import View from 'ol/View';
|
|
@@ -12,7 +12,7 @@ import WMTSCapabilities from 'ol/format/WMTSCapabilities';
|
|
|
12
12
|
import ImageLayer from 'ol/layer/Image';
|
|
13
13
|
import { HttpClient, HttpErrorResponse, HttpHeaders, provideHttpClient, withInterceptors } from '@angular/common/http';
|
|
14
14
|
import OLLayerGroup from 'ol/layer/Group';
|
|
15
|
-
import * as i5 from '@angular/material/select';
|
|
15
|
+
import * as i5$1 from '@angular/material/select';
|
|
16
16
|
import { MatSelectModule } from '@angular/material/select';
|
|
17
17
|
import * as i3$1 from '@angular/material/list';
|
|
18
18
|
import { MatListModule } from '@angular/material/list';
|
|
@@ -22,49 +22,59 @@ import { register } from 'ol/proj/proj4';
|
|
|
22
22
|
import proj4 from 'proj4';
|
|
23
23
|
import { Control, Rotate } from 'ol/control';
|
|
24
24
|
import { Vector, TileWMS } from 'ol/source';
|
|
25
|
-
import { BehaviorSubject,
|
|
25
|
+
import { Subject, BehaviorSubject, tap, switchMap, EMPTY, of, map, ReplaySubject, filter, combineLatest, Observable, takeUntil, take, mergeWith, debounceTime, distinctUntilChanged, forkJoin, catchError, throwError } from 'rxjs';
|
|
26
26
|
import WMTS, { optionsFromCapabilities } from 'ol/source/WMTS';
|
|
27
|
+
import VectorLayer from 'ol/layer/Vector';
|
|
28
|
+
import TileSource from 'ol/source/Tile';
|
|
29
|
+
import ImageSource from 'ol/source/Image';
|
|
30
|
+
import VectorSource from 'ol/source/Vector';
|
|
31
|
+
import { unByKey } from 'ol/Observable';
|
|
32
|
+
import { MAT_SNACK_BAR_DATA, MatSnackBarRef, MatSnackBar } from '@angular/material/snack-bar';
|
|
27
33
|
import * as i4 from '@angular/cdk/drag-drop';
|
|
28
34
|
import { moveItemInArray, transferArrayItem, DragDropModule } from '@angular/cdk/drag-drop';
|
|
29
35
|
import * as i1 from '@angular/material/form-field';
|
|
30
36
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
31
|
-
import * as
|
|
37
|
+
import * as i1$1 from '@angular/forms';
|
|
32
38
|
import { FormsModule } from '@angular/forms';
|
|
33
|
-
import * as
|
|
39
|
+
import * as i5 from '@angular/material/expansion';
|
|
34
40
|
import { MatExpansionModule } from '@angular/material/expansion';
|
|
35
41
|
import * as i6 from '@angular/material/input';
|
|
36
42
|
import { MatInputModule } from '@angular/material/input';
|
|
37
43
|
import ol_control_Control from 'ol/control/Control';
|
|
38
|
-
import
|
|
39
|
-
import
|
|
40
|
-
import ImageSource from 'ol/source/Image';
|
|
41
|
-
import VectorSource from 'ol/source/Vector';
|
|
42
|
-
import { unByKey } from 'ol/Observable';
|
|
43
|
-
import { MAT_SNACK_BAR_DATA, MatSnackBarRef, MatSnackBar } from '@angular/material/snack-bar';
|
|
44
|
+
import * as i7 from '@angular/material/tooltip';
|
|
45
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
44
46
|
import 'ol/ol.css';
|
|
45
47
|
import { LineString, Point } from 'ol/geom';
|
|
46
48
|
import { getArea, getLength } from 'ol/sphere';
|
|
47
|
-
import Draw from 'ol/interaction/Draw';
|
|
49
|
+
import Draw, { createBox, createRegularPolygon } from 'ol/interaction/Draw';
|
|
48
50
|
import { Snap, Select as Select$1, Modify } from 'ol/interaction';
|
|
49
|
-
import { Style, Circle, Stroke, Fill, Text } from 'ol/style';
|
|
51
|
+
import { Style, Circle, Stroke, Fill, Text, RegularShape } from 'ol/style';
|
|
50
52
|
import * as i4$1 from '@angular/material/core';
|
|
51
53
|
import { MatOptionModule } from '@angular/material/core';
|
|
52
54
|
import * as SLDReader from '@nieuwlandgeo/sldreader';
|
|
53
55
|
import WKT from 'ol/format/WKT';
|
|
54
|
-
import { extend, createEmpty, buffer as buffer$1 } from 'ol/extent';
|
|
55
56
|
import Feature$1 from 'ol/Feature';
|
|
56
57
|
import { never, always } from 'ol/events/condition';
|
|
57
|
-
import { buffer, featureCollection, difference, booleanIntersects, union } from '@turf/turf';
|
|
58
|
+
import { buffer, featureCollection, difference, booleanIntersects, union, point, booleanPointInPolygon, area } from '@turf/turf';
|
|
58
59
|
import GeoJSON from 'ol/format/GeoJSON';
|
|
59
|
-
import * as i7 from '@angular/material/tooltip';
|
|
60
|
-
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
61
60
|
import * as i8 from '@angular/material/slide-toggle';
|
|
62
61
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
63
62
|
import { Feature } from 'ol';
|
|
63
|
+
import { extend, createEmpty, buffer as buffer$1 } from 'ol/extent';
|
|
64
64
|
import Select from 'ol/interaction/Select';
|
|
65
65
|
import html2canvas from 'html2canvas-pro';
|
|
66
|
-
import
|
|
66
|
+
import CircleStyle from 'ol/style/Circle';
|
|
67
|
+
import { transform } from 'ol/proj';
|
|
68
|
+
import * as i2 from '@angular/material/button';
|
|
69
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
70
|
+
import * as i1$2 from '@angular/material/dialog';
|
|
71
|
+
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogTitle, MatDialogContent, MatDialogActions } from '@angular/material/dialog';
|
|
72
|
+
import * as i5$2 from '@angular/material/autocomplete';
|
|
67
73
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
74
|
+
import WFS from 'ol/format/WFS';
|
|
75
|
+
import { like } from 'ol/format/filter';
|
|
76
|
+
import { map as map$1 } from 'rxjs/operators';
|
|
77
|
+
import { createStringXY } from 'ol/coordinate';
|
|
68
78
|
|
|
69
79
|
const GISKOMPONENT_CONFIG = new InjectionToken('GisKomponentConfig');
|
|
70
80
|
|
|
@@ -116,83 +126,6 @@ class CopyrightControl extends Control {
|
|
|
116
126
|
}
|
|
117
127
|
}
|
|
118
128
|
|
|
119
|
-
class LayerHelperService {
|
|
120
|
-
activeLayersChanged = new BehaviorSubject(true);
|
|
121
|
-
_layerDbIdKey = 'layerDbId';
|
|
122
|
-
_layerGroupDbIdKey = 'layerGroupDbId';
|
|
123
|
-
_layerIdsToDisplayInMapKeyName = 'layerIdsToDisplayInMap';
|
|
124
|
-
setDbId(layer, id) {
|
|
125
|
-
layer.set(this._layerDbIdKey, id);
|
|
126
|
-
}
|
|
127
|
-
getDbId(layer) {
|
|
128
|
-
const dbId = layer.get(this._layerDbIdKey) ?? -1;
|
|
129
|
-
return +dbId;
|
|
130
|
-
}
|
|
131
|
-
setLayerGroupDbId(layer, id) {
|
|
132
|
-
layer.set(this._layerGroupDbIdKey, id);
|
|
133
|
-
}
|
|
134
|
-
getLayerGroupDbId(layer) {
|
|
135
|
-
const dbId = layer.get(this._layerGroupDbIdKey) ?? -1;
|
|
136
|
-
return +dbId;
|
|
137
|
-
}
|
|
138
|
-
applyCachedLayersToDisplayInMap(map, profileId) {
|
|
139
|
-
this.activeLayersChanged.next(true);
|
|
140
|
-
const layerIdsCachedToDisplay = localStorage.getItem(`${this._layerIdsToDisplayInMapKeyName}_${profileId}`)?.split(',');
|
|
141
|
-
if (layerIdsCachedToDisplay) {
|
|
142
|
-
//Bottom layers are rendered first, top layers are rendered last (on top)
|
|
143
|
-
layerIdsCachedToDisplay.reverse();
|
|
144
|
-
map.getLayers().getArray().forEach(layergroup => {
|
|
145
|
-
if (layergroup instanceof OLLayerGroup) {
|
|
146
|
-
layergroup.getLayers().getArray().forEach(l => {
|
|
147
|
-
if (!layerIdsCachedToDisplay.some(id => l.get(this._layerDbIdKey) == id)) {
|
|
148
|
-
const current = l.getVisible();
|
|
149
|
-
if (current) {
|
|
150
|
-
l.setVisible(!current);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
//Set z index to match the order in cache
|
|
155
|
-
l.setZIndex(layerIdsCachedToDisplay.indexOf(l.get(this._layerDbIdKey).toString()));
|
|
156
|
-
//console.log('layer id '+l.get(this._layerDbIdKey)+' - setZIndex:'+layerIdsCachedToDisplay.indexOf(l.get(this._layerDbIdKey).toString()));
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
updateLayerOpacityInMap(map, layer) {
|
|
164
|
-
map.getLayers().getArray().forEach(layergroup => {
|
|
165
|
-
if (layergroup instanceof OLLayerGroup) {
|
|
166
|
-
layergroup.getLayers().getArray().forEach(l => {
|
|
167
|
-
if (l.get(this._layerDbIdKey) === layer.id && layer.opacity) {
|
|
168
|
-
l.setOpacity(layer.opacity);
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
toggleLayerInMap(map, layer) {
|
|
175
|
-
map.getLayers().getArray().forEach(layergroup => {
|
|
176
|
-
if (layergroup instanceof OLLayerGroup) {
|
|
177
|
-
layergroup.getLayers().getArray().forEach(l => {
|
|
178
|
-
if (l.get(this._layerDbIdKey) === layer.id) {
|
|
179
|
-
const current = l.getVisible();
|
|
180
|
-
l.setVisible(!current);
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LayerHelperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
187
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LayerHelperService, providedIn: 'root' });
|
|
188
|
-
}
|
|
189
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LayerHelperService, decorators: [{
|
|
190
|
-
type: Injectable,
|
|
191
|
-
args: [{
|
|
192
|
-
providedIn: 'root'
|
|
193
|
-
}]
|
|
194
|
-
}] });
|
|
195
|
-
|
|
196
129
|
class LibNotificationComponent {
|
|
197
130
|
data = inject(MAT_SNACK_BAR_DATA);
|
|
198
131
|
_snackRef = inject((MatSnackBarRef));
|
|
@@ -257,6 +190,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
257
190
|
|
|
258
191
|
class LayerErrorService {
|
|
259
192
|
layerStatusChanged = new Subject();
|
|
193
|
+
layerErrored = new Subject();
|
|
260
194
|
layerStatuses = new Map();
|
|
261
195
|
listeners = new Map();
|
|
262
196
|
_errorService = inject(LibErrorService);
|
|
@@ -275,6 +209,7 @@ class LayerErrorService {
|
|
|
275
209
|
console.error(`[Layer ${layerId}] load error:`, event);
|
|
276
210
|
this._errorService.show(new Error(`Indlæsningsfejl for lag med id ${layerId}.`));
|
|
277
211
|
this.layerStatusChanged.next(layerId);
|
|
212
|
+
this.layerErrored.next(layerId);
|
|
278
213
|
};
|
|
279
214
|
const clearError = () => {
|
|
280
215
|
this.layerStatuses.set(layerId, { layerId, hasError: false });
|
|
@@ -324,6 +259,121 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
324
259
|
args: [{ providedIn: 'root' }]
|
|
325
260
|
}] });
|
|
326
261
|
|
|
262
|
+
class LayerHelperService {
|
|
263
|
+
activeLayersChanged = new BehaviorSubject(true);
|
|
264
|
+
_layerDbIdKey = 'layerDbId';
|
|
265
|
+
_layerGroupDbIdKey = 'layerGroupDbId';
|
|
266
|
+
_mapFilteredLayerGroupsKeyName = 'mapFilteredLayerGroups';
|
|
267
|
+
_layerErrorService = inject(LayerErrorService);
|
|
268
|
+
layerActivatedByBackgroundGroup = new Subject();
|
|
269
|
+
setDbId(layer, id) {
|
|
270
|
+
layer.set(this._layerDbIdKey, id);
|
|
271
|
+
}
|
|
272
|
+
getDbId(layer) {
|
|
273
|
+
const dbId = layer.get(this._layerDbIdKey) ?? -1;
|
|
274
|
+
return +dbId;
|
|
275
|
+
}
|
|
276
|
+
setLayerGroupDbId(layer, id) {
|
|
277
|
+
layer.set(this._layerGroupDbIdKey, id);
|
|
278
|
+
}
|
|
279
|
+
getLayerGroupDbId(layer) {
|
|
280
|
+
const dbId = layer.get(this._layerGroupDbIdKey) ?? -1;
|
|
281
|
+
return +dbId;
|
|
282
|
+
}
|
|
283
|
+
applyCachedLayersToDisplayInMap(map, profileId) {
|
|
284
|
+
this.activeLayersChanged.next(true);
|
|
285
|
+
const cacheValue = localStorage.getItem(`${this._mapFilteredLayerGroupsKeyName}_${profileId}`);
|
|
286
|
+
if (cacheValue) {
|
|
287
|
+
const layersCachedToDisplay = JSON.parse(cacheValue).cachedLayerGroups
|
|
288
|
+
.flatMap((lg) => lg.layers)
|
|
289
|
+
.map((l) => ({ id: l.id, visible: l.visible }));
|
|
290
|
+
//Bottom layers are rendered first, top layers are rendered last (on top)
|
|
291
|
+
layersCachedToDisplay.reverse();
|
|
292
|
+
map.getLayers().getArray().forEach(layergroup => {
|
|
293
|
+
if (layergroup instanceof OLLayerGroup) {
|
|
294
|
+
layergroup.getLayers().getArray().forEach(l => {
|
|
295
|
+
const cachedLayer = layersCachedToDisplay
|
|
296
|
+
.find((layer) => l.get(this._layerDbIdKey) == layer.id);
|
|
297
|
+
const current = l.getVisible();
|
|
298
|
+
if (cachedLayer != undefined && current != cachedLayer.visible) {
|
|
299
|
+
l.setVisible(cachedLayer.visible);
|
|
300
|
+
}
|
|
301
|
+
//Set z index to match the order in cache
|
|
302
|
+
l.setZIndex(layersCachedToDisplay.indexOf(cachedLayer));
|
|
303
|
+
//console.log('layer id '+l.get(this._layerDbIdKey)+' - setZIndex:'+layerIdsCachedToDisplay.indexOf(l.get(this._layerDbIdKey).toString()))
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
startFailoverForBackgroundGroup(aMap, groupId) {
|
|
310
|
+
const currentIndex$ = new BehaviorSubject(0);
|
|
311
|
+
const layergroup = aMap.getLayers().getArray()
|
|
312
|
+
.find(layergroup => layergroup instanceof OLLayerGroup && layergroup.get('id') === groupId);
|
|
313
|
+
const items = layergroup.getLayers().getArray().sort((a, b) => (b.getZIndex() ?? 0) - (a.getZIndex() ?? 0));
|
|
314
|
+
// Handles activating the current item
|
|
315
|
+
const activation$ = currentIndex$.pipe(tap(index => {
|
|
316
|
+
// deactivate all first
|
|
317
|
+
items.forEach(layer => layer.setVisible(false));
|
|
318
|
+
// if out of range, stop completely
|
|
319
|
+
if (index >= items.length) {
|
|
320
|
+
console.warn('No more items left. Stopping failover.');
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
// activate current
|
|
324
|
+
const layer = items[index];
|
|
325
|
+
console.log('Failover turning layer on:', layer.get(this._layerDbIdKey));
|
|
326
|
+
layer.setVisible(true);
|
|
327
|
+
this.layerActivatedByBackgroundGroup.next(layer.get(this._layerDbIdKey));
|
|
328
|
+
}),
|
|
329
|
+
// Listen for failures only while we have a valid index
|
|
330
|
+
switchMap(index => {
|
|
331
|
+
if (index >= items.length)
|
|
332
|
+
return EMPTY;
|
|
333
|
+
const currentItem = items[index];
|
|
334
|
+
return this._layerErrorService.layerErrored.pipe(tap(failedId => {
|
|
335
|
+
// If the current one failed, move to next
|
|
336
|
+
if (failedId === currentItem.get(this._layerDbIdKey)) {
|
|
337
|
+
console.log('Failover layer failed:', currentItem.get(this._layerDbIdKey));
|
|
338
|
+
currentIndex$.next(index + 1);
|
|
339
|
+
}
|
|
340
|
+
}));
|
|
341
|
+
}));
|
|
342
|
+
activation$.subscribe();
|
|
343
|
+
}
|
|
344
|
+
updateLayerOpacityInMap(map, layer) {
|
|
345
|
+
map.getLayers().getArray().forEach(layergroup => {
|
|
346
|
+
if (layergroup instanceof OLLayerGroup) {
|
|
347
|
+
layergroup.getLayers().getArray().forEach(l => {
|
|
348
|
+
if (l.get(this._layerDbIdKey) === layer.id && layer.opacity) {
|
|
349
|
+
l.setOpacity(layer.opacity);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
toggleLayerInMap(map, layerId) {
|
|
356
|
+
map.getLayers().getArray().forEach(layergroup => {
|
|
357
|
+
if (layergroup instanceof OLLayerGroup) {
|
|
358
|
+
layergroup.getLayers().getArray().forEach(l => {
|
|
359
|
+
if (l.get(this._layerDbIdKey) === layerId) {
|
|
360
|
+
const current = l.getVisible();
|
|
361
|
+
l.setVisible(!current);
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LayerHelperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
368
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LayerHelperService, providedIn: 'root' });
|
|
369
|
+
}
|
|
370
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LayerHelperService, decorators: [{
|
|
371
|
+
type: Injectable,
|
|
372
|
+
args: [{
|
|
373
|
+
providedIn: 'root'
|
|
374
|
+
}]
|
|
375
|
+
}] });
|
|
376
|
+
|
|
327
377
|
class LayerSelectorComponent {
|
|
328
378
|
set contentIcon(content) {
|
|
329
379
|
this._layerSelectorIcon = content;
|
|
@@ -340,17 +390,17 @@ class LayerSelectorComponent {
|
|
|
340
390
|
showLegend = false; // TO DO - this will be added later, as a change (probably as a Profile setting)
|
|
341
391
|
showSelector = false;
|
|
342
392
|
legendUrl = 'https://docs.geoserver.org/main/en/user/_images/samplelegend.png'; // TO DO - remove this (mockup for now, will be done as a change later)
|
|
343
|
-
_namesToGoLast = ['Baggrundskort'];
|
|
344
393
|
_layerSelectorIcon;
|
|
345
394
|
_layerSelectorIconControl;
|
|
346
395
|
_layerSelectorBody;
|
|
347
396
|
_layerSelectorBodyControl;
|
|
348
397
|
_mapFilteredLayerGroupsKeyName = 'mapFilteredLayerGroups';
|
|
349
|
-
_layerIdsToDisplayInMapKeyName = 'layerIdsToDisplayInMap';
|
|
350
398
|
_layerHelper = inject(LayerHelperService);
|
|
351
399
|
_layerErrorService = inject(LayerErrorService);
|
|
352
400
|
ngOnInit() {
|
|
353
|
-
this.
|
|
401
|
+
this._layerHelper.layerActivatedByBackgroundGroup
|
|
402
|
+
.subscribe(layerId => this.toggleLayer(layerId, undefined, true));
|
|
403
|
+
this._layerErrorService.layerErrored
|
|
354
404
|
.subscribe(layerId => {
|
|
355
405
|
const layerHasErrors = this._layerErrorService.getLayerStatus(layerId)?.hasError;
|
|
356
406
|
if (layerHasErrors != undefined)
|
|
@@ -384,16 +434,25 @@ class LayerSelectorComponent {
|
|
|
384
434
|
this.filteredLayerGroups = this.setfilteredGroups();
|
|
385
435
|
this._cacheProfileInfo();
|
|
386
436
|
}
|
|
437
|
+
// Apply Failover logic to all background groups
|
|
438
|
+
this.filteredLayerGroups.filter(group => group.background)
|
|
439
|
+
.forEach(group => {
|
|
440
|
+
group.layers.forEach(layer => layer.visible = false); //Turn all layers off in selector to begin with
|
|
441
|
+
group.visible = true; // Expand the group (there will be at least one active layer)
|
|
442
|
+
group.expanded = true;
|
|
443
|
+
this._layerHelper.startFailoverForBackgroundGroup(this.map, group.id);
|
|
444
|
+
});
|
|
387
445
|
this._initializeMapIconControl();
|
|
388
446
|
}
|
|
389
447
|
}
|
|
390
|
-
toggleLayer(event,
|
|
391
|
-
event
|
|
392
|
-
|
|
448
|
+
toggleLayer(layerId, event, skipMapToggle = false) {
|
|
449
|
+
event?.stopPropagation(); // Prevent the panel from expanding/collapsing
|
|
450
|
+
if (!skipMapToggle)
|
|
451
|
+
this._layerHelper.toggleLayerInMap(this.map, layerId);
|
|
393
452
|
// Toggle layer in all groups in the selector UI
|
|
394
453
|
this.filteredLayerGroups.forEach(group => {
|
|
395
454
|
group.layers.forEach(l => {
|
|
396
|
-
if (
|
|
455
|
+
if (layerId === l.id) {
|
|
397
456
|
l.visible = !l.visible;
|
|
398
457
|
}
|
|
399
458
|
});
|
|
@@ -415,23 +474,30 @@ class LayerSelectorComponent {
|
|
|
415
474
|
toggleGroup(event, layerGroup) {
|
|
416
475
|
event.stopPropagation(); // Prevent the panel from expanding/collapsing
|
|
417
476
|
const visible = !layerGroup.visible;
|
|
418
|
-
layerGroup.
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
477
|
+
if (visible && layerGroup.background) {
|
|
478
|
+
//Toggle background group on, apply failover logic
|
|
479
|
+
layerGroup.layers.forEach(layer => layer.visible = false); // Turn all off in selector to begin with
|
|
480
|
+
this._layerHelper.startFailoverForBackgroundGroup(this.map, layerGroup.id);
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
layerGroup.layers.forEach(layer => {
|
|
484
|
+
if (layer.visible != visible) {
|
|
485
|
+
//Toggle layer in map
|
|
486
|
+
this._layerHelper.toggleLayerInMap(this.map, layer.id);
|
|
487
|
+
// Toggle layer in all groups in the selector UI
|
|
488
|
+
this.filteredLayerGroups.forEach(group => {
|
|
489
|
+
group.layers.forEach(l => {
|
|
490
|
+
if (layer.id === l.id) {
|
|
491
|
+
l.visible = !l.visible;
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
group.noOfVisibleLayers = group.layers.filter(l => l.visible).length;
|
|
495
|
+
group.visible = group.layers.some(l => l.visible);
|
|
496
|
+
group.expanded = group.layers.some(l => l.visible);
|
|
428
497
|
});
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
});
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
}
|
|
435
501
|
layerGroup.visible = visible;
|
|
436
502
|
layerGroup.expanded = layerGroup.layers.some(l => l.visible);
|
|
437
503
|
this._cacheProfileInfo();
|
|
@@ -470,11 +536,9 @@ class LayerSelectorComponent {
|
|
|
470
536
|
})
|
|
471
537
|
.filter(g => g.layers.length > 0)
|
|
472
538
|
.sort((a, b) => {
|
|
473
|
-
|
|
474
|
-
const bIsLast = this._namesToGoLast.includes(b.name) || b.layers.some(layer => layer.background);
|
|
475
|
-
if (aIsLast && !bIsLast)
|
|
539
|
+
if (a.background && !b.background)
|
|
476
540
|
return 1;
|
|
477
|
-
if (!
|
|
541
|
+
if (!a.background && b.background)
|
|
478
542
|
return -1;
|
|
479
543
|
return a.sortOrder - b.sortOrder;
|
|
480
544
|
});
|
|
@@ -508,10 +572,6 @@ class LayerSelectorComponent {
|
|
|
508
572
|
_cacheProfileInfo() {
|
|
509
573
|
const cacheItem = { profile: this.profile, cachedLayerGroups: this.filteredLayerGroups };
|
|
510
574
|
localStorage.setItem(`${this._mapFilteredLayerGroupsKeyName}_${this.profile.id}`, JSON.stringify(cacheItem));
|
|
511
|
-
localStorage.setItem(`${this._layerIdsToDisplayInMapKeyName}_${this.profile.id}`, this.filteredLayerGroups
|
|
512
|
-
.flatMap(lg => lg.layers)
|
|
513
|
-
.filter(lg => lg.visible)
|
|
514
|
-
.map(lg => lg.id).join(','));
|
|
515
575
|
// Reflect new order in map
|
|
516
576
|
this._layerHelper.applyCachedLayersToDisplayInMap(this.map, this.profile.id);
|
|
517
577
|
}
|
|
@@ -539,12 +599,12 @@ class LayerSelectorComponent {
|
|
|
539
599
|
}));
|
|
540
600
|
}
|
|
541
601
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LayerSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
542
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: LayerSelectorComponent, isStandalone: true, selector: "lib-layer-selector", inputs: { map: "map", profile: "profile", currentZoomLevel: "currentZoomLevel" }, viewQueries: [{ propertyName: "contentIcon", first: true, predicate: ["layerSelectorIcon"], descendants: true }, { propertyName: "contentBody", first: true, predicate: ["layerSelectorBody"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #layerSelectorIcon id=\"layerSelector\" class=\"ol-unselectable ol-control layer-selector-icon\">\n <mat-icon (click)=\"toggleLayerSelector()\">layers</mat-icon>\n</div>\n<div #layerSelectorBody [class.display-none]=\"!showSelector\" class=\"layer-selector-body-wrapper\" cdkDrag cdkDragBoundary=\".map-container\">\n <div class=\"drag-handle-selector\" cdkDragHandle>\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"ol-unselectable ol-control layer-selector-body\">\n <div class=\"search-section\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Filtrer</mat-label>\n <input \n matInput \n type=\"text\" \n [(ngModel)]=\"searchText\" \n (ngModelChange)=\"filteredLayerGroups=setfilteredGroups()\"\n placeholder=\"Skriv for at filtrere...\"\n />\n </mat-form-field>\n <mat-icon (click)=\"clearSearchText()\">undo</mat-icon>\n </div>\n \n <div\n cdkDropList\n [cdkDropListData]=\"filteredLayerGroups\"\n (cdkDropListDropped)=\"dropGroup($event)\"\n class=\"item-list\">\n @for (group of filteredLayerGroups; track group.id; let gIndex = $index) {\n <div class=\"group\" cdkDrag cdkDragPreviewDisabled>\n <mat-expansion-panel [(expanded)]=\"group.expanded\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (group.expanded) {\n <mat-icon>arrow_upward</mat-icon>\n }\n @if (!group.expanded) {\n <mat-icon>arrow_downward</mat-icon> \n }\n {{ group.name }} \n <mat-icon class=\"lightbulb\">lightbulb</mat-icon>\n ({{ group.noOfVisibleLayers }}/{{ group.layers.length }})\n @if (group.visible) {\n <mat-icon (click)=\"toggleGroup($event, group)\" class=\"power-on\">power</mat-icon>(t\u00E6nd)\n }\n @if (!group.visible) {\n <mat-icon (click)=\"toggleGroup($event, group)\" class=\"power-off\">power_off</mat-icon>(sluk)\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n <!-- This is only shown during drag -->\n <!-- <div *cdkDragPreview class=\"drag-preview\">\n {{ group.name }}\n </div> -->\n\n <!-- Placeholder to avoid jump -->\n <!-- <div *cdkDragPlaceholder class=\"drag-placeholder\"></div> -->\n\n <div\n cdkDropList\n [cdkDropListData]=\"group.layers\"\n (cdkDropListDropped)=\"dropLayer($event, group)\"\n class=\"item-list\">\n @for (layer of group.layers; track layer.id; let iIndex = $index) {\n <mat-expansion-panel expanded=\"false\" [disabled]=\"!layer.description\"> \n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"item\" cdkDrag cdkDragPreviewDisabled>\n <div class=\"item-left\">\n <mat-icon class=\"drag-indicator\">drag_indicator</mat-icon>\n <span>{{ layer.name }}</span>\n </div>\n <div class=\"item-center\">\n @if (layer.maxZoom < currentZoomLevel || layer.minZoom > currentZoomLevel) {\n <mat-icon class=\"zoom-off\">browser_not_supported</mat-icon>\n <span class=\"icon-label\">(zoom)</span>\n }\n @if (layer.hasErrors) {\n <mat-icon class=\"zoom-off\">wifi_off</mat-icon>\n <span class=\"icon-label\">(fejle)</span>\n }\n </div>\n <div class=\"item-right\">\n @if (layer.visible) {\n <mat-icon (click)=\"toggleLayer($event, layer)\" class=\"power-on\">power</mat-icon>\n <span class=\"icon-label\">(t\u00E6nd)</span>\n }\n @if (!layer.visible) {\n <mat-icon (click)=\"toggleLayer($event, layer)\" class=\"power-off\">power_off</mat-icon>\n <span class=\"icon-label\">(sluk)</span>\n }\n <input \n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n [(ngModel)]=\"layer.opacity\"\n (click)=\"stopDrag($event)\"\n (input)=\"updateOpacity(layer)\"\n (mousedown)=\"stopDrag($event)\"\n (touchstart)=\"stopDrag($event)\"\n (pointerdown)=\"stopDrag($event)\"\n >\n </div>\n </div>\n </mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"item\">{{ layer.description }}</div>\n @if (showLegend) {\n <img [src]=\"legendUrl\" class=\"legend-thumbnail\"/>\n }\n </mat-expansion-panel>\n }\n </div>\n </mat-expansion-panel>\n </div>\n }\n </div>\n </div>\n</div>", styles: ["::ng-deep .layer-selector-icon{position:absolute;left:auto;right:1em;bottom:4.5em;z-index:1000}::ng-deep .layer-selector-icon mat-icon{display:flex;justify-content:center;align-items:center;cursor:pointer;transition:all .3s ease;outline:none;border:0;height:40px;border-radius:5px;width:40px;background:color-mix(in srgb,#000 60%,transparent);box-shadow:#0000004d 0 1px 4px -1px;font-size:2em;color:#fff}::ng-deep .layer-selector-icon mat-icon:hover{box-shadow:0 4px 12px #0003;color:#fff}.legend-thumbnail{max-width:200px;max-height:200px;width:auto;height:auto;border:2px solid #dee2e6;border-radius:6px;padding:6px}.layer-selector-body-wrapper{position:absolute;left:auto;right:4em;bottom:.2em;z-index:1000;cursor:grab;max-width:calc(100vw - 8em)}.layer-selector-body-wrapper.cdk-drag-dragging{opacity:.8;cursor:grab;z-index:1001}.layer-selector-body-wrapper .ol-control{border-radius:0}@media (max-width: 767px){.layer-selector-body-wrapper{right:.5em;bottom:4em;max-width:calc(100vw - 7em);left:.5em;width:calc(100vw - 7em)}}@media (min-width: 768px) and (max-width: 1024px){.layer-selector-body-wrapper{right:1em;bottom:4em;max-width:calc(100vw - 2em)}}.drag-handle-selector{display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,#000 60%,transparent);border-radius:4px 4px 0 0;padding:4px;cursor:grab;box-shadow:0 -2px 8px #0003}.drag-handle-selector mat-icon{color:#fff;font-size:20px;width:20px;height:20px}::ng-deep .layer-selector-body{position:relative;left:auto;right:auto;bottom:auto;z-index:auto;background:color-mix(in srgb,#000 60%,transparent);box-shadow:0 4px 20px #00000026;width:480px;max-width:100%;max-height:660px;overflow:hidden;display:flex;flex-direction:column}@media (max-width: 767px){::ng-deep .layer-selector-body{width:100%;max-height:60vh}}@media (min-width: 768px) and (max-width: 1024px){::ng-deep .layer-selector-body{width:100%;max-width:480px;max-height:50vh}}::ng-deep .layer-selector-body .search-section{display:flex;align-items:center;gap:6px;padding:8px 12px 6px}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section{padding:6px 8px 4px;gap:4px}}::ng-deep .layer-selector-body .search-section mat-form-field{flex:1}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-text-field-wrapper{padding-bottom:0}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-wrapper{padding-bottom:0;margin-bottom:0}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-form-field-infix{padding-bottom:6px;min-height:auto}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-outline{background:#fff}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-outline-thick{color:#1976d2}::ng-deep .layer-selector-body .search-section mat-form-field input{font-size:13px;padding:3px 0}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-form-field input{font-size:12px}}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-label{color:#fff;font-weight:500;font-size:13px}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-label{font-size:12px}}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-form-field-subscript-wrapper{height:0;margin-top:0}::ng-deep .layer-selector-body .search-section mat-icon{color:#fff;cursor:pointer;padding:6px;border-radius:4px;transition:all .2s ease;font-size:24px;width:24px;height:24px;display:flex;justify-content:center;align-items:center}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-icon{font-size:20px;width:20px;height:20px;padding:4px}}::ng-deep .layer-selector-body .search-section mat-icon:hover{color:#f9fafb}::ng-deep .layer-selector-body .item-list{flex:1;overflow-y:auto;padding:6px;max-height:660px;width:100%}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list{padding:4px;max-height:calc(60vh - 80px)}}@media (min-width: 768px) and (max-width: 1024px){::ng-deep .layer-selector-body .item-list{max-height:calc(70vh - 80px)}}::ng-deep .layer-selector-body .item-list .group{margin-bottom:6px;overflow:hidden;box-shadow:0 -2px 2px #4868b20a,0 2px 2px #6a6f7517,0 1px 2px #4868b214}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel{box-shadow:none!important;border-radius:0!important}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header{padding:0 11px;height:40px;background:color-mix(in srgb,#000 55%,transparent)}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header{padding:0 20px;height:36px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header:hover{background:color-mix(in srgb,#000 60%,transparent)!important}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title{align-items:center;gap:6px;font-weight:600;color:#fff;font-size:13px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title{gap:4px;font-size:11px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon{color:#fff;font-size:16px;width:16px;height:16px;transition:transform .2s ease}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon{font-size:14px;width:14px;height:14px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.lightbulb{color:#dfca0e}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.power-on{color:#4caf50}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.power-off{color:#f44336}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content{background:color-mix(in srgb,#000 40%,transparent)}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content .mat-expansion-panel-body{padding:4px 0}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content .mat-expansion-panel-body{padding:2px 0}}::ng-deep .layer-selector-body .item-list .group .item-list{padding:0;max-height:none}::ng-deep .layer-selector-body .item-list .group .item-list .item{width:100%;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:6px;padding:8px 12px;background:transparent;transition:all .2s ease;color:#fff;cursor:grab}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item{gap:4px;padding:6px 8px}}::ng-deep .layer-selector-body .item-list .group .item-list .item:last-child{border-bottom:none}::ng-deep .layer-selector-body .item-list .group .item-list .item:hover{background-color:transparent;transition:all .2s ease}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left{display:flex;align-items:center;gap:3px;flex:1;min-width:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left span{flex:1;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left span{font-size:11px}}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center{display:flex;align-items:center;gap:2px;flex-shrink:0;justify-content:center;position:relative;left:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center .icon-label{font-size:11px;opacity:.8;margin-right:4px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center .icon-label{font-size:9px;margin-right:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right{display:flex;align-items:center;flex:1;justify-content:flex-end;min-width:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right .icon-label{font-size:11px;opacity:.8;margin-right:4px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right .icon-label{font-size:9px;margin-right:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right input[type=range]{width:80px;height:4px;margin:0;flex-shrink:0}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right input[type=range]{width:60px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon{flex-shrink:0}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.drag-indicator{color:#fff;font-size:16px;width:16px;height:16px;cursor:grab}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.drag-indicator{font-size:14px;width:14px;height:14px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on{color:#4caf50;font-size:18px;width:18px;height:18px;cursor:pointer;padding:3px;border-radius:3px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on{font-size:16px;width:16px;height:16px;padding:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on:hover{background:#4caf5033}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off{color:#f44336;font-size:18px;width:18px;height:18px;cursor:pointer;padding:3px;border-radius:3px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off{font-size:16px;width:16px;height:16px;padding:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off:hover{background:#f4433633}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.zoom-off{color:#f44336;font-size:16px;width:16px;height:16px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.zoom-off{font-size:14px;width:14px;height:14px}}::ng-deep .mat-expansion-indicator svg{fill:#fff!important}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 15px #00000026;background:#fff;padding:10px 12px}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.item-list.cdk-drop-list-dragging .item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.power-on{color:#4caf50}.power-off{color:#f44336}.display-none{display:none}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar{width:8px;border-radius:10px;border:5px solid transparent}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-thumb{background:#0000004d;border:5px solid transparent;border-radius:10px;background-clip:padding-box}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-thumb:hover{background:#0006;background-clip:padding-box;border:3px solid transparent}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i4.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i4.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i3.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i3.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i3.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }] });
|
|
602
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: LayerSelectorComponent, isStandalone: true, selector: "lib-layer-selector", inputs: { map: "map", profile: "profile", currentZoomLevel: "currentZoomLevel" }, viewQueries: [{ propertyName: "contentIcon", first: true, predicate: ["layerSelectorIcon"], descendants: true }, { propertyName: "contentBody", first: true, predicate: ["layerSelectorBody"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #layerSelectorIcon id=\"layerSelector\" class=\"ol-unselectable ol-control layer-selector-icon\">\n <mat-icon (click)=\"toggleLayerSelector()\">layers</mat-icon>\n</div>\n<div #layerSelectorBody [class.display-none]=\"!showSelector\" class=\"layer-selector-body-wrapper\" cdkDrag cdkDragBoundary=\".map-container\">\n <div class=\"drag-handle-selector\" cdkDragHandle>\n <div class=\"drag-handle-content\">\n <div class=\"drag-handle-icons\">\n <mat-icon class=\"drag-indicator-right\">open_with</mat-icon>\n <mat-icon class=\"minimize-button\" (click)=\"toggleLayerSelector()\">minimize</mat-icon>\n </div>\n </div>\n </div>\n <div class=\"ol-unselectable ol-control layer-selector-body\">\n <div class=\"search-section\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Filtrer</mat-label>\n <input \n matInput \n type=\"text\" \n [(ngModel)]=\"searchText\" \n (ngModelChange)=\"filteredLayerGroups=setfilteredGroups()\"\n placeholder=\"Skriv for at filtrere...\"\n />\n </mat-form-field>\n <mat-icon (click)=\"clearSearchText()\">undo</mat-icon>\n </div>\n \n <div\n cdkDropList\n [cdkDropListData]=\"filteredLayerGroups\"\n (cdkDropListDropped)=\"dropGroup($event)\"\n class=\"item-list\">\n @for (group of filteredLayerGroups; track group.id; let gIndex = $index) {\n <div class=\"group\" cdkDrag cdkDragPreviewDisabled>\n <mat-expansion-panel [(expanded)]=\"group.expanded\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (group.expanded) {\n <mat-icon>arrow_upward</mat-icon>\n }\n @if (!group.expanded) {\n <mat-icon>arrow_downward</mat-icon> \n }\n {{ group.name }} \n <mat-icon class=\"lightbulb\">lightbulb</mat-icon>\n ({{ group.noOfVisibleLayers }}/{{ group.layers.length }})\n @if (group.visible) {\n <mat-icon (click)=\"toggleGroup($event, group)\" class=\"power-on\" \n matTooltip=\"T\u00E6nd\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">power_settings_new\n </mat-icon> \n }\n @if (!group.visible) {\n <mat-icon (click)=\"toggleGroup($event, group)\" class=\"power-off\"\n matTooltip=\"Sluk\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">power_settings_new\n </mat-icon>\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n <!-- This is only shown during drag -->\n <!-- <div *cdkDragPreview class=\"drag-preview\">\n {{ group.name }}\n </div> -->\n\n <!-- Placeholder to avoid jump -->\n <!-- <div *cdkDragPlaceholder class=\"drag-placeholder\"></div> -->\n\n <div\n cdkDropList\n [cdkDropListData]=\"group.layers\"\n (cdkDropListDropped)=\"dropLayer($event, group)\"\n class=\"item-list\">\n @for (layer of group.layers; track layer.id; let iIndex = $index) {\n <mat-expansion-panel expanded=\"false\" [disabled]=\"!layer.description\"> \n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"item\" cdkDrag cdkDragPreviewDisabled>\n <div class=\"item-left\">\n <mat-icon class=\"drag-indicator\">drag_indicator</mat-icon>\n <span>{{ layer.name }}</span>\n </div>\n <div class=\"item-center\">\n @if (layer.maxZoom < currentZoomLevel || layer.minZoom > currentZoomLevel) {\n <mat-icon class=\"zoom-off\" \n matTooltip=\"Zoom\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">browser_not_supported\n </mat-icon>\n }\n @if (layer.hasErrors) {\n <mat-icon class=\"zoom-off\" \n matTooltip=\"Fejl\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">priority_high\n </mat-icon>\n\n }\n </div>\n <div class=\"item-right\">\n @if (layer.visible) {\n <mat-icon (click)=\"toggleLayer(layer.id, $event)\" class=\"power-on\" \n matTooltip=\"T\u00E6nd\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">power_settings_new\n </mat-icon>\n }\n @if (!layer.visible) {\n <mat-icon (click)=\"toggleLayer(layer.id, $event)\" class=\"power-off\"\n matTooltip=\"Sluk\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">power_settings_new\n </mat-icon>\n }\n <input \n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n [(ngModel)]=\"layer.opacity\"\n (click)=\"stopDrag($event)\"\n (input)=\"updateOpacity(layer)\"\n (mousedown)=\"stopDrag($event)\"\n (touchstart)=\"stopDrag($event)\"\n (pointerdown)=\"stopDrag($event)\"\n >\n </div>\n </div>\n </mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"layer-description\">{{ layer.description }}</div>\n @if (showLegend) {\n <img [src]=\"legendUrl\" class=\"legend-thumbnail\"/>\n }\n </mat-expansion-panel>\n }\n </div>\n </mat-expansion-panel>\n </div>\n }\n </div>\n </div>\n</div>", styles: ["::ng-deep .layer-selector-icon{position:absolute;left:auto;right:1em;bottom:4.5em;z-index:1000}::ng-deep .layer-selector-icon mat-icon{display:flex;justify-content:center;align-items:center;cursor:pointer;transition:all .3s ease;outline:none;border:0;height:40px;border-radius:5px;width:40px;background:color-mix(in srgb,#000 60%,transparent);box-shadow:#0000004d 0 1px 4px -1px;font-size:2em;color:#fff}::ng-deep .layer-selector-icon mat-icon:hover{box-shadow:0 4px 12px #0003;color:#fff}.legend-thumbnail{max-width:200px;max-height:200px;width:auto;height:auto;border:2px solid #dee2e6;border-radius:6px;padding:6px}.layer-selector-body-wrapper{position:absolute;left:auto;right:4em;bottom:.2em;z-index:1000;cursor:grab;max-width:calc(100vw - 8em)}.layer-selector-body-wrapper.cdk-drag-dragging{opacity:.8;cursor:grab;z-index:1001}.layer-selector-body-wrapper .ol-control{border-radius:0}@media (max-width: 767px){.layer-selector-body-wrapper{right:.5em;bottom:4em;max-width:calc(100vw - 7em);left:.5em;width:calc(100vw - 7em)}}@media (min-width: 768px) and (max-width: 1024px){.layer-selector-body-wrapper{right:3.5em;bottom:.5em;max-width:calc(100vw - 2em)}}.drag-handle-selector{display:flex;align-items:center;justify-content:flex-end;border-radius:5px 5px 0 0;padding:5px;cursor:grab;background:color-mix(in srgb,#000 60%,transparent)}.drag-handle-content{display:flex;align-items:center;justify-content:flex-end;width:100%}.drag-handle-icons{display:flex;align-items:center;gap:16px}.drag-indicator-right{color:#fff;font-size:18px;width:18px;height:18px;cursor:grab;transition:all .2s ease}.minimize-button{color:#fff;font-size:18px;width:18px;height:18px;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;transform:translateY(-30%)}.minimize-button:hover{color:#fff;background:#ffffff26}::ng-deep .layer-selector-body{position:relative;left:auto;right:auto;bottom:auto;z-index:auto;background:color-mix(in srgb,#000 60%,transparent);box-shadow:0 4px 20px #00000026;width:480px;max-width:100%;max-height:700px;min-height:120px;overflow:hidden;display:flex;flex-direction:column}@media (max-width: 767px){::ng-deep .layer-selector-body{width:100%;max-height:70vh;min-height:140px}}@media (min-width: 768px) and (max-width: 1024px){::ng-deep .layer-selector-body{width:100%;max-width:445px;max-height:76vh;min-height:110px}}::ng-deep .layer-selector-body .search-section{display:flex;align-items:center;gap:6px;padding:8px 12px 6px}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section{padding:6px 8px 4px;gap:4px}}::ng-deep .layer-selector-body .search-section mat-form-field{flex:1}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-text-field-wrapper{padding-bottom:0;background:#000}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-wrapper{padding-bottom:0;margin-bottom:0}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-form-field-infix{padding-bottom:6px;min-height:auto}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-outline{background:#fff}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-outline-thick{color:#1976d2}::ng-deep .layer-selector-body .search-section mat-form-field input{font-size:13px;padding:3px 0}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-form-field input{font-size:12px}}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-label{color:#fff;font-weight:500;font-size:13px}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-label{font-size:12px}}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-form-field-subscript-wrapper{height:0;margin-top:0}::ng-deep .layer-selector-body .search-section mat-icon{color:#fff;cursor:pointer;padding:6px;border-radius:4px;transition:all .2s ease;font-size:24px;width:24px;height:24px;display:flex;justify-content:center;align-items:center}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-icon{font-size:20px;width:20px;height:20px;padding:4px}}::ng-deep .layer-selector-body .search-section mat-icon:hover{color:#f9fafb}::ng-deep .layer-selector-body .item-list{flex:1;overflow-y:auto;max-height:660px;width:100%}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list{padding:4px;max-height:calc(60vh - 80px)}}@media (min-width: 768px) and (max-width: 1024px){::ng-deep .layer-selector-body .item-list{max-height:calc(77vh - 78px)}}::ng-deep .layer-selector-body .item-list .group{overflow:hidden;box-shadow:0 -2px 2px #4868b20a,0 2px 2px #6a6f7517,0 1px 2px #4868b214}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel{box-shadow:none!important;border-radius:0!important}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header{padding:0 11px;height:40px;background:#000!important}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header:hover{background:#333!important}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header{padding:0 20px;height:36px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header:hover{background:color-mix(in srgb,#000 60%,transparent)!important}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title{align-items:center;gap:6px;font-weight:600;color:#bdc1c3cc;font-size:17px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title{gap:4px;font-size:11px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon{color:#bdc1c3cc;font-size:16px;width:16px;height:16px;transition:transform .2s ease}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon{font-size:14px;width:14px;height:14px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.lightbulb{color:#dfca0e}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.power-on{color:#4caf50}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.power-off{color:#f44336}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content{background:#4d4f55}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content .mat-expansion-panel-body{padding:4px 0;background:#000}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content .mat-expansion-panel-body{padding:2px 0}}::ng-deep .layer-selector-body .item-list .group .item-list{padding:0;max-height:none}::ng-deep .layer-selector-body .item-list .group .item-list .layer-description{font-size:13px;padding:0 31px;color:#fffc}::ng-deep .layer-selector-body .item-list .group .item-list .item{width:100%;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:6px;background:transparent;transition:all .2s ease;color:#fff;cursor:grab;font-size:14px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item{gap:4px;padding:6px 8px}}::ng-deep .layer-selector-body .item-list .group .item-list .item:last-child{border-bottom:none}::ng-deep .layer-selector-body .item-list .group .item-list .item:hover{background-color:transparent;transition:all .2s ease}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left{display:flex;align-items:center;gap:3px;flex:1;min-width:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left span{font-size:13px;word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;white-space:normal;flex:1;min-width:0;color:#fff}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left span{font-size:11px}}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center{display:flex;align-items:center;gap:2px;flex-shrink:0;justify-content:center;position:relative;left:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center .icon-label{font-size:11px;opacity:.8;margin-right:4px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center .icon-label{font-size:9px;margin-right:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right{display:flex;align-items:center;flex:1;justify-content:flex-end;min-width:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right input[type=range]{width:80px;height:4px;margin:0;flex-shrink:0}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right input[type=range]{width:60px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon{flex-shrink:0}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.drag-indicator{color:#fff;font-size:16px;width:16px;height:16px;cursor:grab}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.drag-indicator{font-size:14px;width:14px;height:14px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on{color:#4caf50;font-size:18px;width:18px;height:18px;cursor:pointer;padding:3px;border-radius:3px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on{font-size:16px;width:16px;height:16px;padding:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on:hover{background:#4caf5033}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off{color:#f44336;font-size:18px;width:18px;height:18px;cursor:pointer;padding:3px;border-radius:3px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off{font-size:16px;width:16px;height:16px;padding:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off:hover{background:#f4433633}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.zoom-off{color:#f44336;font-size:16px;width:16px;height:16px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.zoom-off{font-size:14px;width:14px;height:14px}}::ng-deep .mat-expansion-indicator svg{fill:#fff!important}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 15px #00000026;background:#fff;padding:10px 12px}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.item-list.cdk-drop-list-dragging .item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.power-on{color:#4caf50}.power-off{color:#f44336}.display-none{display:none}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar{width:12px}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-track{background:#757474;border-radius:8px}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-thumb{background:#1a1c1f;border-radius:8px;border:2px solid #2a2c30}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-thumb:hover{background:#0f1012}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-button{width:12px;height:16px;background:#2a2c30;border:1px solid #1a1c1f}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-button:vertical:decrement{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 4l-4 4h8z'/%3E%3C/svg%3E\") no-repeat center;border-radius:8px 8px 0 0}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-button:vertical:decrement:hover{background-color:#1a1c1f}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-button:vertical:increment{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 8l4-4H2z'/%3E%3C/svg%3E\") no-repeat center;border-radius:0 0 8px 8px}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-button:vertical:increment:hover{background-color:#1a1c1f}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i4.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i4.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i5.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i5.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i5.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
543
603
|
}
|
|
544
604
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LayerSelectorComponent, decorators: [{
|
|
545
605
|
type: Component,
|
|
546
606
|
args: [{ selector: 'lib-layer-selector', imports: [MatFormFieldModule, CommonModule, MatIconModule, FormsModule, DragDropModule,
|
|
547
|
-
MatExpansionModule, MatInputModule], template: "<div #layerSelectorIcon id=\"layerSelector\" class=\"ol-unselectable ol-control layer-selector-icon\">\n <mat-icon (click)=\"toggleLayerSelector()\">layers</mat-icon>\n</div>\n<div #layerSelectorBody [class.display-none]=\"!showSelector\" class=\"layer-selector-body-wrapper\" cdkDrag cdkDragBoundary=\".map-container\">\n <div class=\"drag-handle-selector\" cdkDragHandle>\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"ol-unselectable ol-control layer-selector-body\">\n <div class=\"search-section\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Filtrer</mat-label>\n <input \n matInput \n type=\"text\" \n [(ngModel)]=\"searchText\" \n (ngModelChange)=\"filteredLayerGroups=setfilteredGroups()\"\n placeholder=\"Skriv for at filtrere...\"\n />\n </mat-form-field>\n <mat-icon (click)=\"clearSearchText()\">undo</mat-icon>\n </div>\n \n <div\n cdkDropList\n [cdkDropListData]=\"filteredLayerGroups\"\n (cdkDropListDropped)=\"dropGroup($event)\"\n class=\"item-list\">\n @for (group of filteredLayerGroups; track group.id; let gIndex = $index) {\n <div class=\"group\" cdkDrag cdkDragPreviewDisabled>\n <mat-expansion-panel [(expanded)]=\"group.expanded\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (group.expanded) {\n <mat-icon>arrow_upward</mat-icon>\n }\n @if (!group.expanded) {\n <mat-icon>arrow_downward</mat-icon> \n }\n {{ group.name }} \n <mat-icon class=\"lightbulb\">lightbulb</mat-icon>\n ({{ group.noOfVisibleLayers }}/{{ group.layers.length }})\n @if (group.visible) {\n <mat-icon (click)=\"toggleGroup($event, group)\" class=\"power-on\">power</mat-icon>(t\u00E6nd)\n }\n @if (!group.visible) {\n <mat-icon (click)=\"toggleGroup($event, group)\" class=\"power-off\">power_off</mat-icon>(sluk)\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n <!-- This is only shown during drag -->\n <!-- <div *cdkDragPreview class=\"drag-preview\">\n {{ group.name }}\n </div> -->\n\n <!-- Placeholder to avoid jump -->\n <!-- <div *cdkDragPlaceholder class=\"drag-placeholder\"></div> -->\n\n <div\n cdkDropList\n [cdkDropListData]=\"group.layers\"\n (cdkDropListDropped)=\"dropLayer($event, group)\"\n class=\"item-list\">\n @for (layer of group.layers; track layer.id; let iIndex = $index) {\n <mat-expansion-panel expanded=\"false\" [disabled]=\"!layer.description\"> \n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"item\" cdkDrag cdkDragPreviewDisabled>\n <div class=\"item-left\">\n <mat-icon class=\"drag-indicator\">drag_indicator</mat-icon>\n <span>{{ layer.name }}</span>\n </div>\n <div class=\"item-center\">\n @if (layer.maxZoom < currentZoomLevel || layer.minZoom > currentZoomLevel) {\n <mat-icon class=\"zoom-off\">browser_not_supported</mat-icon>\n <span class=\"icon-label\">(zoom)</span>\n }\n @if (layer.hasErrors) {\n <mat-icon class=\"zoom-off\">wifi_off</mat-icon>\n <span class=\"icon-label\">(fejle)</span>\n }\n </div>\n <div class=\"item-right\">\n @if (layer.visible) {\n <mat-icon (click)=\"toggleLayer($event, layer)\" class=\"power-on\">power</mat-icon>\n <span class=\"icon-label\">(t\u00E6nd)</span>\n }\n @if (!layer.visible) {\n <mat-icon (click)=\"toggleLayer($event, layer)\" class=\"power-off\">power_off</mat-icon>\n <span class=\"icon-label\">(sluk)</span>\n }\n <input \n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n [(ngModel)]=\"layer.opacity\"\n (click)=\"stopDrag($event)\"\n (input)=\"updateOpacity(layer)\"\n (mousedown)=\"stopDrag($event)\"\n (touchstart)=\"stopDrag($event)\"\n (pointerdown)=\"stopDrag($event)\"\n >\n </div>\n </div>\n </mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"item\">{{ layer.description }}</div>\n @if (showLegend) {\n <img [src]=\"legendUrl\" class=\"legend-thumbnail\"/>\n }\n </mat-expansion-panel>\n }\n </div>\n </mat-expansion-panel>\n </div>\n }\n </div>\n </div>\n</div>", styles: ["::ng-deep .layer-selector-icon{position:absolute;left:auto;right:1em;bottom:4.5em;z-index:1000}::ng-deep .layer-selector-icon mat-icon{display:flex;justify-content:center;align-items:center;cursor:pointer;transition:all .3s ease;outline:none;border:0;height:40px;border-radius:5px;width:40px;background:color-mix(in srgb,#000 60%,transparent);box-shadow:#0000004d 0 1px 4px -1px;font-size:2em;color:#fff}::ng-deep .layer-selector-icon mat-icon:hover{box-shadow:0 4px 12px #0003;color:#fff}.legend-thumbnail{max-width:200px;max-height:200px;width:auto;height:auto;border:2px solid #dee2e6;border-radius:6px;padding:6px}.layer-selector-body-wrapper{position:absolute;left:auto;right:4em;bottom:.2em;z-index:1000;cursor:grab;max-width:calc(100vw - 8em)}.layer-selector-body-wrapper.cdk-drag-dragging{opacity:.8;cursor:grab;z-index:1001}.layer-selector-body-wrapper .ol-control{border-radius:0}@media (max-width: 767px){.layer-selector-body-wrapper{right:.5em;bottom:4em;max-width:calc(100vw - 7em);left:.5em;width:calc(100vw - 7em)}}@media (min-width: 768px) and (max-width: 1024px){.layer-selector-body-wrapper{right:1em;bottom:4em;max-width:calc(100vw - 2em)}}.drag-handle-selector{display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,#000 60%,transparent);border-radius:4px 4px 0 0;padding:4px;cursor:grab;box-shadow:0 -2px 8px #0003}.drag-handle-selector mat-icon{color:#fff;font-size:20px;width:20px;height:20px}::ng-deep .layer-selector-body{position:relative;left:auto;right:auto;bottom:auto;z-index:auto;background:color-mix(in srgb,#000 60%,transparent);box-shadow:0 4px 20px #00000026;width:480px;max-width:100%;max-height:660px;overflow:hidden;display:flex;flex-direction:column}@media (max-width: 767px){::ng-deep .layer-selector-body{width:100%;max-height:60vh}}@media (min-width: 768px) and (max-width: 1024px){::ng-deep .layer-selector-body{width:100%;max-width:480px;max-height:50vh}}::ng-deep .layer-selector-body .search-section{display:flex;align-items:center;gap:6px;padding:8px 12px 6px}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section{padding:6px 8px 4px;gap:4px}}::ng-deep .layer-selector-body .search-section mat-form-field{flex:1}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-text-field-wrapper{padding-bottom:0}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-wrapper{padding-bottom:0;margin-bottom:0}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-form-field-infix{padding-bottom:6px;min-height:auto}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-outline{background:#fff}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-outline-thick{color:#1976d2}::ng-deep .layer-selector-body .search-section mat-form-field input{font-size:13px;padding:3px 0}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-form-field input{font-size:12px}}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-label{color:#fff;font-weight:500;font-size:13px}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-label{font-size:12px}}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-form-field-subscript-wrapper{height:0;margin-top:0}::ng-deep .layer-selector-body .search-section mat-icon{color:#fff;cursor:pointer;padding:6px;border-radius:4px;transition:all .2s ease;font-size:24px;width:24px;height:24px;display:flex;justify-content:center;align-items:center}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-icon{font-size:20px;width:20px;height:20px;padding:4px}}::ng-deep .layer-selector-body .search-section mat-icon:hover{color:#f9fafb}::ng-deep .layer-selector-body .item-list{flex:1;overflow-y:auto;padding:6px;max-height:660px;width:100%}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list{padding:4px;max-height:calc(60vh - 80px)}}@media (min-width: 768px) and (max-width: 1024px){::ng-deep .layer-selector-body .item-list{max-height:calc(70vh - 80px)}}::ng-deep .layer-selector-body .item-list .group{margin-bottom:6px;overflow:hidden;box-shadow:0 -2px 2px #4868b20a,0 2px 2px #6a6f7517,0 1px 2px #4868b214}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel{box-shadow:none!important;border-radius:0!important}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header{padding:0 11px;height:40px;background:color-mix(in srgb,#000 55%,transparent)}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header{padding:0 20px;height:36px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header:hover{background:color-mix(in srgb,#000 60%,transparent)!important}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title{align-items:center;gap:6px;font-weight:600;color:#fff;font-size:13px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title{gap:4px;font-size:11px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon{color:#fff;font-size:16px;width:16px;height:16px;transition:transform .2s ease}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon{font-size:14px;width:14px;height:14px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.lightbulb{color:#dfca0e}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.power-on{color:#4caf50}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.power-off{color:#f44336}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content{background:color-mix(in srgb,#000 40%,transparent)}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content .mat-expansion-panel-body{padding:4px 0}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content .mat-expansion-panel-body{padding:2px 0}}::ng-deep .layer-selector-body .item-list .group .item-list{padding:0;max-height:none}::ng-deep .layer-selector-body .item-list .group .item-list .item{width:100%;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:6px;padding:8px 12px;background:transparent;transition:all .2s ease;color:#fff;cursor:grab}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item{gap:4px;padding:6px 8px}}::ng-deep .layer-selector-body .item-list .group .item-list .item:last-child{border-bottom:none}::ng-deep .layer-selector-body .item-list .group .item-list .item:hover{background-color:transparent;transition:all .2s ease}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left{display:flex;align-items:center;gap:3px;flex:1;min-width:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left span{flex:1;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left span{font-size:11px}}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center{display:flex;align-items:center;gap:2px;flex-shrink:0;justify-content:center;position:relative;left:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center .icon-label{font-size:11px;opacity:.8;margin-right:4px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center .icon-label{font-size:9px;margin-right:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right{display:flex;align-items:center;flex:1;justify-content:flex-end;min-width:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right .icon-label{font-size:11px;opacity:.8;margin-right:4px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right .icon-label{font-size:9px;margin-right:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right input[type=range]{width:80px;height:4px;margin:0;flex-shrink:0}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right input[type=range]{width:60px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon{flex-shrink:0}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.drag-indicator{color:#fff;font-size:16px;width:16px;height:16px;cursor:grab}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.drag-indicator{font-size:14px;width:14px;height:14px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on{color:#4caf50;font-size:18px;width:18px;height:18px;cursor:pointer;padding:3px;border-radius:3px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on{font-size:16px;width:16px;height:16px;padding:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on:hover{background:#4caf5033}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off{color:#f44336;font-size:18px;width:18px;height:18px;cursor:pointer;padding:3px;border-radius:3px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off{font-size:16px;width:16px;height:16px;padding:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off:hover{background:#f4433633}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.zoom-off{color:#f44336;font-size:16px;width:16px;height:16px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.zoom-off{font-size:14px;width:14px;height:14px}}::ng-deep .mat-expansion-indicator svg{fill:#fff!important}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 15px #00000026;background:#fff;padding:10px 12px}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.item-list.cdk-drop-list-dragging .item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.power-on{color:#4caf50}.power-off{color:#f44336}.display-none{display:none}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar{width:8px;border-radius:10px;border:5px solid transparent}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-thumb{background:#0000004d;border:5px solid transparent;border-radius:10px;background-clip:padding-box}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-thumb:hover{background:#0006;background-clip:padding-box;border:3px solid transparent}\n"] }]
|
|
607
|
+
MatExpansionModule, MatInputModule, MatTooltipModule], template: "<div #layerSelectorIcon id=\"layerSelector\" class=\"ol-unselectable ol-control layer-selector-icon\">\n <mat-icon (click)=\"toggleLayerSelector()\">layers</mat-icon>\n</div>\n<div #layerSelectorBody [class.display-none]=\"!showSelector\" class=\"layer-selector-body-wrapper\" cdkDrag cdkDragBoundary=\".map-container\">\n <div class=\"drag-handle-selector\" cdkDragHandle>\n <div class=\"drag-handle-content\">\n <div class=\"drag-handle-icons\">\n <mat-icon class=\"drag-indicator-right\">open_with</mat-icon>\n <mat-icon class=\"minimize-button\" (click)=\"toggleLayerSelector()\">minimize</mat-icon>\n </div>\n </div>\n </div>\n <div class=\"ol-unselectable ol-control layer-selector-body\">\n <div class=\"search-section\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Filtrer</mat-label>\n <input \n matInput \n type=\"text\" \n [(ngModel)]=\"searchText\" \n (ngModelChange)=\"filteredLayerGroups=setfilteredGroups()\"\n placeholder=\"Skriv for at filtrere...\"\n />\n </mat-form-field>\n <mat-icon (click)=\"clearSearchText()\">undo</mat-icon>\n </div>\n \n <div\n cdkDropList\n [cdkDropListData]=\"filteredLayerGroups\"\n (cdkDropListDropped)=\"dropGroup($event)\"\n class=\"item-list\">\n @for (group of filteredLayerGroups; track group.id; let gIndex = $index) {\n <div class=\"group\" cdkDrag cdkDragPreviewDisabled>\n <mat-expansion-panel [(expanded)]=\"group.expanded\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (group.expanded) {\n <mat-icon>arrow_upward</mat-icon>\n }\n @if (!group.expanded) {\n <mat-icon>arrow_downward</mat-icon> \n }\n {{ group.name }} \n <mat-icon class=\"lightbulb\">lightbulb</mat-icon>\n ({{ group.noOfVisibleLayers }}/{{ group.layers.length }})\n @if (group.visible) {\n <mat-icon (click)=\"toggleGroup($event, group)\" class=\"power-on\" \n matTooltip=\"T\u00E6nd\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">power_settings_new\n </mat-icon> \n }\n @if (!group.visible) {\n <mat-icon (click)=\"toggleGroup($event, group)\" class=\"power-off\"\n matTooltip=\"Sluk\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">power_settings_new\n </mat-icon>\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n <!-- This is only shown during drag -->\n <!-- <div *cdkDragPreview class=\"drag-preview\">\n {{ group.name }}\n </div> -->\n\n <!-- Placeholder to avoid jump -->\n <!-- <div *cdkDragPlaceholder class=\"drag-placeholder\"></div> -->\n\n <div\n cdkDropList\n [cdkDropListData]=\"group.layers\"\n (cdkDropListDropped)=\"dropLayer($event, group)\"\n class=\"item-list\">\n @for (layer of group.layers; track layer.id; let iIndex = $index) {\n <mat-expansion-panel expanded=\"false\" [disabled]=\"!layer.description\"> \n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"item\" cdkDrag cdkDragPreviewDisabled>\n <div class=\"item-left\">\n <mat-icon class=\"drag-indicator\">drag_indicator</mat-icon>\n <span>{{ layer.name }}</span>\n </div>\n <div class=\"item-center\">\n @if (layer.maxZoom < currentZoomLevel || layer.minZoom > currentZoomLevel) {\n <mat-icon class=\"zoom-off\" \n matTooltip=\"Zoom\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">browser_not_supported\n </mat-icon>\n }\n @if (layer.hasErrors) {\n <mat-icon class=\"zoom-off\" \n matTooltip=\"Fejl\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">priority_high\n </mat-icon>\n\n }\n </div>\n <div class=\"item-right\">\n @if (layer.visible) {\n <mat-icon (click)=\"toggleLayer(layer.id, $event)\" class=\"power-on\" \n matTooltip=\"T\u00E6nd\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">power_settings_new\n </mat-icon>\n }\n @if (!layer.visible) {\n <mat-icon (click)=\"toggleLayer(layer.id, $event)\" class=\"power-off\"\n matTooltip=\"Sluk\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"above\">power_settings_new\n </mat-icon>\n }\n <input \n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n [(ngModel)]=\"layer.opacity\"\n (click)=\"stopDrag($event)\"\n (input)=\"updateOpacity(layer)\"\n (mousedown)=\"stopDrag($event)\"\n (touchstart)=\"stopDrag($event)\"\n (pointerdown)=\"stopDrag($event)\"\n >\n </div>\n </div>\n </mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"layer-description\">{{ layer.description }}</div>\n @if (showLegend) {\n <img [src]=\"legendUrl\" class=\"legend-thumbnail\"/>\n }\n </mat-expansion-panel>\n }\n </div>\n </mat-expansion-panel>\n </div>\n }\n </div>\n </div>\n</div>", styles: ["::ng-deep .layer-selector-icon{position:absolute;left:auto;right:1em;bottom:4.5em;z-index:1000}::ng-deep .layer-selector-icon mat-icon{display:flex;justify-content:center;align-items:center;cursor:pointer;transition:all .3s ease;outline:none;border:0;height:40px;border-radius:5px;width:40px;background:color-mix(in srgb,#000 60%,transparent);box-shadow:#0000004d 0 1px 4px -1px;font-size:2em;color:#fff}::ng-deep .layer-selector-icon mat-icon:hover{box-shadow:0 4px 12px #0003;color:#fff}.legend-thumbnail{max-width:200px;max-height:200px;width:auto;height:auto;border:2px solid #dee2e6;border-radius:6px;padding:6px}.layer-selector-body-wrapper{position:absolute;left:auto;right:4em;bottom:.2em;z-index:1000;cursor:grab;max-width:calc(100vw - 8em)}.layer-selector-body-wrapper.cdk-drag-dragging{opacity:.8;cursor:grab;z-index:1001}.layer-selector-body-wrapper .ol-control{border-radius:0}@media (max-width: 767px){.layer-selector-body-wrapper{right:.5em;bottom:4em;max-width:calc(100vw - 7em);left:.5em;width:calc(100vw - 7em)}}@media (min-width: 768px) and (max-width: 1024px){.layer-selector-body-wrapper{right:3.5em;bottom:.5em;max-width:calc(100vw - 2em)}}.drag-handle-selector{display:flex;align-items:center;justify-content:flex-end;border-radius:5px 5px 0 0;padding:5px;cursor:grab;background:color-mix(in srgb,#000 60%,transparent)}.drag-handle-content{display:flex;align-items:center;justify-content:flex-end;width:100%}.drag-handle-icons{display:flex;align-items:center;gap:16px}.drag-indicator-right{color:#fff;font-size:18px;width:18px;height:18px;cursor:grab;transition:all .2s ease}.minimize-button{color:#fff;font-size:18px;width:18px;height:18px;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;transform:translateY(-30%)}.minimize-button:hover{color:#fff;background:#ffffff26}::ng-deep .layer-selector-body{position:relative;left:auto;right:auto;bottom:auto;z-index:auto;background:color-mix(in srgb,#000 60%,transparent);box-shadow:0 4px 20px #00000026;width:480px;max-width:100%;max-height:700px;min-height:120px;overflow:hidden;display:flex;flex-direction:column}@media (max-width: 767px){::ng-deep .layer-selector-body{width:100%;max-height:70vh;min-height:140px}}@media (min-width: 768px) and (max-width: 1024px){::ng-deep .layer-selector-body{width:100%;max-width:445px;max-height:76vh;min-height:110px}}::ng-deep .layer-selector-body .search-section{display:flex;align-items:center;gap:6px;padding:8px 12px 6px}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section{padding:6px 8px 4px;gap:4px}}::ng-deep .layer-selector-body .search-section mat-form-field{flex:1}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-text-field-wrapper{padding-bottom:0;background:#000}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-wrapper{padding-bottom:0;margin-bottom:0}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-form-field-infix{padding-bottom:6px;min-height:auto}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-outline{background:#fff}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-outline-thick{color:#1976d2}::ng-deep .layer-selector-body .search-section mat-form-field input{font-size:13px;padding:3px 0}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-form-field input{font-size:12px}}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-label{color:#fff;font-weight:500;font-size:13px}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-label{font-size:12px}}::ng-deep .layer-selector-body .search-section mat-form-field .mat-mdc-form-field-subscript-wrapper{height:0;margin-top:0}::ng-deep .layer-selector-body .search-section mat-icon{color:#fff;cursor:pointer;padding:6px;border-radius:4px;transition:all .2s ease;font-size:24px;width:24px;height:24px;display:flex;justify-content:center;align-items:center}@media (max-width: 767px){::ng-deep .layer-selector-body .search-section mat-icon{font-size:20px;width:20px;height:20px;padding:4px}}::ng-deep .layer-selector-body .search-section mat-icon:hover{color:#f9fafb}::ng-deep .layer-selector-body .item-list{flex:1;overflow-y:auto;max-height:660px;width:100%}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list{padding:4px;max-height:calc(60vh - 80px)}}@media (min-width: 768px) and (max-width: 1024px){::ng-deep .layer-selector-body .item-list{max-height:calc(77vh - 78px)}}::ng-deep .layer-selector-body .item-list .group{overflow:hidden;box-shadow:0 -2px 2px #4868b20a,0 2px 2px #6a6f7517,0 1px 2px #4868b214}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel{box-shadow:none!important;border-radius:0!important}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header{padding:0 11px;height:40px;background:#000!important}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header:hover{background:#333!important}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header{padding:0 20px;height:36px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header:hover{background:color-mix(in srgb,#000 60%,transparent)!important}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title{align-items:center;gap:6px;font-weight:600;color:#bdc1c3cc;font-size:17px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title{gap:4px;font-size:11px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon{color:#bdc1c3cc;font-size:16px;width:16px;height:16px;transition:transform .2s ease}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon{font-size:14px;width:14px;height:14px}}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.lightbulb{color:#dfca0e}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.power-on{color:#4caf50}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon.power-off{color:#f44336}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content{background:#4d4f55}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content .mat-expansion-panel-body{padding:4px 0;background:#000}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content .mat-expansion-panel-body{padding:2px 0}}::ng-deep .layer-selector-body .item-list .group .item-list{padding:0;max-height:none}::ng-deep .layer-selector-body .item-list .group .item-list .layer-description{font-size:13px;padding:0 31px;color:#fffc}::ng-deep .layer-selector-body .item-list .group .item-list .item{width:100%;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:6px;background:transparent;transition:all .2s ease;color:#fff;cursor:grab;font-size:14px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item{gap:4px;padding:6px 8px}}::ng-deep .layer-selector-body .item-list .group .item-list .item:last-child{border-bottom:none}::ng-deep .layer-selector-body .item-list .group .item-list .item:hover{background-color:transparent;transition:all .2s ease}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left{display:flex;align-items:center;gap:3px;flex:1;min-width:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left span{font-size:13px;word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;white-space:normal;flex:1;min-width:0;color:#fff}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-left span{font-size:11px}}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center{display:flex;align-items:center;gap:2px;flex-shrink:0;justify-content:center;position:relative;left:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center .icon-label{font-size:11px;opacity:.8;margin-right:4px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-center .icon-label{font-size:9px;margin-right:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right{display:flex;align-items:center;flex:1;justify-content:flex-end;min-width:0}::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right input[type=range]{width:80px;height:4px;margin:0;flex-shrink:0}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item .item-right input[type=range]{width:60px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon{flex-shrink:0}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.drag-indicator{color:#fff;font-size:16px;width:16px;height:16px;cursor:grab}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.drag-indicator{font-size:14px;width:14px;height:14px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on{color:#4caf50;font-size:18px;width:18px;height:18px;cursor:pointer;padding:3px;border-radius:3px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on{font-size:16px;width:16px;height:16px;padding:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on:hover{background:#4caf5033}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off{color:#f44336;font-size:18px;width:18px;height:18px;cursor:pointer;padding:3px;border-radius:3px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off{font-size:16px;width:16px;height:16px;padding:2px}}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off:hover{background:#f4433633}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.zoom-off{color:#f44336;font-size:16px;width:16px;height:16px}@media (max-width: 767px){::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.zoom-off{font-size:14px;width:14px;height:14px}}::ng-deep .mat-expansion-indicator svg{fill:#fff!important}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 15px #00000026;background:#fff;padding:10px 12px}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.item-list.cdk-drop-list-dragging .item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.power-on{color:#4caf50}.power-off{color:#f44336}.display-none{display:none}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar{width:12px}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-track{background:#757474;border-radius:8px}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-thumb{background:#1a1c1f;border-radius:8px;border:2px solid #2a2c30}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-thumb:hover{background:#0f1012}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-button{width:12px;height:16px;background:#2a2c30;border:1px solid #1a1c1f}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-button:vertical:decrement{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 4l-4 4h8z'/%3E%3C/svg%3E\") no-repeat center;border-radius:8px 8px 0 0}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-button:vertical:decrement:hover{background-color:#1a1c1f}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-button:vertical:increment{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 8l4-4H2z'/%3E%3C/svg%3E\") no-repeat center;border-radius:0 0 8px 8px}::ng-deep .layer-selector-body .item-list::-webkit-scrollbar-button:vertical:increment:hover{background-color:#1a1c1f}\n"] }]
|
|
548
608
|
}], propDecorators: { contentIcon: [{
|
|
549
609
|
type: ViewChild,
|
|
550
610
|
args: ['layerSelectorIcon', { static: false }]
|
|
@@ -625,7 +685,7 @@ class CurrentItemsService {
|
|
|
625
685
|
this._mapSubject.next(value);
|
|
626
686
|
}
|
|
627
687
|
profile;
|
|
628
|
-
_mapSubject = new ReplaySubject();
|
|
688
|
+
_mapSubject = new ReplaySubject(1);
|
|
629
689
|
map$ = this._mapSubject.asObservable();
|
|
630
690
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: CurrentItemsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
631
691
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: CurrentItemsService, providedIn: 'root' });
|
|
@@ -643,7 +703,8 @@ class DrawLayerSourceService {
|
|
|
643
703
|
features$ = this._features.asObservable();
|
|
644
704
|
source = new VectorSource();
|
|
645
705
|
layer = new VectorLayer({
|
|
646
|
-
source: this.source
|
|
706
|
+
source: this.source,
|
|
707
|
+
zIndex: 999
|
|
647
708
|
});
|
|
648
709
|
_disabled = false;
|
|
649
710
|
constructor() {
|
|
@@ -706,9 +767,6 @@ class FeatureHelperService {
|
|
|
706
767
|
_idCounter = 0;
|
|
707
768
|
isLocked = (feature) => feature.get(this.FEATURE_LOCKED) === 'true';
|
|
708
769
|
lock(feature) { feature.set(this.FEATURE_LOCKED, 'true'); }
|
|
709
|
-
constructor() {
|
|
710
|
-
console.log('FeatureHelperService, constructor');
|
|
711
|
-
}
|
|
712
770
|
setTypeId(feature, typeId) {
|
|
713
771
|
feature.set(this.FEATURE_TYPE_ID, typeId);
|
|
714
772
|
}
|
|
@@ -724,7 +782,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
724
782
|
args: [{
|
|
725
783
|
providedIn: 'root'
|
|
726
784
|
}]
|
|
727
|
-
}]
|
|
785
|
+
}] });
|
|
728
786
|
|
|
729
787
|
class UndoRedoService {
|
|
730
788
|
_drawlayerSourceService;
|
|
@@ -812,7 +870,7 @@ class GeometrySplitService {
|
|
|
812
870
|
const bufferedLine = buffer(lineGeoJSON, bufferMeters, { units: 'meters' });
|
|
813
871
|
// Move back to 25832
|
|
814
872
|
bufferedLine.geometry.coordinates = bufferedLine.geometry.coordinates.map(a => a.map(c => proj4('EPSG:4326', 'EPSG:25832', c)));
|
|
815
|
-
const overlappingFeatures = vectorSource.getFeatures().filter(f => f.getGeometry()?.intersectsExtent(lineFeature.getGeometry()?.getExtent()));
|
|
873
|
+
const overlappingFeatures = vectorSource.getFeatures().filter(f => !this._featureHelper.isLocked(f) && f.getGeometry()?.intersectsExtent(lineFeature.getGeometry()?.getExtent()));
|
|
816
874
|
overlappingFeatures.forEach((feature) => {
|
|
817
875
|
const overlappingFeatureGeoJson = this.geoJsonFormat.writeFeatureObject(feature);
|
|
818
876
|
const features = featureCollection([overlappingFeatureGeoJson, bufferedLine]);
|
|
@@ -867,10 +925,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
867
925
|
}]
|
|
868
926
|
}] });
|
|
869
927
|
|
|
870
|
-
class
|
|
871
|
-
|
|
872
|
-
console.log('highlightservice, constructor');
|
|
873
|
-
}
|
|
928
|
+
class HighlightService {
|
|
929
|
+
_wktFormat = new WKT();
|
|
874
930
|
_zoomService = inject(ZoomService);
|
|
875
931
|
_style = new Style({
|
|
876
932
|
stroke: new Stroke({
|
|
@@ -896,7 +952,7 @@ class highlightService {
|
|
|
896
952
|
}
|
|
897
953
|
highlight(feature, zoomToFeatures = true) {
|
|
898
954
|
if (!Array.isArray(feature)) {
|
|
899
|
-
this.highlight([feature]);
|
|
955
|
+
this.highlight([this._ensureFeature(feature)]);
|
|
900
956
|
return;
|
|
901
957
|
}
|
|
902
958
|
// If the feature has a style, it overwrites the style of the layer, so I create a new feature without properties or style.
|
|
@@ -905,15 +961,24 @@ class highlightService {
|
|
|
905
961
|
this._zoomService.zoomToFeatures(feature);
|
|
906
962
|
}
|
|
907
963
|
}
|
|
908
|
-
|
|
909
|
-
|
|
964
|
+
_ensureFeature(feature) {
|
|
965
|
+
if (typeof feature === 'string') {
|
|
966
|
+
const newFeature = this._wktFormat.readFeature(feature, { dataProjection: 'EPSG:25832', featureProjection: 'EPSG:25832' });
|
|
967
|
+
return newFeature;
|
|
968
|
+
}
|
|
969
|
+
else {
|
|
970
|
+
return feature;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: HighlightService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
974
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: HighlightService, providedIn: 'root' });
|
|
910
975
|
}
|
|
911
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type:
|
|
976
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: HighlightService, decorators: [{
|
|
912
977
|
type: Injectable,
|
|
913
978
|
args: [{
|
|
914
979
|
providedIn: 'root'
|
|
915
980
|
}]
|
|
916
|
-
}]
|
|
981
|
+
}] });
|
|
917
982
|
|
|
918
983
|
class InteractionHelperService {
|
|
919
984
|
_current = inject(CurrentItemsService);
|
|
@@ -950,6 +1015,9 @@ class MergeFeaturesService {
|
|
|
950
1015
|
formatter = new GeoJSON();
|
|
951
1016
|
_formatterOptions = { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:25832' };
|
|
952
1017
|
_selectFilter(f, typeId) {
|
|
1018
|
+
if (this._featureHelper.isLocked(f)) {
|
|
1019
|
+
return false;
|
|
1020
|
+
}
|
|
953
1021
|
if (this._selectedMergeFeature) {
|
|
954
1022
|
const previusFeatureObject = this.formatter.writeFeatureObject(this._selectedMergeFeature, this._formatterOptions);
|
|
955
1023
|
const bufferedPreviouslySelected = buffer(previusFeatureObject, 5, { units: 'centimeters' });
|
|
@@ -1023,26 +1091,11 @@ class IconsConstants {
|
|
|
1023
1091
|
|
|
1024
1092
|
class PrintDrawLayerSourceService {
|
|
1025
1093
|
_current = inject(CurrentItemsService);
|
|
1026
|
-
// private _features = new Subject<Feature[]>;
|
|
1027
|
-
// features$ = this._features.asObservable();
|
|
1028
1094
|
source = new VectorSource();
|
|
1029
1095
|
layer = new VectorLayer({
|
|
1030
1096
|
source: this.source,
|
|
1031
|
-
|
|
1032
|
-
stroke: new Stroke({
|
|
1033
|
-
color: 'blue',
|
|
1034
|
-
width: 2
|
|
1035
|
-
}),
|
|
1036
|
-
text: new Text({
|
|
1037
|
-
text: 'MySpecialText',
|
|
1038
|
-
font: '12px Calibri,sans-serif',
|
|
1039
|
-
fill: new Fill({ color: '#000' }),
|
|
1040
|
-
stroke: new Stroke({ color: '#fff', width: 3 }),
|
|
1041
|
-
placement: 'line'
|
|
1042
|
-
})
|
|
1043
|
-
})
|
|
1097
|
+
zIndex: 999
|
|
1044
1098
|
});
|
|
1045
|
-
// private _disabled = false;
|
|
1046
1099
|
constructor() {
|
|
1047
1100
|
this.layer.set('PRINTDRAWLAYER', 'true');
|
|
1048
1101
|
this._initListener();
|
|
@@ -1050,15 +1103,9 @@ class PrintDrawLayerSourceService {
|
|
|
1050
1103
|
_initListener() {
|
|
1051
1104
|
this._current.map$.subscribe({
|
|
1052
1105
|
next: map => {
|
|
1053
|
-
console.log("🚀 ~ PrintDrawLayerSourceService ~ _initListener ~ map:", map);
|
|
1054
1106
|
map.addLayer(this.layer);
|
|
1055
1107
|
}
|
|
1056
1108
|
});
|
|
1057
|
-
// this.source.on(['addfeature', 'changefeature', 'removefeature'], evt => {
|
|
1058
|
-
// if (this._disabled) { return; }
|
|
1059
|
-
// const features = this.source.getFeatures();
|
|
1060
|
-
// this._features.next(features);
|
|
1061
|
-
// });
|
|
1062
1109
|
}
|
|
1063
1110
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PrintDrawLayerSourceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1064
1111
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PrintDrawLayerSourceService, providedIn: 'root' });
|
|
@@ -1070,6 +1117,203 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
1070
1117
|
}]
|
|
1071
1118
|
}], ctorParameters: () => [] });
|
|
1072
1119
|
|
|
1120
|
+
class CenterPointService {
|
|
1121
|
+
_settingsHelper = inject(KomponentSettingsHelperService);
|
|
1122
|
+
_current = inject(CurrentItemsService);
|
|
1123
|
+
_drawLayerService = inject(DrawLayerSourceService);
|
|
1124
|
+
_interactionHelper = inject(InteractionHelperService);
|
|
1125
|
+
_geoJson = new GeoJSON();
|
|
1126
|
+
_snackbar = inject(MatSnackBar);
|
|
1127
|
+
_featureHelper = inject(FeatureHelperService);
|
|
1128
|
+
handleFeatureDeleted(featureId) {
|
|
1129
|
+
const centerFeature = this._drawLayerService.source.getFeatures().find(f => f.get('_parentPolyId') == featureId);
|
|
1130
|
+
if (centerFeature) {
|
|
1131
|
+
this._drawLayerService.remove(centerFeature.getId());
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
setCenterPoint(style, withinPolygon, callBack) {
|
|
1135
|
+
const style$ = this._settingsHelper.getStyle(style, this._current.profile.styleRepositoryWorkspace, this._current.profile.styleRepositoryGeoserver, 'Point');
|
|
1136
|
+
combineLatest([style$, this._current.map$]).subscribe({
|
|
1137
|
+
next: ([loadedStyle, map]) => {
|
|
1138
|
+
let parentPolyId;
|
|
1139
|
+
const centerDraw = new Draw({
|
|
1140
|
+
type: 'Point',
|
|
1141
|
+
source: this._drawLayerService.source,
|
|
1142
|
+
condition: evt => {
|
|
1143
|
+
if (!withinPolygon) {
|
|
1144
|
+
return true;
|
|
1145
|
+
}
|
|
1146
|
+
// The center needs to be inside a feature, so since turf is great for figuring out if something is in something, move the click and features to EPSG:4326
|
|
1147
|
+
const lonlat = transform(evt.coordinate, 'EPSG:25832', 'EPSG:4326');
|
|
1148
|
+
const pt = point(lonlat);
|
|
1149
|
+
const polygons = this._drawLayerService.source.getFeatures().filter(f => f.getGeometry() && f.getGeometry().getType() === 'Polygon'); // No point in checking linestrings and points
|
|
1150
|
+
const features = this._geoJson.writeFeaturesObject(polygons, { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:25832' });
|
|
1151
|
+
const parentPoly = features.features.find(f => booleanPointInPolygon(pt, f));
|
|
1152
|
+
if (!parentPoly) {
|
|
1153
|
+
this._snackbar.open('Centerpunktet skal være inde i en flade', '', { duration: 3000 });
|
|
1154
|
+
return false;
|
|
1155
|
+
}
|
|
1156
|
+
// Save the parent polygon's id on the center. If the parent is deleted, the point will be deleted too
|
|
1157
|
+
parentPolyId = parentPoly.id;
|
|
1158
|
+
return !!parentPoly;
|
|
1159
|
+
},
|
|
1160
|
+
style: loadedStyle
|
|
1161
|
+
});
|
|
1162
|
+
this._interactionHelper.setAsTemp(centerDraw);
|
|
1163
|
+
map.addInteraction(centerDraw);
|
|
1164
|
+
centerDraw.on('drawend', evt => {
|
|
1165
|
+
const existing = this._drawLayerService.source.getFeatures().filter(f => f.get('centerpoint') === true);
|
|
1166
|
+
// There can only be ONE centerpoint, so remove previous if exists
|
|
1167
|
+
if (existing) {
|
|
1168
|
+
this._drawLayerService.source.removeFeatures(existing);
|
|
1169
|
+
}
|
|
1170
|
+
// Mark feature as centerpoint - this is to find it again an remove
|
|
1171
|
+
evt.feature.set('centerpoint', true);
|
|
1172
|
+
evt.feature.set('_parentPolyId', parentPolyId);
|
|
1173
|
+
this._featureHelper.setId(evt.feature);
|
|
1174
|
+
callBack();
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
});
|
|
1178
|
+
}
|
|
1179
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: CenterPointService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1180
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: CenterPointService, providedIn: 'root' });
|
|
1181
|
+
}
|
|
1182
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: CenterPointService, decorators: [{
|
|
1183
|
+
type: Injectable,
|
|
1184
|
+
args: [{
|
|
1185
|
+
providedIn: 'root'
|
|
1186
|
+
}]
|
|
1187
|
+
}] });
|
|
1188
|
+
|
|
1189
|
+
class ConfirmDialogComponent {
|
|
1190
|
+
dialogRef;
|
|
1191
|
+
data;
|
|
1192
|
+
constructor(dialogRef, data) {
|
|
1193
|
+
this.dialogRef = dialogRef;
|
|
1194
|
+
this.data = data;
|
|
1195
|
+
}
|
|
1196
|
+
choose(choice) {
|
|
1197
|
+
this.dialogRef.close(choice);
|
|
1198
|
+
}
|
|
1199
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ConfirmDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
1200
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ConfirmDialogComponent, isStandalone: true, selector: "app-confirm-dialog", ngImport: i0, template: "\n@if(data.title) {\n <h2 mat-dialog-title>{{ data.title }}</h2>\n}\n<mat-dialog-content>\n <p>{{ data.message }}</p>\n</mat-dialog-content>\n\n<mat-dialog-actions align=\"end\">\n <!-- Sekund\u00E6r handling -->\n <button mat-button (click)=\"choose('secondary')\">\n {{ data.secondaryText }}\n </button>\n\n <!-- Prim\u00E6r handling -->\n <button mat-raised-button color=\"primary\" (click)=\"choose('primary')\">\n {{ data.primaryText }}\n </button>\n</mat-dialog-actions>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] });
|
|
1201
|
+
}
|
|
1202
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
|
|
1203
|
+
type: Component,
|
|
1204
|
+
args: [{ selector: 'app-confirm-dialog', imports: [CommonModule, MatDialogModule, MatButtonModule, MatDialogTitle, MatDialogContent, MatDialogActions], template: "\n@if(data.title) {\n <h2 mat-dialog-title>{{ data.title }}</h2>\n}\n<mat-dialog-content>\n <p>{{ data.message }}</p>\n</mat-dialog-content>\n\n<mat-dialog-actions align=\"end\">\n <!-- Sekund\u00E6r handling -->\n <button mat-button (click)=\"choose('secondary')\">\n {{ data.secondaryText }}\n </button>\n\n <!-- Prim\u00E6r handling -->\n <button mat-raised-button color=\"primary\" (click)=\"choose('primary')\">\n {{ data.primaryText }}\n </button>\n</mat-dialog-actions>\n" }]
|
|
1205
|
+
}], ctorParameters: () => [{ type: i1$2.MatDialogRef }, { type: undefined, decorators: [{
|
|
1206
|
+
type: Inject,
|
|
1207
|
+
args: [MAT_DIALOG_DATA]
|
|
1208
|
+
}] }] });
|
|
1209
|
+
|
|
1210
|
+
class ConfirmDialogService {
|
|
1211
|
+
dialog;
|
|
1212
|
+
constructor(dialog) {
|
|
1213
|
+
this.dialog = dialog;
|
|
1214
|
+
}
|
|
1215
|
+
open(data) {
|
|
1216
|
+
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
|
|
1217
|
+
width: '400px',
|
|
1218
|
+
disableClose: !!data.disableClose,
|
|
1219
|
+
data
|
|
1220
|
+
});
|
|
1221
|
+
return dialogRef.afterClosed();
|
|
1222
|
+
}
|
|
1223
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ConfirmDialogService, deps: [{ token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1224
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ConfirmDialogService, providedIn: 'root' });
|
|
1225
|
+
}
|
|
1226
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ConfirmDialogService, decorators: [{
|
|
1227
|
+
type: Injectable,
|
|
1228
|
+
args: [{ providedIn: 'root' }]
|
|
1229
|
+
}], ctorParameters: () => [{ type: i1$2.MatDialog }] });
|
|
1230
|
+
|
|
1231
|
+
class OverlapService {
|
|
1232
|
+
_drawLayerService = inject(DrawLayerSourceService);
|
|
1233
|
+
_featureHelper = inject(FeatureHelperService);
|
|
1234
|
+
_snackbar = inject(MatSnackBar);
|
|
1235
|
+
_confirmService = inject(ConfirmDialogService);
|
|
1236
|
+
handleOverlap(feature) {
|
|
1237
|
+
const geoJsonFormat = new GeoJSON();
|
|
1238
|
+
const epsilon = 0.1;
|
|
1239
|
+
const overlappingLockedFeatures = this._drawLayerService.source.getFeatures().filter(f => this._featureHelper.isLocked(f) && f.getGeometry()?.intersectsExtent(feature.getGeometry().getExtent()));
|
|
1240
|
+
let newFeatureGeoJson = geoJsonFormat.writeFeatureObject(feature);
|
|
1241
|
+
const orgFeatureArea = area(newFeatureGeoJson);
|
|
1242
|
+
if (overlappingLockedFeatures.length > 0) {
|
|
1243
|
+
const overlappingLockedFeaturesAsGeoJson = overlappingLockedFeatures.map(f => geoJsonFormat.writeFeatureObject(f));
|
|
1244
|
+
const features = featureCollection([newFeatureGeoJson, ...overlappingLockedFeaturesAsGeoJson]);
|
|
1245
|
+
const clipped = difference(features);
|
|
1246
|
+
if (clipped) {
|
|
1247
|
+
const clippedArea = area(clipped.geometry);
|
|
1248
|
+
// The overlap is done by checking extent. To make sure there's an actual change, I check if the areas are diffent
|
|
1249
|
+
// but sometimes, the calculations of the same area can be a bit of. Like 0.01. To make sure that doesn't register as a change
|
|
1250
|
+
// I check that there's actually a change.
|
|
1251
|
+
const actuallyClipped = Math.abs(orgFeatureArea - clippedArea) > epsilon;
|
|
1252
|
+
if (actuallyClipped) {
|
|
1253
|
+
const geom = geoJsonFormat.readGeometry(clipped.geometry);
|
|
1254
|
+
feature.setGeometry(geom);
|
|
1255
|
+
this._snackbar.open("Der var overlap med låste flader, så den indtegnede flade er blevet beskåret", '', { duration: 3000 });
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
// Handle the unlocked.
|
|
1260
|
+
const overlappingUnlockedFeatures = this._drawLayerService.source.getFeatures().filter(f => !this._featureHelper.isLocked(f) && f.getGeometry()?.intersectsExtent(feature.getGeometry().getExtent()));
|
|
1261
|
+
if (overlappingUnlockedFeatures.length === 0) {
|
|
1262
|
+
return of(feature);
|
|
1263
|
+
}
|
|
1264
|
+
else {
|
|
1265
|
+
newFeatureGeoJson = geoJsonFormat.writeFeatureObject(feature);
|
|
1266
|
+
const newFeatureArea = area(newFeatureGeoJson);
|
|
1267
|
+
const unlockedFeaturesAsGeoJson = overlappingUnlockedFeatures.map(f => geoJsonFormat.writeFeatureObject(f));
|
|
1268
|
+
const newClippedFeature = difference(featureCollection([newFeatureGeoJson, ...unlockedFeaturesAsGeoJson]));
|
|
1269
|
+
const areaNewClippedFeature = area(newClippedFeature);
|
|
1270
|
+
if (Math.abs(newFeatureArea - areaNewClippedFeature) < epsilon) {
|
|
1271
|
+
return of(feature);
|
|
1272
|
+
}
|
|
1273
|
+
else {
|
|
1274
|
+
const open$ = this._confirmService.open({
|
|
1275
|
+
primaryText: 'Nye',
|
|
1276
|
+
secondaryText: 'Eksisterende',
|
|
1277
|
+
disableClose: true,
|
|
1278
|
+
message: 'Den nye flade overlapper med eksisterende flade. Ønsker du at beskære de nye eller de eksisterende?',
|
|
1279
|
+
title: 'Beskæring'
|
|
1280
|
+
});
|
|
1281
|
+
return open$.pipe(map(msg => {
|
|
1282
|
+
if (msg === 'primary') {
|
|
1283
|
+
const newGeometry = geoJsonFormat.readGeometry(newClippedFeature.geometry);
|
|
1284
|
+
feature.setGeometry(newGeometry);
|
|
1285
|
+
return feature;
|
|
1286
|
+
}
|
|
1287
|
+
else {
|
|
1288
|
+
unlockedFeaturesAsGeoJson.forEach(f => {
|
|
1289
|
+
const featureArea = area(f.geometry);
|
|
1290
|
+
const fc = featureCollection([f, newFeatureGeoJson]);
|
|
1291
|
+
const featureDiff = difference(fc);
|
|
1292
|
+
const featureDiffArea = area(featureDiff.geometry);
|
|
1293
|
+
if (Math.abs(featureArea - featureDiffArea) > epsilon) {
|
|
1294
|
+
const existingFeature = this._drawLayerService.source.getFeatureById(f.id);
|
|
1295
|
+
if (existingFeature) {
|
|
1296
|
+
const newGeometry = geoJsonFormat.readGeometry(featureDiff?.geometry);
|
|
1297
|
+
existingFeature.setGeometry(newGeometry);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
});
|
|
1301
|
+
return feature;
|
|
1302
|
+
}
|
|
1303
|
+
}));
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: OverlapService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1308
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: OverlapService, providedIn: 'root' });
|
|
1309
|
+
}
|
|
1310
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: OverlapService, decorators: [{
|
|
1311
|
+
type: Injectable,
|
|
1312
|
+
args: [{
|
|
1313
|
+
providedIn: 'root'
|
|
1314
|
+
}]
|
|
1315
|
+
}] });
|
|
1316
|
+
|
|
1073
1317
|
class ToolboxComponent {
|
|
1074
1318
|
// Inputs
|
|
1075
1319
|
map;
|
|
@@ -1088,9 +1332,12 @@ class ToolboxComponent {
|
|
|
1088
1332
|
_featureHelper = inject(FeatureHelperService);
|
|
1089
1333
|
_undoRedo = inject(UndoRedoService);
|
|
1090
1334
|
_geomSplitService = inject(GeometrySplitService);
|
|
1091
|
-
_highlight = inject(
|
|
1335
|
+
_highlight = inject(HighlightService);
|
|
1092
1336
|
_interactionHelper = inject(InteractionHelperService);
|
|
1093
1337
|
_mergeService = inject(MergeFeaturesService);
|
|
1338
|
+
_centerPointService = inject(CenterPointService);
|
|
1339
|
+
_overlap = inject(OverlapService);
|
|
1340
|
+
_zoomService = inject(ZoomService);
|
|
1094
1341
|
_POSITION_STORAGE_KEY = 'toolbox_position';
|
|
1095
1342
|
_current = inject(CurrentItemsService);
|
|
1096
1343
|
_originalMapWidth = 0;
|
|
@@ -1106,7 +1353,7 @@ class ToolboxComponent {
|
|
|
1106
1353
|
[800, 600]
|
|
1107
1354
|
];
|
|
1108
1355
|
printDrawLabel = "";
|
|
1109
|
-
printDrawTool = "
|
|
1356
|
+
printDrawTool = "Point";
|
|
1110
1357
|
selectedGeometrySetting = undefined;
|
|
1111
1358
|
undoIconBase64 = IconsConstants.undoIconBase64;
|
|
1112
1359
|
redoIconBase64 = IconsConstants.redoIconBase64;
|
|
@@ -1170,9 +1417,21 @@ class ToolboxComponent {
|
|
|
1170
1417
|
next: featureStyle => {
|
|
1171
1418
|
feature.setStyle(featureStyle);
|
|
1172
1419
|
this._featureHelper.setTypeId(feature, this.selectedGeometrySetting?.typeId || '');
|
|
1173
|
-
this.
|
|
1174
|
-
|
|
1175
|
-
|
|
1420
|
+
this._featureHelper.setId(feature);
|
|
1421
|
+
if (featureType === 'Polygon') {
|
|
1422
|
+
this._overlap.handleOverlap(feature).subscribe({
|
|
1423
|
+
next: f => {
|
|
1424
|
+
if (f) {
|
|
1425
|
+
this._zoomService.zoomToFeatures([f]);
|
|
1426
|
+
this._drawLayerService.source.addFeature(f);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
});
|
|
1430
|
+
}
|
|
1431
|
+
else {
|
|
1432
|
+
this._zoomService.zoomToFeatures([feature]);
|
|
1433
|
+
this._drawLayerService.source.addFeature(feature);
|
|
1434
|
+
}
|
|
1176
1435
|
}
|
|
1177
1436
|
});
|
|
1178
1437
|
}
|
|
@@ -1184,6 +1443,14 @@ class ToolboxComponent {
|
|
|
1184
1443
|
type: 'Polygon',
|
|
1185
1444
|
source: this._drawLayerService.source
|
|
1186
1445
|
});
|
|
1446
|
+
setCenterPoint() {
|
|
1447
|
+
this._clearAllInteractions();
|
|
1448
|
+
this.activeMode = 'center-point';
|
|
1449
|
+
this._centerPointService.setCenterPoint(this.settings.centerPoint.style, this.settings.centerPoint.withinPolygon, () => {
|
|
1450
|
+
this.activeMode = null;
|
|
1451
|
+
this._clearAllInteractions();
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1187
1454
|
_actionSource = new VectorSource();
|
|
1188
1455
|
clipHole() {
|
|
1189
1456
|
this._clearAllInteractions();
|
|
@@ -1194,7 +1461,7 @@ class ToolboxComponent {
|
|
|
1194
1461
|
});
|
|
1195
1462
|
this._interactionHelper.setAsTemp(clipHoleDraw);
|
|
1196
1463
|
clipHoleDraw.on('drawend', evt => {
|
|
1197
|
-
const overlappingFeatures = this._drawLayerService.source.getFeatures().filter(f => f.getGeometry()?.intersectsExtent(evt.feature.getGeometry().getExtent()));
|
|
1464
|
+
const overlappingFeatures = this._drawLayerService.source.getFeatures().filter(f => !this._featureHelper.isLocked(f) && f.getGeometry()?.intersectsExtent(evt.feature.getGeometry().getExtent()));
|
|
1198
1465
|
const geoJsonFormat = new GeoJSON();
|
|
1199
1466
|
const holeGeoJson = geoJsonFormat.writeFeatureObject(evt.feature);
|
|
1200
1467
|
overlappingFeatures.forEach(f => {
|
|
@@ -1264,6 +1531,7 @@ class ToolboxComponent {
|
|
|
1264
1531
|
this._interactionHelper.setAsTemp(this.deleteSelect);
|
|
1265
1532
|
this.deleteSelect.on('select', evt => {
|
|
1266
1533
|
this._drawLayerService.source.removeFeatures(evt.selected);
|
|
1534
|
+
evt.selected.forEach(f => this._centerPointService.handleFeatureDeleted(f.getId()));
|
|
1267
1535
|
});
|
|
1268
1536
|
return this._deleteSelect;
|
|
1269
1537
|
}
|
|
@@ -1280,10 +1548,18 @@ class ToolboxComponent {
|
|
|
1280
1548
|
this.activeMode = 'edit-remove';
|
|
1281
1549
|
const modifyRemove = new Modify({
|
|
1282
1550
|
source: this._drawLayerService.source,
|
|
1551
|
+
condition: evt => {
|
|
1552
|
+
// first, get all features from the draw-layer
|
|
1553
|
+
const feature = this.map.forEachFeatureAtPixel(evt.pixel, f => f, { layerFilter: l => l == this._drawLayerService.layer });
|
|
1554
|
+
if (!feature) {
|
|
1555
|
+
return false;
|
|
1556
|
+
}
|
|
1557
|
+
return !this._featureHelper.isLocked(feature);
|
|
1558
|
+
},
|
|
1283
1559
|
// Make sure delete is allowed and other interactions are not.
|
|
1284
1560
|
deleteCondition: always,
|
|
1285
1561
|
insertVertexCondition: never,
|
|
1286
|
-
snapToPointer: this.snap
|
|
1562
|
+
snapToPointer: this.snap,
|
|
1287
1563
|
});
|
|
1288
1564
|
this._interactionHelper.setAsTemp(modifyRemove);
|
|
1289
1565
|
this.map.addInteraction(modifyRemove);
|
|
@@ -1294,10 +1570,18 @@ class ToolboxComponent {
|
|
|
1294
1570
|
this.activeMode = 'edit';
|
|
1295
1571
|
const modify = new Modify({
|
|
1296
1572
|
source: this._drawLayerService.source,
|
|
1573
|
+
condition: evt => {
|
|
1574
|
+
// first, get all features from the draw-layer
|
|
1575
|
+
const feature = this.map.forEachFeatureAtPixel(evt.pixel, f => f, { layerFilter: l => l == this._drawLayerService.layer });
|
|
1576
|
+
if (!feature) {
|
|
1577
|
+
return false;
|
|
1578
|
+
}
|
|
1579
|
+
return !this._featureHelper.isLocked(feature);
|
|
1580
|
+
},
|
|
1297
1581
|
// No delete
|
|
1298
1582
|
deleteCondition: () => false,
|
|
1299
1583
|
// Allow moving existing and add new points
|
|
1300
|
-
condition: always,
|
|
1584
|
+
// condition: always,
|
|
1301
1585
|
insertVertexCondition: always,
|
|
1302
1586
|
});
|
|
1303
1587
|
/* Modify fires changes to features a LOT, so to not flood the UndoRedo service, I disable until ending the modify
|
|
@@ -1324,13 +1608,28 @@ class ToolboxComponent {
|
|
|
1324
1608
|
next: style => {
|
|
1325
1609
|
const drawInteraction = new Draw({
|
|
1326
1610
|
type: geomType,
|
|
1327
|
-
source:
|
|
1611
|
+
source: new VectorSource(),
|
|
1328
1612
|
style: style
|
|
1329
1613
|
});
|
|
1614
|
+
this._undoRedo.disable();
|
|
1330
1615
|
drawInteraction.on('drawend', evt => {
|
|
1331
1616
|
this._featureHelper.setTypeId(evt.feature, this.selectedGeometrySetting?.typeId || '');
|
|
1332
1617
|
this._featureHelper.setId(evt.feature);
|
|
1333
1618
|
evt.feature.setStyle(style);
|
|
1619
|
+
if (geomType === 'Polygon') {
|
|
1620
|
+
this._overlap.handleOverlap(evt.feature).pipe(filter(f => !!f)).subscribe({
|
|
1621
|
+
next: f => {
|
|
1622
|
+
if (f) {
|
|
1623
|
+
this._undoRedo.enable();
|
|
1624
|
+
this._drawLayerService.source.addFeature(f);
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
else {
|
|
1630
|
+
this._undoRedo.enable();
|
|
1631
|
+
this._drawLayerService.source.addFeature(evt.feature);
|
|
1632
|
+
}
|
|
1334
1633
|
});
|
|
1335
1634
|
this._interactionHelper.setAsTemp(drawInteraction);
|
|
1336
1635
|
// this._setDrawLayer()
|
|
@@ -1344,6 +1643,7 @@ class ToolboxComponent {
|
|
|
1344
1643
|
_areaSource = new VectorSource();
|
|
1345
1644
|
_areaLayer = new VectorLayer({
|
|
1346
1645
|
source: this._areaSource,
|
|
1646
|
+
zIndex: 999,
|
|
1347
1647
|
style: (feature) => {
|
|
1348
1648
|
const geom = feature.getGeometry();
|
|
1349
1649
|
const area = getArea(geom);
|
|
@@ -1369,6 +1669,7 @@ class ToolboxComponent {
|
|
|
1369
1669
|
_distanceLabelSource = new VectorSource();
|
|
1370
1670
|
_distanceLabelLayer = new VectorLayer({
|
|
1371
1671
|
source: this._distanceLabelSource,
|
|
1672
|
+
zIndex: 999,
|
|
1372
1673
|
style: (feature) => {
|
|
1373
1674
|
return new Style({
|
|
1374
1675
|
text: new Text({
|
|
@@ -1383,6 +1684,7 @@ class ToolboxComponent {
|
|
|
1383
1684
|
_distanceSource = new VectorSource();
|
|
1384
1685
|
_distanceLayer = new VectorLayer({
|
|
1385
1686
|
source: this._distanceSource,
|
|
1687
|
+
zIndex: 999,
|
|
1386
1688
|
style: (feature) => {
|
|
1387
1689
|
const geom = feature.getGeometry();
|
|
1388
1690
|
const length = getLength(geom);
|
|
@@ -1664,32 +1966,84 @@ class ToolboxComponent {
|
|
|
1664
1966
|
this._active = 'No';
|
|
1665
1967
|
this._removePrintDrawToolInteraction();
|
|
1666
1968
|
this.activeMode = null;
|
|
1969
|
+
this.printDrawTool = 'Point';
|
|
1667
1970
|
return;
|
|
1668
1971
|
}
|
|
1669
1972
|
this._active = 'PrintDraw';
|
|
1670
1973
|
this._clearAllInteractions();
|
|
1671
1974
|
this._addPrintDrawToolInteraction();
|
|
1672
1975
|
this.activeMode = null;
|
|
1976
|
+
this.printDrawTool = 'Point';
|
|
1673
1977
|
}
|
|
1674
1978
|
handlePrintDrawToolChanged() {
|
|
1675
1979
|
if (this.active === 'PrintDraw') {
|
|
1676
|
-
this.
|
|
1677
|
-
|
|
1980
|
+
this._removePrintDrawToolInteraction();
|
|
1981
|
+
this._addPrintDrawToolInteraction();
|
|
1678
1982
|
}
|
|
1679
1983
|
}
|
|
1984
|
+
handleClearPrintDrawFeatures() {
|
|
1985
|
+
this._printDrawLayerService.source.clear();
|
|
1986
|
+
}
|
|
1680
1987
|
printDraw;
|
|
1681
1988
|
_addPrintDrawToolInteraction() {
|
|
1682
1989
|
if (this.active === 'PrintDraw') {
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1990
|
+
switch (this.printDrawTool) {
|
|
1991
|
+
case 'Arrow':
|
|
1992
|
+
this.printDraw = new Draw({
|
|
1993
|
+
source: this._printDrawLayerService.source,
|
|
1994
|
+
type: 'LineString',
|
|
1995
|
+
});
|
|
1996
|
+
break;
|
|
1997
|
+
case 'Square':
|
|
1998
|
+
this.printDraw = new Draw({
|
|
1999
|
+
source: this._printDrawLayerService.source,
|
|
2000
|
+
type: 'Circle',
|
|
2001
|
+
geometryFunction: createRegularPolygon(4)
|
|
2002
|
+
});
|
|
2003
|
+
break;
|
|
2004
|
+
case 'Rectangle':
|
|
2005
|
+
this.printDraw = new Draw({
|
|
2006
|
+
source: this._printDrawLayerService.source,
|
|
2007
|
+
type: 'Circle',
|
|
2008
|
+
geometryFunction: createBox()
|
|
2009
|
+
});
|
|
2010
|
+
break;
|
|
2011
|
+
default:
|
|
2012
|
+
this.printDraw = new Draw({
|
|
2013
|
+
source: this._printDrawLayerService.source,
|
|
2014
|
+
type: this.printDrawTool,
|
|
2015
|
+
});
|
|
2016
|
+
break;
|
|
2017
|
+
}
|
|
1691
2018
|
this.printDraw.on('drawend', evt => {
|
|
1692
|
-
evt.feature
|
|
2019
|
+
const feature = evt.feature;
|
|
2020
|
+
feature.set("printDrawLabel", this.printDrawLabel);
|
|
2021
|
+
feature.set("printDrawTool", this.printDrawTool);
|
|
2022
|
+
if (this.printDrawTool === 'Arrow') {
|
|
2023
|
+
feature.setStyle((feature) => {
|
|
2024
|
+
const styles = this._getDrawToolStyle(feature);
|
|
2025
|
+
const geom = feature.getGeometry();
|
|
2026
|
+
const rot = this._lastSegmentRotation(geom);
|
|
2027
|
+
const arrowHead = new RegularShape({
|
|
2028
|
+
points: 3,
|
|
2029
|
+
radius: 10,
|
|
2030
|
+
angle: Math.PI / 2,
|
|
2031
|
+
rotation: -rot,
|
|
2032
|
+
rotateWithView: true,
|
|
2033
|
+
stroke: new Stroke({ color: '#1f6feb', width: 3 })
|
|
2034
|
+
});
|
|
2035
|
+
const endCoord = geom.getCoordinateAt(1);
|
|
2036
|
+
const arrowEndStyle = new Style({
|
|
2037
|
+
image: arrowHead,
|
|
2038
|
+
geometry: () => new Point(endCoord)
|
|
2039
|
+
});
|
|
2040
|
+
styles.push(arrowEndStyle);
|
|
2041
|
+
return styles;
|
|
2042
|
+
});
|
|
2043
|
+
}
|
|
2044
|
+
else {
|
|
2045
|
+
feature.setStyle((feature) => this._getDrawToolStyle(feature));
|
|
2046
|
+
}
|
|
1693
2047
|
});
|
|
1694
2048
|
}
|
|
1695
2049
|
this.map.addInteraction(this.printDraw);
|
|
@@ -1698,55 +2052,49 @@ class ToolboxComponent {
|
|
|
1698
2052
|
_removePrintDrawToolInteraction() {
|
|
1699
2053
|
this.map.removeInteraction(this.printDraw);
|
|
1700
2054
|
}
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
}
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
'circle-fill-color': 'red',
|
|
1739
|
-
'stroke-color': 'blue',
|
|
1740
|
-
'stroke-width': 2,
|
|
1741
|
-
'fill-color': 'yellow',
|
|
1742
|
-
},
|
|
1743
|
-
};
|
|
2055
|
+
_lastSegmentRotation(lineString) {
|
|
2056
|
+
const coords = lineString.getCoordinates();
|
|
2057
|
+
if (!coords || coords.length < 2)
|
|
2058
|
+
return 0;
|
|
2059
|
+
const [x1, y1] = coords[coords.length - 2];
|
|
2060
|
+
const [x2, y2] = coords[coords.length - 1];
|
|
2061
|
+
return Math.atan2(y2 - y1, x2 - x1);
|
|
2062
|
+
}
|
|
2063
|
+
_getDrawToolStyle(feature) {
|
|
2064
|
+
const textStyle = new Style({
|
|
2065
|
+
text: new Text({
|
|
2066
|
+
text: feature.get("printDrawLabel"),
|
|
2067
|
+
font: '12px Calibri,sans-serif',
|
|
2068
|
+
fill: new Fill({ color: '#000' }),
|
|
2069
|
+
stroke: new Stroke({ color: '#fff', width: 3 }),
|
|
2070
|
+
placement: 'point'
|
|
2071
|
+
})
|
|
2072
|
+
});
|
|
2073
|
+
const lineStyle = new Style({
|
|
2074
|
+
stroke: new Stroke({
|
|
2075
|
+
color: '#1f6feb',
|
|
2076
|
+
width: 3
|
|
2077
|
+
})
|
|
2078
|
+
});
|
|
2079
|
+
const circleStyle = new Style({
|
|
2080
|
+
image: new CircleStyle({
|
|
2081
|
+
radius: 5,
|
|
2082
|
+
fill: new Fill({ color: '#7da8e9ff' }), // teal fill
|
|
2083
|
+
stroke: new Stroke({ color: '#1f6feb', width: 2 }),
|
|
2084
|
+
})
|
|
2085
|
+
});
|
|
2086
|
+
let styles = [textStyle, lineStyle];
|
|
2087
|
+
if (feature.get("printDrawTool") === 'Point') {
|
|
2088
|
+
styles.push(circleStyle);
|
|
2089
|
+
}
|
|
2090
|
+
return styles;
|
|
2091
|
+
}
|
|
1744
2092
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ToolboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1745
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ToolboxComponent, isStandalone: true, selector: "map-toolbox", inputs: { map: "map", showMeasureDistance: "showMeasureDistance", showMeasureArea: "showMeasureArea", collapsed: "collapsed", settings: "settings", profile: "profile", WKTInputEnabled: "WKTInputEnabled", deleteEnabled: "deleteEnabled" }, ngImport: i0, template: "<div class=\"toolbox-wrapper\" \n cdkDrag \n cdkDragBoundary=\".map-container\"\n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\">\n <div class=\"drag-handle-toolbox\" cdkDragHandle>\n <mat-icon>build_circle</mat-icon>\n <mat-icon class=\"toggle-icon\" (click)=\"toggleCollapsed($event)\">{{ collapsed ? 'flip_to_front' : 'remove' }}</mat-icon> </div>\n <div class=\"toolbox-container\" [class.collapsed]=\"collapsed\">\n @if(!collapsed) {\n <div class=\"toolbox-content\">\n @if (settings.geometryTypeSettings && settings.geometryTypeSettings.length) {\n <mat-select class=\"geometry-selector\" (selectionChange)=\"settingsChanged($event)\" [(ngModel)]=\"selectedGeometrySetting\" [compareWith]=\"compareGeometrySetting\">\n @for (setting of settings.geometryTypeSettings; track setting) {\n <mat-option [value]=\"setting\">{{setting.typeName}}</mat-option>\n }\n </mat-select> \n }\n <div class=\"all-tools-container\">\n <div class=\"main-tools\">\n @if(!settings?.undoDisabled) {\n <img \n [src]=\"undoIconBase64\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"undo()\" \n matTooltip=\"Fortryd\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Undo\">\n\n <img \n [src]=\"redoIconBase64\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"redo()\" \n matTooltip=\"Gentag\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Redo\">\n }\n <mat-slide-toggle [(ngModel)]=\"snap\" (change)=\"onSnapChange()\">Snap</mat-slide-toggle>\n @if(settings.editEnabled) {\n <img \n [src]=\"editIconBase64\" \n [class.active]=\"activeMode === 'edit'\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"startEdit()\" \n matTooltip=\"Rediger\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Rediger\">\n\n <img \n [src]=\"removePointsIconBase64\" \n [class.active]=\"activeMode === 'edit-remove'\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"startEditRemovePoints()\" \n matTooltip=\"Fjern punkter\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Fjern punkter\">\n }\n @if(settings.cutHoleEnabled) {\n <img \n [src]=\"trimIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'clip-hole'\" \n (click)=\"clipHole()\" \n matTooltip=\"Klip hul\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Klip hul\">\n }\n @if(settings.splitEnabled) {\n <img \n [src]=\"splitIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'split'\"\n (click)=\"split()\" \n matTooltip=\"Sk\u00E6r over\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Sk\u00E6r over\">\n }\n @if(settings.changeTypeEnabled) {\n <mat-icon \n class=\"compact-icon\" \n [class.active]=\"activeMode === 'change-type'\" \n (click)=\"startChangeType()\"\n [matTooltipShowDelay]=\"200\"\n matTooltipClass=\"custom-tooltip\"\n [matTooltipHideDelay]=\"300\" \n matTooltip=\"Skift type\" \n matTooltipPosition=\"below\">\n find_replace\n </mat-icon>\n }\n @if(settings.mergeEnabled) {\n <mat-icon \n class=\"compact-icon\" \n (click)=\"startMergeFeatures()\" \n matTooltipPosition=\"below\"\n [matTooltipShowDelay]=\"200\"\n matTooltipClass=\"custom-tooltip\"\n [matTooltipHideDelay]=\"300\" \n matTooltip=\"Saml flader\" \n [class.active]=\"activeMode === 'merge-features'\">\n merge\n </mat-icon>\n }\n </div>\n @if(selectedGeometrySetting && selectedGeometrySetting.availableGeometryTypes?.length) {\n <div class=\"geometry-tools\">\n @for(geomType of selectedGeometrySetting.availableGeometryTypes;track geomType) {\n @if(geomType === 'Polygon') {\n <img \n [src]=\"polygonIconBase64\" \n [class.active]=\"activeMode === 'draw-polygon'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawPolygon()\" \n matTooltip=\"Polygon\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Polygon\">\n }\n @if(geomType === 'LineString') {\n <img \n [src]=\"lineStringIconBase64\" \n [class.active]=\"activeMode === 'draw-linestring'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawLineString()\" \n matTooltip=\"LineString\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"LineString\">\n }\n @if(geomType === 'Point') {\n <img \n [src]=\"pointIconBase64\" \n [class.active]=\"activeMode === 'draw-point'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawPoint()\" \n matTooltip=\"Punkter\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Punkter\">\n }\n }\n <img \n [src]=\"wktIconBase64\" \n class=\"compact-icon secondary custom-image-icon\"\n (click)=\"activateShowInputWKT()\" \n matTooltip=\"WKT\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"WKT\">\n </div>\n }\n <div class=\"tool-separator\" *ngIf=\"deleteEnabled || showMeasureDistance || showMeasureArea || profile.showPrint\"></div>\n <div class=\"measurement-print-tools\">\n <div class=\"measurement-tools\">\n @if (deleteEnabled) {\n <img \n [src]=\"deleteIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'delete'\"\n (click)=\"startDelete()\" \n matTooltip=\"Slet\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Slet\">\n }\n @if (showMeasureDistance) {\n <img \n [src]=\"measureDistanceIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'measure-distance'\"\n (click)=\"startMeasureLength()\" \n matTooltip=\"M\u00E5le afstand\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"M\u00E5le afstand\">\n }\n @if(showMeasureArea) {\n <img \n [src]=\"measureAreaIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'measure-area'\"\n (click)=\"startMeasureArea()\" \n matTooltip=\"M\u00E5le areal\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"M\u00E5le areal\">\n }\n </div>\n @if(profile.showPrint) {\n <div class=\"tool-separator print-separator\"></div>\n <div class=\"print-tools\">\n <img \n [src]=\"printBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"active === 'Print'\"\n (click)=\"startPrintMode()\" \n matTooltip=\"Udskriv\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Udskriv\">\n <!-- <img \n [src]=\"drawBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"active === 'Draw'\"\n (click)=\"startDrawMode()\" \n matTooltip=\"Tegn\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Tegn\"> -->\n </div>\n }\n </div>\n </div>\n @if(showInputWKT) {\n <div class=\"wkt-section\">\n <input class=\"compact-input\" [(ngModel)]=\"WKTString\">\n <div class=\"wkt-actions\">\n <button class=\"compact-button primary\" (click)=\"ReadWKT()\">Indl\u00E6s WKT</button>\n <button class=\"compact-button\" (click)=\"cancelWKT()\">Annuller</button>\n </div>\n </div>\n }\n @if(profile.showPrint) {\n @if(active === \"Print\") {\n <div class=\"print-config\">\n <img \n [src]=\"printBase64\" \n class=\"compact-icon\"\n (click)=\"doPrint()\" \n alt=\"Udskriv\"> \n <span class=\"icon-separator\">i</span>\n <select id=\"formatSelector\" [(ngModel)]=\"format\">\n <option value=\"image/png\" selected>.PNG</option>\n <option value=\"image/jpeg\">.JPG</option>\n </select>\n <select id=\"dimensionSelector\" [(ngModel)]=\"dimId\" (change)=\"handleDimensionSelected()\">\n <option value=\"99\" selected></option>\n <option value=\"0\">1920 X 1080</option>\n <option value=\"1\">1680 X 1050</option>\n <option value=\"2\">1280 X 800</option>\n <option value=\"3\">800 X 600</option>\n </select>\n <input type=\"text\" [(ngModel)]=\"mapWidth\"/> \n <span class=\"icon-separator\">x</span>\n <input type=\"text\" [(ngModel)]=\"mapHeight\"/>\n <button (click)=\"setNewMapDimensions()\">V\u00E6lg</button>\n </div>\n }\n @if(active === \"PrintDraw\") {\n <div class=\"print-draw-config\">\n <span class=\"icon-separator\">Label</span>\n <input type=\"text\" [(ngModel)]=\"printDrawLabel\"/>\n <select id=\"drawToolSelector\" [(ngModel)]=\"printDrawTool\" (change)=\"handlePrintDrawToolChanged()\">\n <option value=\"arrow\" selected>Pil</option>\n <option value=\"point\">Punkt</option>\n <option value=\"line\">Linje</option>\n <option value=\"polygon\">Polygon</option>\n <option value=\"cirkel\">Cirkel</option>\n <option value=\"square\">Kvadrat</option>\n <option value=\"rectangle\">Firkant</option>\n </select>\n <button>Ryd</button>\n </div>\n }\n }\n </div>\n }\n </div>\n</div>\n", styles: [".toolbox-wrapper{position:absolute;left:1em;top:31.5em;z-index:1000;cursor:grab;max-width:95vw}.toolbox-wrapper.cdk-drag-dragging{opacity:.8;cursor:grab;z-index:1001}.drag-handle-toolbox{display:flex;align-items:center;justify-content:space-between;background:color-mix(in srgb,#000 60%,transparent);padding:2px 10px;cursor:grab;gap:8px}.drag-handle-toolbox mat-icon{color:#fff;font-size:18px;width:18px;height:18px}.drag-handle-toolbox mat-icon:first-child{flex:1;text-align:center}.toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:18px!important;width:18px!important;height:18px!important;display:flex;align-items:center;justify-content:center;border-radius:4px;padding:2px;flex-shrink:0}.toggle-icon:hover{color:#fff;background:#ffffff26}.toggle-icon:active{background:#ffffff40}:host{position:relative;display:flex;justify-content:center}:host.expanded{width:auto;min-width:320px;padding:12px}.toolbox-container{display:flex;flex-direction:column;align-items:center;width:100%;gap:10px;background:color-mix(in srgb,#000 60%,transparent);box-shadow:#0000004d 0 1px 4px -1px;padding:10px;width:auto;min-width:32px;transition:all .3s ease;cursor:default}.toolbox-container.collapsed{display:none}.toolbox-content{display:flex;flex-direction:column;width:100%;gap:3px;animation:slideDown .3s cubic-bezier(.4,0,.2,1)}.all-tools-container{display:flex;flex-direction:row;align-items:center;flex-wrap:nowrap;width:100%;justify-content:flex-start;overflow-x:hidden}.all-tools-container::-webkit-scrollbar{height:4px}.all-tools-container::-webkit-scrollbar-thumb{background:#ccc;border-radius:2px}.main-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.main-tools ::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:12px;font-weight:500;color:#fff}.geometry-selector{width:100%}.geometry-selector ::ng-deep .mat-mdc-select{font-size:14px;line-height:1.4;border-radius:6px}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:32px;min-height:32px;padding:0 10px;border:none;border-radius:6px;background:color-mix(in srgb,#000 60%,transparent);transition:all .2s ease}.geometry-selector ::ng-deep .mat-mdc-select-trigger:hover{background:color-mix(in srgb,#000 70%,transparent);border-color:#667eea;box-shadow:0 4px 12px #0003}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:14px;font-weight:500;color:#fff}.geometry-selector ::ng-deep .mat-mdc-select-arrow-wrapper{height:16px;transform:scale(.85)}.geometry-selector ::ng-deep .mat-mdc-form-field-infix{min-height:32px;padding:6px 0}.geometry-selector ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .mat-mdc-select-panel{min-width:fit-content!important;max-width:320px!important;background:color-mix(in srgb,#000 100%,transparent)!important;border:none!important;border-radius:8px!important;box-shadow:0 8px 24px #0000001f,0 2px 6px #00000014!important;margin-top:6px!important;padding:4px 0!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:14px!important;min-height:36px!important;padding:8px 14px!important;transition:all .15s ease!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option:hover:not(.mat-mdc-option-disabled){background:#444849!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option.mat-active{background:color-mix(in srgb,#000 60%,transparent)!important;color:#fff!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option .mdc-list-item__primary-text{font-size:14px!important;font-weight:500!important;color:#fff!important}::ng-deep .cdk-overlay-pane{z-index:1001}::ng-deep .cdk-overlay-backdrop{z-index:1000}.geometry-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.measurement-print-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap;background:color-mix(in srgb,#000 20%,transparent);border-radius:8px;padding:4px 8px;border:1px solid rgba(255,255,255,.1)}.measurement-tools,.print-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.measurement-tools .compact-icon,.print-tools .compact-icon{transition:all .3s cubic-bezier(.4,0,.2,1)}.measurement-tools .compact-icon.custom-image-icon,.print-tools .compact-icon.custom-image-icon{padding:4px;background:none;border:1px solid rgba(255,255,255,.2)}.measurement-tools .compact-icon.custom-image-icon img,.print-tools .compact-icon.custom-image-icon img{width:100%;height:100%;object-fit:contain;transition:filter .2s ease}.measurement-tools .compact-icon.custom-image-icon.active,.print-tools .compact-icon.custom-image-icon.active{background:linear-gradient(147.38deg,#0ea5e9,#075985);border-color:transparent;box-shadow:0 4px 12px #0ea5e966}.measurement-tools .compact-icon.custom-image-icon.active img,.print-tools .compact-icon.custom-image-icon.active img{filter:brightness(0) invert(1)}.measurement-tools .compact-icon.custom-image-icon.active:hover,.print-tools .compact-icon.custom-image-icon.active:hover{box-shadow:0 6px 20px #0ea5e980}.measurement-tools .compact-icon.custom-image-icon:hover:not(.active),.print-tools .compact-icon.custom-image-icon:hover:not(.active){background:color-mix(in srgb,#000 70%,transparent);border-color:#0ea5e9;box-shadow:0 2px 8px #0ea5e94d}.measurement-tools .compact-icon.custom-image-icon:hover:not(.active) img,.print-tools .compact-icon.custom-image-icon:hover:not(.active) img{filter:brightness(0) invert(.8)}.print-tools .compact-icon{background:linear-gradient(147.38deg,#4f46e5,#3730a3);color:#fff;border:1px solid rgba(255,255,255,.2)}.print-tools .compact-icon.print-icon{background:linear-gradient(147.38deg,#10b981,#047857)}.print-tools .compact-icon.draw-icon{background:linear-gradient(147.38deg,#f59e0b,#d97706)}.print-tools .compact-icon.active{background:linear-gradient(147.38deg,#ef4444,#dc2626);box-shadow:0 4px 12px #ef444466;border-color:transparent;transform:scale(1.05)}.print-tools .compact-icon.active:hover{box-shadow:0 6px 20px #ef444480;transform:scale(1.08)}.print-tools .compact-icon:hover:not(.active){box-shadow:0 4px 12px #0000004d;opacity:.9}.tool-separator{width:1px;height:24px;background:linear-gradient(to bottom,transparent,rgba(255,255,255,.3),transparent);margin:0 4px}.tool-separator.print-separator{height:28px;background:linear-gradient(to bottom,transparent,rgba(255,255,255,.5),transparent)}.compact-icon{cursor:pointer;color:#fff;transition:all .3s cubic-bezier(.4,0,.2,1);width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:6px;background:color-mix(in srgb,#000 40%,transparent);border:1px solid rgba(255,255,255,.2);box-shadow:0 1px 2px #0000001a;flex-shrink:0}.compact-icon.active{color:#fff;background:linear-gradient(135deg,#667eea,#764ba2);border-color:transparent;box-shadow:0 8px 25px #667eea4d;transform:scale(1.05)}.compact-icon.active:hover{box-shadow:0 12px 35px #667eea66;transform:scale(1.08)}.compact-icon:hover:not(.active){color:#fff;background:color-mix(in srgb,#000 70%,transparent);border-color:#667eea;box-shadow:0 4px 12px #0003}.compact-icon.custom-image-icon{padding:0;background:none;border:none}.compact-icon.custom-image-icon img{width:100%;height:100%;object-fit:contain;transition:transform .2s ease}.compact-icon.custom-image-icon.active{background:linear-gradient(135deg,#667eea,#764ba2);border-color:transparent}.compact-icon.custom-image-icon.active img{filter:brightness(0) invert(1);transform:scale(1.1)}.compact-icon.custom-image-icon:hover:not(.active) img{transform:scale(1.05)}.wkt-section{display:flex;flex-direction:column;gap:8px;padding-top:10px;border-top:1px solid rgba(255,255,255,.1);animation:fadeIn .2s ease}.wkt-actions{display:flex;gap:6px;justify-content:space-between}.compact-button{padding:6px 10px;border:none;border-radius:6px;background:color-mix(in srgb,#000 60%,transparent);color:#fff;font-size:12px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);text-transform:uppercase;letter-spacing:.4px;min-height:32px;display:flex;align-items:center;justify-content:center;flex:1;box-shadow:0 1px 2px #0000000d}.compact-button.primary.active{background:linear-gradient(135deg,#667eea,#764ba2);box-shadow:0 8px 25px #667eea4d;color:#fff}.compact-button.primary.active:hover{box-shadow:0 12px 35px #667eea66}.compact-button.secondary{background:color-mix(in srgb,#000 20%,transparent);color:#fff}.compact-button.secondary:hover{background:color-mix(in srgb,#5a6268 60%,transparent)}.compact-button:hover:not(.active){background:color-mix(in srgb,#000 70%,transparent);color:#fff}.compact-input{padding:8px 10px;border:none;border-radius:6px;font-size:13px;transition:all .2s ease;background:color-mix(in srgb,#000 60%,transparent);color:#fff}.compact-input:focus{outline:none;border-color:#1976d2;background:color-mix(in srgb,#000 70%,transparent);box-shadow:0 0 0 3px #1976d233}.print-config,.print-draw-config{display:flex;align-items:center;gap:8px;padding:5px;background:color-mix(in srgb,#000 40%,transparent);border-radius:8px;border:1px solid rgba(255,255,255,.1);animation:slideDown .3s ease}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{background:color-mix(in srgb,#000 60%,transparent);border:1px solid rgba(255,255,255,.2);color:#fff;border-radius:6px;font-size:12px;height:32px;min-height:32px;padding:0 10px}.print-config select:focus,.print-config input:focus,.print-draw-config select:focus,.print-draw-config input:focus{outline:none;border-color:#0ea5e9;box-shadow:0 0 0 2px #0ea5e933}.print-config select,.print-draw-config select{cursor:pointer}.print-config option,.print-draw-config option{background:color-mix(in srgb,#000 98%,transparent)!important;border:none!important}.print-config input,.print-draw-config input{width:60px;text-align:center}.print-config button,.print-draw-config button{background:linear-gradient(147.38deg,#10b981,#047857);color:#fff;border:none;padding:6px 12px;border-radius:4px;font-size:12px;cursor:pointer;transition:all .2s ease}.print-config button:hover,.print-draw-config button:hover{box-shadow:0 4px 12px #10b9814d}.print-config .icon-separator,.print-draw-config .icon-separator{color:#70706f}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes pulse{0%{box-shadow:0 0 #667eeab3}70%{box-shadow:0 0 0 6px #667eea00}to{box-shadow:0 0 #667eea00}}.compact-icon.active{animation:pulse 2s infinite}@media (max-width: 768px){.toolbox-wrapper{left:.5em;top:8em;max-width:calc(100vw - 2.5em)}.drag-handle-toolbox{padding:3px 6px;gap:6px}.drag-handle-toolbox mat-icon{font-size:16px;width:16px;height:16px}.toggle-icon{font-size:16px!important;width:16px!important;height:16px!important}.toolbox-container{padding:8px;min-width:28px;max-width:calc(100vw - 3em)}:host{padding:8px;min-width:32px}:host.expanded{min-width:280px;padding:10px}.all-tools-container{flex-wrap:wrap;gap:6px;max-height:50vh;overflow-y:auto;padding:0;-ms-overflow-style:none;scrollbar-width:none}.all-tools-container::-webkit-scrollbar{display:none}.main-tools,.geometry-tools,.measurement-print-tools,.print-tools{display:flex;flex-wrap:wrap;justify-content:center;gap:4px}.compact-icon{width:28px;height:28px;flex-shrink:0}.measurement-print-tools{padding:3px 6px}.geometry-selector{width:100%;margin-bottom:8px}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:28px;min-height:28px;padding:0 8px;font-size:12px}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:12px}::ng-deep .mat-mdc-select-panel{max-width:calc(100vw - 2em)!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:13px!important;min-height:32px!important;padding:6px 12px!important}.print-config,.print-draw-config{flex-direction:column;align-items:stretch;gap:6px}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{font-size:11px;padding:4px 8px;height:28px;min-height:28px}.print-config input,.print-draw-config input{width:50px}.print-config button,.print-draw-config button{padding:4px 8px;font-size:11px;height:28px}.wkt-section .compact-input{font-size:12px;padding:6px 8px}.wkt-section .compact-button{font-size:11px;padding:5px 8px;min-height:28px}::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:11px!important}}@media (max-width: 480px){.toolbox-wrapper{left:.25em;top:6em;transform-origin:left top;max-width:calc(100vw - .5em)}.drag-handle-toolbox{padding:2px 4px;gap:4px}.drag-handle-toolbox mat-icon{font-size:14px;width:14px;height:14px}.toggle-icon{font-size:14px!important;width:14px!important;height:14px!important}.toolbox-container{padding:6px;min-width:24px}.toolbox-content{gap:8px}.all-tools-container{flex-direction:row;align-items:center;max-height:60vh}.main-tools,.geometry-tools{gap:3px;flex-wrap:wrap;justify-content:center}.measurement-print-tools{gap:3px;flex-wrap:wrap;padding:2px 4px;width:100%;justify-content:center}.measurement-tools,.print-tools{gap:3px}.compact-icon{width:26px;height:26px}.tool-separator{display:none}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:26px;min-height:26px;padding:0 6px;font-size:11px}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:11px}.compact-button{font-size:10px;letter-spacing:.2px;padding:4px 6px;min-height:26px}.compact-input{font-size:11px;padding:4px 6px}.print-config,.print-draw-config{gap:4px;padding:6px}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{font-size:10px;height:26px;min-height:26px;padding:2px 6px}.print-config input,.print-draw-config input{width:45px}.print-config button,.print-draw-config button{flex:1;min-width:60px;font-size:10px;padding:3px 6px;height:26px}.print-config .icon-separator,.print-draw-config .icon-separator{font-size:10px}.wkt-section{gap:6px;padding-top:8px}::ng-deep .mat-mdc-slide-toggle{transform:scale(.9)}::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:10px!important}::ng-deep .mat-mdc-select-panel{max-width:calc(100vw - 1em)!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:12px!important;min-height:28px!important;padding:4px 10px!important}}::ng-deep .mat-mdc-simple-snack-bar{background-color:#fff!important}::ng-deep .mat-mdc-tooltip{--mdc-plain-tooltip-container-color: #050505 !important;--mdc-plain-tooltip-supporting-text-color: white !important;border-radius:6px}::ng-deep .mat-mdc-tooltip .mdc-tooltip__surface{background-color:#050505!important;color:#fff!important;border-radius:6px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i4.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i8.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }] });
|
|
2093
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ToolboxComponent, isStandalone: true, selector: "map-toolbox", inputs: { map: "map", showMeasureDistance: "showMeasureDistance", showMeasureArea: "showMeasureArea", collapsed: "collapsed", settings: "settings", profile: "profile", WKTInputEnabled: "WKTInputEnabled", deleteEnabled: "deleteEnabled" }, ngImport: i0, template: "<div class=\"toolbox-wrapper\" \n cdkDrag \n cdkDragBoundary=\".map-container\"\n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\">\n <div class=\"drag-handle-toolbox\" cdkDragHandle>\n <mat-icon>handyman</mat-icon>\n <mat-icon class=\"toggle-icon\" (click)=\"toggleCollapsed($event)\">{{ collapsed ? 'flip_to_front' : 'remove' }}</mat-icon> </div>\n <div class=\"toolbox-container\" [class.collapsed]=\"collapsed\">\n @if(!collapsed) {\n <div class=\"toolbox-content\">\n @if (settings.geometryTypeSettings && settings.geometryTypeSettings.length) {\n <mat-select class=\"geometry-selector\" (selectionChange)=\"settingsChanged($event)\" [(ngModel)]=\"selectedGeometrySetting\" [compareWith]=\"compareGeometrySetting\">\n @for (setting of settings.geometryTypeSettings; track setting) {\n <mat-option [value]=\"setting\">{{setting.typeName}}</mat-option>\n }\n </mat-select> \n }\n <div class=\"all-tools-container\">\n <div class=\"main-tools\">\n @if(!settings?.undoDisabled) {\n <img \n [src]=\"undoIconBase64\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"undo()\" \n matTooltip=\"Fortryd\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Undo\">\n\n <img \n [src]=\"redoIconBase64\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"redo()\" \n matTooltip=\"Gentag\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Redo\">\n }\n <mat-slide-toggle [(ngModel)]=\"snap\" (change)=\"onSnapChange()\">Snap</mat-slide-toggle>\n @if(settings.editEnabled) {\n <img \n [src]=\"editIconBase64\" \n [class.active]=\"activeMode === 'edit'\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"startEdit()\" \n matTooltip=\"Rediger\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Rediger\">\n\n <img \n [src]=\"removePointsIconBase64\" \n [class.active]=\"activeMode === 'edit-remove'\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"startEditRemovePoints()\" \n matTooltip=\"Fjern punkter\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Fjern punkter\">\n }\n @if(settings.cutHoleEnabled) {\n <img \n [src]=\"trimIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'clip-hole'\" \n (click)=\"clipHole()\" \n matTooltip=\"Klip hul\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Klip hul\">\n }\n @if(settings.splitEnabled) {\n <img \n [src]=\"splitIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'split'\"\n (click)=\"split()\" \n matTooltip=\"Sk\u00E6r over\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Sk\u00E6r over\">\n }\n @if(settings.changeTypeEnabled) {\n <mat-icon \n class=\"compact-icon\" \n [class.active]=\"activeMode === 'change-type'\" \n (click)=\"startChangeType()\"\n [matTooltipShowDelay]=\"200\"\n matTooltipClass=\"custom-tooltip\"\n [matTooltipHideDelay]=\"300\" \n matTooltip=\"Skift type\" \n matTooltipPosition=\"below\">\n find_replace\n </mat-icon>\n }\n @if(settings.mergeEnabled) {\n <mat-icon \n class=\"compact-icon\" \n (click)=\"startMergeFeatures()\" \n matTooltipPosition=\"below\"\n [matTooltipShowDelay]=\"200\"\n matTooltipClass=\"custom-tooltip\"\n [matTooltipHideDelay]=\"300\" \n matTooltip=\"Saml flader\" \n [class.active]=\"activeMode === 'merge-features'\">\n merge\n </mat-icon>\n }\n @if(settings.centerPoint) {\n <mat-icon\n (click)=\"setCenterPoint()\"\n matTooltipPosition=\"below\"\n [matTooltipShowDelay]=\"200\"\n matTooltipClass=\"custom-tooltip\"\n [matTooltipHideDelay]=\"300\" \n matTooltip=\"S\u00E6t centerpunkt\" \n [class.active]=\"activeMode === 'center-point'\"\n >adjust</mat-icon>\n }\n </div>\n @if(selectedGeometrySetting && selectedGeometrySetting.availableGeometryTypes?.length) {\n <div class=\"geometry-tools\">\n @for(geomType of selectedGeometrySetting.availableGeometryTypes;track geomType) {\n @if(geomType === 'Polygon') {\n <img \n [src]=\"polygonIconBase64\" \n [class.active]=\"activeMode === 'draw-polygon'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawPolygon()\" \n matTooltip=\"Polygon\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Polygon\">\n }\n @if(geomType === 'LineString') {\n <img \n [src]=\"lineStringIconBase64\" \n [class.active]=\"activeMode === 'draw-linestring'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawLineString()\" \n matTooltip=\"LineString\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"LineString\">\n }\n @if(geomType === 'Point') {\n <img \n [src]=\"pointIconBase64\" \n [class.active]=\"activeMode === 'draw-point'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawPoint()\" \n matTooltip=\"Punkter\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Punkter\">\n }\n }\n <img \n [src]=\"wktIconBase64\" \n class=\"compact-icon secondary custom-image-icon\"\n (click)=\"activateShowInputWKT()\" \n matTooltip=\"WKT\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"WKT\">\n </div>\n }\n <div class=\"tool-separator\" *ngIf=\"deleteEnabled || showMeasureDistance || showMeasureArea || profile.showPrint\"></div>\n <div class=\"measurement-print-tools\">\n <div class=\"measurement-tools\">\n @if (deleteEnabled) {\n <img \n [src]=\"deleteIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'delete'\"\n (click)=\"startDelete()\" \n matTooltip=\"Slet\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Slet\">\n }\n @if (showMeasureDistance) {\n <img \n [src]=\"measureDistanceIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'measure-distance'\"\n (click)=\"startMeasureLength()\" \n matTooltip=\"M\u00E5le afstand\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"M\u00E5le afstand\">\n }\n @if(showMeasureArea) {\n <img \n [src]=\"measureAreaIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'measure-area'\"\n (click)=\"startMeasureArea()\" \n matTooltip=\"M\u00E5le areal\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"M\u00E5le areal\">\n }\n </div>\n @if(profile.showPrint) {\n <div class=\"tool-separator print-separator\"></div>\n <div class=\"print-tools\">\n <img \n [src]=\"printBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"active === 'Print'\"\n (click)=\"startPrintMode()\" \n matTooltip=\"Udskriv\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Udskriv\">\n <img \n [src]=\"drawBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"active === 'Draw'\"\n (click)=\"startDrawMode()\" \n matTooltip=\"Tegn\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Tegn\">\n </div>\n }\n </div>\n </div>\n @if(showInputWKT) {\n <div class=\"wkt-section\">\n <input class=\"compact-input\" [(ngModel)]=\"WKTString\">\n <div class=\"wkt-actions\">\n <button class=\"compact-button primary\" (click)=\"ReadWKT()\">Indl\u00E6s WKT</button>\n <button class=\"compact-button\" (click)=\"cancelWKT()\">Annuller</button>\n </div>\n </div>\n }\n @if(profile.showPrint) {\n @if(active === \"Print\") {\n <div class=\"print-config\">\n <img \n [src]=\"printBase64\" \n class=\"compact-icon\"\n (click)=\"doPrint()\" \n alt=\"Udskriv\"> \n <span class=\"icon-separator\">i</span>\n <select id=\"formatSelector\" [(ngModel)]=\"format\">\n <option value=\"image/png\" selected>.PNG</option>\n <option value=\"image/jpeg\">.JPG</option>\n </select>\n <select id=\"dimensionSelector\" [(ngModel)]=\"dimId\" (change)=\"handleDimensionSelected()\">\n <option value=\"99\" selected></option>\n <option value=\"0\">1920 X 1080</option>\n <option value=\"1\">1680 X 1050</option>\n <option value=\"2\">1280 X 800</option>\n <option value=\"3\">800 X 600</option>\n </select>\n <input type=\"text\" [(ngModel)]=\"mapWidth\"/> \n <span class=\"icon-separator\">x</span>\n <input type=\"text\" [(ngModel)]=\"mapHeight\"/>\n <button (click)=\"setNewMapDimensions()\">V\u00E6lg</button>\n </div>\n }\n @if(active === \"PrintDraw\") {\n <div class=\"print-draw-config\">\n <span class=\"icon-separator\">Label</span>\n <input type=\"text\" [(ngModel)]=\"printDrawLabel\"/>\n <select id=\"drawToolSelector\" [(ngModel)]=\"printDrawTool\" (change)=\"handlePrintDrawToolChanged()\">\n <option value=\"Arrow\" selected>Pil</option>\n <option value=\"Point\">Punkt</option>\n <option value=\"LineString\">Linje</option>\n <option value=\"Polygon\">Polygon</option>\n <option value=\"Circle\">Cirkel</option>\n <option value=\"Square\">Kvadrat</option>\n <option value=\"Rectangle\">Firkant</option>\n </select>\n <button class=\"compact-button\" (click)=\"handleClearPrintDrawFeatures()\">Ryd</button>\n </div>\n }\n }\n </div>\n }\n </div>\n</div>\n", styles: [".toolbox-wrapper{position:absolute;left:1em;top:31.5em;z-index:1000;cursor:grab;max-width:95vw}.toolbox-wrapper.cdk-drag-dragging{opacity:.8;cursor:grab;z-index:1001}.drag-handle-toolbox{display:flex;align-items:center;justify-content:space-between;background:color-mix(in srgb,#000 60%,transparent);padding:2px 10px;cursor:grab;gap:8px;border-radius:5px 5px 0 0}.drag-handle-toolbox mat-icon{color:#fff;font-size:18px;width:18px;height:18px}.drag-handle-toolbox mat-icon:first-child{flex:1;text-align:left}.toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:18px!important;width:18px!important;height:18px!important;display:flex;align-items:center;justify-content:center;border-radius:4px;padding:2px;flex-shrink:0}.toggle-icon:hover{color:#fff;background:#ffffff26}.toggle-icon:active{background:#ffffff40}:host{position:relative;display:flex;justify-content:center}:host.expanded{width:auto;min-width:320px;padding:12px}.toolbox-container{display:flex;flex-direction:column;align-items:center;width:100%;gap:10px;background:color-mix(in srgb,#000 60%,transparent);box-shadow:#0000004d 0 1px 4px -1px;padding:10px;width:auto;min-width:32px;transition:all .3s ease;cursor:default;border-radius:0 0 5px 5px}.toolbox-container.collapsed{display:none}.toolbox-content{display:flex;flex-direction:column;width:100%;gap:3px;animation:slideDown .3s cubic-bezier(.4,0,.2,1)}.all-tools-container{display:flex;flex-direction:row;align-items:center;flex-wrap:nowrap;width:100%;justify-content:flex-start;overflow-x:hidden}.all-tools-container::-webkit-scrollbar{height:4px}.all-tools-container::-webkit-scrollbar-thumb{background:#ccc;border-radius:2px}.main-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.main-tools ::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:12px;font-weight:500;color:#fff}.geometry-selector{width:100%}.geometry-selector ::ng-deep .mat-mdc-select{font-size:14px;line-height:1.4;border-radius:6px}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:32px;min-height:32px;padding:0 10px;border:none;border-radius:6px;background:color-mix(in srgb,#000 60%,transparent);transition:all .2s ease}.geometry-selector ::ng-deep .mat-mdc-select-trigger:hover{background:color-mix(in srgb,#000 70%,transparent);border-color:#667eea;box-shadow:0 4px 12px #0003}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:14px;font-weight:500;color:#fff}.geometry-selector ::ng-deep .mat-mdc-select-arrow-wrapper{height:16px;transform:scale(.85)}.geometry-selector ::ng-deep .mat-mdc-form-field-infix{min-height:32px;padding:6px 0}.geometry-selector ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .mat-mdc-select-panel{min-width:fit-content!important;max-width:320px!important;background:color-mix(in srgb,#000 100%,transparent)!important;border:none!important;border-radius:8px!important;box-shadow:0 8px 24px #0000001f,0 2px 6px #00000014!important;margin-top:6px!important;padding:4px 0!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:14px!important;min-height:36px!important;padding:8px 14px!important;transition:all .15s ease!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option:hover:not(.mat-mdc-option-disabled){background:#444849!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option.mat-active{background:color-mix(in srgb,#000 60%,transparent)!important;color:#fff!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option .mdc-list-item__primary-text{font-size:14px!important;font-weight:500!important;color:#fff!important}::ng-deep .cdk-overlay-pane{z-index:1001}::ng-deep .cdk-overlay-backdrop{z-index:1000}.geometry-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.measurement-print-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap;background:color-mix(in srgb,#000 20%,transparent);border-radius:8px;padding:4px 8px;border:1px solid rgba(255,255,255,.1)}.measurement-tools,.print-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.measurement-tools .compact-icon,.print-tools .compact-icon{transition:all .3s cubic-bezier(.4,0,.2,1)}.measurement-tools .compact-icon.custom-image-icon,.print-tools .compact-icon.custom-image-icon{padding:4px;background:none;border:1px solid rgba(255,255,255,.2)}.measurement-tools .compact-icon.custom-image-icon img,.print-tools .compact-icon.custom-image-icon img{width:100%;height:100%;object-fit:contain;transition:filter .2s ease}.measurement-tools .compact-icon.custom-image-icon.active,.print-tools .compact-icon.custom-image-icon.active{background:linear-gradient(147.38deg,#0ea5e9,#075985);border-color:transparent;box-shadow:0 4px 12px #0ea5e966}.measurement-tools .compact-icon.custom-image-icon.active img,.print-tools .compact-icon.custom-image-icon.active img{filter:brightness(0) invert(1)}.measurement-tools .compact-icon.custom-image-icon.active:hover,.print-tools .compact-icon.custom-image-icon.active:hover{box-shadow:0 6px 20px #0ea5e980}.measurement-tools .compact-icon.custom-image-icon:hover:not(.active),.print-tools .compact-icon.custom-image-icon:hover:not(.active){background:color-mix(in srgb,#000 70%,transparent);border-color:#0ea5e9;box-shadow:0 2px 8px #0ea5e94d}.measurement-tools .compact-icon.custom-image-icon:hover:not(.active) img,.print-tools .compact-icon.custom-image-icon:hover:not(.active) img{filter:brightness(0) invert(.8)}.print-tools .compact-icon{background:linear-gradient(147.38deg,#4f46e5,#3730a3);color:#fff;border:1px solid rgba(255,255,255,.2)}.print-tools .compact-icon.print-icon{background:linear-gradient(147.38deg,#10b981,#047857)}.print-tools .compact-icon.draw-icon{background:linear-gradient(147.38deg,#f59e0b,#d97706)}.print-tools .compact-icon.active{background:linear-gradient(147.38deg,#ef4444,#dc2626);box-shadow:0 4px 12px #ef444466;border-color:transparent;transform:scale(1.05)}.print-tools .compact-icon.active:hover{box-shadow:0 6px 20px #ef444480;transform:scale(1.08)}.print-tools .compact-icon:hover:not(.active){box-shadow:0 4px 12px #0000004d;opacity:.9}.tool-separator{width:1px;height:24px;background:linear-gradient(to bottom,transparent,rgba(255,255,255,.3),transparent);margin:0 4px}.tool-separator.print-separator{height:28px;background:linear-gradient(to bottom,transparent,rgba(255,255,255,.5),transparent)}.compact-icon{cursor:pointer;color:#fff;transition:all .3s cubic-bezier(.4,0,.2,1);width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:6px;background:color-mix(in srgb,#000 40%,transparent);border:1px solid rgba(255,255,255,.2);box-shadow:0 1px 2px #0000001a;flex-shrink:0}.compact-icon.active{color:#fff;background:linear-gradient(135deg,#667eea,#764ba2);border-color:transparent;box-shadow:0 8px 25px #667eea4d;transform:scale(1.05)}.compact-icon.active:hover{box-shadow:0 12px 35px #667eea66;transform:scale(1.08)}.compact-icon:hover:not(.active){color:#fff;background:color-mix(in srgb,#000 70%,transparent);border-color:#667eea;box-shadow:0 4px 12px #0003}.compact-icon.custom-image-icon{padding:0;background:none;border:none}.compact-icon.custom-image-icon img{width:100%;height:100%;object-fit:contain;transition:transform .2s ease}.compact-icon.custom-image-icon.active{background:linear-gradient(135deg,#667eea,#764ba2);border-color:transparent}.compact-icon.custom-image-icon.active img{filter:brightness(0) invert(1);transform:scale(1.1)}.compact-icon.custom-image-icon:hover:not(.active) img{transform:scale(1.05)}.wkt-section{display:flex;flex-direction:column;gap:8px;padding-top:10px;border-top:1px solid rgba(255,255,255,.1);animation:fadeIn .2s ease}.wkt-actions{display:flex;gap:6px;justify-content:space-between}.compact-button{padding:6px 10px;border:none;border-radius:6px;background:color-mix(in srgb,#000 60%,transparent);color:#fff;font-size:12px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);text-transform:uppercase;letter-spacing:.4px;min-height:32px;display:flex;align-items:center;justify-content:center;flex:1;box-shadow:0 1px 2px #0000000d}.compact-button.primary.active{background:linear-gradient(135deg,#667eea,#764ba2);box-shadow:0 8px 25px #667eea4d;color:#fff}.compact-button.primary.active:hover{box-shadow:0 12px 35px #667eea66}.compact-button.secondary{background:color-mix(in srgb,#000 20%,transparent);color:#fff}.compact-button.secondary:hover{background:color-mix(in srgb,#5a6268 60%,transparent)}.compact-input{padding:8px 10px;border:none;border-radius:6px;font-size:13px;transition:all .2s ease;background:color-mix(in srgb,#000 60%,transparent);color:#fff}.compact-input:focus{outline:none;border-color:#1976d2;background:color-mix(in srgb,#000 70%,transparent);box-shadow:0 0 0 3px #1976d233}.print-config,.print-draw-config{display:flex;align-items:center;gap:8px;padding:5px;background:color-mix(in srgb,#000 40%,transparent);border-radius:8px;border:1px solid rgba(255,255,255,.1);animation:slideDown .3s ease}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{background:color-mix(in srgb,#000 60%,transparent);border:1px solid rgba(255,255,255,.2);color:#fff;border-radius:6px;font-size:12px;height:32px;min-height:32px;padding:0 10px}.print-config select:focus,.print-config input:focus,.print-draw-config select:focus,.print-draw-config input:focus{outline:none;border-color:#0ea5e9;box-shadow:0 0 0 2px #0ea5e933}.print-config select,.print-draw-config select{cursor:pointer}.print-config option,.print-draw-config option{background:color-mix(in srgb,#000 98%,transparent)!important;border:none!important}.print-config input,.print-draw-config input{width:60px;text-align:center}.print-config button,.print-draw-config button{background:linear-gradient(147.38deg,#10b981,#047857);color:#fff;border:none;padding:6px 12px;border-radius:4px;font-size:12px;cursor:pointer;transition:all .2s ease}.print-config button:hover,.print-draw-config button:hover{box-shadow:0 4px 12px #10b9814d}.print-config .icon-separator,.print-draw-config .icon-separator{color:#fff}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes pulse{0%{box-shadow:0 0 #667eeab3}70%{box-shadow:0 0 0 6px #667eea00}to{box-shadow:0 0 #667eea00}}.compact-icon.active{animation:pulse 2s infinite}@media (max-width: 768px){.toolbox-wrapper{left:.5em;top:8em;max-width:calc(100vw - 2.5em)}.drag-handle-toolbox{padding:3px 6px;gap:6px}.drag-handle-toolbox mat-icon{font-size:16px;width:16px;height:16px}.toggle-icon{font-size:16px!important;width:16px!important;height:16px!important}.toolbox-container{padding:8px;min-width:28px;max-width:calc(100vw - 3em)}:host{padding:8px;min-width:32px}:host.expanded{min-width:280px;padding:10px}.all-tools-container{flex-wrap:wrap;gap:6px;max-height:50vh;overflow-y:auto;padding:0;-ms-overflow-style:none;scrollbar-width:none}.all-tools-container::-webkit-scrollbar{display:none}.main-tools,.geometry-tools,.measurement-print-tools,.print-tools{display:flex;flex-wrap:wrap;justify-content:center;gap:4px}.compact-icon{width:28px;height:28px;flex-shrink:0}.measurement-print-tools{padding:3px 6px}.geometry-selector{width:100%;margin-bottom:8px}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:28px;min-height:28px;padding:0 8px;font-size:12px}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:12px}::ng-deep .mat-mdc-select-panel{max-width:calc(100vw - 2em)!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:13px!important;min-height:32px!important;padding:6px 12px!important}.print-config,.print-draw-config{flex-direction:column;align-items:stretch;gap:6px}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{font-size:11px;padding:4px 8px;height:28px;min-height:28px}.print-config input,.print-draw-config input{width:50px}.print-config button,.print-draw-config button{padding:4px 8px;font-size:11px;height:28px}.wkt-section .compact-input{font-size:12px;padding:6px 8px}.wkt-section .compact-button{font-size:11px;padding:5px 8px;min-height:28px}::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:11px!important}}@media (max-width: 480px){.toolbox-wrapper{left:.25em;top:6em;transform-origin:left top;max-width:calc(100vw - .5em)}.drag-handle-toolbox{padding:2px 4px;gap:4px}.drag-handle-toolbox mat-icon{font-size:14px;width:14px;height:14px}.toggle-icon{font-size:14px!important;width:14px!important;height:14px!important}.toolbox-container{padding:6px;min-width:24px}.toolbox-content{gap:8px}.all-tools-container{flex-direction:row;align-items:center;max-height:60vh}.main-tools,.geometry-tools{gap:3px;flex-wrap:wrap;justify-content:center}.measurement-print-tools{gap:3px;flex-wrap:wrap;padding:2px 4px;width:100%;justify-content:center}.measurement-tools,.print-tools{gap:3px}.compact-icon{width:26px;height:26px}.tool-separator{display:none}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:26px;min-height:26px;padding:0 6px;font-size:11px}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:11px}.compact-button{font-size:10px;letter-spacing:.2px;padding:4px 6px;min-height:26px}.compact-input{font-size:11px;padding:4px 6px}.print-config,.print-draw-config{gap:4px;padding:6px}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{font-size:10px;height:26px;min-height:26px;padding:2px 6px}.print-config input,.print-draw-config input{width:45px}.print-config button,.print-draw-config button{flex:1;min-width:60px;font-size:10px;padding:3px 6px;height:26px}.print-config .icon-separator,.print-draw-config .icon-separator{font-size:10px}.wkt-section{gap:6px;padding-top:8px}::ng-deep .mat-mdc-slide-toggle{transform:scale(.9)}::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:10px!important}::ng-deep .mat-mdc-select-panel{max-width:calc(100vw - 1em)!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:12px!important;min-height:28px!important;padding:4px 10px!important}}::ng-deep .mat-mdc-simple-snack-bar{background-color:#fff!important}::ng-deep .mat-mdc-tooltip{--mdc-plain-tooltip-container-color: #050505 !important;--mdc-plain-tooltip-supporting-text-color: white !important;border-radius:6px}::ng-deep .mat-mdc-tooltip .mdc-tooltip__surface{background-color:#050505!important;color:#fff!important;border-radius:6px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i4.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i8.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }] });
|
|
1746
2094
|
}
|
|
1747
2095
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ToolboxComponent, decorators: [{
|
|
1748
2096
|
type: Component,
|
|
1749
|
-
args: [{ selector: 'map-toolbox', imports: [FormsModule, CommonModule, MatIconModule, MatOptionModule, MatSelectModule, DragDropModule, MatTooltipModule, MatSlideToggleModule], template: "<div class=\"toolbox-wrapper\" \n cdkDrag \n cdkDragBoundary=\".map-container\"\n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\">\n <div class=\"drag-handle-toolbox\" cdkDragHandle>\n <mat-icon>build_circle</mat-icon>\n <mat-icon class=\"toggle-icon\" (click)=\"toggleCollapsed($event)\">{{ collapsed ? 'flip_to_front' : 'remove' }}</mat-icon> </div>\n <div class=\"toolbox-container\" [class.collapsed]=\"collapsed\">\n @if(!collapsed) {\n <div class=\"toolbox-content\">\n @if (settings.geometryTypeSettings && settings.geometryTypeSettings.length) {\n <mat-select class=\"geometry-selector\" (selectionChange)=\"settingsChanged($event)\" [(ngModel)]=\"selectedGeometrySetting\" [compareWith]=\"compareGeometrySetting\">\n @for (setting of settings.geometryTypeSettings; track setting) {\n <mat-option [value]=\"setting\">{{setting.typeName}}</mat-option>\n }\n </mat-select> \n }\n <div class=\"all-tools-container\">\n <div class=\"main-tools\">\n @if(!settings?.undoDisabled) {\n <img \n [src]=\"undoIconBase64\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"undo()\" \n matTooltip=\"Fortryd\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Undo\">\n\n <img \n [src]=\"redoIconBase64\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"redo()\" \n matTooltip=\"Gentag\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Redo\">\n }\n <mat-slide-toggle [(ngModel)]=\"snap\" (change)=\"onSnapChange()\">Snap</mat-slide-toggle>\n @if(settings.editEnabled) {\n <img \n [src]=\"editIconBase64\" \n [class.active]=\"activeMode === 'edit'\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"startEdit()\" \n matTooltip=\"Rediger\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Rediger\">\n\n <img \n [src]=\"removePointsIconBase64\" \n [class.active]=\"activeMode === 'edit-remove'\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"startEditRemovePoints()\" \n matTooltip=\"Fjern punkter\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Fjern punkter\">\n }\n @if(settings.cutHoleEnabled) {\n <img \n [src]=\"trimIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'clip-hole'\" \n (click)=\"clipHole()\" \n matTooltip=\"Klip hul\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Klip hul\">\n }\n @if(settings.splitEnabled) {\n <img \n [src]=\"splitIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'split'\"\n (click)=\"split()\" \n matTooltip=\"Sk\u00E6r over\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Sk\u00E6r over\">\n }\n @if(settings.changeTypeEnabled) {\n <mat-icon \n class=\"compact-icon\" \n [class.active]=\"activeMode === 'change-type'\" \n (click)=\"startChangeType()\"\n [matTooltipShowDelay]=\"200\"\n matTooltipClass=\"custom-tooltip\"\n [matTooltipHideDelay]=\"300\" \n matTooltip=\"Skift type\" \n matTooltipPosition=\"below\">\n find_replace\n </mat-icon>\n }\n @if(settings.mergeEnabled) {\n <mat-icon \n class=\"compact-icon\" \n (click)=\"startMergeFeatures()\" \n matTooltipPosition=\"below\"\n [matTooltipShowDelay]=\"200\"\n matTooltipClass=\"custom-tooltip\"\n [matTooltipHideDelay]=\"300\" \n matTooltip=\"Saml flader\" \n [class.active]=\"activeMode === 'merge-features'\">\n merge\n </mat-icon>\n }\n </div>\n @if(selectedGeometrySetting && selectedGeometrySetting.availableGeometryTypes?.length) {\n <div class=\"geometry-tools\">\n @for(geomType of selectedGeometrySetting.availableGeometryTypes;track geomType) {\n @if(geomType === 'Polygon') {\n <img \n [src]=\"polygonIconBase64\" \n [class.active]=\"activeMode === 'draw-polygon'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawPolygon()\" \n matTooltip=\"Polygon\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Polygon\">\n }\n @if(geomType === 'LineString') {\n <img \n [src]=\"lineStringIconBase64\" \n [class.active]=\"activeMode === 'draw-linestring'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawLineString()\" \n matTooltip=\"LineString\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"LineString\">\n }\n @if(geomType === 'Point') {\n <img \n [src]=\"pointIconBase64\" \n [class.active]=\"activeMode === 'draw-point'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawPoint()\" \n matTooltip=\"Punkter\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Punkter\">\n }\n }\n <img \n [src]=\"wktIconBase64\" \n class=\"compact-icon secondary custom-image-icon\"\n (click)=\"activateShowInputWKT()\" \n matTooltip=\"WKT\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"WKT\">\n </div>\n }\n <div class=\"tool-separator\" *ngIf=\"deleteEnabled || showMeasureDistance || showMeasureArea || profile.showPrint\"></div>\n <div class=\"measurement-print-tools\">\n <div class=\"measurement-tools\">\n @if (deleteEnabled) {\n <img \n [src]=\"deleteIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'delete'\"\n (click)=\"startDelete()\" \n matTooltip=\"Slet\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Slet\">\n }\n @if (showMeasureDistance) {\n <img \n [src]=\"measureDistanceIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'measure-distance'\"\n (click)=\"startMeasureLength()\" \n matTooltip=\"M\u00E5le afstand\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"M\u00E5le afstand\">\n }\n @if(showMeasureArea) {\n <img \n [src]=\"measureAreaIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'measure-area'\"\n (click)=\"startMeasureArea()\" \n matTooltip=\"M\u00E5le areal\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"M\u00E5le areal\">\n }\n </div>\n @if(profile.showPrint) {\n <div class=\"tool-separator print-separator\"></div>\n <div class=\"print-tools\">\n <img \n [src]=\"printBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"active === 'Print'\"\n (click)=\"startPrintMode()\" \n matTooltip=\"Udskriv\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Udskriv\">\n <!-- <img \n [src]=\"drawBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"active === 'Draw'\"\n (click)=\"startDrawMode()\" \n matTooltip=\"Tegn\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Tegn\"> -->\n </div>\n }\n </div>\n </div>\n @if(showInputWKT) {\n <div class=\"wkt-section\">\n <input class=\"compact-input\" [(ngModel)]=\"WKTString\">\n <div class=\"wkt-actions\">\n <button class=\"compact-button primary\" (click)=\"ReadWKT()\">Indl\u00E6s WKT</button>\n <button class=\"compact-button\" (click)=\"cancelWKT()\">Annuller</button>\n </div>\n </div>\n }\n @if(profile.showPrint) {\n @if(active === \"Print\") {\n <div class=\"print-config\">\n <img \n [src]=\"printBase64\" \n class=\"compact-icon\"\n (click)=\"doPrint()\" \n alt=\"Udskriv\"> \n <span class=\"icon-separator\">i</span>\n <select id=\"formatSelector\" [(ngModel)]=\"format\">\n <option value=\"image/png\" selected>.PNG</option>\n <option value=\"image/jpeg\">.JPG</option>\n </select>\n <select id=\"dimensionSelector\" [(ngModel)]=\"dimId\" (change)=\"handleDimensionSelected()\">\n <option value=\"99\" selected></option>\n <option value=\"0\">1920 X 1080</option>\n <option value=\"1\">1680 X 1050</option>\n <option value=\"2\">1280 X 800</option>\n <option value=\"3\">800 X 600</option>\n </select>\n <input type=\"text\" [(ngModel)]=\"mapWidth\"/> \n <span class=\"icon-separator\">x</span>\n <input type=\"text\" [(ngModel)]=\"mapHeight\"/>\n <button (click)=\"setNewMapDimensions()\">V\u00E6lg</button>\n </div>\n }\n @if(active === \"PrintDraw\") {\n <div class=\"print-draw-config\">\n <span class=\"icon-separator\">Label</span>\n <input type=\"text\" [(ngModel)]=\"printDrawLabel\"/>\n <select id=\"drawToolSelector\" [(ngModel)]=\"printDrawTool\" (change)=\"handlePrintDrawToolChanged()\">\n <option value=\"arrow\" selected>Pil</option>\n <option value=\"point\">Punkt</option>\n <option value=\"line\">Linje</option>\n <option value=\"polygon\">Polygon</option>\n <option value=\"cirkel\">Cirkel</option>\n <option value=\"square\">Kvadrat</option>\n <option value=\"rectangle\">Firkant</option>\n </select>\n <button>Ryd</button>\n </div>\n }\n }\n </div>\n }\n </div>\n</div>\n", styles: [".toolbox-wrapper{position:absolute;left:1em;top:31.5em;z-index:1000;cursor:grab;max-width:95vw}.toolbox-wrapper.cdk-drag-dragging{opacity:.8;cursor:grab;z-index:1001}.drag-handle-toolbox{display:flex;align-items:center;justify-content:space-between;background:color-mix(in srgb,#000 60%,transparent);padding:2px 10px;cursor:grab;gap:8px}.drag-handle-toolbox mat-icon{color:#fff;font-size:18px;width:18px;height:18px}.drag-handle-toolbox mat-icon:first-child{flex:1;text-align:center}.toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:18px!important;width:18px!important;height:18px!important;display:flex;align-items:center;justify-content:center;border-radius:4px;padding:2px;flex-shrink:0}.toggle-icon:hover{color:#fff;background:#ffffff26}.toggle-icon:active{background:#ffffff40}:host{position:relative;display:flex;justify-content:center}:host.expanded{width:auto;min-width:320px;padding:12px}.toolbox-container{display:flex;flex-direction:column;align-items:center;width:100%;gap:10px;background:color-mix(in srgb,#000 60%,transparent);box-shadow:#0000004d 0 1px 4px -1px;padding:10px;width:auto;min-width:32px;transition:all .3s ease;cursor:default}.toolbox-container.collapsed{display:none}.toolbox-content{display:flex;flex-direction:column;width:100%;gap:3px;animation:slideDown .3s cubic-bezier(.4,0,.2,1)}.all-tools-container{display:flex;flex-direction:row;align-items:center;flex-wrap:nowrap;width:100%;justify-content:flex-start;overflow-x:hidden}.all-tools-container::-webkit-scrollbar{height:4px}.all-tools-container::-webkit-scrollbar-thumb{background:#ccc;border-radius:2px}.main-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.main-tools ::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:12px;font-weight:500;color:#fff}.geometry-selector{width:100%}.geometry-selector ::ng-deep .mat-mdc-select{font-size:14px;line-height:1.4;border-radius:6px}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:32px;min-height:32px;padding:0 10px;border:none;border-radius:6px;background:color-mix(in srgb,#000 60%,transparent);transition:all .2s ease}.geometry-selector ::ng-deep .mat-mdc-select-trigger:hover{background:color-mix(in srgb,#000 70%,transparent);border-color:#667eea;box-shadow:0 4px 12px #0003}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:14px;font-weight:500;color:#fff}.geometry-selector ::ng-deep .mat-mdc-select-arrow-wrapper{height:16px;transform:scale(.85)}.geometry-selector ::ng-deep .mat-mdc-form-field-infix{min-height:32px;padding:6px 0}.geometry-selector ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .mat-mdc-select-panel{min-width:fit-content!important;max-width:320px!important;background:color-mix(in srgb,#000 100%,transparent)!important;border:none!important;border-radius:8px!important;box-shadow:0 8px 24px #0000001f,0 2px 6px #00000014!important;margin-top:6px!important;padding:4px 0!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:14px!important;min-height:36px!important;padding:8px 14px!important;transition:all .15s ease!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option:hover:not(.mat-mdc-option-disabled){background:#444849!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option.mat-active{background:color-mix(in srgb,#000 60%,transparent)!important;color:#fff!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option .mdc-list-item__primary-text{font-size:14px!important;font-weight:500!important;color:#fff!important}::ng-deep .cdk-overlay-pane{z-index:1001}::ng-deep .cdk-overlay-backdrop{z-index:1000}.geometry-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.measurement-print-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap;background:color-mix(in srgb,#000 20%,transparent);border-radius:8px;padding:4px 8px;border:1px solid rgba(255,255,255,.1)}.measurement-tools,.print-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.measurement-tools .compact-icon,.print-tools .compact-icon{transition:all .3s cubic-bezier(.4,0,.2,1)}.measurement-tools .compact-icon.custom-image-icon,.print-tools .compact-icon.custom-image-icon{padding:4px;background:none;border:1px solid rgba(255,255,255,.2)}.measurement-tools .compact-icon.custom-image-icon img,.print-tools .compact-icon.custom-image-icon img{width:100%;height:100%;object-fit:contain;transition:filter .2s ease}.measurement-tools .compact-icon.custom-image-icon.active,.print-tools .compact-icon.custom-image-icon.active{background:linear-gradient(147.38deg,#0ea5e9,#075985);border-color:transparent;box-shadow:0 4px 12px #0ea5e966}.measurement-tools .compact-icon.custom-image-icon.active img,.print-tools .compact-icon.custom-image-icon.active img{filter:brightness(0) invert(1)}.measurement-tools .compact-icon.custom-image-icon.active:hover,.print-tools .compact-icon.custom-image-icon.active:hover{box-shadow:0 6px 20px #0ea5e980}.measurement-tools .compact-icon.custom-image-icon:hover:not(.active),.print-tools .compact-icon.custom-image-icon:hover:not(.active){background:color-mix(in srgb,#000 70%,transparent);border-color:#0ea5e9;box-shadow:0 2px 8px #0ea5e94d}.measurement-tools .compact-icon.custom-image-icon:hover:not(.active) img,.print-tools .compact-icon.custom-image-icon:hover:not(.active) img{filter:brightness(0) invert(.8)}.print-tools .compact-icon{background:linear-gradient(147.38deg,#4f46e5,#3730a3);color:#fff;border:1px solid rgba(255,255,255,.2)}.print-tools .compact-icon.print-icon{background:linear-gradient(147.38deg,#10b981,#047857)}.print-tools .compact-icon.draw-icon{background:linear-gradient(147.38deg,#f59e0b,#d97706)}.print-tools .compact-icon.active{background:linear-gradient(147.38deg,#ef4444,#dc2626);box-shadow:0 4px 12px #ef444466;border-color:transparent;transform:scale(1.05)}.print-tools .compact-icon.active:hover{box-shadow:0 6px 20px #ef444480;transform:scale(1.08)}.print-tools .compact-icon:hover:not(.active){box-shadow:0 4px 12px #0000004d;opacity:.9}.tool-separator{width:1px;height:24px;background:linear-gradient(to bottom,transparent,rgba(255,255,255,.3),transparent);margin:0 4px}.tool-separator.print-separator{height:28px;background:linear-gradient(to bottom,transparent,rgba(255,255,255,.5),transparent)}.compact-icon{cursor:pointer;color:#fff;transition:all .3s cubic-bezier(.4,0,.2,1);width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:6px;background:color-mix(in srgb,#000 40%,transparent);border:1px solid rgba(255,255,255,.2);box-shadow:0 1px 2px #0000001a;flex-shrink:0}.compact-icon.active{color:#fff;background:linear-gradient(135deg,#667eea,#764ba2);border-color:transparent;box-shadow:0 8px 25px #667eea4d;transform:scale(1.05)}.compact-icon.active:hover{box-shadow:0 12px 35px #667eea66;transform:scale(1.08)}.compact-icon:hover:not(.active){color:#fff;background:color-mix(in srgb,#000 70%,transparent);border-color:#667eea;box-shadow:0 4px 12px #0003}.compact-icon.custom-image-icon{padding:0;background:none;border:none}.compact-icon.custom-image-icon img{width:100%;height:100%;object-fit:contain;transition:transform .2s ease}.compact-icon.custom-image-icon.active{background:linear-gradient(135deg,#667eea,#764ba2);border-color:transparent}.compact-icon.custom-image-icon.active img{filter:brightness(0) invert(1);transform:scale(1.1)}.compact-icon.custom-image-icon:hover:not(.active) img{transform:scale(1.05)}.wkt-section{display:flex;flex-direction:column;gap:8px;padding-top:10px;border-top:1px solid rgba(255,255,255,.1);animation:fadeIn .2s ease}.wkt-actions{display:flex;gap:6px;justify-content:space-between}.compact-button{padding:6px 10px;border:none;border-radius:6px;background:color-mix(in srgb,#000 60%,transparent);color:#fff;font-size:12px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);text-transform:uppercase;letter-spacing:.4px;min-height:32px;display:flex;align-items:center;justify-content:center;flex:1;box-shadow:0 1px 2px #0000000d}.compact-button.primary.active{background:linear-gradient(135deg,#667eea,#764ba2);box-shadow:0 8px 25px #667eea4d;color:#fff}.compact-button.primary.active:hover{box-shadow:0 12px 35px #667eea66}.compact-button.secondary{background:color-mix(in srgb,#000 20%,transparent);color:#fff}.compact-button.secondary:hover{background:color-mix(in srgb,#5a6268 60%,transparent)}.compact-button:hover:not(.active){background:color-mix(in srgb,#000 70%,transparent);color:#fff}.compact-input{padding:8px 10px;border:none;border-radius:6px;font-size:13px;transition:all .2s ease;background:color-mix(in srgb,#000 60%,transparent);color:#fff}.compact-input:focus{outline:none;border-color:#1976d2;background:color-mix(in srgb,#000 70%,transparent);box-shadow:0 0 0 3px #1976d233}.print-config,.print-draw-config{display:flex;align-items:center;gap:8px;padding:5px;background:color-mix(in srgb,#000 40%,transparent);border-radius:8px;border:1px solid rgba(255,255,255,.1);animation:slideDown .3s ease}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{background:color-mix(in srgb,#000 60%,transparent);border:1px solid rgba(255,255,255,.2);color:#fff;border-radius:6px;font-size:12px;height:32px;min-height:32px;padding:0 10px}.print-config select:focus,.print-config input:focus,.print-draw-config select:focus,.print-draw-config input:focus{outline:none;border-color:#0ea5e9;box-shadow:0 0 0 2px #0ea5e933}.print-config select,.print-draw-config select{cursor:pointer}.print-config option,.print-draw-config option{background:color-mix(in srgb,#000 98%,transparent)!important;border:none!important}.print-config input,.print-draw-config input{width:60px;text-align:center}.print-config button,.print-draw-config button{background:linear-gradient(147.38deg,#10b981,#047857);color:#fff;border:none;padding:6px 12px;border-radius:4px;font-size:12px;cursor:pointer;transition:all .2s ease}.print-config button:hover,.print-draw-config button:hover{box-shadow:0 4px 12px #10b9814d}.print-config .icon-separator,.print-draw-config .icon-separator{color:#70706f}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes pulse{0%{box-shadow:0 0 #667eeab3}70%{box-shadow:0 0 0 6px #667eea00}to{box-shadow:0 0 #667eea00}}.compact-icon.active{animation:pulse 2s infinite}@media (max-width: 768px){.toolbox-wrapper{left:.5em;top:8em;max-width:calc(100vw - 2.5em)}.drag-handle-toolbox{padding:3px 6px;gap:6px}.drag-handle-toolbox mat-icon{font-size:16px;width:16px;height:16px}.toggle-icon{font-size:16px!important;width:16px!important;height:16px!important}.toolbox-container{padding:8px;min-width:28px;max-width:calc(100vw - 3em)}:host{padding:8px;min-width:32px}:host.expanded{min-width:280px;padding:10px}.all-tools-container{flex-wrap:wrap;gap:6px;max-height:50vh;overflow-y:auto;padding:0;-ms-overflow-style:none;scrollbar-width:none}.all-tools-container::-webkit-scrollbar{display:none}.main-tools,.geometry-tools,.measurement-print-tools,.print-tools{display:flex;flex-wrap:wrap;justify-content:center;gap:4px}.compact-icon{width:28px;height:28px;flex-shrink:0}.measurement-print-tools{padding:3px 6px}.geometry-selector{width:100%;margin-bottom:8px}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:28px;min-height:28px;padding:0 8px;font-size:12px}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:12px}::ng-deep .mat-mdc-select-panel{max-width:calc(100vw - 2em)!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:13px!important;min-height:32px!important;padding:6px 12px!important}.print-config,.print-draw-config{flex-direction:column;align-items:stretch;gap:6px}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{font-size:11px;padding:4px 8px;height:28px;min-height:28px}.print-config input,.print-draw-config input{width:50px}.print-config button,.print-draw-config button{padding:4px 8px;font-size:11px;height:28px}.wkt-section .compact-input{font-size:12px;padding:6px 8px}.wkt-section .compact-button{font-size:11px;padding:5px 8px;min-height:28px}::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:11px!important}}@media (max-width: 480px){.toolbox-wrapper{left:.25em;top:6em;transform-origin:left top;max-width:calc(100vw - .5em)}.drag-handle-toolbox{padding:2px 4px;gap:4px}.drag-handle-toolbox mat-icon{font-size:14px;width:14px;height:14px}.toggle-icon{font-size:14px!important;width:14px!important;height:14px!important}.toolbox-container{padding:6px;min-width:24px}.toolbox-content{gap:8px}.all-tools-container{flex-direction:row;align-items:center;max-height:60vh}.main-tools,.geometry-tools{gap:3px;flex-wrap:wrap;justify-content:center}.measurement-print-tools{gap:3px;flex-wrap:wrap;padding:2px 4px;width:100%;justify-content:center}.measurement-tools,.print-tools{gap:3px}.compact-icon{width:26px;height:26px}.tool-separator{display:none}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:26px;min-height:26px;padding:0 6px;font-size:11px}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:11px}.compact-button{font-size:10px;letter-spacing:.2px;padding:4px 6px;min-height:26px}.compact-input{font-size:11px;padding:4px 6px}.print-config,.print-draw-config{gap:4px;padding:6px}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{font-size:10px;height:26px;min-height:26px;padding:2px 6px}.print-config input,.print-draw-config input{width:45px}.print-config button,.print-draw-config button{flex:1;min-width:60px;font-size:10px;padding:3px 6px;height:26px}.print-config .icon-separator,.print-draw-config .icon-separator{font-size:10px}.wkt-section{gap:6px;padding-top:8px}::ng-deep .mat-mdc-slide-toggle{transform:scale(.9)}::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:10px!important}::ng-deep .mat-mdc-select-panel{max-width:calc(100vw - 1em)!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:12px!important;min-height:28px!important;padding:4px 10px!important}}::ng-deep .mat-mdc-simple-snack-bar{background-color:#fff!important}::ng-deep .mat-mdc-tooltip{--mdc-plain-tooltip-container-color: #050505 !important;--mdc-plain-tooltip-supporting-text-color: white !important;border-radius:6px}::ng-deep .mat-mdc-tooltip .mdc-tooltip__surface{background-color:#050505!important;color:#fff!important;border-radius:6px}\n"] }]
|
|
2097
|
+
args: [{ selector: 'map-toolbox', imports: [FormsModule, CommonModule, MatIconModule, MatOptionModule, MatSelectModule, DragDropModule, MatTooltipModule, MatSlideToggleModule], template: "<div class=\"toolbox-wrapper\" \n cdkDrag \n cdkDragBoundary=\".map-container\"\n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\">\n <div class=\"drag-handle-toolbox\" cdkDragHandle>\n <mat-icon>handyman</mat-icon>\n <mat-icon class=\"toggle-icon\" (click)=\"toggleCollapsed($event)\">{{ collapsed ? 'flip_to_front' : 'remove' }}</mat-icon> </div>\n <div class=\"toolbox-container\" [class.collapsed]=\"collapsed\">\n @if(!collapsed) {\n <div class=\"toolbox-content\">\n @if (settings.geometryTypeSettings && settings.geometryTypeSettings.length) {\n <mat-select class=\"geometry-selector\" (selectionChange)=\"settingsChanged($event)\" [(ngModel)]=\"selectedGeometrySetting\" [compareWith]=\"compareGeometrySetting\">\n @for (setting of settings.geometryTypeSettings; track setting) {\n <mat-option [value]=\"setting\">{{setting.typeName}}</mat-option>\n }\n </mat-select> \n }\n <div class=\"all-tools-container\">\n <div class=\"main-tools\">\n @if(!settings?.undoDisabled) {\n <img \n [src]=\"undoIconBase64\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"undo()\" \n matTooltip=\"Fortryd\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Undo\">\n\n <img \n [src]=\"redoIconBase64\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"redo()\" \n matTooltip=\"Gentag\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Redo\">\n }\n <mat-slide-toggle [(ngModel)]=\"snap\" (change)=\"onSnapChange()\">Snap</mat-slide-toggle>\n @if(settings.editEnabled) {\n <img \n [src]=\"editIconBase64\" \n [class.active]=\"activeMode === 'edit'\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"startEdit()\" \n matTooltip=\"Rediger\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Rediger\">\n\n <img \n [src]=\"removePointsIconBase64\" \n [class.active]=\"activeMode === 'edit-remove'\" \n class=\"compact-icon custom-image-icon\"\n (click)=\"startEditRemovePoints()\" \n matTooltip=\"Fjern punkter\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Fjern punkter\">\n }\n @if(settings.cutHoleEnabled) {\n <img \n [src]=\"trimIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'clip-hole'\" \n (click)=\"clipHole()\" \n matTooltip=\"Klip hul\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Klip hul\">\n }\n @if(settings.splitEnabled) {\n <img \n [src]=\"splitIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'split'\"\n (click)=\"split()\" \n matTooltip=\"Sk\u00E6r over\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Sk\u00E6r over\">\n }\n @if(settings.changeTypeEnabled) {\n <mat-icon \n class=\"compact-icon\" \n [class.active]=\"activeMode === 'change-type'\" \n (click)=\"startChangeType()\"\n [matTooltipShowDelay]=\"200\"\n matTooltipClass=\"custom-tooltip\"\n [matTooltipHideDelay]=\"300\" \n matTooltip=\"Skift type\" \n matTooltipPosition=\"below\">\n find_replace\n </mat-icon>\n }\n @if(settings.mergeEnabled) {\n <mat-icon \n class=\"compact-icon\" \n (click)=\"startMergeFeatures()\" \n matTooltipPosition=\"below\"\n [matTooltipShowDelay]=\"200\"\n matTooltipClass=\"custom-tooltip\"\n [matTooltipHideDelay]=\"300\" \n matTooltip=\"Saml flader\" \n [class.active]=\"activeMode === 'merge-features'\">\n merge\n </mat-icon>\n }\n @if(settings.centerPoint) {\n <mat-icon\n (click)=\"setCenterPoint()\"\n matTooltipPosition=\"below\"\n [matTooltipShowDelay]=\"200\"\n matTooltipClass=\"custom-tooltip\"\n [matTooltipHideDelay]=\"300\" \n matTooltip=\"S\u00E6t centerpunkt\" \n [class.active]=\"activeMode === 'center-point'\"\n >adjust</mat-icon>\n }\n </div>\n @if(selectedGeometrySetting && selectedGeometrySetting.availableGeometryTypes?.length) {\n <div class=\"geometry-tools\">\n @for(geomType of selectedGeometrySetting.availableGeometryTypes;track geomType) {\n @if(geomType === 'Polygon') {\n <img \n [src]=\"polygonIconBase64\" \n [class.active]=\"activeMode === 'draw-polygon'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawPolygon()\" \n matTooltip=\"Polygon\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Polygon\">\n }\n @if(geomType === 'LineString') {\n <img \n [src]=\"lineStringIconBase64\" \n [class.active]=\"activeMode === 'draw-linestring'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawLineString()\" \n matTooltip=\"LineString\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"LineString\">\n }\n @if(geomType === 'Point') {\n <img \n [src]=\"pointIconBase64\" \n [class.active]=\"activeMode === 'draw-point'\"\n class=\"compact-icon primary custom-image-icon\"\n (click)=\"startDrawPoint()\" \n matTooltip=\"Punkter\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Punkter\">\n }\n }\n <img \n [src]=\"wktIconBase64\" \n class=\"compact-icon secondary custom-image-icon\"\n (click)=\"activateShowInputWKT()\" \n matTooltip=\"WKT\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"WKT\">\n </div>\n }\n <div class=\"tool-separator\" *ngIf=\"deleteEnabled || showMeasureDistance || showMeasureArea || profile.showPrint\"></div>\n <div class=\"measurement-print-tools\">\n <div class=\"measurement-tools\">\n @if (deleteEnabled) {\n <img \n [src]=\"deleteIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'delete'\"\n (click)=\"startDelete()\" \n matTooltip=\"Slet\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Slet\">\n }\n @if (showMeasureDistance) {\n <img \n [src]=\"measureDistanceIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'measure-distance'\"\n (click)=\"startMeasureLength()\" \n matTooltip=\"M\u00E5le afstand\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"M\u00E5le afstand\">\n }\n @if(showMeasureArea) {\n <img \n [src]=\"measureAreaIconBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"activeMode === 'measure-area'\"\n (click)=\"startMeasureArea()\" \n matTooltip=\"M\u00E5le areal\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"M\u00E5le areal\">\n }\n </div>\n @if(profile.showPrint) {\n <div class=\"tool-separator print-separator\"></div>\n <div class=\"print-tools\">\n <img \n [src]=\"printBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"active === 'Print'\"\n (click)=\"startPrintMode()\" \n matTooltip=\"Udskriv\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Udskriv\">\n <img \n [src]=\"drawBase64\" \n class=\"compact-icon custom-image-icon\"\n [class.active]=\"active === 'Draw'\"\n (click)=\"startDrawMode()\" \n matTooltip=\"Tegn\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipClass=\"custom-tooltip\"\n matTooltipPosition=\"below\"\n alt=\"Tegn\">\n </div>\n }\n </div>\n </div>\n @if(showInputWKT) {\n <div class=\"wkt-section\">\n <input class=\"compact-input\" [(ngModel)]=\"WKTString\">\n <div class=\"wkt-actions\">\n <button class=\"compact-button primary\" (click)=\"ReadWKT()\">Indl\u00E6s WKT</button>\n <button class=\"compact-button\" (click)=\"cancelWKT()\">Annuller</button>\n </div>\n </div>\n }\n @if(profile.showPrint) {\n @if(active === \"Print\") {\n <div class=\"print-config\">\n <img \n [src]=\"printBase64\" \n class=\"compact-icon\"\n (click)=\"doPrint()\" \n alt=\"Udskriv\"> \n <span class=\"icon-separator\">i</span>\n <select id=\"formatSelector\" [(ngModel)]=\"format\">\n <option value=\"image/png\" selected>.PNG</option>\n <option value=\"image/jpeg\">.JPG</option>\n </select>\n <select id=\"dimensionSelector\" [(ngModel)]=\"dimId\" (change)=\"handleDimensionSelected()\">\n <option value=\"99\" selected></option>\n <option value=\"0\">1920 X 1080</option>\n <option value=\"1\">1680 X 1050</option>\n <option value=\"2\">1280 X 800</option>\n <option value=\"3\">800 X 600</option>\n </select>\n <input type=\"text\" [(ngModel)]=\"mapWidth\"/> \n <span class=\"icon-separator\">x</span>\n <input type=\"text\" [(ngModel)]=\"mapHeight\"/>\n <button (click)=\"setNewMapDimensions()\">V\u00E6lg</button>\n </div>\n }\n @if(active === \"PrintDraw\") {\n <div class=\"print-draw-config\">\n <span class=\"icon-separator\">Label</span>\n <input type=\"text\" [(ngModel)]=\"printDrawLabel\"/>\n <select id=\"drawToolSelector\" [(ngModel)]=\"printDrawTool\" (change)=\"handlePrintDrawToolChanged()\">\n <option value=\"Arrow\" selected>Pil</option>\n <option value=\"Point\">Punkt</option>\n <option value=\"LineString\">Linje</option>\n <option value=\"Polygon\">Polygon</option>\n <option value=\"Circle\">Cirkel</option>\n <option value=\"Square\">Kvadrat</option>\n <option value=\"Rectangle\">Firkant</option>\n </select>\n <button class=\"compact-button\" (click)=\"handleClearPrintDrawFeatures()\">Ryd</button>\n </div>\n }\n }\n </div>\n }\n </div>\n</div>\n", styles: [".toolbox-wrapper{position:absolute;left:1em;top:31.5em;z-index:1000;cursor:grab;max-width:95vw}.toolbox-wrapper.cdk-drag-dragging{opacity:.8;cursor:grab;z-index:1001}.drag-handle-toolbox{display:flex;align-items:center;justify-content:space-between;background:color-mix(in srgb,#000 60%,transparent);padding:2px 10px;cursor:grab;gap:8px;border-radius:5px 5px 0 0}.drag-handle-toolbox mat-icon{color:#fff;font-size:18px;width:18px;height:18px}.drag-handle-toolbox mat-icon:first-child{flex:1;text-align:left}.toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:18px!important;width:18px!important;height:18px!important;display:flex;align-items:center;justify-content:center;border-radius:4px;padding:2px;flex-shrink:0}.toggle-icon:hover{color:#fff;background:#ffffff26}.toggle-icon:active{background:#ffffff40}:host{position:relative;display:flex;justify-content:center}:host.expanded{width:auto;min-width:320px;padding:12px}.toolbox-container{display:flex;flex-direction:column;align-items:center;width:100%;gap:10px;background:color-mix(in srgb,#000 60%,transparent);box-shadow:#0000004d 0 1px 4px -1px;padding:10px;width:auto;min-width:32px;transition:all .3s ease;cursor:default;border-radius:0 0 5px 5px}.toolbox-container.collapsed{display:none}.toolbox-content{display:flex;flex-direction:column;width:100%;gap:3px;animation:slideDown .3s cubic-bezier(.4,0,.2,1)}.all-tools-container{display:flex;flex-direction:row;align-items:center;flex-wrap:nowrap;width:100%;justify-content:flex-start;overflow-x:hidden}.all-tools-container::-webkit-scrollbar{height:4px}.all-tools-container::-webkit-scrollbar-thumb{background:#ccc;border-radius:2px}.main-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.main-tools ::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:12px;font-weight:500;color:#fff}.geometry-selector{width:100%}.geometry-selector ::ng-deep .mat-mdc-select{font-size:14px;line-height:1.4;border-radius:6px}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:32px;min-height:32px;padding:0 10px;border:none;border-radius:6px;background:color-mix(in srgb,#000 60%,transparent);transition:all .2s ease}.geometry-selector ::ng-deep .mat-mdc-select-trigger:hover{background:color-mix(in srgb,#000 70%,transparent);border-color:#667eea;box-shadow:0 4px 12px #0003}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:14px;font-weight:500;color:#fff}.geometry-selector ::ng-deep .mat-mdc-select-arrow-wrapper{height:16px;transform:scale(.85)}.geometry-selector ::ng-deep .mat-mdc-form-field-infix{min-height:32px;padding:6px 0}.geometry-selector ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .mat-mdc-select-panel{min-width:fit-content!important;max-width:320px!important;background:color-mix(in srgb,#000 100%,transparent)!important;border:none!important;border-radius:8px!important;box-shadow:0 8px 24px #0000001f,0 2px 6px #00000014!important;margin-top:6px!important;padding:4px 0!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:14px!important;min-height:36px!important;padding:8px 14px!important;transition:all .15s ease!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option:hover:not(.mat-mdc-option-disabled){background:#444849!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option.mat-active{background:color-mix(in srgb,#000 60%,transparent)!important;color:#fff!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option .mdc-list-item__primary-text{font-size:14px!important;font-weight:500!important;color:#fff!important}::ng-deep .cdk-overlay-pane{z-index:1001}::ng-deep .cdk-overlay-backdrop{z-index:1000}.geometry-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.measurement-print-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap;background:color-mix(in srgb,#000 20%,transparent);border-radius:8px;padding:4px 8px;border:1px solid rgba(255,255,255,.1)}.measurement-tools,.print-tools{display:flex;flex-direction:row;align-items:center;gap:6px;flex-wrap:nowrap}.measurement-tools .compact-icon,.print-tools .compact-icon{transition:all .3s cubic-bezier(.4,0,.2,1)}.measurement-tools .compact-icon.custom-image-icon,.print-tools .compact-icon.custom-image-icon{padding:4px;background:none;border:1px solid rgba(255,255,255,.2)}.measurement-tools .compact-icon.custom-image-icon img,.print-tools .compact-icon.custom-image-icon img{width:100%;height:100%;object-fit:contain;transition:filter .2s ease}.measurement-tools .compact-icon.custom-image-icon.active,.print-tools .compact-icon.custom-image-icon.active{background:linear-gradient(147.38deg,#0ea5e9,#075985);border-color:transparent;box-shadow:0 4px 12px #0ea5e966}.measurement-tools .compact-icon.custom-image-icon.active img,.print-tools .compact-icon.custom-image-icon.active img{filter:brightness(0) invert(1)}.measurement-tools .compact-icon.custom-image-icon.active:hover,.print-tools .compact-icon.custom-image-icon.active:hover{box-shadow:0 6px 20px #0ea5e980}.measurement-tools .compact-icon.custom-image-icon:hover:not(.active),.print-tools .compact-icon.custom-image-icon:hover:not(.active){background:color-mix(in srgb,#000 70%,transparent);border-color:#0ea5e9;box-shadow:0 2px 8px #0ea5e94d}.measurement-tools .compact-icon.custom-image-icon:hover:not(.active) img,.print-tools .compact-icon.custom-image-icon:hover:not(.active) img{filter:brightness(0) invert(.8)}.print-tools .compact-icon{background:linear-gradient(147.38deg,#4f46e5,#3730a3);color:#fff;border:1px solid rgba(255,255,255,.2)}.print-tools .compact-icon.print-icon{background:linear-gradient(147.38deg,#10b981,#047857)}.print-tools .compact-icon.draw-icon{background:linear-gradient(147.38deg,#f59e0b,#d97706)}.print-tools .compact-icon.active{background:linear-gradient(147.38deg,#ef4444,#dc2626);box-shadow:0 4px 12px #ef444466;border-color:transparent;transform:scale(1.05)}.print-tools .compact-icon.active:hover{box-shadow:0 6px 20px #ef444480;transform:scale(1.08)}.print-tools .compact-icon:hover:not(.active){box-shadow:0 4px 12px #0000004d;opacity:.9}.tool-separator{width:1px;height:24px;background:linear-gradient(to bottom,transparent,rgba(255,255,255,.3),transparent);margin:0 4px}.tool-separator.print-separator{height:28px;background:linear-gradient(to bottom,transparent,rgba(255,255,255,.5),transparent)}.compact-icon{cursor:pointer;color:#fff;transition:all .3s cubic-bezier(.4,0,.2,1);width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:6px;background:color-mix(in srgb,#000 40%,transparent);border:1px solid rgba(255,255,255,.2);box-shadow:0 1px 2px #0000001a;flex-shrink:0}.compact-icon.active{color:#fff;background:linear-gradient(135deg,#667eea,#764ba2);border-color:transparent;box-shadow:0 8px 25px #667eea4d;transform:scale(1.05)}.compact-icon.active:hover{box-shadow:0 12px 35px #667eea66;transform:scale(1.08)}.compact-icon:hover:not(.active){color:#fff;background:color-mix(in srgb,#000 70%,transparent);border-color:#667eea;box-shadow:0 4px 12px #0003}.compact-icon.custom-image-icon{padding:0;background:none;border:none}.compact-icon.custom-image-icon img{width:100%;height:100%;object-fit:contain;transition:transform .2s ease}.compact-icon.custom-image-icon.active{background:linear-gradient(135deg,#667eea,#764ba2);border-color:transparent}.compact-icon.custom-image-icon.active img{filter:brightness(0) invert(1);transform:scale(1.1)}.compact-icon.custom-image-icon:hover:not(.active) img{transform:scale(1.05)}.wkt-section{display:flex;flex-direction:column;gap:8px;padding-top:10px;border-top:1px solid rgba(255,255,255,.1);animation:fadeIn .2s ease}.wkt-actions{display:flex;gap:6px;justify-content:space-between}.compact-button{padding:6px 10px;border:none;border-radius:6px;background:color-mix(in srgb,#000 60%,transparent);color:#fff;font-size:12px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);text-transform:uppercase;letter-spacing:.4px;min-height:32px;display:flex;align-items:center;justify-content:center;flex:1;box-shadow:0 1px 2px #0000000d}.compact-button.primary.active{background:linear-gradient(135deg,#667eea,#764ba2);box-shadow:0 8px 25px #667eea4d;color:#fff}.compact-button.primary.active:hover{box-shadow:0 12px 35px #667eea66}.compact-button.secondary{background:color-mix(in srgb,#000 20%,transparent);color:#fff}.compact-button.secondary:hover{background:color-mix(in srgb,#5a6268 60%,transparent)}.compact-input{padding:8px 10px;border:none;border-radius:6px;font-size:13px;transition:all .2s ease;background:color-mix(in srgb,#000 60%,transparent);color:#fff}.compact-input:focus{outline:none;border-color:#1976d2;background:color-mix(in srgb,#000 70%,transparent);box-shadow:0 0 0 3px #1976d233}.print-config,.print-draw-config{display:flex;align-items:center;gap:8px;padding:5px;background:color-mix(in srgb,#000 40%,transparent);border-radius:8px;border:1px solid rgba(255,255,255,.1);animation:slideDown .3s ease}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{background:color-mix(in srgb,#000 60%,transparent);border:1px solid rgba(255,255,255,.2);color:#fff;border-radius:6px;font-size:12px;height:32px;min-height:32px;padding:0 10px}.print-config select:focus,.print-config input:focus,.print-draw-config select:focus,.print-draw-config input:focus{outline:none;border-color:#0ea5e9;box-shadow:0 0 0 2px #0ea5e933}.print-config select,.print-draw-config select{cursor:pointer}.print-config option,.print-draw-config option{background:color-mix(in srgb,#000 98%,transparent)!important;border:none!important}.print-config input,.print-draw-config input{width:60px;text-align:center}.print-config button,.print-draw-config button{background:linear-gradient(147.38deg,#10b981,#047857);color:#fff;border:none;padding:6px 12px;border-radius:4px;font-size:12px;cursor:pointer;transition:all .2s ease}.print-config button:hover,.print-draw-config button:hover{box-shadow:0 4px 12px #10b9814d}.print-config .icon-separator,.print-draw-config .icon-separator{color:#fff}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes pulse{0%{box-shadow:0 0 #667eeab3}70%{box-shadow:0 0 0 6px #667eea00}to{box-shadow:0 0 #667eea00}}.compact-icon.active{animation:pulse 2s infinite}@media (max-width: 768px){.toolbox-wrapper{left:.5em;top:8em;max-width:calc(100vw - 2.5em)}.drag-handle-toolbox{padding:3px 6px;gap:6px}.drag-handle-toolbox mat-icon{font-size:16px;width:16px;height:16px}.toggle-icon{font-size:16px!important;width:16px!important;height:16px!important}.toolbox-container{padding:8px;min-width:28px;max-width:calc(100vw - 3em)}:host{padding:8px;min-width:32px}:host.expanded{min-width:280px;padding:10px}.all-tools-container{flex-wrap:wrap;gap:6px;max-height:50vh;overflow-y:auto;padding:0;-ms-overflow-style:none;scrollbar-width:none}.all-tools-container::-webkit-scrollbar{display:none}.main-tools,.geometry-tools,.measurement-print-tools,.print-tools{display:flex;flex-wrap:wrap;justify-content:center;gap:4px}.compact-icon{width:28px;height:28px;flex-shrink:0}.measurement-print-tools{padding:3px 6px}.geometry-selector{width:100%;margin-bottom:8px}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:28px;min-height:28px;padding:0 8px;font-size:12px}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:12px}::ng-deep .mat-mdc-select-panel{max-width:calc(100vw - 2em)!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:13px!important;min-height:32px!important;padding:6px 12px!important}.print-config,.print-draw-config{flex-direction:column;align-items:stretch;gap:6px}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{font-size:11px;padding:4px 8px;height:28px;min-height:28px}.print-config input,.print-draw-config input{width:50px}.print-config button,.print-draw-config button{padding:4px 8px;font-size:11px;height:28px}.wkt-section .compact-input{font-size:12px;padding:6px 8px}.wkt-section .compact-button{font-size:11px;padding:5px 8px;min-height:28px}::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:11px!important}}@media (max-width: 480px){.toolbox-wrapper{left:.25em;top:6em;transform-origin:left top;max-width:calc(100vw - .5em)}.drag-handle-toolbox{padding:2px 4px;gap:4px}.drag-handle-toolbox mat-icon{font-size:14px;width:14px;height:14px}.toggle-icon{font-size:14px!important;width:14px!important;height:14px!important}.toolbox-container{padding:6px;min-width:24px}.toolbox-content{gap:8px}.all-tools-container{flex-direction:row;align-items:center;max-height:60vh}.main-tools,.geometry-tools{gap:3px;flex-wrap:wrap;justify-content:center}.measurement-print-tools{gap:3px;flex-wrap:wrap;padding:2px 4px;width:100%;justify-content:center}.measurement-tools,.print-tools{gap:3px}.compact-icon{width:26px;height:26px}.tool-separator{display:none}.geometry-selector ::ng-deep .mat-mdc-select-trigger{height:26px;min-height:26px;padding:0 6px;font-size:11px}.geometry-selector ::ng-deep .mat-mdc-select-value{font-size:11px}.compact-button{font-size:10px;letter-spacing:.2px;padding:4px 6px;min-height:26px}.compact-input{font-size:11px;padding:4px 6px}.print-config,.print-draw-config{gap:4px;padding:6px}.print-config select,.print-config input,.print-draw-config select,.print-draw-config input{font-size:10px;height:26px;min-height:26px;padding:2px 6px}.print-config input,.print-draw-config input{width:45px}.print-config button,.print-draw-config button{flex:1;min-width:60px;font-size:10px;padding:3px 6px;height:26px}.print-config .icon-separator,.print-draw-config .icon-separator{font-size:10px}.wkt-section{gap:6px;padding-top:8px}::ng-deep .mat-mdc-slide-toggle{transform:scale(.9)}::ng-deep .mat-mdc-slide-toggle .mdc-label{font-size:10px!important}::ng-deep .mat-mdc-select-panel{max-width:calc(100vw - 1em)!important}::ng-deep .mat-mdc-select-panel .mat-mdc-option{font-size:12px!important;min-height:28px!important;padding:4px 10px!important}}::ng-deep .mat-mdc-simple-snack-bar{background-color:#fff!important}::ng-deep .mat-mdc-tooltip{--mdc-plain-tooltip-container-color: #050505 !important;--mdc-plain-tooltip-supporting-text-color: white !important;border-radius:6px}::ng-deep .mat-mdc-tooltip .mdc-tooltip__surface{background-color:#050505!important;color:#fff!important;border-radius:6px}\n"] }]
|
|
1750
2098
|
}], ctorParameters: () => [], propDecorators: { map: [{
|
|
1751
2099
|
type: Input,
|
|
1752
2100
|
args: [{ required: true }]
|
|
@@ -1770,12 +2118,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
1770
2118
|
|
|
1771
2119
|
class ActiveObjectsComponent {
|
|
1772
2120
|
_drawLayerService = inject(DrawLayerSourceService);
|
|
2121
|
+
_centerPointService = inject(CenterPointService);
|
|
2122
|
+
_undoRedo = inject(UndoRedoService);
|
|
1773
2123
|
features$ = this._drawLayerService.features$;
|
|
1774
2124
|
collapsed = false;
|
|
1775
2125
|
settings;
|
|
1776
2126
|
activeFeatures = [];
|
|
1777
2127
|
_featureHelper = inject(FeatureHelperService);
|
|
1778
|
-
_highlight = inject(
|
|
2128
|
+
_highlight = inject(HighlightService);
|
|
1779
2129
|
_zoomService = inject(ZoomService);
|
|
1780
2130
|
opacity = 1;
|
|
1781
2131
|
dragPosition = { x: 0, y: 0 };
|
|
@@ -1789,7 +2139,12 @@ class ActiveObjectsComponent {
|
|
|
1789
2139
|
.map(ft => ({ featureType: ft,
|
|
1790
2140
|
display: this.settings.geometryTypeSettings.find(gts => gts.typeId === ft).typeName,
|
|
1791
2141
|
features: features.filter(f => this._featureHelper.typeId(f) === ft)
|
|
1792
|
-
.map(f => ({
|
|
2142
|
+
.map(f => ({
|
|
2143
|
+
id: f.getId(),
|
|
2144
|
+
feature: f,
|
|
2145
|
+
locked: this._featureHelper.isLocked(f),
|
|
2146
|
+
area: this._getAreaString(f)
|
|
2147
|
+
})) }));
|
|
1793
2148
|
this.activeFeatures = [...featuresObj];
|
|
1794
2149
|
}
|
|
1795
2150
|
});
|
|
@@ -1803,10 +2158,13 @@ class ActiveObjectsComponent {
|
|
|
1803
2158
|
}
|
|
1804
2159
|
return this.settings.sizeInHa ? `(${(getArea(feature.getGeometry()) / 10000).toFixed(2)} ha)` : `(${getArea(feature.getGeometry()).toFixed(2)} m2)`;
|
|
1805
2160
|
}
|
|
2161
|
+
reset() {
|
|
2162
|
+
this._undoRedo.reset();
|
|
2163
|
+
this.highlightedId = null;
|
|
2164
|
+
this._highlight.clear();
|
|
2165
|
+
this.zoomToAll();
|
|
2166
|
+
}
|
|
1806
2167
|
zoomToAll() {
|
|
1807
|
-
const formatter = new GeoJSON({ dataProjection: 'EPSG:25832', featureProjection: 'EPSG:25832' });
|
|
1808
|
-
const allTheFeatures = formatter.writeFeaturesObject(this._drawLayerService.allFeatures);
|
|
1809
|
-
console.log("🚀 ~ ActiveObjectsComponent ~ zoomToAll ~ allTheFeatures:", JSON.stringify(allTheFeatures));
|
|
1810
2168
|
this._zoomService.zoomToFeatures(this._drawLayerService.allFeatures);
|
|
1811
2169
|
}
|
|
1812
2170
|
highlight(id) {
|
|
@@ -1827,6 +2185,7 @@ class ActiveObjectsComponent {
|
|
|
1827
2185
|
}
|
|
1828
2186
|
delete(id) {
|
|
1829
2187
|
this._drawLayerService.remove(id);
|
|
2188
|
+
this._centerPointService.handleFeatureDeleted(id);
|
|
1830
2189
|
this._highlight.clear();
|
|
1831
2190
|
}
|
|
1832
2191
|
togglePanel() {
|
|
@@ -1858,33 +2217,158 @@ class ActiveObjectsComponent {
|
|
|
1858
2217
|
}
|
|
1859
2218
|
}
|
|
1860
2219
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ActiveObjectsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1861
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ActiveObjectsComponent, isStandalone: true, selector: "activeObjects", inputs: { settings: "settings" }, ngImport: i0, template: "<div class=\"active-objects-wrapper\" \n cdkDrag \n cdkDragBoundary=\".map-container\" \n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\"\n [class.collapsed]=\"collapsed\">\n <div class=\"drag-handle-active-objects\" cdkDragHandle>\n <mat-icon class=\"zoom-icon\" (click)=\"zoomToAll()\">share_reviewsr</mat-icon>\n @if(!collapsed) {\n <h4>Aktive flader</h4>\n }\n <mat-icon class=\"toggle-icon\" (click)=\"togglePanel()\">\n {{ collapsed ? 'flip_to_front' : 'remove' }}\n </mat-icon>\n </div>\n <div class=\"active-objects-container\">\n @if(!collapsed) {\n <input \n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n [(ngModel)]=\"opacity\"\n (input)=\"updateOpacity()\"\n (mousedown)=\"stopDrag($event)\"\n (touchstart)=\"stopDrag($event)\"\n (pointerdown)=\"stopDrag($event)\"\n >\n }\n\n @if(!collapsed) {\n <div class=\"active-objects-content\">\n <mat-icon class=\"zoom-icon\" (click)=\"zoomToAll()\">highlight</mat-icon>\n @for(featureTypeObj of activeFeatures; track featureTypeObj.featureType) {\n <mat-expansion-panel>\n <mat-expansion-panel-header \n [matTooltip]=\"featureTypeObj.display\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"right\">\n <span class=\"panel-title\">\n {{featureTypeObj.display}} ({{featureTypeObj.features.length}})\n </span>\n </mat-expansion-panel-header>\n <div class=\"item-list\">\n @for(item of featureTypeObj.features; track item.id) {\n <div class=\"item\">\n <div class=\"item-text\">\n <span class=\"item-id\">{{item.id}}</span>\n <span class=\"item-area\">{{item.area}}</span>\n </div>\n <mat-icon *ngIf=\"!item.locked\" (click)=\"delete(item.id)\">delete</mat-icon>\n <mat-icon (click)=\"highlight(item.id)\" [class.highlight-active]=\"highlightedId === item.id\">highlight</mat-icon>\n </div>\n }\n </div>\n </mat-expansion-panel>\n }\n </div>\n }\n </div> \n</div>", styles: ["@charset \"UTF-8\";.active-objects-wrapper{position:absolute;top:15em;left:1em;z-index:1000;cursor:grab;box-shadow:0 2px 10px #0000001a;background:color-mix(in srgb,#000 60%,transparent);width:fit-content;max-width:295px;transition:width .3s ease}.active-objects-wrapper.collapsed{width:70px;max-width:150px}.active-objects-wrapper.cdk-drag-dragging{opacity:.8;cursor:grab;z-index:1001}mat-expansion-panel ::ng-deep .mat-expansion-panel-header .panel-title{display:block;overflow:visible;text-overflow:clip;white-space:normal;max-width:220px;margin-right:10px;line-height:1.3;word-break:break-word}.item{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-radius:4px;background:color-mix(in srgb,#000 60%,transparent)!important;transition:all .2s ease;font-size:14px;color:#fff;min-height:40px;cursor:default}.item .item-text{flex:1;min-width:0;display:flex;flex-direction:column;overflow:hidden}.item .item-id{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-bottom:2px}.item .item-area{font-size:12px;color:#ccc;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item mat-icon{cursor:pointer;color:#f44336;font-size:18px;width:18px;height:18px;flex-shrink:0;margin-left:8px;transition:color .2s ease,background .2s ease}.item mat-icon:hover{color:#d32f2f}.highlight-active{color:#4caf50!important;text-shadow:0 0 6px #4caf50;transform:scale(1.1);transition:all .2s ease}.drag-handle-active-objects{display:flex;align-items:center;justify-content:space-between;background:color-mix(in srgb,#000 0%,transparent);border-radius:8px 8px 0 0;padding:4px 8px;cursor:grab}.drag-handle-active-objects h4{margin:0;padding:5px;background:transparent;font-weight:600;color:#fff;flex:1;font-size:16px;-webkit-user-select:none;user-select:none;transition:color .2s ease;white-space:nowrap;text-align:center}.drag-handle-active-objects .zoom-icon{color:#fff;font-size:18px;width:18px;height:18px}.drag-handle-active-objects .toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:22px;width:22px;height:22px;display:flex;align-items:center;justify-content:center;border-radius:6px;flex-shrink:0;margin:0}.drag-handle-active-objects .toggle-icon:hover{color:#ffffffb3;background:#1976d214}.active-objects-container{display:flex;flex-direction:column;align-items:center;width:100%;gap:10px;transition:all .3s ease;cursor:default;box-sizing:border-box}.active-objects-container .panel-header{display:flex;align-items:center;justify-content:space-between;width:100%;padding:5px;cursor:default}.active-objects-container .panel-header h4{margin:0;padding:5px;background:transparent;font-weight:600;color:#fff;flex:1;font-size:16px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease;white-space:nowrap;text-align:center}.active-objects-container .panel-header .toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:22px;width:22px;height:22px;display:flex;align-items:center;justify-content:center;border-radius:6px;flex-shrink:0;margin:0}.active-objects-container .panel-header .toggle-icon:hover{color:#ffffffb3;background:#1976d214}.active-objects-container .collapsed-title{color:#fff;font-weight:600;font-size:12px;padding:8px 4px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease;white-space:nowrap;text-align:center}.active-objects-container .collapsed-title:hover{color:#1976d2}.active-objects-content{display:block;max-height:278px;overflow:auto}.active-objects-content::-webkit-scrollbar{width:8px;border-radius:10px;border:5px solid transparent}.active-objects-content::-webkit-scrollbar-thumb{background:#0000004d;border:5px solid transparent;border-radius:10px;background-clip:padding-box}.active-objects-content::-webkit-scrollbar-thumb:hover{background:#0006;background-clip:padding-box;border:3px solid transparent}.active-objects-content .zoom-icon{color:#4caf50!important;border-radius:50%;padding:6px;margin:4px;cursor:pointer;transition:all .3s ease;font-size:20px;width:20px;height:20px}.active-objects-content .zoom-icon:hover{background:#4caf5033!important}mat-expansion-panel{border-radius:0!important;box-shadow:none!important}mat-expansion-panel:last-child{border-bottom:none}mat-expansion-panel ::ng-deep .mat-expansion-panel-header{padding:0 16px;font-weight:500}mat-expansion-panel ::ng-deep .mat-expansion-panel-header .mat-content{display:flex;justify-content:space-between;align-items:center;color:#fff}mat-expansion-panel ::ng-deep .mat-expansion-panel-body{padding:0}.item-list{display:flex;flex-direction:column;gap:4px;padding:8px;max-height:300px;overflow-y:auto}.item-list::-webkit-scrollbar{width:6px}.item-list::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.item-list::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px}.item-list::-webkit-scrollbar-thumb:hover{background:#a8a8a8}@media (max-width: 768px){.active-objects-wrapper{right:.5em;top:8em;max-width:280px;width:280px}.item{font-size:13px;padding:6px 10px}}@media (max-width: 480px){.active-objects-wrapper{right:.5em;left:.5em;max-width:calc(100vw - 1em);width:auto}.item-list{max-height:200px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i3.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i3.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i4.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
2220
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ActiveObjectsComponent, isStandalone: true, selector: "activeObjects", inputs: { settings: "settings" }, ngImport: i0, template: "<div class=\"active-objects-wrapper\" \n cdkDrag \n cdkDragBoundary=\".map-container\" \n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\"\n [class.collapsed]=\"collapsed\">\n <div class=\"drag-handle-active-objects\" cdkDragHandle>\n <mat-icon class=\"zoom-icon\" (click)=\"zoomToAll()\">dynamic_form</mat-icon>\n <mat-icon class=\"toggle-icon\" (click)=\"togglePanel()\">\n {{ collapsed ? 'flip_to_front' : 'remove' }}\n </mat-icon>\n </div>\n <div class=\"active-objects-container\">\n @if(!collapsed) {\n <input \n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n [(ngModel)]=\"opacity\"\n (input)=\"updateOpacity()\"\n (mousedown)=\"stopDrag($event)\"\n (touchstart)=\"stopDrag($event)\"\n (pointerdown)=\"stopDrag($event)\"\n >\n }\n\n @if(!collapsed) {\n <div class=\"active-objects-content\">\n <mat-icon class=\"zoom-icon\" (click)=\"zoomToAll()\">highlight</mat-icon>\n <mat-icon (click)=\"reset()\">replay</mat-icon>\n @for(featureTypeObj of activeFeatures; track featureTypeObj.featureType) {\n <mat-expansion-panel>\n <mat-expansion-panel-header \n [matTooltip]=\"featureTypeObj.display\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"right\">\n <span class=\"panel-title\">\n {{featureTypeObj.display}} ({{featureTypeObj.features.length}})\n </span>\n </mat-expansion-panel-header>\n <div class=\"item-list\">\n @for(item of featureTypeObj.features; track item.id) {\n <div class=\"item\">\n <div class=\"item-text\">\n <span class=\"item-id\">{{item.id}}</span>\n <span class=\"item-area\">{{item.area}}</span>\n </div>\n @if(!item.locked) {\n <mat-icon (click)=\"delete(item.id)\">delete</mat-icon>\n }\n <mat-icon (click)=\"highlight(item.id)\" [class.highlight-active]=\"highlightedId === item.id\">highlight</mat-icon>\n </div>\n }\n </div>\n </mat-expansion-panel>\n }\n </div>\n }\n </div> \n</div>", styles: ["@charset \"UTF-8\";.active-objects-wrapper{position:absolute;top:15em;left:1em;z-index:1000;cursor:grab;box-shadow:0 2px 10px #0000001a;background:color-mix(in srgb,#000 60%,transparent);width:fit-content;max-width:295px;transition:width .3s ease;border-radius:5px 5px 0 0}.active-objects-wrapper.collapsed{width:70px;max-width:150px}.active-objects-wrapper.cdk-drag-dragging{opacity:.8;cursor:grab;z-index:1001}mat-expansion-panel ::ng-deep .mat-expansion-panel-header .panel-title{display:block;overflow:visible;text-overflow:clip;white-space:normal;max-width:220px;margin-right:10px;line-height:1.3;word-break:break-word}.item{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-radius:4px;background:color-mix(in srgb,#000 60%,transparent)!important;transition:all .2s ease;font-size:14px;color:#fff;min-height:40px;cursor:default}.item .item-text{flex:1;min-width:0;display:flex;flex-direction:column;overflow:hidden}.item .item-id{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-bottom:2px}.item .item-area{font-size:12px;color:#ccc;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item mat-icon{cursor:pointer;color:#f44336;font-size:18px;width:18px;height:18px;flex-shrink:0;margin-left:8px;transition:color .2s ease,background .2s ease}.item mat-icon:hover{color:#d32f2f}.highlight-active{color:#4caf50!important;text-shadow:0 0 6px #4caf50;transform:scale(1.1);transition:all .2s ease}.drag-handle-active-objects{display:flex;align-items:center;justify-content:space-between;background:color-mix(in srgb,#000 0%,transparent);padding:4px 8px;cursor:grab}.drag-handle-active-objects .zoom-icon{color:#fff;font-size:18px;width:18px;height:18px}.drag-handle-active-objects .toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:18px!important;width:18px!important;height:18px!important;display:flex;align-items:center;justify-content:center;border-radius:4px;padding:2px;flex-shrink:0}.drag-handle-active-objects .toggle-icon:hover{color:#fff;background:#ffffff26}.active-objects-container{display:flex;flex-direction:column;align-items:center;width:100%;gap:10px;transition:all .3s ease;cursor:default;box-sizing:border-box}.active-objects-container .panel-header{display:flex;align-items:center;justify-content:space-between;width:100%;padding:5px;cursor:default}.active-objects-container .panel-header h4{margin:0;padding:5px;background:transparent;font-weight:600;color:#fff;flex:1;font-size:16px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease;white-space:nowrap;text-align:center}.active-objects-container .collapsed-title{color:#fff;font-weight:600;font-size:12px;padding:8px 4px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease;white-space:nowrap;text-align:center}.active-objects-container .collapsed-title:hover{color:#1976d2}.active-objects-content{display:block;max-height:278px;overflow:auto}.active-objects-content::-webkit-scrollbar{width:12px}.active-objects-content::-webkit-scrollbar-track{background:#757474;border-radius:8px}.active-objects-content::-webkit-scrollbar-thumb{background:#1a1c1f;border-radius:8px;border:2px solid #2a2c30}.active-objects-content::-webkit-scrollbar-thumb:hover{background:#0f1012}.active-objects-content::-webkit-scrollbar-button{width:12px;height:16px;background:#2a2c30;border:1px solid #1a1c1f}.active-objects-content::-webkit-scrollbar-button:vertical:decrement{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 4l-4 4h8z'/%3E%3C/svg%3E\") no-repeat center;border-radius:8px 8px 0 0}.active-objects-content::-webkit-scrollbar-button:vertical:decrement:hover{background-color:#1a1c1f}.active-objects-content::-webkit-scrollbar-button:vertical:increment{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 8l4-4H2z'/%3E%3C/svg%3E\") no-repeat center;border-radius:0 0 8px 8px}.active-objects-content::-webkit-scrollbar-button:vertical:increment:hover{background-color:#1a1c1f}.active-objects-content .zoom-icon{color:#4caf50!important;border-radius:50%;padding:6px;margin:4px;cursor:pointer;transition:all .3s ease;font-size:20px;width:20px;height:20px}.active-objects-content .zoom-icon:hover{background:#4caf5033!important}mat-expansion-panel{border-radius:0!important;box-shadow:none!important}mat-expansion-panel:last-child{border-bottom:none}mat-expansion-panel ::ng-deep .mat-expansion-panel-header{padding:0 16px;font-weight:500}mat-expansion-panel ::ng-deep .mat-expansion-panel-header .mat-content{display:flex;justify-content:space-between;align-items:center;color:#fff}mat-expansion-panel ::ng-deep .mat-expansion-panel-body{padding:0}.item-list{display:flex;flex-direction:column;gap:4px;padding:8px;max-height:300px;overflow-y:auto}.item-list::-webkit-scrollbar{width:6px}.item-list::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.item-list::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px}.item-list::-webkit-scrollbar-thumb:hover{background:#a8a8a8}@media (max-width: 768px){.active-objects-wrapper{right:.5em;top:8em;max-width:280px;width:280px}.item{font-size:13px;padding:6px 10px}}@media (max-width: 480px){.active-objects-wrapper{right:.5em;left:.5em;max-width:calc(100vw - 1em);width:auto}.item-list{max-height:200px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i5.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i5.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i4.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
1862
2221
|
}
|
|
1863
2222
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ActiveObjectsComponent, decorators: [{
|
|
1864
2223
|
type: Component,
|
|
1865
|
-
args: [{ selector: 'activeObjects', imports: [CommonModule, FormsModule, MatExpansionModule, MatIconModule, DragDropModule, MatTooltipModule], template: "<div class=\"active-objects-wrapper\" \n cdkDrag \n cdkDragBoundary=\".map-container\" \n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\"\n [class.collapsed]=\"collapsed\">\n <div class=\"drag-handle-active-objects\" cdkDragHandle>\n <mat-icon class=\"zoom-icon\" (click)=\"zoomToAll()\">
|
|
2224
|
+
args: [{ selector: 'activeObjects', imports: [CommonModule, FormsModule, MatExpansionModule, MatIconModule, DragDropModule, MatTooltipModule], template: "<div class=\"active-objects-wrapper\" \n cdkDrag \n cdkDragBoundary=\".map-container\" \n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\"\n [class.collapsed]=\"collapsed\">\n <div class=\"drag-handle-active-objects\" cdkDragHandle>\n <mat-icon class=\"zoom-icon\" (click)=\"zoomToAll()\">dynamic_form</mat-icon>\n <mat-icon class=\"toggle-icon\" (click)=\"togglePanel()\">\n {{ collapsed ? 'flip_to_front' : 'remove' }}\n </mat-icon>\n </div>\n <div class=\"active-objects-container\">\n @if(!collapsed) {\n <input \n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n [(ngModel)]=\"opacity\"\n (input)=\"updateOpacity()\"\n (mousedown)=\"stopDrag($event)\"\n (touchstart)=\"stopDrag($event)\"\n (pointerdown)=\"stopDrag($event)\"\n >\n }\n\n @if(!collapsed) {\n <div class=\"active-objects-content\">\n <mat-icon class=\"zoom-icon\" (click)=\"zoomToAll()\">highlight</mat-icon>\n <mat-icon (click)=\"reset()\">replay</mat-icon>\n @for(featureTypeObj of activeFeatures; track featureTypeObj.featureType) {\n <mat-expansion-panel>\n <mat-expansion-panel-header \n [matTooltip]=\"featureTypeObj.display\" \n [matTooltipShowDelay]=\"200\"\n [matTooltipHideDelay]=\"300\" \n matTooltipPosition=\"right\">\n <span class=\"panel-title\">\n {{featureTypeObj.display}} ({{featureTypeObj.features.length}})\n </span>\n </mat-expansion-panel-header>\n <div class=\"item-list\">\n @for(item of featureTypeObj.features; track item.id) {\n <div class=\"item\">\n <div class=\"item-text\">\n <span class=\"item-id\">{{item.id}}</span>\n <span class=\"item-area\">{{item.area}}</span>\n </div>\n @if(!item.locked) {\n <mat-icon (click)=\"delete(item.id)\">delete</mat-icon>\n }\n <mat-icon (click)=\"highlight(item.id)\" [class.highlight-active]=\"highlightedId === item.id\">highlight</mat-icon>\n </div>\n }\n </div>\n </mat-expansion-panel>\n }\n </div>\n }\n </div> \n</div>", styles: ["@charset \"UTF-8\";.active-objects-wrapper{position:absolute;top:15em;left:1em;z-index:1000;cursor:grab;box-shadow:0 2px 10px #0000001a;background:color-mix(in srgb,#000 60%,transparent);width:fit-content;max-width:295px;transition:width .3s ease;border-radius:5px 5px 0 0}.active-objects-wrapper.collapsed{width:70px;max-width:150px}.active-objects-wrapper.cdk-drag-dragging{opacity:.8;cursor:grab;z-index:1001}mat-expansion-panel ::ng-deep .mat-expansion-panel-header .panel-title{display:block;overflow:visible;text-overflow:clip;white-space:normal;max-width:220px;margin-right:10px;line-height:1.3;word-break:break-word}.item{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-radius:4px;background:color-mix(in srgb,#000 60%,transparent)!important;transition:all .2s ease;font-size:14px;color:#fff;min-height:40px;cursor:default}.item .item-text{flex:1;min-width:0;display:flex;flex-direction:column;overflow:hidden}.item .item-id{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-bottom:2px}.item .item-area{font-size:12px;color:#ccc;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item mat-icon{cursor:pointer;color:#f44336;font-size:18px;width:18px;height:18px;flex-shrink:0;margin-left:8px;transition:color .2s ease,background .2s ease}.item mat-icon:hover{color:#d32f2f}.highlight-active{color:#4caf50!important;text-shadow:0 0 6px #4caf50;transform:scale(1.1);transition:all .2s ease}.drag-handle-active-objects{display:flex;align-items:center;justify-content:space-between;background:color-mix(in srgb,#000 0%,transparent);padding:4px 8px;cursor:grab}.drag-handle-active-objects .zoom-icon{color:#fff;font-size:18px;width:18px;height:18px}.drag-handle-active-objects .toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:18px!important;width:18px!important;height:18px!important;display:flex;align-items:center;justify-content:center;border-radius:4px;padding:2px;flex-shrink:0}.drag-handle-active-objects .toggle-icon:hover{color:#fff;background:#ffffff26}.active-objects-container{display:flex;flex-direction:column;align-items:center;width:100%;gap:10px;transition:all .3s ease;cursor:default;box-sizing:border-box}.active-objects-container .panel-header{display:flex;align-items:center;justify-content:space-between;width:100%;padding:5px;cursor:default}.active-objects-container .panel-header h4{margin:0;padding:5px;background:transparent;font-weight:600;color:#fff;flex:1;font-size:16px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease;white-space:nowrap;text-align:center}.active-objects-container .collapsed-title{color:#fff;font-weight:600;font-size:12px;padding:8px 4px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease;white-space:nowrap;text-align:center}.active-objects-container .collapsed-title:hover{color:#1976d2}.active-objects-content{display:block;max-height:278px;overflow:auto}.active-objects-content::-webkit-scrollbar{width:12px}.active-objects-content::-webkit-scrollbar-track{background:#757474;border-radius:8px}.active-objects-content::-webkit-scrollbar-thumb{background:#1a1c1f;border-radius:8px;border:2px solid #2a2c30}.active-objects-content::-webkit-scrollbar-thumb:hover{background:#0f1012}.active-objects-content::-webkit-scrollbar-button{width:12px;height:16px;background:#2a2c30;border:1px solid #1a1c1f}.active-objects-content::-webkit-scrollbar-button:vertical:decrement{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 4l-4 4h8z'/%3E%3C/svg%3E\") no-repeat center;border-radius:8px 8px 0 0}.active-objects-content::-webkit-scrollbar-button:vertical:decrement:hover{background-color:#1a1c1f}.active-objects-content::-webkit-scrollbar-button:vertical:increment{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 8l4-4H2z'/%3E%3C/svg%3E\") no-repeat center;border-radius:0 0 8px 8px}.active-objects-content::-webkit-scrollbar-button:vertical:increment:hover{background-color:#1a1c1f}.active-objects-content .zoom-icon{color:#4caf50!important;border-radius:50%;padding:6px;margin:4px;cursor:pointer;transition:all .3s ease;font-size:20px;width:20px;height:20px}.active-objects-content .zoom-icon:hover{background:#4caf5033!important}mat-expansion-panel{border-radius:0!important;box-shadow:none!important}mat-expansion-panel:last-child{border-bottom:none}mat-expansion-panel ::ng-deep .mat-expansion-panel-header{padding:0 16px;font-weight:500}mat-expansion-panel ::ng-deep .mat-expansion-panel-header .mat-content{display:flex;justify-content:space-between;align-items:center;color:#fff}mat-expansion-panel ::ng-deep .mat-expansion-panel-body{padding:0}.item-list{display:flex;flex-direction:column;gap:4px;padding:8px;max-height:300px;overflow-y:auto}.item-list::-webkit-scrollbar{width:6px}.item-list::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.item-list::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px}.item-list::-webkit-scrollbar-thumb:hover{background:#a8a8a8}@media (max-width: 768px){.active-objects-wrapper{right:.5em;top:8em;max-width:280px;width:280px}.item{font-size:13px;padding:6px 10px}}@media (max-width: 480px){.active-objects-wrapper{right:.5em;left:.5em;max-width:calc(100vw - 1em);width:auto}.item-list{max-height:200px}}\n"] }]
|
|
1866
2225
|
}], ctorParameters: () => [], propDecorators: { settings: [{
|
|
1867
2226
|
type: Input,
|
|
1868
2227
|
args: [{ required: true }]
|
|
1869
2228
|
}] } });
|
|
1870
2229
|
|
|
2230
|
+
class SearchProviderService {
|
|
2231
|
+
_cancelSearch = new Subject();
|
|
2232
|
+
maxSearchResults = 8;
|
|
2233
|
+
searchProviders = [];
|
|
2234
|
+
search(searchString) {
|
|
2235
|
+
this._cancelSearch.next('');
|
|
2236
|
+
let combinedSearch = new Observable();
|
|
2237
|
+
this.searchProviders.forEach(searchProvider => {
|
|
2238
|
+
const search = searchProvider
|
|
2239
|
+
.search(searchString, this.maxSearchResults)
|
|
2240
|
+
.pipe(takeUntil(this._cancelSearch.asObservable()))
|
|
2241
|
+
.pipe(take(this.maxSearchResults));
|
|
2242
|
+
combinedSearch = combinedSearch ? combinedSearch.pipe(mergeWith(search)) : search;
|
|
2243
|
+
});
|
|
2244
|
+
return combinedSearch;
|
|
2245
|
+
}
|
|
2246
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: SearchProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2247
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: SearchProviderService, providedIn: 'root' });
|
|
2248
|
+
}
|
|
2249
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: SearchProviderService, decorators: [{
|
|
2250
|
+
type: Injectable,
|
|
2251
|
+
args: [{
|
|
2252
|
+
providedIn: 'root'
|
|
2253
|
+
}]
|
|
2254
|
+
}] });
|
|
2255
|
+
|
|
2256
|
+
class WFSSearchService {
|
|
2257
|
+
name = 'WFS Search';
|
|
2258
|
+
_http = inject(HttpClient);
|
|
2259
|
+
wfsFormat = new WFS();
|
|
2260
|
+
wktFormat = new WKT();
|
|
2261
|
+
_searcheableLayers = [];
|
|
2262
|
+
geoJsonFormat = new GeoJSON({ dataProjection: 'EPSG:25832', featureProjection: 'EPSG:25832' });
|
|
2263
|
+
_serializer = new XMLSerializer();
|
|
2264
|
+
search(searchValue, maxCount = 5) {
|
|
2265
|
+
const wftSearches = [];
|
|
2266
|
+
this._searcheableLayers.flatMap(layer => {
|
|
2267
|
+
const filter = like(layer.searchField, `*${searchValue}*`, '*', '?', '/', false);
|
|
2268
|
+
var searchFeature = this.wfsFormat.writeGetFeature({
|
|
2269
|
+
featureTypes: [layer.featureType.includes(':') ? layer.featureType.split(':')[1] : ''],
|
|
2270
|
+
outputFormat: 'application/json',
|
|
2271
|
+
featureNS: '',
|
|
2272
|
+
featurePrefix: '',
|
|
2273
|
+
srsName: 'EPSG:25832',
|
|
2274
|
+
maxFeatures: maxCount,
|
|
2275
|
+
filter
|
|
2276
|
+
});
|
|
2277
|
+
wftSearches.push(this._http.post(layer.baseUrl.replace('wms', 'wfs'), this._serializer.serializeToString(searchFeature), { headers: { 'Content-Type': 'text/xml' }, responseType: 'json' }).pipe(map$1(r => {
|
|
2278
|
+
const result = {
|
|
2279
|
+
title: layer.name,
|
|
2280
|
+
total: r.numberMatched ?? 0,
|
|
2281
|
+
items: r.features.map(f => ({ header: f.properties[layer.headerField], wkt: this._formatWKT(f) }))
|
|
2282
|
+
};
|
|
2283
|
+
return result;
|
|
2284
|
+
})));
|
|
2285
|
+
});
|
|
2286
|
+
return combineLatest(wftSearches);
|
|
2287
|
+
}
|
|
2288
|
+
onSelect(searchResult, targetSrs) {
|
|
2289
|
+
// TO DO : add logic for when an item is selected (right now, the map search component does a highlight on it)
|
|
2290
|
+
}
|
|
2291
|
+
onClear() {
|
|
2292
|
+
// TO DO : add logic for when the results list is cleared
|
|
2293
|
+
}
|
|
2294
|
+
setSearcheableLayers(layers) {
|
|
2295
|
+
console.log('setSearcheableLayers', layers);
|
|
2296
|
+
this._searcheableLayers = layers;
|
|
2297
|
+
}
|
|
2298
|
+
_formatWKT(feature) {
|
|
2299
|
+
const olFeature = this.geoJsonFormat.readFeature(feature);
|
|
2300
|
+
return this.wktFormat.writeFeature(olFeature);
|
|
2301
|
+
}
|
|
2302
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: WFSSearchService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2303
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: WFSSearchService, providedIn: 'root' });
|
|
2304
|
+
}
|
|
2305
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: WFSSearchService, decorators: [{
|
|
2306
|
+
type: Injectable,
|
|
2307
|
+
args: [{
|
|
2308
|
+
providedIn: 'root'
|
|
2309
|
+
}]
|
|
2310
|
+
}] });
|
|
2311
|
+
|
|
1871
2312
|
class MapSearchComponent {
|
|
1872
2313
|
searchAddress = '';
|
|
1873
|
-
|
|
2314
|
+
profile;
|
|
2315
|
+
// allResults = ['address1', 'address2', 'address3', 'address4'];
|
|
1874
2316
|
filteredResults = [];
|
|
1875
2317
|
collapsed = true;
|
|
1876
2318
|
dragPosition = { x: 0, y: 0 };
|
|
1877
2319
|
POSITION_STORAGE_KEY = 'mapSearchPosition';
|
|
2320
|
+
_mapFilteredLayerGroupsKeyName = 'mapFilteredLayerGroups';
|
|
2321
|
+
_highlight = inject(HighlightService);
|
|
2322
|
+
_searchSubject = new Subject();
|
|
2323
|
+
_searchService = inject(SearchProviderService);
|
|
2324
|
+
_searchProviderService = inject(SearchProviderService);
|
|
2325
|
+
_wfsSearch = inject(WFSSearchService);
|
|
2326
|
+
_layerHelperService = inject(LayerHelperService);
|
|
1878
2327
|
ngOnInit() {
|
|
2328
|
+
this._layerHelperService.activeLayersChanged
|
|
2329
|
+
.subscribe(() => this._addWFSSearchLayers());
|
|
1879
2330
|
this.filterResults();
|
|
1880
2331
|
this._loadPosition();
|
|
2332
|
+
this._addWFSSearch();
|
|
2333
|
+
this._searchSubject.pipe(debounceTime(200), distinctUntilChanged(), switchMap(value => this._searchService.search(value))).subscribe({
|
|
2334
|
+
next: result => {
|
|
2335
|
+
console.log('search results', result);
|
|
2336
|
+
this.filteredResults = result;
|
|
2337
|
+
}
|
|
2338
|
+
});
|
|
2339
|
+
}
|
|
2340
|
+
_addWFSSearch() {
|
|
2341
|
+
this._searchProviderService.searchProviders = [];
|
|
2342
|
+
this._searchProviderService.searchProviders.push(this._wfsSearch);
|
|
2343
|
+
}
|
|
2344
|
+
_addWFSSearchLayers() {
|
|
2345
|
+
if (this.profile) {
|
|
2346
|
+
const cacheValue = localStorage.getItem(`${this._mapFilteredLayerGroupsKeyName}_${this.profile.id}`);
|
|
2347
|
+
if (cacheValue) {
|
|
2348
|
+
const cachedProfileInfo = JSON.parse(cacheValue);
|
|
2349
|
+
const visibleLayerIds = cachedProfileInfo.cachedLayerGroups
|
|
2350
|
+
.flatMap(group => group.layers)
|
|
2351
|
+
.filter(layer => layer.visible)
|
|
2352
|
+
.map(layer => layer.id);
|
|
2353
|
+
const searcheableLayers = cachedProfileInfo.profile
|
|
2354
|
+
.layerGroups.flatMap(group => group.layers)
|
|
2355
|
+
.filter(layer => layer.wfsSearchable && visibleLayerIds.includes(layer.id))
|
|
2356
|
+
.map(layer => ({ featureType: layer.layers, baseUrl: layer.baseUrl, name: layer.name,
|
|
2357
|
+
headerField: layer.headerField, searchField: layer.searchField
|
|
2358
|
+
}));
|
|
2359
|
+
this._wfsSearch.setSearcheableLayers(searcheableLayers);
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
1881
2362
|
}
|
|
1882
2363
|
filterResults() {
|
|
1883
2364
|
if (!this.searchAddress) {
|
|
1884
2365
|
this.filteredResults = [];
|
|
1885
2366
|
return;
|
|
1886
2367
|
}
|
|
1887
|
-
this.
|
|
2368
|
+
this._searchSubject.next(this.searchAddress);
|
|
2369
|
+
// this._wfsSearch.search(this.searchAddress).subscribe(r => {
|
|
2370
|
+
// this.filteredResults = [r];
|
|
2371
|
+
// });
|
|
1888
2372
|
}
|
|
1889
2373
|
toggleSearch() {
|
|
1890
2374
|
this.collapsed = !this.collapsed;
|
|
@@ -1893,6 +2377,10 @@ class MapSearchComponent {
|
|
|
1893
2377
|
this.filterResults();
|
|
1894
2378
|
}
|
|
1895
2379
|
}
|
|
2380
|
+
highlight(wkt, event) {
|
|
2381
|
+
event.stopPropagation();
|
|
2382
|
+
this._highlight.highlight(wkt);
|
|
2383
|
+
}
|
|
1896
2384
|
onDragEnded(event) {
|
|
1897
2385
|
const position = event.source.getFreeDragPosition();
|
|
1898
2386
|
this.dragPosition = position;
|
|
@@ -1919,7 +2407,7 @@ class MapSearchComponent {
|
|
|
1919
2407
|
}
|
|
1920
2408
|
}
|
|
1921
2409
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: MapSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1922
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: MapSearchComponent, isStandalone: true, selector: "lib-map-search", ngImport: i0, template: "<div class=\"search-container\" \n cdkDrag \n cdkDragBoundary=\".map-container\" \n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\"\n [class.collapsed]=\"collapsed\">\n <div class=\"drag-handle\" cdkDragHandle>\n <mat-icon>search</mat-icon>\n <mat-icon class=\"toggle-icon\" (click)=\"toggleSearch()\">{{ collapsed ? 'flip_to_front' : 'remove' }}</mat-icon>\n </div>\n <div class=\"search-content\" *ngIf=\"!collapsed\">\n <mat-form-field appearance=\"outline\" class=\"search-field\">\n <mat-label>S\u00F8ge</mat-label>\n <input\n type=\"text\"\n matInput\n [(ngModel)]=\"searchAddress\"\n [matAutocomplete]=\"auto\"\n (input)=\"filterResults()\"\n />\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let result of filteredResults\" [value]=\"result\">\n {{ result }}\n </mat-option>\n </mat-autocomplete>\n </mat-form-field>\n </div>\n</div>", styles: [".search-container{position:absolute;top:8em;left:1em;z-index:1000;cursor:grab;max-width:400px;min-width:48px;width:auto}.search-container.collapsed{width:48px;min-width:68px;max-width:48px}.search-container.cdk-drag-dragging{opacity:.8;cursor:grab}.drag-handle{display:flex;align-items:center;justify-content:space-between;background:color-mix(in srgb,#000 60%,transparent);padding:4px;cursor:grab}.drag-handle mat-icon:not(.toggle-icon){color:#fff;font-size:20px;width:20px;height:20px}.search-content{display:flex;align-items:center;background:color-mix(in srgb,#000 60%,transparent);padding:5px;transition:all .3s ease;box-sizing:border-box;cursor:default}.toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:
|
|
2410
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: MapSearchComponent, isStandalone: true, selector: "lib-map-search", inputs: { profile: "profile" }, ngImport: i0, template: "<div class=\"search-container\" \n cdkDrag \n cdkDragBoundary=\".map-container\" \n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\"\n [class.collapsed]=\"collapsed\">\n <div class=\"drag-handle\" cdkDragHandle>\n <mat-icon>search</mat-icon>\n <mat-icon class=\"toggle-icon\" (click)=\"toggleSearch()\">{{ collapsed ? 'flip_to_front' : 'remove' }}</mat-icon>\n </div>\n <div class=\"search-content\" *ngIf=\"!collapsed\">\n <mat-form-field appearance=\"outline\" class=\"search-field\">\n <mat-label>S\u00F8ge</mat-label>\n <input\n type=\"text\"\n matInput\n [(ngModel)]=\"searchAddress\"\n [matAutocomplete]=\"auto\"\n (input)=\"filterResults()\"\n />\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let result of filteredResults\" [value]=\"result\" class=\"search-result-option\">\n {{ result.title }} ({{result.items.length}} af {{ result.total }})\n <div *ngFor=\"let item of result.items\" class=\"search-result-item\">\n {{item.header}} \n <mat-icon (click)=\"highlight(item.wkt, $event)\">highlight</mat-icon>\n </div>\n </mat-option>\n </mat-autocomplete>\n </mat-form-field>\n </div>\n</div>", styles: [".search-container{position:absolute;top:8em;left:1em;z-index:1000;cursor:grab;max-width:400px;min-width:48px;width:auto}.search-container.collapsed{width:48px;min-width:68px;max-width:48px}.search-container.cdk-drag-dragging{opacity:.8;cursor:grab}.drag-handle{display:flex;align-items:center;justify-content:space-between;background:color-mix(in srgb,#000 60%,transparent);padding:4px;cursor:grab;border-radius:5px 5px 0 0}.drag-handle mat-icon:not(.toggle-icon){color:#fff;font-size:20px;width:20px;height:20px}.search-content{display:flex;align-items:center;background:color-mix(in srgb,#000 60%,transparent);padding:5px;transition:all .3s ease;box-sizing:border-box;cursor:default;border-radius:0 0 5px 5px}.toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:18px!important;width:18px!important;height:18px!important;display:flex;align-items:center;justify-content:center;border-radius:4px;padding:2px;flex-shrink:0}.toggle-icon:hover{color:#fff;background:#ffffff26}.search-field{width:100%;min-width:200px;cursor:pointer;flex:1}.search-field ::ng-deep .mat-mdc-form-field-focus-overlay{background-color:transparent}.search-field ::ng-deep .mdc-notched-outline .mdc-notched-outline__leading,.search-field ::ng-deep .mdc-notched-outline .mdc-notched-outline__notch,.search-field ::ng-deep .mdc-notched-outline .mdc-notched-outline__trailing{border-color:transparent!important;border-width:1.5px!important;transition:border-color .3s ease,border-width .3s ease}.search-field:not(.mat-focused):hover ::ng-deep .mdc-notched-outline .mdc-notched-outline__leading,.search-field:not(.mat-focused):hover ::ng-deep .mdc-notched-outline .mdc-notched-outline__notch,.search-field:not(.mat-focused):hover ::ng-deep .mdc-notched-outline .mdc-notched-outline__trailing{border-color:transparent!important}.search-field ::ng-deep .mat-mdc-form-field-label{color:#fff!important;font-weight:500;font-size:15px}.search-field ::ng-deep .mat-mdc-form-field.mat-focused .mat-mdc-form-field-label{color:#2196f3!important}.search-field ::ng-deep .mat-mdc-input-element{font-size:15px;color:#fff;font-weight:400;line-height:1.5}.search-field ::ng-deep .mat-mdc-input-element::placeholder{color:#ccc;font-weight:400;opacity:.8}.search-field ::ng-deep .mdc-floating-label{padding:0 4px;left:40px!important}::ng-deep .mat-mdc-form-field.mat-form-field-animations-enabled .mdc-text-field__input{margin-left:12px;color:#fff!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item__primary-text{color:#fff!important}::ng-deep .mat-mdc-option .mat-pseudo-checkbox-minimal{color:#fff!important}::ng-deep .mat-mdc-form-field-flex{height:40px!important}::ng-deep .mat-mdc-autocomplete-panel{border-radius:12px!important;max-height:320px!important;background:color-mix(in srgb,#000 85%,transparent)!important;box-shadow:0 8px 24px #00000026!important;margin-top:8px!important;overflow:hidden!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option{min-height:30px!important;border-radius:8px!important;transition:all .2s cubic-bezier(.4,0,.2,1);position:relative;overflow:auto}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option:hover:not(.mdc-list-item--disabled){background-color:#0000004d!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item__primary-text{font-size:14px;font-weight:400;color:inherit;line-height:1.5}::ng-deep .mat-mdc-autocomplete-panel::-webkit-scrollbar{width:6px}::ng-deep .mat-mdc-autocomplete-panel::-webkit-scrollbar-track{background:#f1f1f1;border-radius:0 12px 12px 0}::ng-deep .mat-mdc-autocomplete-panel::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px;transition:background .3s ease}::ng-deep .mat-mdc-autocomplete-panel::-webkit-scrollbar-thumb:hover{background:#a8a8a8}::ng-deep .mat-mdc-text-field-wrapper{background:color-mix(in srgb,#000 60%,transparent);border-radius:8px;box-shadow:#0000004d 0 1px 4px -1px;transition:all .3s cubic-bezier(.4,0,.2,1)}::ng-deep .mat-mdc-text-field-wrapper:hover{box-shadow:0 4px 16px #00000026}::ng-deep .mat-mdc-form-field:not(.mat-form-field-disabled) .mat-mdc-floating-label.mdc-floating-label{color:#fff!important}::ng-deep .mdc-text-field{border-radius:8px!important}@media (max-width: 768px){.search-container{left:2em;top:1.5em;max-width:350px}.search-container.collapsed{width:44px;min-width:44px;max-width:44px}.search-field{min-width:180px}.toggle-icon{font-size:18px;width:18px;height:18px}}@media (max-width: 480px){.search-container{left:1.5em;right:1.5em;max-width:calc(100vw - 3em)}.search-container.collapsed{width:40px;min-width:40px;max-width:40px;right:auto}.search-field{min-width:150px}.search-field ::ng-deep .mat-mdc-input-element{font-size:14px}::ng-deep .mat-mdc-autocomplete-panel{max-height:240px!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option{min-height:48px!important;padding:10px 16px!important}.toggle-icon{font-size:16px;width:16px;height:16px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i5$2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i4$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i5$2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i4.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }] });
|
|
1923
2411
|
}
|
|
1924
2412
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: MapSearchComponent, decorators: [{
|
|
1925
2413
|
type: Component,
|
|
@@ -1932,8 +2420,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
1932
2420
|
MatOptionModule,
|
|
1933
2421
|
MatIconModule,
|
|
1934
2422
|
DragDropModule
|
|
1935
|
-
], template: "<div class=\"search-container\" \n cdkDrag \n cdkDragBoundary=\".map-container\" \n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\"\n [class.collapsed]=\"collapsed\">\n <div class=\"drag-handle\" cdkDragHandle>\n <mat-icon>search</mat-icon>\n <mat-icon class=\"toggle-icon\" (click)=\"toggleSearch()\">{{ collapsed ? 'flip_to_front' : 'remove' }}</mat-icon>\n </div>\n <div class=\"search-content\" *ngIf=\"!collapsed\">\n <mat-form-field appearance=\"outline\" class=\"search-field\">\n <mat-label>S\u00F8ge</mat-label>\n <input\n type=\"text\"\n matInput\n [(ngModel)]=\"searchAddress\"\n [matAutocomplete]=\"auto\"\n (input)=\"filterResults()\"\n />\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let result of filteredResults\" [value]=\"result\">\n {{ result }}\n </mat-option>\n </mat-autocomplete>\n </mat-form-field>\n </div>\n</div>", styles: [".search-container{position:absolute;top:8em;left:1em;z-index:1000;cursor:grab;max-width:400px;min-width:48px;width:auto}.search-container.collapsed{width:48px;min-width:68px;max-width:48px}.search-container.cdk-drag-dragging{opacity:.8;cursor:grab}.drag-handle{display:flex;align-items:center;justify-content:space-between;background:color-mix(in srgb,#000 60%,transparent);padding:4px;cursor:grab}.drag-handle mat-icon:not(.toggle-icon){color:#fff;font-size:20px;width:20px;height:20px}.search-content{display:flex;align-items:center;background:color-mix(in srgb,#000 60%,transparent);padding:5px;transition:all .3s ease;box-sizing:border-box;cursor:default}.toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:
|
|
1936
|
-
}]
|
|
2423
|
+
], template: "<div class=\"search-container\" \n cdkDrag \n cdkDragBoundary=\".map-container\" \n [cdkDragFreeDragPosition]=\"dragPosition\"\n (cdkDragEnded)=\"onDragEnded($event)\"\n [class.collapsed]=\"collapsed\">\n <div class=\"drag-handle\" cdkDragHandle>\n <mat-icon>search</mat-icon>\n <mat-icon class=\"toggle-icon\" (click)=\"toggleSearch()\">{{ collapsed ? 'flip_to_front' : 'remove' }}</mat-icon>\n </div>\n <div class=\"search-content\" *ngIf=\"!collapsed\">\n <mat-form-field appearance=\"outline\" class=\"search-field\">\n <mat-label>S\u00F8ge</mat-label>\n <input\n type=\"text\"\n matInput\n [(ngModel)]=\"searchAddress\"\n [matAutocomplete]=\"auto\"\n (input)=\"filterResults()\"\n />\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let result of filteredResults\" [value]=\"result\" class=\"search-result-option\">\n {{ result.title }} ({{result.items.length}} af {{ result.total }})\n <div *ngFor=\"let item of result.items\" class=\"search-result-item\">\n {{item.header}} \n <mat-icon (click)=\"highlight(item.wkt, $event)\">highlight</mat-icon>\n </div>\n </mat-option>\n </mat-autocomplete>\n </mat-form-field>\n </div>\n</div>", styles: [".search-container{position:absolute;top:8em;left:1em;z-index:1000;cursor:grab;max-width:400px;min-width:48px;width:auto}.search-container.collapsed{width:48px;min-width:68px;max-width:48px}.search-container.cdk-drag-dragging{opacity:.8;cursor:grab}.drag-handle{display:flex;align-items:center;justify-content:space-between;background:color-mix(in srgb,#000 60%,transparent);padding:4px;cursor:grab;border-radius:5px 5px 0 0}.drag-handle mat-icon:not(.toggle-icon){color:#fff;font-size:20px;width:20px;height:20px}.search-content{display:flex;align-items:center;background:color-mix(in srgb,#000 60%,transparent);padding:5px;transition:all .3s ease;box-sizing:border-box;cursor:default;border-radius:0 0 5px 5px}.toggle-icon{cursor:pointer;color:#fff;transition:all .2s ease;-webkit-user-select:none;user-select:none;font-size:18px!important;width:18px!important;height:18px!important;display:flex;align-items:center;justify-content:center;border-radius:4px;padding:2px;flex-shrink:0}.toggle-icon:hover{color:#fff;background:#ffffff26}.search-field{width:100%;min-width:200px;cursor:pointer;flex:1}.search-field ::ng-deep .mat-mdc-form-field-focus-overlay{background-color:transparent}.search-field ::ng-deep .mdc-notched-outline .mdc-notched-outline__leading,.search-field ::ng-deep .mdc-notched-outline .mdc-notched-outline__notch,.search-field ::ng-deep .mdc-notched-outline .mdc-notched-outline__trailing{border-color:transparent!important;border-width:1.5px!important;transition:border-color .3s ease,border-width .3s ease}.search-field:not(.mat-focused):hover ::ng-deep .mdc-notched-outline .mdc-notched-outline__leading,.search-field:not(.mat-focused):hover ::ng-deep .mdc-notched-outline .mdc-notched-outline__notch,.search-field:not(.mat-focused):hover ::ng-deep .mdc-notched-outline .mdc-notched-outline__trailing{border-color:transparent!important}.search-field ::ng-deep .mat-mdc-form-field-label{color:#fff!important;font-weight:500;font-size:15px}.search-field ::ng-deep .mat-mdc-form-field.mat-focused .mat-mdc-form-field-label{color:#2196f3!important}.search-field ::ng-deep .mat-mdc-input-element{font-size:15px;color:#fff;font-weight:400;line-height:1.5}.search-field ::ng-deep .mat-mdc-input-element::placeholder{color:#ccc;font-weight:400;opacity:.8}.search-field ::ng-deep .mdc-floating-label{padding:0 4px;left:40px!important}::ng-deep .mat-mdc-form-field.mat-form-field-animations-enabled .mdc-text-field__input{margin-left:12px;color:#fff!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item__primary-text{color:#fff!important}::ng-deep .mat-mdc-option .mat-pseudo-checkbox-minimal{color:#fff!important}::ng-deep .mat-mdc-form-field-flex{height:40px!important}::ng-deep .mat-mdc-autocomplete-panel{border-radius:12px!important;max-height:320px!important;background:color-mix(in srgb,#000 85%,transparent)!important;box-shadow:0 8px 24px #00000026!important;margin-top:8px!important;overflow:hidden!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option{min-height:30px!important;border-radius:8px!important;transition:all .2s cubic-bezier(.4,0,.2,1);position:relative;overflow:auto}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option:hover:not(.mdc-list-item--disabled){background-color:#0000004d!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item__primary-text{font-size:14px;font-weight:400;color:inherit;line-height:1.5}::ng-deep .mat-mdc-autocomplete-panel::-webkit-scrollbar{width:6px}::ng-deep .mat-mdc-autocomplete-panel::-webkit-scrollbar-track{background:#f1f1f1;border-radius:0 12px 12px 0}::ng-deep .mat-mdc-autocomplete-panel::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px;transition:background .3s ease}::ng-deep .mat-mdc-autocomplete-panel::-webkit-scrollbar-thumb:hover{background:#a8a8a8}::ng-deep .mat-mdc-text-field-wrapper{background:color-mix(in srgb,#000 60%,transparent);border-radius:8px;box-shadow:#0000004d 0 1px 4px -1px;transition:all .3s cubic-bezier(.4,0,.2,1)}::ng-deep .mat-mdc-text-field-wrapper:hover{box-shadow:0 4px 16px #00000026}::ng-deep .mat-mdc-form-field:not(.mat-form-field-disabled) .mat-mdc-floating-label.mdc-floating-label{color:#fff!important}::ng-deep .mdc-text-field{border-radius:8px!important}@media (max-width: 768px){.search-container{left:2em;top:1.5em;max-width:350px}.search-container.collapsed{width:44px;min-width:44px;max-width:44px}.search-field{min-width:180px}.toggle-icon{font-size:18px;width:18px;height:18px}}@media (max-width: 480px){.search-container{left:1.5em;right:1.5em;max-width:calc(100vw - 3em)}.search-container.collapsed{width:40px;min-width:40px;max-width:40px;right:auto}.search-field{min-width:150px}.search-field ::ng-deep .mat-mdc-input-element{font-size:14px}::ng-deep .mat-mdc-autocomplete-panel{max-height:240px!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option{min-height:48px!important;padding:10px 16px!important}.toggle-icon{font-size:16px;width:16px;height:16px}}\n"] }]
|
|
2424
|
+
}], propDecorators: { profile: [{
|
|
2425
|
+
type: Input
|
|
2426
|
+
}] } });
|
|
1937
2427
|
|
|
1938
2428
|
class LayerService {
|
|
1939
2429
|
config = inject(GISKOMPONENT_CONFIG);
|
|
@@ -1979,7 +2469,7 @@ class LegendsListComponent {
|
|
|
1979
2469
|
_legendsListIconControl;
|
|
1980
2470
|
_legendsListBody;
|
|
1981
2471
|
_legendsListBodyControl;
|
|
1982
|
-
|
|
2472
|
+
_mapFilteredLayerGroupsKeyName = 'mapFilteredLayerGroups';
|
|
1983
2473
|
_layerService = inject(LayerService);
|
|
1984
2474
|
_layerHelperService = inject(LayerHelperService);
|
|
1985
2475
|
toggleLegendsList() {
|
|
@@ -2015,7 +2505,14 @@ class LegendsListComponent {
|
|
|
2015
2505
|
if (!this.profile?.id) {
|
|
2016
2506
|
return of([]);
|
|
2017
2507
|
}
|
|
2018
|
-
const
|
|
2508
|
+
const cacheValue = localStorage.getItem(`${this._mapFilteredLayerGroupsKeyName}_${this.profile?.id}`);
|
|
2509
|
+
if (!cacheValue) {
|
|
2510
|
+
return of([]);
|
|
2511
|
+
}
|
|
2512
|
+
const layerIdsCachedToDisplay = JSON.parse(cacheValue).cachedLayerGroups
|
|
2513
|
+
.flatMap((lg) => lg.layers)
|
|
2514
|
+
.filter((l) => l.visible)
|
|
2515
|
+
.map((l) => l.id);
|
|
2019
2516
|
if (!layerIdsCachedToDisplay) {
|
|
2020
2517
|
return of([]);
|
|
2021
2518
|
}
|
|
@@ -2053,12 +2550,12 @@ class LegendsListComponent {
|
|
|
2053
2550
|
})));
|
|
2054
2551
|
}
|
|
2055
2552
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LegendsListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2056
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: LegendsListComponent, isStandalone: true, selector: "lib-legends-list", inputs: { map: "map", profile: "profile" }, viewQueries: [{ propertyName: "contentIcon", first: true, predicate: ["legendsListIcon"], descendants: true }, { propertyName: "contentBody", first: true, predicate: ["legendsListBody"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #legendsListIcon class=\"ol-unselectable ol-control legends-list-icon\">\n <mat-icon (click)=\"toggleLegendsList()\">area_chart</mat-icon>\n</div>\n<div #legendsListBody [class.display-none]=\"!showList\" class=\"legends-list-body-wrapper\" cdkDrag cdkDragBoundary=\".map-container\">\n <div class=\"drag-handle-selector\" cdkDragHandle>\n <mat-icon>
|
|
2553
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: LegendsListComponent, isStandalone: true, selector: "lib-legends-list", inputs: { map: "map", profile: "profile" }, viewQueries: [{ propertyName: "contentIcon", first: true, predicate: ["legendsListIcon"], descendants: true }, { propertyName: "contentBody", first: true, predicate: ["legendsListBody"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #legendsListIcon class=\"ol-unselectable ol-control legends-list-icon\">\n <mat-icon (click)=\"toggleLegendsList()\">area_chart</mat-icon>\n</div>\n<div #legendsListBody [class.display-none]=\"!showList\" class=\"legends-list-body-wrapper\" cdkDrag cdkDragBoundary=\".map-container\">\n <div class=\"drag-handle-selector\" cdkDragHandle>\n <div class=\"drag-handle-content\">\n <div class=\"drag-handle-icons\">\n <mat-icon class=\"drag-indicator-right\">open_with</mat-icon>\n <mat-icon class=\"minimize-button\" (click)=\"toggleLegendsList()\">minimize</mat-icon>\n </div>\n </div>\n </div>\n <div class=\"ol-unselectable ol-control legends-list-body\">\n <div class=\"item-list\">\n @for (layer of filteredLayersDetailed; track layer.id; let iIndex = $index) {\n @if (layer.imageUrl) {\n <mat-expansion-panel expanded=\"true\"> \n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"item\" ><span>{{ layer.name }}</span></div>\n </mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"legend\">\n <span><img [src]=\"layer.imageUrl\" class=\"legend-thumbnail\"/></span>\n </div>\n </mat-expansion-panel>\n }\n }\n </div>\n </div>\n</div>", styles: ["::ng-deep .legends-list-icon{position:absolute;left:auto;right:1em;bottom:1em;z-index:1000}::ng-deep .legends-list-icon mat-icon{display:flex;justify-content:center;align-items:center;cursor:pointer;transition:all .3s ease;outline:none;border:0;height:40px;border-radius:5px;width:40px;background:color-mix(in srgb,#000 60%,transparent);box-shadow:#0000004d 0 1px 4px -1px;font-size:2em;color:#fff}::ng-deep .legends-list-icon mat-icon:hover{box-shadow:0 4px 12px #0003;color:#fff}.display-none{display:none!important}::ng-deep .legends-list-body{position:relative;left:auto;right:auto;bottom:auto;z-index:auto;background:color-mix(in srgb,#000 60%,transparent);box-shadow:0 4px 20px #00000026;width:250px;max-height:700px;min-height:80px;overflow:hidden;display:flex;flex-direction:column}@media (max-width: 1024px){::ng-deep .legends-list-body{width:240px;max-height:550px;min-height:70px}}@media (max-width: 768px){::ng-deep .legends-list-body{width:100%;max-height:60vh;max-height:calc(var(--vh, 1vh) * 60);min-height:100px}}@media (max-width: 480px){::ng-deep .legends-list-body{max-height:70vh;max-height:calc(var(--vh, 1vh) * 70);min-height:90px}}.legends-list-body-wrapper{position:absolute;left:auto;right:35em;bottom:.2em;z-index:1000;cursor:grab;width:fit-content;max-width:250px}@media (max-width: 1024px){.legends-list-body-wrapper{right:32em;bottom:.5em;max-width:240px}}@media (max-width: 768px){.legends-list-body-wrapper{position:fixed;right:3em;left:1em;bottom:5em;width:calc(100% - 7em);max-width:100%}}@media (max-width: 480px){.legends-list-body-wrapper{bottom:4em}}.legends-list-body-wrapper.cdk-drag-dragging{opacity:.8;cursor:grabbing;z-index:1001}.legends-list-body-wrapper .ol-control{border-radius:0}.drag-handle-selector{display:flex;align-items:center;justify-content:flex-end;border-radius:5px 5px 0 0;padding:5px;cursor:grab;background:#000}.drag-handle-content{display:flex;align-items:center;justify-content:flex-end;width:100%}.drag-handle-icons{display:flex;align-items:center;gap:16px}.drag-indicator-right{color:#fff;font-size:18px;width:18px;height:18px;cursor:grab;transition:all .2s ease}.minimize-button{color:#fff;font-size:18px;width:18px;height:18px;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;transform:translateY(-30%)}.minimize-button:hover{color:#fff;background:#ffffff26}.drag-handle-selector{display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,#000 60%,transparent);border-radius:5px 5px 0 0;padding:5px;cursor:grab;box-shadow:0 -2px 8px #0003;position:sticky;top:0;z-index:1}@media (max-width: 768px){.drag-handle-selector{padding:8px}}.drag-handle-selector mat-icon{color:#fff;font-size:18px;width:18px;height:18px}@media (max-width: 768px){.drag-handle-selector mat-icon{font-size:20px;width:20px;height:20px}}::ng-deep .legends-list-body .item-list{flex:1 1 auto;overflow-y:auto;padding:4px;min-height:0;background:#000}@media (max-width: 768px){::ng-deep .legends-list-body .item-list{padding:6px}}::ng-deep .legends-list-body .item-list mat-expansion-panel .mat-expansion-panel-header{padding:0 8px;height:40px!important;min-height:40px!important}::ng-deep .legends-list-body .item-list mat-expansion-panel .mat-expansion-panel-header .mat-content{display:flex;align-items:center}::ng-deep .legends-list-body .item-list mat-expansion-panel .mat-expansion-panel-header .mat-expansion-panel-header-title{font-weight:600;color:#fff;font-size:17px}::ng-deep .legends-list-body .item-list .mat-expansion-panel-body{padding:4px 8px 0!important}::ng-deep .legends-list-body .item-list .legend{overflow:hidden;box-shadow:0 -2px 2px #4868b20a,0 2px 2px #6a6f7517,0 1px 2px #4868b214}::ng-deep .legends-list-body .item-list .legend span{color:#fff}::ng-deep .legends-list-body .item-list .item{display:flex;align-items:center;gap:4px;padding:6px 0;background:transparent;transition:all .2s ease;color:#bdc1c3cc;cursor:grab;min-width:0;flex:1}::ng-deep .legends-list-body .item-list .item span{word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;white-space:normal;flex:1;min-width:0}@media (max-width: 768px){::ng-deep .legends-list-body .item-list .item{padding:8px 12px;gap:6px}}@media (max-width: 768px){::ng-deep .legends-list-body .item-list mat-expansion-panel{margin-bottom:6px}::ng-deep .legends-list-body .item-list mat-expansion-panel .mat-expansion-panel-header{padding:0 6px;height:18px!important;min-height:18px!important}::ng-deep .legends-list-body .item-list .legend{padding:6px}::ng-deep .legends-list-body .item-list .legend-thumbnail{max-width:100%;height:auto;max-height:120px}}.legend-thumbnail{max-width:150px;max-height:150px;width:auto;height:auto;border:1px solid #dee2e6;border-radius:4px;padding:4px}@media (max-width: 768px){.legend-thumbnail{max-width:100%;max-height:120px;padding:3px}}::ng-deep .legends-list-body .item-list::-webkit-scrollbar{width:12px}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-track{background:#757474;border-radius:8px}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-thumb{background:#1a1c1f;border-radius:8px;border:2px solid #2a2c30}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-thumb:hover{background:#0f1012}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-button{width:12px;height:16px;background:#2a2c30;border:1px solid #1a1c1f}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-button:vertical:decrement{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 4l-4 4h8z'/%3E%3C/svg%3E\") no-repeat center;border-radius:8px 8px 0 0}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-button:vertical:decrement:hover{background-color:#1a1c1f}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-button:vertical:increment{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 8l4-4H2z'/%3E%3C/svg%3E\") no-repeat center;border-radius:0 0 8px 8px}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-button:vertical:increment:hover{background-color:#1a1c1f}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i4.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i5.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i5.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i5.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatInputModule }] });
|
|
2057
2554
|
}
|
|
2058
2555
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LegendsListComponent, decorators: [{
|
|
2059
2556
|
type: Component,
|
|
2060
2557
|
args: [{ selector: 'lib-legends-list', imports: [MatFormFieldModule, CommonModule, MatIconModule, FormsModule, DragDropModule,
|
|
2061
|
-
MatExpansionModule, MatInputModule], template: "<div #legendsListIcon class=\"ol-unselectable ol-control legends-list-icon\">\n <mat-icon (click)=\"toggleLegendsList()\">area_chart</mat-icon>\n</div>\n<div #legendsListBody [class.display-none]=\"!showList\" class=\"legends-list-body-wrapper\" cdkDrag cdkDragBoundary=\".map-container\">\n <div class=\"drag-handle-selector\" cdkDragHandle>\n <mat-icon>
|
|
2558
|
+
MatExpansionModule, MatInputModule], template: "<div #legendsListIcon class=\"ol-unselectable ol-control legends-list-icon\">\n <mat-icon (click)=\"toggleLegendsList()\">area_chart</mat-icon>\n</div>\n<div #legendsListBody [class.display-none]=\"!showList\" class=\"legends-list-body-wrapper\" cdkDrag cdkDragBoundary=\".map-container\">\n <div class=\"drag-handle-selector\" cdkDragHandle>\n <div class=\"drag-handle-content\">\n <div class=\"drag-handle-icons\">\n <mat-icon class=\"drag-indicator-right\">open_with</mat-icon>\n <mat-icon class=\"minimize-button\" (click)=\"toggleLegendsList()\">minimize</mat-icon>\n </div>\n </div>\n </div>\n <div class=\"ol-unselectable ol-control legends-list-body\">\n <div class=\"item-list\">\n @for (layer of filteredLayersDetailed; track layer.id; let iIndex = $index) {\n @if (layer.imageUrl) {\n <mat-expansion-panel expanded=\"true\"> \n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"item\" ><span>{{ layer.name }}</span></div>\n </mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"legend\">\n <span><img [src]=\"layer.imageUrl\" class=\"legend-thumbnail\"/></span>\n </div>\n </mat-expansion-panel>\n }\n }\n </div>\n </div>\n</div>", styles: ["::ng-deep .legends-list-icon{position:absolute;left:auto;right:1em;bottom:1em;z-index:1000}::ng-deep .legends-list-icon mat-icon{display:flex;justify-content:center;align-items:center;cursor:pointer;transition:all .3s ease;outline:none;border:0;height:40px;border-radius:5px;width:40px;background:color-mix(in srgb,#000 60%,transparent);box-shadow:#0000004d 0 1px 4px -1px;font-size:2em;color:#fff}::ng-deep .legends-list-icon mat-icon:hover{box-shadow:0 4px 12px #0003;color:#fff}.display-none{display:none!important}::ng-deep .legends-list-body{position:relative;left:auto;right:auto;bottom:auto;z-index:auto;background:color-mix(in srgb,#000 60%,transparent);box-shadow:0 4px 20px #00000026;width:250px;max-height:700px;min-height:80px;overflow:hidden;display:flex;flex-direction:column}@media (max-width: 1024px){::ng-deep .legends-list-body{width:240px;max-height:550px;min-height:70px}}@media (max-width: 768px){::ng-deep .legends-list-body{width:100%;max-height:60vh;max-height:calc(var(--vh, 1vh) * 60);min-height:100px}}@media (max-width: 480px){::ng-deep .legends-list-body{max-height:70vh;max-height:calc(var(--vh, 1vh) * 70);min-height:90px}}.legends-list-body-wrapper{position:absolute;left:auto;right:35em;bottom:.2em;z-index:1000;cursor:grab;width:fit-content;max-width:250px}@media (max-width: 1024px){.legends-list-body-wrapper{right:32em;bottom:.5em;max-width:240px}}@media (max-width: 768px){.legends-list-body-wrapper{position:fixed;right:3em;left:1em;bottom:5em;width:calc(100% - 7em);max-width:100%}}@media (max-width: 480px){.legends-list-body-wrapper{bottom:4em}}.legends-list-body-wrapper.cdk-drag-dragging{opacity:.8;cursor:grabbing;z-index:1001}.legends-list-body-wrapper .ol-control{border-radius:0}.drag-handle-selector{display:flex;align-items:center;justify-content:flex-end;border-radius:5px 5px 0 0;padding:5px;cursor:grab;background:#000}.drag-handle-content{display:flex;align-items:center;justify-content:flex-end;width:100%}.drag-handle-icons{display:flex;align-items:center;gap:16px}.drag-indicator-right{color:#fff;font-size:18px;width:18px;height:18px;cursor:grab;transition:all .2s ease}.minimize-button{color:#fff;font-size:18px;width:18px;height:18px;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;transform:translateY(-30%)}.minimize-button:hover{color:#fff;background:#ffffff26}.drag-handle-selector{display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,#000 60%,transparent);border-radius:5px 5px 0 0;padding:5px;cursor:grab;box-shadow:0 -2px 8px #0003;position:sticky;top:0;z-index:1}@media (max-width: 768px){.drag-handle-selector{padding:8px}}.drag-handle-selector mat-icon{color:#fff;font-size:18px;width:18px;height:18px}@media (max-width: 768px){.drag-handle-selector mat-icon{font-size:20px;width:20px;height:20px}}::ng-deep .legends-list-body .item-list{flex:1 1 auto;overflow-y:auto;padding:4px;min-height:0;background:#000}@media (max-width: 768px){::ng-deep .legends-list-body .item-list{padding:6px}}::ng-deep .legends-list-body .item-list mat-expansion-panel .mat-expansion-panel-header{padding:0 8px;height:40px!important;min-height:40px!important}::ng-deep .legends-list-body .item-list mat-expansion-panel .mat-expansion-panel-header .mat-content{display:flex;align-items:center}::ng-deep .legends-list-body .item-list mat-expansion-panel .mat-expansion-panel-header .mat-expansion-panel-header-title{font-weight:600;color:#fff;font-size:17px}::ng-deep .legends-list-body .item-list .mat-expansion-panel-body{padding:4px 8px 0!important}::ng-deep .legends-list-body .item-list .legend{overflow:hidden;box-shadow:0 -2px 2px #4868b20a,0 2px 2px #6a6f7517,0 1px 2px #4868b214}::ng-deep .legends-list-body .item-list .legend span{color:#fff}::ng-deep .legends-list-body .item-list .item{display:flex;align-items:center;gap:4px;padding:6px 0;background:transparent;transition:all .2s ease;color:#bdc1c3cc;cursor:grab;min-width:0;flex:1}::ng-deep .legends-list-body .item-list .item span{word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;white-space:normal;flex:1;min-width:0}@media (max-width: 768px){::ng-deep .legends-list-body .item-list .item{padding:8px 12px;gap:6px}}@media (max-width: 768px){::ng-deep .legends-list-body .item-list mat-expansion-panel{margin-bottom:6px}::ng-deep .legends-list-body .item-list mat-expansion-panel .mat-expansion-panel-header{padding:0 6px;height:18px!important;min-height:18px!important}::ng-deep .legends-list-body .item-list .legend{padding:6px}::ng-deep .legends-list-body .item-list .legend-thumbnail{max-width:100%;height:auto;max-height:120px}}.legend-thumbnail{max-width:150px;max-height:150px;width:auto;height:auto;border:1px solid #dee2e6;border-radius:4px;padding:4px}@media (max-width: 768px){.legend-thumbnail{max-width:100%;max-height:120px;padding:3px}}::ng-deep .legends-list-body .item-list::-webkit-scrollbar{width:12px}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-track{background:#757474;border-radius:8px}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-thumb{background:#1a1c1f;border-radius:8px;border:2px solid #2a2c30}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-thumb:hover{background:#0f1012}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-button{width:12px;height:16px;background:#2a2c30;border:1px solid #1a1c1f}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-button:vertical:decrement{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 4l-4 4h8z'/%3E%3C/svg%3E\") no-repeat center;border-radius:8px 8px 0 0}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-button:vertical:decrement:hover{background-color:#1a1c1f}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-button:vertical:increment{background:#2a2c30 url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 8l4-4H2z'/%3E%3C/svg%3E\") no-repeat center;border-radius:0 0 8px 8px}::ng-deep .legends-list-body .item-list::-webkit-scrollbar-button:vertical:increment:hover{background-color:#1a1c1f}\n"] }]
|
|
2062
2559
|
}], propDecorators: { contentIcon: [{
|
|
2063
2560
|
type: ViewChild,
|
|
2064
2561
|
args: ['legendsListIcon', { static: false }]
|
|
@@ -2084,19 +2581,45 @@ class FeatureLoaderService {
|
|
|
2084
2581
|
return;
|
|
2085
2582
|
}
|
|
2086
2583
|
const profile = this._current.profile;
|
|
2584
|
+
if (!settings || !settings.geometryTypeSettings)
|
|
2585
|
+
return;
|
|
2087
2586
|
const allTheFeatures = settings.geometryTypeSettings.filter(gt => gt.features).map(gt => {
|
|
2088
2587
|
const rawFeatures = this.fomatter.readFeatures(gt.features);
|
|
2089
2588
|
rawFeatures.forEach(f => {
|
|
2090
2589
|
this._featureHelper.setId(f);
|
|
2091
2590
|
this._featureHelper.setTypeId(f, gt.typeId);
|
|
2591
|
+
if (gt.disableEditFeatures) {
|
|
2592
|
+
this._featureHelper.lock(f);
|
|
2593
|
+
}
|
|
2092
2594
|
f.set('STYLENAME', gt.style);
|
|
2595
|
+
if (gt.showLabelFromProperty) {
|
|
2596
|
+
f.set('showlabelfrom', gt.showLabelFromProperty);
|
|
2597
|
+
}
|
|
2093
2598
|
});
|
|
2094
2599
|
return rawFeatures;
|
|
2095
2600
|
}).flatMap(f => f);
|
|
2096
2601
|
const getAllStyles$ = allTheFeatures.map(f => this._settingsHelper.getStyle(f.get('STYLENAME'), profile?.styleRepositoryWorkspace, profile?.styleRepositoryGeoserver, f.getGeometry().getType()));
|
|
2097
2602
|
combineLatest(getAllStyles$).subscribe({
|
|
2098
2603
|
next: styles => {
|
|
2099
|
-
styles.forEach((s, i) =>
|
|
2604
|
+
styles.forEach((s, i) => {
|
|
2605
|
+
const feature = allTheFeatures[i];
|
|
2606
|
+
if (feature.get('showlabelfrom')) {
|
|
2607
|
+
const styles = Array.isArray(s) ? s : [s];
|
|
2608
|
+
const textStyle = new Text({
|
|
2609
|
+
font: '14px Calibri,sans-serif',
|
|
2610
|
+
fill: new Fill({ color: '#000' }),
|
|
2611
|
+
stroke: new Stroke({ color: '#fff', width: 3 }),
|
|
2612
|
+
textAlign: 'center',
|
|
2613
|
+
text: feature.get(feature.get('showlabelfrom'))
|
|
2614
|
+
});
|
|
2615
|
+
const styleText = new Style({ text: textStyle });
|
|
2616
|
+
styles.push(styleText);
|
|
2617
|
+
feature.setStyle(styles);
|
|
2618
|
+
}
|
|
2619
|
+
else {
|
|
2620
|
+
feature.setStyle(s);
|
|
2621
|
+
}
|
|
2622
|
+
});
|
|
2100
2623
|
this._drawHelperService.setFeatures(allTheFeatures);
|
|
2101
2624
|
this._zoom.zoomToFeatures(allTheFeatures);
|
|
2102
2625
|
this._undoRedo.init();
|
|
@@ -2139,10 +2662,13 @@ class GisKomponentComponent {
|
|
|
2139
2662
|
profiles = [];
|
|
2140
2663
|
selectedProfile;
|
|
2141
2664
|
profileShowToolbox = false;
|
|
2142
|
-
_highlightService = inject(
|
|
2665
|
+
_highlightService = inject(HighlightService);
|
|
2143
2666
|
_currentItems = inject(CurrentItemsService);
|
|
2144
2667
|
layers = [];
|
|
2145
|
-
mousePositionCtrl = new ol_control_mouse({
|
|
2668
|
+
mousePositionCtrl = new ol_control_mouse({
|
|
2669
|
+
projection: 'EPSG:25832',
|
|
2670
|
+
coordinateFormat: createStringXY(2)
|
|
2671
|
+
});
|
|
2146
2672
|
onMoveEndCheckZoomFunction = () => { };
|
|
2147
2673
|
currentZoomLevel = 0;
|
|
2148
2674
|
scaleCtrl = new ol_control_scale({
|
|
@@ -2173,16 +2699,17 @@ class GisKomponentComponent {
|
|
|
2173
2699
|
layers: lg.layers
|
|
2174
2700
|
.filter(layer => layer.activeInSelector)
|
|
2175
2701
|
.sort((a, b) => a.sortOrder - b.sortOrder)
|
|
2176
|
-
.map((l, index) => this._mapLayer(l, capabilityObject, 'EPSG:25832', lg.id, index)) // for now, we default to EPSG:25832.
|
|
2702
|
+
.map((l, index) => this._mapLayer(l, capabilityObject, 'EPSG:25832', lg.id, index)), // for now, we default to EPSG:25832.
|
|
2703
|
+
properties: { id: lg.id }
|
|
2177
2704
|
}))
|
|
2178
2705
|
];
|
|
2179
2706
|
this.map.setLayers(layers);
|
|
2180
|
-
this.map.addLayer(this._highlightService.highlightLayer);
|
|
2181
2707
|
if (this.settings) {
|
|
2182
2708
|
this._featureLoader.loadFeaturesSettings(this.settings);
|
|
2183
2709
|
}
|
|
2184
2710
|
this._currentItems.map = this.map;
|
|
2185
2711
|
this._layerHelper.applyCachedLayersToDisplayInMap(this.map, profile.id);
|
|
2712
|
+
this.map.addLayer(this._highlightService.highlightLayer);
|
|
2186
2713
|
}
|
|
2187
2714
|
});
|
|
2188
2715
|
const toolbarControl = new Control({
|
|
@@ -2206,7 +2733,6 @@ class GisKomponentComponent {
|
|
|
2206
2733
|
this._checkZoom(this.map);
|
|
2207
2734
|
};
|
|
2208
2735
|
this.map.on('moveend', this.onMoveEndCheckZoomFunction);
|
|
2209
|
-
this._currentItems.map = this.map;
|
|
2210
2736
|
}
|
|
2211
2737
|
});
|
|
2212
2738
|
}
|
|
@@ -2327,6 +2853,24 @@ class GisKomponentComponent {
|
|
|
2327
2853
|
target: 'map',
|
|
2328
2854
|
});
|
|
2329
2855
|
this.map.addControl(new Rotate({ autoHide: false }));
|
|
2856
|
+
this._addRotateControl();
|
|
2857
|
+
}
|
|
2858
|
+
// Added custom north-arrow with a compass one
|
|
2859
|
+
_addRotateControl() {
|
|
2860
|
+
const iconElement = document.createElement('span');
|
|
2861
|
+
iconElement.innerHTML = `
|
|
2862
|
+
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2863
|
+
<path d="M12 3 L16 10 L12 8 L8 10 Z" fill="currentColor"/>
|
|
2864
|
+
<path d="M12 21 L8 14 L12 16 L16 14 Z" fill="currentColor"/>
|
|
2865
|
+
<circle cx="12" cy="12" r="1.5" fill="currentColor"/>
|
|
2866
|
+
</svg>
|
|
2867
|
+
`;
|
|
2868
|
+
const rotateControl = new Rotate({
|
|
2869
|
+
label: iconElement,
|
|
2870
|
+
tipLabel: 'Reset to north',
|
|
2871
|
+
autoHide: false
|
|
2872
|
+
});
|
|
2873
|
+
this.map.addControl(rotateControl);
|
|
2330
2874
|
}
|
|
2331
2875
|
toggleShowConflicts() {
|
|
2332
2876
|
this.showConflicts = !this.showConflicts;
|
|
@@ -2344,11 +2888,11 @@ class GisKomponentComponent {
|
|
|
2344
2888
|
this.activeObjectsCollapsed = !this.activeObjectsCollapsed;
|
|
2345
2889
|
}
|
|
2346
2890
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: GisKomponentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2347
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: GisKomponentComponent, isStandalone: true, selector: "gis-komponent", inputs: { showToolbox: "showToolbox", showActiveObjects: "showActiveObjects", showLegendList: "showLegendList", showMapSearch: "showMapSearch", identifier: "identifier", settings: "settings" }, providers: [LayerHelperService], viewQueries: [{ propertyName: "toolbarRef", first: true, predicate: ["toolbarRef"], descendants: true, static: true }, { propertyName: "activeObjectsRef", first: true, predicate: ["activeObjectsRef"], descendants: true, static: true }], ngImport: i0, template: "@if (selectedProfile && selectedProfile.showLayerSelector) {\n <lib-layer-selector [map]=\"map\" [profile]=\"selectedProfile\" [currentZoomLevel]=\"currentZoomLevel\"></lib-layer-selector>\n}\n@if (selectedProfile && selectedProfile.showLegends) {\n <lib-legends-list [map]=\"map\" [profile]=\"selectedProfile\"></lib-legends-list>\n}\n\n<!-- <span>Zoom: {{ currentZoomLevel}}</span> -->\n<div #activeObjectsRef>\n @if(showActiveObjects && activeObjectsReady && settings) {\n <activeObjects [settings]=\"settings\"></activeObjects>\n }\n</div>\n<div #toolbarRef class=\"map-toolbar-container\">\n @if(showToolbox && profileShowToolbox && settings) {\n <map-toolbox [map]=\"map\" \n [profile]=\"selectedProfile\"\n [settings]=\"settings\"\n [collapsed]=\"selectedProfile.toolbarCollapsed\" [WKTInputEnabled]=\"settings?.WKTInputEnabled\" [deleteEnabled]=\"settings?.deleteEnabled\" [showMeasureArea]=\"selectedProfile.showAreaMeasurement\" [showMeasureDistance]=\"selectedProfile.showDistanceMeasurement\"></map-toolbox>\n }\n</div>\n\n<div class=\"map-container\">\n <lib-map-search *ngIf=\"showMapSearch\"></lib-map-search>\n\n <!-- Objektvisning -->\n <!-- @if (showObjects) {\n <div class=\"object-panel\" [class.collapsed]=\"activeObjectsCollapsed\">\n <div class=\"header\" (click)=\"toggleActiveObjectsCollapsed()\">\n <span>Aktive objekter ({{activeObjects.length}})</span>\n <mat-icon>{{ activeObjectsCollapsed ? 'expand_more' : 'expand_less' }}</mat-icon>\n </div>\n @if (!activeObjectsCollapsed){\n <ul>\n <li *ngFor=\"let obj of activeObjects\">{{ obj.name }} ({{obj.size}})</li>\n </ul>\n }\n </div>\n } -->\n\n <!-- Konflikter -->\n @if (showConflicts) {\n\n <div class=\"conflict-panel\" [class.collapsed]=\"conflictsCollapsed\">\n <div class=\"header\">\n <span>Konflikter (3)</span>\n <mat-icon>{{ activeObjectsCollapsed ? 'expand_more' : 'expand_less' }}</mat-icon> -->\n </div>\n <mat-list>\n <mat-list-item>\n <span matListItemTitle>Lag #1</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #1</span>\n </mat-list-item>\n <mat-list-item>\n <span matListItemTitle>Lag #2 (svarer ikke)</span>\n </mat-list-item>\n <mat-list-item>\n <span matListItemTitle>Lag #3</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #1</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #2</span>\n </mat-list-item>\n </mat-list>\n </div>\n \n } \n\n <!-- Kort -->\n <div id=\"map\" class=\"map\"></div>\n</div>\n", styles: [":host{display:block;width:100%;height:100%;overflow:hidden}::ng-deep .lib-error-snackbar{background-color:#d32f2f;color:#fff;font-weight:500}::ng-deep .map-container{position:relative;height:81vh;width:100%;overflow:hidden}::ng-deep #map{width:100%;height:100%;position:absolute;inset:0;overflow:hidden}::ng-deep .ol-viewport{overflow:hidden!important}::ng-deep ::ng-deep .ol-logo{position:absolute;left:auto;right:3em;top:6.25em}::ng-deep ::ng-deep .ol-copyright{background-color:transparent;position:absolute;bottom:10px;width:100%;text-align:center}::ng-deep ::ng-deep .toolbar{position:absolute;top:10px;left:10px;background:#fff;padding:4px;border-radius:4px;display:flex;flex-direction:column;transition:width .3s;z-index:1000;overflow:hidden}::ng-deep ::ng-deep .toolbar.collapsed{width:40px;overflow:hidden}::ng-deep .object-panel{position:absolute;bottom:10px;left:10px;background:#fff;padding:8px;border-radius:4px;z-index:1000;max-height:calc(85vh - 20px);overflow-y:auto}::ng-deep .object-panel .header{display:flex;justify-content:space-between;padding:8px;cursor:pointer;background:#f0f0f0}::ng-deep .conflict-panel{position:absolute;bottom:10px;right:10px;background:#fff;padding:8px;border-radius:4px;z-index:1000;max-height:calc(85vh - 20px);overflow-y:auto}::ng-deep .conflict-panel .header{display:flex;justify-content:space-between;padding:8px;cursor:pointer;background:#f0f0f0}::ng-deep ::ng-deep .ol-zoom.ol-unselectable.ol-control{display:flex;flex-direction:column;position:absolute;
|
|
2891
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: GisKomponentComponent, isStandalone: true, selector: "gis-komponent", inputs: { showToolbox: "showToolbox", showActiveObjects: "showActiveObjects", showLegendList: "showLegendList", showMapSearch: "showMapSearch", identifier: "identifier", settings: "settings" }, providers: [LayerHelperService], viewQueries: [{ propertyName: "toolbarRef", first: true, predicate: ["toolbarRef"], descendants: true, static: true }, { propertyName: "activeObjectsRef", first: true, predicate: ["activeObjectsRef"], descendants: true, static: true }], ngImport: i0, template: "@if (selectedProfile && selectedProfile.showLayerSelector) {\n <lib-layer-selector [map]=\"map\" [profile]=\"selectedProfile\" [currentZoomLevel]=\"currentZoomLevel\"></lib-layer-selector>\n}\n@if (selectedProfile && selectedProfile.showLegends) {\n <lib-legends-list [map]=\"map\" [profile]=\"selectedProfile\"></lib-legends-list>\n}\n\n<!-- <span>Zoom: {{ currentZoomLevel}}</span> -->\n<div #activeObjectsRef>\n @if(showActiveObjects && activeObjectsReady && settings) {\n <activeObjects [settings]=\"settings\"></activeObjects>\n }\n</div>\n<div #toolbarRef class=\"map-toolbar-container\">\n @if(showToolbox && profileShowToolbox && settings) {\n <map-toolbox [map]=\"map\" \n [profile]=\"selectedProfile\"\n [settings]=\"settings\"\n [collapsed]=\"selectedProfile.toolbarCollapsed\" [WKTInputEnabled]=\"settings?.WKTInputEnabled\" [deleteEnabled]=\"settings?.deleteEnabled\" [showMeasureArea]=\"selectedProfile.showAreaMeasurement\" [showMeasureDistance]=\"selectedProfile.showDistanceMeasurement\"></map-toolbox>\n }\n</div>\n\n<div class=\"map-container\">\n <lib-map-search *ngIf=\"showMapSearch\" [profile]=\"selectedProfile\"></lib-map-search>\n\n <!-- Objektvisning -->\n <!-- @if (showObjects) {\n <div class=\"object-panel\" [class.collapsed]=\"activeObjectsCollapsed\">\n <div class=\"header\" (click)=\"toggleActiveObjectsCollapsed()\">\n <span>Aktive objekter ({{activeObjects.length}})</span>\n <mat-icon>{{ activeObjectsCollapsed ? 'expand_more' : 'expand_less' }}</mat-icon>\n </div>\n @if (!activeObjectsCollapsed){\n <ul>\n <li *ngFor=\"let obj of activeObjects\">{{ obj.name }} ({{obj.size}})</li>\n </ul>\n }\n </div>\n } -->\n\n <!-- Konflikter -->\n @if (showConflicts) {\n\n <div class=\"conflict-panel\" [class.collapsed]=\"conflictsCollapsed\">\n <div class=\"header\">\n <span>Konflikter (3)</span>\n <mat-icon>{{ activeObjectsCollapsed ? 'expand_more' : 'expand_less' }}</mat-icon> -->\n </div>\n <mat-list>\n <mat-list-item>\n <span matListItemTitle>Lag #1</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #1</span>\n </mat-list-item>\n <mat-list-item>\n <span matListItemTitle>Lag #2 (svarer ikke)</span>\n </mat-list-item>\n <mat-list-item>\n <span matListItemTitle>Lag #3</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #1</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #2</span>\n </mat-list-item>\n </mat-list>\n </div>\n \n } \n\n <!-- Kort -->\n <div id=\"map\" class=\"map\"></div>\n</div>\n", styles: [":host{display:block;width:100%;height:100%;overflow:hidden}::ng-deep .lib-error-snackbar{background-color:#d32f2f;color:#fff;font-weight:500}::ng-deep .map-container{position:relative;height:81vh;width:100%;overflow:hidden}::ng-deep #map{width:100%;height:100%;position:absolute;inset:0;overflow:hidden}::ng-deep .ol-viewport{overflow:hidden!important}::ng-deep ::ng-deep .ol-logo{position:absolute;left:auto;right:3em;top:6.25em}::ng-deep ::ng-deep .ol-copyright{background-color:transparent;position:absolute;bottom:10px;width:100%;text-align:center}::ng-deep ::ng-deep .toolbar{position:absolute;top:10px;left:10px;background:#fff;padding:4px;border-radius:4px;display:flex;flex-direction:column;transition:width .3s;z-index:1000;overflow:hidden}::ng-deep ::ng-deep .toolbar.collapsed{width:40px;overflow:hidden}::ng-deep .object-panel{position:absolute;bottom:10px;left:10px;background:#fff;padding:8px;border-radius:4px;z-index:1000;max-height:calc(85vh - 20px);overflow-y:auto}::ng-deep .object-panel .header{display:flex;justify-content:space-between;padding:8px;cursor:pointer;background:#f0f0f0}::ng-deep .conflict-panel{position:absolute;bottom:10px;right:10px;background:#fff;padding:8px;border-radius:4px;z-index:1000;max-height:calc(85vh - 20px);overflow-y:auto}::ng-deep .conflict-panel .header{display:flex;justify-content:space-between;padding:8px;cursor:pointer;background:#f0f0f0}::ng-deep ::ng-deep .ol-zoom.ol-unselectable.ol-control{display:flex;flex-direction:column;position:absolute;left:1rem}::ng-deep ::ng-deep button.ol-zoom-in{font-size:2em;width:40px;height:40px;background-color:color-mix(in srgb,#000 60%,transparent);border:none;box-shadow:none;cursor:pointer;border-radius:5px 5px 0 0!important;color:#fff}::ng-deep ::ng-deep button.ol-zoom-in:hover{color:#e9e3e3;outline:none}::ng-deep ::ng-deep .ol-scale-text{display:flex}::ng-deep button.ol-zoom-out{font-size:2em;width:40px;height:40px;background-color:color-mix(in srgb,#000 60%,transparent);border:none;box-shadow:none;cursor:pointer;color:#fff;border-radius:0 0 5px 5px!important}::ng-deep button.ol-zoom-out:hover{color:#e9e3e3;outline:none}::ng-deep button.ol-rotate-reset{font-size:2em;width:40px;height:40px;background-color:color-mix(in srgb,#000 60%,transparent);border:none;box-shadow:none;cursor:pointer;color:#fff;border-radius:5px}::ng-deep button.ol-rotate-reset:hover{color:#e9e3e3;outline:none}::ng-deep .ol-scale-bar.ol-unselectable{position:absolute;bottom:3rem;left:1rem}::ng-deep .ol-mouse-position{top:44em;left:12px;position:absolute;background:color-mix(in srgb,#000 21%,transparent);color:#fffcfc;width:189px;height:30px;padding:2px;border-radius:5px;font-family:Avenir Next W01,Lato,-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;text-align:center;display:flex;align-items:center;justify-content:flex-start}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i3$1.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i3$1.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i3$1.MatListItemLine, selector: "[matListItemLine]" }, { kind: "directive", type: i3$1.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: LayerSelectorComponent, selector: "lib-layer-selector", inputs: ["map", "profile", "currentZoomLevel"] }, { kind: "component", type: MapSearchComponent, selector: "lib-map-search", inputs: ["profile"] }, { kind: "component", type: ToolboxComponent, selector: "map-toolbox", inputs: ["map", "showMeasureDistance", "showMeasureArea", "collapsed", "settings", "profile", "WKTInputEnabled", "deleteEnabled"] }, { kind: "component", type: ActiveObjectsComponent, selector: "activeObjects", inputs: ["settings"] }, { kind: "component", type: LegendsListComponent, selector: "lib-legends-list", inputs: ["map", "profile"] }] });
|
|
2348
2892
|
}
|
|
2349
2893
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: GisKomponentComponent, decorators: [{
|
|
2350
2894
|
type: Component,
|
|
2351
|
-
args: [{ selector: 'gis-komponent', imports: [CommonModule, MatIconModule, MatListModule, MatSelectModule, LayerSelectorComponent, MapSearchComponent, ToolboxComponent, ActiveObjectsComponent, LegendsListComponent], providers: [LayerHelperService], template: "@if (selectedProfile && selectedProfile.showLayerSelector) {\n <lib-layer-selector [map]=\"map\" [profile]=\"selectedProfile\" [currentZoomLevel]=\"currentZoomLevel\"></lib-layer-selector>\n}\n@if (selectedProfile && selectedProfile.showLegends) {\n <lib-legends-list [map]=\"map\" [profile]=\"selectedProfile\"></lib-legends-list>\n}\n\n<!-- <span>Zoom: {{ currentZoomLevel}}</span> -->\n<div #activeObjectsRef>\n @if(showActiveObjects && activeObjectsReady && settings) {\n <activeObjects [settings]=\"settings\"></activeObjects>\n }\n</div>\n<div #toolbarRef class=\"map-toolbar-container\">\n @if(showToolbox && profileShowToolbox && settings) {\n <map-toolbox [map]=\"map\" \n [profile]=\"selectedProfile\"\n [settings]=\"settings\"\n [collapsed]=\"selectedProfile.toolbarCollapsed\" [WKTInputEnabled]=\"settings?.WKTInputEnabled\" [deleteEnabled]=\"settings?.deleteEnabled\" [showMeasureArea]=\"selectedProfile.showAreaMeasurement\" [showMeasureDistance]=\"selectedProfile.showDistanceMeasurement\"></map-toolbox>\n }\n</div>\n\n<div class=\"map-container\">\n <lib-map-search *ngIf=\"showMapSearch\"></lib-map-search>\n\n <!-- Objektvisning -->\n <!-- @if (showObjects) {\n <div class=\"object-panel\" [class.collapsed]=\"activeObjectsCollapsed\">\n <div class=\"header\" (click)=\"toggleActiveObjectsCollapsed()\">\n <span>Aktive objekter ({{activeObjects.length}})</span>\n <mat-icon>{{ activeObjectsCollapsed ? 'expand_more' : 'expand_less' }}</mat-icon>\n </div>\n @if (!activeObjectsCollapsed){\n <ul>\n <li *ngFor=\"let obj of activeObjects\">{{ obj.name }} ({{obj.size}})</li>\n </ul>\n }\n </div>\n } -->\n\n <!-- Konflikter -->\n @if (showConflicts) {\n\n <div class=\"conflict-panel\" [class.collapsed]=\"conflictsCollapsed\">\n <div class=\"header\">\n <span>Konflikter (3)</span>\n <mat-icon>{{ activeObjectsCollapsed ? 'expand_more' : 'expand_less' }}</mat-icon> -->\n </div>\n <mat-list>\n <mat-list-item>\n <span matListItemTitle>Lag #1</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #1</span>\n </mat-list-item>\n <mat-list-item>\n <span matListItemTitle>Lag #2 (svarer ikke)</span>\n </mat-list-item>\n <mat-list-item>\n <span matListItemTitle>Lag #3</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #1</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #2</span>\n </mat-list-item>\n </mat-list>\n </div>\n \n } \n\n <!-- Kort -->\n <div id=\"map\" class=\"map\"></div>\n</div>\n", styles: [":host{display:block;width:100%;height:100%;overflow:hidden}::ng-deep .lib-error-snackbar{background-color:#d32f2f;color:#fff;font-weight:500}::ng-deep .map-container{position:relative;height:81vh;width:100%;overflow:hidden}::ng-deep #map{width:100%;height:100%;position:absolute;inset:0;overflow:hidden}::ng-deep .ol-viewport{overflow:hidden!important}::ng-deep ::ng-deep .ol-logo{position:absolute;left:auto;right:3em;top:6.25em}::ng-deep ::ng-deep .ol-copyright{background-color:transparent;position:absolute;bottom:10px;width:100%;text-align:center}::ng-deep ::ng-deep .toolbar{position:absolute;top:10px;left:10px;background:#fff;padding:4px;border-radius:4px;display:flex;flex-direction:column;transition:width .3s;z-index:1000;overflow:hidden}::ng-deep ::ng-deep .toolbar.collapsed{width:40px;overflow:hidden}::ng-deep .object-panel{position:absolute;bottom:10px;left:10px;background:#fff;padding:8px;border-radius:4px;z-index:1000;max-height:calc(85vh - 20px);overflow-y:auto}::ng-deep .object-panel .header{display:flex;justify-content:space-between;padding:8px;cursor:pointer;background:#f0f0f0}::ng-deep .conflict-panel{position:absolute;bottom:10px;right:10px;background:#fff;padding:8px;border-radius:4px;z-index:1000;max-height:calc(85vh - 20px);overflow-y:auto}::ng-deep .conflict-panel .header{display:flex;justify-content:space-between;padding:8px;cursor:pointer;background:#f0f0f0}::ng-deep ::ng-deep .ol-zoom.ol-unselectable.ol-control{display:flex;flex-direction:column;position:absolute;
|
|
2895
|
+
args: [{ selector: 'gis-komponent', imports: [CommonModule, MatIconModule, MatListModule, MatSelectModule, LayerSelectorComponent, MapSearchComponent, ToolboxComponent, ActiveObjectsComponent, LegendsListComponent], providers: [LayerHelperService], template: "@if (selectedProfile && selectedProfile.showLayerSelector) {\n <lib-layer-selector [map]=\"map\" [profile]=\"selectedProfile\" [currentZoomLevel]=\"currentZoomLevel\"></lib-layer-selector>\n}\n@if (selectedProfile && selectedProfile.showLegends) {\n <lib-legends-list [map]=\"map\" [profile]=\"selectedProfile\"></lib-legends-list>\n}\n\n<!-- <span>Zoom: {{ currentZoomLevel}}</span> -->\n<div #activeObjectsRef>\n @if(showActiveObjects && activeObjectsReady && settings) {\n <activeObjects [settings]=\"settings\"></activeObjects>\n }\n</div>\n<div #toolbarRef class=\"map-toolbar-container\">\n @if(showToolbox && profileShowToolbox && settings) {\n <map-toolbox [map]=\"map\" \n [profile]=\"selectedProfile\"\n [settings]=\"settings\"\n [collapsed]=\"selectedProfile.toolbarCollapsed\" [WKTInputEnabled]=\"settings?.WKTInputEnabled\" [deleteEnabled]=\"settings?.deleteEnabled\" [showMeasureArea]=\"selectedProfile.showAreaMeasurement\" [showMeasureDistance]=\"selectedProfile.showDistanceMeasurement\"></map-toolbox>\n }\n</div>\n\n<div class=\"map-container\">\n <lib-map-search *ngIf=\"showMapSearch\" [profile]=\"selectedProfile\"></lib-map-search>\n\n <!-- Objektvisning -->\n <!-- @if (showObjects) {\n <div class=\"object-panel\" [class.collapsed]=\"activeObjectsCollapsed\">\n <div class=\"header\" (click)=\"toggleActiveObjectsCollapsed()\">\n <span>Aktive objekter ({{activeObjects.length}})</span>\n <mat-icon>{{ activeObjectsCollapsed ? 'expand_more' : 'expand_less' }}</mat-icon>\n </div>\n @if (!activeObjectsCollapsed){\n <ul>\n <li *ngFor=\"let obj of activeObjects\">{{ obj.name }} ({{obj.size}})</li>\n </ul>\n }\n </div>\n } -->\n\n <!-- Konflikter -->\n @if (showConflicts) {\n\n <div class=\"conflict-panel\" [class.collapsed]=\"conflictsCollapsed\">\n <div class=\"header\">\n <span>Konflikter (3)</span>\n <mat-icon>{{ activeObjectsCollapsed ? 'expand_more' : 'expand_less' }}</mat-icon> -->\n </div>\n <mat-list>\n <mat-list-item>\n <span matListItemTitle>Lag #1</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #1</span>\n </mat-list-item>\n <mat-list-item>\n <span matListItemTitle>Lag #2 (svarer ikke)</span>\n </mat-list-item>\n <mat-list-item>\n <span matListItemTitle>Lag #3</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #1</span>\n <span matListItemLine><mat-icon>highlight</mat-icon> Objekt #2</span>\n </mat-list-item>\n </mat-list>\n </div>\n \n } \n\n <!-- Kort -->\n <div id=\"map\" class=\"map\"></div>\n</div>\n", styles: [":host{display:block;width:100%;height:100%;overflow:hidden}::ng-deep .lib-error-snackbar{background-color:#d32f2f;color:#fff;font-weight:500}::ng-deep .map-container{position:relative;height:81vh;width:100%;overflow:hidden}::ng-deep #map{width:100%;height:100%;position:absolute;inset:0;overflow:hidden}::ng-deep .ol-viewport{overflow:hidden!important}::ng-deep ::ng-deep .ol-logo{position:absolute;left:auto;right:3em;top:6.25em}::ng-deep ::ng-deep .ol-copyright{background-color:transparent;position:absolute;bottom:10px;width:100%;text-align:center}::ng-deep ::ng-deep .toolbar{position:absolute;top:10px;left:10px;background:#fff;padding:4px;border-radius:4px;display:flex;flex-direction:column;transition:width .3s;z-index:1000;overflow:hidden}::ng-deep ::ng-deep .toolbar.collapsed{width:40px;overflow:hidden}::ng-deep .object-panel{position:absolute;bottom:10px;left:10px;background:#fff;padding:8px;border-radius:4px;z-index:1000;max-height:calc(85vh - 20px);overflow-y:auto}::ng-deep .object-panel .header{display:flex;justify-content:space-between;padding:8px;cursor:pointer;background:#f0f0f0}::ng-deep .conflict-panel{position:absolute;bottom:10px;right:10px;background:#fff;padding:8px;border-radius:4px;z-index:1000;max-height:calc(85vh - 20px);overflow-y:auto}::ng-deep .conflict-panel .header{display:flex;justify-content:space-between;padding:8px;cursor:pointer;background:#f0f0f0}::ng-deep ::ng-deep .ol-zoom.ol-unselectable.ol-control{display:flex;flex-direction:column;position:absolute;left:1rem}::ng-deep ::ng-deep button.ol-zoom-in{font-size:2em;width:40px;height:40px;background-color:color-mix(in srgb,#000 60%,transparent);border:none;box-shadow:none;cursor:pointer;border-radius:5px 5px 0 0!important;color:#fff}::ng-deep ::ng-deep button.ol-zoom-in:hover{color:#e9e3e3;outline:none}::ng-deep ::ng-deep .ol-scale-text{display:flex}::ng-deep button.ol-zoom-out{font-size:2em;width:40px;height:40px;background-color:color-mix(in srgb,#000 60%,transparent);border:none;box-shadow:none;cursor:pointer;color:#fff;border-radius:0 0 5px 5px!important}::ng-deep button.ol-zoom-out:hover{color:#e9e3e3;outline:none}::ng-deep button.ol-rotate-reset{font-size:2em;width:40px;height:40px;background-color:color-mix(in srgb,#000 60%,transparent);border:none;box-shadow:none;cursor:pointer;color:#fff;border-radius:5px}::ng-deep button.ol-rotate-reset:hover{color:#e9e3e3;outline:none}::ng-deep .ol-scale-bar.ol-unselectable{position:absolute;bottom:3rem;left:1rem}::ng-deep .ol-mouse-position{top:44em;left:12px;position:absolute;background:color-mix(in srgb,#000 21%,transparent);color:#fffcfc;width:189px;height:30px;padding:2px;border-radius:5px;font-family:Avenir Next W01,Lato,-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;text-align:center;display:flex;align-items:center;justify-content:flex-start}\n"] }]
|
|
2352
2896
|
}], propDecorators: { showToolbox: [{
|
|
2353
2897
|
type: Input
|
|
2354
2898
|
}], showActiveObjects: [{
|