@regionerne/gis-komponent 0.0.2 → 0.0.3
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 +539 -13
- package/fesm2022/regionerne-gis-komponent.mjs.map +1 -1
- package/lib/components/gis-komponent/gis-komponent.component.d.ts +52 -0
- package/lib/components/layer-selector/layer-selector.component.d.ts +38 -0
- package/lib/config/config.d.ts +5 -0
- package/lib/config/library-provider.d.ts +3 -0
- package/lib/controls/CopyrightControl/copyRightControl.d.ts +4 -0
- package/lib/controls/LogoControl/logoControl.d.ts +4 -0
- package/lib/models/GisKomponentSettings.d.ts +6 -0
- package/lib/models/ILayer.d.ts +50 -0
- package/lib/models/ILayerGroup.d.ts +28 -0
- package/lib/models/IProfile.d.ts +38 -0
- package/lib/models/geoserver.d.ts +12 -0
- package/lib/models/profile.d.ts +52 -0
- package/lib/services/komponentSettingsHelper.service.d.ts +11 -0
- package/lib/services/layerHelper.service.d.ts +16 -0
- package/lib/services/profile.service.d.ts +8 -0
- package/package.json +7 -2
- package/public-api.d.ts +4 -1
- package/lib/gis-komponent.component.d.ts +0 -5
|
@@ -1,22 +1,548 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
1
2
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component } from '@angular/core';
|
|
3
|
+
import { InjectionToken, inject, Injectable, Input, ViewChild, Component } from '@angular/core';
|
|
4
|
+
import * as i2 from '@angular/material/icon';
|
|
5
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
6
|
+
import Map from 'ol/Map';
|
|
7
|
+
import View from 'ol/View';
|
|
8
|
+
import TileLayer from 'ol/layer/Tile';
|
|
9
|
+
import ol_layer_Vector from 'ol/layer/Vector';
|
|
10
|
+
import VectorSource from 'ol/source/Vector';
|
|
11
|
+
import ImageWMS from 'ol/source/ImageWMS';
|
|
12
|
+
import WMTSCapabilities from 'ol/format/WMTSCapabilities';
|
|
13
|
+
import Draw from 'ol/interaction/Draw';
|
|
14
|
+
import Translate from 'ol/interaction/Translate';
|
|
15
|
+
import ImageLayer from 'ol/layer/Image';
|
|
16
|
+
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
17
|
+
import OLLayerGroup from 'ol/layer/Group';
|
|
18
|
+
import { MatSelectModule } from '@angular/material/select';
|
|
19
|
+
import * as i2$1 from '@angular/material/list';
|
|
20
|
+
import { MatListModule } from '@angular/material/list';
|
|
21
|
+
import ol_control_mouse from 'ol/control/MousePosition';
|
|
22
|
+
import ol_control_scale from 'ol/control/ScaleLine';
|
|
23
|
+
import { register } from 'ol/proj/proj4';
|
|
24
|
+
import proj4 from 'proj4';
|
|
25
|
+
import { Control } from 'ol/control';
|
|
26
|
+
import { TileWMS } from 'ol/source';
|
|
27
|
+
import { map, of, combineLatest } from 'rxjs';
|
|
28
|
+
import WMTS, { optionsFromCapabilities } from 'ol/source/WMTS';
|
|
29
|
+
import * as i4 from '@angular/cdk/drag-drop';
|
|
30
|
+
import { moveItemInArray, transferArrayItem, DragDropModule } from '@angular/cdk/drag-drop';
|
|
31
|
+
import * as i1 from '@angular/material/form-field';
|
|
32
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
33
|
+
import * as i3 from '@angular/forms';
|
|
34
|
+
import { FormsModule } from '@angular/forms';
|
|
35
|
+
import * as i5 from '@angular/material/expansion';
|
|
36
|
+
import { MatExpansionModule } from '@angular/material/expansion';
|
|
37
|
+
import * as i6 from '@angular/material/input';
|
|
38
|
+
import { MatInputModule } from '@angular/material/input';
|
|
39
|
+
import ol_control_Control from 'ol/control/Control';
|
|
40
|
+
import WKT from 'ol/format/WKT';
|
|
41
|
+
import * as SLDReader from '@nieuwlandgeo/sldreader';
|
|
42
|
+
import { extend } from 'ol/extent';
|
|
43
|
+
import 'ol/ol.css';
|
|
44
|
+
|
|
45
|
+
const GISKOMPONENT_CONFIG = new InjectionToken('GisKomponentConfig');
|
|
46
|
+
|
|
47
|
+
class ProfileService {
|
|
48
|
+
config = inject(GISKOMPONENT_CONFIG);
|
|
49
|
+
_baseUrl = this.config.apiBaseUrl;
|
|
50
|
+
_http = inject(HttpClient);
|
|
51
|
+
getByIdentifier(identifier) {
|
|
52
|
+
const url = `${this._baseUrl}/api/profile/identifier/${identifier}`;
|
|
53
|
+
return this._http.get(url);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// logo-control.ts
|
|
58
|
+
class LogoControl extends Control {
|
|
59
|
+
constructor(url) {
|
|
60
|
+
const element = document.createElement('div');
|
|
61
|
+
element.className = 'ol-logo ol-unselectable ol-control';
|
|
62
|
+
if (url) {
|
|
63
|
+
const img = document.createElement('img');
|
|
64
|
+
img.src = url;
|
|
65
|
+
img.alt = 'Logo';
|
|
66
|
+
element.appendChild(img);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
element.style.display = 'none';
|
|
70
|
+
}
|
|
71
|
+
super({ element });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
class CopyrightControl extends Control {
|
|
76
|
+
constructor(text) {
|
|
77
|
+
const element = document.createElement('div');
|
|
78
|
+
element.className = 'ol-copyright ol-unselectable ol-control';
|
|
79
|
+
element.innerText = text;
|
|
80
|
+
super({ element });
|
|
81
|
+
if (!text) {
|
|
82
|
+
element.style.display = 'none';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
Injectable({
|
|
88
|
+
providedIn: 'root'
|
|
89
|
+
});
|
|
90
|
+
class LayerHelperService {
|
|
91
|
+
_layerDbIdKey = 'layerDbId';
|
|
92
|
+
_layerGroupDbIdKey = 'layerGroupDbId';
|
|
93
|
+
_mapFilteredLayerGroupsKeyName = 'mapFilteredLayerGroups';
|
|
94
|
+
_layerIdsToDisplayInMapKeyName = 'layerIdsToDisplayInMap';
|
|
95
|
+
setDbId(layer, id) {
|
|
96
|
+
layer.set(this._layerDbIdKey, id);
|
|
97
|
+
}
|
|
98
|
+
getDbId(layer) {
|
|
99
|
+
const dbId = layer.get(this._layerDbIdKey) ?? -1;
|
|
100
|
+
return +dbId;
|
|
101
|
+
}
|
|
102
|
+
setLayerGroupDbId(layer, id) {
|
|
103
|
+
layer.set(this._layerGroupDbIdKey, id);
|
|
104
|
+
}
|
|
105
|
+
getLayerGroupDbId(layer) {
|
|
106
|
+
const dbId = layer.get(this._layerGroupDbIdKey) ?? -1;
|
|
107
|
+
return +dbId;
|
|
108
|
+
}
|
|
109
|
+
applyCachedLayersToDisplayInMap(map) {
|
|
110
|
+
const layerIdsCachedToDisplay = localStorage.getItem(this._layerIdsToDisplayInMapKeyName)?.split(',');
|
|
111
|
+
if (layerIdsCachedToDisplay) {
|
|
112
|
+
map.getLayers().getArray().forEach(layergroup => {
|
|
113
|
+
if (layergroup instanceof OLLayerGroup) {
|
|
114
|
+
layergroup.getLayers().getArray().forEach(l => {
|
|
115
|
+
if (!layerIdsCachedToDisplay.some(id => l.get(this._layerDbIdKey) == id)) {
|
|
116
|
+
const current = l.getVisible();
|
|
117
|
+
if (current) {
|
|
118
|
+
l.setVisible(!current);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
toggleLayer(map, layer, filteredLayerGroups) {
|
|
127
|
+
map.getLayers().getArray().forEach(layergroup => {
|
|
128
|
+
if (layergroup instanceof OLLayerGroup) {
|
|
129
|
+
layergroup.getLayers().getArray().forEach(l => {
|
|
130
|
+
if (l.get(this._layerDbIdKey) === layer.id) {
|
|
131
|
+
const current = l.getVisible();
|
|
132
|
+
l.setVisible(!current);
|
|
133
|
+
layer.visible = !current;
|
|
134
|
+
//console.log('set '+ layer.id +' to visible '+layer.displayInMap);
|
|
135
|
+
localStorage.setItem(this._mapFilteredLayerGroupsKeyName, JSON.stringify(filteredLayerGroups));
|
|
136
|
+
localStorage.setItem(this._layerIdsToDisplayInMapKeyName, filteredLayerGroups
|
|
137
|
+
.flatMap(lg => lg.layers)
|
|
138
|
+
.filter(lg => lg.visible)
|
|
139
|
+
.map(lg => lg.id).join(','));
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
class LayerSelectorComponent {
|
|
148
|
+
set contentIcon(content) {
|
|
149
|
+
this._layerSelectorIcon = content;
|
|
150
|
+
}
|
|
151
|
+
set contentBody(content) {
|
|
152
|
+
this._layerSelectorBody = content;
|
|
153
|
+
}
|
|
154
|
+
map;
|
|
155
|
+
profile;
|
|
156
|
+
searchText = '';
|
|
157
|
+
allLayerGroups = [];
|
|
158
|
+
filteredLayerGroups = [];
|
|
159
|
+
showSelector = false;
|
|
160
|
+
_layerSelectorIcon;
|
|
161
|
+
_layerSelectorIconControl;
|
|
162
|
+
_layerSelectorBody;
|
|
163
|
+
_layerSelectorBodyControl;
|
|
164
|
+
_mapFilteredLayerGroupsKeyName = 'mapFilteredLayerGroups';
|
|
165
|
+
_layerIdsToDisplayInMapKeyName = 'layerIdsToDisplayInMap';
|
|
166
|
+
_layerHelper = inject(LayerHelperService);
|
|
167
|
+
ngOnChanges() {
|
|
168
|
+
if (this.profile) {
|
|
169
|
+
this.allLayerGroups = this.profile.layerGroups
|
|
170
|
+
.map((lg, idx) => ({ ...lg, layers: lg.layers
|
|
171
|
+
.filter((l) => l.activeInSelector),
|
|
172
|
+
sortOrder: idx }))
|
|
173
|
+
.filter(g => g.layers.length > 0);
|
|
174
|
+
const cachedFilteredLayergroups = localStorage.getItem(this._mapFilteredLayerGroupsKeyName);
|
|
175
|
+
if (cachedFilteredLayergroups) {
|
|
176
|
+
const parsedFilteredLayerGroups = JSON.parse(cachedFilteredLayergroups);
|
|
177
|
+
if (parsedFilteredLayerGroups.length != this.allLayerGroups.length) {
|
|
178
|
+
//If layer groups changed in the backend, then use those
|
|
179
|
+
this.filteredLayerGroups = this.setfilteredGroups();
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
this.filteredLayerGroups = parsedFilteredLayerGroups;
|
|
183
|
+
this._setVisibleLayersFromCache(parsedFilteredLayerGroups);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
this.filteredLayerGroups = this.setfilteredGroups();
|
|
188
|
+
}
|
|
189
|
+
localStorage.setItem(this._layerIdsToDisplayInMapKeyName, this.filteredLayerGroups
|
|
190
|
+
.flatMap(lg => lg.layers)
|
|
191
|
+
.filter(lg => lg.visible)
|
|
192
|
+
.map(lg => lg.id).join(','));
|
|
193
|
+
this._initializeMapIconControl();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
toggleLayer(layer) {
|
|
197
|
+
this._layerHelper.toggleLayer(this.map, layer, this.filteredLayerGroups);
|
|
198
|
+
}
|
|
199
|
+
toggleLayerSelector() {
|
|
200
|
+
this.showSelector = !this.showSelector;
|
|
201
|
+
if (this.showSelector) {
|
|
202
|
+
this._addMapBodyControl();
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
this._removeMapBodyControl();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
setfilteredGroups() {
|
|
209
|
+
const text = this.searchText.toLowerCase();
|
|
210
|
+
return this.allLayerGroups
|
|
211
|
+
.map((g, idx) => {
|
|
212
|
+
if (!text) {
|
|
213
|
+
return { ...g, expanded: false, sortOrder: idx }; // collapsed by default
|
|
214
|
+
}
|
|
215
|
+
const filteredItems = g.layers.filter(l => l.name.toLowerCase().includes(text));
|
|
216
|
+
return {
|
|
217
|
+
...g,
|
|
218
|
+
expanded: filteredItems.length > 0,
|
|
219
|
+
sortOrder: idx,
|
|
220
|
+
layers: filteredItems
|
|
221
|
+
};
|
|
222
|
+
})
|
|
223
|
+
.filter(g => g.layers.length > 0)
|
|
224
|
+
.sort((a, b) => a.sortOrder - b.sortOrder);
|
|
225
|
+
}
|
|
226
|
+
dropGroup(event) {
|
|
227
|
+
moveItemInArray(this.filteredLayerGroups, event.previousIndex, event.currentIndex);
|
|
228
|
+
this.updateGroupSortOrders();
|
|
229
|
+
localStorage.setItem(this._mapFilteredLayerGroupsKeyName, JSON.stringify(this.filteredLayerGroups));
|
|
230
|
+
}
|
|
231
|
+
dropLayer(event, group) {
|
|
232
|
+
if (event.previousContainer === event.container) {
|
|
233
|
+
moveItemInArray(group.layers, event.previousIndex, event.currentIndex);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
transferArrayItem(event.previousContainer.data, event.container.data, event.previousIndex, event.currentIndex);
|
|
237
|
+
}
|
|
238
|
+
this.updateLayerSortOrders(group);
|
|
239
|
+
localStorage.setItem(this._mapFilteredLayerGroupsKeyName, JSON.stringify(this.filteredLayerGroups));
|
|
240
|
+
}
|
|
241
|
+
clearSearchText() {
|
|
242
|
+
this.searchText = '';
|
|
243
|
+
this.filteredLayerGroups = this.setfilteredGroups();
|
|
244
|
+
}
|
|
245
|
+
updateGroupSortOrders() {
|
|
246
|
+
this.filteredLayerGroups.forEach((g, idx) => (g.sortOrder = idx));
|
|
247
|
+
}
|
|
248
|
+
updateLayerSortOrders(group) {
|
|
249
|
+
group.layers.forEach((layer, idx) => (layer.sortOrder = idx));
|
|
250
|
+
}
|
|
251
|
+
_initializeMapIconControl() {
|
|
252
|
+
this.map.removeControl(this._layerSelectorIconControl);
|
|
253
|
+
const element = this._layerSelectorIcon.nativeElement;
|
|
254
|
+
this._layerSelectorIconControl = new ol_control_Control({ element: element });
|
|
255
|
+
this.map.addControl(this._layerSelectorIconControl);
|
|
256
|
+
}
|
|
257
|
+
_addMapBodyControl() {
|
|
258
|
+
this.map.removeControl(this._layerSelectorBodyControl);
|
|
259
|
+
const element = this._layerSelectorBody.nativeElement;
|
|
260
|
+
this._layerSelectorBodyControl = new ol_control_Control({ element: element });
|
|
261
|
+
this.map.addControl(this._layerSelectorBodyControl);
|
|
262
|
+
}
|
|
263
|
+
_removeMapBodyControl() {
|
|
264
|
+
this.map.removeControl(this._layerSelectorBodyControl);
|
|
265
|
+
}
|
|
266
|
+
_setVisibleLayersFromCache(cachedFilteredLayergroups) {
|
|
267
|
+
this.allLayerGroups.forEach(group => group.layers.forEach(layer => {
|
|
268
|
+
const cachedLayer = cachedFilteredLayergroups.find(gr => gr.id === group.id)?.layers?.find(l => l.id === layer.id);
|
|
269
|
+
layer.visible = cachedLayer?.visible ?? layer.visible;
|
|
270
|
+
}));
|
|
271
|
+
}
|
|
272
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LayerSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
273
|
+
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" }, viewQueries: [{ propertyName: "contentIcon", first: true, predicate: ["layerSelectorIcon"], descendants: true }, { propertyName: "contentBody", first: true, predicate: ["layerSelectorBody"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #layerSelectorIcon 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=\"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-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 <div class=\"item\" cdkDrag cdkDragPreviewDisabled>\n <mat-icon class=\"drag-indicator\">drag_indicator</mat-icon>\n <span>{{ layer.name }}</span>\n @if (layer.visible) {\n <mat-icon (click)=\"toggleLayer(layer)\" class=\"power-on\">power</mat-icon>(t\u00E6nd)\n }\n @if (!layer.visible) {\n <mat-icon (click)=\"toggleLayer(layer)\" class=\"power-off\">power</mat-icon>(sluk)\n }\n </div>\n }\n </div>\n </mat-expansion-panel>\n </div>\n }\n </div>\n</div>\n", styles: ["::ng-deep .layer-selector-icon{position:absolute;left:auto;right:4em;bottom:.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;font-size:45px;width:50px;height:50px;background-color:#0004;border:1px solid rgba(255,255,255,.8);border-radius:8px;-webkit-text-fill-color:#334155;-webkit-text-stroke-width:.9px;-webkit-text-stroke-color:white}::ng-deep .layer-selector-icon mat-icon:hover{box-shadow:0 4px 12px #0003;color:#3e4b5e}::ng-deep .layer-selector-body{position:absolute;left:auto;right:4em;bottom:4em;z-index:1000;background:#fff;border-radius:8px;box-shadow:0 4px 20px #00000026;border:1px solid #e0e0e0;width:320px;max-height:500px;overflow:hidden;display:flex;flex-direction:column}::ng-deep .layer-selector-body .search-section{display:flex;align-items:center;gap:8px;padding:16px 16px 8px;background:#fff;border-bottom:1px solid #e0e0e0}::ng-deep .layer-selector-body .search-section mat-form-field{flex:1}::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-wrapper{padding-bottom:0}::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:14px;padding:8px 0}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-label{color:#666;font-weight:500}::ng-deep .layer-selector-body .search-section mat-icon{color:#666;cursor:pointer;padding:8px;border-radius:4px;transition:all .2s ease;font-size:30px;width:20px;height:20px;display:flex;justify-content:center;align-items:end}::ng-deep .layer-selector-body .search-section mat-icon:hover{color:#334155}::ng-deep .layer-selector-body .item-list{flex:1;overflow-y:auto;padding:8px;max-height:400px}::ng-deep .layer-selector-body .item-list .group{margin-bottom:8px;border-radius: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 16px;height:48px;background:#f8f9fa;border-bottom:1px solid #e0e0e0}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header:hover{background:#e6e7ec}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title{align-items:center;gap:8px;font-weight:600;color:#333;font-size:14px}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon{color:#666;font-size:18px;width:18px;height:18px;transition:transform .2s ease}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content{background:#fff}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content .mat-expansion-panel-body{padding:8px 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{display:flex;align-items:center;gap:8px;padding:12px 16px;border-bottom:1px solid #f5f5f5;background:#fff;transition:all .2s ease;cursor:move}::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:#f8f9fa}::ng-deep .layer-selector-body .item-list .group .item-list .item.cdk-drag-preview{background:#fff;box-shadow:0 4px 12px #00000026;border-radius:4px}::ng-deep .layer-selector-body .item-list .group .item-list .item.cdk-drag-placeholder{background:#e3f2fd;opacity:.6}::ng-deep .layer-selector-body .item-list .group .item-list .item.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.drag-indicator{color:#9e9e9e;font-size:18px;width:18px;height:18px;cursor:move}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on{color:#4caf50;font-size:20px;width:20px;height:20px;cursor:pointer;margin-left:auto;padding:4px;border-radius:4px}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on:hover{background:#e8f5e8}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off{color:#f44336;font-size:20px;width:20px;height:20px;cursor:pointer;margin-left:auto;padding:4px;border-radius:4px}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off:hover{background:#ffebee}::ng-deep .layer-selector-body .item-list .group .item-list .item>:nth-child(2){flex:1;font-size:14px;color:#333;margin:0}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 15px #00000026;background:#fff;padding:12px 16px}.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{scrollbar-width:thin;scrollbar-color:#c1c1c1 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: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.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: "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"] }] });
|
|
274
|
+
}
|
|
275
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: LayerSelectorComponent, decorators: [{
|
|
276
|
+
type: Component,
|
|
277
|
+
args: [{ selector: 'lib-layer-selector', imports: [MatFormFieldModule, CommonModule, MatIconModule, FormsModule, DragDropModule,
|
|
278
|
+
MatExpansionModule, MatInputModule], template: "<div #layerSelectorIcon 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=\"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-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 <div class=\"item\" cdkDrag cdkDragPreviewDisabled>\n <mat-icon class=\"drag-indicator\">drag_indicator</mat-icon>\n <span>{{ layer.name }}</span>\n @if (layer.visible) {\n <mat-icon (click)=\"toggleLayer(layer)\" class=\"power-on\">power</mat-icon>(t\u00E6nd)\n }\n @if (!layer.visible) {\n <mat-icon (click)=\"toggleLayer(layer)\" class=\"power-off\">power</mat-icon>(sluk)\n }\n </div>\n }\n </div>\n </mat-expansion-panel>\n </div>\n }\n </div>\n</div>\n", styles: ["::ng-deep .layer-selector-icon{position:absolute;left:auto;right:4em;bottom:.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;font-size:45px;width:50px;height:50px;background-color:#0004;border:1px solid rgba(255,255,255,.8);border-radius:8px;-webkit-text-fill-color:#334155;-webkit-text-stroke-width:.9px;-webkit-text-stroke-color:white}::ng-deep .layer-selector-icon mat-icon:hover{box-shadow:0 4px 12px #0003;color:#3e4b5e}::ng-deep .layer-selector-body{position:absolute;left:auto;right:4em;bottom:4em;z-index:1000;background:#fff;border-radius:8px;box-shadow:0 4px 20px #00000026;border:1px solid #e0e0e0;width:320px;max-height:500px;overflow:hidden;display:flex;flex-direction:column}::ng-deep .layer-selector-body .search-section{display:flex;align-items:center;gap:8px;padding:16px 16px 8px;background:#fff;border-bottom:1px solid #e0e0e0}::ng-deep .layer-selector-body .search-section mat-form-field{flex:1}::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-wrapper{padding-bottom:0}::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:14px;padding:8px 0}::ng-deep .layer-selector-body .search-section mat-form-field .mat-form-field-label{color:#666;font-weight:500}::ng-deep .layer-selector-body .search-section mat-icon{color:#666;cursor:pointer;padding:8px;border-radius:4px;transition:all .2s ease;font-size:30px;width:20px;height:20px;display:flex;justify-content:center;align-items:end}::ng-deep .layer-selector-body .search-section mat-icon:hover{color:#334155}::ng-deep .layer-selector-body .item-list{flex:1;overflow-y:auto;padding:8px;max-height:400px}::ng-deep .layer-selector-body .item-list .group{margin-bottom:8px;border-radius: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 16px;height:48px;background:#f8f9fa;border-bottom:1px solid #e0e0e0}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header:hover{background:#e6e7ec}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title{align-items:center;gap:8px;font-weight:600;color:#333;font-size:14px}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel mat-expansion-panel-header mat-panel-title mat-icon{color:#666;font-size:18px;width:18px;height:18px;transition:transform .2s ease}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content{background:#fff}::ng-deep .layer-selector-body .item-list .group mat-expansion-panel .mat-expansion-panel-content .mat-expansion-panel-body{padding:8px 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{display:flex;align-items:center;gap:8px;padding:12px 16px;border-bottom:1px solid #f5f5f5;background:#fff;transition:all .2s ease;cursor:move}::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:#f8f9fa}::ng-deep .layer-selector-body .item-list .group .item-list .item.cdk-drag-preview{background:#fff;box-shadow:0 4px 12px #00000026;border-radius:4px}::ng-deep .layer-selector-body .item-list .group .item-list .item.cdk-drag-placeholder{background:#e3f2fd;opacity:.6}::ng-deep .layer-selector-body .item-list .group .item-list .item.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.drag-indicator{color:#9e9e9e;font-size:18px;width:18px;height:18px;cursor:move}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on{color:#4caf50;font-size:20px;width:20px;height:20px;cursor:pointer;margin-left:auto;padding:4px;border-radius:4px}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-on:hover{background:#e8f5e8}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off{color:#f44336;font-size:20px;width:20px;height:20px;cursor:pointer;margin-left:auto;padding:4px;border-radius:4px}::ng-deep .layer-selector-body .item-list .group .item-list .item mat-icon.power-off:hover{background:#ffebee}::ng-deep .layer-selector-body .item-list .group .item-list .item>:nth-child(2){flex:1;font-size:14px;color:#333;margin:0}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 15px #00000026;background:#fff;padding:12px 16px}.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{scrollbar-width:thin;scrollbar-color:#c1c1c1 transparent}\n"] }]
|
|
279
|
+
}], propDecorators: { contentIcon: [{
|
|
280
|
+
type: ViewChild,
|
|
281
|
+
args: ['layerSelectorIcon', { static: false }]
|
|
282
|
+
}], contentBody: [{
|
|
283
|
+
type: ViewChild,
|
|
284
|
+
args: ['layerSelectorBody', { static: false }]
|
|
285
|
+
}], map: [{
|
|
286
|
+
type: Input
|
|
287
|
+
}], profile: [{
|
|
288
|
+
type: Input
|
|
289
|
+
}] } });
|
|
290
|
+
|
|
291
|
+
class KomponentSettingsHelperService {
|
|
292
|
+
_httpClient = inject(HttpClient);
|
|
293
|
+
loadThem(settings, workpace, geoserver, map) {
|
|
294
|
+
this.getStyleLoader(settings.style, workpace, geoserver).subscribe({
|
|
295
|
+
next: loadedStyle => {
|
|
296
|
+
const parser = new WKT();
|
|
297
|
+
const features = settings.geometries.map(g => parser.readFeature(g.geometry, { featureProjection: 'EPSG:25832', dataProjection: 'EPSG:25832' }));
|
|
298
|
+
console.log("🚀 ~ KomponentSettingsHelperService ~ loadThem ~ SLDReader:", SLDReader);
|
|
299
|
+
debugger;
|
|
300
|
+
const sldObject = SLDReader.Reader(loadedStyle);
|
|
301
|
+
const sldLayer = SLDReader.getLayer(sldObject);
|
|
302
|
+
const sldStyles = SLDReader.getStyle(sldLayer);
|
|
303
|
+
const sldFeatureStyle = sldStyles.featuretypestyles[0];
|
|
304
|
+
const olStyle = SLDReader.createOlStyle(sldFeatureStyle.rules[0], 'Polygon');
|
|
305
|
+
const layer = new ol_layer_Vector({
|
|
306
|
+
source: new VectorSource(),
|
|
307
|
+
style: olStyle
|
|
308
|
+
});
|
|
309
|
+
layer.getSource()?.addFeatures(features.filter(f => !!f));
|
|
310
|
+
map.addLayer(layer);
|
|
311
|
+
const extent = features.filter(f => !!f).reduce((e, f) => extend(e, f.getGeometry().getExtent()), features[0]?.getGeometry().getExtent());
|
|
312
|
+
map.getView().fit(extent);
|
|
313
|
+
console.log("🚀 ~ KomponentSettingsHelperService ~ loadThem ~ style:", sldObject);
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
getStyleLoader(styleName, workspace, geoserver) {
|
|
318
|
+
const headerstring = `${geoserver.userName}:${geoserver.password}`;
|
|
319
|
+
const encoded = btoa(headerstring);
|
|
320
|
+
const headers = new HttpHeaders().set('Authorization', `Basic ${encoded}`);
|
|
321
|
+
const url = `${geoserver.url}/rest/workspaces/${workspace}/styles/${styleName}.sld`;
|
|
322
|
+
return this._httpClient.get(url, { headers, responseType: 'text' });
|
|
323
|
+
}
|
|
324
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: KomponentSettingsHelperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
325
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: KomponentSettingsHelperService, providedIn: 'root' });
|
|
326
|
+
}
|
|
327
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: KomponentSettingsHelperService, decorators: [{
|
|
328
|
+
type: Injectable,
|
|
329
|
+
args: [{
|
|
330
|
+
providedIn: 'root'
|
|
331
|
+
}]
|
|
332
|
+
}] });
|
|
3
333
|
|
|
4
334
|
class GisKomponentComponent {
|
|
335
|
+
_profileService = inject(ProfileService);
|
|
336
|
+
_http = inject(HttpClient);
|
|
337
|
+
_layerHelper = inject(LayerHelperService);
|
|
338
|
+
identifier;
|
|
339
|
+
settings;
|
|
340
|
+
map;
|
|
341
|
+
toolbarCollapsed = false;
|
|
342
|
+
layerPanelCollapsed = false;
|
|
343
|
+
activeObjectsCollapsed = false;
|
|
344
|
+
conflictsCollapsed = false;
|
|
345
|
+
showConflicts = false;
|
|
346
|
+
showObjects = false;
|
|
347
|
+
profiles = [];
|
|
348
|
+
selectedProfile;
|
|
349
|
+
_komponentSettingsHelper = inject(KomponentSettingsHelperService);
|
|
350
|
+
layers = [];
|
|
351
|
+
// activeObjects = [
|
|
352
|
+
// { name: 'Objekt A', size: '22 m2' },
|
|
353
|
+
// { name: 'Objekt B', size: '108,4 m2' }
|
|
354
|
+
// ];
|
|
355
|
+
source = new VectorSource({ wrapX: false });
|
|
356
|
+
layer = new ol_layer_Vector({ source: this.source });
|
|
357
|
+
draw = new Draw({ source: this.source, type: 'Polygon' });
|
|
358
|
+
move = new Translate({ layers: [this.layer] });
|
|
359
|
+
mousePositionCtrl = new ol_control_mouse({ projection: 'EPSG:25832' });
|
|
360
|
+
scaleCtrl = new ol_control_scale({
|
|
361
|
+
units: 'metric',
|
|
362
|
+
bar: true,
|
|
363
|
+
steps: 4,
|
|
364
|
+
text: true,
|
|
365
|
+
minWidth: 120
|
|
366
|
+
});
|
|
367
|
+
profileSelected(profileIdentifier) {
|
|
368
|
+
this._profileService.getByIdentifier(profileIdentifier).subscribe({
|
|
369
|
+
next: profile => {
|
|
370
|
+
this.selectedProfile = profile;
|
|
371
|
+
const view = new View({
|
|
372
|
+
center: [profile.centerX, profile.centerY],
|
|
373
|
+
extent: [profile.minX, profile.minX, profile.maxX, profile.maxY],
|
|
374
|
+
zoom: profile.zoom ?? 8,
|
|
375
|
+
maxZoom: profile.maxZoom ?? undefined,
|
|
376
|
+
minZoom: profile.minZoom ?? undefined,
|
|
377
|
+
projection: 'EPSG:25832'
|
|
378
|
+
});
|
|
379
|
+
this._getCapabilitiesObject(profile).subscribe({
|
|
380
|
+
next: capabilityObject => {
|
|
381
|
+
const layers = [...profile.layerGroups.map((lg) => new OLLayerGroup({
|
|
382
|
+
layers: lg.layers
|
|
383
|
+
.filter(layer => layer.activeInSelector)
|
|
384
|
+
.map(l => this._mapLayer(l, capabilityObject, 'EPSG:25832', lg.id)) // for now, we default to EPSG:25832.
|
|
385
|
+
}))
|
|
386
|
+
];
|
|
387
|
+
this.map.setLayers(layers);
|
|
388
|
+
if (this.settings && profile.styleRepositoryWorkspace && profile.styleRepositoryGeoserver) {
|
|
389
|
+
this._komponentSettingsHelper.loadThem(this.settings, profile.styleRepositoryWorkspace, profile.styleRepositoryGeoserver, this.map);
|
|
390
|
+
}
|
|
391
|
+
this._layerHelper.applyCachedLayersToDisplayInMap(this.map);
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
this._handleShowMouseCoordinates(profile.showCoordinates);
|
|
395
|
+
this._handleShowScale(profile.showScale);
|
|
396
|
+
this._setLogo(profile.logoUrl);
|
|
397
|
+
this._setCopyRight(profile.copyrightMessage);
|
|
398
|
+
this.map.setView(view);
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
_getCapabilitiesObject(profile) {
|
|
403
|
+
// Find all WMTS-layers and get their base url's for retrieving the capabilities. Make sure every url is only called once by removing duplicates
|
|
404
|
+
const getCapabilitiesUrls = [...new Set(profile.layerGroups.flatMap(lg => lg.layers).filter(lg => lg.layerType === 'WMTS').map(lg => lg.baseUrl))];
|
|
405
|
+
const parser = new WMTSCapabilities();
|
|
406
|
+
const capabilities$ = getCapabilitiesUrls.map(url => this._http.get(`${url}/gwc/service/wmts?request=GetCapabilities`, { responseType: 'text' }).pipe(map(result => ({
|
|
407
|
+
url,
|
|
408
|
+
sourceObject: parser.read(result)
|
|
409
|
+
}))));
|
|
410
|
+
// To make it easier to find the appropriate object, I convert the array to an object of a key/value type.
|
|
411
|
+
return capabilities$.length == 0 ? of({}) :
|
|
412
|
+
combineLatest(capabilities$).pipe(map(allCapabilities => allCapabilities.reduce((obj, item) => {
|
|
413
|
+
obj[item.url] = item.sourceObject;
|
|
414
|
+
return obj;
|
|
415
|
+
}, {})));
|
|
416
|
+
}
|
|
417
|
+
_mapLayer(layer, wmtsOptions, projection, layerGroupDbId) {
|
|
418
|
+
const params = {
|
|
419
|
+
layers: layer.layers,
|
|
420
|
+
};
|
|
421
|
+
if (layer.token) {
|
|
422
|
+
params[layer.authKeyName] = layer.token;
|
|
423
|
+
}
|
|
424
|
+
layer.wmsParameters.forEach(param => {
|
|
425
|
+
params[param.key] = param.value;
|
|
426
|
+
});
|
|
427
|
+
let result;
|
|
428
|
+
switch (layer.layerType) {
|
|
429
|
+
case 'WMS':
|
|
430
|
+
result = new ImageLayer({
|
|
431
|
+
source: new ImageWMS({
|
|
432
|
+
url: layer.baseUrl,
|
|
433
|
+
params
|
|
434
|
+
}),
|
|
435
|
+
});
|
|
436
|
+
break;
|
|
437
|
+
case 'TILEWMS':
|
|
438
|
+
result = new TileLayer({
|
|
439
|
+
source: new TileWMS({
|
|
440
|
+
url: layer.baseUrl,
|
|
441
|
+
params,
|
|
442
|
+
})
|
|
443
|
+
});
|
|
444
|
+
break;
|
|
445
|
+
case 'WMTS':
|
|
446
|
+
// Create WMST options from the capabilities loaded from the getCapabilities called.
|
|
447
|
+
const options = optionsFromCapabilities(wmtsOptions[layer.baseUrl], {
|
|
448
|
+
layer: layer.layers,
|
|
449
|
+
matrixSet: layer.projection || projection
|
|
450
|
+
});
|
|
451
|
+
result = new TileLayer({
|
|
452
|
+
source: new WMTS(options)
|
|
453
|
+
});
|
|
454
|
+
break;
|
|
455
|
+
}
|
|
456
|
+
if (layer.minZoom) {
|
|
457
|
+
result.setMinZoom(layer.minZoom);
|
|
458
|
+
}
|
|
459
|
+
if (layer.maxZoom) {
|
|
460
|
+
result.setMaxZoom(layer.maxZoom);
|
|
461
|
+
}
|
|
462
|
+
if (layer.maxX && layer.minX && layer.maxY && layer.minY) {
|
|
463
|
+
result.setExtent([layer.minX, layer.minX, layer.maxX, layer.maxY]);
|
|
464
|
+
}
|
|
465
|
+
this._layerHelper.setDbId(result, layer.id);
|
|
466
|
+
this._layerHelper.setLayerGroupDbId(result, layerGroupDbId);
|
|
467
|
+
return result;
|
|
468
|
+
}
|
|
469
|
+
_setLogo(url) {
|
|
470
|
+
const logoCtrl = new LogoControl(url);
|
|
471
|
+
this.map.addControl(logoCtrl);
|
|
472
|
+
}
|
|
473
|
+
_setCopyRight(message) {
|
|
474
|
+
const copyrightCtrl = new CopyrightControl(message);
|
|
475
|
+
this.map.addControl(copyrightCtrl);
|
|
476
|
+
}
|
|
477
|
+
_handleShowMouseCoordinates(showCoords) {
|
|
478
|
+
if (showCoords) {
|
|
479
|
+
this.map.addControl(this.mousePositionCtrl);
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
this.map.removeControl(this.mousePositionCtrl);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
_handleShowScale(showScale) {
|
|
486
|
+
if (showScale) {
|
|
487
|
+
this.map.addControl(this.scaleCtrl);
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
this.map.removeControl(this.scaleCtrl);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
ngOnInit() {
|
|
494
|
+
this.profileSelected(this.identifier);
|
|
495
|
+
proj4.defs("EPSG:25832", "+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs +type=crs");
|
|
496
|
+
register(proj4);
|
|
497
|
+
// const projection = getProjection("EPSG:25832");
|
|
498
|
+
this.map = new Map({
|
|
499
|
+
target: 'map',
|
|
500
|
+
});
|
|
501
|
+
this.draw.setActive(false);
|
|
502
|
+
this.move.setActive(false);
|
|
503
|
+
this.map.addInteraction(this.draw);
|
|
504
|
+
this.map.addInteraction(this.move);
|
|
505
|
+
}
|
|
506
|
+
toggleDraw() {
|
|
507
|
+
this.move.setActive(false);
|
|
508
|
+
this.draw.setActive(!this.draw.getActive());
|
|
509
|
+
}
|
|
510
|
+
toggleShowConflicts() {
|
|
511
|
+
this.showConflicts = !this.showConflicts;
|
|
512
|
+
}
|
|
513
|
+
toggleShowObjects() {
|
|
514
|
+
this.showObjects = !this.showObjects;
|
|
515
|
+
}
|
|
516
|
+
toggleMove() {
|
|
517
|
+
this.draw.setActive(false);
|
|
518
|
+
this.move.setActive(true);
|
|
519
|
+
}
|
|
520
|
+
toggleToolbar() {
|
|
521
|
+
this.toolbarCollapsed = !this.toolbarCollapsed;
|
|
522
|
+
}
|
|
523
|
+
toggleLayerPanel() {
|
|
524
|
+
this.layerPanelCollapsed = !this.layerPanelCollapsed;
|
|
525
|
+
}
|
|
526
|
+
toggleActiveObjectsCollapsed() {
|
|
527
|
+
this.activeObjectsCollapsed = !this.activeObjectsCollapsed;
|
|
528
|
+
}
|
|
5
529
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: GisKomponentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
7
|
-
<p>
|
|
8
|
-
gis-komponent works!
|
|
9
|
-
</p>
|
|
10
|
-
`, isInline: true, styles: [""] });
|
|
530
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: GisKomponentComponent, isStandalone: true, selector: "gis-komponent", inputs: { identifier: "identifier", settings: "settings" }, providers: [LayerHelperService], ngImport: i0, template: " <lib-layer-selector [map]=\"map\" [profile]=\"selectedProfile\"></lib-layer-selector>\n\n<div class=\"map-container\">\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: ["::ng-deep .map-container{position:relative;height:85vh;width:100%}::ng-deep #map{width:100%;height:100%;position:absolute;inset:0}::ng-deep ::ng-deep .ol-logo{position:absolute;left:auto;right:3em;top:6.25em}::ng-deep ::ng-deep .ol-copyright{position:absolute;left:auto;right:calc(50vw - 90px);bottom:.5em}::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}::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}::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}::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;top:2rem;left:1rem}::ng-deep ::ng-deep button.ol-zoom-in{font-size:28px;width:35px;height:35px;background-color:#fff;border:1px solid rgba(255,255,255,.8);box-shadow:#0000004d 0 1px 4px -1px;cursor:pointer;color:#334155}::ng-deep button.ol-zoom-out{font-size:28px;width:35px;height:35px;background-color:#fff;border:1px solid rgba(255,255,255,.8);box-shadow:#0000004d 0 1px 4px -1px;cursor:pointer;color:#334155}::ng-deep button.ol-rotate-reset{font-size:28px;width:35px;height:35px;background-color:#fff;border:1px solid rgba(255,255,255,.8);box-shadow:#0000004d 0 1px 4px -1px;cursor:pointer;color:#334155;margin-top:10px}::ng-deep .ol-scale-bar.ol-unselectable{position:absolute;bottom:1rem;left:1rem}\n"], dependencies: [{ 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: MatListModule }, { kind: "component", type: i2$1.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i2$1.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i2$1.MatListItemLine, selector: "[matListItemLine]" }, { kind: "directive", type: i2$1.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: LayerSelectorComponent, selector: "lib-layer-selector", inputs: ["map", "profile"] }] });
|
|
11
531
|
}
|
|
12
532
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: GisKomponentComponent, decorators: [{
|
|
13
533
|
type: Component,
|
|
14
|
-
args: [{ selector: 'gis-komponent', imports: [], template:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
534
|
+
args: [{ selector: 'gis-komponent', imports: [CommonModule, MatIconModule, MatListModule, MatSelectModule, LayerSelectorComponent], providers: [LayerHelperService], template: " <lib-layer-selector [map]=\"map\" [profile]=\"selectedProfile\"></lib-layer-selector>\n\n<div class=\"map-container\">\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: ["::ng-deep .map-container{position:relative;height:85vh;width:100%}::ng-deep #map{width:100%;height:100%;position:absolute;inset:0}::ng-deep ::ng-deep .ol-logo{position:absolute;left:auto;right:3em;top:6.25em}::ng-deep ::ng-deep .ol-copyright{position:absolute;left:auto;right:calc(50vw - 90px);bottom:.5em}::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}::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}::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}::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;top:2rem;left:1rem}::ng-deep ::ng-deep button.ol-zoom-in{font-size:28px;width:35px;height:35px;background-color:#fff;border:1px solid rgba(255,255,255,.8);box-shadow:#0000004d 0 1px 4px -1px;cursor:pointer;color:#334155}::ng-deep button.ol-zoom-out{font-size:28px;width:35px;height:35px;background-color:#fff;border:1px solid rgba(255,255,255,.8);box-shadow:#0000004d 0 1px 4px -1px;cursor:pointer;color:#334155}::ng-deep button.ol-rotate-reset{font-size:28px;width:35px;height:35px;background-color:#fff;border:1px solid rgba(255,255,255,.8);box-shadow:#0000004d 0 1px 4px -1px;cursor:pointer;color:#334155;margin-top:10px}::ng-deep .ol-scale-bar.ol-unselectable{position:absolute;bottom:1rem;left:1rem}\n"] }]
|
|
535
|
+
}], propDecorators: { identifier: [{
|
|
536
|
+
type: Input
|
|
537
|
+
}], settings: [{
|
|
538
|
+
type: Input
|
|
539
|
+
}] } });
|
|
540
|
+
|
|
541
|
+
function provideLibrary(config) {
|
|
542
|
+
return [
|
|
543
|
+
{ provide: GISKOMPONENT_CONFIG, useValue: config }
|
|
544
|
+
];
|
|
545
|
+
}
|
|
20
546
|
|
|
21
547
|
/*
|
|
22
548
|
* Public API Surface of gis-komponent
|
|
@@ -26,5 +552,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
26
552
|
* Generated bundle index. Do not edit.
|
|
27
553
|
*/
|
|
28
554
|
|
|
29
|
-
export { GisKomponentComponent };
|
|
555
|
+
export { GisKomponentComponent, LayerHelperService, ProfileService, provideLibrary };
|
|
30
556
|
//# sourceMappingURL=regionerne-gis-komponent.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"regionerne-gis-komponent.mjs","sources":["../../../projects/gis-komponent/src/lib/gis-komponent.component.ts","../../../projects/gis-komponent/src/public-api.ts","../../../projects/gis-komponent/src/regionerne-gis-komponent.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 'gis-komponent',\n imports: [],\n template: `\n <p>\n gis-komponent works!\n </p>\n `,\n styles: ``\n})\nexport class GisKomponentComponent {\n\n}\n","/*\n * Public API Surface of gis-komponent\n */\n\nexport * from './lib/gis-komponent.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;MAYa,qBAAqB,CAAA;wGAArB,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,qBAAqB,EAPtB,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA;;;;AAIT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;4FAGU,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAVjC,SAAS;+BACE,eAAe,EAAA,OAAA,EAChB,EAAE,EACD,QAAA,EAAA;;;;AAIT,EAAA,CAAA,EAAA;;;ACTH;;AAEG;;ACFH;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"regionerne-gis-komponent.mjs","sources":["../../../projects/gis-komponent/src/lib/config/config.ts","../../../projects/gis-komponent/src/lib/services/profile.service.ts","../../../projects/gis-komponent/src/lib/controls/LogoControl/logoControl.ts","../../../projects/gis-komponent/src/lib/controls/CopyrightControl/copyRightControl.ts","../../../projects/gis-komponent/src/lib/services/layerHelper.service.ts","../../../projects/gis-komponent/src/lib/components/layer-selector/layer-selector.component.ts","../../../projects/gis-komponent/src/lib/components/layer-selector/layer-selector.component.html","../../../projects/gis-komponent/src/lib/services/komponentSettingsHelper.service.ts","../../../projects/gis-komponent/src/lib/components/gis-komponent/gis-komponent.component.ts","../../../projects/gis-komponent/src/lib/components/gis-komponent/gis-komponent.component.html","../../../projects/gis-komponent/src/lib/config/library-provider.ts","../../../projects/gis-komponent/src/public-api.ts","../../../projects/gis-komponent/src/regionerne-gis-komponent.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport interface GISKomponentConfig {\n apiBaseUrl: string;\n}\n\nexport const GISKOMPONENT_CONFIG = new InjectionToken<GISKomponentConfig>('GisKomponentConfig');\n","import { inject } from '@angular/core';\nimport { GISKOMPONENT_CONFIG } from '../config/config';\nimport { Observable } from 'rxjs';\nimport { HttpClient } from '@angular/common/http';\nimport { IProfileDetailed } from '../models/IProfile';\n\nexport class ProfileService {\n\n private config = inject(GISKOMPONENT_CONFIG);\n private _baseUrl = this.config.apiBaseUrl;\n private _http = inject(HttpClient);\n\n getByIdentifier(identifier: string): Observable<IProfileDetailed> {\n const url = `${this._baseUrl}/api/profile/identifier/${identifier}`;\n return this._http.get<IProfileDetailed>(url);\n }\n}","// logo-control.ts\nimport { Control } from 'ol/control';\n\nexport class LogoControl extends Control {\n constructor(url: string) {\n const element = document.createElement('div');\n element.className = 'ol-logo ol-unselectable ol-control';\n\n if (url) {\n const img = document.createElement('img');\n img.src = url;\n img.alt = 'Logo';\n element.appendChild(img);\n } else {\n element.style.display = 'none';\n }\n\n super({ element });\n }\n}\n","import { Control } from 'ol/control';\n\nexport class CopyrightControl extends Control {\n constructor(text: string) {\n const element = document.createElement('div');\n element.className = 'ol-copyright ol-unselectable ol-control';\n element.innerText = text;\n\n super({ element });\n\n if (!text) {\n element.style.display = 'none';\n }\n }\n}\n","import { Injectable } from '@angular/core';\nimport BaseLayer from 'ol/layer/Base';\nimport Map from 'ol/Map';\nimport OLLayerGroup from 'ol/layer/Group';\nimport { LayerSelectorGroup } from '../models/profile';\nimport { ILayer } from '../models/ILayer';\n\nInjectable({\n providedIn: 'root'\n})\nexport class LayerHelperService {\n\n private readonly _layerDbIdKey: string = 'layerDbId';\n private readonly _layerGroupDbIdKey: string = 'layerGroupDbId';\n private readonly _mapFilteredLayerGroupsKeyName: string = 'mapFilteredLayerGroups';\n private readonly _layerIdsToDisplayInMapKeyName: string = 'layerIdsToDisplayInMap';\n\n setDbId(layer: BaseLayer, id: number): void {\n layer.set(this._layerDbIdKey, id);\n }\n\n getDbId(layer: BaseLayer): number {\n const dbId = layer.get(this._layerDbIdKey) ?? -1;\n return +dbId;\n }\n\n setLayerGroupDbId(layer: BaseLayer, id: number): void {\n layer.set(this._layerGroupDbIdKey, id);\n }\n\n getLayerGroupDbId(layer: BaseLayer): number {\n const dbId = layer.get(this._layerGroupDbIdKey) ?? -1;\n return +dbId;\n }\n\n applyCachedLayersToDisplayInMap(map: Map): void {\n const layerIdsCachedToDisplay = localStorage.getItem(this._layerIdsToDisplayInMapKeyName)?.split(',');\n if (layerIdsCachedToDisplay) {\n map.getLayers().getArray().forEach(layergroup => {\n if (layergroup instanceof OLLayerGroup) {\n layergroup.getLayers().getArray().forEach(l => {\n if (!layerIdsCachedToDisplay.some(id => l.get(this._layerDbIdKey) == id)) {\n const current = l.getVisible();\n if (current) {\n l.setVisible(!current);\n }\n }\n })\n }\n })\n } \n }\n \n\n toggleLayer(map: Map, layer: ILayer, filteredLayerGroups: LayerSelectorGroup[]): void {\n map.getLayers().getArray().forEach(layergroup => {\n if (layergroup instanceof OLLayerGroup) {\n layergroup.getLayers().getArray().forEach(l => {\n if (l.get(this._layerDbIdKey) === layer.id) {\n const current = l.getVisible();\n l.setVisible(!current);\n layer.visible = !current;\n //console.log('set '+ layer.id +' to visible '+layer.displayInMap);\n localStorage.setItem(this._mapFilteredLayerGroupsKeyName, JSON.stringify(filteredLayerGroups));\n localStorage.setItem(this._layerIdsToDisplayInMapKeyName, filteredLayerGroups\n .flatMap(lg => lg.layers)\n .filter(lg => lg.visible)\n .map(lg => lg.id).join(','));\n }\n })}}\n );\n }\n}","import { Component, ElementRef, inject, Input, OnChanges, ViewChild } from '@angular/core';\nimport { CdkDragDrop, DragDropModule, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';\nimport { LayerSelectorGroup, Profile } from '../../models/profile';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { CommonModule } from '@angular/common';\nimport { MatIconModule } from '@angular/material/icon';\nimport { FormsModule } from '@angular/forms';\nimport { MatExpansionModule } from '@angular/material/expansion';\nimport { MatInputModule } from '@angular/material/input';\nimport Map from 'ol/Map';\nimport { LayerHelperService } from '../../services/layerHelper.service';\nimport ol_control_Control from 'ol/control/Control';\nimport { ILayer } from '../../models/ILayer';\n\n@Component({\n selector: 'lib-layer-selector',\n templateUrl: './layer-selector.component.html',\n styleUrls: ['./layer-selector.component.scss'],\n imports: [ MatFormFieldModule, CommonModule, MatIconModule, FormsModule, DragDropModule, \n MatExpansionModule, MatInputModule ]\n})\nexport class LayerSelectorComponent implements OnChanges {\n @ViewChild('layerSelectorIcon', { static: false }) set contentIcon(content: ElementRef) {\n this._layerSelectorIcon = content;\n }\n @ViewChild('layerSelectorBody', { static: false }) set contentBody(content: ElementRef) {\n this._layerSelectorBody = content;\n }\n @Input() map!: Map;\n @Input() profile!: Profile;\n searchText = '';\n allLayerGroups: LayerSelectorGroup[] = [];\n filteredLayerGroups: LayerSelectorGroup[] = [];\n showSelector: boolean = false;\n private _layerSelectorIcon!: ElementRef;\n private _layerSelectorIconControl!: ol_control_Control;\n private _layerSelectorBody!: ElementRef;\n private _layerSelectorBodyControl!: ol_control_Control;\n private readonly _mapFilteredLayerGroupsKeyName: string = 'mapFilteredLayerGroups';\n private readonly _layerIdsToDisplayInMapKeyName: string = 'layerIdsToDisplayInMap';\n private readonly _layerHelper: LayerHelperService = inject(LayerHelperService);\n\n ngOnChanges(): void {\n if (this.profile) {\n this.allLayerGroups = this.profile.layerGroups\n .map((lg, idx) => ({... lg, layers: lg.layers\n .filter((l: { activeInSelector: boolean; }) => l.activeInSelector), \n sortOrder: idx}))\n .filter(g => g.layers.length > 0); \n const cachedFilteredLayergroups = localStorage.getItem(this._mapFilteredLayerGroupsKeyName);\n\n if (cachedFilteredLayergroups) {\n const parsedFilteredLayerGroups = JSON.parse(cachedFilteredLayergroups);\n if (parsedFilteredLayerGroups.length != this.allLayerGroups.length) {\n //If layer groups changed in the backend, then use those\n this.filteredLayerGroups = this.setfilteredGroups(); \n } else {\n this.filteredLayerGroups = parsedFilteredLayerGroups;\n this._setVisibleLayersFromCache(parsedFilteredLayerGroups);\n }\n } else {\n this.filteredLayerGroups = this.setfilteredGroups(); \n }\n localStorage.setItem(this._layerIdsToDisplayInMapKeyName, this.filteredLayerGroups\n .flatMap(lg => lg.layers)\n .filter(lg => lg.visible)\n .map(lg => lg.id).join(','));\n this._initializeMapIconControl();\n }\n }\n\n toggleLayer(layer: ILayer): void {\n this._layerHelper.toggleLayer(this.map, layer, this.filteredLayerGroups);\n }\n\n toggleLayerSelector(): void {\n this.showSelector = !this.showSelector;\n if (this.showSelector) {\n this._addMapBodyControl();\n } else {\n this._removeMapBodyControl();\n }\n }\n\n setfilteredGroups(): LayerSelectorGroup[] {\n const text = this.searchText.toLowerCase();\n return this.allLayerGroups\n .map((g, idx) => {\n if (!text) {\n return { ...g, expanded: false, sortOrder: idx }; // collapsed by default\n }\n const filteredItems = g.layers.filter(l => l.name.toLowerCase().includes(text));\n return {\n ...g,\n expanded: filteredItems.length > 0,\n sortOrder: idx,\n layers: filteredItems\n };\n })\n .filter(g => g.layers.length > 0)\n .sort((a, b) => a.sortOrder - b.sortOrder);\n }\n\n dropGroup(event: CdkDragDrop<LayerSelectorGroup[]>) {\n moveItemInArray(this.filteredLayerGroups, event.previousIndex, event.currentIndex);\n this.updateGroupSortOrders();\n localStorage.setItem(this._mapFilteredLayerGroupsKeyName, JSON.stringify(this.filteredLayerGroups));\n }\n\n dropLayer(event: CdkDragDrop<ILayer[]>, group: LayerSelectorGroup) {\n if (event.previousContainer === event.container) {\n moveItemInArray(group.layers, event.previousIndex, event.currentIndex);\n } else {\n transferArrayItem(\n event.previousContainer.data,\n event.container.data,\n event.previousIndex,\n event.currentIndex\n );\n }\n this.updateLayerSortOrders(group);\n localStorage.setItem(this._mapFilteredLayerGroupsKeyName, JSON.stringify(this.filteredLayerGroups));\n }\n\n clearSearchText(): void {\n this.searchText = '';\n this.filteredLayerGroups = this.setfilteredGroups();\n }\n\n updateGroupSortOrders() {\n this.filteredLayerGroups.forEach((g, idx) => (g.sortOrder = idx));\n }\n\n updateLayerSortOrders(group: LayerSelectorGroup) {\n group.layers.forEach((layer, idx) => (layer.sortOrder = idx));\n }\n\n private _initializeMapIconControl(): void {\n this.map.removeControl(this._layerSelectorIconControl);\n const element = this._layerSelectorIcon.nativeElement;\n this._layerSelectorIconControl = new ol_control_Control({ element: element });\n this.map.addControl(this._layerSelectorIconControl);\n }\n\n private _addMapBodyControl(): void {\n this.map.removeControl(this._layerSelectorBodyControl);\n const element = this._layerSelectorBody.nativeElement;\n this._layerSelectorBodyControl = new ol_control_Control({ element: element });\n this.map.addControl(this._layerSelectorBodyControl);\n }\n\n private _removeMapBodyControl(): void {\n this.map.removeControl(this._layerSelectorBodyControl);\n }\n\n private _setVisibleLayersFromCache(cachedFilteredLayergroups: LayerSelectorGroup[]): void {\n this.allLayerGroups.forEach(group => group.layers.forEach(layer => {\n const cachedLayer = cachedFilteredLayergroups.find(gr => gr.id === group.id)?.layers?.find(l => l.id === layer.id);\n layer.visible = cachedLayer?.visible ?? layer.visible;\n }))\n }\n\n}\n","<div #layerSelectorIcon 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=\"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-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 <div class=\"item\" cdkDrag cdkDragPreviewDisabled>\n <mat-icon class=\"drag-indicator\">drag_indicator</mat-icon>\n <span>{{ layer.name }}</span>\n @if (layer.visible) {\n <mat-icon (click)=\"toggleLayer(layer)\" class=\"power-on\">power</mat-icon>(tænd)\n }\n @if (!layer.visible) {\n <mat-icon (click)=\"toggleLayer(layer)\" class=\"power-off\">power</mat-icon>(sluk)\n }\n </div>\n }\n </div>\n </mat-expansion-panel>\n </div>\n }\n </div>\n</div>\n","import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { GisKomponentSettings } from '../models/GisKomponentSettings';\nimport { GeoServer } from '../models/geoserver';\nimport { Observable } from 'rxjs';\nimport WKT from 'ol/format/WKT'\n// @ts-ignore\nimport * as SLDReader from '@nieuwlandgeo/sldreader';\n\nimport Map from 'ol/Map';\nimport ol_layer_Vector from 'ol/layer/Vector';\nimport VectorSource from 'ol/source/Vector';\nimport { extend } from 'ol/extent';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class KomponentSettingsHelperService {\n\n private readonly _httpClient = inject(HttpClient);\n\n loadThem(settings: GisKomponentSettings, workpace: string, geoserver: GeoServer, map: Map): void {\n this.getStyleLoader(settings.style, workpace, geoserver).subscribe({\n next: loadedStyle => {\n const parser = new WKT();\n\n const features = settings.geometries.map(g => parser.readFeature(g.geometry, { featureProjection: 'EPSG:25832', dataProjection: 'EPSG:25832'}));\n console.log(\"🚀 ~ KomponentSettingsHelperService ~ loadThem ~ SLDReader:\", SLDReader)\n debugger;\n const sldObject = SLDReader.Reader(loadedStyle);\n const sldLayer = SLDReader.getLayer(sldObject);\n const sldStyles = SLDReader.getStyle(sldLayer);\n const sldFeatureStyle = sldStyles.featuretypestyles[0];\n const olStyle = SLDReader.createOlStyle(sldFeatureStyle.rules[0], 'Polygon');\n const layer = new ol_layer_Vector({\n source: new VectorSource(),\n style: olStyle\n });\n layer.getSource()?.addFeatures(features.filter(f => !!f));\n map.addLayer(layer);\n const extent = features.filter(f => !!f).reduce((e, f) => extend(e, f.getGeometry()!.getExtent()!), features[0]?.getGeometry()!.getExtent()!);\n map.getView().fit(extent);\n console.log(\"🚀 ~ KomponentSettingsHelperService ~ loadThem ~ style:\", sldObject)\n }\n });\n }\n\n private getStyleLoader(styleName: string, workspace: string, geoserver: GeoServer): Observable<string> {\n const headerstring = `${geoserver.userName}:${geoserver.password}`;\n const encoded = btoa(headerstring); \n const headers = new HttpHeaders().set('Authorization', `Basic ${encoded}`);\n const url = `${geoserver.url}/rest/workspaces/${workspace}/styles/${styleName}.sld`;\n return this._httpClient.get(url, { headers, responseType: 'text' });\n }\n}","import { CommonModule } from '@angular/common';\nimport { Component, inject, Input, input, OnInit } from '@angular/core';\nimport { MatIconModule } from '@angular/material/icon';\nimport Map from 'ol/Map';\nimport View from 'ol/View';\nimport TileLayer from 'ol/layer/Tile';\nimport ol_layer_Vector from 'ol/layer/Vector';\nimport VectorSource from 'ol/source/Vector';\nimport ImageWMS from 'ol/source/ImageWMS';\nimport WMTSCapabilities from 'ol/format/WMTSCapabilities';\nimport Draw from 'ol/interaction/Draw';\nimport Translate from 'ol/interaction/Translate';\nimport ImageLayer from 'ol/layer/Image';\nimport { ProfileService } from '../../services/profile.service';\nimport LayerGroup from 'ol/layer/Group';\nimport { ILayer } from \"../../models/ILayer\";\n import { MatSelectModule } from '@angular/material/select';\nimport { MatListModule } from '@angular/material/list';\nimport { HttpClient } from '@angular/common/http';\nimport ol_control_mouse from 'ol/control/MousePosition';\nimport ol_control_scale from 'ol/control/ScaleLine';\nimport BaseLayer from 'ol/layer/Base';\nimport { register } from 'ol/proj/proj4';\nimport proj4 from 'proj4';\nimport { LogoControl } from '../../controls/LogoControl/logoControl';\nimport { CopyrightControl } from '../../controls/CopyrightControl/copyRightControl';\nimport { TileWMS } from 'ol/source';\nimport { combineLatest, map, Observable, of } from 'rxjs';\nimport WMTS, { optionsFromCapabilities } from 'ol/source/WMTS';\nimport { LayerHelperService } from '../../services/layerHelper.service';\nimport { IProfile, IProfileDetailed } from '../../models/IProfile';\nimport { Profile } from '../../models/profile';\nimport { LayerSelectorComponent } from \"../layer-selector/layer-selector.component\";\nimport { GisKomponentSettings } from '../../models/GisKomponentSettings';\nimport { KomponentSettingsHelperService } from '../../services/komponentSettingsHelper.service';\nimport 'ol/ol.css';\n\n@Component({\n selector: 'gis-komponent',\n templateUrl: './gis-komponent.component.html',\n styleUrls: ['./gis-komponent.component.scss'],\n imports: [CommonModule, MatIconModule, MatListModule, MatSelectModule, LayerSelectorComponent],\n providers: [LayerHelperService]\n})\nexport class GisKomponentComponent implements OnInit {\n\n private readonly _profileService = inject(ProfileService);\n private readonly _http = inject(HttpClient);\n private readonly _layerHelper = inject(LayerHelperService);\n @Input() identifier!: string;\n @Input() settings: GisKomponentSettings | undefined;\n map!: Map;\n toolbarCollapsed = false;\n layerPanelCollapsed = false;\n activeObjectsCollapsed = false;\n conflictsCollapsed = false;\n showConflicts = false;\n showObjects = false;\n profiles: IProfile[] = [];\n selectedProfile!: IProfileDetailed;\n private readonly _komponentSettingsHelper = inject(KomponentSettingsHelperService);\n\n layers: { name: string, visible: boolean, activeInSelector: boolean, legendUrl: string }[] = [];\n\n // activeObjects = [\n // { name: 'Objekt A', size: '22 m2' },\n // { name: 'Objekt B', size: '108,4 m2' }\n // ];\n\n private source = new VectorSource({ wrapX: false});\n private layer = new ol_layer_Vector({ source: this.source});\n private draw = new Draw({ source: this.source, type: 'Polygon'});\n private move = new Translate({ layers: [this.layer] });\n private mousePositionCtrl = new ol_control_mouse({ projection: 'EPSG:25832' }); \n private scaleCtrl = new ol_control_scale({\n units: 'metric',\n bar: true,\n steps: 4,\n text: true,\n minWidth: 120\n });\n \n profileSelected(profileIdentifier: string): void {\n this._profileService.getByIdentifier(profileIdentifier).subscribe({\n next: profile => { \n this.selectedProfile = profile; \n const view: View = new View({\n center: [profile.centerX, profile.centerY],\n extent: [profile.minX, profile.minX, profile.maxX, profile.maxY],\n zoom: profile.zoom ?? 8,\n maxZoom: profile.maxZoom ?? undefined,\n minZoom: profile.minZoom ?? undefined,\n projection: 'EPSG:25832'\n });\n\n\n this._getCapabilitiesObject(profile).subscribe({\n next: capabilityObject => { \n const layers: BaseLayer[] = [...profile.layerGroups.map((lg: { layers: any[]; id: number; }) => \n new LayerGroup({\n layers: lg.layers\n .filter(layer => layer.activeInSelector)\n .map(l => this._mapLayer(l, capabilityObject, 'EPSG:25832', lg.id)) // for now, we default to EPSG:25832. \n })\n )\n ];\n this.map.setLayers(layers);\n if (this.settings && profile.styleRepositoryWorkspace && profile.styleRepositoryGeoserver) {\n this._komponentSettingsHelper.loadThem(this.settings, profile.styleRepositoryWorkspace, profile.styleRepositoryGeoserver, this.map);\n }\n this._layerHelper.applyCachedLayersToDisplayInMap(this.map);\n }\n });\n \n this._handleShowMouseCoordinates(profile.showCoordinates);\n this._handleShowScale(profile.showScale);\n this._setLogo(profile.logoUrl);\n this._setCopyRight(profile.copyrightMessage);\n this.map.setView(view);\n }}); \n }\n\n private _getCapabilitiesObject(profile: Profile): Observable<Record<string, any>> {\n // Find all WMTS-layers and get their base url's for retrieving the capabilities. Make sure every url is only called once by removing duplicates\n const getCapabilitiesUrls = [... new Set(profile.layerGroups.flatMap(lg => lg.layers).filter(lg => lg.layerType === 'WMTS').map(lg => lg.baseUrl))];\n const parser = new WMTSCapabilities();\n const capabilities$ = getCapabilitiesUrls.map(url => this._http.get(`${url}/gwc/service/wmts?request=GetCapabilities`, {responseType: 'text'}).pipe(map(result => \n ({\n url,\n sourceObject: parser.read(result)\n }))));\n // To make it easier to find the appropriate object, I convert the array to an object of a key/value type.\n return capabilities$.length == 0 ? of({} as Record<string, any>) :\n combineLatest(capabilities$).pipe(map(allCapabilities => \n allCapabilities.reduce((obj, item) => {\n obj[item.url] = item.sourceObject;\n return obj;\n }, {} as Record<string, any>)\n ));\n }\n\n private _mapLayer(layer: ILayer, wmtsOptions: Record<string, any>, projection: string, layerGroupDbId: number): BaseLayer {\n const params: { [x: string]: any } = {\n layers: layer.layers,\n }\n if (layer.token) {\n params[layer.authKeyName] = layer.token;\n }\n layer.wmsParameters.forEach(param => {\n params[param.key] = param.value\n });\n\n let result: BaseLayer;\n switch (layer.layerType) {\n case 'WMS':\n result = new ImageLayer({ \n source: new ImageWMS({ \n url: layer.baseUrl,\n params\n }), \n }); \n break;\n case 'TILEWMS':\n result = new TileLayer({\n source: new TileWMS({\n url: layer.baseUrl,\n params, \n })\n });\n break;\n case 'WMTS':\n // Create WMST options from the capabilities loaded from the getCapabilities called.\n const options = optionsFromCapabilities(wmtsOptions[layer.baseUrl], {\n layer: layer.layers,\n matrixSet: layer.projection || projection\n });\n result = new TileLayer({\n source: new WMTS(options!)\n });\n break;\n }\n \n if (layer.minZoom) {\n result.setMinZoom(layer.minZoom); \n }\n if (layer.maxZoom) {\n result.setMaxZoom(layer.maxZoom);\n } \n if (layer.maxX && layer.minX && layer.maxY && layer.minY) {\n result.setExtent([layer.minX, layer.minX, layer.maxX, layer.maxY]);\n }\n this._layerHelper.setDbId(result, layer.id);\n this._layerHelper.setLayerGroupDbId(result, layerGroupDbId);\n return result;\n }\n\n private _setLogo(url: string): void {\n const logoCtrl = new LogoControl(url);\n this.map.addControl(logoCtrl);\n }\n\n private _setCopyRight(message: string): void {\n const copyrightCtrl = new CopyrightControl(message);\n this.map.addControl(copyrightCtrl);\n }\n\n private _handleShowMouseCoordinates(showCoords: boolean): void {\n if (showCoords) {\n this.map.addControl(this.mousePositionCtrl);\n } else {\n this.map.removeControl(this.mousePositionCtrl);\n }\n }\n\n private _handleShowScale(showScale: boolean): void {\n if (showScale) {\n this.map.addControl(this.scaleCtrl);\n } else {\n this.map.removeControl(this.scaleCtrl);\n }\n }\n\n ngOnInit(): void {\n this.profileSelected(this.identifier);\n proj4.defs(\"EPSG:25832\", \"+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs +type=crs\");\n register(proj4);\n // const projection = getProjection(\"EPSG:25832\");\n this.map = new Map({\n target: 'map',\n });\n this.draw.setActive(false);\n this.move.setActive(false);\n this.map.addInteraction(this.draw);\n this.map.addInteraction(this.move);\n }\n\n toggleDraw(): void {\n this.move.setActive(false);\n this.draw.setActive(!this.draw.getActive());\n }\n\n toggleShowConflicts(): void {\n this.showConflicts = !this.showConflicts;\n }\n\n toggleShowObjects(): void {\n this.showObjects = !this.showObjects;\n }\n\n toggleMove(): void {\n this.draw.setActive(false);\n this.move.setActive(true);\n }\n toggleToolbar(): void {\n this.toolbarCollapsed = !this.toolbarCollapsed;\n }\n\n toggleLayerPanel(): void {\n this.layerPanelCollapsed = !this.layerPanelCollapsed;\n }\n\n toggleActiveObjectsCollapsed(): void { \n this.activeObjectsCollapsed = !this.activeObjectsCollapsed;\n }\n}\n"," <lib-layer-selector [map]=\"map\" [profile]=\"selectedProfile\"></lib-layer-selector>\n\n<div class=\"map-container\">\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","import { Provider } from '@angular/core';\nimport { GISKOMPONENT_CONFIG, GISKomponentConfig } from './config';\n\nexport function provideLibrary(config: GISKomponentConfig): Provider[] {\n return [ \n { provide: GISKOMPONENT_CONFIG, useValue: config }\n ];\n}","/*\n * Public API Surface of gis-komponent\n */\n\nexport * from './lib/components/gis-komponent/gis-komponent.component';\nexport * from './lib/config/library-provider';\nexport * from './lib/services/profile.service';\nexport * from './lib/services/layerHelper.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["LayerGroup","i1","i2"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { OnInit } from '@angular/core';
|
|
2
|
+
import Map from 'ol/Map';
|
|
3
|
+
import { IProfile, IProfileDetailed } from '../../models/IProfile';
|
|
4
|
+
import { GisKomponentSettings } from '../../models/GisKomponentSettings';
|
|
5
|
+
import 'ol/ol.css';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
export declare class GisKomponentComponent implements OnInit {
|
|
8
|
+
private readonly _profileService;
|
|
9
|
+
private readonly _http;
|
|
10
|
+
private readonly _layerHelper;
|
|
11
|
+
identifier: string;
|
|
12
|
+
settings: GisKomponentSettings | undefined;
|
|
13
|
+
map: Map;
|
|
14
|
+
toolbarCollapsed: boolean;
|
|
15
|
+
layerPanelCollapsed: boolean;
|
|
16
|
+
activeObjectsCollapsed: boolean;
|
|
17
|
+
conflictsCollapsed: boolean;
|
|
18
|
+
showConflicts: boolean;
|
|
19
|
+
showObjects: boolean;
|
|
20
|
+
profiles: IProfile[];
|
|
21
|
+
selectedProfile: IProfileDetailed;
|
|
22
|
+
private readonly _komponentSettingsHelper;
|
|
23
|
+
layers: {
|
|
24
|
+
name: string;
|
|
25
|
+
visible: boolean;
|
|
26
|
+
activeInSelector: boolean;
|
|
27
|
+
legendUrl: string;
|
|
28
|
+
}[];
|
|
29
|
+
private source;
|
|
30
|
+
private layer;
|
|
31
|
+
private draw;
|
|
32
|
+
private move;
|
|
33
|
+
private mousePositionCtrl;
|
|
34
|
+
private scaleCtrl;
|
|
35
|
+
profileSelected(profileIdentifier: string): void;
|
|
36
|
+
private _getCapabilitiesObject;
|
|
37
|
+
private _mapLayer;
|
|
38
|
+
private _setLogo;
|
|
39
|
+
private _setCopyRight;
|
|
40
|
+
private _handleShowMouseCoordinates;
|
|
41
|
+
private _handleShowScale;
|
|
42
|
+
ngOnInit(): void;
|
|
43
|
+
toggleDraw(): void;
|
|
44
|
+
toggleShowConflicts(): void;
|
|
45
|
+
toggleShowObjects(): void;
|
|
46
|
+
toggleMove(): void;
|
|
47
|
+
toggleToolbar(): void;
|
|
48
|
+
toggleLayerPanel(): void;
|
|
49
|
+
toggleActiveObjectsCollapsed(): void;
|
|
50
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<GisKomponentComponent, never>;
|
|
51
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<GisKomponentComponent, "gis-komponent", never, { "identifier": { "alias": "identifier"; "required": false; }; "settings": { "alias": "settings"; "required": false; }; }, {}, never, never, true, never>;
|
|
52
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ElementRef, OnChanges } from '@angular/core';
|
|
2
|
+
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
|
3
|
+
import { LayerSelectorGroup, Profile } from '../../models/profile';
|
|
4
|
+
import Map from 'ol/Map';
|
|
5
|
+
import { ILayer } from '../../models/ILayer';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
export declare class LayerSelectorComponent implements OnChanges {
|
|
8
|
+
set contentIcon(content: ElementRef);
|
|
9
|
+
set contentBody(content: ElementRef);
|
|
10
|
+
map: Map;
|
|
11
|
+
profile: Profile;
|
|
12
|
+
searchText: string;
|
|
13
|
+
allLayerGroups: LayerSelectorGroup[];
|
|
14
|
+
filteredLayerGroups: LayerSelectorGroup[];
|
|
15
|
+
showSelector: boolean;
|
|
16
|
+
private _layerSelectorIcon;
|
|
17
|
+
private _layerSelectorIconControl;
|
|
18
|
+
private _layerSelectorBody;
|
|
19
|
+
private _layerSelectorBodyControl;
|
|
20
|
+
private readonly _mapFilteredLayerGroupsKeyName;
|
|
21
|
+
private readonly _layerIdsToDisplayInMapKeyName;
|
|
22
|
+
private readonly _layerHelper;
|
|
23
|
+
ngOnChanges(): void;
|
|
24
|
+
toggleLayer(layer: ILayer): void;
|
|
25
|
+
toggleLayerSelector(): void;
|
|
26
|
+
setfilteredGroups(): LayerSelectorGroup[];
|
|
27
|
+
dropGroup(event: CdkDragDrop<LayerSelectorGroup[]>): void;
|
|
28
|
+
dropLayer(event: CdkDragDrop<ILayer[]>, group: LayerSelectorGroup): void;
|
|
29
|
+
clearSearchText(): void;
|
|
30
|
+
updateGroupSortOrders(): void;
|
|
31
|
+
updateLayerSortOrders(group: LayerSelectorGroup): void;
|
|
32
|
+
private _initializeMapIconControl;
|
|
33
|
+
private _addMapBodyControl;
|
|
34
|
+
private _removeMapBodyControl;
|
|
35
|
+
private _setVisibleLayersFromCache;
|
|
36
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<LayerSelectorComponent, never>;
|
|
37
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<LayerSelectorComponent, "lib-layer-selector", never, { "map": { "alias": "map"; "required": false; }; "profile": { "alias": "profile"; "required": false; }; }, {}, never, never, true, never>;
|
|
38
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface IKeyValue {
|
|
2
|
+
key: string;
|
|
3
|
+
value: string;
|
|
4
|
+
}
|
|
5
|
+
interface ILayerBase {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
layerType: 'WMS' | 'TILEWMS' | 'WMTS';
|
|
9
|
+
legendFileName: string;
|
|
10
|
+
baseUrl: string;
|
|
11
|
+
background: boolean;
|
|
12
|
+
layers: string;
|
|
13
|
+
authKeyName: string;
|
|
14
|
+
token?: string;
|
|
15
|
+
minX: number;
|
|
16
|
+
minY: number;
|
|
17
|
+
maxX: number;
|
|
18
|
+
maxY: number;
|
|
19
|
+
minZoom: number;
|
|
20
|
+
maxZoom: number;
|
|
21
|
+
wmsParameters: IKeyValue[];
|
|
22
|
+
sortOrder: number;
|
|
23
|
+
visible: boolean;
|
|
24
|
+
activeInSelector: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface ILayer extends ILayerBase {
|
|
27
|
+
id: number;
|
|
28
|
+
projection: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ILayerLayerGroup {
|
|
31
|
+
visible: boolean;
|
|
32
|
+
activeInSelector: boolean;
|
|
33
|
+
sortOrder: number;
|
|
34
|
+
id: number;
|
|
35
|
+
name: string;
|
|
36
|
+
description: string;
|
|
37
|
+
allowMultiSelect: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface ILayerDetailed extends ILayer {
|
|
40
|
+
layerGroups: ILayerLayerGroup[];
|
|
41
|
+
}
|
|
42
|
+
export interface ILayerSave extends ILayerBase {
|
|
43
|
+
id?: number;
|
|
44
|
+
projection?: string;
|
|
45
|
+
layerGroups: {
|
|
46
|
+
layerGroupId: number;
|
|
47
|
+
visible: boolean;
|
|
48
|
+
}[];
|
|
49
|
+
}
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ILayer } from './ILayer';
|
|
2
|
+
interface ILayerGroupBase {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
allowMultiSelect: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ILayerGroup extends ILayerGroupBase {
|
|
8
|
+
id: number;
|
|
9
|
+
profileCount?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ILayerGroupLayer extends ILayer {
|
|
12
|
+
id: number;
|
|
13
|
+
sortOrder: number;
|
|
14
|
+
visible: boolean;
|
|
15
|
+
activeInSelector: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface ILayerGroupDetailed extends ILayerGroup {
|
|
18
|
+
layers: ILayerGroupLayer[];
|
|
19
|
+
}
|
|
20
|
+
export interface ILayerGroupSaveLayer {
|
|
21
|
+
id: number;
|
|
22
|
+
visible: boolean;
|
|
23
|
+
activeInSelector: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface ILayerGroupSave extends ILayerGroupBase {
|
|
26
|
+
layers: ILayerGroupSaveLayer[];
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ILayerGroupDetailed } from "././ILayerGroup";
|
|
2
|
+
import { GeoServer } from "./geoserver";
|
|
3
|
+
export interface IProfileBase {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
identifier: string;
|
|
7
|
+
allowFeatureOverlap: boolean;
|
|
8
|
+
allowMapDrawing: boolean;
|
|
9
|
+
showCoordinates: boolean;
|
|
10
|
+
maxX: number;
|
|
11
|
+
maxY: number;
|
|
12
|
+
minX: number;
|
|
13
|
+
minY: number;
|
|
14
|
+
centerX: number;
|
|
15
|
+
centerY: number;
|
|
16
|
+
maxZoom: number;
|
|
17
|
+
minZoom: number;
|
|
18
|
+
zoom: number;
|
|
19
|
+
showScale: boolean;
|
|
20
|
+
logoUrl: string;
|
|
21
|
+
copyrightMessage: string;
|
|
22
|
+
}
|
|
23
|
+
export interface IProfile extends IProfileBase {
|
|
24
|
+
id: number;
|
|
25
|
+
layerGroupCount?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface IProfileLayerGroup extends ILayerGroupDetailed {
|
|
28
|
+
id: number;
|
|
29
|
+
sortOrder: number;
|
|
30
|
+
}
|
|
31
|
+
export interface IProfileDetailed extends IProfile {
|
|
32
|
+
layerGroups: IProfileLayerGroup[];
|
|
33
|
+
styleRepositoryGeoserver?: GeoServer;
|
|
34
|
+
styleRepositoryWorkspace?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface IProfileSave extends IProfileBase {
|
|
37
|
+
layerGroups: number[];
|
|
38
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ILayer } from './ILayer';
|
|
2
|
+
import { ILayerGroupDetailed } from './ILayerGroup';
|
|
3
|
+
interface LayerBase {
|
|
4
|
+
id: string;
|
|
5
|
+
kind: string;
|
|
6
|
+
name: string;
|
|
7
|
+
}
|
|
8
|
+
export interface Layer extends LayerBase {
|
|
9
|
+
kind: 'layer';
|
|
10
|
+
geoserver: boolean;
|
|
11
|
+
baseUrl: string;
|
|
12
|
+
layers: string;
|
|
13
|
+
}
|
|
14
|
+
export interface LayerListItem extends Layer {
|
|
15
|
+
layerGroupCount: number;
|
|
16
|
+
}
|
|
17
|
+
export interface OSMLayer extends LayerBase {
|
|
18
|
+
kind: 'osmLayer';
|
|
19
|
+
}
|
|
20
|
+
export interface LayerGroup {
|
|
21
|
+
id: number;
|
|
22
|
+
name: string;
|
|
23
|
+
allowMultiSelect: boolean;
|
|
24
|
+
layers: ILayer[];
|
|
25
|
+
}
|
|
26
|
+
export interface LayerSelectorGroup extends LayerGroup {
|
|
27
|
+
sortOrder: number;
|
|
28
|
+
expanded?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface Profile {
|
|
31
|
+
id: number;
|
|
32
|
+
name: string;
|
|
33
|
+
description: string;
|
|
34
|
+
identifier: string;
|
|
35
|
+
allowFeatureOverlap: boolean;
|
|
36
|
+
allowMapDrawing: boolean;
|
|
37
|
+
showCoordinates: boolean;
|
|
38
|
+
layerGroups: ILayerGroupDetailed[];
|
|
39
|
+
maxX: number;
|
|
40
|
+
maxY: number;
|
|
41
|
+
minX: number;
|
|
42
|
+
minY: number;
|
|
43
|
+
centerX: number;
|
|
44
|
+
centerY: number;
|
|
45
|
+
maxZoom: number;
|
|
46
|
+
minZoom: number;
|
|
47
|
+
zoom: number;
|
|
48
|
+
showScale: boolean;
|
|
49
|
+
logoUrl: string;
|
|
50
|
+
copyrightMessage: string;
|
|
51
|
+
}
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { GisKomponentSettings } from '../models/GisKomponentSettings';
|
|
2
|
+
import { GeoServer } from '../models/geoserver';
|
|
3
|
+
import Map from 'ol/Map';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export declare class KomponentSettingsHelperService {
|
|
6
|
+
private readonly _httpClient;
|
|
7
|
+
loadThem(settings: GisKomponentSettings, workpace: string, geoserver: GeoServer, map: Map): void;
|
|
8
|
+
private getStyleLoader;
|
|
9
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<KomponentSettingsHelperService, never>;
|
|
10
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<KomponentSettingsHelperService>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import BaseLayer from 'ol/layer/Base';
|
|
2
|
+
import Map from 'ol/Map';
|
|
3
|
+
import { LayerSelectorGroup } from '../models/profile';
|
|
4
|
+
import { ILayer } from '../models/ILayer';
|
|
5
|
+
export declare class LayerHelperService {
|
|
6
|
+
private readonly _layerDbIdKey;
|
|
7
|
+
private readonly _layerGroupDbIdKey;
|
|
8
|
+
private readonly _mapFilteredLayerGroupsKeyName;
|
|
9
|
+
private readonly _layerIdsToDisplayInMapKeyName;
|
|
10
|
+
setDbId(layer: BaseLayer, id: number): void;
|
|
11
|
+
getDbId(layer: BaseLayer): number;
|
|
12
|
+
setLayerGroupDbId(layer: BaseLayer, id: number): void;
|
|
13
|
+
getLayerGroupDbId(layer: BaseLayer): number;
|
|
14
|
+
applyCachedLayersToDisplayInMap(map: Map): void;
|
|
15
|
+
toggleLayer(map: Map, layer: ILayer, filteredLayerGroups: LayerSelectorGroup[]): void;
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@regionerne/gis-komponent",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/common": "^19.2.0",
|
|
6
|
-
"@angular/core": "^19.2.0"
|
|
6
|
+
"@angular/core": "^19.2.0",
|
|
7
|
+
"@angular/material": "^19.2.0",
|
|
8
|
+
"@nieuwlandgeo/sldreader": "0.7.2",
|
|
9
|
+
"ol": "^10.5.0",
|
|
10
|
+
"proj4": "^2.19.10",
|
|
11
|
+
"rxjs": "~7.8.0"
|
|
7
12
|
},
|
|
8
13
|
"dependencies": {
|
|
9
14
|
"tslib": "^2.3.0"
|
package/public-api.d.ts
CHANGED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import * as i0 from "@angular/core";
|
|
2
|
-
export declare class GisKomponentComponent {
|
|
3
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<GisKomponentComponent, never>;
|
|
4
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<GisKomponentComponent, "gis-komponent", never, {}, {}, never, never, true, never>;
|
|
5
|
-
}
|