@igo2/geo 20.1.0-next.15 → 20.1.0-next.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, DOCUMENT, Injectable, Optional, input, model, Component, output, ChangeDetectorRef, ChangeDetectionStrategy, HostBinding, viewChildren, signal, effect, Directive, contentChild, TemplateRef, HostListener, Input, ApplicationRef, NgModule, Pipe, computed, viewChild, ElementRef, Self, EventEmitter, Output, ViewEncapsulation, Inject, Injector, InjectionToken, provideAppInitializer, makeEnvironmentProviders, APP_INITIALIZER } from '@angular/core';
2
+ import { inject, DOCUMENT, Injectable, Optional, input, output, Component, ChangeDetectorRef, computed, ChangeDetectionStrategy, HostBinding, viewChildren, signal, model, effect, DestroyRef, Directive, viewChild, contentChild, TemplateRef, HostListener, Input, ApplicationRef, NgModule, Pipe, ElementRef, Self, EventEmitter, Output, ViewEncapsulation, Inject, Injector, InjectionToken, provideAppInitializer, makeEnvironmentProviders, APP_INITIALIZER } from '@angular/core';
3
3
  import { Clipboard } from '@angular/cdk/clipboard';
4
4
  import * as i1 from '@angular/material/button';
5
5
  import { MatButtonModule } from '@angular/material/button';
6
6
  import * as i3 from '@angular/material/icon';
7
- import { MatIconModule } from '@angular/material/icon';
7
+ import { MatIconModule, MatIconRegistry } from '@angular/material/icon';
8
8
  import * as i2 from '@angular/material/tooltip';
9
9
  import { MatTooltipModule } from '@angular/material/tooltip';
10
10
  import { LanguageService, IgoLanguageModule } from '@igo2/core/language';
@@ -111,29 +111,31 @@ import * as olproj4 from 'ol/proj/proj4';
111
111
  import proj4 from 'proj4';
112
112
  import * as i2$1 from '@angular/material/checkbox';
113
113
  import { MatCheckboxModule } from '@angular/material/checkbox';
114
+ import { toSignal, toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
114
115
  import * as i4$4 from '@angular/material/badge';
115
116
  import { MatBadgeModule } from '@angular/material/badge';
117
+ import { DomSanitizer } from '@angular/platform-browser';
118
+ import { IgoBadgeIconDirective } from '@igo2/common/badge';
116
119
  import { IgoIconComponent, VECTOR_SQUARE_ICON, KEYBOARD_ESC_ICON, ENGINE_ICON } from '@igo2/common/icon';
117
- import { NetworkService } from '@igo2/core/network';
118
- import { CollapseDirective, CollapsibleComponent } from '@igo2/common/collapsible';
119
- import { SanitizeHtmlPipe, CustomHtmlComponent } from '@igo2/common/custom-html';
120
+ import { stylefunction } from 'ol-mapbox-style';
120
121
  import { optionsFromCapabilities } from 'ol/source/WMTS.js';
121
122
  import { Cacheable } from 'ts-cacheable';
122
- import { ListComponent, ListItemDirective } from '@igo2/common/list';
123
- import { stylefunction } from 'ol-mapbox-style';
123
+ import { NetworkService } from '@igo2/core/network';
124
124
  import olLayerImage from 'ol/layer/Image';
125
125
  import olLayerTile from 'ol/layer/Tile';
126
126
  import olLayerVectorTile from 'ol/layer/VectorTile';
127
127
  import { Group } from 'ol/layer.js';
128
128
  import { SelectionModel } from '@angular/cdk/collections';
129
+ import { CollapseDirective, CollapsibleComponent } from '@igo2/common/collapsible';
130
+ import { SanitizeHtmlPipe, CustomHtmlComponent } from '@igo2/common/custom-html';
131
+ import { ListComponent, ListItemDirective } from '@igo2/common/list';
129
132
  import * as i3$2 from '@angular/material/menu';
130
133
  import { MatMenuModule } from '@angular/material/menu';
131
134
  import { FormDialogService, FormComponent, IgoFormDialogModule, FormService, FormFieldComponent, IgoFormFieldComponent } from '@igo2/common/form';
132
- import { FlatTreeControl, NestedTreeControl } from '@angular/cdk/tree';
133
135
  import * as i6 from '@angular/material/slider';
134
136
  import { MatSliderModule, MatSlider } from '@angular/material/slider';
135
137
  import * as i8 from '@angular/material/tree';
136
- import { MatTreeFlattener, MatTreeFlatDataSource, MatTreeModule, MatTreeNestedDataSource } from '@angular/material/tree';
138
+ import { MatTree, MatTreeModule, MatTreeNestedDataSource } from '@angular/material/tree';
137
139
  import { TreeDragDropDirective, DragAndDropDirective } from '@igo2/common/drag-drop';
138
140
  import { PanelComponent } from '@igo2/common/panel';
139
141
  import olGeolocation from 'ol/Geolocation';
@@ -158,13 +160,13 @@ import { MatChipsModule } from '@angular/material/chips';
158
160
  import * as i8$1 from '@angular/material/radio';
159
161
  import { MatRadioModule } from '@angular/material/radio';
160
162
  import { DOMService } from '@igo2/common/dom';
163
+ import { NestedTreeControl } from '@angular/cdk/tree';
161
164
  import * as i6$1 from '@angular/material/table';
162
165
  import { MatTableModule } from '@angular/material/table';
163
166
  import OlOverlay from 'ol/Overlay';
164
167
  import * as i2$3 from '@angular/material/dialog';
165
168
  import { MatDialogRef, MAT_DIALOG_DATA, MatDialogTitle, MatDialogContent, MatDialogActions, MatDialogClose, MatDialog, MatDialogModule } from '@angular/material/dialog';
166
169
  import { Document } from 'flexsearch';
167
- import { DomSanitizer } from '@angular/platform-browser';
168
170
  import OlDraw from 'ol/interaction/Draw';
169
171
  import OlModify from 'ol/interaction/Modify';
170
172
  import OlSelect from 'ol/interaction/Select';
@@ -181,7 +183,6 @@ import * as i2$2 from '@mat-datetimepicker/core';
181
183
  import { MatDatetimepickerModule, MatNativeDatetimeModule } from '@mat-datetimepicker/core';
182
184
  import { ConfirmDialogService } from '@igo2/common/confirm-dialog';
183
185
  import { SpinnerComponent } from '@igo2/common/spinner';
184
- import { IgoBadgeIconDirective } from '@igo2/common/badge';
185
186
  import { StopPropagationDirective } from '@igo2/common/stop-propagation';
186
187
  import Circle from 'ol/style/Circle';
187
188
  import Fill from 'ol/style/Fill';
@@ -3319,6 +3320,83 @@ function handleFilterDate(filter, interfaceOgc, saveableInterface) {
3319
3320
  }
3320
3321
  });
3321
3322
  }
3323
+ function isOgcFilterableDataSourceOptions(dataSourceOptions) {
3324
+ return 'ogcFilters' in dataSourceOptions;
3325
+ }
3326
+ function isTimeFilterableDataSourceOptions(datasourceOption) {
3327
+ return 'timeFilter' in datasourceOption;
3328
+ }
3329
+ function getFilterBadge(dataSourceOptions) {
3330
+ if (!isOgcFilterableDataSourceOptions(dataSourceOptions) &&
3331
+ !isTimeFilterableDataSourceOptions(dataSourceOptions)) {
3332
+ return undefined;
3333
+ }
3334
+ let cnt = 0;
3335
+ if (isOgcFilterableDataSourceOptions(dataSourceOptions) &&
3336
+ dataSourceOptions.ogcFilters) {
3337
+ cnt += getOGCFilterBadge(dataSourceOptions.ogcFilters) ?? 0;
3338
+ }
3339
+ if (isTimeFilterableDataSourceOptions(dataSourceOptions) &&
3340
+ dataSourceOptions.timeFilter) {
3341
+ cnt += getTimeFilterBadge(dataSourceOptions) ?? 0;
3342
+ }
3343
+ return cnt > 0 ? cnt : undefined;
3344
+ }
3345
+ function getOGCFilterBadge(options) {
3346
+ if (!options)
3347
+ return undefined;
3348
+ let cnt = 0;
3349
+ if (!options.advancedOgcFilters) {
3350
+ cnt += countOgcActiveSelectors(options);
3351
+ }
3352
+ else if (options.filters) {
3353
+ cnt +=
3354
+ isIgoLogicalArray(options.filters) &&
3355
+ Array.isArray(options.filters.filters)
3356
+ ? options.filters.filters.length
3357
+ : 1;
3358
+ }
3359
+ if (options.filters && options.interfaceOgcFilters) {
3360
+ cnt += countOgcActiveInterface(options);
3361
+ }
3362
+ return cnt || undefined;
3363
+ }
3364
+ function countOgcActiveSelectors(options) {
3365
+ return OgcSelectorFields.reduce((total, field) => {
3366
+ const selectorField = options[field];
3367
+ if (!selectorField)
3368
+ return total;
3369
+ const activeGroup = selectorField.groups.find((group) => group.enabled);
3370
+ if (!activeGroup)
3371
+ return total;
3372
+ const activatedCount = (activeGroup.computedSelectors ?? []).reduce((sum, selectorGroup) => sum +
3373
+ (selectorGroup.selectors?.filter((button) => button.enabled).length ??
3374
+ 0), 0);
3375
+ return total + activatedCount;
3376
+ }, 0);
3377
+ }
3378
+ function countOgcActiveInterface(options) {
3379
+ return options.interfaceOgcFilters.reduce((cnt, interfaceOgc) => {
3380
+ const layerFilter = searchFilter(options.filters, 'propertyName', interfaceOgc.propertyName);
3381
+ if (layerFilter &&
3382
+ isOgcFilterDuringOptions(layerFilter) &&
3383
+ interfaceOgc.active) {
3384
+ return cnt + (interfaceOgc.begin || interfaceOgc.end ? 1 : 0);
3385
+ }
3386
+ return cnt;
3387
+ }, 0);
3388
+ }
3389
+ function getTimeFilterBadge(timeFilterableOptions) {
3390
+ if (timeFilterableOptions.timeFilterable &&
3391
+ timeFilterableOptions.timeFilter &&
3392
+ timeFilterableOptions.timeFilter.value &&
3393
+ timeFilterableOptions.timeFilter.enabled) {
3394
+ return 1;
3395
+ }
3396
+ else {
3397
+ return undefined;
3398
+ }
3399
+ }
3322
3400
 
3323
3401
  class WFSDataSource extends DataSource {
3324
3402
  options;
@@ -5153,6 +5231,13 @@ class LayerBase {
5153
5231
  }
5154
5232
  _visible$ = new BehaviorSubject(undefined);
5155
5233
  visible$ = this._visible$.asObservable();
5234
+ get parent() {
5235
+ return this.parent$.value;
5236
+ }
5237
+ set parent(parent) {
5238
+ this.parent$.next(parent);
5239
+ }
5240
+ parent$ = new BehaviorSubject(undefined);
5156
5241
  get displayed() {
5157
5242
  return this._displayed$.value;
5158
5243
  }
@@ -5170,6 +5255,7 @@ class LayerBase {
5170
5255
  }
5171
5256
  get saveableOptions() {
5172
5257
  return {
5258
+ id: this.id,
5173
5259
  title: this.options.title,
5174
5260
  zIndex: this.zIndex,
5175
5261
  visible: this.visible,
@@ -5769,6 +5855,14 @@ class Linked {
5769
5855
  });
5770
5856
  this.enable(LinkedProperties.ZINDEX);
5771
5857
  }
5858
+ display() {
5859
+ // Some child doesn't have a z-index and may be hidden by the main layer.
5860
+ this.children.forEach((link) => {
5861
+ if (link.options.zIndex == null) {
5862
+ link.zIndex = (this.layer.zIndex ?? 1) + 1;
5863
+ }
5864
+ });
5865
+ }
5772
5866
  disable(...properties) {
5773
5867
  properties.forEach((property) => {
5774
5868
  if (this.disabledProperties.includes(property)) {
@@ -5873,7 +5967,6 @@ let Layer = class Layer extends LayerBase {
5873
5967
  options;
5874
5968
  messageService;
5875
5969
  authInterceptor;
5876
- parent;
5877
5970
  ol;
5878
5971
  hasBeenVisible$ = new BehaviorSubject(undefined);
5879
5972
  legend;
@@ -5894,6 +5987,9 @@ let Layer = class Layer extends LayerBase {
5894
5987
  .filter((m) => m.options?.showOnEachLayerVisibility)
5895
5988
  .map((message) => this.showMessage(message));
5896
5989
  }
5990
+ if (value && this.link) {
5991
+ this.link.display();
5992
+ }
5897
5993
  value ? this.dataSource.addEvents() : this.dataSource.removeEvents();
5898
5994
  }
5899
5995
  get maxResolution() {
@@ -5924,6 +6020,9 @@ let Layer = class Layer extends LayerBase {
5924
6020
  this.options = options;
5925
6021
  this.messageService = messageService;
5926
6022
  this.authInterceptor = authInterceptor;
6023
+ if (!options.id) {
6024
+ options.id = uuid();
6025
+ }
5927
6026
  this.dataSource = options.source;
5928
6027
  this.legendCollapsed = options.legendOptions
5929
6028
  ? options.legendOptions.collapsed
@@ -8446,10 +8545,10 @@ class DirectionsButtonsComponent {
8446
8545
  routeService = inject(RouteService, { optional: true });
8447
8546
  directionsService = inject(DirectionsService);
8448
8547
  contextUri = input.required(...(ngDevMode ? [{ debugName: "contextUri" }] : []));
8449
- zoomOnActiveRoute = model.required(...(ngDevMode ? [{ debugName: "zoomOnActiveRoute" }] : []));
8450
8548
  stopsStore = input.required(...(ngDevMode ? [{ debugName: "stopsStore" }] : []));
8451
8549
  routesFeatureStore = input.required(...(ngDevMode ? [{ debugName: "routesFeatureStore" }] : []));
8452
8550
  stepsFeatureStore = input.required(...(ngDevMode ? [{ debugName: "stepsFeatureStore" }] : []));
8551
+ zoomOnActiveRoute = output();
8453
8552
  downloadDirectionsBtnDisabled = false;
8454
8553
  /**
8455
8554
  * Returns the active route from the routesFeatureStore.
@@ -8468,13 +8567,6 @@ class DirectionsButtonsComponent {
8468
8567
  resetStops() {
8469
8568
  this.stopsStore().clearStops();
8470
8569
  }
8471
- /**
8472
- * Triggers the zoom on the active route.
8473
- *
8474
- */
8475
- setZoomOnActiveRoute() {
8476
- this.zoomOnActiveRoute.set(true);
8477
- }
8478
8570
  /**
8479
8571
  * Copies the directions to the clipboard and displays a success message if the copy is successful.
8480
8572
  *
@@ -8628,12 +8720,12 @@ class DirectionsButtonsComponent {
8628
8720
  return;
8629
8721
  }
8630
8722
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DirectionsButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8631
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.18", type: DirectionsButtonsComponent, isStandalone: true, selector: "igo-directions-buttons", inputs: { contextUri: { classPropertyName: "contextUri", publicName: "contextUri", isSignal: true, isRequired: true, transformFunction: null }, zoomOnActiveRoute: { classPropertyName: "zoomOnActiveRoute", publicName: "zoomOnActiveRoute", isSignal: true, isRequired: true, transformFunction: null }, stopsStore: { classPropertyName: "stopsStore", publicName: "stopsStore", isSignal: true, isRequired: true, transformFunction: null }, routesFeatureStore: { classPropertyName: "routesFeatureStore", publicName: "routesFeatureStore", isSignal: true, isRequired: true, transformFunction: null }, stepsFeatureStore: { classPropertyName: "stepsFeatureStore", publicName: "stepsFeatureStore", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { zoomOnActiveRoute: "zoomOnActiveRouteChange" }, ngImport: i0, template: "<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.resetStops' | translate\"\n color=\"warn\"\n (click)=\"resetStops()\"\n>\n <mat-icon>restart_alt</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.zoomOnRoute' | translate\"\n color=\"primary\"\n (click)=\"setZoomOnActiveRoute()\"\n>\n <mat-icon>frame_inspect</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyDirections' | translate\"\n color=\"primary\"\n (click)=\"copyDirectionsToClipboard()\"\n>\n <mat-icon>content_copy</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyLink' | translate\"\n color=\"primary\"\n (click)=\"copyLinkToClipboard()\"\n>\n <mat-icon>link</mat-icon>\n</button>\n\n<button\n mat-icon-button\n [disabled]=\"downloadDirectionsBtnDisabled\"\n [matTooltip]=\"'igo.geo.directions.buttons.downloadDirections' | translate\"\n color=\"primary\"\n (click)=\"downloadDirections()\"\n>\n <mat-icon>download</mat-icon>\n</button>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] });
8723
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.18", type: DirectionsButtonsComponent, isStandalone: true, selector: "igo-directions-buttons", inputs: { contextUri: { classPropertyName: "contextUri", publicName: "contextUri", isSignal: true, isRequired: true, transformFunction: null }, stopsStore: { classPropertyName: "stopsStore", publicName: "stopsStore", isSignal: true, isRequired: true, transformFunction: null }, routesFeatureStore: { classPropertyName: "routesFeatureStore", publicName: "routesFeatureStore", isSignal: true, isRequired: true, transformFunction: null }, stepsFeatureStore: { classPropertyName: "stepsFeatureStore", publicName: "stepsFeatureStore", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { zoomOnActiveRoute: "zoomOnActiveRoute" }, ngImport: i0, template: "<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.resetStops' | translate\"\n color=\"warn\"\n (click)=\"resetStops()\"\n>\n <mat-icon>restart_alt</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.zoomOnRoute' | translate\"\n color=\"primary\"\n (click)=\"zoomOnActiveRoute.emit()\"\n>\n <mat-icon>frame_inspect</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyDirections' | translate\"\n color=\"primary\"\n (click)=\"copyDirectionsToClipboard()\"\n>\n <mat-icon>content_copy</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyLink' | translate\"\n color=\"primary\"\n (click)=\"copyLinkToClipboard()\"\n>\n <mat-icon>link</mat-icon>\n</button>\n\n<button\n mat-icon-button\n [disabled]=\"downloadDirectionsBtnDisabled\"\n [matTooltip]=\"'igo.geo.directions.buttons.downloadDirections' | translate\"\n color=\"primary\"\n (click)=\"downloadDirections()\"\n>\n <mat-icon>download</mat-icon>\n</button>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] });
8632
8724
  }
8633
8725
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DirectionsButtonsComponent, decorators: [{
8634
8726
  type: Component,
8635
- args: [{ selector: 'igo-directions-buttons', imports: [MatButtonModule, MatTooltipModule, MatIconModule, IgoLanguageModule], template: "<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.resetStops' | translate\"\n color=\"warn\"\n (click)=\"resetStops()\"\n>\n <mat-icon>restart_alt</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.zoomOnRoute' | translate\"\n color=\"primary\"\n (click)=\"setZoomOnActiveRoute()\"\n>\n <mat-icon>frame_inspect</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyDirections' | translate\"\n color=\"primary\"\n (click)=\"copyDirectionsToClipboard()\"\n>\n <mat-icon>content_copy</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyLink' | translate\"\n color=\"primary\"\n (click)=\"copyLinkToClipboard()\"\n>\n <mat-icon>link</mat-icon>\n</button>\n\n<button\n mat-icon-button\n [disabled]=\"downloadDirectionsBtnDisabled\"\n [matTooltip]=\"'igo.geo.directions.buttons.downloadDirections' | translate\"\n color=\"primary\"\n (click)=\"downloadDirections()\"\n>\n <mat-icon>download</mat-icon>\n</button>\n" }]
8636
- }], propDecorators: { contextUri: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextUri", required: true }] }], zoomOnActiveRoute: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomOnActiveRoute", required: true }] }, { type: i0.Output, args: ["zoomOnActiveRouteChange"] }], stopsStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "stopsStore", required: true }] }], routesFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "routesFeatureStore", required: true }] }], stepsFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepsFeatureStore", required: true }] }] } });
8727
+ args: [{ selector: 'igo-directions-buttons', imports: [MatButtonModule, MatTooltipModule, MatIconModule, IgoLanguageModule], template: "<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.resetStops' | translate\"\n color=\"warn\"\n (click)=\"resetStops()\"\n>\n <mat-icon>restart_alt</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.zoomOnRoute' | translate\"\n color=\"primary\"\n (click)=\"zoomOnActiveRoute.emit()\"\n>\n <mat-icon>frame_inspect</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyDirections' | translate\"\n color=\"primary\"\n (click)=\"copyDirectionsToClipboard()\"\n>\n <mat-icon>content_copy</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyLink' | translate\"\n color=\"primary\"\n (click)=\"copyLinkToClipboard()\"\n>\n <mat-icon>link</mat-icon>\n</button>\n\n<button\n mat-icon-button\n [disabled]=\"downloadDirectionsBtnDisabled\"\n [matTooltip]=\"'igo.geo.directions.buttons.downloadDirections' | translate\"\n color=\"primary\"\n (click)=\"downloadDirections()\"\n>\n <mat-icon>download</mat-icon>\n</button>\n" }]
8728
+ }], propDecorators: { contextUri: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextUri", required: true }] }], stopsStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "stopsStore", required: true }] }], routesFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "routesFeatureStore", required: true }] }], stepsFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepsFeatureStore", required: true }] }], zoomOnActiveRoute: [{ type: i0.Output, args: ["zoomOnActiveRoute"] }] } });
8637
8729
 
8638
8730
  class DirectionsInputsComponent {
8639
8731
  languageService = inject(LanguageService);
@@ -9043,178 +9135,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
9043
9135
  ], template: "@if (routes && activeRoute) {\n <div class=\"igo-input-container\">\n @if (routes.length > 1) {\n <mat-form-field [matTooltip]=\"activeRoute.title\">\n <mat-label>{{\n 'igo.geo.directions.results.routeOptions' | translate\n }}</mat-label>\n <mat-select\n (selectionChange)=\"chooseRouteOption()\"\n [(ngModel)]=\"activeRoute\"\n >\n @for (route of routes; track route; let routeIndex = $index) {\n <mat-option [value]=\"route\">\n Option {{ routeIndex + 1 }}: {{ route.title }} ({{\n formatDistance(route.distance)\n }}\n - {{ formatDuration(route.duration) }})\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n <h4 mat-header class=\"igo-route-title\">\n {{ activeRoute.title }}\n {{ getTitleDurationAndDistance() }}\n </h4>\n <mat-list (mouseleave)=\"onLeaveList()\">\n @for (step of activeRoute.steps; track step; let stepIndex = $index) {\n @if (\n (formatDistance(step.distance) && formatDuration(step.duration)) ||\n stepIndex === activeRoute.steps.length - 1\n ) {\n <mat-list-item\n matListItem\n class=\"igo-steps step\"\n (mouseenter)=\"showStep(step)\"\n (click)=\"showStep(step, true)\"\n >\n <mat-icon\n matListItemIcon\n [matTooltip]=\"\n 'igo.geo.directions.results.stepTitleTooltip' | translate\n \"\n >{{ getFormattedStep(step, stepIndex).iconName }}\n </mat-icon>\n <span\n matListItemTitle\n class=\"step-title\"\n [matTooltip]=\"getFormattedStep(step, stepIndex).instruction\"\n >\n {{ getFormattedStep(step, stepIndex).instruction }}\n </span>\n @if (stepIndex !== activeRoute.steps.length - 1) {\n <span matListItemLine>\n {{ formatDistance(step.distance) }} -\n {{ formatDuration(step.duration) }}\n </span>\n }\n </mat-list-item>\n }\n }\n </mat-list>\n </div>\n}\n", styles: [".igo-input-container{width:100%;padding:20px 10px;box-sizing:border-box}.igo-input-container mat-form-field{width:100%}.igo-route-title{font-weight:700;margin:0}.step{cursor:pointer}mat-list-item.igo-steps:hover{background-color:var(--mat-sys-primary-container)}\n"] }]
9044
9136
  }], propDecorators: { routesFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "routesFeatureStore", required: true }] }], stepsFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepsFeatureStore", required: true }] }] } });
9045
9137
 
9046
- const EYE_CLOSE_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>eye-closed</title><path d="M12 17.5C8.2 17.5 4.8 15.4 3.2 12H1C2.7 16.4 7 19.5 12 19.5S21.3 16.4 23 12H20.8C19.2 15.4 15.8 17.5 12 17.5Z" /></svg>`;
9047
- class LayerVisibilityButtonComponent {
9048
- cdr = inject(ChangeDetectorRef);
9049
- eyeClosedSvg = {
9050
- name: 'eye-closed',
9051
- svg: EYE_CLOSE_SVG
9052
- };
9053
- hiddenByParent;
9054
- visible;
9055
- layer = input.required(...(ngDevMode ? [{ debugName: "layer" }] : []));
9056
- tooltip = input(undefined, ...(ngDevMode ? [{ debugName: "tooltip" }] : []));
9057
- disabled = input(undefined, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
9058
- showQueryBadge = input(undefined, ...(ngDevMode ? [{ debugName: "showQueryBadge" }] : []));
9059
- inResolutionsRange = input(undefined, ...(ngDevMode ? [{ debugName: "inResolutionsRange" }] : []));
9060
- get defaultTooltip() {
9061
- const layer = this.layer();
9062
- return !layer.isInResolutionsRange
9063
- ? 'igo.geo.layer.notInResolution'
9064
- : layer.visible && this.disabled()
9065
- ? 'igo.geo.layer.group.hideChildren'
9066
- : layer.visible
9067
- ? 'igo.geo.layer.hideLayer'
9068
- : 'igo.geo.layer.showLayer';
9069
- }
9070
- visibilityChange = output();
9071
- ngOnInit() {
9072
- this.layer().parent?.displayed$.subscribe((displayed) => {
9073
- this.hiddenByParent = !displayed;
9074
- this.cdr.markForCheck();
9075
- });
9076
- this.layer().visible$.subscribe((visible) => {
9077
- this.visible = visible;
9078
- this.cdr.markForCheck();
9079
- });
9080
- }
9081
- toggle(event) {
9082
- this.layer().visible = !this.layer().visible;
9083
- this.visibilityChange.emit(event);
9084
- }
9085
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerVisibilityButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9086
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.18", type: LayerVisibilityButtonComponent, isStandalone: true, selector: "igo-layer-visibility-button", inputs: { layer: { classPropertyName: "layer", publicName: "layer", isSignal: true, isRequired: true, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showQueryBadge: { classPropertyName: "showQueryBadge", publicName: "showQueryBadge", isSignal: true, isRequired: false, transformFunction: null }, inResolutionsRange: { classPropertyName: "inResolutionsRange", publicName: "inResolutionsRange", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visibilityChange: "visibilityChange" }, ngImport: i0, template: "<button\n mat-icon-button\n [ngClass]=\"{\n disabled: disabled(),\n 'out-of-range': !inResolutionsRange(),\n 'visibility-hidden': !visible\n }\"\n [color]=\"visible ? 'primary' : 'default'\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"tooltip() ?? defaultTooltip | translate\"\n (click)=\"toggle($event)\"\n>\n <igo-icon\n matBadge=\"?\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"after\"\n [matBadgeHidden]=\"!showQueryBadge()\"\n [icon]=\"\n visible\n ? hiddenByParent\n ? eyeClosedSvg\n : 'visibility'\n : 'visibility_off'\n \"\n iconPositionEnd\n />\n</button>\n", styles: [":host .disabled.out-of-range,:host .visibility-hidden.out-of-range{opacity:.44}:host ::ng-deep button.mat-default mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}:host ::ng-deep button.out-of-range mat-icon,:host ::ng-deep button.disabled mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}mat-icon[matBadge] ::ng-deep .mat-badge-content{font-size:12px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i4$4.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "component", type: IgoIconComponent, selector: "igo-icon", inputs: ["color", "icon"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9087
- }
9088
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerVisibilityButtonComponent, decorators: [{
9089
- type: Component,
9090
- args: [{ selector: 'igo-layer-visibility-button', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
9091
- NgClass,
9092
- MatBadgeModule,
9093
- MatButtonModule,
9094
- MatIconModule,
9095
- MatTooltipModule,
9096
- IgoLanguageModule,
9097
- IgoIconComponent
9098
- ], template: "<button\n mat-icon-button\n [ngClass]=\"{\n disabled: disabled(),\n 'out-of-range': !inResolutionsRange(),\n 'visibility-hidden': !visible\n }\"\n [color]=\"visible ? 'primary' : 'default'\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"tooltip() ?? defaultTooltip | translate\"\n (click)=\"toggle($event)\"\n>\n <igo-icon\n matBadge=\"?\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"after\"\n [matBadgeHidden]=\"!showQueryBadge()\"\n [icon]=\"\n visible\n ? hiddenByParent\n ? eyeClosedSvg\n : 'visibility'\n : 'visibility_off'\n \"\n iconPositionEnd\n />\n</button>\n", styles: [":host .disabled.out-of-range,:host .visibility-hidden.out-of-range{opacity:.44}:host ::ng-deep button.mat-default mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}:host ::ng-deep button.out-of-range mat-icon,:host ::ng-deep button.disabled mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}mat-icon[matBadge] ::ng-deep .mat-badge-content{font-size:12px}\n"] }]
9099
- }], propDecorators: { layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "layer", required: true }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showQueryBadge: [{ type: i0.Input, args: [{ isSignal: true, alias: "showQueryBadge", required: false }] }], inResolutionsRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "inResolutionsRange", required: false }] }], visibilityChange: [{ type: i0.Output, args: ["visibilityChange"] }] } });
9100
-
9101
- class LayerGroupComponent {
9102
- layer = input(undefined, ...(ngDevMode ? [{ debugName: "layer" }] : []));
9103
- viewerOptions = input(undefined, ...(ngDevMode ? [{ debugName: "viewerOptions" }] : []));
9104
- selected = input(undefined, ...(ngDevMode ? [{ debugName: "selected" }] : []));
9105
- selectionDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "selectionDisabled" }] : []));
9106
- action = output();
9107
- visibilityChange = output();
9108
- expand = output();
9109
- selectChange = output();
9110
- isDisabled;
9111
- get title() {
9112
- return this.layer().title;
9113
- }
9114
- get collapsed() {
9115
- return this.layer().collapsed;
9116
- }
9117
- set collapsed(value) {
9118
- this.layer().collapsed = value;
9119
- }
9120
- get tooltipMessage() {
9121
- const layer = this.layer();
9122
- return !layer.isInResolutionsRange
9123
- ? 'igo.geo.layer.notInResolution'
9124
- : layer.visible && this.isDisabled
9125
- ? 'igo.geo.layer.group.hideChildren'
9126
- : layer.visible
9127
- ? 'igo.geo.layer.group.hide'
9128
- : 'igo.geo.layer.group.show';
9129
- }
9130
- ngOnInit() {
9131
- this.layer().displayed$.subscribe((displayed) => {
9132
- this.isDisabled = !displayed;
9133
- });
9134
- }
9135
- onToggle() {
9136
- this.collapsed = !this.collapsed;
9137
- }
9138
- toggleVisibility(event) {
9139
- event.stopPropagation();
9140
- this.visibilityChange.emit(event);
9138
+ let ImageWatcher = class ImageWatcher extends Watcher {
9139
+ messageService;
9140
+ id;
9141
+ loaded = 0;
9142
+ loading = 0;
9143
+ source;
9144
+ constructor(layer, messageService) {
9145
+ super();
9146
+ this.messageService = messageService;
9147
+ this.source = layer.options.source.ol;
9148
+ this.id = uuid();
9141
9149
  }
9142
- toggleLayerGroupTool(event) {
9143
- event.stopPropagation();
9144
- this.action.emit(this.layer());
9150
+ watch() {
9151
+ this.source.on(`imageloadstart`, (e) => this.handleLoadStart(e));
9152
+ this.source.on(`imageloadend`, (e) => this.handleLoadEnd(e));
9153
+ this.source.on(`imageloaderror`, (e) => this.handleLoadEnd(e));
9154
+ this.source.on(`imageloaderror`, (e) => this.handleLoadError(e));
9145
9155
  }
9146
- toggleLayerTool(layer) {
9147
- this.action.emit(layer);
9156
+ unwatch() {
9157
+ this.source.un(`imageloadstart`, (e) => this.handleLoadStart(e));
9158
+ this.source.un(`imageloadend`, (e) => this.handleLoadEnd(e));
9159
+ this.source.un(`imageloaderror`, (e) => this.handleLoadEnd(e));
9160
+ this.source.un(`imageloaderror`, (e) => this.handleLoadError(e));
9148
9161
  }
9149
- handleExpand() {
9150
- // TODO: The 'emit' function requires a mandatory void argument
9151
- this.expand.emit();
9162
+ handleLoadStart(event) {
9163
+ if (!event.image.__watchers__) {
9164
+ event.image.__watchers__ = [];
9165
+ }
9166
+ event.image.__watchers__.push(this.id);
9167
+ this.loading += 1;
9168
+ this.status = SubjectStatus.Working;
9152
9169
  }
9153
- handleSelect(event) {
9154
- this.selectChange.emit(event.checked);
9170
+ handleLoadEnd(event) {
9171
+ if (!event.image.__watchers__) {
9172
+ return;
9173
+ }
9174
+ const watcherIndex = event.image.__watchers__.indexOf(this.id);
9175
+ if (watcherIndex < 0) {
9176
+ return;
9177
+ }
9178
+ event.image.__watchers__.splice(watcherIndex, 1);
9179
+ this.loaded += 1;
9180
+ const loading = this.loading;
9181
+ if (this.loaded >= loading) {
9182
+ if (loading === this.loading) {
9183
+ this.status = SubjectStatus.Done;
9184
+ this.loaded = this.loading = 0;
9185
+ }
9186
+ }
9155
9187
  }
9156
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9157
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: LayerGroupComponent, isStandalone: true, selector: "igo-layer-group", inputs: { layer: { classPropertyName: "layer", publicName: "layer", isSignal: true, isRequired: false, transformFunction: null }, viewerOptions: { classPropertyName: "viewerOptions", publicName: "viewerOptions", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, selectionDisabled: { classPropertyName: "selectionDisabled", publicName: "selectionDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action", visibilityChange: "visibilityChange", expand: "expand", selectChange: "selectChange" }, host: { properties: { "class.disabled": "this.isDisabled" } }, ngImport: i0, template: "<div class=\"layer-content\">\n <ng-content />\n\n @if (viewerOptions().mode === 'selection') {\n <mat-checkbox\n [checked]=\"selected()\"\n [disabled]=\"selectionDisabled()\"\n (change)=\"handleSelect($event)\"\n />\n }\n <span class=\"igo-layer-title\" (click)=\"handleExpand()\">{{\n layer().title\n }}</span>\n</div>\n\n<div class=\"list-actions\">\n <div class=\"list-secondary-actions\">\n <button\n class=\"actions-button\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.moreOptions' | translate\"\n mat-icon-button\n color=\"primary\"\n (click)=\"toggleLayerGroupTool($event)\"\n >\n <mat-icon>more_horiz</mat-icon>\n </button>\n </div>\n\n <igo-layer-visibility-button\n [layer]=\"layer()\"\n [disabled]=\"isDisabled\"\n [tooltip]=\"tooltipMessage\"\n [inResolutionsRange]=\"layer().isInResolutionsRange$ | async\"\n (visibilityChange)=\"toggleVisibility($event)\"\n />\n</div>\n", styles: [":host ::ng-deep .list-secondary-actions button{visibility:hidden}:host ::ng-deep .list-secondary-actions button.disabled{visibility:visible}:host:hover ::ng-deep .list-secondary-actions button{visibility:visible}:host.disabled ::ng-deep .igo-layer-title,:host.disabled ::ng-deep .list-secondary-actions{opacity:.54}:host{display:flex;align-items:center;justify-content:space-between;background-color:var(--mat-sys-surface)}:host ::ng-deep button.mat-default mat-icon{color:var(--mat-sys-on-surface);fill:var(--mat-sys-on-surface)}:host ::ng-deep button.disabled mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}.igo-layer-title{flex:1;font-weight:700;cursor:pointer;max-height:48px;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;box-orient:vertical;-webkit-box-orient:vertical;line-clamp:2;-webkit-line-clamp:2}.layer-browser-group-carret{margin-right:10px}.layer-content{display:flex;align-items:center;flex:1}.list-actions{display:flex;margin-left:4px;margin-right:4px}.child-list{padding-left:26px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i2$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: LayerVisibilityButtonComponent, selector: "igo-layer-visibility-button", inputs: ["layer", "tooltip", "disabled", "showQueryBadge", "inResolutionsRange"], outputs: ["visibilityChange"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9158
- }
9159
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerGroupComponent, decorators: [{
9160
- type: Component,
9161
- args: [{ selector: 'igo-layer-group', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
9162
- AsyncPipe,
9163
- MatButtonModule,
9164
- MatCheckboxModule,
9165
- MatTooltipModule,
9166
- MatIconModule,
9167
- LayerVisibilityButtonComponent,
9168
- IgoLanguageModule
9169
- ], template: "<div class=\"layer-content\">\n <ng-content />\n\n @if (viewerOptions().mode === 'selection') {\n <mat-checkbox\n [checked]=\"selected()\"\n [disabled]=\"selectionDisabled()\"\n (change)=\"handleSelect($event)\"\n />\n }\n <span class=\"igo-layer-title\" (click)=\"handleExpand()\">{{\n layer().title\n }}</span>\n</div>\n\n<div class=\"list-actions\">\n <div class=\"list-secondary-actions\">\n <button\n class=\"actions-button\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.moreOptions' | translate\"\n mat-icon-button\n color=\"primary\"\n (click)=\"toggleLayerGroupTool($event)\"\n >\n <mat-icon>more_horiz</mat-icon>\n </button>\n </div>\n\n <igo-layer-visibility-button\n [layer]=\"layer()\"\n [disabled]=\"isDisabled\"\n [tooltip]=\"tooltipMessage\"\n [inResolutionsRange]=\"layer().isInResolutionsRange$ | async\"\n (visibilityChange)=\"toggleVisibility($event)\"\n />\n</div>\n", styles: [":host ::ng-deep .list-secondary-actions button{visibility:hidden}:host ::ng-deep .list-secondary-actions button.disabled{visibility:visible}:host:hover ::ng-deep .list-secondary-actions button{visibility:visible}:host.disabled ::ng-deep .igo-layer-title,:host.disabled ::ng-deep .list-secondary-actions{opacity:.54}:host{display:flex;align-items:center;justify-content:space-between;background-color:var(--mat-sys-surface)}:host ::ng-deep button.mat-default mat-icon{color:var(--mat-sys-on-surface);fill:var(--mat-sys-on-surface)}:host ::ng-deep button.disabled mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}.igo-layer-title{flex:1;font-weight:700;cursor:pointer;max-height:48px;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;box-orient:vertical;-webkit-box-orient:vertical;line-clamp:2;-webkit-line-clamp:2}.layer-browser-group-carret{margin-right:10px}.layer-content{display:flex;align-items:center;flex:1}.list-actions{display:flex;margin-left:4px;margin-right:4px}.child-list{padding-left:26px}\n"] }]
9170
- }], propDecorators: { layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "layer", required: false }] }], viewerOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewerOptions", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], selectionDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionDisabled", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], visibilityChange: [{ type: i0.Output, args: ["visibilityChange"] }], expand: [{ type: i0.Output, args: ["expand"] }], selectChange: [{ type: i0.Output, args: ["selectChange"] }], isDisabled: [{
9171
- type: HostBinding,
9172
- args: ['class.disabled']
9173
- }] } });
9174
-
9175
- /**
9176
- * Whether a layer is queryable
9177
- * @param layer Layer
9178
- * @returns True if the layer s squeryable
9179
- */
9180
- function layerIsQueryable(layer) {
9181
- if (isLayerGroup(layer)) {
9182
- return false;
9188
+ handleLoadError(event) {
9189
+ if (!event.image.__watchers__) {
9190
+ return;
9191
+ }
9192
+ this.messageService?.error('igo.geo.dataSource.unavailable', 'igo.geo.dataSource.unavailableTitle', undefined, { value: event.target.params_.LAYERS });
9193
+ this.loaded = -1;
9194
+ this.loading = 0;
9195
+ this.status = SubjectStatus.Error;
9183
9196
  }
9184
- const dataSource = layer.dataSource;
9185
- return dataSource.options.queryable === true;
9186
- }
9187
- /**
9188
- * Whether an OL layer is queryable
9189
- * @param layer Layer
9190
- * @returns True if the ol layer is queryable
9191
- */
9192
- function olLayerIsQueryable(olLayer) {
9193
- const layer = olLayer.get('_layer');
9194
- return layer === undefined ? false : layerIsQueryable(layer);
9195
- }
9196
- /**
9197
- * Whether a layer's feature is queryable
9198
- * @param layer Layer
9199
- * @returns True if the layer's feature is queryable
9200
- */
9201
- function layerFeatureIsQueryable(layer) {
9202
- const dataSource = layer.dataSource;
9203
- return dataSource.options.queryLayerFeatures !== undefined
9204
- ? dataSource.options.queryLayerFeatures === true
9205
- : true;
9206
- }
9207
- /**
9208
- * Whether an OL Vector layer is queryable
9209
- * @param layer Layer
9210
- * @returns True if the ol vector layer is queryable
9211
- */
9212
- function olLayerFeatureIsQueryable(olLayer) {
9213
- const layer = olLayer.get('_layer');
9214
- return layer === undefined
9215
- ? false
9216
- : layerIsQueryable(layer) && layerFeatureIsQueryable(layer);
9217
- }
9197
+ };
9198
+ ImageWatcher = __decorate([
9199
+ __param(1, Optional()),
9200
+ __metadata("design:paramtypes", [Function, MessageService])
9201
+ ], ImageWatcher);
9218
9202
 
9219
9203
  var TimeFilterType;
9220
9204
  (function (TimeFilterType) {
@@ -10054,626 +10038,166 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
10054
10038
  }]
10055
10039
  }], propDecorators: { getArcgisOptions: [], getImageArcgisOptions: [], getTileArcgisOptions: [], getCapabilities: [] } });
10056
10040
 
10057
- class LayerLegendComponent {
10041
+ class OptionsService {
10042
+ }
10043
+
10044
+ class DataSourceService {
10058
10045
  capabilitiesService = inject(CapabilitiesService);
10046
+ optionsService = inject(OptionsService, { optional: true });
10047
+ wfsDataSourceService = inject(WFSService);
10048
+ ogcFilterService = inject(OGCFilterService);
10059
10049
  languageService = inject(LanguageService);
10060
- cdRef = inject(ChangeDetectorRef);
10061
- config = inject(ConfigService);
10062
- http = inject(HttpClient);
10063
- updateLegendOnResolutionChange = input(false, ...(ngDevMode ? [{ debugName: "updateLegendOnResolutionChange" }] : []));
10064
- /**
10065
- * Observable of the legend items
10066
- */
10067
- legendItems$ = new BehaviorSubject([]);
10068
- /**
10069
- * Subscription to the map's resolution
10070
- */
10071
- state$$;
10072
- /**
10073
- * The available styles
10074
- */
10075
- styles;
10076
- /**
10077
- * The style used to make the legend
10078
- */
10079
- currentStyle;
10080
- /**
10081
- * The extent used to make the legend
10082
- */
10083
- view = undefined;
10084
- /**
10085
- * Get list of images display
10086
- */
10087
- renderedLegends = viewChildren('renderedLegend', ...(ngDevMode ? [{ debugName: "renderedLegends" }] : []));
10088
- /**
10089
- * List of size of images displayed
10090
- */
10091
- imagesHeight = {};
10092
- layer = input(undefined, ...(ngDevMode ? [{ debugName: "layer" }] : []));
10093
- /**
10094
- * if getLegendGraphic is authorized
10095
- */
10096
- getLegend = true;
10097
- /**
10098
- * On init, subscribe to the map's resolution and update the legend accordingly
10099
- */
10100
- ngOnInit() {
10101
- let lastlLegend = this.layer().legend;
10102
- this.styles = this.listStyles();
10103
- const sourceOptions = this.layer().options.source.options;
10104
- if (sourceOptions && sourceOptions.params && sourceOptions.params.STYLES) {
10105
- // if a styles is provided into the layers wms params
10106
- this.currentStyle = this.styles.find((style) => style.name === sourceOptions.params.STYLES).name;
10050
+ messageService = inject(MessageService);
10051
+ authInterceptor = inject(AuthInterceptor);
10052
+ datasources$ = new BehaviorSubject([]);
10053
+ createAsyncDataSource(options, detailedContextUri) {
10054
+ if (!options.type) {
10055
+ console.error(options);
10056
+ throw new Error('Datasource needs a type');
10107
10057
  }
10108
- else if (!lastlLegend) {
10109
- // if no legend is manually provided
10110
- if (this.styles && this.styles.length > 1) {
10111
- this.currentStyle = this.styles[0].name;
10058
+ let dataSource;
10059
+ switch (options.type.toLowerCase()) {
10060
+ case 'osm':
10061
+ dataSource = this.createOSMDataSource(options);
10062
+ break;
10063
+ case 'vector':
10064
+ dataSource = this.createFeatureDataSource(options);
10065
+ break;
10066
+ case 'wfs':
10067
+ dataSource = this.createWFSDataSource(options);
10068
+ break;
10069
+ case 'wms': {
10070
+ const wmsContext = options;
10071
+ ObjectUtils.removeDuplicateCaseInsensitive(wmsContext.params);
10072
+ dataSource = this.createWMSDataSource(wmsContext, detailedContextUri);
10073
+ break;
10112
10074
  }
10075
+ case 'wmts':
10076
+ dataSource = this.createWMTSDataSource(options);
10077
+ break;
10078
+ case 'xyz':
10079
+ dataSource = this.createXYZDataSource(options);
10080
+ break;
10081
+ case 'tiledebug':
10082
+ dataSource = this.createTileDebugDataSource(options);
10083
+ break;
10084
+ case 'carto':
10085
+ dataSource = this.createCartoDataSource(options);
10086
+ break;
10087
+ case 'arcgisrest':
10088
+ dataSource = this.createArcGISRestDataSource(options, detailedContextUri);
10089
+ break;
10090
+ case 'imagearcgisrest':
10091
+ dataSource = this.createArcGISRestImageDataSource(options, detailedContextUri);
10092
+ break;
10093
+ case 'websocket':
10094
+ dataSource = this.createWebSocketDataSource(options);
10095
+ break;
10096
+ case 'mvt':
10097
+ dataSource = this.createMVTDataSource(options);
10098
+ break;
10099
+ case 'tilearcgisrest':
10100
+ dataSource = this.createTileArcGISRestDataSource(options, detailedContextUri);
10101
+ break;
10102
+ case 'cluster':
10103
+ dataSource = this.createClusterDataSource(options);
10104
+ break;
10105
+ default:
10106
+ console.error(options);
10107
+ throw new Error('Invalid datasource type');
10113
10108
  }
10114
- else if (this.styles && this.styles.length > 1) {
10115
- this.currentStyle = lastlLegend[0].currentStyle;
10116
- }
10117
- const layer = this.layer();
10118
- if (typeof layer.options.legendOptions !== 'undefined' &&
10119
- layer.options.legendOptions.display === false) {
10120
- lastlLegend = [];
10121
- }
10122
- else {
10123
- lastlLegend = layer.dataSource.getLegend(this.currentStyle, this.view);
10109
+ this.datasources$.next(this.datasources$.value.concat([dataSource]));
10110
+ return dataSource;
10111
+ }
10112
+ createOSMDataSource(options) {
10113
+ return new Observable((d) => d.next(new OSMDataSource(options)));
10114
+ }
10115
+ createFeatureDataSource(options) {
10116
+ return new Observable((d) => d.next(new FeatureDataSource(options)));
10117
+ }
10118
+ createWebSocketDataSource(options) {
10119
+ return new Observable((d) => d.next(new WebSocketDataSource(options)));
10120
+ }
10121
+ createWFSDataSource(options) {
10122
+ return new Observable((d) => d.next(new WFSDataSource(options, this.wfsDataSourceService, this.ogcFilterService, this.authInterceptor)));
10123
+ }
10124
+ createWMSDataSource(options, detailedContextUri) {
10125
+ const observables = [];
10126
+ if (options.optionsFromCapabilities && window.navigator.onLine) {
10127
+ observables.push(this.capabilitiesService.getWMSOptions(options).pipe(catchError$1((e) => {
10128
+ this.messageService.error('igo.geo.dataSource.unavailable', 'igo.geo.dataSource.unavailableTitle', undefined, { value: options.params.LAYERS });
10129
+ throw e;
10130
+ })));
10124
10131
  }
10125
- if (this.updateLegendOnResolutionChange() ||
10126
- sourceOptions.contentDependentLegend) {
10127
- const state$ = layer.map.viewController.state$;
10128
- this.state$$ = state$.subscribe(() => this.onViewControllerStateChange());
10132
+ if (this.optionsService &&
10133
+ options.optionsFromApi &&
10134
+ window.navigator.onLine) {
10135
+ observables.push(this.optionsService.getWMSOptions(options, detailedContextUri).pipe(catchError$1((e) => {
10136
+ e.error.toDisplay = true;
10137
+ e.error.title = this.languageService.translate.instant('igo.geo.dataSource.unavailableTitle');
10138
+ e.error.message = this.languageService.translate.instant('igo.geo.dataSource.optionsApiUnavailable');
10139
+ return of({});
10140
+ })));
10129
10141
  }
10130
- else if (lastlLegend && lastlLegend.length !== 0) {
10131
- this.legendItems$.next(lastlLegend);
10132
- for (const legend of lastlLegend) {
10133
- this.getLegendGraphic(legend);
10142
+ observables.push(of(options));
10143
+ return forkJoin(observables).pipe(map((options) => {
10144
+ const optionsMerged = options.reduce((a, b) => ObjectUtils.mergeDeep(a, b));
10145
+ if (optionsMerged?.params) {
10146
+ optionsMerged.params = this.normalizeParams(optionsMerged.params);
10134
10147
  }
10135
- }
10148
+ return new WMSDataSource(optionsMerged, this.wfsDataSourceService, this.ogcFilterService);
10149
+ }), catchError$1(() => {
10150
+ return of(undefined);
10151
+ }));
10136
10152
  }
10137
- /**
10138
- * On destroy, unsubscribe to the map's view state
10139
- */
10140
- ngOnDestroy() {
10141
- if (this.state$$ !== undefined) {
10142
- this.state$$.unsubscribe();
10153
+ normalizeParams(params) {
10154
+ const uppercasedParams = {};
10155
+ for (const key in params) {
10156
+ if (Object.prototype.hasOwnProperty.call(params, key)) {
10157
+ uppercasedParams[key.toUpperCase()] = params[key];
10158
+ }
10143
10159
  }
10160
+ return uppercasedParams;
10144
10161
  }
10145
- getLegendGraphic(item) {
10146
- if (item.url) {
10147
- const depotUrl = this.config?.getConfig('depot.url');
10148
- fetchImageFromDepotUrl(item.url, depotUrl, this.http)
10149
- .pipe(catchError$1((err) => {
10150
- if (err.error) {
10151
- err.error.caught = true;
10152
- this.getLegend = false;
10153
- this.cdRef.detectChanges();
10154
- return err;
10155
- }
10156
- }))
10157
- .subscribe((obsLegGraph) => {
10158
- const idx = this.legendItems$.value.findIndex((leg) => leg.title === item.title);
10159
- const legendGraph = obsLegGraph;
10160
- this.legendItems$.value[idx].imgGraphValue = legendGraph;
10161
- this.cdRef.detectChanges();
10162
- });
10162
+ createWMTSDataSource(options) {
10163
+ if (options.optionsFromCapabilities && window.navigator.onLine) {
10164
+ return this.capabilitiesService.getWMTSOptions(options).pipe(map((options) => {
10165
+ return options ? new WMTSDataSource(options) : undefined;
10166
+ }), catchError$1(() => {
10167
+ this.messageService.error('igo.geo.dataSource.unavailable', 'igo.geo.dataSource.unavailableTitle', undefined, { value: options.layer });
10168
+ return of(undefined);
10169
+ }));
10163
10170
  }
10171
+ return new Observable((d) => d.next(new WMTSDataSource(options)));
10164
10172
  }
10165
- toggleLegendItem(collapsed, item) {
10166
- item.collapsed = collapsed;
10173
+ createXYZDataSource(options) {
10174
+ return new Observable((d) => d.next(new XYZDataSource(options)));
10167
10175
  }
10168
- transfertToggleLegendItem(newLegends) {
10169
- const outLegends = newLegends;
10170
- const lastLegends = this.layer().legend;
10171
- for (let i = 0; i < lastLegends.length; i++) {
10172
- outLegends[i].collapsed = lastLegends[i].collapsed;
10173
- }
10174
- return outLegends;
10176
+ createTileDebugDataSource(options) {
10177
+ return new Observable((d) => d.next(new TileDebugDataSource(options)));
10175
10178
  }
10176
- computeItemTitle(layerLegend) {
10177
- const layerOptions = this.layer().dataSource.options;
10178
- if (layerOptions.type !== 'wms') {
10179
- return of(layerLegend.title);
10179
+ createCartoDataSource(options) {
10180
+ if (options.mapId) {
10181
+ return this.capabilitiesService
10182
+ .getCartoOptions(options)
10183
+ .pipe(map((options) => new CartoDataSource(options)));
10180
10184
  }
10181
- const layers = layerOptions.params.LAYERS.split(',');
10182
- const localLayerOptions = JSON.parse(JSON.stringify(layerOptions)); // to avoid to alter the original options.
10183
- localLayerOptions.params.LAYERS = layers.find((layer) => layer === layerLegend.title);
10184
- return this.capabilitiesService.getWMSOptions(localLayerOptions).pipe(map((wmsDataSourceOptions) => {
10185
- return wmsDataSourceOptions._layerOptionsFromSource.title;
10186
- }));
10187
- }
10188
- /**
10189
- * On resolution change, compute the effective scale level and update the
10190
- * legend accordingly.
10191
- * @param resolution Map resolution
10192
- */
10193
- onViewControllerStateChange() {
10194
- this.view = {
10195
- resolution: this.layer().map.viewController.getResolution(),
10196
- extent: this.layer().map.viewController.getExtent(),
10197
- projection: this.layer().map.viewController.getOlProjection().getCode(),
10198
- scale: this.layer().map.viewController.getScale(),
10199
- size: this.layer().map.ol.getSize()
10200
- };
10201
- this.updateLegend();
10185
+ return new Observable((d) => d.next(new CartoDataSource(options)));
10202
10186
  }
10203
- /**
10204
- * Update the legend with scale level and style define
10205
- */
10206
- updateLegend() {
10207
- let legendItems = this.layer().dataSource.getLegend(this.currentStyle, this.view);
10208
- const layer = this.layer();
10209
- if (layer.legend && layer.legend.length > 1) {
10210
- legendItems = this.transfertToggleLegendItem(legendItems);
10211
- }
10212
- layer.legend = legendItems;
10213
- if (legendItems.length === 0 && this.legendItems$.value.length === 0) {
10214
- return;
10215
- }
10216
- this.legendItems$.next(legendItems);
10217
- for (const legend of this.legendItems$.value) {
10218
- this.getLegendGraphic(legend);
10219
- }
10220
- }
10221
- listStyles() {
10222
- const layerOptions = this.layer().options;
10223
- if (layerOptions && layerOptions.legendOptions) {
10224
- const translate = this.languageService.translate;
10225
- const title = translate.instant('igo.geo.layer.legend.default');
10226
- let stylesAvailable = [{ name: '', title }];
10227
- if (layerOptions.legendOptions.stylesAvailable) {
10228
- stylesAvailable = stylesAvailable.concat(layerOptions.legendOptions.stylesAvailable.filter((sA) => sA.name.normalize('NFD').replace(/[\u0300-\u036f]/gi, '') !==
10229
- 'default' &&
10230
- sA.name.normalize('NFD').replace(/[\u0300-\u036f]/gi, '') !==
10231
- 'defaut'));
10232
- }
10233
- stylesAvailable
10234
- .filter((sa) => !sa.title)
10235
- .map((sa) => (sa.title = sa.name));
10236
- stylesAvailable.map((s) => (s.title =
10237
- s.title.charAt(0).toUpperCase() +
10238
- s.title.slice(1).replace(/_/g, ' ')));
10239
- return stylesAvailable;
10240
- }
10241
- return;
10242
- }
10243
- onChangeStyle() {
10244
- this.updateLegend();
10245
- let STYLES = '';
10246
- const layer = this.layer();
10247
- if (layer.dataSource instanceof WMSDataSource) {
10248
- layer.dataSource.ol
10249
- .getParams()
10250
- .LAYERS.split(',')
10251
- .map(() => (STYLES += this.currentStyle + ','));
10252
- STYLES = STYLES.slice(0, -1);
10253
- layer.dataSource.stylesParams = STYLES;
10254
- }
10255
- }
10256
- onLoadImage(id) {
10257
- let elemRef;
10258
- const renderedLegends = this.renderedLegends();
10259
- if (renderedLegends.length === 1) {
10260
- elemRef = renderedLegends.at(0).nativeElement;
10261
- }
10262
- else {
10263
- elemRef = renderedLegends.find((renderedLegend) => renderedLegend.nativeElement.id === id).nativeElement;
10264
- }
10265
- this.imagesHeight[id] = elemRef.height;
10266
- }
10267
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerLegendComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10268
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: LayerLegendComponent, isStandalone: true, selector: "igo-layer-legend", inputs: { updateLegendOnResolutionChange: { classPropertyName: "updateLegendOnResolutionChange", publicName: "updateLegendOnResolutionChange", isSignal: true, isRequired: false, transformFunction: null }, layer: { classPropertyName: "layer", publicName: "layer", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "renderedLegends", predicate: ["renderedLegend"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (legendItems$ | async; as items) {\n @if (items.length) {\n @for (item of items.slice().reverse(); track item) {\n <ng-container #renderedLegends>\n @if (getLegend) {\n <div>\n @if (item.title) {\n <mat-list-item>\n <mat-icon\n id=\"legend-toggle\"\n class=\"igo-chevron\"\n matListItemIcon\n igoCollapse\n [target]=\"legend\"\n [collapsed]=\"item.collapsed\"\n (toggle)=\"toggleLegendItem($event, item)\"\n >expand_less\n </mat-icon>\n <span matListItemTitle\n >{{ computeItemTitle(item) | async }}\n </span>\n </mat-list-item>\n }\n <div\n #legend\n class=\"igo-layer-legend\"\n [ngClass]=\"{ 'with-title': item.title }\"\n >\n @if (currentStyle !== undefined) {\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-select\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n 'igo.geo.layer.legend.selectStyle' | translate\n \"\n [(ngModel)]=\"currentStyle\"\n (selectionChange)=\"onChangeStyle()\"\n >\n @for (style of styles; track style) {\n <mat-option [value]=\"style.name\">{{\n style.title\n }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n @if (!item.collapsed) {\n <div>\n @if (item.url) {\n <div>\n @if (item.imgGraphValue) {\n <img\n igoImageError\n [hideError]=\"true\"\n #renderedLegend\n id=\"{{ item.title }}\"\n (load)=\"onLoadImage(item.title)\"\n [src]=\"item.imgGraphValue\"\n alt=\"{{\n 'igo.geo.layer.legend.loadingLegendText' | translate\n }}\"\n />\n }\n @if (imagesHeight[item.title] < 16) {\n <small>\n {{ 'igo.geo.layer.legend.noLegendScale' | translate }}\n </small>\n }\n </div>\n }\n @if (item.html) {\n <div\n [ngStyle]=\"item.style\"\n [innerHTML]=\"item.html | sanitizeHtml\"\n ></div>\n }\n </div>\n }\n </div>\n </div>\n } @else {\n <small>\n {{ 'igo.geo.layer.legend.noLegendText' | translate }}\n </small>\n }\n </ng-container>\n }\n } @else {\n <small>\n {{ 'igo.geo.layer.legend.noLegendText' | translate }}\n </small>\n }\n}\n", styles: [":host{--mat-form-field-container-height: 48px;--mat-form-field-container-vertical-padding: 12px}@-moz-document url-prefix(){:host img:after{margin-left:19px}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.igo-layer-legend.with-title{padding-left:18px}img{max-width:100%}img:after{content:\" \";position:relative;height:17px;float:left;width:17px;top:-3px;right:19px;background-color:#fff;border:3px solid #f3f3f3;border-radius:50%;border-top-color:var(--mat-sys-primary-container);animation:2s linear infinite spin}mat-form-field{margin-bottom:4px}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "component", type: i1$2.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i1$2.MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "directive", type: i1$2.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: CollapseDirective, selector: "[igoCollapse]", inputs: ["target", "collapsed"], outputs: ["toggle"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "directive", type: ImageErrorDirective, selector: "[igoImageError]", inputs: ["errorImageUrl", "hideError"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: SanitizeHtmlPipe, name: "sanitizeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10269
- }
10270
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerLegendComponent, decorators: [{
10271
- type: Component,
10272
- args: [{ selector: 'igo-layer-legend', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
10273
- MatListModule,
10274
- MatIconModule,
10275
- CollapseDirective,
10276
- NgClass,
10277
- MatFormFieldModule,
10278
- MatSelectModule,
10279
- MatTooltipModule,
10280
- FormsModule,
10281
- MatOptionModule,
10282
- ImageErrorDirective,
10283
- NgStyle,
10284
- AsyncPipe,
10285
- IgoLanguageModule,
10286
- SanitizeHtmlPipe
10287
- ], template: "@if (legendItems$ | async; as items) {\n @if (items.length) {\n @for (item of items.slice().reverse(); track item) {\n <ng-container #renderedLegends>\n @if (getLegend) {\n <div>\n @if (item.title) {\n <mat-list-item>\n <mat-icon\n id=\"legend-toggle\"\n class=\"igo-chevron\"\n matListItemIcon\n igoCollapse\n [target]=\"legend\"\n [collapsed]=\"item.collapsed\"\n (toggle)=\"toggleLegendItem($event, item)\"\n >expand_less\n </mat-icon>\n <span matListItemTitle\n >{{ computeItemTitle(item) | async }}\n </span>\n </mat-list-item>\n }\n <div\n #legend\n class=\"igo-layer-legend\"\n [ngClass]=\"{ 'with-title': item.title }\"\n >\n @if (currentStyle !== undefined) {\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-select\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n 'igo.geo.layer.legend.selectStyle' | translate\n \"\n [(ngModel)]=\"currentStyle\"\n (selectionChange)=\"onChangeStyle()\"\n >\n @for (style of styles; track style) {\n <mat-option [value]=\"style.name\">{{\n style.title\n }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n @if (!item.collapsed) {\n <div>\n @if (item.url) {\n <div>\n @if (item.imgGraphValue) {\n <img\n igoImageError\n [hideError]=\"true\"\n #renderedLegend\n id=\"{{ item.title }}\"\n (load)=\"onLoadImage(item.title)\"\n [src]=\"item.imgGraphValue\"\n alt=\"{{\n 'igo.geo.layer.legend.loadingLegendText' | translate\n }}\"\n />\n }\n @if (imagesHeight[item.title] < 16) {\n <small>\n {{ 'igo.geo.layer.legend.noLegendScale' | translate }}\n </small>\n }\n </div>\n }\n @if (item.html) {\n <div\n [ngStyle]=\"item.style\"\n [innerHTML]=\"item.html | sanitizeHtml\"\n ></div>\n }\n </div>\n }\n </div>\n </div>\n } @else {\n <small>\n {{ 'igo.geo.layer.legend.noLegendText' | translate }}\n </small>\n }\n </ng-container>\n }\n } @else {\n <small>\n {{ 'igo.geo.layer.legend.noLegendText' | translate }}\n </small>\n }\n}\n", styles: [":host{--mat-form-field-container-height: 48px;--mat-form-field-container-vertical-padding: 12px}@-moz-document url-prefix(){:host img:after{margin-left:19px}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.igo-layer-legend.with-title{padding-left:18px}img{max-width:100%}img:after{content:\" \";position:relative;height:17px;float:left;width:17px;top:-3px;right:19px;background-color:#fff;border:3px solid #f3f3f3;border-radius:50%;border-top-color:var(--mat-sys-primary-container);animation:2s linear infinite spin}mat-form-field{margin-bottom:4px}\n"] }]
10288
- }], propDecorators: { updateLegendOnResolutionChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "updateLegendOnResolutionChange", required: false }] }], renderedLegends: [{ type: i0.ViewChildren, args: ['renderedLegend', { isSignal: true }] }], layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "layer", required: false }] }] } });
10289
-
10290
- var TooltipType;
10291
- (function (TooltipType) {
10292
- TooltipType["TITLE"] = "title";
10293
- TooltipType["ABSTRACT"] = "abstract";
10294
- TooltipType["CUSTOM"] = "custom";
10295
- })(TooltipType || (TooltipType = {}));
10296
-
10297
- class LayerItemComponent {
10298
- networkService = inject(NetworkService);
10299
- showLegend = signal(true, ...(ngDevMode ? [{ debugName: "showLegend" }] : []));
10300
- inResolutionRange = true;
10301
- queryBadgeHidden = signal(true, ...(ngDevMode ? [{ debugName: "queryBadgeHidden" }] : []));
10302
- tooltipText;
10303
- state;
10304
- resolution$$;
10305
- network$$;
10306
- layer = input.required(...(ngDevMode ? [{ debugName: "layer" }] : []));
10307
- /** Pass the visibility to trigger change detection */
10308
- visible = input.required(...(ngDevMode ? [{ debugName: "visible" }] : []));
10309
- selected = input(undefined, ...(ngDevMode ? [{ debugName: "selected" }] : []));
10310
- selectionDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "selectionDisabled" }] : []));
10311
- viewerOptions = input(undefined, ...(ngDevMode ? [{ debugName: "viewerOptions" }] : []));
10312
- action = output();
10313
- selectChange = output();
10314
- visibilityChange = output();
10315
- isDisabled;
10316
- get opacity() {
10317
- return this.layer().opacity * 100;
10318
- }
10319
- set opacity(opacity) {
10320
- this.layer().opacity = opacity / 100;
10321
- }
10322
- get visibilityTooltip() {
10323
- if (this.viewerOptions().mode !== 'selection' && !this.inResolutionRange) {
10324
- return this.layer().visible
10325
- ? this.isDisabled
10326
- ? 'igo.geo.layer.notInResolution'
10327
- : 'igo.geo.layer.group.hideChildren'
10328
- : 'igo.geo.layer.showLayer';
10329
- }
10330
- return this.layer().visible
10331
- ? this.isDisabled
10332
- ? 'igo.geo.layer.group.hideChildren'
10333
- : 'igo.geo.layer.hideLayer'
10334
- : 'igo.geo.layer.showLayer';
10335
- }
10336
- ngOnInit() {
10337
- this.layer().displayed$.subscribe((displayed) => {
10338
- this.isDisabled = !displayed;
10339
- });
10340
- const layer = this.layer();
10341
- if (layer.visible &&
10342
- this.viewerOptions()?.legend?.showForVisibleLayers &&
10343
- layer.firstLoadComponent === true) {
10344
- layer.firstLoadComponent = false;
10345
- layer.legendCollapsed = false;
10346
- }
10347
- this.toggleLegend(layer.legendCollapsed);
10348
- this.updateQueryBadge();
10349
- const resolution$ = layer.map.viewController.resolution$;
10350
- this.resolution$$ = resolution$.subscribe(() => {
10351
- this.onResolutionChange();
10352
- });
10353
- this.tooltipText = this.computeTooltip();
10354
- this.network$$ = this.networkService
10355
- .currentState()
10356
- .subscribe((state) => {
10357
- this.state = state;
10358
- this.onResolutionChange();
10359
- });
10360
- }
10361
- ngOnDestroy() {
10362
- this.resolution$$?.unsubscribe();
10363
- this.network$$?.unsubscribe();
10364
- }
10365
- toggleLegend(collapsed) {
10366
- this.layer().legendCollapsed = collapsed;
10367
- this.showLegend.set(!collapsed);
10368
- }
10369
- toggleLegendOnClick() {
10370
- this.toggleLegend(this.showLegend());
10371
- }
10372
- handleVisibilityChange(event) {
10373
- event.stopPropagation();
10374
- if (this.viewerOptions().legend?.showOnVisibilityChange) {
10375
- this.toggleLegend(!this.layer().visible);
10376
- }
10377
- this.updateQueryBadge();
10378
- this.visibilityChange.emit(event);
10379
- }
10380
- computeTooltip() {
10381
- const layerOptions = this.layer().options;
10382
- if (!layerOptions.tooltip) {
10383
- return this.layer().title;
10384
- }
10385
- const layerTooltip = layerOptions.tooltip;
10386
- const layerMetadata = layerOptions.metadata;
10387
- switch (layerOptions.tooltip.type) {
10388
- case TooltipType.TITLE:
10389
- return this.layer().title;
10390
- case TooltipType.ABSTRACT:
10391
- if (layerMetadata && layerMetadata.abstract) {
10392
- return layerMetadata.abstract;
10393
- }
10394
- else {
10395
- return this.layer().title;
10396
- }
10397
- case TooltipType.CUSTOM:
10398
- if (layerTooltip && layerTooltip.text) {
10399
- return layerTooltip.text;
10400
- }
10401
- else {
10402
- return this.layer().title;
10403
- }
10404
- default:
10405
- return this.layer().title;
10406
- }
10407
- }
10408
- onResolutionChange() {
10409
- const inResolutionRange = this.layer().isInResolutionsRange;
10410
- if (inResolutionRange === false &&
10411
- this.viewerOptions().legend.updateOnResolutionChange === true) {
10412
- this.toggleLegend(true);
10413
- }
10414
- this.inResolutionRange = inResolutionRange;
10415
- }
10416
- updateQueryBadge() {
10417
- const layer = this.layer();
10418
- const hidden = this.viewerOptions().queryBadge === false ||
10419
- layer.visible === false ||
10420
- !layerIsQueryable(layer);
10421
- this.queryBadgeHidden.set(hidden);
10422
- }
10423
- toggleLayerTool() {
10424
- this.action.emit(this.layer());
10425
- }
10426
- handleSelect(event) {
10427
- this.selectChange.emit(event.checked);
10428
- }
10429
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10430
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: LayerItemComponent, isStandalone: true, selector: "igo-layer-item", inputs: { layer: { classPropertyName: "layer", publicName: "layer", isSignal: true, isRequired: true, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: true, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, selectionDisabled: { classPropertyName: "selectionDisabled", publicName: "selectionDisabled", isSignal: true, isRequired: false, transformFunction: null }, viewerOptions: { classPropertyName: "viewerOptions", publicName: "viewerOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action", selectChange: "selectChange", visibilityChange: "visibilityChange" }, host: { properties: { "class.disabled": "this.isDisabled" } }, ngImport: i0, template: "<div class=\"igo-layer-list-item\">\n <div class=\"layer-content\">\n @if (viewerOptions().mode === 'selection') {\n <mat-checkbox\n [checked]=\"selected()\"\n [disabled]=\"selectionDisabled()\"\n (change)=\"handleSelect($event)\"\n />\n }\n <ng-content />\n <span\n class=\"igo-layer-title\"\n [matTooltip]=\"tooltipText\"\n matTooltipShowDelay=\"500\"\n (click)=\"toggleLegendOnClick()\"\n >\n {{ layer().title }}\n </span>\n </div>\n\n <div class=\"list-actions\">\n <div class=\"list-secondary-actions\">\n @if (viewerOptions().mode !== 'selection') {\n <button\n class=\"actions-button\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.moreOptions' | translate\"\n mat-icon-button\n color=\"primary\"\n (click)=\"toggleLayerTool()\"\n >\n <mat-icon>more_horiz</mat-icon>\n </button>\n }\n </div>\n\n <igo-layer-visibility-button\n [layer]=\"layer()\"\n [tooltip]=\"visibilityTooltip\"\n [disabled]=\"isDisabled\"\n [inResolutionsRange]=\"layer().isInResolutionsRange$ | async\"\n [showQueryBadge]=\"queryBadgeHidden() === false\"\n (visibilityChange)=\"handleVisibilityChange($event)\"\n />\n </div>\n</div>\n\n@if (showLegend()) {\n <div class=\"igo-layer-legend-container\">\n <igo-layer-legend\n [layer]=\"layer()\"\n [updateLegendOnResolutionChange]=\"\n viewerOptions().legend.updateOnResolutionChange\n \"\n />\n </div>\n}\n", styles: [":host ::ng-deep .list-secondary-actions button{visibility:hidden}:host ::ng-deep .list-secondary-actions button.disabled{visibility:visible}:host:hover ::ng-deep .list-secondary-actions button{visibility:visible}:host.disabled ::ng-deep .igo-layer-title,:host.disabled ::ng-deep .list-secondary-actions{opacity:.54}:host{overflow:hidden;background-color:var(--mat-sys-surface)}:host ::ng-deep button.mat-default mat-icon{color:var(--mat-sys-on-surface);fill:var(--mat-sys-on-surface)}:host ::ng-deep button.disabled mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}.list-actions{display:flex;margin-left:4px;margin-right:4px}.layer-content{display:flex;align-items:center;flex:1}.igo-layer-title{display:block;cursor:pointer;max-height:48px;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;box-orient:vertical;-webkit-box-orient:vertical;line-clamp:2;-webkit-line-clamp:2}.igo-layer-list-item{display:flex;align-items:center;justify-content:space-between}.igo-layer-legend-container{padding-top:4px;width:calc(100% - 12px)}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i2$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "component", type: LayerLegendComponent, selector: "igo-layer-legend", inputs: ["updateLegendOnResolutionChange", "layer"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "component", type: LayerVisibilityButtonComponent, selector: "igo-layer-visibility-button", inputs: ["layer", "tooltip", "disabled", "showQueryBadge", "inResolutionsRange"], outputs: ["visibilityChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10431
- }
10432
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerItemComponent, decorators: [{
10433
- type: Component,
10434
- args: [{ selector: 'igo-layer-item', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
10435
- MatListModule,
10436
- MatCheckboxModule,
10437
- MatTooltipModule,
10438
- MatButtonModule,
10439
- MatIconModule,
10440
- MatBadgeModule,
10441
- LayerLegendComponent,
10442
- AsyncPipe,
10443
- IgoLanguageModule,
10444
- LayerVisibilityButtonComponent
10445
- ], template: "<div class=\"igo-layer-list-item\">\n <div class=\"layer-content\">\n @if (viewerOptions().mode === 'selection') {\n <mat-checkbox\n [checked]=\"selected()\"\n [disabled]=\"selectionDisabled()\"\n (change)=\"handleSelect($event)\"\n />\n }\n <ng-content />\n <span\n class=\"igo-layer-title\"\n [matTooltip]=\"tooltipText\"\n matTooltipShowDelay=\"500\"\n (click)=\"toggleLegendOnClick()\"\n >\n {{ layer().title }}\n </span>\n </div>\n\n <div class=\"list-actions\">\n <div class=\"list-secondary-actions\">\n @if (viewerOptions().mode !== 'selection') {\n <button\n class=\"actions-button\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.moreOptions' | translate\"\n mat-icon-button\n color=\"primary\"\n (click)=\"toggleLayerTool()\"\n >\n <mat-icon>more_horiz</mat-icon>\n </button>\n }\n </div>\n\n <igo-layer-visibility-button\n [layer]=\"layer()\"\n [tooltip]=\"visibilityTooltip\"\n [disabled]=\"isDisabled\"\n [inResolutionsRange]=\"layer().isInResolutionsRange$ | async\"\n [showQueryBadge]=\"queryBadgeHidden() === false\"\n (visibilityChange)=\"handleVisibilityChange($event)\"\n />\n </div>\n</div>\n\n@if (showLegend()) {\n <div class=\"igo-layer-legend-container\">\n <igo-layer-legend\n [layer]=\"layer()\"\n [updateLegendOnResolutionChange]=\"\n viewerOptions().legend.updateOnResolutionChange\n \"\n />\n </div>\n}\n", styles: [":host ::ng-deep .list-secondary-actions button{visibility:hidden}:host ::ng-deep .list-secondary-actions button.disabled{visibility:visible}:host:hover ::ng-deep .list-secondary-actions button{visibility:visible}:host.disabled ::ng-deep .igo-layer-title,:host.disabled ::ng-deep .list-secondary-actions{opacity:.54}:host{overflow:hidden;background-color:var(--mat-sys-surface)}:host ::ng-deep button.mat-default mat-icon{color:var(--mat-sys-on-surface);fill:var(--mat-sys-on-surface)}:host ::ng-deep button.disabled mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}.list-actions{display:flex;margin-left:4px;margin-right:4px}.layer-content{display:flex;align-items:center;flex:1}.igo-layer-title{display:block;cursor:pointer;max-height:48px;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;box-orient:vertical;-webkit-box-orient:vertical;line-clamp:2;-webkit-line-clamp:2}.igo-layer-list-item{display:flex;align-items:center;justify-content:space-between}.igo-layer-legend-container{padding-top:4px;width:calc(100% - 12px)}\n"] }]
10446
- }], propDecorators: { layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "layer", required: true }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: true }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], selectionDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionDisabled", required: false }] }], viewerOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewerOptions", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], selectChange: [{ type: i0.Output, args: ["selectChange"] }], visibilityChange: [{ type: i0.Output, args: ["visibilityChange"] }], isDisabled: [{
10447
- type: HostBinding,
10448
- args: ['class.disabled']
10449
- }] } });
10450
-
10451
- class LayerLegendItemComponent {
10452
- networkService = inject(NetworkService);
10453
- inResolutionRange$ = new BehaviorSubject(true);
10454
- tooltipText;
10455
- state;
10456
- resolution$$;
10457
- network$$;
10458
- layer = input(undefined, ...(ngDevMode ? [{ debugName: "layer" }] : []));
10459
- updateLegendOnResolutionChange = input(false, ...(ngDevMode ? [{ debugName: "updateLegendOnResolutionChange" }] : []));
10460
- ngOnInit() {
10461
- const resolution$ = this.layer().map.viewController.resolution$;
10462
- this.resolution$$ = resolution$.subscribe(() => {
10463
- this.onResolutionChange();
10464
- });
10465
- this.tooltipText = this.computeTooltip();
10466
- this.network$$ = this.networkService
10467
- .currentState()
10468
- .subscribe((state) => {
10469
- this.state = state;
10470
- this.onResolutionChange();
10471
- });
10472
- }
10473
- ngOnDestroy() {
10474
- this.resolution$$.unsubscribe();
10475
- this.network$$.unsubscribe();
10476
- }
10477
- computeTooltip() {
10478
- const layerOptions = this.layer().options;
10479
- if (!layerOptions.tooltip) {
10480
- return this.layer().title;
10481
- }
10482
- const layerTooltip = layerOptions.tooltip;
10483
- const layerMetadata = layerOptions.metadata;
10484
- switch (layerOptions.tooltip.type) {
10485
- case TooltipType.TITLE:
10486
- return this.layer().title;
10487
- case TooltipType.ABSTRACT:
10488
- if (layerMetadata && layerMetadata.abstract) {
10489
- return layerMetadata.abstract;
10490
- }
10491
- else {
10492
- return this.layer().title;
10493
- }
10494
- case TooltipType.CUSTOM:
10495
- if (layerTooltip && layerTooltip.text) {
10496
- return layerTooltip.text;
10497
- }
10498
- else {
10499
- return this.layer().title;
10500
- }
10501
- default:
10502
- return this.layer().title;
10503
- }
10504
- }
10505
- onResolutionChange() {
10506
- const inResolutionRange = this.layer().isInResolutionsRange;
10507
- this.inResolutionRange$.next(inResolutionRange);
10508
- }
10509
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerLegendItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10510
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.18", type: LayerLegendItemComponent, isStandalone: true, selector: "igo-layer-legend-item", inputs: { layer: { classPropertyName: "layer", publicName: "layer", isSignal: true, isRequired: false, transformFunction: null }, updateLegendOnResolutionChange: { classPropertyName: "updateLegendOnResolutionChange", publicName: "updateLegendOnResolutionChange", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-list-item class=\"igo-layer-list-item\">\n <span\n matListItemTitle\n class=\"igo-layer-title\"\n [matTooltip]=\"tooltipText\"\n matTooltipShowDelay=\"500\"\n >{{ layer().title }}</span\n >\n</mat-list-item>\n\n<div #legend class=\"igo-layer-legend-container\">\n <igo-layer-legend\n [layer]=\"layer()\"\n [updateLegendOnResolutionChange]=\"updateLegendOnResolutionChange()\"\n />\n</div>\n", styles: [":host{overflow:hidden}:host .igo-layer-list-item{height:48px;clear:both}:host .igo-layer-legend-container{padding-left:18px;width:calc(100% - 18px)}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "component", type: i1$2.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i1$2.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: LayerLegendComponent, selector: "igo-layer-legend", inputs: ["updateLegendOnResolutionChange", "layer"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10511
- }
10512
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerLegendItemComponent, decorators: [{
10513
- type: Component,
10514
- args: [{ selector: 'igo-layer-legend-item', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatListModule, MatTooltipModule, LayerLegendComponent], template: "<mat-list-item class=\"igo-layer-list-item\">\n <span\n matListItemTitle\n class=\"igo-layer-title\"\n [matTooltip]=\"tooltipText\"\n matTooltipShowDelay=\"500\"\n >{{ layer().title }}</span\n >\n</mat-list-item>\n\n<div #legend class=\"igo-layer-legend-container\">\n <igo-layer-legend\n [layer]=\"layer()\"\n [updateLegendOnResolutionChange]=\"updateLegendOnResolutionChange()\"\n />\n</div>\n", styles: [":host{overflow:hidden}:host .igo-layer-list-item{height:48px;clear:both}:host .igo-layer-legend-container{padding-left:18px;width:calc(100% - 18px)}\n"] }]
10515
- }], propDecorators: { layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "layer", required: false }] }], updateLegendOnResolutionChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "updateLegendOnResolutionChange", required: false }] }] } });
10516
-
10517
- let ImageWatcher = class ImageWatcher extends Watcher {
10518
- messageService;
10519
- id;
10520
- loaded = 0;
10521
- loading = 0;
10522
- source;
10523
- constructor(layer, messageService) {
10524
- super();
10525
- this.messageService = messageService;
10526
- this.source = layer.options.source.ol;
10527
- this.id = uuid();
10528
- }
10529
- watch() {
10530
- this.source.on(`imageloadstart`, (e) => this.handleLoadStart(e));
10531
- this.source.on(`imageloadend`, (e) => this.handleLoadEnd(e));
10532
- this.source.on(`imageloaderror`, (e) => this.handleLoadEnd(e));
10533
- this.source.on(`imageloaderror`, (e) => this.handleLoadError(e));
10534
- }
10535
- unwatch() {
10536
- this.source.un(`imageloadstart`, (e) => this.handleLoadStart(e));
10537
- this.source.un(`imageloadend`, (e) => this.handleLoadEnd(e));
10538
- this.source.un(`imageloaderror`, (e) => this.handleLoadEnd(e));
10539
- this.source.un(`imageloaderror`, (e) => this.handleLoadError(e));
10540
- }
10541
- handleLoadStart(event) {
10542
- if (!event.image.__watchers__) {
10543
- event.image.__watchers__ = [];
10544
- }
10545
- event.image.__watchers__.push(this.id);
10546
- this.loading += 1;
10547
- this.status = SubjectStatus.Working;
10548
- }
10549
- handleLoadEnd(event) {
10550
- if (!event.image.__watchers__) {
10551
- return;
10552
- }
10553
- const watcherIndex = event.image.__watchers__.indexOf(this.id);
10554
- if (watcherIndex < 0) {
10555
- return;
10556
- }
10557
- event.image.__watchers__.splice(watcherIndex, 1);
10558
- this.loaded += 1;
10559
- const loading = this.loading;
10560
- if (this.loaded >= loading) {
10561
- if (loading === this.loading) {
10562
- this.status = SubjectStatus.Done;
10563
- this.loaded = this.loading = 0;
10564
- }
10565
- }
10566
- }
10567
- handleLoadError(event) {
10568
- if (!event.image.__watchers__) {
10569
- return;
10570
- }
10571
- this.messageService?.error('igo.geo.dataSource.unavailable', 'igo.geo.dataSource.unavailableTitle', undefined, { value: event.target.params_.LAYERS });
10572
- this.loaded = -1;
10573
- this.loading = 0;
10574
- this.status = SubjectStatus.Error;
10575
- }
10576
- };
10577
- ImageWatcher = __decorate([
10578
- __param(1, Optional()),
10579
- __metadata("design:paramtypes", [Function, MessageService])
10580
- ], ImageWatcher);
10581
-
10582
- class OptionsService {
10583
- }
10584
-
10585
- class DataSourceService {
10586
- capabilitiesService = inject(CapabilitiesService);
10587
- optionsService = inject(OptionsService, { optional: true });
10588
- wfsDataSourceService = inject(WFSService);
10589
- ogcFilterService = inject(OGCFilterService);
10590
- languageService = inject(LanguageService);
10591
- messageService = inject(MessageService);
10592
- authInterceptor = inject(AuthInterceptor);
10593
- datasources$ = new BehaviorSubject([]);
10594
- createAsyncDataSource(options, detailedContextUri) {
10595
- if (!options.type) {
10596
- console.error(options);
10597
- throw new Error('Datasource needs a type');
10598
- }
10599
- let dataSource;
10600
- switch (options.type.toLowerCase()) {
10601
- case 'osm':
10602
- dataSource = this.createOSMDataSource(options);
10603
- break;
10604
- case 'vector':
10605
- dataSource = this.createFeatureDataSource(options);
10606
- break;
10607
- case 'wfs':
10608
- dataSource = this.createWFSDataSource(options);
10609
- break;
10610
- case 'wms': {
10611
- const wmsContext = options;
10612
- ObjectUtils.removeDuplicateCaseInsensitive(wmsContext.params);
10613
- dataSource = this.createWMSDataSource(wmsContext, detailedContextUri);
10614
- break;
10615
- }
10616
- case 'wmts':
10617
- dataSource = this.createWMTSDataSource(options);
10618
- break;
10619
- case 'xyz':
10620
- dataSource = this.createXYZDataSource(options);
10621
- break;
10622
- case 'tiledebug':
10623
- dataSource = this.createTileDebugDataSource(options);
10624
- break;
10625
- case 'carto':
10626
- dataSource = this.createCartoDataSource(options);
10627
- break;
10628
- case 'arcgisrest':
10629
- dataSource = this.createArcGISRestDataSource(options, detailedContextUri);
10630
- break;
10631
- case 'imagearcgisrest':
10632
- dataSource = this.createArcGISRestImageDataSource(options, detailedContextUri);
10633
- break;
10634
- case 'websocket':
10635
- dataSource = this.createWebSocketDataSource(options);
10636
- break;
10637
- case 'mvt':
10638
- dataSource = this.createMVTDataSource(options);
10639
- break;
10640
- case 'tilearcgisrest':
10641
- dataSource = this.createTileArcGISRestDataSource(options, detailedContextUri);
10642
- break;
10643
- case 'cluster':
10644
- dataSource = this.createClusterDataSource(options);
10645
- break;
10646
- default:
10647
- console.error(options);
10648
- throw new Error('Invalid datasource type');
10649
- }
10650
- this.datasources$.next(this.datasources$.value.concat([dataSource]));
10651
- return dataSource;
10652
- }
10653
- createOSMDataSource(options) {
10654
- return new Observable((d) => d.next(new OSMDataSource(options)));
10655
- }
10656
- createFeatureDataSource(options) {
10657
- return new Observable((d) => d.next(new FeatureDataSource(options)));
10658
- }
10659
- createWebSocketDataSource(options) {
10660
- return new Observable((d) => d.next(new WebSocketDataSource(options)));
10661
- }
10662
- createWFSDataSource(options) {
10663
- return new Observable((d) => d.next(new WFSDataSource(options, this.wfsDataSourceService, this.ogcFilterService, this.authInterceptor)));
10664
- }
10665
- createWMSDataSource(options, detailedContextUri) {
10187
+ createArcGISRestDataSource(options, detailedContextUri) {
10666
10188
  const observables = [];
10667
- if (options.optionsFromCapabilities && window.navigator.onLine) {
10668
- observables.push(this.capabilitiesService.getWMSOptions(options).pipe(catchError$1((e) => {
10669
- this.messageService.error('igo.geo.dataSource.unavailable', 'igo.geo.dataSource.unavailableTitle', undefined, { value: options.params.LAYERS });
10189
+ if (window.navigator.onLine) {
10190
+ observables.push(this.capabilitiesService.getArcgisOptions(options).pipe(catchError$1((e) => {
10191
+ this.messageService.error('igo.geo.dataSource.unavailable', 'igo.geo.dataSource.unavailableTitle', undefined, { value: options.layer });
10670
10192
  throw e;
10671
10193
  })));
10672
10194
  }
10673
10195
  if (this.optionsService &&
10674
10196
  options.optionsFromApi &&
10675
10197
  window.navigator.onLine) {
10676
- observables.push(this.optionsService.getWMSOptions(options, detailedContextUri).pipe(catchError$1((e) => {
10198
+ observables.push(this.optionsService
10199
+ .getArcgisRestOptions(options, detailedContextUri)
10200
+ .pipe(catchError$1((e) => {
10677
10201
  e.error.toDisplay = true;
10678
10202
  e.error.title = this.languageService.translate.instant('igo.geo.dataSource.unavailableTitle');
10679
10203
  e.error.message = this.languageService.translate.instant('igo.geo.dataSource.optionsApiUnavailable');
@@ -10683,81 +10207,16 @@ class DataSourceService {
10683
10207
  observables.push(of(options));
10684
10208
  return forkJoin(observables).pipe(map((options) => {
10685
10209
  const optionsMerged = options.reduce((a, b) => ObjectUtils.mergeDeep(a, b));
10686
- if (optionsMerged?.params) {
10687
- optionsMerged.params = this.normalizeParams(optionsMerged.params);
10688
- }
10689
- return new WMSDataSource(optionsMerged, this.wfsDataSourceService, this.ogcFilterService);
10210
+ return new ArcGISRestDataSource(optionsMerged);
10690
10211
  }), catchError$1(() => {
10691
10212
  return of(undefined);
10692
10213
  }));
10693
10214
  }
10694
- normalizeParams(params) {
10695
- const uppercasedParams = {};
10696
- for (const key in params) {
10697
- if (Object.prototype.hasOwnProperty.call(params, key)) {
10698
- uppercasedParams[key.toUpperCase()] = params[key];
10699
- }
10700
- }
10701
- return uppercasedParams;
10702
- }
10703
- createWMTSDataSource(options) {
10704
- if (options.optionsFromCapabilities && window.navigator.onLine) {
10705
- return this.capabilitiesService.getWMTSOptions(options).pipe(map((options) => {
10706
- return options ? new WMTSDataSource(options) : undefined;
10707
- }), catchError$1(() => {
10708
- this.messageService.error('igo.geo.dataSource.unavailable', 'igo.geo.dataSource.unavailableTitle', undefined, { value: options.layer });
10709
- return of(undefined);
10710
- }));
10711
- }
10712
- return new Observable((d) => d.next(new WMTSDataSource(options)));
10713
- }
10714
- createXYZDataSource(options) {
10715
- return new Observable((d) => d.next(new XYZDataSource(options)));
10716
- }
10717
- createTileDebugDataSource(options) {
10718
- return new Observable((d) => d.next(new TileDebugDataSource(options)));
10719
- }
10720
- createCartoDataSource(options) {
10721
- if (options.mapId) {
10722
- return this.capabilitiesService
10723
- .getCartoOptions(options)
10724
- .pipe(map((options) => new CartoDataSource(options)));
10725
- }
10726
- return new Observable((d) => d.next(new CartoDataSource(options)));
10727
- }
10728
- createArcGISRestDataSource(options, detailedContextUri) {
10215
+ createArcGISRestImageDataSource(options, detailedContextUri) {
10729
10216
  const observables = [];
10730
10217
  if (window.navigator.onLine) {
10731
- observables.push(this.capabilitiesService.getArcgisOptions(options).pipe(catchError$1((e) => {
10732
- this.messageService.error('igo.geo.dataSource.unavailable', 'igo.geo.dataSource.unavailableTitle', undefined, { value: options.layer });
10733
- throw e;
10734
- })));
10735
- }
10736
- if (this.optionsService &&
10737
- options.optionsFromApi &&
10738
- window.navigator.onLine) {
10739
- observables.push(this.optionsService
10740
- .getArcgisRestOptions(options, detailedContextUri)
10741
- .pipe(catchError$1((e) => {
10742
- e.error.toDisplay = true;
10743
- e.error.title = this.languageService.translate.instant('igo.geo.dataSource.unavailableTitle');
10744
- e.error.message = this.languageService.translate.instant('igo.geo.dataSource.optionsApiUnavailable');
10745
- return of({});
10746
- })));
10747
- }
10748
- observables.push(of(options));
10749
- return forkJoin(observables).pipe(map((options) => {
10750
- const optionsMerged = options.reduce((a, b) => ObjectUtils.mergeDeep(a, b));
10751
- return new ArcGISRestDataSource(optionsMerged);
10752
- }), catchError$1(() => {
10753
- return of(undefined);
10754
- }));
10755
- }
10756
- createArcGISRestImageDataSource(options, detailedContextUri) {
10757
- const observables = [];
10758
- if (window.navigator.onLine) {
10759
- observables.push(this.capabilitiesService.getImageArcgisOptions(options).pipe(catchError$1((e) => {
10760
- this.messageService.error('igo.geo.dataSource.unavailable', 'igo.geo.dataSource.unavailableTitle', undefined, { value: options.params.LAYERS });
10218
+ observables.push(this.capabilitiesService.getImageArcgisOptions(options).pipe(catchError$1((e) => {
10219
+ this.messageService.error('igo.geo.dataSource.unavailable', 'igo.geo.dataSource.unavailableTitle', undefined, { value: options.params.LAYERS });
10761
10220
  throw e;
10762
10221
  })));
10763
10222
  }
@@ -11384,6 +10843,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
11384
10843
  }]
11385
10844
  }] });
11386
10845
 
10846
+ var TooltipType;
10847
+ (function (TooltipType) {
10848
+ TooltipType["TITLE"] = "title";
10849
+ TooltipType["ABSTRACT"] = "abstract";
10850
+ TooltipType["CUSTOM"] = "custom";
10851
+ })(TooltipType || (TooltipType = {}));
10852
+
11387
10853
  let ImageLayer = class ImageLayer extends Layer {
11388
10854
  messageService;
11389
10855
  authInterceptor;
@@ -11680,7 +11146,6 @@ const ID_GROUP_PREFIX = 'local-group_';
11680
11146
  class LayerGroup extends LayerGroupBase {
11681
11147
  children;
11682
11148
  options;
11683
- parent;
11684
11149
  expanded;
11685
11150
  isInResolutionsRange$$;
11686
11151
  isInResolutionsRange$ = new BehaviorSubject(true);
@@ -12006,10 +11471,7 @@ class LayerService {
12006
11471
  }
12007
11472
  }
12008
11473
  getStuff(url) {
12009
- return this.http.get(url).pipe(map((res) => res), catchError$1((err) => {
12010
- console.log('No style was found');
12011
- return of(err);
12012
- }));
11474
+ return this.http.get(url);
12013
11475
  }
12014
11476
  getAbsoluteUrl(source, url) {
12015
11477
  const r = new RegExp('^http|//', 'i');
@@ -12107,8 +11569,6 @@ class LayerSelectionModel {
12107
11569
  }
12108
11570
  }
12109
11571
 
12110
- // Below 10 is reserved for BaseLayer
12111
- const ZINDEX_MIN = 10;
12112
11572
  /**
12113
11573
  * We got four kind of layers
12114
11574
  * TreeLayer: all layers to show in the layer manager
@@ -12177,7 +11637,8 @@ class LayerController extends LayerSelectionModel {
12177
11637
  // Because the Layer may have have LinkedLayer who need to find the parent.
12178
11638
  this.layersFlattened = [...this.tree.flattened];
12179
11639
  addedLayers.forEach((layer) => layer.add());
12180
- this.recalculateZindex();
11640
+ const baseLayerZindex = this.baseLayer ? 1 : 0;
11641
+ this.recalculateZindex(baseLayerZindex);
12181
11642
  this.notify();
12182
11643
  }
12183
11644
  selectBaseLayer(layer) {
@@ -12188,6 +11649,7 @@ class LayerController extends LayerSelectionModel {
12188
11649
  this.baseLayerSelection.visible = false;
12189
11650
  }
12190
11651
  layer.visible = true;
11652
+ layer.zIndex = 0;
12191
11653
  this.baseLayerSelection = layer;
12192
11654
  this._map.viewController.olView.setMinZoom(layer.dataSource.options.minZoom || (this._map.options.view || {}).minZoom);
12193
11655
  this._map.viewController.olView.setMaxZoom(layer.dataSource.options.maxZoom || (this._map.options.view || {}).maxZoom);
@@ -12293,325 +11755,950 @@ class LayerController extends LayerSelectionModel {
12293
11755
  layers.forEach((layer) => {
12294
11756
  layer.moveTo(keepCurrentParent ? layer.parent : parent);
12295
11757
  });
12296
- this._internalMove();
11758
+ this._internalMove();
11759
+ }
11760
+ _internalMove() {
11761
+ this.recalculateZindex();
11762
+ this.notify();
11763
+ }
11764
+ /** Recursive */
11765
+ recalculateZindex(minIndex = 0, layers = this.treeLayers) {
11766
+ return [...layers].reverse().reduce((previousZindex, layer) => {
11767
+ let zIndex = ++previousZindex;
11768
+ layer.zIndex = zIndex;
11769
+ if (isLayerGroup(layer)) {
11770
+ zIndex = this.recalculateZindex(zIndex, layer.children);
11771
+ }
11772
+ return zIndex;
11773
+ }, minIndex);
11774
+ }
11775
+ handleAdd(layer, offset) {
11776
+ const existingLayer = this.getById(layer.id);
11777
+ if (existingLayer !== undefined) {
11778
+ existingLayer.visible = true;
11779
+ return;
11780
+ }
11781
+ const zIndex = this.getZindexOffset(layer, offset);
11782
+ this.setZindex(layer, zIndex);
11783
+ layer.init(this._map);
11784
+ if (isBaseLayer(layer)) {
11785
+ if (layer.visible) {
11786
+ this.selectBaseLayer(layer);
11787
+ }
11788
+ this._baseLayers.push(layer);
11789
+ }
11790
+ else if (this.isOtherLayer(layer)) {
11791
+ this._otherLayers.push(layer);
11792
+ }
11793
+ else if (this.isSystemLayer(layer) && !layer.showInLayerList) {
11794
+ this._systemLayers.push(layer);
11795
+ }
11796
+ else if (layer.showInLayerList) {
11797
+ return layer;
11798
+ }
11799
+ else {
11800
+ this._otherLayers.push(layer);
11801
+ }
11802
+ const parent = layer.parentId
11803
+ ? this.getById(layer.parentId.toString().split(TREE_SEPERATOR).pop())
11804
+ : undefined;
11805
+ layer.add(parent);
11806
+ return;
11807
+ }
11808
+ _remove(layer) {
11809
+ if (isBaseLayer(layer)) {
11810
+ this.removeBaselayer(layer);
11811
+ }
11812
+ else if (this.isOtherLayer(layer)) {
11813
+ this.removeOtherLayer(layer);
11814
+ }
11815
+ else if (this.isSystemLayer(layer)) {
11816
+ this.removeSystemLayer(layer);
11817
+ }
11818
+ layer.remove();
11819
+ return layer;
11820
+ }
11821
+ removeBaselayer(layer) {
11822
+ this.removeIn(layer, this._baseLayers);
11823
+ }
11824
+ removeSystemLayer(layer) {
11825
+ this.removeIn(layer, this._systemLayers);
11826
+ }
11827
+ removeOtherLayer(layer) {
11828
+ this.removeIn(layer, this._otherLayers);
11829
+ }
11830
+ removeIn(layer, store) {
11831
+ const index = store.findIndex((sysLayer) => sysLayer.id === layer.id);
11832
+ if (index === -1) {
11833
+ return;
11834
+ }
11835
+ store.splice(index, 1);
11836
+ }
11837
+ isSystemLayer(layer) {
11838
+ return isLayerItem(layer) && layer.isIgoInternalLayer;
11839
+ }
11840
+ isOtherLayer(layer) {
11841
+ return isLayerLinked(layer) && !layer.showInLayerList;
11842
+ }
11843
+ clearBaselayers() {
11844
+ this.baseLayers.forEach((layer) => this._remove(layer));
11845
+ this._baseLayers = [];
11846
+ }
11847
+ clearTree() {
11848
+ this.treeLayers.forEach((layer) => this._remove(layer));
11849
+ this.tree.clear();
11850
+ }
11851
+ clearOther() {
11852
+ this._otherLayers.forEach((layer) => this._remove(layer));
11853
+ this._otherLayers = [];
11854
+ }
11855
+ getZindexOffset(layer, previousOffset = 0) {
11856
+ return layer.zIndex ? 0 : previousOffset++;
11857
+ }
11858
+ setZindex(layer, offset) {
11859
+ if (isBaseLayer(layer)) {
11860
+ return;
11861
+ }
11862
+ if (layer.zIndex === undefined || layer.zIndex === 0) {
11863
+ const maxZIndex = Math.max(...this.treeLayers.map((l) => l.zIndex), 0);
11864
+ layer.zIndex = maxZIndex + 1 + (offset ?? 0);
11865
+ }
11866
+ }
11867
+ notify() {
11868
+ this.layersFlattened = [...this.tree.flattened];
11869
+ this._layers$.next([...this.treeLayers]);
11870
+ this._baseLayers$.next([...this.baseLayers]);
11871
+ }
11872
+ }
11873
+
11874
+ function mergeLayersOptions(layersOptionsTree, layersOptions) {
11875
+ const tree = [...layersOptionsTree];
11876
+ layersOptions.forEach((options) => {
11877
+ const identifier = getLayerOptionIdentifier(options);
11878
+ if (!identifier)
11879
+ return;
11880
+ const currentNode = _getNodeById(identifier, tree) ?? _getNodeByTitle(options.title, tree);
11881
+ if (currentNode) {
11882
+ // if we get layer options by title, we update the id of current layer.
11883
+ if (isLayerGroupOptions(currentNode) &&
11884
+ currentNode.id.toString().includes(ID_GROUP_PREFIX)) {
11885
+ currentNode.id = identifier;
11886
+ }
11887
+ const currentNodeParentID = currentNode.parentId ?? findParentId(tree, currentNode);
11888
+ const mergedOptions = ObjectUtils.mergeDeep(currentNode, options);
11889
+ if (currentNodeParentID === options.parentId) {
11890
+ moveOptions(tree, identifier, mergedOptions);
11891
+ }
11892
+ else {
11893
+ // if we have no parent id it means that we are in the root of the tree.
11894
+ if (!options.parentId)
11895
+ mergedOptions.parentId = undefined;
11896
+ const initialIdentifier = getLayerOptionIdentifier(currentNode);
11897
+ moveOptions(tree, initialIdentifier, mergedOptions);
11898
+ }
11899
+ }
11900
+ else {
11901
+ // Some layers in local context doesn't have an id, if this is the case we
11902
+ // check if the layer is already in the tree by its title
11903
+ // and if it is we don't add it again. The changes is ignored
11904
+ if (isLayerGroupOptions(options)) {
11905
+ const currentNode = _getNodeByTitle(options.title, tree);
11906
+ if (currentNode) {
11907
+ return;
11908
+ }
11909
+ }
11910
+ // handel external Data source options
11911
+ if (isLayerItemOptions(options)) {
11912
+ handleExternalDataSource(options);
11913
+ }
11914
+ insertOptions(tree, options);
11915
+ }
11916
+ });
11917
+ return tree;
11918
+ }
11919
+ function handleExternalDataSource(options) {
11920
+ options.sourceOptions = {
11921
+ ...options.sourceOptions,
11922
+ optionsFromCapabilities: true,
11923
+ optionsFromApi: true,
11924
+ crossOrigin: 'anonymous'
11925
+ };
11926
+ }
11927
+ function getLayerOptionIdentifier(layerOptions) {
11928
+ return isLayerGroupOptions(layerOptions)
11929
+ ? String(layerOptions.id)
11930
+ : (getLayerParam(layerOptions) ??
11931
+ (layerOptions.id !== undefined
11932
+ ? layerOptions.id.toString()
11933
+ : undefined));
11934
+ }
11935
+ function moveOptions(tree, initialIdentifier, options) {
11936
+ removeNode(tree, initialIdentifier);
11937
+ insertOptions(tree, options);
11938
+ }
11939
+ function insertOptions(tree, options) {
11940
+ const parentId = options.parentId;
11941
+ if (!parentId) {
11942
+ tree.push(options);
11943
+ }
11944
+ else {
11945
+ const parent = _getNodeById(parentId, tree);
11946
+ if (parent) {
11947
+ (parent.children ??= []).push(options);
11948
+ sortLayersOptionsByZIndex(parent.children);
11949
+ }
11950
+ }
11951
+ }
11952
+ /** Recursive */
11953
+ function _getNodeById(id, data) {
11954
+ let node;
11955
+ data.some((item) => {
11956
+ const identifier = getLayerOptionIdentifier(item);
11957
+ if (identifier === id) {
11958
+ node = item;
11959
+ return true;
11960
+ }
11961
+ const children = isLayerGroupOptions(item) ? item.children : undefined;
11962
+ if (children) {
11963
+ node = _getNodeById(id, children);
11964
+ if (node)
11965
+ return true;
11966
+ }
11967
+ return false;
11968
+ });
11969
+ return node;
11970
+ }
11971
+ /** Recursive */
11972
+ function _getNodeByTitle(title, data) {
11973
+ if (!title)
11974
+ return;
11975
+ let node;
11976
+ data.some((item) => {
11977
+ const itemTitle = item.title;
11978
+ if (itemTitle === title) {
11979
+ node = item;
11980
+ return true;
11981
+ }
11982
+ const children = isLayerGroupOptions(item) ? item.children : undefined;
11983
+ if (children) {
11984
+ node = _getNodeByTitle(title, children);
11985
+ if (node)
11986
+ return true;
11987
+ }
11988
+ return false;
11989
+ });
11990
+ return node;
11991
+ }
11992
+ function removeNode(tree, nodeId) {
11993
+ for (let i = 0; i < tree.length; i++) {
11994
+ const node = tree[i];
11995
+ const currentId = getLayerOptionIdentifier(node);
11996
+ if (currentId === nodeId) {
11997
+ tree.splice(i, 1);
11998
+ return true;
11999
+ }
12000
+ if (isLayerGroupOptions(node) && node.children?.length) {
12001
+ const removed = removeNode(node.children, nodeId);
12002
+ if (removed && node.children.length === 0) {
12003
+ delete node.children;
12004
+ }
12005
+ if (removed)
12006
+ return true;
12007
+ }
12008
+ }
12009
+ return false;
12010
+ }
12011
+ function sortLayersOptionsByZIndex(layers) {
12012
+ layers.sort((a, b) => (a.zIndex ?? 0) - (b.zIndex ?? 0));
12013
+ }
12014
+ function getLayerParam(layerOptions) {
12015
+ const { sourceOptions } = layerOptions;
12016
+ if (!sourceOptions)
12017
+ return;
12018
+ const { type } = sourceOptions;
12019
+ switch (type) {
12020
+ case 'wms':
12021
+ return (sourceOptions.params.LAYERS ??
12022
+ sourceOptions.params['layers']);
12023
+ case 'wmts':
12024
+ case 'arcgisrest':
12025
+ return sourceOptions.layer;
12026
+ case 'imagearcgisrest':
12027
+ case 'tilearcgisrest': {
12028
+ const { layer, params } = sourceOptions;
12029
+ return layer ?? params?.layer;
12030
+ }
12031
+ default:
12032
+ return undefined;
12033
+ }
12034
+ }
12035
+ /**
12036
+ * Recursively finds the parent ID of a target layer option within a tree structure.
12037
+ *
12038
+ * @param tree - The array of layer options representing the tree structure.
12039
+ * @param target - The target layer option whose parent ID is to be found.
12040
+ * @param path - The current path of IDs traversed during the search (used internally).
12041
+ * @returns The parent ID as a dot-separated string, or undefined if no parent is found.
12042
+ */
12043
+ function findParentId(tree, target, path = []) {
12044
+ const targetId = getLayerOptionIdentifier(target);
12045
+ for (const node of tree) {
12046
+ const currentPath = node.id ? [...path, node.id.toString()] : [...path];
12047
+ if (isLayerGroupOptions(node) && node.children) {
12048
+ for (const child of node.children) {
12049
+ // Check if the current child node matches the target node by comparing their IDs
12050
+ if (getLayerOptionIdentifier(child) === targetId) {
12051
+ const targetPath = currentPath?.join('.');
12052
+ return targetPath === undefined || targetPath === ''
12053
+ ? undefined
12054
+ : targetPath;
12055
+ }
12056
+ }
12057
+ const result = findParentId(node.children, target, currentPath);
12058
+ if (result) {
12059
+ return result;
12060
+ }
12061
+ }
12062
+ }
12063
+ return undefined;
12064
+ }
12065
+
12066
+ const EYE_CLOSE_BY_GROUP_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 17.5C8.2 17.5 4.8 15.4 3.2 12H1C2.7 16.4 7 19.5 12 19.5S21.3 16.4 23 12H20.8C19.2 15.4 15.8 17.5 12 17.5Z" /></svg>`;
12067
+ class LayerVisibilityButtonComponent {
12068
+ iconRegistry = inject(MatIconRegistry);
12069
+ sanitizer = inject(DomSanitizer);
12070
+ languageService = inject(LanguageService);
12071
+ eyeClosedByGroupSvg = {
12072
+ name: 'eye-closed',
12073
+ svg: EYE_CLOSE_BY_GROUP_SVG
12074
+ };
12075
+ layer = input.required(...(ngDevMode ? [{ debugName: "layer" }] : []));
12076
+ tooltip = input(undefined, ...(ngDevMode ? [{ debugName: "tooltip" }] : []));
12077
+ disabled = input(undefined, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
12078
+ showQueryBadge = input(undefined, ...(ngDevMode ? [{ debugName: "showQueryBadge" }] : []));
12079
+ inResolutionsRange = input(undefined, ...(ngDevMode ? [{ debugName: "inResolutionsRange" }] : []));
12080
+ parentDisplayed = toSignal(toObservable(this.layer).pipe(switchMap((layer) => layer.parent$), switchMap((parent) => (parent ? parent.displayed$ : of(undefined)))), { initialValue: false });
12081
+ visible = toSignal(toObservable(this.layer).pipe(switchMap((layer) => layer.visible$)));
12082
+ badge = computed(() => this.getBadge(this.layer()), ...(ngDevMode ? [{ debugName: "badge" }] : []));
12083
+ defaultTooltipText = computed(() => {
12084
+ return this.languageService.translate.instant(this.tooltip() ?? this.getDefaultTooltip());
12085
+ }, ...(ngDevMode ? [{ debugName: "defaultTooltipText" }] : []));
12086
+ tooltipText = computed(() => {
12087
+ const tooltip = this.defaultTooltipText();
12088
+ if (this.badge()) {
12089
+ return (`${tooltip}. ` +
12090
+ this.languageService.translate.instant('igo.geo.layer.filterAppliedOnLayer'));
12091
+ }
12092
+ return tooltip;
12093
+ }, ...(ngDevMode ? [{ debugName: "tooltipText" }] : []));
12094
+ visibilityChange = output();
12095
+ constructor() {
12096
+ this.iconRegistry.addSvgIconLiteral('eye-closed-by-group', this.sanitizer.bypassSecurityTrustHtml(EYE_CLOSE_BY_GROUP_SVG));
12097
+ }
12098
+ toggle(event) {
12099
+ this.layer().visible = !this.layer().visible;
12100
+ this.visibilityChange.emit(event);
12101
+ }
12102
+ getBadge(layer) {
12103
+ return isLayerItem(layer)
12104
+ ? getFilterBadge(layer.dataSource.options)
12105
+ : undefined;
12106
+ }
12107
+ getDefaultTooltip() {
12108
+ return !this.inResolutionsRange()
12109
+ ? 'igo.geo.layer.notInResolution'
12110
+ : this.visible() && this.disabled()
12111
+ ? 'igo.geo.layer.group.hideChildren'
12112
+ : this.visible()
12113
+ ? 'igo.geo.layer.hideLayer'
12114
+ : 'igo.geo.layer.showLayer';
12115
+ }
12116
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerVisibilityButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12117
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.18", type: LayerVisibilityButtonComponent, isStandalone: true, selector: "igo-layer-visibility-button", inputs: { layer: { classPropertyName: "layer", publicName: "layer", isSignal: true, isRequired: true, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showQueryBadge: { classPropertyName: "showQueryBadge", publicName: "showQueryBadge", isSignal: true, isRequired: false, transformFunction: null }, inResolutionsRange: { classPropertyName: "inResolutionsRange", publicName: "inResolutionsRange", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visibilityChange: "visibilityChange" }, ngImport: i0, template: "@let hiddenByParent = this.parentDisplayed() === false ? true : false;\n<button\n mat-icon-button\n [ngClass]=\"{\n disabled: disabled(),\n 'out-of-range': !inResolutionsRange(),\n 'visibility-hidden': !visible()\n }\"\n [color]=\"visible() ? 'primary' : 'default'\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"tooltipText()\"\n (click)=\"toggle($event)\"\n>\n @let badge = this.badge();\n <igo-icon\n matBadge=\"icon\"\n [igoMatBadgeIcon]=\"badge ? 'filter_alt' : 'help'\"\n [igoMatBadgeInverseColor]=\"!!badge\"\n [igoMatBadgeBackgroundColor]=\"badge ? '#fff' : null\"\n [matBadgeDisabled]=\"visible() ? (hiddenByParent ? true : false) : true\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"after\"\n [matBadgeHidden]=\"!badge && !showQueryBadge()\"\n [icon]=\"\n visible()\n ? hiddenByParent\n ? eyeClosedByGroupSvg\n : 'visibility'\n : 'visibility_off'\n \"\n iconPositionEnd\n />\n</button>\n", styles: [":host .disabled.out-of-range,:host .visibility-hidden.out-of-range{opacity:.54}:host ::ng-deep .mat-badge-content{height:16px;width:16px;z-index:2;margin:-9px!important;background-color:transparent!important}:host ::ng-deep .mat-badge-content mat-icon{color:var(--mat-sys-on-primary-container);width:12px!important;height:12px!important;font-size:12px!important}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i4$4.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "component", type: IgoIconComponent, selector: "igo-icon", inputs: ["color", "icon"] }, { kind: "directive", type: IgoBadgeIconDirective, selector: "[igoMatBadgeIcon]", inputs: ["igoMatBadgeIcon", "matBadgeHidden", "matBadgeDisabled", "igoMatBadgeInverseColor", "igoMatBadgeInheritColor", "igoMatBadgeColor", "igoMatBadgeBackgroundColor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12118
+ }
12119
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerVisibilityButtonComponent, decorators: [{
12120
+ type: Component,
12121
+ args: [{ selector: 'igo-layer-visibility-button', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
12122
+ NgClass,
12123
+ MatBadgeModule,
12124
+ MatButtonModule,
12125
+ MatIconModule,
12126
+ MatTooltipModule,
12127
+ IgoLanguageModule,
12128
+ IgoIconComponent,
12129
+ IgoBadgeIconDirective
12130
+ ], template: "@let hiddenByParent = this.parentDisplayed() === false ? true : false;\n<button\n mat-icon-button\n [ngClass]=\"{\n disabled: disabled(),\n 'out-of-range': !inResolutionsRange(),\n 'visibility-hidden': !visible()\n }\"\n [color]=\"visible() ? 'primary' : 'default'\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"tooltipText()\"\n (click)=\"toggle($event)\"\n>\n @let badge = this.badge();\n <igo-icon\n matBadge=\"icon\"\n [igoMatBadgeIcon]=\"badge ? 'filter_alt' : 'help'\"\n [igoMatBadgeInverseColor]=\"!!badge\"\n [igoMatBadgeBackgroundColor]=\"badge ? '#fff' : null\"\n [matBadgeDisabled]=\"visible() ? (hiddenByParent ? true : false) : true\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"after\"\n [matBadgeHidden]=\"!badge && !showQueryBadge()\"\n [icon]=\"\n visible()\n ? hiddenByParent\n ? eyeClosedByGroupSvg\n : 'visibility'\n : 'visibility_off'\n \"\n iconPositionEnd\n />\n</button>\n", styles: [":host .disabled.out-of-range,:host .visibility-hidden.out-of-range{opacity:.54}:host ::ng-deep .mat-badge-content{height:16px;width:16px;z-index:2;margin:-9px!important;background-color:transparent!important}:host ::ng-deep .mat-badge-content mat-icon{color:var(--mat-sys-on-primary-container);width:12px!important;height:12px!important;font-size:12px!important}\n"] }]
12131
+ }], ctorParameters: () => [], propDecorators: { layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "layer", required: true }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showQueryBadge: [{ type: i0.Input, args: [{ isSignal: true, alias: "showQueryBadge", required: false }] }], inResolutionsRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "inResolutionsRange", required: false }] }], visibilityChange: [{ type: i0.Output, args: ["visibilityChange"] }] } });
12132
+
12133
+ class LayerGroupComponent {
12134
+ layer = input(undefined, ...(ngDevMode ? [{ debugName: "layer" }] : []));
12135
+ viewerOptions = input(undefined, ...(ngDevMode ? [{ debugName: "viewerOptions" }] : []));
12136
+ selected = input(undefined, ...(ngDevMode ? [{ debugName: "selected" }] : []));
12137
+ selectionDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "selectionDisabled" }] : []));
12138
+ action = output();
12139
+ visibilityChange = output();
12140
+ expand = output();
12141
+ selectChange = output();
12142
+ isDisabled;
12143
+ get title() {
12144
+ return this.layer().title;
12145
+ }
12146
+ get collapsed() {
12147
+ return this.layer().collapsed;
12148
+ }
12149
+ set collapsed(value) {
12150
+ this.layer().collapsed = value;
12151
+ }
12152
+ get tooltipMessage() {
12153
+ const layer = this.layer();
12154
+ return !layer.isInResolutionsRange
12155
+ ? 'igo.geo.layer.notInResolution'
12156
+ : layer.visible && this.isDisabled
12157
+ ? 'igo.geo.layer.group.hideChildren'
12158
+ : layer.visible
12159
+ ? 'igo.geo.layer.group.hide'
12160
+ : 'igo.geo.layer.group.show';
12161
+ }
12162
+ ngOnInit() {
12163
+ this.layer().displayed$.subscribe((displayed) => {
12164
+ this.isDisabled = !displayed;
12165
+ });
12166
+ }
12167
+ onToggle() {
12168
+ this.collapsed = !this.collapsed;
12169
+ }
12170
+ toggleVisibility(event) {
12171
+ event.stopPropagation();
12172
+ this.visibilityChange.emit(event);
12173
+ }
12174
+ toggleLayerGroupTool(event) {
12175
+ event.stopPropagation();
12176
+ this.action.emit(this.layer());
12177
+ }
12178
+ toggleLayerTool(layer) {
12179
+ this.action.emit(layer);
12180
+ }
12181
+ handleExpand() {
12182
+ this.expand.emit();
12183
+ }
12184
+ handleSelect(event) {
12185
+ this.selectChange.emit(event.checked);
12186
+ }
12187
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12188
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: LayerGroupComponent, isStandalone: true, selector: "igo-layer-group", inputs: { layer: { classPropertyName: "layer", publicName: "layer", isSignal: true, isRequired: false, transformFunction: null }, viewerOptions: { classPropertyName: "viewerOptions", publicName: "viewerOptions", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, selectionDisabled: { classPropertyName: "selectionDisabled", publicName: "selectionDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action", visibilityChange: "visibilityChange", expand: "expand", selectChange: "selectChange" }, host: { properties: { "class.disabled": "this.isDisabled" } }, ngImport: i0, template: "<div class=\"layer-content\">\n <ng-content />\n\n @if (viewerOptions().mode === 'selection') {\n <mat-checkbox\n [checked]=\"selected()\"\n [disabled]=\"selectionDisabled()\"\n (change)=\"handleSelect($event)\"\n />\n }\n <span class=\"igo-layer-title\" (click)=\"handleExpand()\">{{\n layer().title\n }}</span>\n</div>\n\n<div class=\"list-actions\">\n <div class=\"list-secondary-actions\">\n <button\n class=\"actions-button\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.group.moreOptions' | translate\"\n mat-icon-button\n color=\"primary\"\n (click)=\"toggleLayerGroupTool($event)\"\n >\n <mat-icon>more_horiz</mat-icon>\n </button>\n </div>\n\n <igo-layer-visibility-button\n [layer]=\"layer()\"\n [disabled]=\"isDisabled\"\n [tooltip]=\"tooltipMessage\"\n [inResolutionsRange]=\"layer().isInResolutionsRange$ | async\"\n (visibilityChange)=\"toggleVisibility($event)\"\n />\n</div>\n", styles: [":host ::ng-deep .list-secondary-actions button{visibility:hidden}:host ::ng-deep .list-secondary-actions button.disabled{visibility:visible}:host:hover ::ng-deep .list-secondary-actions button{visibility:visible}:host.disabled ::ng-deep .igo-layer-title,:host.disabled ::ng-deep .list-secondary-actions{opacity:.54}:host{display:flex;align-items:center;justify-content:space-between;background-color:var(--mat-sys-surface)}:host ::ng-deep button.mat-default mat-icon{color:var(--mat-sys-on-surface);fill:var(--mat-sys-on-surface)}:host ::ng-deep button.disabled mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}.igo-layer-title{flex:1;font-weight:700;cursor:pointer;max-height:48px;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;box-orient:vertical;-webkit-box-orient:vertical;line-clamp:2;-webkit-line-clamp:2}.layer-browser-group-carret{margin-right:10px}.layer-content{display:flex;align-items:center;flex:1}.list-actions{display:flex;margin-left:4px;margin-right:4px}.child-list{padding-left:26px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i2$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: LayerVisibilityButtonComponent, selector: "igo-layer-visibility-button", inputs: ["layer", "tooltip", "disabled", "showQueryBadge", "inResolutionsRange"], outputs: ["visibilityChange"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12189
+ }
12190
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerGroupComponent, decorators: [{
12191
+ type: Component,
12192
+ args: [{ selector: 'igo-layer-group', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
12193
+ AsyncPipe,
12194
+ MatButtonModule,
12195
+ MatCheckboxModule,
12196
+ MatTooltipModule,
12197
+ MatIconModule,
12198
+ LayerVisibilityButtonComponent,
12199
+ IgoLanguageModule
12200
+ ], template: "<div class=\"layer-content\">\n <ng-content />\n\n @if (viewerOptions().mode === 'selection') {\n <mat-checkbox\n [checked]=\"selected()\"\n [disabled]=\"selectionDisabled()\"\n (change)=\"handleSelect($event)\"\n />\n }\n <span class=\"igo-layer-title\" (click)=\"handleExpand()\">{{\n layer().title\n }}</span>\n</div>\n\n<div class=\"list-actions\">\n <div class=\"list-secondary-actions\">\n <button\n class=\"actions-button\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.group.moreOptions' | translate\"\n mat-icon-button\n color=\"primary\"\n (click)=\"toggleLayerGroupTool($event)\"\n >\n <mat-icon>more_horiz</mat-icon>\n </button>\n </div>\n\n <igo-layer-visibility-button\n [layer]=\"layer()\"\n [disabled]=\"isDisabled\"\n [tooltip]=\"tooltipMessage\"\n [inResolutionsRange]=\"layer().isInResolutionsRange$ | async\"\n (visibilityChange)=\"toggleVisibility($event)\"\n />\n</div>\n", styles: [":host ::ng-deep .list-secondary-actions button{visibility:hidden}:host ::ng-deep .list-secondary-actions button.disabled{visibility:visible}:host:hover ::ng-deep .list-secondary-actions button{visibility:visible}:host.disabled ::ng-deep .igo-layer-title,:host.disabled ::ng-deep .list-secondary-actions{opacity:.54}:host{display:flex;align-items:center;justify-content:space-between;background-color:var(--mat-sys-surface)}:host ::ng-deep button.mat-default mat-icon{color:var(--mat-sys-on-surface);fill:var(--mat-sys-on-surface)}:host ::ng-deep button.disabled mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}.igo-layer-title{flex:1;font-weight:700;cursor:pointer;max-height:48px;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;box-orient:vertical;-webkit-box-orient:vertical;line-clamp:2;-webkit-line-clamp:2}.layer-browser-group-carret{margin-right:10px}.layer-content{display:flex;align-items:center;flex:1}.list-actions{display:flex;margin-left:4px;margin-right:4px}.child-list{padding-left:26px}\n"] }]
12201
+ }], propDecorators: { layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "layer", required: false }] }], viewerOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewerOptions", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], selectionDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionDisabled", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], visibilityChange: [{ type: i0.Output, args: ["visibilityChange"] }], expand: [{ type: i0.Output, args: ["expand"] }], selectChange: [{ type: i0.Output, args: ["selectChange"] }], isDisabled: [{
12202
+ type: HostBinding,
12203
+ args: ['class.disabled']
12204
+ }] } });
12205
+
12206
+ /**
12207
+ * Whether a layer is queryable
12208
+ * @param layer Layer
12209
+ * @returns True if the layer s squeryable
12210
+ */
12211
+ function layerIsQueryable(layer) {
12212
+ if (isLayerGroup(layer)) {
12213
+ return false;
12214
+ }
12215
+ const dataSource = layer.dataSource;
12216
+ return dataSource.options.queryable === true;
12217
+ }
12218
+ /**
12219
+ * Whether an OL layer is queryable
12220
+ * @param layer Layer
12221
+ * @returns True if the ol layer is queryable
12222
+ */
12223
+ function olLayerIsQueryable(olLayer) {
12224
+ const layer = olLayer.get('_layer');
12225
+ return layer === undefined ? false : layerIsQueryable(layer);
12226
+ }
12227
+ /**
12228
+ * Whether a layer's feature is queryable
12229
+ * @param layer Layer
12230
+ * @returns True if the layer's feature is queryable
12231
+ */
12232
+ function layerFeatureIsQueryable(layer) {
12233
+ const dataSource = layer.dataSource;
12234
+ return dataSource.options.queryLayerFeatures !== undefined
12235
+ ? dataSource.options.queryLayerFeatures === true
12236
+ : true;
12237
+ }
12238
+ /**
12239
+ * Whether an OL Vector layer is queryable
12240
+ * @param layer Layer
12241
+ * @returns True if the ol vector layer is queryable
12242
+ */
12243
+ function olLayerFeatureIsQueryable(olLayer) {
12244
+ const layer = olLayer.get('_layer');
12245
+ return layer === undefined
12246
+ ? false
12247
+ : layerIsQueryable(layer) && layerFeatureIsQueryable(layer);
12248
+ }
12249
+
12250
+ class LayerLegendComponent {
12251
+ capabilitiesService = inject(CapabilitiesService);
12252
+ languageService = inject(LanguageService);
12253
+ cdRef = inject(ChangeDetectorRef);
12254
+ config = inject(ConfigService);
12255
+ http = inject(HttpClient);
12256
+ updateLegendOnResolutionChange = input(false, ...(ngDevMode ? [{ debugName: "updateLegendOnResolutionChange" }] : []));
12257
+ /**
12258
+ * Observable of the legend items
12259
+ */
12260
+ legendItems$ = new BehaviorSubject([]);
12261
+ /**
12262
+ * Subscription to the map's resolution
12263
+ */
12264
+ state$$;
12265
+ /**
12266
+ * The available styles
12267
+ */
12268
+ styles;
12269
+ /**
12270
+ * The style used to make the legend
12271
+ */
12272
+ currentStyle;
12273
+ /**
12274
+ * The extent used to make the legend
12275
+ */
12276
+ view = undefined;
12277
+ /**
12278
+ * Get list of images display
12279
+ */
12280
+ renderedLegends = viewChildren('renderedLegend', ...(ngDevMode ? [{ debugName: "renderedLegends" }] : []));
12281
+ /**
12282
+ * List of size of images displayed
12283
+ */
12284
+ imagesHeight = {};
12285
+ layer = input(undefined, ...(ngDevMode ? [{ debugName: "layer" }] : []));
12286
+ /**
12287
+ * if getLegendGraphic is authorized
12288
+ */
12289
+ getLegend = true;
12290
+ /**
12291
+ * On init, subscribe to the map's resolution and update the legend accordingly
12292
+ */
12293
+ ngOnInit() {
12294
+ let lastlLegend = this.layer().legend;
12295
+ this.styles = this.listStyles();
12296
+ const sourceOptions = this.layer().options.source.options;
12297
+ if (sourceOptions && sourceOptions.params && sourceOptions.params.STYLES) {
12298
+ // if a styles is provided into the layers wms params
12299
+ this.currentStyle = this.styles.find((style) => style.name === sourceOptions.params.STYLES).name;
12300
+ }
12301
+ else if (!lastlLegend) {
12302
+ // if no legend is manually provided
12303
+ if (this.styles && this.styles.length > 1) {
12304
+ this.currentStyle = this.styles[0].name;
12305
+ }
12306
+ }
12307
+ else if (this.styles && this.styles.length > 1) {
12308
+ this.currentStyle = lastlLegend[0].currentStyle;
12309
+ }
12310
+ const layer = this.layer();
12311
+ if (typeof layer.options.legendOptions !== 'undefined' &&
12312
+ layer.options.legendOptions.display === false) {
12313
+ lastlLegend = [];
12314
+ }
12315
+ else {
12316
+ lastlLegend = layer.dataSource.getLegend(this.currentStyle, this.view);
12317
+ }
12318
+ if (this.updateLegendOnResolutionChange() ||
12319
+ sourceOptions.contentDependentLegend) {
12320
+ const state$ = layer.map.viewController.state$;
12321
+ this.state$$ = state$.subscribe(() => this.onViewControllerStateChange());
12322
+ }
12323
+ else if (lastlLegend && lastlLegend.length !== 0) {
12324
+ this.legendItems$.next(lastlLegend);
12325
+ for (const legend of lastlLegend) {
12326
+ this.getLegendGraphic(legend);
12327
+ }
12328
+ }
12329
+ }
12330
+ /**
12331
+ * On destroy, unsubscribe to the map's view state
12332
+ */
12333
+ ngOnDestroy() {
12334
+ if (this.state$$ !== undefined) {
12335
+ this.state$$.unsubscribe();
12336
+ }
12337
+ }
12338
+ getLegendGraphic(item) {
12339
+ if (item.url) {
12340
+ const depotUrl = this.config?.getConfig('depot.url');
12341
+ fetchImageFromDepotUrl(item.url, depotUrl, this.http)
12342
+ .pipe(catchError$1((err) => {
12343
+ if (err.error) {
12344
+ err.error.caught = true;
12345
+ this.getLegend = false;
12346
+ this.cdRef.detectChanges();
12347
+ }
12348
+ throw err;
12349
+ }))
12350
+ .subscribe((obsLegGraph) => {
12351
+ const idx = this.legendItems$.value.findIndex((leg) => leg.title === item.title);
12352
+ const legendGraph = obsLegGraph;
12353
+ this.legendItems$.value[idx].imgGraphValue = legendGraph;
12354
+ this.cdRef.detectChanges();
12355
+ });
12356
+ }
12357
+ }
12358
+ toggleLegendItem(collapsed, item) {
12359
+ item.collapsed = collapsed;
12360
+ }
12361
+ transfertToggleLegendItem(newLegends) {
12362
+ const outLegends = newLegends;
12363
+ const lastLegends = this.layer().legend;
12364
+ for (let i = 0; i < lastLegends.length; i++) {
12365
+ outLegends[i].collapsed = lastLegends[i].collapsed;
12366
+ }
12367
+ return outLegends;
12368
+ }
12369
+ computeItemTitle(layerLegend) {
12370
+ const layerOptions = this.layer().dataSource.options;
12371
+ if (layerOptions.type !== 'wms') {
12372
+ return of(layerLegend.title);
12373
+ }
12374
+ const layers = layerOptions.params.LAYERS.split(',');
12375
+ const localLayerOptions = JSON.parse(JSON.stringify(layerOptions)); // to avoid to alter the original options.
12376
+ localLayerOptions.params.LAYERS = layers.find((layer) => layer === layerLegend.title);
12377
+ return this.capabilitiesService.getWMSOptions(localLayerOptions).pipe(map((wmsDataSourceOptions) => {
12378
+ return wmsDataSourceOptions._layerOptionsFromSource.title;
12379
+ }));
12380
+ }
12381
+ /**
12382
+ * On resolution change, compute the effective scale level and update the
12383
+ * legend accordingly.
12384
+ * @param resolution Map resolution
12385
+ */
12386
+ onViewControllerStateChange() {
12387
+ this.view = {
12388
+ resolution: this.layer().map.viewController.getResolution(),
12389
+ extent: this.layer().map.viewController.getExtent(),
12390
+ projection: this.layer().map.viewController.getOlProjection().getCode(),
12391
+ scale: this.layer().map.viewController.getScale(),
12392
+ size: this.layer().map.ol.getSize()
12393
+ };
12394
+ this.updateLegend();
12395
+ }
12396
+ /**
12397
+ * Update the legend with scale level and style define
12398
+ */
12399
+ updateLegend() {
12400
+ let legendItems = this.layer().dataSource.getLegend(this.currentStyle, this.view);
12401
+ const layer = this.layer();
12402
+ if (layer.legend && layer.legend.length > 1) {
12403
+ legendItems = this.transfertToggleLegendItem(legendItems);
12404
+ }
12405
+ layer.legend = legendItems;
12406
+ if (legendItems.length === 0 && this.legendItems$.value.length === 0) {
12407
+ return;
12408
+ }
12409
+ this.legendItems$.next(legendItems);
12410
+ for (const legend of this.legendItems$.value) {
12411
+ this.getLegendGraphic(legend);
12412
+ }
12413
+ }
12414
+ listStyles() {
12415
+ const layerOptions = this.layer().options;
12416
+ if (layerOptions && layerOptions.legendOptions) {
12417
+ const translate = this.languageService.translate;
12418
+ const title = translate.instant('igo.geo.layer.legend.default');
12419
+ let stylesAvailable = [{ name: '', title }];
12420
+ if (layerOptions.legendOptions.stylesAvailable) {
12421
+ stylesAvailable = stylesAvailable.concat(layerOptions.legendOptions.stylesAvailable.filter((sA) => sA.name.normalize('NFD').replace(/[\u0300-\u036f]/gi, '') !==
12422
+ 'default' &&
12423
+ sA.name.normalize('NFD').replace(/[\u0300-\u036f]/gi, '') !==
12424
+ 'defaut'));
12425
+ }
12426
+ stylesAvailable
12427
+ .filter((sa) => !sa.title)
12428
+ .map((sa) => (sa.title = sa.name));
12429
+ stylesAvailable.map((s) => (s.title =
12430
+ s.title.charAt(0).toUpperCase() +
12431
+ s.title.slice(1).replace(/_/g, ' ')));
12432
+ return stylesAvailable;
12433
+ }
12434
+ return;
12435
+ }
12436
+ onChangeStyle() {
12437
+ this.updateLegend();
12438
+ let STYLES = '';
12439
+ const layer = this.layer();
12440
+ if (layer.dataSource instanceof WMSDataSource) {
12441
+ layer.dataSource.ol
12442
+ .getParams()
12443
+ .LAYERS.split(',')
12444
+ .map(() => (STYLES += this.currentStyle + ','));
12445
+ STYLES = STYLES.slice(0, -1);
12446
+ layer.dataSource.stylesParams = STYLES;
12447
+ }
12448
+ }
12449
+ onLoadImage(id) {
12450
+ let elemRef;
12451
+ const renderedLegends = this.renderedLegends();
12452
+ if (renderedLegends.length === 1) {
12453
+ elemRef = renderedLegends.at(0).nativeElement;
12454
+ }
12455
+ else {
12456
+ elemRef = renderedLegends.find((renderedLegend) => renderedLegend.nativeElement.id === id).nativeElement;
12457
+ }
12458
+ this.imagesHeight[id] = elemRef.height;
12459
+ }
12460
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerLegendComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12461
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: LayerLegendComponent, isStandalone: true, selector: "igo-layer-legend", inputs: { updateLegendOnResolutionChange: { classPropertyName: "updateLegendOnResolutionChange", publicName: "updateLegendOnResolutionChange", isSignal: true, isRequired: false, transformFunction: null }, layer: { classPropertyName: "layer", publicName: "layer", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "renderedLegends", predicate: ["renderedLegend"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (legendItems$ | async; as items) {\n @if (items.length) {\n @for (item of items.slice().reverse(); track item) {\n <ng-container #renderedLegends>\n @if (getLegend) {\n <div>\n @if (item.title) {\n <mat-list-item>\n <mat-icon\n id=\"legend-toggle\"\n class=\"igo-chevron\"\n matListItemIcon\n igoCollapse\n [target]=\"legend\"\n [collapsed]=\"item.collapsed\"\n (toggle)=\"toggleLegendItem($event, item)\"\n >expand_less\n </mat-icon>\n <span matListItemTitle\n >{{ computeItemTitle(item) | async }}\n </span>\n </mat-list-item>\n }\n <div\n #legend\n class=\"igo-layer-legend\"\n [ngClass]=\"{ 'with-title': item.title }\"\n >\n @if (currentStyle !== undefined) {\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-select\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n 'igo.geo.layer.legend.selectStyle' | translate\n \"\n [(ngModel)]=\"currentStyle\"\n (selectionChange)=\"onChangeStyle()\"\n >\n @for (style of styles; track style) {\n <mat-option [value]=\"style.name\">{{\n style.title\n }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n @if (!item.collapsed) {\n <div>\n @if (item.url) {\n <div>\n @if (item.imgGraphValue) {\n <img\n igoImageError\n [hideError]=\"true\"\n #renderedLegend\n id=\"{{ item.title }}\"\n (load)=\"onLoadImage(item.title)\"\n [src]=\"item.imgGraphValue\"\n alt=\"{{\n 'igo.geo.layer.legend.loadingLegendText' | translate\n }}\"\n />\n }\n @if (imagesHeight[item.title] < 16) {\n <small>\n {{ 'igo.geo.layer.legend.noLegendScale' | translate }}\n </small>\n }\n </div>\n }\n @if (item.html) {\n <div\n [ngStyle]=\"item.style\"\n [innerHTML]=\"item.html | sanitizeHtml\"\n ></div>\n }\n </div>\n }\n </div>\n </div>\n } @else {\n <small>\n {{ 'igo.geo.layer.legend.noLegendText' | translate }}\n </small>\n }\n </ng-container>\n }\n } @else {\n <small>\n {{ 'igo.geo.layer.legend.noLegendText' | translate }}\n </small>\n }\n}\n", styles: [":host{--mat-form-field-container-height: 48px;--mat-form-field-container-vertical-padding: 12px}@-moz-document url-prefix(){:host img:after{margin-left:19px}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.igo-layer-legend.with-title{padding-left:18px}img{max-width:100%}img:after{content:\" \";position:relative;height:17px;float:left;width:17px;top:-3px;right:19px;background-color:#fff;border:3px solid #f3f3f3;border-radius:50%;border-top-color:var(--mat-sys-primary-container);animation:2s linear infinite spin}mat-form-field{margin-bottom:4px}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "component", type: i1$2.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i1$2.MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "directive", type: i1$2.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: CollapseDirective, selector: "[igoCollapse]", inputs: ["target", "collapsed"], outputs: ["toggle"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "directive", type: ImageErrorDirective, selector: "[igoImageError]", inputs: ["errorImageUrl", "hideError"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: SanitizeHtmlPipe, name: "sanitizeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12462
+ }
12463
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerLegendComponent, decorators: [{
12464
+ type: Component,
12465
+ args: [{ selector: 'igo-layer-legend', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
12466
+ MatListModule,
12467
+ MatIconModule,
12468
+ CollapseDirective,
12469
+ NgClass,
12470
+ MatFormFieldModule,
12471
+ MatSelectModule,
12472
+ MatTooltipModule,
12473
+ FormsModule,
12474
+ MatOptionModule,
12475
+ ImageErrorDirective,
12476
+ NgStyle,
12477
+ AsyncPipe,
12478
+ IgoLanguageModule,
12479
+ SanitizeHtmlPipe
12480
+ ], template: "@if (legendItems$ | async; as items) {\n @if (items.length) {\n @for (item of items.slice().reverse(); track item) {\n <ng-container #renderedLegends>\n @if (getLegend) {\n <div>\n @if (item.title) {\n <mat-list-item>\n <mat-icon\n id=\"legend-toggle\"\n class=\"igo-chevron\"\n matListItemIcon\n igoCollapse\n [target]=\"legend\"\n [collapsed]=\"item.collapsed\"\n (toggle)=\"toggleLegendItem($event, item)\"\n >expand_less\n </mat-icon>\n <span matListItemTitle\n >{{ computeItemTitle(item) | async }}\n </span>\n </mat-list-item>\n }\n <div\n #legend\n class=\"igo-layer-legend\"\n [ngClass]=\"{ 'with-title': item.title }\"\n >\n @if (currentStyle !== undefined) {\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-select\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n 'igo.geo.layer.legend.selectStyle' | translate\n \"\n [(ngModel)]=\"currentStyle\"\n (selectionChange)=\"onChangeStyle()\"\n >\n @for (style of styles; track style) {\n <mat-option [value]=\"style.name\">{{\n style.title\n }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n @if (!item.collapsed) {\n <div>\n @if (item.url) {\n <div>\n @if (item.imgGraphValue) {\n <img\n igoImageError\n [hideError]=\"true\"\n #renderedLegend\n id=\"{{ item.title }}\"\n (load)=\"onLoadImage(item.title)\"\n [src]=\"item.imgGraphValue\"\n alt=\"{{\n 'igo.geo.layer.legend.loadingLegendText' | translate\n }}\"\n />\n }\n @if (imagesHeight[item.title] < 16) {\n <small>\n {{ 'igo.geo.layer.legend.noLegendScale' | translate }}\n </small>\n }\n </div>\n }\n @if (item.html) {\n <div\n [ngStyle]=\"item.style\"\n [innerHTML]=\"item.html | sanitizeHtml\"\n ></div>\n }\n </div>\n }\n </div>\n </div>\n } @else {\n <small>\n {{ 'igo.geo.layer.legend.noLegendText' | translate }}\n </small>\n }\n </ng-container>\n }\n } @else {\n <small>\n {{ 'igo.geo.layer.legend.noLegendText' | translate }}\n </small>\n }\n}\n", styles: [":host{--mat-form-field-container-height: 48px;--mat-form-field-container-vertical-padding: 12px}@-moz-document url-prefix(){:host img:after{margin-left:19px}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.igo-layer-legend.with-title{padding-left:18px}img{max-width:100%}img:after{content:\" \";position:relative;height:17px;float:left;width:17px;top:-3px;right:19px;background-color:#fff;border:3px solid #f3f3f3;border-radius:50%;border-top-color:var(--mat-sys-primary-container);animation:2s linear infinite spin}mat-form-field{margin-bottom:4px}\n"] }]
12481
+ }], propDecorators: { updateLegendOnResolutionChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "updateLegendOnResolutionChange", required: false }] }], renderedLegends: [{ type: i0.ViewChildren, args: ['renderedLegend', { isSignal: true }] }], layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "layer", required: false }] }] } });
12482
+
12483
+ class LayerItemComponent {
12484
+ networkService = inject(NetworkService);
12485
+ showLegend = signal(true, ...(ngDevMode ? [{ debugName: "showLegend" }] : []));
12486
+ inResolutionRange = true;
12487
+ queryBadgeHidden = signal(true, ...(ngDevMode ? [{ debugName: "queryBadgeHidden" }] : []));
12488
+ tooltipText;
12489
+ state;
12490
+ resolution$$;
12491
+ network$$;
12492
+ layer = input.required(...(ngDevMode ? [{ debugName: "layer" }] : []));
12493
+ /** Pass the visibility to trigger change detection */
12494
+ visible = input.required(...(ngDevMode ? [{ debugName: "visible" }] : []));
12495
+ selected = input(undefined, ...(ngDevMode ? [{ debugName: "selected" }] : []));
12496
+ selectionDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "selectionDisabled" }] : []));
12497
+ viewerOptions = input(undefined, ...(ngDevMode ? [{ debugName: "viewerOptions" }] : []));
12498
+ action = output();
12499
+ selectChange = output();
12500
+ visibilityChange = output();
12501
+ isDisabled;
12502
+ get opacity() {
12503
+ return this.layer().opacity * 100;
12504
+ }
12505
+ set opacity(opacity) {
12506
+ this.layer().opacity = opacity / 100;
12507
+ }
12508
+ get visibilityTooltip() {
12509
+ if (this.viewerOptions().mode !== 'selection' && !this.inResolutionRange) {
12510
+ return this.layer().visible
12511
+ ? this.isDisabled
12512
+ ? 'igo.geo.layer.notInResolution'
12513
+ : 'igo.geo.layer.group.hideChildren'
12514
+ : 'igo.geo.layer.showLayer';
12515
+ }
12516
+ return this.layer().visible
12517
+ ? this.isDisabled
12518
+ ? 'igo.geo.layer.group.hideChildren'
12519
+ : 'igo.geo.layer.hideLayer'
12520
+ : 'igo.geo.layer.showLayer';
12521
+ }
12522
+ ngOnInit() {
12523
+ this.layer().displayed$.subscribe((displayed) => {
12524
+ this.isDisabled = !displayed;
12525
+ });
12526
+ const layer = this.layer();
12527
+ if (layer.visible &&
12528
+ this.viewerOptions()?.legend?.showForVisibleLayers &&
12529
+ layer.firstLoadComponent === true) {
12530
+ layer.firstLoadComponent = false;
12531
+ layer.legendCollapsed = false;
12532
+ }
12533
+ this.toggleLegend(layer.legendCollapsed);
12534
+ this.updateQueryBadge();
12535
+ const resolution$ = layer.map.viewController.resolution$;
12536
+ this.resolution$$ = resolution$.subscribe(() => {
12537
+ this.onResolutionChange();
12538
+ });
12539
+ this.tooltipText = this.computeTooltip();
12540
+ this.network$$ = this.networkService
12541
+ .currentState()
12542
+ .subscribe((state) => {
12543
+ this.state = state;
12544
+ this.onResolutionChange();
12545
+ });
12297
12546
  }
12298
- _internalMove() {
12299
- this.recalculateZindex();
12300
- this.notify();
12547
+ ngOnDestroy() {
12548
+ this.resolution$$?.unsubscribe();
12549
+ this.network$$?.unsubscribe();
12301
12550
  }
12302
- getBefore(layer) {
12303
- return this.treeLayers.find((layerTree) => layerTree.zIndex <= layer.zIndex);
12551
+ toggleLegend(collapsed) {
12552
+ this.layer().legendCollapsed = collapsed;
12553
+ this.showLegend.set(!collapsed);
12304
12554
  }
12305
- /** Recursive */
12306
- recalculateZindex(minIndex = this.baseLayers.length, layers = this.treeLayers) {
12307
- return [...layers].reverse().reduce((previousZindex, layer) => {
12308
- let zIndex = ++previousZindex;
12309
- layer.zIndex = zIndex;
12310
- if (isLayerGroup(layer)) {
12311
- zIndex = this.recalculateZindex(zIndex, layer.children);
12312
- }
12313
- return zIndex;
12314
- }, minIndex);
12555
+ toggleLegendOnClick() {
12556
+ this.toggleLegend(this.showLegend());
12315
12557
  }
12316
- handleAdd(layer, offset) {
12317
- const existingLayer = this.getById(layer.id);
12318
- if (existingLayer !== undefined) {
12319
- existingLayer.visible = true;
12320
- return;
12321
- }
12322
- const zIndex = this.getZindexOffset(layer, offset);
12323
- this.setZindex(layer, zIndex);
12324
- layer.init(this._map);
12325
- if (isBaseLayer(layer)) {
12326
- if (layer.visible) {
12327
- this.selectBaseLayer(layer);
12328
- }
12329
- this._baseLayers.push(layer);
12330
- }
12331
- else if (this.isOtherLayer(layer)) {
12332
- this._otherLayers.push(layer);
12333
- }
12334
- else if (this.isSystemLayer(layer) && !layer.showInLayerList) {
12335
- this._systemLayers.push(layer);
12336
- }
12337
- else if (layer.showInLayerList) {
12338
- return layer;
12339
- }
12340
- else {
12341
- this._otherLayers.push(layer);
12558
+ handleVisibilityChange(event) {
12559
+ event.stopPropagation();
12560
+ if (this.viewerOptions().legend?.showOnVisibilityChange) {
12561
+ this.toggleLegend(!this.layer().visible);
12342
12562
  }
12343
- const parent = layer.parentId
12344
- ? this.getById(layer.parentId.toString().split(TREE_SEPERATOR).pop())
12345
- : undefined;
12346
- layer.add(parent);
12347
- return;
12563
+ this.updateQueryBadge();
12564
+ this.visibilityChange.emit(event);
12348
12565
  }
12349
- _remove(layer) {
12350
- if (isBaseLayer(layer)) {
12351
- this.removeBaselayer(layer);
12352
- }
12353
- else if (this.isOtherLayer(layer)) {
12354
- this.removeOtherLayer(layer);
12566
+ computeTooltip() {
12567
+ const layerOptions = this.layer().options;
12568
+ if (!layerOptions.tooltip) {
12569
+ return this.layer().title;
12355
12570
  }
12356
- else if (this.isSystemLayer(layer)) {
12357
- this.removeSystemLayer(layer);
12571
+ const layerTooltip = layerOptions.tooltip;
12572
+ const layerMetadata = layerOptions.metadata;
12573
+ switch (layerOptions.tooltip.type) {
12574
+ case TooltipType.TITLE:
12575
+ return this.layer().title;
12576
+ case TooltipType.ABSTRACT:
12577
+ if (layerMetadata && layerMetadata.abstract) {
12578
+ return layerMetadata.abstract;
12579
+ }
12580
+ else {
12581
+ return this.layer().title;
12582
+ }
12583
+ case TooltipType.CUSTOM:
12584
+ if (layerTooltip && layerTooltip.text) {
12585
+ return layerTooltip.text;
12586
+ }
12587
+ else {
12588
+ return this.layer().title;
12589
+ }
12590
+ default:
12591
+ return this.layer().title;
12358
12592
  }
12359
- layer.remove();
12360
- return layer;
12361
- }
12362
- removeBaselayer(layer) {
12363
- this.removeIn(layer, this._baseLayers);
12364
- }
12365
- removeSystemLayer(layer) {
12366
- this.removeIn(layer, this._systemLayers);
12367
12593
  }
12368
- removeOtherLayer(layer) {
12369
- this.removeIn(layer, this._otherLayers);
12370
- }
12371
- removeIn(layer, store) {
12372
- const index = store.findIndex((sysLayer) => sysLayer.id === layer.id);
12373
- if (index === -1) {
12374
- return;
12594
+ onResolutionChange() {
12595
+ const inResolutionRange = this.layer().isInResolutionsRange;
12596
+ if (inResolutionRange === false &&
12597
+ this.viewerOptions().legend.updateOnResolutionChange === true) {
12598
+ this.toggleLegend(true);
12375
12599
  }
12376
- store.splice(index, 1);
12377
- }
12378
- isSystemLayer(layer) {
12379
- return isLayerItem(layer) && layer.isIgoInternalLayer;
12380
- }
12381
- isOtherLayer(layer) {
12382
- return isLayerLinked(layer) && !layer.showInLayerList;
12383
- }
12384
- clearBaselayers() {
12385
- this.baseLayers.forEach((layer) => this._remove(layer));
12386
- this._baseLayers = [];
12387
- }
12388
- clearTree() {
12389
- this.treeLayers.forEach((layer) => this._remove(layer));
12390
- this.tree.clear();
12391
- }
12392
- clearSystems() {
12393
- this._systemLayers.forEach((layer) => this._remove(layer));
12394
- this._systemLayers = [];
12395
- }
12396
- clearOther() {
12397
- this._otherLayers.forEach((layer) => this._remove(layer));
12398
- this._otherLayers = [];
12399
- }
12400
- getZindexOffset(layer, previousOffset = 0) {
12401
- return layer.zIndex ? 0 : previousOffset++;
12600
+ this.inResolutionRange = inResolutionRange;
12402
12601
  }
12403
- setZindex(layer, offset) {
12404
- if (isBaseLayer(layer)) {
12405
- return this.handleBaselayerZIndex(layer, offset);
12406
- }
12407
- if (layer.zIndex === undefined || layer.zIndex === 0) {
12408
- const maxZIndex = Math.max(ZINDEX_MIN, ...this.treeLayers.map((l) => l.zIndex));
12409
- layer.zIndex = maxZIndex + 1 + (offset ?? 0);
12410
- }
12602
+ updateQueryBadge() {
12603
+ const layer = this.layer();
12604
+ const hidden = this.viewerOptions().queryBadge === false ||
12605
+ layer.visible === false ||
12606
+ !layerIsQueryable(layer);
12607
+ this.queryBadgeHidden.set(hidden);
12411
12608
  }
12412
- handleBaselayerZIndex(layer, offset) {
12413
- const maxZIndex = Math.max(0, ...this.baseLayers.map((l) => l.zIndex));
12414
- const zIndex = maxZIndex + 1 + (offset ?? 0);
12415
- layer.zIndex = zIndex > ZINDEX_MIN ? ZINDEX_MIN : zIndex;
12609
+ toggleLayerTool() {
12610
+ this.action.emit(this.layer());
12416
12611
  }
12417
- notify() {
12418
- this.layersFlattened = [...this.tree.flattened];
12419
- this._layers$.next([...this.treeLayers]);
12420
- this._baseLayers$.next([...this.baseLayers]);
12612
+ handleSelect(event) {
12613
+ this.selectChange.emit(event.checked);
12421
12614
  }
12615
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12616
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: LayerItemComponent, isStandalone: true, selector: "igo-layer-item", inputs: { layer: { classPropertyName: "layer", publicName: "layer", isSignal: true, isRequired: true, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: true, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, selectionDisabled: { classPropertyName: "selectionDisabled", publicName: "selectionDisabled", isSignal: true, isRequired: false, transformFunction: null }, viewerOptions: { classPropertyName: "viewerOptions", publicName: "viewerOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action", selectChange: "selectChange", visibilityChange: "visibilityChange" }, host: { properties: { "class.disabled": "this.isDisabled" } }, ngImport: i0, template: "<div class=\"igo-layer-list-item\">\n <div class=\"layer-content\">\n @if (viewerOptions().mode === 'selection') {\n <mat-checkbox\n [checked]=\"selected()\"\n [disabled]=\"selectionDisabled()\"\n (change)=\"handleSelect($event)\"\n />\n }\n <ng-content />\n <span\n class=\"igo-layer-title\"\n [matTooltip]=\"tooltipText\"\n matTooltipShowDelay=\"500\"\n (click)=\"toggleLegendOnClick()\"\n >\n {{ layer().title }}\n </span>\n </div>\n\n <div class=\"list-actions\">\n <div class=\"list-secondary-actions\">\n @if (viewerOptions().mode !== 'selection') {\n <button\n class=\"actions-button\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.moreOptions' | translate\"\n mat-icon-button\n color=\"primary\"\n (click)=\"toggleLayerTool()\"\n >\n <mat-icon>more_horiz</mat-icon>\n </button>\n }\n </div>\n\n <igo-layer-visibility-button\n [layer]=\"layer()\"\n [tooltip]=\"visibilityTooltip\"\n [disabled]=\"isDisabled\"\n [inResolutionsRange]=\"layer().isInResolutionsRange$ | async\"\n [showQueryBadge]=\"queryBadgeHidden() === false\"\n (visibilityChange)=\"handleVisibilityChange($event)\"\n />\n </div>\n</div>\n\n@if (showLegend()) {\n <div class=\"igo-layer-legend-container\">\n <igo-layer-legend\n [layer]=\"layer()\"\n [updateLegendOnResolutionChange]=\"\n viewerOptions().legend.updateOnResolutionChange\n \"\n />\n </div>\n}\n", styles: [":host ::ng-deep .list-secondary-actions button{visibility:hidden}:host ::ng-deep .list-secondary-actions button.disabled{visibility:visible}:host:hover ::ng-deep .list-secondary-actions button{visibility:visible}:host.disabled ::ng-deep .igo-layer-title,:host.disabled ::ng-deep .list-secondary-actions{opacity:.54}:host{overflow:hidden;background-color:var(--mat-sys-surface)}:host ::ng-deep button.mat-default mat-icon{color:var(--mat-sys-on-surface);fill:var(--mat-sys-on-surface)}:host ::ng-deep button.disabled mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}.list-actions{display:flex;margin-left:4px;margin-right:4px}.layer-content{display:flex;align-items:center;flex:1}.igo-layer-title{display:block;cursor:pointer;max-height:48px;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;box-orient:vertical;-webkit-box-orient:vertical;line-clamp:2;-webkit-line-clamp:2}.igo-layer-list-item{display:flex;align-items:center;justify-content:space-between}.igo-layer-legend-container{padding-top:4px;width:calc(100% - 12px)}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i2$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "component", type: LayerLegendComponent, selector: "igo-layer-legend", inputs: ["updateLegendOnResolutionChange", "layer"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "component", type: LayerVisibilityButtonComponent, selector: "igo-layer-visibility-button", inputs: ["layer", "tooltip", "disabled", "showQueryBadge", "inResolutionsRange"], outputs: ["visibilityChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12422
12617
  }
12618
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerItemComponent, decorators: [{
12619
+ type: Component,
12620
+ args: [{ selector: 'igo-layer-item', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
12621
+ MatListModule,
12622
+ MatCheckboxModule,
12623
+ MatTooltipModule,
12624
+ MatButtonModule,
12625
+ MatIconModule,
12626
+ MatBadgeModule,
12627
+ LayerLegendComponent,
12628
+ AsyncPipe,
12629
+ IgoLanguageModule,
12630
+ LayerVisibilityButtonComponent
12631
+ ], template: "<div class=\"igo-layer-list-item\">\n <div class=\"layer-content\">\n @if (viewerOptions().mode === 'selection') {\n <mat-checkbox\n [checked]=\"selected()\"\n [disabled]=\"selectionDisabled()\"\n (change)=\"handleSelect($event)\"\n />\n }\n <ng-content />\n <span\n class=\"igo-layer-title\"\n [matTooltip]=\"tooltipText\"\n matTooltipShowDelay=\"500\"\n (click)=\"toggleLegendOnClick()\"\n >\n {{ layer().title }}\n </span>\n </div>\n\n <div class=\"list-actions\">\n <div class=\"list-secondary-actions\">\n @if (viewerOptions().mode !== 'selection') {\n <button\n class=\"actions-button\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.moreOptions' | translate\"\n mat-icon-button\n color=\"primary\"\n (click)=\"toggleLayerTool()\"\n >\n <mat-icon>more_horiz</mat-icon>\n </button>\n }\n </div>\n\n <igo-layer-visibility-button\n [layer]=\"layer()\"\n [tooltip]=\"visibilityTooltip\"\n [disabled]=\"isDisabled\"\n [inResolutionsRange]=\"layer().isInResolutionsRange$ | async\"\n [showQueryBadge]=\"queryBadgeHidden() === false\"\n (visibilityChange)=\"handleVisibilityChange($event)\"\n />\n </div>\n</div>\n\n@if (showLegend()) {\n <div class=\"igo-layer-legend-container\">\n <igo-layer-legend\n [layer]=\"layer()\"\n [updateLegendOnResolutionChange]=\"\n viewerOptions().legend.updateOnResolutionChange\n \"\n />\n </div>\n}\n", styles: [":host ::ng-deep .list-secondary-actions button{visibility:hidden}:host ::ng-deep .list-secondary-actions button.disabled{visibility:visible}:host:hover ::ng-deep .list-secondary-actions button{visibility:visible}:host.disabled ::ng-deep .igo-layer-title,:host.disabled ::ng-deep .list-secondary-actions{opacity:.54}:host{overflow:hidden;background-color:var(--mat-sys-surface)}:host ::ng-deep button.mat-default mat-icon{color:var(--mat-sys-on-surface);fill:var(--mat-sys-on-surface)}:host ::ng-deep button.disabled mat-icon{color:var(--mat-sys-on-secondary-fixed);fill:var(--mat-sys-on-secondary-fixed);opacity:.64}.list-actions{display:flex;margin-left:4px;margin-right:4px}.layer-content{display:flex;align-items:center;flex:1}.igo-layer-title{display:block;cursor:pointer;max-height:48px;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;box-orient:vertical;-webkit-box-orient:vertical;line-clamp:2;-webkit-line-clamp:2}.igo-layer-list-item{display:flex;align-items:center;justify-content:space-between}.igo-layer-legend-container{padding-top:4px;width:calc(100% - 12px)}\n"] }]
12632
+ }], propDecorators: { layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "layer", required: true }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: true }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], selectionDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionDisabled", required: false }] }], viewerOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewerOptions", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], selectChange: [{ type: i0.Output, args: ["selectChange"] }], visibilityChange: [{ type: i0.Output, args: ["visibilityChange"] }], isDisabled: [{
12633
+ type: HostBinding,
12634
+ args: ['class.disabled']
12635
+ }] } });
12423
12636
 
12424
- function mergeLayersOptions(layersOptionsTree, layersOptions) {
12425
- const tree = [...layersOptionsTree];
12426
- layersOptions.forEach((options) => {
12427
- const identifier = getLayerOptionIdentifier(options);
12428
- if (!identifier)
12429
- return;
12430
- const currentNode = _getNodeById(identifier, tree) ?? _getNodeByTitle(options.title, tree);
12431
- if (currentNode) {
12432
- // if we get layer options by title, we update the id of current layer.
12433
- if (isLayerGroupOptions(currentNode) &&
12434
- currentNode.id.toString().includes(ID_GROUP_PREFIX)) {
12435
- currentNode.id = identifier;
12436
- }
12437
- const currentNodeParentID = currentNode.parentId ?? findParentId(tree, currentNode);
12438
- const mergedOptions = ObjectUtils.mergeDeep(currentNode, options);
12439
- if (currentNodeParentID === options.parentId) {
12440
- moveOptions(tree, identifier, mergedOptions);
12441
- }
12442
- else {
12443
- // if we have no parent id it means that we are in the root of the tree.
12444
- if (!options.parentId)
12445
- mergedOptions.parentId = undefined;
12446
- const initialIdentifier = getLayerOptionIdentifier(currentNode);
12447
- moveOptions(tree, initialIdentifier, mergedOptions);
12448
- }
12449
- }
12450
- else {
12451
- // Some layers in local context doesn't have an id, if this is the case we
12452
- // check if the layer is already in the tree by its title
12453
- // and if it is we don't add it again. The changes is ignored
12454
- if (isLayerGroupOptions(options)) {
12455
- const currentNode = _getNodeByTitle(options.title, tree);
12456
- if (currentNode) {
12457
- return;
12458
- }
12459
- }
12460
- // handel external Data source options
12461
- if (isLayerItemOptions(options)) {
12462
- handleExternalDataSource(options);
12463
- }
12464
- insertOptions(tree, options);
12465
- }
12466
- });
12467
- return tree;
12468
- }
12469
- function handleExternalDataSource(options) {
12470
- options.sourceOptions = {
12471
- ...options.sourceOptions,
12472
- optionsFromCapabilities: true,
12473
- optionsFromApi: true,
12474
- crossOrigin: 'anonymous'
12475
- };
12476
- }
12477
- function getLayerOptionIdentifier(layerOptions) {
12478
- return isLayerGroupOptions(layerOptions)
12479
- ? String(layerOptions.id)
12480
- : (getLayerParam(layerOptions) ??
12481
- (layerOptions.id !== undefined
12482
- ? layerOptions.id.toString()
12483
- : undefined));
12484
- }
12485
- function moveOptions(tree, initialIdentifier, options) {
12486
- removeNode(tree, initialIdentifier);
12487
- insertOptions(tree, options);
12488
- }
12489
- function insertOptions(tree, options) {
12490
- const parentId = options.parentId;
12491
- if (!parentId) {
12492
- tree.push(options);
12493
- }
12494
- else {
12495
- const parent = _getNodeById(parentId, tree);
12496
- if (parent) {
12497
- (parent.children ??= []).push(options);
12498
- sortLayersOptionsByZIndex(parent.children);
12499
- }
12637
+ class LayerLegendItemComponent {
12638
+ networkService = inject(NetworkService);
12639
+ inResolutionRange$ = new BehaviorSubject(true);
12640
+ tooltipText;
12641
+ state;
12642
+ resolution$$;
12643
+ network$$;
12644
+ layer = input(undefined, ...(ngDevMode ? [{ debugName: "layer" }] : []));
12645
+ updateLegendOnResolutionChange = input(false, ...(ngDevMode ? [{ debugName: "updateLegendOnResolutionChange" }] : []));
12646
+ ngOnInit() {
12647
+ const resolution$ = this.layer().map.viewController.resolution$;
12648
+ this.resolution$$ = resolution$.subscribe(() => {
12649
+ this.onResolutionChange();
12650
+ });
12651
+ this.tooltipText = this.computeTooltip();
12652
+ this.network$$ = this.networkService
12653
+ .currentState()
12654
+ .subscribe((state) => {
12655
+ this.state = state;
12656
+ this.onResolutionChange();
12657
+ });
12500
12658
  }
12501
- }
12502
- /** Recursive */
12503
- function _getNodeById(id, data) {
12504
- let node;
12505
- data.some((item) => {
12506
- const identifier = getLayerOptionIdentifier(item);
12507
- if (identifier === id) {
12508
- node = item;
12509
- return true;
12510
- }
12511
- const children = isLayerGroupOptions(item) ? item.children : undefined;
12512
- if (children) {
12513
- node = _getNodeById(id, children);
12514
- if (node)
12515
- return true;
12516
- }
12517
- return false;
12518
- });
12519
- return node;
12520
- }
12521
- /** Recursive */
12522
- function _getNodeByTitle(title, data) {
12523
- if (!title)
12524
- return;
12525
- let node;
12526
- data.some((item) => {
12527
- const itemTitle = item.title;
12528
- if (itemTitle === title) {
12529
- node = item;
12530
- return true;
12531
- }
12532
- const children = isLayerGroupOptions(item) ? item.children : undefined;
12533
- if (children) {
12534
- node = _getNodeByTitle(title, children);
12535
- if (node)
12536
- return true;
12537
- }
12538
- return false;
12539
- });
12540
- return node;
12541
- }
12542
- function removeNode(tree, nodeId) {
12543
- for (let i = 0; i < tree.length; i++) {
12544
- const node = tree[i];
12545
- const currentId = getLayerOptionIdentifier(node);
12546
- if (currentId === nodeId) {
12547
- tree.splice(i, 1);
12548
- return true;
12549
- }
12550
- if (isLayerGroupOptions(node) && node.children?.length) {
12551
- const removed = removeNode(node.children, nodeId);
12552
- if (removed && node.children.length === 0) {
12553
- delete node.children;
12554
- }
12555
- if (removed)
12556
- return true;
12557
- }
12659
+ ngOnDestroy() {
12660
+ this.resolution$$.unsubscribe();
12661
+ this.network$$.unsubscribe();
12558
12662
  }
12559
- return false;
12560
- }
12561
- function sortLayersOptionsByZIndex(layers) {
12562
- layers.sort((a, b) => (a.zIndex ?? 0) - (b.zIndex ?? 0));
12563
- }
12564
- function getLayerParam(layerOptions) {
12565
- const { sourceOptions } = layerOptions;
12566
- if (!sourceOptions)
12567
- return;
12568
- const { type } = sourceOptions;
12569
- switch (type) {
12570
- case 'wms':
12571
- return (sourceOptions.params.LAYERS ??
12572
- sourceOptions.params['layers']);
12573
- case 'wmts':
12574
- case 'arcgisrest':
12575
- return sourceOptions.layer;
12576
- case 'imagearcgisrest':
12577
- case 'tilearcgisrest': {
12578
- const { layer, params } = sourceOptions;
12579
- return layer ?? params?.layer;
12663
+ computeTooltip() {
12664
+ const layerOptions = this.layer().options;
12665
+ if (!layerOptions.tooltip) {
12666
+ return this.layer().title;
12580
12667
  }
12581
- default:
12582
- return undefined;
12583
- }
12584
- }
12585
- /**
12586
- * Recursively finds the parent ID of a target layer option within a tree structure.
12587
- *
12588
- * @param tree - The array of layer options representing the tree structure.
12589
- * @param target - The target layer option whose parent ID is to be found.
12590
- * @param path - The current path of IDs traversed during the search (used internally).
12591
- * @returns The parent ID as a dot-separated string, or undefined if no parent is found.
12592
- */
12593
- function findParentId(tree, target, path = []) {
12594
- const targetId = getLayerOptionIdentifier(target);
12595
- for (const node of tree) {
12596
- const currentPath = node.id ? [...path, node.id.toString()] : [...path];
12597
- if (isLayerGroupOptions(node) && node.children) {
12598
- for (const child of node.children) {
12599
- // Check if the current child node matches the target node by comparing their IDs
12600
- if (getLayerOptionIdentifier(child) === targetId) {
12601
- const targetPath = currentPath?.join('.');
12602
- return targetPath === undefined || targetPath === ''
12603
- ? undefined
12604
- : targetPath;
12668
+ const layerTooltip = layerOptions.tooltip;
12669
+ const layerMetadata = layerOptions.metadata;
12670
+ switch (layerOptions.tooltip.type) {
12671
+ case TooltipType.TITLE:
12672
+ return this.layer().title;
12673
+ case TooltipType.ABSTRACT:
12674
+ if (layerMetadata && layerMetadata.abstract) {
12675
+ return layerMetadata.abstract;
12605
12676
  }
12606
- }
12607
- const result = findParentId(node.children, target, currentPath);
12608
- if (result) {
12609
- return result;
12610
- }
12677
+ else {
12678
+ return this.layer().title;
12679
+ }
12680
+ case TooltipType.CUSTOM:
12681
+ if (layerTooltip && layerTooltip.text) {
12682
+ return layerTooltip.text;
12683
+ }
12684
+ else {
12685
+ return this.layer().title;
12686
+ }
12687
+ default:
12688
+ return this.layer().title;
12611
12689
  }
12612
12690
  }
12613
- return undefined;
12691
+ onResolutionChange() {
12692
+ const inResolutionRange = this.layer().isInResolutionsRange;
12693
+ this.inResolutionRange$.next(inResolutionRange);
12694
+ }
12695
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerLegendItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12696
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.18", type: LayerLegendItemComponent, isStandalone: true, selector: "igo-layer-legend-item", inputs: { layer: { classPropertyName: "layer", publicName: "layer", isSignal: true, isRequired: false, transformFunction: null }, updateLegendOnResolutionChange: { classPropertyName: "updateLegendOnResolutionChange", publicName: "updateLegendOnResolutionChange", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-list-item class=\"igo-layer-list-item\">\n <span\n matListItemTitle\n class=\"igo-layer-title\"\n [matTooltip]=\"tooltipText\"\n matTooltipShowDelay=\"500\"\n >{{ layer().title }}</span\n >\n</mat-list-item>\n\n<div #legend class=\"igo-layer-legend-container\">\n <igo-layer-legend\n [layer]=\"layer()\"\n [updateLegendOnResolutionChange]=\"updateLegendOnResolutionChange()\"\n />\n</div>\n", styles: [":host{overflow:hidden}:host .igo-layer-list-item{height:48px;clear:both}:host .igo-layer-legend-container{padding-left:18px;width:calc(100% - 18px)}\n"], dependencies: [{ kind: "ngmodule", type: MatListModule }, { kind: "component", type: i1$2.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i1$2.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: LayerLegendComponent, selector: "igo-layer-legend", inputs: ["updateLegendOnResolutionChange", "layer"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12614
12697
  }
12698
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerLegendItemComponent, decorators: [{
12699
+ type: Component,
12700
+ args: [{ selector: 'igo-layer-legend-item', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatListModule, MatTooltipModule, LayerLegendComponent], template: "<mat-list-item class=\"igo-layer-list-item\">\n <span\n matListItemTitle\n class=\"igo-layer-title\"\n [matTooltip]=\"tooltipText\"\n matTooltipShowDelay=\"500\"\n >{{ layer().title }}</span\n >\n</mat-list-item>\n\n<div #legend class=\"igo-layer-legend-container\">\n <igo-layer-legend\n [layer]=\"layer()\"\n [updateLegendOnResolutionChange]=\"updateLegendOnResolutionChange()\"\n />\n</div>\n", styles: [":host{overflow:hidden}:host .igo-layer-list-item{height:48px;clear:both}:host .igo-layer-legend-container{padding-left:18px;width:calc(100% - 18px)}\n"] }]
12701
+ }], propDecorators: { layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "layer", required: false }] }], updateLegendOnResolutionChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "updateLegendOnResolutionChange", required: false }] }] } });
12615
12702
 
12616
12703
  class LayerLegendListComponent {
12617
12704
  orderable = true;
@@ -12629,21 +12716,21 @@ class LayerLegendListComponent {
12629
12716
  isLayerItem = isLayerItem;
12630
12717
  constructor() {
12631
12718
  effect(() => {
12632
- const layers = this.computeShownLayers(this.layers());
12719
+ const layers = this.layers() ?? [];
12720
+ const shownLayers = this.computeShownLayers(layers);
12721
+ this.layersLegend.set(shownLayers);
12633
12722
  this.handleLayersChange(layers);
12634
12723
  });
12635
12724
  }
12636
12725
  handleLayersChange(layers) {
12637
- this.layersLegend.set(layers);
12638
- const layersValue = this.layers();
12639
- this.hasVisibleOrInRangeLayers.set(layersValue
12726
+ this.hasVisibleOrInRangeLayers.set(layers
12640
12727
  .filter((layer) => !isBaseLayer(layer))
12641
12728
  .filter((layer) => layer.displayed).length > 0);
12642
- this.hasVisibleAndNotInRangeLayers.set(layersValue
12729
+ this.hasVisibleAndNotInRangeLayers.set(layers
12643
12730
  .filter((layer) => !isBaseLayer(layer))
12644
12731
  .filter((layer) => layer.visible && !layer.isInResolutionsRange)
12645
12732
  .length > 0);
12646
- this.layersInUi.set(layersValue.filter((layer) => layer.showInLayerList !== false &&
12733
+ this.layersInUi.set(layers.filter((layer) => layer.showInLayerList !== false &&
12647
12734
  (!this.excludeBaseLayers() || !isBaseLayer(layer))) ?? []);
12648
12735
  }
12649
12736
  computeShownLayers(layers) {
@@ -12679,34 +12766,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
12679
12766
 
12680
12767
  class LayerLegendListBindingDirective {
12681
12768
  mapService = inject(MapService);
12682
- component;
12683
- layersOrResolutionChange$$;
12684
- layersVisibility$$;
12685
- constructor() {
12686
- this.component = inject(LayerLegendListComponent, { self: true });
12687
- }
12769
+ component = inject(LayerLegendListComponent, { self: true });
12770
+ destroyRef = inject(DestroyRef);
12688
12771
  ngOnInit() {
12689
- const map = this.mapService.getMap();
12690
- // Override input layers
12691
- this.component.setLayers([]);
12692
- this.layersOrResolutionChange$$ = combineLatest([
12693
- map.layerController.all$,
12694
- map.viewController.resolution$
12772
+ const mapInstance = this.mapService.getMap();
12773
+ combineLatest([
12774
+ mapInstance.layerController.all$,
12775
+ mapInstance.viewController.resolution$
12695
12776
  ])
12696
- .pipe(debounceTime(10))
12697
- .subscribe((bunch) => {
12698
- const shownLayers = bunch[0].filter((layer) => {
12699
- return isLayerItem(layer) && layer.showInLayerList === true;
12700
- });
12701
- this.component.setLayers(shownLayers);
12702
- });
12703
- }
12704
- ngOnDestroy() {
12705
- this.layersOrResolutionChange$$.unsubscribe();
12706
- if (this.layersVisibility$$ !== undefined) {
12707
- this.layersVisibility$$.unsubscribe();
12708
- this.layersVisibility$$ = undefined;
12709
- }
12777
+ .pipe(debounceTime(10), switchMap$1(([layers]) => {
12778
+ const shownLayers = layers.filter((layer) => isLayerItem(layer) && layer.showInLayerList === true);
12779
+ if (shownLayers.length === 0) {
12780
+ return of(shownLayers);
12781
+ }
12782
+ return merge(of(shownLayers), merge(...shownLayers.map((l) => l.displayed$)).pipe(map(() => [...shownLayers])));
12783
+ }), takeUntilDestroyed(this.destroyRef))
12784
+ .subscribe((shownLayers) => this.component.setLayers(shownLayers));
12710
12785
  }
12711
12786
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerLegendListBindingDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
12712
12787
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.18", type: LayerLegendListBindingDirective, isStandalone: true, selector: "[igoLayerLegendListBinding]", ngImport: i0 });
@@ -12717,7 +12792,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
12717
12792
  selector: '[igoLayerLegendListBinding]',
12718
12793
  standalone: true
12719
12794
  }]
12720
- }], ctorParameters: () => [] });
12795
+ }] });
12721
12796
 
12722
12797
  class LayerSearchComponent {
12723
12798
  control = new FormControl();
@@ -12862,7 +12937,7 @@ var LayerListControlsEnum;
12862
12937
  class LayerListComponent {
12863
12938
  messageService = inject(MessageService);
12864
12939
  toggleOpacity = false;
12865
- isInit;
12940
+ expansionKey = (node) => String(node.id);
12866
12941
  controller = input.required(...(ngDevMode ? [{ debugName: "controller" }] : []));
12867
12942
  layers = input.required(...(ngDevMode ? [{ debugName: "layers" }] : []));
12868
12943
  isDesktop = input(undefined, ...(ngDevMode ? [{ debugName: "isDesktop" }] : []));
@@ -12870,32 +12945,31 @@ class LayerListComponent {
12870
12945
  selectAll = input(undefined, ...(ngDevMode ? [{ debugName: "selectAll" }] : []));
12871
12946
  viewerOptions = input(undefined, ...(ngDevMode ? [{ debugName: "viewerOptions" }] : []));
12872
12947
  activeChange = output();
12873
- _transformer = (layer, level) => {
12874
- return {
12875
- id: layer.id?.toString() || layer.options.name,
12876
- isGroup: !!isLayerGroup(layer),
12877
- descendantLevels: isLayerGroup(layer)
12878
- ? layer.descendantsLevel
12879
- : undefined,
12880
- level: level,
12881
- data: layer,
12882
- disabled: false
12883
- };
12948
+ tree = viewChild(MatTree, ...(ngDevMode ? [{ debugName: "tree" }] : []));
12949
+ childrenAccessor = (layer) => {
12950
+ if (isLayerGroup(layer)) {
12951
+ return layer.children
12952
+ .filter((l) => l.showInLayerList)
12953
+ .sort((a, b) => a.zIndex + b.zIndex);
12954
+ }
12955
+ return [];
12884
12956
  };
12885
- treeControl = new FlatTreeControl((node) => node.level, (node) => node.isGroup);
12886
- treeFlattener = new MatTreeFlattener(this._transformer, (node) => node.level, (node) => node.isGroup, (node) => node.children
12887
- .filter((layer) => layer.showInLayerList)
12888
- .sort((a, b) => a.zIndex + b.zIndex));
12889
- dataSource;
12890
- constructor() {
12891
- this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener, []);
12892
- effect(() => this.updateDatasource(this.layers() ?? []));
12893
- }
12894
- isGroup = (_, node) => node.isGroup;
12957
+ treeConfig = {
12958
+ isGroup: (layer) => isLayerGroup(layer),
12959
+ descendantLevels: (layer) => isLayerGroup(layer) ? layer.descendantsLevel : undefined
12960
+ };
12961
+ isNodeGroup = (_, node) => isLayerGroup(node);
12895
12962
  isLayerGroup = isLayerGroup;
12896
12963
  isLayerItem = isLayerItem;
12897
12964
  isSelected = (layer) => this.controller().isSelected(layer);
12898
12965
  isDescendantSelection = (layer) => this.controller().isDescendantSelection(layer);
12966
+ ngAfterViewInit() {
12967
+ const layers = this.layers();
12968
+ const tree = this.tree();
12969
+ if (tree && layers) {
12970
+ this.expandGroup(layers, tree);
12971
+ }
12972
+ }
12899
12973
  toggleActive(layer) {
12900
12974
  const isSelected = this.controller().isSelected(layer);
12901
12975
  this.controller().clearSelection();
@@ -12931,34 +13005,37 @@ class LayerListComponent {
12931
13005
  ? 'draw'
12932
13006
  : VECTOR_SQUARE_ICON;
12933
13007
  }
12934
- dropNode({ node, ref, position }) {
12935
- let nodesToDrop = [node.data];
13008
+ trackByFn(_index, node) {
13009
+ return String(node.id);
13010
+ }
13011
+ dropNode(event) {
13012
+ const { node, ref, position } = event;
13013
+ let nodesToDrop = [node];
12936
13014
  const controller = this.controller();
12937
13015
  if (controller.hasSelection) {
12938
- // The selection could contains data from the outside the TreeController
12939
- nodesToDrop = controller.selected.filter((layer) => !!this.findNodeByLayerId(layer.id));
13016
+ nodesToDrop = controller.selected;
12940
13017
  }
12941
- if (node.isGroup) {
12942
- nodesToDrop = nodesToDrop.filter((nodeDrop) => !node.data.isDescendant(nodeDrop));
13018
+ if (isLayerGroup(node)) {
13019
+ nodesToDrop = nodesToDrop.filter((nodeDrop) => !node.isDescendant(nodeDrop));
12943
13020
  }
12944
- if (ref.isGroup) {
13021
+ if (isLayerGroup(ref)) {
12945
13022
  const isSelected = nodesToDrop.some((nodeDrop) => nodeDrop.id === ref.id);
12946
13023
  if (isSelected) {
12947
13024
  nodesToDrop = nodesToDrop.filter((nodeDrop) => nodeDrop.id !== ref.id);
12948
13025
  }
12949
13026
  }
12950
- if (!nodesToDrop.includes(node.data)) {
12951
- nodesToDrop.push(node.data);
13027
+ if (!nodesToDrop.includes(node)) {
13028
+ nodesToDrop.push(node);
12952
13029
  }
12953
13030
  switch (position) {
12954
13031
  case 'above':
12955
- controller.moveAbove(ref.data, ...nodesToDrop);
13032
+ controller.moveAbove(ref, ...nodesToDrop);
12956
13033
  break;
12957
13034
  case 'inside':
12958
- controller.moveInside(ref.data, ...nodesToDrop);
13035
+ controller.moveInside(ref, ...nodesToDrop);
12959
13036
  break;
12960
13037
  default:
12961
- controller.moveBelow(ref.data, ...nodesToDrop);
13038
+ controller.moveBelow(ref, ...nodesToDrop);
12962
13039
  break;
12963
13040
  }
12964
13041
  }
@@ -12972,48 +13049,26 @@ class LayerListComponent {
12972
13049
  this.controller().clearSelection();
12973
13050
  }
12974
13051
  handleNodeToggle(node) {
12975
- node.data.expanded = this.treeControl.isExpanded(node);
12976
- }
12977
- findNodeByLayerId(id) {
12978
- return this.treeControl.dataNodes.find((node) => node.id === id);
12979
- }
12980
- updateDatasource(layers) {
12981
- const expansionModel = this.treeControl.expansionModel;
12982
- this.dataSource.data = layers;
12983
- this.isInit
12984
- ? this.restoreModel(expansionModel, (node) => this.treeControl.expand(node))
12985
- : this.expandGroup(layers);
12986
- if (!this.isInit && layers.length) {
12987
- this.isInit = true;
13052
+ if (!isLayerGroup(node)) {
13053
+ return;
12988
13054
  }
13055
+ const tree = this.tree();
13056
+ tree.toggle(node);
13057
+ node.expanded = tree.isExpanded(node);
12989
13058
  }
12990
- /** Recursive */
12991
- expandGroup(layers) {
13059
+ expandGroup(layers, tree) {
12992
13060
  layers.forEach((layer) => {
12993
13061
  if (!isLayerGroup(layer)) {
12994
13062
  return;
12995
13063
  }
12996
13064
  if (layer.expanded) {
12997
- const node = this.findNodeByLayerId(layer.id);
12998
- if (!node) {
12999
- return;
13000
- }
13001
- this.treeControl.expand(node);
13002
- }
13003
- this.expandGroup(layer.children);
13004
- });
13005
- }
13006
- restoreModel(model, callback) {
13007
- const ids = Array.from(model['_selection']).map((value) => value['id']);
13008
- model.clear();
13009
- this.treeControl.dataNodes.forEach((node) => {
13010
- if (model.isSelected(node) || ids.includes(node.id)) {
13011
- callback(node);
13065
+ tree.expand(layer);
13012
13066
  }
13067
+ this.expandGroup(layer.children, tree);
13013
13068
  });
13014
13069
  }
13015
13070
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13016
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.18", type: LayerListComponent, isStandalone: true, selector: "igo-layer-list", inputs: { controller: { classPropertyName: "controller", publicName: "controller", isSignal: true, isRequired: true, transformFunction: null }, layers: { classPropertyName: "layers", publicName: "layers", isSignal: true, isRequired: true, transformFunction: null }, isDesktop: { classPropertyName: "isDesktop", publicName: "isDesktop", isSignal: true, isRequired: false, transformFunction: null }, isDragDropDisabled: { classPropertyName: "isDragDropDisabled", publicName: "isDragDropDisabled", isSignal: true, isRequired: false, transformFunction: null }, selectAll: { classPropertyName: "selectAll", publicName: "selectAll", isSignal: true, isRequired: false, transformFunction: null }, viewerOptions: { classPropertyName: "viewerOptions", publicName: "viewerOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeChange: "activeChange" }, ngImport: i0, template: "<mat-tree\n [class.--not-desktop]=\"!isDesktop()\"\n igoTreeDragDrop\n [treeDragDropIsDisabled]=\"isDragDropDisabled()\"\n [maxLevel]=\"viewerOptions()?.group?.maxHierarchyLevel\"\n [dataSource]=\"dataSource\"\n [treeControl]=\"treeControl\"\n (dragStart)=\"dragStart()\"\n (onDrop)=\"dropNode($event)\"\n (onDropError)=\"dropNodeError($event)\"\n>\n <!-- This is the tree node template for leaf nodes -->\n <mat-tree-node\n *matTreeNodeDef=\"let node\"\n [class.--selected]=\"isSelected(node.data)\"\n [class.--children-selected]=\"isDescendantSelection(node.data)\"\n >\n <igo-layer-item\n [matTreeNodePadding]=\"node.level === 0 ? 1 : node.level\"\n [matTreeNodePaddingIndent]=\"node.level === 0 ? 16 : 24 + 16 / node.level\"\n class=\"tree-node-item\"\n [layer]=\"node.data\"\n [visible]=\"node.data.visible\"\n [viewerOptions]=\"viewerOptions()\"\n [selected]=\"isSelected(node.data) || isDescendantSelection(node.data)\"\n [selectionDisabled]=\"isDescendantSelection(node.data)\"\n (action)=\"toggleActive($event)\"\n (selectChange)=\"handleSelect($event, node.data)\"\n />\n </mat-tree-node>\n <!-- This is the tree node template for expandable nodes -->\n <mat-tree-node\n *matTreeNodeDef=\"let node; when: isGroup\"\n [class.--selected]=\"isSelected(node.data)\"\n [class.--children-selected]=\"isDescendantSelection(node.data)\"\n >\n <igo-layer-group\n matTreeNodePadding\n [matTreeNodePaddingIndent]=\"24\"\n class=\"tree-node-item\"\n [layer]=\"node.data\"\n [viewerOptions]=\"viewerOptions()\"\n [selected]=\"isSelected(node.data) || isDescendantSelection(node.data)\"\n [selectionDisabled]=\"isDescendantSelection(node.data)\"\n (action)=\"toggleActive($event)\"\n (expand)=\"treeControl.toggle(node); handleNodeToggle(node)\"\n (selectChange)=\"handleSelect($event, node.data)\"\n >\n <button\n mat-icon-button\n matTreeNodeToggle\n class=\"layer-indicator\"\n [attr.aria-label]=\"'Toggle ' + node.data.title\"\n (click)=\"handleNodeToggle(node)\"\n >\n <mat-icon class=\"mat-icon-rtl-mirror\">\n {{\n treeControl.isExpanded(node)\n ? 'keyboard_arrow_down'\n : 'keyboard_arrow_right'\n }}\n </mat-icon>\n </button>\n </igo-layer-group>\n </mat-tree-node>\n</mat-tree>\n", styles: [".--not-desktop igo-layer-group ::ng-deep .list-secondary-actions button,.--not-desktop igo-layer-item ::ng-deep .list-secondary-actions button{visibility:visible!important}.tree-node-item{flex:1}mat-tree-node{position:relative;min-height:40px;font:var(--mat-sys-body-medium)}mat-tree-node:hover:after,mat-tree-node.--drag-hover:after{content:\"\";position:absolute;inset:0;border-style:solid;border-width:1px;border-color:transparent;pointer-events:none}mat-tree-node.--selected igo-layer-group,mat-tree-node.--selected igo-layer-item,mat-tree-node.--dragged igo-layer-group,mat-tree-node.--dragged igo-layer-item{background-color:var(--mat-sys-secondary-fixed-dim);color:var(--mat-sys-on-tertiary-fixed)}mat-tree-node.--children-selected igo-layer-group,mat-tree-node.--children-selected igo-layer-item{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-tertiary-fixed)}mat-tree-node.--drag-hover:after{border-color:var(--mat-sys-tertiary)!important}mat-tree:not(.--dragging) mat-tree-node:hover:after{border-color:var(--mat-sys-tertiary)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatSliderModule }, { kind: "ngmodule", type: MatTreeModule }, { kind: "directive", type: i8.MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "directive", type: i8.MatTreeNodePadding, selector: "[matTreeNodePadding]", inputs: ["matTreeNodePadding", "matTreeNodePaddingIndent"] }, { kind: "directive", type: i8.MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "component", type: i8.MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: i8.MatTreeNode, selector: "mat-tree-node", inputs: ["tabIndex", "disabled"], outputs: ["activation", "expandedChange"], exportAs: ["matTreeNode"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: TreeDragDropDirective, selector: "[igoTreeDragDrop]", inputs: ["treeControl", "maxLevel", "treeDragDropIsDisabled"], outputs: ["dragStart", "onDrop", "onDropError"] }, { kind: "component", type: LayerGroupComponent, selector: "igo-layer-group", inputs: ["layer", "viewerOptions", "selected", "selectionDisabled"], outputs: ["action", "visibilityChange", "expand", "selectChange"] }, { kind: "component", type: LayerItemComponent, selector: "igo-layer-item", inputs: ["layer", "visible", "selected", "selectionDisabled", "viewerOptions"], outputs: ["action", "selectChange", "visibilityChange"] }, { kind: "ngmodule", type: IgoLanguageModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13071
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.18", type: LayerListComponent, isStandalone: true, selector: "igo-layer-list", inputs: { controller: { classPropertyName: "controller", publicName: "controller", isSignal: true, isRequired: true, transformFunction: null }, layers: { classPropertyName: "layers", publicName: "layers", isSignal: true, isRequired: true, transformFunction: null }, isDesktop: { classPropertyName: "isDesktop", publicName: "isDesktop", isSignal: true, isRequired: false, transformFunction: null }, isDragDropDisabled: { classPropertyName: "isDragDropDisabled", publicName: "isDragDropDisabled", isSignal: true, isRequired: false, transformFunction: null }, selectAll: { classPropertyName: "selectAll", publicName: "selectAll", isSignal: true, isRequired: false, transformFunction: null }, viewerOptions: { classPropertyName: "viewerOptions", publicName: "viewerOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeChange: "activeChange" }, viewQueries: [{ propertyName: "tree", first: true, predicate: MatTree, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-tree\n #tree\n [class.--not-desktop]=\"!isDesktop()\"\n igoTreeDragDrop\n [tree]=\"tree\"\n [config]=\"treeConfig\"\n [treeDragDropIsDisabled]=\"isDragDropDisabled()\"\n [maxLevel]=\"viewerOptions()?.group?.maxHierarchyLevel\"\n [dataSource]=\"layers()\"\n [childrenAccessor]=\"childrenAccessor\"\n [trackBy]=\"trackByFn\"\n [expansionKey]=\"expansionKey\"\n (dragStart)=\"dragStart()\"\n (dropped)=\"dropNode($event)\"\n (droppedError)=\"dropNodeError($event)\"\n>\n <!-- This is the tree node template for leaf nodes -->\n <mat-tree-node\n #treeNode=\"matTreeNode\"\n *matTreeNodeDef=\"let node\"\n [class.--selected]=\"isSelected(node)\"\n [class.--children-selected]=\"isDescendantSelection(node)\"\n >\n <igo-layer-item\n [matTreeNodePadding]=\"treeNode.level === 0 ? 1 : treeNode.level\"\n [matTreeNodePaddingIndent]=\"\n treeNode.level === 0 ? 16 : 24 + 16 / treeNode.level\n \"\n class=\"tree-node-item\"\n [layer]=\"node\"\n [visible]=\"node.visible\"\n [viewerOptions]=\"viewerOptions()\"\n [selected]=\"isSelected(node) || isDescendantSelection(node)\"\n [selectionDisabled]=\"isDescendantSelection(node)\"\n (action)=\"toggleActive($event)\"\n (selectChange)=\"handleSelect($event, node)\"\n />\n </mat-tree-node>\n <!-- This is the tree node template for expandable nodes -->\n <mat-tree-node\n #treeNode=\"matTreeNode\"\n *matTreeNodeDef=\"let node; when: isNodeGroup\"\n [class.--selected]=\"isSelected(node)\"\n [class.--children-selected]=\"isDescendantSelection(node)\"\n >\n <igo-layer-group\n [matTreeNodePadding]=\"treeNode.level\"\n [matTreeNodePaddingIndent]=\"24\"\n class=\"tree-node-item\"\n [layer]=\"node\"\n [viewerOptions]=\"viewerOptions()\"\n [selected]=\"isSelected(node) || isDescendantSelection(node)\"\n [selectionDisabled]=\"isDescendantSelection(node)\"\n (action)=\"toggleActive($event)\"\n (expand)=\"handleNodeToggle(node)\"\n (selectChange)=\"handleSelect($event, node)\"\n >\n <button\n mat-icon-button\n class=\"layer-indicator\"\n [attr.aria-label]=\"'Toggle ' + node.title\"\n (click)=\"handleNodeToggle(node)\"\n >\n <mat-icon class=\"mat-icon-rtl-mirror\">\n {{\n tree.isExpanded(node)\n ? 'keyboard_arrow_down'\n : 'keyboard_arrow_right'\n }}\n </mat-icon>\n </button>\n </igo-layer-group>\n </mat-tree-node>\n</mat-tree>\n", styles: [".--not-desktop igo-layer-group ::ng-deep .list-secondary-actions button,.--not-desktop igo-layer-item ::ng-deep .list-secondary-actions button{visibility:visible!important}.tree-node-item{flex:1}mat-tree-node{position:relative;min-height:40px;font:var(--mat-sys-body-medium)}mat-tree-node:hover:after,mat-tree-node.--drag-hover:after{content:\"\";position:absolute;inset:0;border-style:solid;border-width:1px;border-color:transparent;pointer-events:none}mat-tree-node.--selected igo-layer-group,mat-tree-node.--selected igo-layer-item,mat-tree-node.--dragged igo-layer-group,mat-tree-node.--dragged igo-layer-item{background-color:var(--mat-sys-secondary-fixed-dim);color:var(--mat-sys-on-tertiary-fixed)}mat-tree-node.--children-selected igo-layer-group,mat-tree-node.--children-selected igo-layer-item{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-tertiary-fixed)}mat-tree-node.--drag-hover:after{border-color:var(--mat-sys-tertiary)!important}mat-tree:not(.--dragging) mat-tree-node:hover:after{border-color:var(--mat-sys-tertiary)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatSliderModule }, { kind: "ngmodule", type: MatTreeModule }, { kind: "directive", type: i8.MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "directive", type: i8.MatTreeNodePadding, selector: "[matTreeNodePadding]", inputs: ["matTreeNodePadding", "matTreeNodePaddingIndent"] }, { kind: "component", type: i8.MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: i8.MatTreeNode, selector: "mat-tree-node", inputs: ["tabIndex", "disabled"], outputs: ["activation", "expandedChange"], exportAs: ["matTreeNode"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: TreeDragDropDirective, selector: "[igoTreeDragDrop]", inputs: ["tree", "childrenAccessor", "config", "maxLevel", "treeDragDropIsDisabled"], outputs: ["dragStart", "dropped", "droppedError"] }, { kind: "component", type: LayerGroupComponent, selector: "igo-layer-group", inputs: ["layer", "viewerOptions", "selected", "selectionDisabled"], outputs: ["action", "visibilityChange", "expand", "selectChange"] }, { kind: "component", type: LayerItemComponent, selector: "igo-layer-item", inputs: ["layer", "visible", "selected", "selectionDisabled", "viewerOptions"], outputs: ["action", "selectChange", "visibilityChange"] }, { kind: "ngmodule", type: IgoLanguageModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13017
13072
  }
13018
13073
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerListComponent, decorators: [{
13019
13074
  type: Component,
@@ -13032,8 +13087,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
13032
13087
  LayerGroupComponent,
13033
13088
  LayerItemComponent,
13034
13089
  IgoLanguageModule
13035
- ], template: "<mat-tree\n [class.--not-desktop]=\"!isDesktop()\"\n igoTreeDragDrop\n [treeDragDropIsDisabled]=\"isDragDropDisabled()\"\n [maxLevel]=\"viewerOptions()?.group?.maxHierarchyLevel\"\n [dataSource]=\"dataSource\"\n [treeControl]=\"treeControl\"\n (dragStart)=\"dragStart()\"\n (onDrop)=\"dropNode($event)\"\n (onDropError)=\"dropNodeError($event)\"\n>\n <!-- This is the tree node template for leaf nodes -->\n <mat-tree-node\n *matTreeNodeDef=\"let node\"\n [class.--selected]=\"isSelected(node.data)\"\n [class.--children-selected]=\"isDescendantSelection(node.data)\"\n >\n <igo-layer-item\n [matTreeNodePadding]=\"node.level === 0 ? 1 : node.level\"\n [matTreeNodePaddingIndent]=\"node.level === 0 ? 16 : 24 + 16 / node.level\"\n class=\"tree-node-item\"\n [layer]=\"node.data\"\n [visible]=\"node.data.visible\"\n [viewerOptions]=\"viewerOptions()\"\n [selected]=\"isSelected(node.data) || isDescendantSelection(node.data)\"\n [selectionDisabled]=\"isDescendantSelection(node.data)\"\n (action)=\"toggleActive($event)\"\n (selectChange)=\"handleSelect($event, node.data)\"\n />\n </mat-tree-node>\n <!-- This is the tree node template for expandable nodes -->\n <mat-tree-node\n *matTreeNodeDef=\"let node; when: isGroup\"\n [class.--selected]=\"isSelected(node.data)\"\n [class.--children-selected]=\"isDescendantSelection(node.data)\"\n >\n <igo-layer-group\n matTreeNodePadding\n [matTreeNodePaddingIndent]=\"24\"\n class=\"tree-node-item\"\n [layer]=\"node.data\"\n [viewerOptions]=\"viewerOptions()\"\n [selected]=\"isSelected(node.data) || isDescendantSelection(node.data)\"\n [selectionDisabled]=\"isDescendantSelection(node.data)\"\n (action)=\"toggleActive($event)\"\n (expand)=\"treeControl.toggle(node); handleNodeToggle(node)\"\n (selectChange)=\"handleSelect($event, node.data)\"\n >\n <button\n mat-icon-button\n matTreeNodeToggle\n class=\"layer-indicator\"\n [attr.aria-label]=\"'Toggle ' + node.data.title\"\n (click)=\"handleNodeToggle(node)\"\n >\n <mat-icon class=\"mat-icon-rtl-mirror\">\n {{\n treeControl.isExpanded(node)\n ? 'keyboard_arrow_down'\n : 'keyboard_arrow_right'\n }}\n </mat-icon>\n </button>\n </igo-layer-group>\n </mat-tree-node>\n</mat-tree>\n", styles: [".--not-desktop igo-layer-group ::ng-deep .list-secondary-actions button,.--not-desktop igo-layer-item ::ng-deep .list-secondary-actions button{visibility:visible!important}.tree-node-item{flex:1}mat-tree-node{position:relative;min-height:40px;font:var(--mat-sys-body-medium)}mat-tree-node:hover:after,mat-tree-node.--drag-hover:after{content:\"\";position:absolute;inset:0;border-style:solid;border-width:1px;border-color:transparent;pointer-events:none}mat-tree-node.--selected igo-layer-group,mat-tree-node.--selected igo-layer-item,mat-tree-node.--dragged igo-layer-group,mat-tree-node.--dragged igo-layer-item{background-color:var(--mat-sys-secondary-fixed-dim);color:var(--mat-sys-on-tertiary-fixed)}mat-tree-node.--children-selected igo-layer-group,mat-tree-node.--children-selected igo-layer-item{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-tertiary-fixed)}mat-tree-node.--drag-hover:after{border-color:var(--mat-sys-tertiary)!important}mat-tree:not(.--dragging) mat-tree-node:hover:after{border-color:var(--mat-sys-tertiary)}\n"] }]
13036
- }], ctorParameters: () => [], propDecorators: { controller: [{ type: i0.Input, args: [{ isSignal: true, alias: "controller", required: true }] }], layers: [{ type: i0.Input, args: [{ isSignal: true, alias: "layers", required: true }] }], isDesktop: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDesktop", required: false }] }], isDragDropDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDragDropDisabled", required: false }] }], selectAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAll", required: false }] }], viewerOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewerOptions", required: false }] }], activeChange: [{ type: i0.Output, args: ["activeChange"] }] } });
13090
+ ], template: "<mat-tree\n #tree\n [class.--not-desktop]=\"!isDesktop()\"\n igoTreeDragDrop\n [tree]=\"tree\"\n [config]=\"treeConfig\"\n [treeDragDropIsDisabled]=\"isDragDropDisabled()\"\n [maxLevel]=\"viewerOptions()?.group?.maxHierarchyLevel\"\n [dataSource]=\"layers()\"\n [childrenAccessor]=\"childrenAccessor\"\n [trackBy]=\"trackByFn\"\n [expansionKey]=\"expansionKey\"\n (dragStart)=\"dragStart()\"\n (dropped)=\"dropNode($event)\"\n (droppedError)=\"dropNodeError($event)\"\n>\n <!-- This is the tree node template for leaf nodes -->\n <mat-tree-node\n #treeNode=\"matTreeNode\"\n *matTreeNodeDef=\"let node\"\n [class.--selected]=\"isSelected(node)\"\n [class.--children-selected]=\"isDescendantSelection(node)\"\n >\n <igo-layer-item\n [matTreeNodePadding]=\"treeNode.level === 0 ? 1 : treeNode.level\"\n [matTreeNodePaddingIndent]=\"\n treeNode.level === 0 ? 16 : 24 + 16 / treeNode.level\n \"\n class=\"tree-node-item\"\n [layer]=\"node\"\n [visible]=\"node.visible\"\n [viewerOptions]=\"viewerOptions()\"\n [selected]=\"isSelected(node) || isDescendantSelection(node)\"\n [selectionDisabled]=\"isDescendantSelection(node)\"\n (action)=\"toggleActive($event)\"\n (selectChange)=\"handleSelect($event, node)\"\n />\n </mat-tree-node>\n <!-- This is the tree node template for expandable nodes -->\n <mat-tree-node\n #treeNode=\"matTreeNode\"\n *matTreeNodeDef=\"let node; when: isNodeGroup\"\n [class.--selected]=\"isSelected(node)\"\n [class.--children-selected]=\"isDescendantSelection(node)\"\n >\n <igo-layer-group\n [matTreeNodePadding]=\"treeNode.level\"\n [matTreeNodePaddingIndent]=\"24\"\n class=\"tree-node-item\"\n [layer]=\"node\"\n [viewerOptions]=\"viewerOptions()\"\n [selected]=\"isSelected(node) || isDescendantSelection(node)\"\n [selectionDisabled]=\"isDescendantSelection(node)\"\n (action)=\"toggleActive($event)\"\n (expand)=\"handleNodeToggle(node)\"\n (selectChange)=\"handleSelect($event, node)\"\n >\n <button\n mat-icon-button\n class=\"layer-indicator\"\n [attr.aria-label]=\"'Toggle ' + node.title\"\n (click)=\"handleNodeToggle(node)\"\n >\n <mat-icon class=\"mat-icon-rtl-mirror\">\n {{\n tree.isExpanded(node)\n ? 'keyboard_arrow_down'\n : 'keyboard_arrow_right'\n }}\n </mat-icon>\n </button>\n </igo-layer-group>\n </mat-tree-node>\n</mat-tree>\n", styles: [".--not-desktop igo-layer-group ::ng-deep .list-secondary-actions button,.--not-desktop igo-layer-item ::ng-deep .list-secondary-actions button{visibility:visible!important}.tree-node-item{flex:1}mat-tree-node{position:relative;min-height:40px;font:var(--mat-sys-body-medium)}mat-tree-node:hover:after,mat-tree-node.--drag-hover:after{content:\"\";position:absolute;inset:0;border-style:solid;border-width:1px;border-color:transparent;pointer-events:none}mat-tree-node.--selected igo-layer-group,mat-tree-node.--selected igo-layer-item,mat-tree-node.--dragged igo-layer-group,mat-tree-node.--dragged igo-layer-item{background-color:var(--mat-sys-secondary-fixed-dim);color:var(--mat-sys-on-tertiary-fixed)}mat-tree-node.--children-selected igo-layer-group,mat-tree-node.--children-selected igo-layer-item{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-tertiary-fixed)}mat-tree-node.--drag-hover:after{border-color:var(--mat-sys-tertiary)!important}mat-tree:not(.--dragging) mat-tree-node:hover:after{border-color:var(--mat-sys-tertiary)}\n"] }]
13091
+ }], propDecorators: { controller: [{ type: i0.Input, args: [{ isSignal: true, alias: "controller", required: true }] }], layers: [{ type: i0.Input, args: [{ isSignal: true, alias: "layers", required: true }] }], isDesktop: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDesktop", required: false }] }], isDragDropDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDragDropDisabled", required: false }] }], selectAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAll", required: false }] }], viewerOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewerOptions", required: false }] }], activeChange: [{ type: i0.Output, args: ["activeChange"] }], tree: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatTree), { isSignal: true }] }] } });
13037
13092
 
13038
13093
  class LayerUnavailableComponent {
13039
13094
  layerOptions = input(undefined, ...(ngDevMode ? [{ debugName: "layerOptions" }] : []));
@@ -13122,6 +13177,7 @@ class LayerViewerBottomActionsComponent {
13122
13177
  return isLayerGroup(layer);
13123
13178
  }
13124
13179
  isLayerItem = isLayerItem;
13180
+ isLayerGroup = isLayerGroup;
13125
13181
  handleRename() {
13126
13182
  const layer = this.selected[0];
13127
13183
  this.layerListToolService.renameGroup(layer).subscribe((name) => {
@@ -13238,7 +13294,7 @@ class LayerViewerBottomActionsComponent {
13238
13294
  return layer.options.removable !== false;
13239
13295
  }
13240
13296
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerViewerBottomActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13241
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: LayerViewerBottomActionsComponent, isStandalone: true, selector: "igo-layer-viewer-bottom-actions", inputs: { map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: true, transformFunction: null }, controller: { classPropertyName: "controller", publicName: "controller", isSignal: true, isRequired: true, transformFunction: null }, searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: true, transformFunction: null }, viewerOptions: { classPropertyName: "viewerOptions", publicName: "viewerOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { layerChange: "layerChange" }, providers: [LayerListToolService, FormDialogService], ngImport: i0, template: "<igo-panel\n class=\"igo-layer-actions-container\"\n [title]=\"\n hasMultipleSelection\n ? ('igo.geo.layer.tools' | translate)\n : selected[0].title\n \"\n>\n <div class=\"igo-layer-button-group\">\n @if (isLayersRemovable(selected)) {\n <button\n class=\"delete-button\"\n mat-icon-button\n color=\"warn\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n (hasMultipleSelection\n ? isLayersRemovable(selected)\n ? ('igo.geo.layer.removeSelectedLayers' | translate)\n : ('igo.geo.layer.removeSelectedLayersRestriction' | translate)\n : 'igo.geo.layer.removeLayer'\n ) | translate\n \"\n (click)=\"removeLayers()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"'!'\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"\n !hasMultipleSelection || isLayersRemovable(selected)\n \"\n >delete</mat-icon\n >\n </button>\n }\n\n @if (hasMultipleSelection) {\n <button\n class=\"eye-button\"\n mat-icon-button\n color=\"primary\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [disabled]=\"selected.length === 0\"\n [matTooltip]=\"\n allSelectionVisibilityHidden\n ? ('igo.geo.layer.showSelectedLayers' | translate)\n : ('igo.geo.layer.hideSelectedLayers' | translate)\n \"\n (click)=\"toggleSelectionVisibility()\"\n >\n <mat-icon>{{\n allSelectionVisibilityHidden ? 'visibility_off' : 'visibility'\n }}</mat-icon>\n </button>\n }\n\n <button\n class=\"down-button\"\n mat-icon-button\n color=\"primary\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n searchTerm()\n ? ('igo.geo.layer.filterLowerLayer' | translate)\n : ('igo.geo.layer.lowerLayer' | translate)\n \"\n [disabled]=\"!isSelectionLowerable\"\n (click)=\"lowerSelection()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"searchTerm() ? '!' : ''\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"!isSelectionLowerable\"\n >arrow_downward</mat-icon\n >\n </button>\n\n <button\n class=\"up-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n searchTerm()\n ? ('igo.geo.layer.filterRaiseLayer' | translate)\n : ('igo.geo.layer.raiseLayer' | translate)\n \"\n [disabled]=\"!isSelectionRaisable\"\n (click)=\"raiseSelection()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"searchTerm() ? '!' : ''\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"!isSelectionRaisable\"\n >\n arrow_upward\n </mat-icon>\n </button>\n\n @if (controller().selected.length === 1) {\n <button\n class=\"opacity-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matMenuTriggerFor]=\"opacityMenu\"\n [matTooltip]=\"'igo.geo.layer.opacity' | translate\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"opacity === 100 ? null : opacity\"\n matBadgeColor=\"primary\"\n matBadgeSize=\"medium\"\n >opacity</mat-icon\n >\n </button>\n <mat-menu #opacityMenu=\"matMenu\" class=\"panel-opacity-menu\">\n <mat-slider\n id=\"opacity-slider\"\n color=\"primary\"\n discrete\n step=\"5\"\n [min]=\"0\"\n [max]=\"100\"\n [matTooltip]=\"'igo.geo.layer.opacity' | translate\"\n (click)=\"$event.stopPropagation()\"\n matTooltipShowDelay=\"500\"\n tooltip-position=\"below\"\n #ngSlider\n ><input\n matSliderThumb\n [value]=\"opacity\"\n (input)=\"\n changeOpacity({\n source: ngSliderThumb,\n parent: ngSlider,\n value: ngSliderThumb.value\n })\n \"\n #ngSliderThumb=\"matSliderThumb\"\n />\n </mat-slider>\n </mat-menu>\n }\n\n @if (isExtentsValid()) {\n <button\n class=\"zoomLayer-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n (hasMultipleSelection\n ? 'igo.geo.layer.zoomLayers'\n : 'igo.geo.layer.zoomLayer'\n ) | translate\n \"\n (click)=\"zoomLayersExtents()\"\n >\n <mat-icon matBadgeColor=\"primary\" matBadgeSize=\"medium\"\n >frame_inspect</mat-icon\n >\n </button>\n }\n\n @if (canRename) {\n <button\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.group.rename' | translate\"\n (click)=\"handleRename()\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n }\n\n <ng-content />\n </div>\n</igo-panel>\n", styles: [".igo-layer-actions-container{padding:0 6px 0 4px}.igo-layer-actions-container>div{text-align:center}.igo-layer-button-group,.actions-buttons-multi{display:flex;align-items:center;flex-direction:row-reverse;overflow-x:auto;overflow-y:hidden}.igo-layer-button-group::-webkit-scrollbar,.actions-buttons-multi::-webkit-scrollbar{height:4px}.igo-layer-button-group::-webkit-scrollbar-track,.actions-buttons-multi::-webkit-scrollbar-track{background:#f1f1f1}.igo-layer-button-group::-webkit-scrollbar-thumb,.actions-buttons-multi::-webkit-scrollbar-thumb{background:#888}.igo-layer-button-group::-webkit-scrollbar-thumb:hover,.actions-buttons-multi::-webkit-scrollbar-thumb:hover{background:#555}.igo-layer-button-group{padding-top:4px}igo-panel{height:unset}::ng-deep .panel-opacity-menu{overflow:visible!important}::ng-deep .panel-opacity-menu #opacity-slider{margin:0 16px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i4$4.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i3$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i6.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i6.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "component", type: PanelComponent, selector: "igo-panel", inputs: ["title", "withHeader", "cursorPointer"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] });
13297
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: LayerViewerBottomActionsComponent, isStandalone: true, selector: "igo-layer-viewer-bottom-actions", inputs: { map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: true, transformFunction: null }, controller: { classPropertyName: "controller", publicName: "controller", isSignal: true, isRequired: true, transformFunction: null }, searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: true, transformFunction: null }, viewerOptions: { classPropertyName: "viewerOptions", publicName: "viewerOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { layerChange: "layerChange" }, providers: [LayerListToolService, FormDialogService], ngImport: i0, template: "<igo-panel\n class=\"igo-layer-actions-container\"\n [title]=\"\n hasMultipleSelection\n ? ('igo.geo.layer.tools' | translate)\n : selected[0].title\n \"\n>\n <div class=\"igo-layer-button-group\">\n @if (isLayersRemovable(selected)) {\n <button\n class=\"delete-button\"\n mat-icon-button\n color=\"warn\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n (hasMultipleSelection\n ? isLayersRemovable(selected)\n ? ('igo.geo.layer.removeSelectedLayers' | translate)\n : ('igo.geo.layer.removeSelectedLayersRestriction' | translate)\n : isLayerGroup(selected[0])\n ? ('igo.geo.layer.group.remove' | translate)\n : ('igo.geo.layer.removeLayer' | translate)\n ) | translate\n \"\n (click)=\"removeLayers()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"'!'\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"\n !hasMultipleSelection || isLayersRemovable(selected)\n \"\n >delete</mat-icon\n >\n </button>\n }\n\n @if (hasMultipleSelection) {\n <button\n class=\"eye-button\"\n mat-icon-button\n color=\"primary\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [disabled]=\"selected.length === 0\"\n [matTooltip]=\"\n allSelectionVisibilityHidden\n ? ('igo.geo.layer.showSelectedLayers' | translate)\n : ('igo.geo.layer.hideSelectedLayers' | translate)\n \"\n (click)=\"toggleSelectionVisibility()\"\n >\n <mat-icon>{{\n allSelectionVisibilityHidden ? 'visibility_off' : 'visibility'\n }}</mat-icon>\n </button>\n }\n\n <button\n class=\"down-button\"\n mat-icon-button\n color=\"primary\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n searchTerm()\n ? ('igo.geo.layer.filterLowerLayer' | translate)\n : ('igo.geo.layer.lowerLayer' | translate)\n \"\n [disabled]=\"!isSelectionLowerable\"\n (click)=\"lowerSelection()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"searchTerm() ? '!' : ''\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"!isSelectionLowerable\"\n >arrow_downward</mat-icon\n >\n </button>\n\n <button\n class=\"up-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n searchTerm()\n ? ('igo.geo.layer.filterRaiseLayer' | translate)\n : ('igo.geo.layer.raiseLayer' | translate)\n \"\n [disabled]=\"!isSelectionRaisable\"\n (click)=\"raiseSelection()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"searchTerm() ? '!' : ''\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"!isSelectionRaisable\"\n >\n arrow_upward\n </mat-icon>\n </button>\n\n @if (controller().selected.length === 1) {\n <button\n class=\"opacity-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matMenuTriggerFor]=\"opacityMenu\"\n [matTooltip]=\"'igo.geo.layer.opacity' | translate\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"opacity === 100 ? null : opacity\"\n matBadgeColor=\"primary\"\n matBadgeSize=\"medium\"\n >opacity</mat-icon\n >\n </button>\n <mat-menu #opacityMenu=\"matMenu\" class=\"panel-opacity-menu\">\n <mat-slider\n id=\"opacity-slider\"\n color=\"primary\"\n discrete\n step=\"5\"\n [min]=\"0\"\n [max]=\"100\"\n [matTooltip]=\"'igo.geo.layer.opacity' | translate\"\n (click)=\"$event.stopPropagation()\"\n matTooltipShowDelay=\"500\"\n tooltip-position=\"below\"\n #ngSlider\n ><input\n matSliderThumb\n [value]=\"opacity\"\n (input)=\"\n changeOpacity({\n source: ngSliderThumb,\n parent: ngSlider,\n value: ngSliderThumb.value\n })\n \"\n #ngSliderThumb=\"matSliderThumb\"\n />\n </mat-slider>\n </mat-menu>\n }\n\n @if (isExtentsValid()) {\n <button\n class=\"zoomLayer-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n (hasMultipleSelection\n ? 'igo.geo.layer.zoomLayers'\n : 'igo.geo.layer.zoomLayer'\n ) | translate\n \"\n (click)=\"zoomLayersExtents()\"\n >\n <mat-icon matBadgeColor=\"primary\" matBadgeSize=\"medium\"\n >frame_inspect</mat-icon\n >\n </button>\n }\n\n @if (canRename) {\n <button\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.group.rename' | translate\"\n (click)=\"handleRename()\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n }\n\n <ng-content />\n </div>\n</igo-panel>\n", styles: [".igo-layer-actions-container{padding:0 6px 0 4px}.igo-layer-actions-container>div{text-align:center}.igo-layer-button-group,.actions-buttons-multi{display:flex;align-items:center;flex-direction:row-reverse;overflow-x:auto;overflow-y:hidden}.igo-layer-button-group::-webkit-scrollbar,.actions-buttons-multi::-webkit-scrollbar{height:4px}.igo-layer-button-group::-webkit-scrollbar-track,.actions-buttons-multi::-webkit-scrollbar-track{background:#f1f1f1}.igo-layer-button-group::-webkit-scrollbar-thumb,.actions-buttons-multi::-webkit-scrollbar-thumb{background:#888}.igo-layer-button-group::-webkit-scrollbar-thumb:hover,.actions-buttons-multi::-webkit-scrollbar-thumb:hover{background:#555}.igo-layer-button-group{padding-top:4px}igo-panel{height:unset}::ng-deep .panel-opacity-menu{overflow:visible!important}::ng-deep .panel-opacity-menu #opacity-slider{margin:0 16px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i4$4.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i3$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i6.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i6.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "component", type: PanelComponent, selector: "igo-panel", inputs: ["title", "withHeader", "cursorPointer"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] });
13242
13298
  }
13243
13299
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LayerViewerBottomActionsComponent, decorators: [{
13244
13300
  type: Component,
@@ -13251,7 +13307,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
13251
13307
  MatSliderModule,
13252
13308
  IgoLanguageModule,
13253
13309
  PanelComponent
13254
- ], providers: [LayerListToolService, FormDialogService], template: "<igo-panel\n class=\"igo-layer-actions-container\"\n [title]=\"\n hasMultipleSelection\n ? ('igo.geo.layer.tools' | translate)\n : selected[0].title\n \"\n>\n <div class=\"igo-layer-button-group\">\n @if (isLayersRemovable(selected)) {\n <button\n class=\"delete-button\"\n mat-icon-button\n color=\"warn\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n (hasMultipleSelection\n ? isLayersRemovable(selected)\n ? ('igo.geo.layer.removeSelectedLayers' | translate)\n : ('igo.geo.layer.removeSelectedLayersRestriction' | translate)\n : 'igo.geo.layer.removeLayer'\n ) | translate\n \"\n (click)=\"removeLayers()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"'!'\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"\n !hasMultipleSelection || isLayersRemovable(selected)\n \"\n >delete</mat-icon\n >\n </button>\n }\n\n @if (hasMultipleSelection) {\n <button\n class=\"eye-button\"\n mat-icon-button\n color=\"primary\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [disabled]=\"selected.length === 0\"\n [matTooltip]=\"\n allSelectionVisibilityHidden\n ? ('igo.geo.layer.showSelectedLayers' | translate)\n : ('igo.geo.layer.hideSelectedLayers' | translate)\n \"\n (click)=\"toggleSelectionVisibility()\"\n >\n <mat-icon>{{\n allSelectionVisibilityHidden ? 'visibility_off' : 'visibility'\n }}</mat-icon>\n </button>\n }\n\n <button\n class=\"down-button\"\n mat-icon-button\n color=\"primary\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n searchTerm()\n ? ('igo.geo.layer.filterLowerLayer' | translate)\n : ('igo.geo.layer.lowerLayer' | translate)\n \"\n [disabled]=\"!isSelectionLowerable\"\n (click)=\"lowerSelection()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"searchTerm() ? '!' : ''\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"!isSelectionLowerable\"\n >arrow_downward</mat-icon\n >\n </button>\n\n <button\n class=\"up-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n searchTerm()\n ? ('igo.geo.layer.filterRaiseLayer' | translate)\n : ('igo.geo.layer.raiseLayer' | translate)\n \"\n [disabled]=\"!isSelectionRaisable\"\n (click)=\"raiseSelection()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"searchTerm() ? '!' : ''\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"!isSelectionRaisable\"\n >\n arrow_upward\n </mat-icon>\n </button>\n\n @if (controller().selected.length === 1) {\n <button\n class=\"opacity-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matMenuTriggerFor]=\"opacityMenu\"\n [matTooltip]=\"'igo.geo.layer.opacity' | translate\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"opacity === 100 ? null : opacity\"\n matBadgeColor=\"primary\"\n matBadgeSize=\"medium\"\n >opacity</mat-icon\n >\n </button>\n <mat-menu #opacityMenu=\"matMenu\" class=\"panel-opacity-menu\">\n <mat-slider\n id=\"opacity-slider\"\n color=\"primary\"\n discrete\n step=\"5\"\n [min]=\"0\"\n [max]=\"100\"\n [matTooltip]=\"'igo.geo.layer.opacity' | translate\"\n (click)=\"$event.stopPropagation()\"\n matTooltipShowDelay=\"500\"\n tooltip-position=\"below\"\n #ngSlider\n ><input\n matSliderThumb\n [value]=\"opacity\"\n (input)=\"\n changeOpacity({\n source: ngSliderThumb,\n parent: ngSlider,\n value: ngSliderThumb.value\n })\n \"\n #ngSliderThumb=\"matSliderThumb\"\n />\n </mat-slider>\n </mat-menu>\n }\n\n @if (isExtentsValid()) {\n <button\n class=\"zoomLayer-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n (hasMultipleSelection\n ? 'igo.geo.layer.zoomLayers'\n : 'igo.geo.layer.zoomLayer'\n ) | translate\n \"\n (click)=\"zoomLayersExtents()\"\n >\n <mat-icon matBadgeColor=\"primary\" matBadgeSize=\"medium\"\n >frame_inspect</mat-icon\n >\n </button>\n }\n\n @if (canRename) {\n <button\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.group.rename' | translate\"\n (click)=\"handleRename()\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n }\n\n <ng-content />\n </div>\n</igo-panel>\n", styles: [".igo-layer-actions-container{padding:0 6px 0 4px}.igo-layer-actions-container>div{text-align:center}.igo-layer-button-group,.actions-buttons-multi{display:flex;align-items:center;flex-direction:row-reverse;overflow-x:auto;overflow-y:hidden}.igo-layer-button-group::-webkit-scrollbar,.actions-buttons-multi::-webkit-scrollbar{height:4px}.igo-layer-button-group::-webkit-scrollbar-track,.actions-buttons-multi::-webkit-scrollbar-track{background:#f1f1f1}.igo-layer-button-group::-webkit-scrollbar-thumb,.actions-buttons-multi::-webkit-scrollbar-thumb{background:#888}.igo-layer-button-group::-webkit-scrollbar-thumb:hover,.actions-buttons-multi::-webkit-scrollbar-thumb:hover{background:#555}.igo-layer-button-group{padding-top:4px}igo-panel{height:unset}::ng-deep .panel-opacity-menu{overflow:visible!important}::ng-deep .panel-opacity-menu #opacity-slider{margin:0 16px}\n"] }]
13310
+ ], providers: [LayerListToolService, FormDialogService], template: "<igo-panel\n class=\"igo-layer-actions-container\"\n [title]=\"\n hasMultipleSelection\n ? ('igo.geo.layer.tools' | translate)\n : selected[0].title\n \"\n>\n <div class=\"igo-layer-button-group\">\n @if (isLayersRemovable(selected)) {\n <button\n class=\"delete-button\"\n mat-icon-button\n color=\"warn\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n (hasMultipleSelection\n ? isLayersRemovable(selected)\n ? ('igo.geo.layer.removeSelectedLayers' | translate)\n : ('igo.geo.layer.removeSelectedLayersRestriction' | translate)\n : isLayerGroup(selected[0])\n ? ('igo.geo.layer.group.remove' | translate)\n : ('igo.geo.layer.removeLayer' | translate)\n ) | translate\n \"\n (click)=\"removeLayers()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"'!'\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"\n !hasMultipleSelection || isLayersRemovable(selected)\n \"\n >delete</mat-icon\n >\n </button>\n }\n\n @if (hasMultipleSelection) {\n <button\n class=\"eye-button\"\n mat-icon-button\n color=\"primary\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [disabled]=\"selected.length === 0\"\n [matTooltip]=\"\n allSelectionVisibilityHidden\n ? ('igo.geo.layer.showSelectedLayers' | translate)\n : ('igo.geo.layer.hideSelectedLayers' | translate)\n \"\n (click)=\"toggleSelectionVisibility()\"\n >\n <mat-icon>{{\n allSelectionVisibilityHidden ? 'visibility_off' : 'visibility'\n }}</mat-icon>\n </button>\n }\n\n <button\n class=\"down-button\"\n mat-icon-button\n color=\"primary\"\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n searchTerm()\n ? ('igo.geo.layer.filterLowerLayer' | translate)\n : ('igo.geo.layer.lowerLayer' | translate)\n \"\n [disabled]=\"!isSelectionLowerable\"\n (click)=\"lowerSelection()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"searchTerm() ? '!' : ''\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"!isSelectionLowerable\"\n >arrow_downward</mat-icon\n >\n </button>\n\n <button\n class=\"up-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n searchTerm()\n ? ('igo.geo.layer.filterRaiseLayer' | translate)\n : ('igo.geo.layer.raiseLayer' | translate)\n \"\n [disabled]=\"!isSelectionRaisable\"\n (click)=\"raiseSelection()\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"searchTerm() ? '!' : ''\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"medium\"\n [matBadgeHidden]=\"!isSelectionRaisable\"\n >\n arrow_upward\n </mat-icon>\n </button>\n\n @if (controller().selected.length === 1) {\n <button\n class=\"opacity-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matMenuTriggerFor]=\"opacityMenu\"\n [matTooltip]=\"'igo.geo.layer.opacity' | translate\"\n >\n <mat-icon\n aria-hidden=\"false\"\n [matBadge]=\"opacity === 100 ? null : opacity\"\n matBadgeColor=\"primary\"\n matBadgeSize=\"medium\"\n >opacity</mat-icon\n >\n </button>\n <mat-menu #opacityMenu=\"matMenu\" class=\"panel-opacity-menu\">\n <mat-slider\n id=\"opacity-slider\"\n color=\"primary\"\n discrete\n step=\"5\"\n [min]=\"0\"\n [max]=\"100\"\n [matTooltip]=\"'igo.geo.layer.opacity' | translate\"\n (click)=\"$event.stopPropagation()\"\n matTooltipShowDelay=\"500\"\n tooltip-position=\"below\"\n #ngSlider\n ><input\n matSliderThumb\n [value]=\"opacity\"\n (input)=\"\n changeOpacity({\n source: ngSliderThumb,\n parent: ngSlider,\n value: ngSliderThumb.value\n })\n \"\n #ngSliderThumb=\"matSliderThumb\"\n />\n </mat-slider>\n </mat-menu>\n }\n\n @if (isExtentsValid()) {\n <button\n class=\"zoomLayer-button\"\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"\n (hasMultipleSelection\n ? 'igo.geo.layer.zoomLayers'\n : 'igo.geo.layer.zoomLayer'\n ) | translate\n \"\n (click)=\"zoomLayersExtents()\"\n >\n <mat-icon matBadgeColor=\"primary\" matBadgeSize=\"medium\"\n >frame_inspect</mat-icon\n >\n </button>\n }\n\n @if (canRename) {\n <button\n color=\"primary\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.group.rename' | translate\"\n (click)=\"handleRename()\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n }\n\n <ng-content />\n </div>\n</igo-panel>\n", styles: [".igo-layer-actions-container{padding:0 6px 0 4px}.igo-layer-actions-container>div{text-align:center}.igo-layer-button-group,.actions-buttons-multi{display:flex;align-items:center;flex-direction:row-reverse;overflow-x:auto;overflow-y:hidden}.igo-layer-button-group::-webkit-scrollbar,.actions-buttons-multi::-webkit-scrollbar{height:4px}.igo-layer-button-group::-webkit-scrollbar-track,.actions-buttons-multi::-webkit-scrollbar-track{background:#f1f1f1}.igo-layer-button-group::-webkit-scrollbar-thumb,.actions-buttons-multi::-webkit-scrollbar-thumb{background:#888}.igo-layer-button-group::-webkit-scrollbar-thumb:hover,.actions-buttons-multi::-webkit-scrollbar-thumb:hover{background:#555}.igo-layer-button-group{padding-top:4px}igo-panel{height:unset}::ng-deep .panel-opacity-menu{overflow:visible!important}::ng-deep .panel-opacity-menu #opacity-slider{margin:0 16px}\n"] }]
13255
13311
  }], propDecorators: { map: [{ type: i0.Input, args: [{ isSignal: true, alias: "map", required: true }] }], controller: [{ type: i0.Input, args: [{ isSignal: true, alias: "controller", required: true }] }], searchTerm: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchTerm", required: true }] }], viewerOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewerOptions", required: false }] }], layerChange: [{ type: i0.Output, args: ["layerChange"] }] } });
13256
13312
 
13257
13313
  class LayerViewerComponent {
@@ -16093,16 +16149,24 @@ class MiniBaseMapComponent {
16093
16149
  interactions: false
16094
16150
  });
16095
16151
  constructor() {
16096
- effect(() => {
16097
- this.display();
16098
- this.basemap.ol.getView().changed();
16099
- });
16100
16152
  effect(() => {
16101
16153
  this.handleBaseLayerChanged(this.baseLayer());
16102
16154
  });
16103
16155
  }
16104
16156
  ngAfterViewInit() {
16105
- this.basemap.ol.setView(this.map().ol.getView());
16157
+ const mainView = this.map().ol.getView();
16158
+ const basemapView = new olView({
16159
+ center: mainView.getCenter(),
16160
+ zoom: mainView.getZoom(),
16161
+ projection: mainView.getProjection(),
16162
+ minZoom: mainView.getMinZoom(),
16163
+ maxZoom: mainView.getMaxZoom()
16164
+ });
16165
+ this.basemap.ol.setView(basemapView);
16166
+ mainView.on(['change:center', 'change:resolution'], () => {
16167
+ this.basemap.ol.getView().setCenter(mainView.getCenter());
16168
+ this.basemap.ol.getView().setZoom(mainView.getZoom());
16169
+ });
16106
16170
  }
16107
16171
  changeBaseLayer(baseLayer) {
16108
16172
  if (this.disabled()) {
@@ -16259,6 +16323,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
16259
16323
  * Tool to swipe the layers
16260
16324
  */
16261
16325
  class SwipeControlComponent {
16326
+ destroyRef = inject(DestroyRef);
16262
16327
  /**
16263
16328
  * Get an active map
16264
16329
  */
@@ -16279,38 +16344,35 @@ class SwipeControlComponent {
16279
16344
  * State of draggable action
16280
16345
  */
16281
16346
  inDragAction = false;
16282
- /**
16283
- * Listener of toggle from advanced-map-tool
16284
- */
16285
- swipeEnabled$$;
16286
16347
  /**
16287
16348
  * Binder of prerender on the same element
16288
16349
  */
16289
16350
  boundPrerender = this.prerender.bind(this);
16351
+ activated = signal(false, ...(ngDevMode ? [{ debugName: "activated" }] : []));
16290
16352
  /**
16291
16353
  * Get the list of layers for swipe and activate of deactivate the swipe
16292
16354
  * @internal
16293
16355
  */
16294
16356
  ngAfterViewInit() {
16295
16357
  this.getListOfLayers();
16296
- this.swipeEnabled$$ = this.map().swipeEnabled$.subscribe((value) => {
16358
+ this.map()
16359
+ .swipeEnabled$?.pipe(takeUntilDestroyed(this.destroyRef))
16360
+ .subscribe((value) => {
16297
16361
  value ? this.displaySwipe() : this.displaySwipeOff();
16298
16362
  });
16299
- this.letZoom();
16300
16363
  }
16301
16364
  /**
16302
16365
  * Clear the overlay layer and any interaction added by this component.
16303
16366
  * @internal
16304
16367
  */
16305
16368
  ngOnDestroy() {
16306
- this.swipeEnabled$$.unsubscribe();
16307
- this.map().swipeEnabled$.unsubscribe();
16308
16369
  this.displaySwipeOff();
16309
16370
  }
16310
16371
  /**
16311
16372
  * Display a swipe-element and render the layers
16312
16373
  */
16313
16374
  displaySwipe() {
16375
+ this.activated.set(true);
16314
16376
  if (this.swipeId) {
16315
16377
  this.swipeId.style.visibility = 'visible';
16316
16378
  }
@@ -16322,6 +16384,9 @@ class SwipeControlComponent {
16322
16384
  * Clear a swipe-element and render the layers on the initial state
16323
16385
  */
16324
16386
  displaySwipeOff() {
16387
+ if (!this.activated()) {
16388
+ return;
16389
+ }
16325
16390
  if (this.swipeId) {
16326
16391
  this.swipeId.style.visibility = 'hidden';
16327
16392
  }
@@ -16329,6 +16394,7 @@ class SwipeControlComponent {
16329
16394
  this.layers.map((layer) => layer.ol.un('postrender', this.postrender));
16330
16395
  this.map().ol.render();
16331
16396
  this.layers = [];
16397
+ this.activated.set(false);
16332
16398
  }
16333
16399
  /**
16334
16400
  * Getter of element
@@ -16442,22 +16508,12 @@ class SwipeControlComponent {
16442
16508
  event.context.restore();
16443
16509
  event.context.save();
16444
16510
  }
16445
- /**
16446
- * Zoom on div
16447
- */
16448
- letZoom() {
16449
- document.getElementById('igo-layer-swipe').addEventListener('wheel', (event) => {
16450
- event.deltaY > 0
16451
- ? this.map().viewController.zoomOut()
16452
- : this.map().viewController.zoomIn();
16453
- }, true);
16454
- }
16455
16511
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SwipeControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
16456
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.18", type: SwipeControlComponent, isStandalone: true, selector: "igo-swipe-control", inputs: { map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"igo-swipe-control-container\"\n id=\"igo-layer-swipe\"\n (mousedown)=\"dragDown($event)\"\n (mouseup)=\"closeDragMouseElement()\"\n (touchstart)=\"dragDown($event)\"\n (touchend)=\"closeDragTouchElement()\"\n>\n <div class=\"igo-swipe-control-line\"></div>\n\n <div class=\"igo-swipe-control-arrows\" id=\"arrows\">\n <div class=\"igo-arrow-left\"></div>\n <div class=\"igo-arrow-right\"></div>\n </div>\n</div>\n", styles: [".igo-swipe-control-container{position:absolute;width:80px;height:100%;top:0%;left:50%;cursor:grab;z-index:1;transform:translate(-40px)}.igo-swipe-control-container:active{cursor:grabbing}.igo-swipe-control-line{position:absolute;width:4px;height:100%;top:50%;left:50%;transform:translate(-50%,-50%);background-color:#5e5a5a}.igo-swipe-control-arrows{position:absolute;width:32px;height:32px;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:-16px;padding:5px 4px;background-color:#5e5a5a;z-index:2;-webkit-tap-highlight-color:rgba(0,0,0,0)}.igo-swipe-control-arrows div{display:inline-block;width:0;height:0;border-top:10px solid transparent;border-bottom:10px solid transparent}.igo-swipe-control-arrows .igo-arrow-right{margin-left:4px;border-left:10px solid white}.igo-swipe-control-arrows .igo-arrow-left{border-right:10px solid white}.igo-swipe-control-arrows:active{display:none}\n"] });
16512
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: SwipeControlComponent, isStandalone: true, selector: "igo-swipe-control", inputs: { map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (activated()) {\n <div\n class=\"igo-swipe-control-container\"\n id=\"igo-layer-swipe\"\n (mousedown)=\"dragDown($event)\"\n (mouseup)=\"closeDragMouseElement()\"\n (touchstart)=\"dragDown($event)\"\n (touchend)=\"closeDragTouchElement()\"\n >\n <div class=\"igo-swipe-control-line\"></div>\n\n <div class=\"igo-swipe-control-arrows\" id=\"arrows\">\n <div class=\"igo-arrow-left\"></div>\n <div class=\"igo-arrow-right\"></div>\n </div>\n </div>\n}\n", styles: [".igo-swipe-control-container{position:absolute;width:80px;height:100%;top:0%;left:50%;cursor:grab;z-index:1;transform:translate(-40px)}.igo-swipe-control-container:active{cursor:grabbing}.igo-swipe-control-line{position:absolute;width:4px;height:100%;top:50%;left:50%;transform:translate(-50%,-50%);background-color:#5e5a5a}.igo-swipe-control-arrows{position:absolute;width:32px;height:32px;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:-16px;padding:5px 4px;background-color:#5e5a5a;z-index:2;-webkit-tap-highlight-color:rgba(0,0,0,0)}.igo-swipe-control-arrows div{display:inline-block;width:0;height:0;border-top:10px solid transparent;border-bottom:10px solid transparent}.igo-swipe-control-arrows .igo-arrow-right{margin-left:4px;border-left:10px solid white}.igo-swipe-control-arrows .igo-arrow-left{border-right:10px solid white}.igo-swipe-control-arrows:active{display:none}\n"] });
16457
16513
  }
16458
16514
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SwipeControlComponent, decorators: [{
16459
16515
  type: Component,
16460
- args: [{ selector: 'igo-swipe-control', standalone: true, template: "<div\n class=\"igo-swipe-control-container\"\n id=\"igo-layer-swipe\"\n (mousedown)=\"dragDown($event)\"\n (mouseup)=\"closeDragMouseElement()\"\n (touchstart)=\"dragDown($event)\"\n (touchend)=\"closeDragTouchElement()\"\n>\n <div class=\"igo-swipe-control-line\"></div>\n\n <div class=\"igo-swipe-control-arrows\" id=\"arrows\">\n <div class=\"igo-arrow-left\"></div>\n <div class=\"igo-arrow-right\"></div>\n </div>\n</div>\n", styles: [".igo-swipe-control-container{position:absolute;width:80px;height:100%;top:0%;left:50%;cursor:grab;z-index:1;transform:translate(-40px)}.igo-swipe-control-container:active{cursor:grabbing}.igo-swipe-control-line{position:absolute;width:4px;height:100%;top:50%;left:50%;transform:translate(-50%,-50%);background-color:#5e5a5a}.igo-swipe-control-arrows{position:absolute;width:32px;height:32px;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:-16px;padding:5px 4px;background-color:#5e5a5a;z-index:2;-webkit-tap-highlight-color:rgba(0,0,0,0)}.igo-swipe-control-arrows div{display:inline-block;width:0;height:0;border-top:10px solid transparent;border-bottom:10px solid transparent}.igo-swipe-control-arrows .igo-arrow-right{margin-left:4px;border-left:10px solid white}.igo-swipe-control-arrows .igo-arrow-left{border-right:10px solid white}.igo-swipe-control-arrows:active{display:none}\n"] }]
16516
+ args: [{ selector: 'igo-swipe-control', standalone: true, template: "@if (activated()) {\n <div\n class=\"igo-swipe-control-container\"\n id=\"igo-layer-swipe\"\n (mousedown)=\"dragDown($event)\"\n (mouseup)=\"closeDragMouseElement()\"\n (touchstart)=\"dragDown($event)\"\n (touchend)=\"closeDragTouchElement()\"\n >\n <div class=\"igo-swipe-control-line\"></div>\n\n <div class=\"igo-swipe-control-arrows\" id=\"arrows\">\n <div class=\"igo-arrow-left\"></div>\n <div class=\"igo-arrow-right\"></div>\n </div>\n </div>\n}\n", styles: [".igo-swipe-control-container{position:absolute;width:80px;height:100%;top:0%;left:50%;cursor:grab;z-index:1;transform:translate(-40px)}.igo-swipe-control-container:active{cursor:grabbing}.igo-swipe-control-line{position:absolute;width:4px;height:100%;top:50%;left:50%;transform:translate(-50%,-50%);background-color:#5e5a5a}.igo-swipe-control-arrows{position:absolute;width:32px;height:32px;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:-16px;padding:5px 4px;background-color:#5e5a5a;z-index:2;-webkit-tap-highlight-color:rgba(0,0,0,0)}.igo-swipe-control-arrows div{display:inline-block;width:0;height:0;border-top:10px solid transparent;border-bottom:10px solid transparent}.igo-swipe-control-arrows .igo-arrow-right{margin-left:4px;border-left:10px solid white}.igo-swipe-control-arrows .igo-arrow-left{border-right:10px solid white}.igo-swipe-control-arrows:active{display:none}\n"] }]
16461
16517
  }], propDecorators: { map: [{ type: i0.Input, args: [{ isSignal: true, alias: "map", required: false }] }] } });
16462
16518
 
16463
16519
  /**
@@ -17539,9 +17595,7 @@ class DirectionsComponent {
17539
17595
  queryService = inject(QueryService);
17540
17596
  messageService = inject(MessageService);
17541
17597
  projection = 'EPSG:4326';
17542
- hasOsrmPrivateAccess = false;
17543
17598
  twoSourcesAvailable = false;
17544
- zoomOnActiveRoute$$;
17545
17599
  storeEmpty$$;
17546
17600
  storeChange$$;
17547
17601
  routesQueries$$ = [];
@@ -17561,7 +17615,6 @@ class DirectionsComponent {
17561
17615
  debounce = input(200, ...(ngDevMode ? [{ debugName: "debounce" }] : []));
17562
17616
  length = input(2, ...(ngDevMode ? [{ debugName: "length" }] : []));
17563
17617
  coordRoundedDecimals = input(6, ...(ngDevMode ? [{ debugName: "coordRoundedDecimals" }] : []));
17564
- zoomOnActiveRoute = input.required(...(ngDevMode ? [{ debugName: "zoomOnActiveRoute" }] : []));
17565
17618
  authenticated$ = input.required(...(ngDevMode ? [{ debugName: "authenticated$" }] : []));
17566
17619
  /**
17567
17620
  * Wheter one of the direction control is active
@@ -17577,23 +17630,7 @@ class DirectionsComponent {
17577
17630
  return this.directionsSourceService.sources[0].getEnabledProfile()
17578
17631
  .authorization;
17579
17632
  }
17580
- constructor() {
17581
- this.monitorActiveRouteZoom();
17582
- }
17583
17633
  ngOnInit() {
17584
- this.authenticated$$ = this.authenticated$().subscribe((authenticated) => {
17585
- if (authenticated) {
17586
- const profileWithAuth = this.directionsSourceService.sources[0].getProfileWithAuthorization();
17587
- if (profileWithAuth) {
17588
- this.http
17589
- .get(profileWithAuth.authorization.url)
17590
- .subscribe((user) => {
17591
- this.hasOsrmPrivateAccess =
17592
- user[profileWithAuth.authorization.property];
17593
- });
17594
- }
17595
- }
17596
- });
17597
17634
  this.twoSourcesAvailable =
17598
17635
  this.directionsSourceService.sources[0].profiles.length === 2
17599
17636
  ? true
@@ -17612,7 +17649,6 @@ class DirectionsComponent {
17612
17649
  this.storeEmpty$$.unsubscribe();
17613
17650
  this.storeChange$$.unsubscribe();
17614
17651
  this.routesQueries$$.map((u) => u.unsubscribe());
17615
- this.zoomOnActiveRoute$$.destroy();
17616
17652
  this.authenticated$$.unsubscribe();
17617
17653
  this.freezeStores();
17618
17654
  const stopsFeatureStore = this.stopsFeatureStore();
@@ -17635,32 +17671,29 @@ class DirectionsComponent {
17635
17671
  this.monitorEmptyEntityStore();
17636
17672
  this.monitorEntityStoreChange();
17637
17673
  }
17638
- monitorActiveRouteZoom() {
17639
- this.zoomOnActiveRoute$$ = effect(() => {
17640
- this.zoomOnActiveRoute();
17641
- if (this.routesFeatureStore().count >= 1) {
17642
- const activeRoute = this.routesFeatureStore()
17674
+ zoomOnActiveRoute() {
17675
+ if (this.routesFeatureStore().count >= 1) {
17676
+ const activeRoute = this.routesFeatureStore()
17677
+ .all()
17678
+ .find((route) => route.properties.active);
17679
+ if (activeRoute) {
17680
+ const stopsCoordinates = this.stopsStore()
17643
17681
  .all()
17644
- .find((route) => route.properties.active);
17645
- if (activeRoute) {
17646
- const stopsCoordinates = this.stopsStore()
17647
- .all()
17648
- .map((stop) => olproj.transform(stop.coordinates, 'EPSG:4326', 'EPSG:3857'));
17649
- const routeCoordinates = activeRoute.geometry.coordinates;
17650
- const coordinates = [
17651
- ...stopsCoordinates,
17652
- ...routeCoordinates
17653
- ];
17654
- const routeExtent = coordinates.reduce(([x_min, y_min, x_max, y_max], [x, y]) => [
17655
- Math.min(x_min, x),
17656
- Math.min(y_min, y),
17657
- Math.max(x_max, x),
17658
- Math.max(y_max, y)
17659
- ], [Infinity, Infinity, -Infinity, -Infinity]);
17660
- this.routesFeatureStore().layer.map.viewController.zoomToExtent(routeExtent);
17661
- }
17682
+ .map((stop) => olproj.transform(stop.coordinates, 'EPSG:4326', 'EPSG:3857'));
17683
+ const routeCoordinates = activeRoute.geometry.coordinates;
17684
+ const coordinates = [
17685
+ ...stopsCoordinates,
17686
+ ...routeCoordinates
17687
+ ];
17688
+ const routeExtent = coordinates.reduce(([x_min, y_min, x_max, y_max], [x, y]) => [
17689
+ Math.min(x_min, x),
17690
+ Math.min(y_min, y),
17691
+ Math.max(x_max, x),
17692
+ Math.max(y_max, y)
17693
+ ], [Infinity, Infinity, -Infinity, -Infinity]);
17694
+ this.routesFeatureStore().layer.map.viewController.zoomToExtent(routeExtent);
17662
17695
  }
17663
- }, ...(ngDevMode ? [{ debugName: "zoomOnActiveRoute$$" }] : []));
17696
+ }
17664
17697
  }
17665
17698
  initOlInteraction() {
17666
17699
  this.selectStopInteraction = new olInteraction.Select({
@@ -17872,19 +17905,8 @@ class DirectionsComponent {
17872
17905
  ? ol.addInteraction(interaction)
17873
17906
  : ol.removeInteraction(interaction));
17874
17907
  }
17875
- onTogglePrivateModeControl(isActive) {
17876
- this.directionsSourceService.sources[0].profiles.forEach((profile) => (profile.enabled = false));
17877
- if (isActive) {
17878
- this.directionsSourceService.sources[0].profiles.find((profile) => profile.authorization).enabled = true;
17879
- this.messageService.alert(this.languageService.translate.instant('igo.geo.directions.forestRoadsWarning.text'), this.languageService.translate.instant('igo.geo.directions.forestRoadsWarning.title'));
17880
- }
17881
- else {
17882
- this.directionsSourceService.sources[0].profiles.find((profile) => !profile.authorization).enabled = true;
17883
- }
17884
- this.getRoutes();
17885
- }
17886
17908
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DirectionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
17887
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: DirectionsComponent, isStandalone: true, selector: "igo-directions", inputs: { contextUri: { classPropertyName: "contextUri", publicName: "contextUri", isSignal: true, isRequired: false, transformFunction: null }, stopsStore: { classPropertyName: "stopsStore", publicName: "stopsStore", isSignal: true, isRequired: true, transformFunction: null }, stopsFeatureStore: { classPropertyName: "stopsFeatureStore", publicName: "stopsFeatureStore", isSignal: true, isRequired: true, transformFunction: null }, routesFeatureStore: { classPropertyName: "routesFeatureStore", publicName: "routesFeatureStore", isSignal: true, isRequired: true, transformFunction: null }, stepsFeatureStore: { classPropertyName: "stepsFeatureStore", publicName: "stepsFeatureStore", isSignal: true, isRequired: true, transformFunction: null }, debounce: { classPropertyName: "debounce", publicName: "debounce", isSignal: true, isRequired: false, transformFunction: null }, length: { classPropertyName: "length", publicName: "length", isSignal: true, isRequired: false, transformFunction: null }, coordRoundedDecimals: { classPropertyName: "coordRoundedDecimals", publicName: "coordRoundedDecimals", isSignal: true, isRequired: false, transformFunction: null }, zoomOnActiveRoute: { classPropertyName: "zoomOnActiveRoute", publicName: "zoomOnActiveRoute", isSignal: true, isRequired: true, transformFunction: null }, authenticated$: { classPropertyName: "authenticated$", publicName: "authenticated$", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"directions-options\">\n <mat-slide-toggle\n [checked]=\"directionControlIsActive\"\n [labelPosition]=\"'before'\"\n (change)=\"onToggleDirectionsControl($event.checked)\"\n >\n {{ 'igo.geo.directions.toggle.activateControl' | translate }}\n </mat-slide-toggle>\n @if (hasOsrmPrivateAccess && twoSourcesAvailable) {\n <mat-slide-toggle\n [checked]=\"enabledProfileHasAuthorization\"\n [labelPosition]=\"'before'\"\n (change)=\"onTogglePrivateModeControl($event.checked)\"\n >\n {{ 'igo.geo.directions.toggle.type' | translate }}\n </mat-slide-toggle>\n }\n</div>\n\n<igo-directions-inputs\n (stopInputHasFocus)=\"onStopInputHasFocusChange($event)\"\n [coordRoundedDecimals]=\"coordRoundedDecimals()\"\n [projection]=\"projection\"\n [stopsFeatureStore]=\"stopsFeatureStore()\"\n [stopsStore]=\"stopsStore()\"\n [debounce]=\"debounce()\"\n [length]=\"length()\"\n/>\n\n@if (routesFeatureStore().all().length > 0) {\n <igo-directions-buttons\n [stepsFeatureStore]=\"stepsFeatureStore()\"\n [contextUri]=\"contextUri()\"\n [zoomOnActiveRoute]=\"zoomOnActiveRoute()\"\n [routesFeatureStore]=\"routesFeatureStore()\"\n [stopsStore]=\"stopsStore()\"\n />\n}\n\n<igo-directions-results\n [stepsFeatureStore]=\"stepsFeatureStore()\"\n [routesFeatureStore]=\"routesFeatureStore()\"\n/>\n", styles: [":host{display:block;padding:16px}.directions-options{display:flex;flex-flow:column;align-items:center;row-gap:8px;margin-bottom:16px}.directions-options mat-slide-toggle{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-form-field{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-label{margin-left:0;margin-right:auto;width:auto;padding-right:0}.directions-options mat-slide-toggle ::ng-deep .mdc-slide-toggle{margin-left:auto;margin-right:0}\n"], dependencies: [{ kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i1$3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: DirectionsButtonsComponent, selector: "igo-directions-buttons", inputs: ["contextUri", "zoomOnActiveRoute", "stopsStore", "routesFeatureStore", "stepsFeatureStore"], outputs: ["zoomOnActiveRouteChange"] }, { kind: "component", type: DirectionsInputsComponent, selector: "igo-directions-inputs", inputs: ["stopsStore", "stopsFeatureStore", "projection", "coordRoundedDecimals", "debounce", "length"], outputs: ["stopInputHasFocus"] }, { kind: "component", type: DirectionsResultsComponent, selector: "igo-directions-results", inputs: ["routesFeatureStore", "stepsFeatureStore"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] });
17909
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: DirectionsComponent, isStandalone: true, selector: "igo-directions", inputs: { contextUri: { classPropertyName: "contextUri", publicName: "contextUri", isSignal: true, isRequired: false, transformFunction: null }, stopsStore: { classPropertyName: "stopsStore", publicName: "stopsStore", isSignal: true, isRequired: true, transformFunction: null }, stopsFeatureStore: { classPropertyName: "stopsFeatureStore", publicName: "stopsFeatureStore", isSignal: true, isRequired: true, transformFunction: null }, routesFeatureStore: { classPropertyName: "routesFeatureStore", publicName: "routesFeatureStore", isSignal: true, isRequired: true, transformFunction: null }, stepsFeatureStore: { classPropertyName: "stepsFeatureStore", publicName: "stepsFeatureStore", isSignal: true, isRequired: true, transformFunction: null }, debounce: { classPropertyName: "debounce", publicName: "debounce", isSignal: true, isRequired: false, transformFunction: null }, length: { classPropertyName: "length", publicName: "length", isSignal: true, isRequired: false, transformFunction: null }, coordRoundedDecimals: { classPropertyName: "coordRoundedDecimals", publicName: "coordRoundedDecimals", isSignal: true, isRequired: false, transformFunction: null }, authenticated$: { classPropertyName: "authenticated$", publicName: "authenticated$", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"directions-options\">\n <mat-slide-toggle\n [checked]=\"directionControlIsActive\"\n [labelPosition]=\"'before'\"\n (change)=\"onToggleDirectionsControl($event.checked)\"\n >\n {{ 'igo.geo.directions.toggle.activateControl' | translate }}\n </mat-slide-toggle>\n</div>\n\n<igo-directions-inputs\n (stopInputHasFocus)=\"onStopInputHasFocusChange($event)\"\n [coordRoundedDecimals]=\"coordRoundedDecimals()\"\n [projection]=\"projection\"\n [stopsFeatureStore]=\"stopsFeatureStore()\"\n [stopsStore]=\"stopsStore()\"\n [debounce]=\"debounce()\"\n [length]=\"length()\"\n/>\n\n@if (routesFeatureStore().all().length > 0) {\n <igo-directions-buttons\n [stepsFeatureStore]=\"stepsFeatureStore()\"\n [contextUri]=\"contextUri()\"\n (zoomOnActiveRoute)=\"zoomOnActiveRoute()\"\n [routesFeatureStore]=\"routesFeatureStore()\"\n [stopsStore]=\"stopsStore()\"\n />\n}\n\n<igo-directions-results\n [stepsFeatureStore]=\"stepsFeatureStore()\"\n [routesFeatureStore]=\"routesFeatureStore()\"\n/>\n", styles: [":host{display:block;padding:16px}.directions-options{display:flex;flex-flow:column;align-items:center;row-gap:8px;margin-bottom:16px}.directions-options mat-slide-toggle{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-form-field{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-label{margin-left:0;margin-right:auto;width:auto;padding-right:0}.directions-options mat-slide-toggle ::ng-deep .mdc-slide-toggle{margin-left:auto;margin-right:0}\n"], dependencies: [{ kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i1$3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: DirectionsButtonsComponent, selector: "igo-directions-buttons", inputs: ["contextUri", "stopsStore", "routesFeatureStore", "stepsFeatureStore"], outputs: ["zoomOnActiveRoute"] }, { kind: "component", type: DirectionsInputsComponent, selector: "igo-directions-inputs", inputs: ["stopsStore", "stopsFeatureStore", "projection", "coordRoundedDecimals", "debounce", "length"], outputs: ["stopInputHasFocus"] }, { kind: "component", type: DirectionsResultsComponent, selector: "igo-directions-results", inputs: ["routesFeatureStore", "stepsFeatureStore"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] });
17888
17910
  }
17889
17911
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DirectionsComponent, decorators: [{
17890
17912
  type: Component,
@@ -17894,8 +17916,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
17894
17916
  DirectionsInputsComponent,
17895
17917
  DirectionsResultsComponent,
17896
17918
  IgoLanguageModule
17897
- ], template: "<div class=\"directions-options\">\n <mat-slide-toggle\n [checked]=\"directionControlIsActive\"\n [labelPosition]=\"'before'\"\n (change)=\"onToggleDirectionsControl($event.checked)\"\n >\n {{ 'igo.geo.directions.toggle.activateControl' | translate }}\n </mat-slide-toggle>\n @if (hasOsrmPrivateAccess && twoSourcesAvailable) {\n <mat-slide-toggle\n [checked]=\"enabledProfileHasAuthorization\"\n [labelPosition]=\"'before'\"\n (change)=\"onTogglePrivateModeControl($event.checked)\"\n >\n {{ 'igo.geo.directions.toggle.type' | translate }}\n </mat-slide-toggle>\n }\n</div>\n\n<igo-directions-inputs\n (stopInputHasFocus)=\"onStopInputHasFocusChange($event)\"\n [coordRoundedDecimals]=\"coordRoundedDecimals()\"\n [projection]=\"projection\"\n [stopsFeatureStore]=\"stopsFeatureStore()\"\n [stopsStore]=\"stopsStore()\"\n [debounce]=\"debounce()\"\n [length]=\"length()\"\n/>\n\n@if (routesFeatureStore().all().length > 0) {\n <igo-directions-buttons\n [stepsFeatureStore]=\"stepsFeatureStore()\"\n [contextUri]=\"contextUri()\"\n [zoomOnActiveRoute]=\"zoomOnActiveRoute()\"\n [routesFeatureStore]=\"routesFeatureStore()\"\n [stopsStore]=\"stopsStore()\"\n />\n}\n\n<igo-directions-results\n [stepsFeatureStore]=\"stepsFeatureStore()\"\n [routesFeatureStore]=\"routesFeatureStore()\"\n/>\n", styles: [":host{display:block;padding:16px}.directions-options{display:flex;flex-flow:column;align-items:center;row-gap:8px;margin-bottom:16px}.directions-options mat-slide-toggle{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-form-field{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-label{margin-left:0;margin-right:auto;width:auto;padding-right:0}.directions-options mat-slide-toggle ::ng-deep .mdc-slide-toggle{margin-left:auto;margin-right:0}\n"] }]
17898
- }], ctorParameters: () => [], propDecorators: { contextUri: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextUri", required: false }] }], stopsStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "stopsStore", required: true }] }], stopsFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "stopsFeatureStore", required: true }] }], routesFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "routesFeatureStore", required: true }] }], stepsFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepsFeatureStore", required: true }] }], debounce: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounce", required: false }] }], length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: false }] }], coordRoundedDecimals: [{ type: i0.Input, args: [{ isSignal: true, alias: "coordRoundedDecimals", required: false }] }], zoomOnActiveRoute: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomOnActiveRoute", required: true }] }], authenticated$: [{ type: i0.Input, args: [{ isSignal: true, alias: "authenticated$", required: true }] }] } });
17919
+ ], template: "<div class=\"directions-options\">\n <mat-slide-toggle\n [checked]=\"directionControlIsActive\"\n [labelPosition]=\"'before'\"\n (change)=\"onToggleDirectionsControl($event.checked)\"\n >\n {{ 'igo.geo.directions.toggle.activateControl' | translate }}\n </mat-slide-toggle>\n</div>\n\n<igo-directions-inputs\n (stopInputHasFocus)=\"onStopInputHasFocusChange($event)\"\n [coordRoundedDecimals]=\"coordRoundedDecimals()\"\n [projection]=\"projection\"\n [stopsFeatureStore]=\"stopsFeatureStore()\"\n [stopsStore]=\"stopsStore()\"\n [debounce]=\"debounce()\"\n [length]=\"length()\"\n/>\n\n@if (routesFeatureStore().all().length > 0) {\n <igo-directions-buttons\n [stepsFeatureStore]=\"stepsFeatureStore()\"\n [contextUri]=\"contextUri()\"\n (zoomOnActiveRoute)=\"zoomOnActiveRoute()\"\n [routesFeatureStore]=\"routesFeatureStore()\"\n [stopsStore]=\"stopsStore()\"\n />\n}\n\n<igo-directions-results\n [stepsFeatureStore]=\"stepsFeatureStore()\"\n [routesFeatureStore]=\"routesFeatureStore()\"\n/>\n", styles: [":host{display:block;padding:16px}.directions-options{display:flex;flex-flow:column;align-items:center;row-gap:8px;margin-bottom:16px}.directions-options mat-slide-toggle{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-form-field{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-label{margin-left:0;margin-right:auto;width:auto;padding-right:0}.directions-options mat-slide-toggle ::ng-deep .mdc-slide-toggle{margin-left:auto;margin-right:0}\n"] }]
17920
+ }], propDecorators: { contextUri: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextUri", required: false }] }], stopsStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "stopsStore", required: true }] }], stopsFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "stopsFeatureStore", required: true }] }], routesFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "routesFeatureStore", required: true }] }], stepsFeatureStore: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepsFeatureStore", required: true }] }], debounce: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounce", required: false }] }], length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: false }] }], coordRoundedDecimals: [{ type: i0.Input, args: [{ isSignal: true, alias: "coordRoundedDecimals", required: false }] }], authenticated$: [{ type: i0.Input, args: [{ isSignal: true, alias: "authenticated$", required: true }] }] } });
17899
17921
 
17900
17922
  class IgoDirectionsModule {
17901
17923
  /**
@@ -22444,7 +22466,7 @@ class FeatureDetailsComponent {
22444
22466
  if (!value.body) {
22445
22467
  return;
22446
22468
  }
22447
- const regexBase = /<base href="[\w:\/\.]+">/;
22469
+ const regexBase = /<base href="[\w:/.]+">/;
22448
22470
  if (!regexBase.test(value.body)) {
22449
22471
  const url = new URL(value.url, window.location.origin);
22450
22472
  value.body = value.body.replace('<head>', `<head><base href="${url.origin}">`);
@@ -22473,7 +22495,7 @@ class FeatureDetailsComponent {
22473
22495
  }
22474
22496
  else {
22475
22497
  let url = value;
22476
- if (this.isEmbeddedLink(value)) {
22498
+ if (this.hasEmbeddedLinks(value)) {
22477
22499
  const div = document.createElement('div');
22478
22500
  div.innerHTML = value;
22479
22501
  url = div.children[0].getAttribute('href');
@@ -22509,7 +22531,7 @@ class FeatureDetailsComponent {
22509
22531
  }
22510
22532
  }
22511
22533
  }
22512
- isEmbeddedLink(value) {
22534
+ hasEmbeddedLinks(value) {
22513
22535
  if (typeof value === 'string') {
22514
22536
  const matchRegex = /<a/g;
22515
22537
  const match = value.match(matchRegex) || [];
@@ -22604,7 +22626,7 @@ class FeatureDetailsComponent {
22604
22626
  }
22605
22627
  }
22606
22628
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: FeatureDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
22607
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: FeatureDetailsComponent, isStandalone: true, selector: "igo-feature-details", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null }, map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: false, transformFunction: null }, toolbox: { classPropertyName: "toolbox", publicName: "toolbox", isSignal: true, isRequired: false, transformFunction: null }, feature: { classPropertyName: "feature", publicName: "feature", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { routeEvent: "routeEvent", selectFeature: "selectFeature", htmlDisplayEvent: "htmlDisplayEvent" }, ngImport: i0, template: "@let properties = feature()?.properties;\n@if (\n ready && feature() && isObject(properties) && properties.target !== 'iframe'\n) {\n <table class=\"igo-striped\">\n <tbody>\n @for (\n property of filterFeatureProperties(feature()) | keyvalue;\n track property\n ) {\n <tr>\n @if (properties.target === '_blank' && property.key === 'url') {\n <td>\n <mat-icon matListItemIcon>{{ icon }}</mat-icon>\n </td>\n }\n @if (properties.target === '_blank' && property.key === 'url') {\n <td>\n <a\n href=\"{{ property.value }}\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {{ 'igo.geo.targetHtmlUrl' | translate }} {{ title }}</a\n >\n <button\n class=\"copyClipboard\"\n mat-icon-button\n (click)=\"copyTextToClipboard(property.value)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </td>\n }\n @if (properties.target === undefined) {\n <td id=\"keyValue\">\n {{ property.key }}\n </td>\n }\n @if (\n properties.target === undefined &&\n !isObject(property.value) &&\n !isUrl(property.value) &&\n !isEmbeddedLink(property.value)\n ) {\n <td [innerHTML]=\"property.value\"></td>\n }\n @if (\n properties.target === undefined && isEmbeddedLink(property.value)\n ) {\n <td>\n <u\n [ngStyle]=\"{ cursor: 'pointer', color: 'blue' }\"\n (click)=\"openSecureUrl(property.value)\"\n >{{ getEmbeddedLinkText(property.value) }}</u\n >\n </td>\n }\n @if (\n properties.target === undefined &&\n !isObject(property.value) &&\n (isDoc(property.value) || isUrl(property.value)) &&\n !isImg(property.value)\n ) {\n <td>\n <u\n [ngStyle]=\"{ cursor: 'pointer', color: 'blue' }\"\n (click)=\"openSecureUrl(property.value)\"\n >{{ 'igo.geo.targetHtmlUrl' | translate }}</u\n >\n <button\n class=\"copyClipboard\"\n mat-icon-button\n (click)=\"copyTextToClipboard(property.value)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </td>\n }\n @if (\n properties.target === undefined &&\n !isObject(property.value) &&\n isUrl(property.value) &&\n isImg(property.value)\n ) {\n <td>\n <a\n href=\"{{ property.value }}\"\n target=\"_blank\"\n (click)=\"openSecureUrl(property.value)\"\n rel=\"noopener noreferrer\"\n >\n <img\n igoImageError\n src=\"{{ property.value | secureImage | async }}\"\n width=\"225\"\n height=\"auto\"\n />\n </a>\n </td>\n }\n @if (properties.target === undefined && isObject(property.value)) {\n <td [innerHTML]=\"property.value | json\"></td>\n }\n </tr>\n }\n </tbody>\n </table>\n}\n\n@if (isHtmlDisplay()) {\n <iframe\n [srcdoc]=\"htmlSanitizer(properties)\"\n [src]=\"urlSanitizer(properties.url)\"\n ></iframe>\n}\n", styles: ["table{width:100%}table .igo-striped tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container-low);color:#000}table td{padding:4px}#keyValue{width:30%}table ::ng-deep .routing{cursor:pointer}iframe{height:calc(100% - 4px);width:100%;border:0}.copyClipboard{border:none;background:transparent;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: ImageErrorDirective, selector: "[igoImageError]", inputs: ["errorImageUrl", "hideError"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: SecureImagePipe, name: "secureImage" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
22629
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: FeatureDetailsComponent, isStandalone: true, selector: "igo-feature-details", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null }, map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: false, transformFunction: null }, toolbox: { classPropertyName: "toolbox", publicName: "toolbox", isSignal: true, isRequired: false, transformFunction: null }, feature: { classPropertyName: "feature", publicName: "feature", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { routeEvent: "routeEvent", selectFeature: "selectFeature", htmlDisplayEvent: "htmlDisplayEvent" }, ngImport: i0, template: "@let properties = feature()?.properties;\n@if (\n ready && feature() && isObject(properties) && properties?.target !== 'iframe'\n) {\n <table class=\"igo-striped\">\n <tbody>\n @for (\n property of filterFeatureProperties(feature()) | keyvalue;\n track property\n ) {\n <tr>\n @if (properties?.target === '_blank' && property.key === 'url') {\n <td>\n <mat-icon matListItemIcon>{{ icon }}</mat-icon>\n </td>\n }\n @if (properties?.target === '_blank' && property.key === 'url') {\n <td>\n <a\n href=\"{{ property.value }}\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {{ 'igo.geo.targetHtmlUrl' | translate }} {{ title }}</a\n >\n <button\n matIconButton\n (click)=\"copyTextToClipboard(property.value)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </td>\n }\n @if (properties?.target === undefined) {\n <td id=\"keyValue\">\n {{ property.key }}\n </td>\n }\n @if (\n properties?.target === undefined &&\n !isObject(property.value) &&\n !isUrl(property.value) &&\n !hasEmbeddedLinks(property.value)\n ) {\n <td [innerHTML]=\"property.value\"></td>\n }\n @if (\n properties?.target === undefined && hasEmbeddedLinks(property.value)\n ) {\n <td>\n <u\n [ngStyle]=\"{ cursor: 'pointer', color: 'blue' }\"\n (click)=\"openSecureUrl(property.value)\"\n >{{ getEmbeddedLinkText(property.value) }}</u\n >\n </td>\n }\n @if (\n properties?.target === undefined &&\n !isObject(property.value) &&\n (isDoc(property.value) || isUrl(property.value)) &&\n !isImg(property.value)\n ) {\n <td>\n <u\n [ngStyle]=\"{ cursor: 'pointer', color: 'blue' }\"\n (click)=\"openSecureUrl(property.value)\"\n >{{ 'igo.geo.targetHtmlUrl' | translate }}</u\n >\n <button\n matIconButton\n (click)=\"copyTextToClipboard(property.value)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </td>\n }\n @if (\n properties?.target === undefined &&\n !isObject(property.value) &&\n isUrl(property.value) &&\n isImg(property.value)\n ) {\n <td>\n <a\n href=\"{{ property.value }}\"\n target=\"_blank\"\n (click)=\"openSecureUrl(property.value)\"\n rel=\"noopener noreferrer\"\n >\n <img\n igoImageError\n src=\"{{ property.value | secureImage | async }}\"\n width=\"225\"\n height=\"auto\"\n />\n </a>\n </td>\n }\n @if (properties?.target === undefined && isObject(property.value)) {\n <td [innerHTML]=\"property.value | json\"></td>\n }\n </tr>\n }\n </tbody>\n </table>\n}\n\n@if (isHtmlDisplay()) {\n <iframe\n [srcdoc]=\"htmlSanitizer(properties)\"\n [src]=\"urlSanitizer(properties?.url)\"\n ></iframe>\n}\n", styles: ["table{width:100%}table.igo-striped tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container-high)}table td{padding:4px}#keyValue{width:30%}table ::ng-deep .routing{cursor:pointer}iframe{height:calc(100% - 4px);width:100%;border:0}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: ImageErrorDirective, selector: "[igoImageError]", inputs: ["errorImageUrl", "hideError"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: SecureImagePipe, name: "secureImage" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
22608
22630
  }
22609
22631
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: FeatureDetailsComponent, decorators: [{
22610
22632
  type: Component,
@@ -22616,8 +22638,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
22616
22638
  JsonPipe,
22617
22639
  KeyValuePipe,
22618
22640
  IgoLanguageModule,
22619
- SecureImagePipe
22620
- ], template: "@let properties = feature()?.properties;\n@if (\n ready && feature() && isObject(properties) && properties.target !== 'iframe'\n) {\n <table class=\"igo-striped\">\n <tbody>\n @for (\n property of filterFeatureProperties(feature()) | keyvalue;\n track property\n ) {\n <tr>\n @if (properties.target === '_blank' && property.key === 'url') {\n <td>\n <mat-icon matListItemIcon>{{ icon }}</mat-icon>\n </td>\n }\n @if (properties.target === '_blank' && property.key === 'url') {\n <td>\n <a\n href=\"{{ property.value }}\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {{ 'igo.geo.targetHtmlUrl' | translate }} {{ title }}</a\n >\n <button\n class=\"copyClipboard\"\n mat-icon-button\n (click)=\"copyTextToClipboard(property.value)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </td>\n }\n @if (properties.target === undefined) {\n <td id=\"keyValue\">\n {{ property.key }}\n </td>\n }\n @if (\n properties.target === undefined &&\n !isObject(property.value) &&\n !isUrl(property.value) &&\n !isEmbeddedLink(property.value)\n ) {\n <td [innerHTML]=\"property.value\"></td>\n }\n @if (\n properties.target === undefined && isEmbeddedLink(property.value)\n ) {\n <td>\n <u\n [ngStyle]=\"{ cursor: 'pointer', color: 'blue' }\"\n (click)=\"openSecureUrl(property.value)\"\n >{{ getEmbeddedLinkText(property.value) }}</u\n >\n </td>\n }\n @if (\n properties.target === undefined &&\n !isObject(property.value) &&\n (isDoc(property.value) || isUrl(property.value)) &&\n !isImg(property.value)\n ) {\n <td>\n <u\n [ngStyle]=\"{ cursor: 'pointer', color: 'blue' }\"\n (click)=\"openSecureUrl(property.value)\"\n >{{ 'igo.geo.targetHtmlUrl' | translate }}</u\n >\n <button\n class=\"copyClipboard\"\n mat-icon-button\n (click)=\"copyTextToClipboard(property.value)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </td>\n }\n @if (\n properties.target === undefined &&\n !isObject(property.value) &&\n isUrl(property.value) &&\n isImg(property.value)\n ) {\n <td>\n <a\n href=\"{{ property.value }}\"\n target=\"_blank\"\n (click)=\"openSecureUrl(property.value)\"\n rel=\"noopener noreferrer\"\n >\n <img\n igoImageError\n src=\"{{ property.value | secureImage | async }}\"\n width=\"225\"\n height=\"auto\"\n />\n </a>\n </td>\n }\n @if (properties.target === undefined && isObject(property.value)) {\n <td [innerHTML]=\"property.value | json\"></td>\n }\n </tr>\n }\n </tbody>\n </table>\n}\n\n@if (isHtmlDisplay()) {\n <iframe\n [srcdoc]=\"htmlSanitizer(properties)\"\n [src]=\"urlSanitizer(properties.url)\"\n ></iframe>\n}\n", styles: ["table{width:100%}table .igo-striped tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container-low);color:#000}table td{padding:4px}#keyValue{width:30%}table ::ng-deep .routing{cursor:pointer}iframe{height:calc(100% - 4px);width:100%;border:0}.copyClipboard{border:none;background:transparent;cursor:pointer}\n"] }]
22641
+ SecureImagePipe,
22642
+ MatButtonModule
22643
+ ], template: "@let properties = feature()?.properties;\n@if (\n ready && feature() && isObject(properties) && properties?.target !== 'iframe'\n) {\n <table class=\"igo-striped\">\n <tbody>\n @for (\n property of filterFeatureProperties(feature()) | keyvalue;\n track property\n ) {\n <tr>\n @if (properties?.target === '_blank' && property.key === 'url') {\n <td>\n <mat-icon matListItemIcon>{{ icon }}</mat-icon>\n </td>\n }\n @if (properties?.target === '_blank' && property.key === 'url') {\n <td>\n <a\n href=\"{{ property.value }}\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {{ 'igo.geo.targetHtmlUrl' | translate }} {{ title }}</a\n >\n <button\n matIconButton\n (click)=\"copyTextToClipboard(property.value)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </td>\n }\n @if (properties?.target === undefined) {\n <td id=\"keyValue\">\n {{ property.key }}\n </td>\n }\n @if (\n properties?.target === undefined &&\n !isObject(property.value) &&\n !isUrl(property.value) &&\n !hasEmbeddedLinks(property.value)\n ) {\n <td [innerHTML]=\"property.value\"></td>\n }\n @if (\n properties?.target === undefined && hasEmbeddedLinks(property.value)\n ) {\n <td>\n <u\n [ngStyle]=\"{ cursor: 'pointer', color: 'blue' }\"\n (click)=\"openSecureUrl(property.value)\"\n >{{ getEmbeddedLinkText(property.value) }}</u\n >\n </td>\n }\n @if (\n properties?.target === undefined &&\n !isObject(property.value) &&\n (isDoc(property.value) || isUrl(property.value)) &&\n !isImg(property.value)\n ) {\n <td>\n <u\n [ngStyle]=\"{ cursor: 'pointer', color: 'blue' }\"\n (click)=\"openSecureUrl(property.value)\"\n >{{ 'igo.geo.targetHtmlUrl' | translate }}</u\n >\n <button\n matIconButton\n (click)=\"copyTextToClipboard(property.value)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </td>\n }\n @if (\n properties?.target === undefined &&\n !isObject(property.value) &&\n isUrl(property.value) &&\n isImg(property.value)\n ) {\n <td>\n <a\n href=\"{{ property.value }}\"\n target=\"_blank\"\n (click)=\"openSecureUrl(property.value)\"\n rel=\"noopener noreferrer\"\n >\n <img\n igoImageError\n src=\"{{ property.value | secureImage | async }}\"\n width=\"225\"\n height=\"auto\"\n />\n </a>\n </td>\n }\n @if (properties?.target === undefined && isObject(property.value)) {\n <td [innerHTML]=\"property.value | json\"></td>\n }\n </tr>\n }\n </tbody>\n </table>\n}\n\n@if (isHtmlDisplay()) {\n <iframe\n [srcdoc]=\"htmlSanitizer(properties)\"\n [src]=\"urlSanitizer(properties?.url)\"\n ></iframe>\n}\n", styles: ["table{width:100%}table.igo-striped tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container-high)}table td{padding:4px}#keyValue{width:30%}table ::ng-deep .routing{cursor:pointer}iframe{height:calc(100% - 4px);width:100%;border:0}\n"] }]
22621
22644
  }], ctorParameters: () => [], propDecorators: { source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: false }] }], map: [{ type: i0.Input, args: [{ isSignal: true, alias: "map", required: false }] }], toolbox: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolbox", required: false }] }], feature: [{ type: i0.Input, args: [{ isSignal: true, alias: "feature", required: false }] }], routeEvent: [{ type: i0.Output, args: ["routeEvent"] }], selectFeature: [{ type: i0.Output, args: ["selectFeature"] }], htmlDisplayEvent: [{ type: i0.Output, args: ["htmlDisplayEvent"] }] } });
22622
22645
 
22623
22646
  class FeatureDetailsDirective {
@@ -30641,9 +30664,10 @@ class ImportExportComponent {
30641
30664
  if (isLayerGroup(layer)) {
30642
30665
  return false;
30643
30666
  }
30644
- return ((layer instanceof VectorLayer && layer.exportable === true) ||
30645
- (layer.dataSource.options.download &&
30646
- layer.dataSource.options.download.url));
30667
+ if (layer instanceof VectorLayer) {
30668
+ return layer.exportable || layer.dataSource.options.download?.url;
30669
+ }
30670
+ return false;
30647
30671
  });
30648
30672
  this.exportableLayers$.next(exportableLayers);
30649
30673
  });
@@ -33032,7 +33056,7 @@ class SaveFeatureDialogComponent {
33032
33056
  this.dialogRef.close();
33033
33057
  }
33034
33058
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SaveFeatureDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
33035
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: SaveFeatureDialogComponent, isStandalone: true, selector: "igo-save-feature-dialog", ngImport: i0, template: "<h1 mat-dialog-title>\n {{ 'igo.geo.layer.saveFeatureInLayer' | translate }}\n</h1>\n\n<div mat-dialog-content>\n <form class=\"igo-form\" [formGroup]=\"form\">\n <igo-list [navigation]=\"false\" [selection]=\"false\">\n <igo-search-results-item\n igoListItem\n color=\"accent\"\n [result]=\"feature\"\n [showIcons]=\"true\"\n />\n </igo-list>\n\n <div class=\"igo-input-container\">\n <mat-form-field>\n <input\n type=\"text\"\n placeholder=\"{{ 'igo.geo.layer.chooseOrSet' | translate }}\"\n matInput\n [matAutocomplete]=\"auto\"\n formControlName=\"layerName\"\n />\n <mat-autocomplete [displayWith]=\"displayFn\" #auto=\"matAutocomplete\">\n @for (layer of filteredLayers$ | async; track layer) {\n <mat-option [value]=\"layer\">\n <p matListItemTitle>{{ layer.title }}</p>\n </mat-option>\n }\n </mat-autocomplete>\n </mat-form-field>\n </div>\n </form>\n</div>\n\n<div mat-dialog-actions style=\"justify-content: center\">\n <div class=\"igo-form-button-group create-layer-button-top-padding\">\n <button matButton=\"elevated\" type=\"button\" (click)=\"cancel()\">\n {{ 'igo.geo.layer.cancelBtn' | translate }}\n </button>\n <button\n id=\"createLayerBtnDialog\"\n matButton=\"elevated\"\n type=\"button\"\n color=\"primary\"\n (click)=\"save()\"\n >\n {{ 'igo.geo.layer.saveBtn' | translate }}\n </button>\n </div>\n</div>\n", styles: [":host mat-form-field{width:100%}:host .create-layer-button-top-padding{padding-top:25px}:host .igo-form{padding:10px 5px 5px}:host .igo-form-button-group{text-align:center}:host button{cursor:pointer}:host button#createLayerBtnDialog[disabled=true]{cursor:default;background-color:#0000001f;color:#00000042}:host .error{color:red}\n"], dependencies: [{ kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: ListComponent, selector: "igo-list", inputs: ["navigation", "selection"] }, { kind: "component", type: SearchResultsItemComponent, selector: "igo-search-results-item", inputs: ["result", "map", "showIcons", "withZoomButton"], outputs: ["zoomEvent"] }, { kind: "directive", type: ListItemDirective, selector: "[igoListItem]", inputs: ["color", "focused", "selected", "disabled"], outputs: ["beforeSelect", "beforeFocus", "beforeUnselect", "beforeUnfocus", "beforeDisable", "beforeEnable", "focus", "unfocus", "select", "unselect", "disable", "enable"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i4$2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i4$3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4$2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatListModule }, { kind: "directive", type: i1$2.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] });
33059
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: SaveFeatureDialogComponent, isStandalone: true, selector: "igo-save-feature-dialog", ngImport: i0, template: "<h1 mat-dialog-title>\n {{ 'igo.geo.layer.saveFeatureInLayer' | translate }}\n</h1>\n\n<div mat-dialog-content>\n <form class=\"igo-form\" [formGroup]=\"form\">\n <igo-list [navigation]=\"false\" [selection]=\"false\">\n <igo-search-results-item\n igoListItem\n color=\"accent\"\n [result]=\"feature\"\n [showIcons]=\"true\"\n />\n </igo-list>\n\n <div class=\"igo-input-container\">\n <mat-form-field>\n <input\n type=\"text\"\n placeholder=\"{{ 'igo.geo.layer.chooseOrSet' | translate }}\"\n matInput\n [matAutocomplete]=\"auto\"\n formControlName=\"layerName\"\n />\n <mat-autocomplete [displayWith]=\"displayFn\" #auto=\"matAutocomplete\">\n @for (layer of filteredLayers$ | async; track layer) {\n <mat-option [value]=\"layer\">\n {{ layer.title }}\n </mat-option>\n }\n </mat-autocomplete>\n </mat-form-field>\n </div>\n </form>\n</div>\n\n<div mat-dialog-actions style=\"justify-content: center\">\n <div class=\"igo-form-button-group create-layer-button-top-padding\">\n <button matButton=\"elevated\" type=\"button\" (click)=\"cancel()\">\n {{ 'igo.geo.layer.cancelBtn' | translate }}\n </button>\n <button\n id=\"createLayerBtnDialog\"\n matButton=\"elevated\"\n type=\"button\"\n color=\"primary\"\n (click)=\"save()\"\n >\n {{ 'igo.geo.layer.saveBtn' | translate }}\n </button>\n </div>\n</div>\n", styles: [":host mat-form-field{width:100%}:host .create-layer-button-top-padding{padding-top:25px}:host .igo-form{padding:10px 5px 5px}:host .igo-form-button-group{text-align:center}:host button{cursor:pointer}:host button#createLayerBtnDialog[disabled=true]{cursor:default;background-color:#0000001f;color:#00000042}:host .error{color:red}\n"], dependencies: [{ kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: ListComponent, selector: "igo-list", inputs: ["navigation", "selection"] }, { kind: "component", type: SearchResultsItemComponent, selector: "igo-search-results-item", inputs: ["result", "map", "showIcons", "withZoomButton"], outputs: ["zoomEvent"] }, { kind: "directive", type: ListItemDirective, selector: "[igoListItem]", inputs: ["color", "focused", "selected", "disabled"], outputs: ["beforeSelect", "beforeFocus", "beforeUnselect", "beforeUnfocus", "beforeDisable", "beforeEnable", "focus", "unfocus", "select", "unselect", "disable", "enable"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i4$2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i4$3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4$2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatListModule }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] });
33036
33060
  }
33037
33061
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SaveFeatureDialogComponent, decorators: [{
33038
33062
  type: Component,
@@ -33053,7 +33077,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
33053
33077
  MatButtonModule,
33054
33078
  AsyncPipe,
33055
33079
  IgoLanguageModule
33056
- ], template: "<h1 mat-dialog-title>\n {{ 'igo.geo.layer.saveFeatureInLayer' | translate }}\n</h1>\n\n<div mat-dialog-content>\n <form class=\"igo-form\" [formGroup]=\"form\">\n <igo-list [navigation]=\"false\" [selection]=\"false\">\n <igo-search-results-item\n igoListItem\n color=\"accent\"\n [result]=\"feature\"\n [showIcons]=\"true\"\n />\n </igo-list>\n\n <div class=\"igo-input-container\">\n <mat-form-field>\n <input\n type=\"text\"\n placeholder=\"{{ 'igo.geo.layer.chooseOrSet' | translate }}\"\n matInput\n [matAutocomplete]=\"auto\"\n formControlName=\"layerName\"\n />\n <mat-autocomplete [displayWith]=\"displayFn\" #auto=\"matAutocomplete\">\n @for (layer of filteredLayers$ | async; track layer) {\n <mat-option [value]=\"layer\">\n <p matListItemTitle>{{ layer.title }}</p>\n </mat-option>\n }\n </mat-autocomplete>\n </mat-form-field>\n </div>\n </form>\n</div>\n\n<div mat-dialog-actions style=\"justify-content: center\">\n <div class=\"igo-form-button-group create-layer-button-top-padding\">\n <button matButton=\"elevated\" type=\"button\" (click)=\"cancel()\">\n {{ 'igo.geo.layer.cancelBtn' | translate }}\n </button>\n <button\n id=\"createLayerBtnDialog\"\n matButton=\"elevated\"\n type=\"button\"\n color=\"primary\"\n (click)=\"save()\"\n >\n {{ 'igo.geo.layer.saveBtn' | translate }}\n </button>\n </div>\n</div>\n", styles: [":host mat-form-field{width:100%}:host .create-layer-button-top-padding{padding-top:25px}:host .igo-form{padding:10px 5px 5px}:host .igo-form-button-group{text-align:center}:host button{cursor:pointer}:host button#createLayerBtnDialog[disabled=true]{cursor:default;background-color:#0000001f;color:#00000042}:host .error{color:red}\n"] }]
33080
+ ], template: "<h1 mat-dialog-title>\n {{ 'igo.geo.layer.saveFeatureInLayer' | translate }}\n</h1>\n\n<div mat-dialog-content>\n <form class=\"igo-form\" [formGroup]=\"form\">\n <igo-list [navigation]=\"false\" [selection]=\"false\">\n <igo-search-results-item\n igoListItem\n color=\"accent\"\n [result]=\"feature\"\n [showIcons]=\"true\"\n />\n </igo-list>\n\n <div class=\"igo-input-container\">\n <mat-form-field>\n <input\n type=\"text\"\n placeholder=\"{{ 'igo.geo.layer.chooseOrSet' | translate }}\"\n matInput\n [matAutocomplete]=\"auto\"\n formControlName=\"layerName\"\n />\n <mat-autocomplete [displayWith]=\"displayFn\" #auto=\"matAutocomplete\">\n @for (layer of filteredLayers$ | async; track layer) {\n <mat-option [value]=\"layer\">\n {{ layer.title }}\n </mat-option>\n }\n </mat-autocomplete>\n </mat-form-field>\n </div>\n </form>\n</div>\n\n<div mat-dialog-actions style=\"justify-content: center\">\n <div class=\"igo-form-button-group create-layer-button-top-padding\">\n <button matButton=\"elevated\" type=\"button\" (click)=\"cancel()\">\n {{ 'igo.geo.layer.cancelBtn' | translate }}\n </button>\n <button\n id=\"createLayerBtnDialog\"\n matButton=\"elevated\"\n type=\"button\"\n color=\"primary\"\n (click)=\"save()\"\n >\n {{ 'igo.geo.layer.saveBtn' | translate }}\n </button>\n </div>\n</div>\n", styles: [":host mat-form-field{width:100%}:host .create-layer-button-top-padding{padding-top:25px}:host .igo-form{padding:10px 5px 5px}:host .igo-form-button-group{text-align:center}:host button{cursor:pointer}:host button#createLayerBtnDialog[disabled=true]{cursor:default;background-color:#0000001f;color:#00000042}:host .error{color:red}\n"] }]
33057
33081
  }], ctorParameters: () => [] });
33058
33082
 
33059
33083
  class SearchResultAddButtonComponent {
@@ -34460,15 +34484,15 @@ class IChercheSearchSource extends SearchSource {
34460
34484
  },
34461
34485
  {
34462
34486
  title: 'igo.geo.search.icherche.type.cycleStop',
34463
- value: 'haltes_cyclables',
34464
- enabled: types.indexOf('haltes_cyclables') !== -1,
34465
- hashtags: ['haltevelo', 'haltes_cyclables']
34487
+ value: 'haltes-cyclables',
34488
+ enabled: types.indexOf('haltes-cyclables') !== -1,
34489
+ hashtags: ['haltevelo']
34466
34490
  },
34467
34491
  {
34468
34492
  title: 'igo.geo.search.icherche.type.restArea',
34469
- value: 'haltes_routieres',
34470
- enabled: types.indexOf('haltes_routieres') !== -1,
34471
- hashtags: ['halteroute', 'haltes_routieres']
34493
+ value: 'haltes-routieres',
34494
+ enabled: types.indexOf('haltes-routieres') !== -1,
34495
+ hashtags: ['halteroute']
34472
34496
  },
34473
34497
  {
34474
34498
  title: 'igo.geo.search.icherche.type.hq',
@@ -39787,7 +39811,7 @@ class AddCatalogDialogComponent {
39787
39811
  configService = inject(ConfigService);
39788
39812
  formService = inject(FormService);
39789
39813
  dialogRef = inject(MatDialogRef);
39790
- data = inject(MAT_DIALOG_DATA, { optional: true });
39814
+ data = inject(MAT_DIALOG_DATA);
39791
39815
  predefinedForm$ = new BehaviorSubject(undefined);
39792
39816
  customForm$ = new BehaviorSubject(undefined);
39793
39817
  data$ = new BehaviorSubject(undefined);
@@ -39888,7 +39912,7 @@ class AddCatalogDialogComponent {
39888
39912
  .every((e) => e);
39889
39913
  }
39890
39914
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AddCatalogDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
39891
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AddCatalogDialogComponent, isStandalone: true, selector: "igo-add-catalog-dialog", ngImport: i0, template: "<mat-tab-group\n [selectedIndex]=\"!data.addedCatalog && data.predefinedCatalogs.length ? 0 : 1\"\n>\n <mat-tab\n [label]=\"'igo.geo.catalog.library.predefined' | translate\"\n [disabled]=\"!data.predefinedCatalogs.length\"\n >\n @if (predefinedForm$ | async; as form) {\n <igo-form\n [form]=\"form\"\n [formData]=\"data$ | async\"\n (submitForm)=\"onPredefinedSubmit($any($event))\"\n >\n @if (form.fields.length) {\n <div class=\"form-container\">\n @for (field of form.fields; track field) {\n <igo-form-field [field]=\"field\" />\n }\n </div>\n }\n <div formButtons class=\"actions-container\">\n <button matButton=\"filled\" type=\"submit\" color=\"primary\">\n {{ 'igo.geo.catalog.library.add' | translate }}\n </button>\n </div>\n </igo-form>\n }\n </mat-tab>\n\n <mat-tab class=\"tabs\" [label]=\"'igo.geo.catalog.library.custom' | translate\">\n @if (customForm$ | async; as form) {\n <igo-form\n [form]=\"form\"\n [formData]=\"customData$ | async\"\n (submitForm)=\"onCustomSubmit($any($event))\"\n >\n @if (form.fields.length) {\n <div class=\"form-container\">\n @for (field of form.fields; track field) {\n <igo-form-field [field]=\"field\" />\n }\n </div>\n }\n <div formButtons class=\"actions-container\">\n <button matButton=\"filled\" type=\"submit\" color=\"primary\">\n {{ 'igo.geo.catalog.library.add' | translate }}\n </button>\n </div>\n </igo-form>\n }\n @if (data.error && data.addedCatalog && emailAddress) {\n <span>\n <p class=\"error\">\n {{\n languageService.translate.instant(\n 'igo.geo.catalog.externalProvider.unavailableWithEmail',\n { value: data.addedCatalog.url, email: emailAddress }\n )\n }}\n </p>\n </span>\n }\n @if (data.error && data.addedCatalog && !emailAddress) {\n <span>\n <p class=\"error\">\n {{\n languageService.translate.instant('igo.geo.catalog.unavailable', {\n value: data.addedCatalog.url\n })\n }}\n </p>\n </span>\n }\n </mat-tab>\n</mat-tab-group>\n", styles: [":host mat-tab-group{padding:10px}:host igo-form{overflow:hidden}:host .actions-container button:not(:last-child){margin-right:8px}:host .form-container{width:100%;height:auto;padding:10px}:host .form-container igo-form-field{display:block;height:auto}:host .error{color:red}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i1$5.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i1$5.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "component", type: FormComponent, selector: "igo-form", inputs: ["form", "formData", "autocomplete"], outputs: ["submitForm"] }, { kind: "component", type: FormFieldComponent, selector: "igo-form-field", inputs: ["field"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] });
39915
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AddCatalogDialogComponent, isStandalone: true, selector: "igo-add-catalog-dialog", ngImport: i0, template: "<mat-tab-group\n [selectedIndex]=\"\n !data.addedCatalog ||\n (data.error && data.isPredefinedCatalog && data.predefinedCatalogs.length)\n ? 0\n : 1\n \"\n>\n <mat-tab\n [label]=\"'igo.geo.catalog.library.predefined' | translate\"\n [disabled]=\"!data.predefinedCatalogs.length\"\n >\n @if (predefinedForm$ | async; as form) {\n <igo-form\n [form]=\"form\"\n [formData]=\"data$ | async\"\n (submitForm)=\"onPredefinedSubmit($any($event))\"\n >\n @if (form.fields.length) {\n <div class=\"form-container\">\n @for (field of form.fields; track field) {\n <igo-form-field [field]=\"field\" />\n }\n </div>\n }\n <div formButtons class=\"actions-container\">\n <button matButton=\"filled\" type=\"submit\" color=\"primary\">\n {{ 'igo.geo.catalog.library.add' | translate }}\n </button>\n </div>\n </igo-form>\n }\n </mat-tab>\n\n <mat-tab class=\"tabs\" [label]=\"'igo.geo.catalog.library.custom' | translate\">\n @if (customForm$ | async; as form) {\n <igo-form\n [form]=\"form\"\n [formData]=\"customData$ | async\"\n (submitForm)=\"onCustomSubmit($any($event))\"\n >\n @if (form.fields.length) {\n <div class=\"form-container\">\n @for (field of form.fields; track field) {\n <igo-form-field [field]=\"field\" />\n }\n </div>\n }\n <div formButtons class=\"actions-container\">\n <button matButton=\"filled\" type=\"submit\" color=\"primary\">\n {{ 'igo.geo.catalog.library.add' | translate }}\n </button>\n </div>\n </igo-form>\n }\n </mat-tab>\n</mat-tab-group>\n\n@if (data.error && data.addedCatalog) {\n <p class=\"error\">\n {{\n emailAddress\n ? languageService.translate.instant(\n 'igo.geo.catalog.externalProvider.unavailableWithEmail',\n { value: data.addedCatalog.url, email: emailAddress }\n )\n : languageService.translate.instant('igo.geo.catalog.unavailable', {\n value: data.addedCatalog.url\n })\n }}\n </p>\n}\n", styles: [":host mat-tab-group{padding:10px}:host igo-form{overflow:hidden}:host .actions-container button:not(:last-child){margin-right:8px}:host .form-container{width:100%;height:auto;padding:10px}:host .form-container igo-form-field{display:block;height:auto}:host .error{overflow-wrap:break-word;padding:0 20px;color:red}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i1$5.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i1$5.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "component", type: FormComponent, selector: "igo-form", inputs: ["form", "formData", "autocomplete"], outputs: ["submitForm"] }, { kind: "component", type: FormFieldComponent, selector: "igo-form-field", inputs: ["field"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }] });
39892
39916
  }
39893
39917
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AddCatalogDialogComponent, decorators: [{
39894
39918
  type: Component,
@@ -39908,7 +39932,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
39908
39932
  IgoLanguageModule,
39909
39933
  FormComponent,
39910
39934
  FormFieldComponent
39911
- ], template: "<mat-tab-group\n [selectedIndex]=\"!data.addedCatalog && data.predefinedCatalogs.length ? 0 : 1\"\n>\n <mat-tab\n [label]=\"'igo.geo.catalog.library.predefined' | translate\"\n [disabled]=\"!data.predefinedCatalogs.length\"\n >\n @if (predefinedForm$ | async; as form) {\n <igo-form\n [form]=\"form\"\n [formData]=\"data$ | async\"\n (submitForm)=\"onPredefinedSubmit($any($event))\"\n >\n @if (form.fields.length) {\n <div class=\"form-container\">\n @for (field of form.fields; track field) {\n <igo-form-field [field]=\"field\" />\n }\n </div>\n }\n <div formButtons class=\"actions-container\">\n <button matButton=\"filled\" type=\"submit\" color=\"primary\">\n {{ 'igo.geo.catalog.library.add' | translate }}\n </button>\n </div>\n </igo-form>\n }\n </mat-tab>\n\n <mat-tab class=\"tabs\" [label]=\"'igo.geo.catalog.library.custom' | translate\">\n @if (customForm$ | async; as form) {\n <igo-form\n [form]=\"form\"\n [formData]=\"customData$ | async\"\n (submitForm)=\"onCustomSubmit($any($event))\"\n >\n @if (form.fields.length) {\n <div class=\"form-container\">\n @for (field of form.fields; track field) {\n <igo-form-field [field]=\"field\" />\n }\n </div>\n }\n <div formButtons class=\"actions-container\">\n <button matButton=\"filled\" type=\"submit\" color=\"primary\">\n {{ 'igo.geo.catalog.library.add' | translate }}\n </button>\n </div>\n </igo-form>\n }\n @if (data.error && data.addedCatalog && emailAddress) {\n <span>\n <p class=\"error\">\n {{\n languageService.translate.instant(\n 'igo.geo.catalog.externalProvider.unavailableWithEmail',\n { value: data.addedCatalog.url, email: emailAddress }\n )\n }}\n </p>\n </span>\n }\n @if (data.error && data.addedCatalog && !emailAddress) {\n <span>\n <p class=\"error\">\n {{\n languageService.translate.instant('igo.geo.catalog.unavailable', {\n value: data.addedCatalog.url\n })\n }}\n </p>\n </span>\n }\n </mat-tab>\n</mat-tab-group>\n", styles: [":host mat-tab-group{padding:10px}:host igo-form{overflow:hidden}:host .actions-container button:not(:last-child){margin-right:8px}:host .form-container{width:100%;height:auto;padding:10px}:host .form-container igo-form-field{display:block;height:auto}:host .error{color:red}\n"] }]
39935
+ ], template: "<mat-tab-group\n [selectedIndex]=\"\n !data.addedCatalog ||\n (data.error && data.isPredefinedCatalog && data.predefinedCatalogs.length)\n ? 0\n : 1\n \"\n>\n <mat-tab\n [label]=\"'igo.geo.catalog.library.predefined' | translate\"\n [disabled]=\"!data.predefinedCatalogs.length\"\n >\n @if (predefinedForm$ | async; as form) {\n <igo-form\n [form]=\"form\"\n [formData]=\"data$ | async\"\n (submitForm)=\"onPredefinedSubmit($any($event))\"\n >\n @if (form.fields.length) {\n <div class=\"form-container\">\n @for (field of form.fields; track field) {\n <igo-form-field [field]=\"field\" />\n }\n </div>\n }\n <div formButtons class=\"actions-container\">\n <button matButton=\"filled\" type=\"submit\" color=\"primary\">\n {{ 'igo.geo.catalog.library.add' | translate }}\n </button>\n </div>\n </igo-form>\n }\n </mat-tab>\n\n <mat-tab class=\"tabs\" [label]=\"'igo.geo.catalog.library.custom' | translate\">\n @if (customForm$ | async; as form) {\n <igo-form\n [form]=\"form\"\n [formData]=\"customData$ | async\"\n (submitForm)=\"onCustomSubmit($any($event))\"\n >\n @if (form.fields.length) {\n <div class=\"form-container\">\n @for (field of form.fields; track field) {\n <igo-form-field [field]=\"field\" />\n }\n </div>\n }\n <div formButtons class=\"actions-container\">\n <button matButton=\"filled\" type=\"submit\" color=\"primary\">\n {{ 'igo.geo.catalog.library.add' | translate }}\n </button>\n </div>\n </igo-form>\n }\n </mat-tab>\n</mat-tab-group>\n\n@if (data.error && data.addedCatalog) {\n <p class=\"error\">\n {{\n emailAddress\n ? languageService.translate.instant(\n 'igo.geo.catalog.externalProvider.unavailableWithEmail',\n { value: data.addedCatalog.url, email: emailAddress }\n )\n : languageService.translate.instant('igo.geo.catalog.unavailable', {\n value: data.addedCatalog.url\n })\n }}\n </p>\n}\n", styles: [":host mat-tab-group{padding:10px}:host igo-form{overflow:hidden}:host .actions-container button:not(:last-child){margin-right:8px}:host .form-container{width:100%;height:auto;padding:10px}:host .form-container igo-form-field{display:block;height:auto}:host .error{overflow-wrap:break-word;padding:0 20px;color:red}\n"] }]
39912
39936
  }] });
39913
39937
 
39914
39938
  /**
@@ -40037,34 +40061,31 @@ class CatalogLibraryComponent {
40037
40061
  }
40038
40062
  this.unsubscribeAddingCatalog();
40039
40063
  if (predefinedCatalog) {
40040
- predefinedCatalog.removable ??= true;
40041
- this.handleAddCatalogToStore(predefinedCatalog);
40042
- }
40043
- else {
40044
- this.addingCatalog$$ = this.capabilitiesService
40045
- .getCapabilities(addedCatalog.type, addedCatalog.url)
40046
- .pipe(catchError((e) => {
40047
- if (e.error) {
40048
- this.addCatalogDialog(true, addedCatalog);
40049
- e.error.caught = true;
40050
- return e;
40051
- }
40052
- this.messageService.error('igo.geo.catalog.unavailable', 'igo.geo.catalog.unavailableTitle', undefined, { value: addedCatalog.url });
40053
- throw e;
40054
- }))
40055
- .subscribe((capabilities) => {
40056
- const catalogToAdd = ObjectUtils.removeUndefined(Object.assign({}, {
40057
- id,
40058
- title: addedCatalog.title,
40059
- url: addedCatalog.url,
40060
- type: addedCatalog.type || 'wms',
40061
- externalProvider: true,
40062
- removable: true,
40063
- version: addedCatalog.type === 'wms' ? capabilities.version : '1.3.0'
40064
- }));
40065
- this.handleAddCatalogToStore(catalogToAdd);
40066
- });
40064
+ addedCatalog.removable ??= true;
40067
40065
  }
40066
+ this.addingCatalog$$ = this.capabilitiesService
40067
+ .getCapabilities(addedCatalog.type, addedCatalog.url)
40068
+ .pipe(catchError((e) => {
40069
+ if (e.error) {
40070
+ this.addCatalogDialog(true, addedCatalog, !!predefinedCatalog);
40071
+ e.error.caught = true;
40072
+ return EMPTY;
40073
+ }
40074
+ this.messageService.error('igo.geo.catalog.unavailable', 'igo.geo.catalog.unavailableTitle', undefined, { value: addedCatalog.url });
40075
+ throw e;
40076
+ }))
40077
+ .subscribe((capabilities) => {
40078
+ const catalogToAdd = ObjectUtils.removeUndefined(Object.assign({}, {
40079
+ id,
40080
+ title: addedCatalog.title,
40081
+ url: addedCatalog.url,
40082
+ type: addedCatalog.type || 'wms',
40083
+ externalProvider: true,
40084
+ removable: true,
40085
+ version: addedCatalog.type === 'wms' ? capabilities.version : '1.3.0'
40086
+ }));
40087
+ this.handleAddCatalogToStore(catalogToAdd);
40088
+ });
40068
40089
  }
40069
40090
  ngOnDestroy() {
40070
40091
  this.unsubscribeAddingCatalog();
@@ -40080,14 +40101,15 @@ class CatalogLibraryComponent {
40080
40101
  .slice(0)
40081
40102
  .filter((c) => c.id !== catalog.id);
40082
40103
  }
40083
- addCatalogDialog(error, addedCatalog) {
40104
+ addCatalogDialog(error, addedCatalog, isPredefinedCatalog) {
40084
40105
  const dialogRef = this.dialog.open(AddCatalogDialogComponent, {
40085
40106
  width: '700px',
40086
40107
  data: {
40087
40108
  predefinedCatalogs: this.predefinedCatalogs(),
40088
40109
  store: this.store(),
40089
40110
  error,
40090
- addedCatalog
40111
+ addedCatalog,
40112
+ isPredefinedCatalog
40091
40113
  }
40092
40114
  });
40093
40115
  dialogRef.afterClosed().subscribe((catalog) => {
@@ -42376,5 +42398,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
42376
42398
  * Generated bundle index. Do not edit.
42377
42399
  */
42378
42400
 
42379
- export { AddCatalogDialogComponent, ArcGISRestCapabilitiesLayerTypes, ArcGISRestDataSource, BaseLayersSwitcherComponent, CATALOG_DIRECTIVES, CATALOG_LIBRARY_DIRECTIVES, CadastreSearchSource, CapabilitiesService, CartoDataSource, Catalog, CatalogBrowserComponent, CatalogItemType, CatalogLibraryComponent, CatalogService, ClusterDataSource, ConfigFileToGeoDBService, ConfirmationPopupComponent, CoordinatesReverseSearchSource, CoordinatesReverseSearchSourceFactory, CoordinatesSearchResultFormatter, CoordinatesUnit, CsvSeparator, DDtoDMS, DataService, DataSource, DataSourceService, DirectionRelativePositionType, DirectionSourceKind, DirectionsButtonsComponent, DirectionsComponent, DirectionsFormat, DirectionsInputsComponent, DirectionsResultsComponent, DirectionsService, DirectionsSource, DirectionsType, DownloadButtonComponent, DownloadService, DrawComponent, DrawControl, DrawIconService, DrawStyleService, DropGeoFileDirective, EditionWorkspace, EditionWorkspaceService, EpsgSelectorModalComponent, EsriStyleGenerator, EventRefresh, ExportButtonComponent, ExportError, ExportFormat, ExportFormatLegacy, ExportInvalidFileError, ExportNothingToExportError, ExportService, FEATURE, FEATURE_DETAILS_DIRECTIVES, FEATURE_DIRECTIVES, FILTER_DIRECTIVES, FeatureDataSource, FeatureDetailsComponent, FeatureDetailsDirective, FeatureFormComponent, FeatureMotion, FeatureStore, FeatureStoreInMapExtentStrategy, FeatureStoreInMapResolutionStrategy, FeatureStoreLoadingLayerStrategy, FeatureStoreLoadingStrategy, FeatureStoreSearchIndexStrategy, FeatureStoreSelectionStrategy, FeatureWorkspace, FeatureWorkspaceService, FilterableDataSourcePipe, GEOMETRY_FORM_FIELD_DIRECTIVES, GeoDB, GeoNetworkService, GeoPropertiesStrategy, GeolocateButtonComponent, GeolocationOverlayType, GeometryFormFieldComponent, GeometryFormFieldInputComponent, GeometrySliceError, GeometrySliceLineStringError, GeometrySliceMultiPolygonError, GeometrySliceTooManyIntersectionError, GeometryType, GoogleLinks, HomeExtentButtonComponent, HoverFeatureDirective, IChercheReverseSearchSource, IChercheSearchResultFormatter, IChercheSearchSource, ID_GROUP_PREFIX, ILayerSearchResultFormatter, ILayerSearchSource, IMPORT_EXPORT_DIRECTIVES, IgoCatalogBrowserModule, IgoCatalogLibraryModule, IgoCatalogModule, IgoConfirmationPopupModule, IgoDirectionsModule, IgoDownloadModule, IgoDrawModule, IgoDrawingToolModule, IgoFeatureDetailsModule, IgoFeatureFormModule, IgoFeatureModule, IgoFilterModule, IgoGeoModule, IgoGeoWorkspaceModule, IgoGeometryFormFieldModule, IgoGeometryModule, IgoHttpParameterCodec, IgoImportExportModule, IgoLayerModule, IgoMap, IgoMapModule, IgoMeasureModule, IgoMeasurerModule, IgoMetadataModule, IgoOgcFilterModule, IgoPrintModule, IgoQueryModule, IgoSearchBarModule, IgoSearchModule, IgoSearchResultsModule, IgoSearchSelectorModule, IgoSearchSettingsModule, IgoStyleListModule, IgoStyleModule, IgoToastModule, IgoWktModule, IgoWorkspaceSelectorModule, IgoWorkspaceUpdatorModule, ImageArcGISRestDataSource, ImageLayer, ImageWatcher, ImportError, ImportExportComponent, ImportInvalidFileError, ImportNothingToImportError, ImportOgreServerError, ImportSRSError, ImportService, ImportSizeError, ImportUnreadableFileError, InfoSectionComponent, InsertSourceInsertDBEnum, InteractiveSelectionFormWidget, LAYER, LAYER_DIRECTIVES, LabelType, LaneType, Layer, LayerBase, LayerController, LayerDB, LayerGroup, LayerGroupBase, LayerGroupComponent, LayerItemComponent, LayerLegendComponent, LayerLegendItemComponent, LayerLegendListBindingDirective, LayerLegendListComponent, LayerListComponent, LayerListControlsEnum, LayerListToolComponent, LayerListToolService, LayerSearchComponent, LayerService, LayerUnavailableComponent, LayerUnavailableListComponent, LayerViewerBottomActionsComponent, LayerViewerComponent, LayerVisibilityButtonComponent, Linked, LinkedProperties, MAP_DIRECTIVES, MEASURER_DIRECTIVES, MEASURE_UNIT_AUTO, METADATA_DIRECTIVES, MVTDataSource, ManeuverModifier, ManeuverType, MapBase, MapBrowserComponent, MapCenterComponent, MapController, MapGeolocationController, MapOfflineDirective, MapService, MapViewAction, MapViewController, MeasureAreaUnit, MeasureAreaUnitAbbreviation, MeasureFormatPipe, MeasureLengthUnit, MeasureLengthUnitAbbreviation, MeasureType, MeasurerComponent, MenuButtonComponent, MetadataAbstractComponent, MetadataButtonComponent, MetadataService, MiniBaseMapComponent, ModifyControl, NominatimSearchSource, OGCFilterService, OSMDataSource, OfflineButtonComponent, OgcFilterButtonComponent, OgcFilterComponent, OgcFilterFormComponent, OgcFilterOperator, OgcFilterOperatorType, OgcFilterSelectionComponent, OgcFilterTimeComponent, OgcFilterTimeSliderComponent, OgcFilterWidget, OgcFilterWriter, OgcFilterableFormComponent, OgcFilterableItemComponent, OgcFilterableListBindingDirective, OgcFilterableListComponent, OgcSelectorFields, OlDragSelectInteraction, OptionsApiService, OptionsService, OsmLinks, OsrmDirectionsSource, Overlay, OverlayAction, PointerPositionDirective, PrintComponent, PrintFormComponent, PrintLegendPosition, PrintOrientation, PrintOutputFormat, PrintPaperFormat, PrintResolution, PrintSaveImageFormat, PrintService, ProjectionService, PropertyTypeDetectorService, ProposalType, QueryDirective, QueryFormat, QueryFormatMimeType, QueryHtmlTarget, QuerySearchSource, QueryService, RADIUS_NAME, RotationButtonComponent, RoutesFeatureStore, SEARCH_DIRECTIVES, SEARCH_RESULTS_DIRECTIVES, SEARCH_TYPES, STYLELIST_OPTIONS, SearchBarComponent, SearchPointerSummaryDirective, SearchResultAddButtonComponent, SearchResultMode, SearchResultsComponent, SearchSelectorComponent, SearchService, SearchSettingsComponent, SearchSource, SearchSourceKind, SearchSourceService, SliceControl, SourceDirectionsType, SpatialFilterItemComponent, SpatialFilterItemType, SpatialFilterListComponent, SpatialFilterQueryType, SpatialFilterService, SpatialFilterType, SpatialFilterTypeComponent, StepsFeatureStore, StopsFeatureStore, StopsStore, StoredQueriesReverseSearchSource, StoredQueriesSearchSource, StyleListService, StyleModalDrawingComponent, StyleModalLayerButtonComponent, StyleModalLayerComponent, StyleService, SwipeControlComponent, TileArcGISRestDataSource, TileDebugDataSource, TileLayer, TileWatcher, TimeFilterButtonComponent, TimeFilterFormComponent, TimeFilterItemComponent, TimeFilterListBindingDirective, TimeFilterListComponent, TimeFilterService, TimeFilterStyle, TimeFilterType, ToastComponent, TooltipType, TrackFeatureButtonComponent, TypeCapabilities, TypeCatalog, VectorLayer, VectorTileLayer, VectorWatcher, WFSDataSource, WFSService, WMSDataSource, WMTSDataSource, WakeLockButtonComponent, WebSocketDataSource, WfsWorkspace, WfsWorkspaceService, WktService, WorkspaceSearchSource, WorkspaceSelectorDirective, WorkspaceUpdatorDirective, XYZDataSource, ZoomButtonComponent, addLayerAndFeaturesStyledToMap, addLayerAndFeaturesToMap, addLinearRingToOlPolygon, addOrRemoveLayer, addRouteToRoutesFeatureStore, addStopToStopsFeatureStore, addStopToStore, bufferOlGeometry, buildUrl, cadastreSearchSourceFactory, checkWfsParams, clearOlGeometryMidpoints, computeBestAreaUnit, computeBestLengthUnit, computeLayerTitleFromFile, computeMVTOptionsOnHover, computeOlFeatureExtent, computeOlFeaturesDiff, computeOlFeaturesExtent, computeProjectionsConstraints, computeRelativePosition, computeStopsPosition, computeTermSimilarity, convertDDToDMS, createDefaultTileGrid, createDrawHoleInteractionStyle, createDrawInteractionStyle, createFilterInMapExtentOrResolutionStrategy, createInteractionStyle, createMeasureInteractionStyle, createMeasureLayerStyle, createOlTooltipAtPoint, createOlTooltipDrawAtPoint, createOverlayDefaultStyle, createOverlayLayer, createOverlayLayerStyle, createOverlayMarkerStyle, createTableTemplate, ctrlKeyDown, defaultCoordinatesSearchResultFormatterFactory, defaultEpsg, defaultFieldNameGeometry, defaultIChercheSearchResultFormatterFactory, defaultMaxFeatures, defaultWfsVersion, detectFileEPSG, directionsStyle, doesOlGeometryIntersects, entitiesToRowData, exportToCSV, featureFromOl, featureRandomStyle, featureRandomStyleFunction, featureToOl, featureToSearchResult, featuresAreOutOfView, featuresAreTooDeepInView, findDiff, findLayerByLinkId, findParentId, formatDistance, formatDuration, formatMeasure, formatScale, formatStep, formatWFSQueryString, generateArcgisRestIdFromSourceOptions, generateFeatureIdFromSourceOptions, generateId, generateIdFromSourceOptions, generateWMSIdFromSourceOptions, generateWMTSIdFromSourceOptions, generateWfsIdFromSourceOptions, generateXYZIdFromSourceOptions, getAllChildLayersByDeletion, getAllChildLayersByProperty, getCommonVectorSelectedStyle, getCommonVectorStyle, getFileExtension, getFormatFromOptions, getGeoServiceAction, getLayerOptionIdentifier, getLayersByDeletion, getLayersLegends, getLinkedLayersOptions, getMousePositionFromOlGeometryEvent, getOlTooltipAtCenter, getOlTooltipsAtMidpoints, getResolutionFromScale, getRootParentByDeletion, getRootParentByProperty, getRowsInMapExtent, getSaveableOgcParams, getScaleFromResolution, getSelectedOnly, getTooltipsOfOlGeometry, gmlRegex, handleFileExportError, handleFileExportSuccess, handleFileImportError, handleFileImportSuccess, handleInvalidFileImportError, handleLayerPropertyChange, handleNothingToExportError, handleNothingToImportError, handleOgreServerImportError, handleSRSImportError, handleSizeFileImportError, handleUnreadbleFileImportError, hideOlFeature, hoverFeatureMarkerStyle, ichercheReverseSearchSourceFactory, ichercheSearchSourceFactory, ilayerSearchResultFormatterFactory, ilayerSearchSourceFactory, initRoutesFeatureStore, initStepsFeatureStore, initStopsFeatureStore, interactiveSelectionFormWidgetFactory, isBaseLayer, isBaseLayerLinked, isCsvExport, isLayerGroup, isLayerGroupOptions, isLayerItem, isLayerItemOptions, isLayerLinked, isLayerLinkedOptions, isLayerLinkedTogether, isLinkMaster, isSaveableLayer, jsonRegex, layerFeatureIsQueryable, layerIsQueryable, lonLatConversion, mapExtentStrategyActiveToolTip, measureOlGeometry, measureOlGeometryArea, measureOlGeometryLength, mergeLayersOptions, metersToFeet, metersToKilometers, metersToMiles, metersToUnit, moveToOlFeatures, mtmZoneFromLonLat, noElementSelected, nominatimSearchSourceFactory, ogcFilterWidgetFactory, olLayerFeatureIsQueryable, olLayerIsQueryable, olStyleToBasicIgoStyle, optionsApiFactory, osrmDirectionsSourcesFactory, pointerPositionSummaryMarkerStyle, provideCadastreSearchSource, provideCoordinatesReverseSearchSource, provideDefaultCoordinatesSearchResultFormatter, provideDefaultIChercheSearchResultFormatter, provideDirection, provideIChercheReverseSearchSource, provideIChercheSearchSource, provideILayerSearchResultFormatter, provideILayerSearchSource, provideInteractiveSelectionFormWidget, provideNominatimSearchSource, provideOffline, provideOgcFilterWidget, provideOptionsApi, provideOsrmDirectionsSource, provideQuerySearchSource, provideSearch, provideSearchSourceService, provideStoredQueriesReverseSearchSource, provideStoredQueriesSearchSource, provideStyleListLoader, provideStyleListOptions, provideWorkspaceSearchSource, querySearchSourceFactory, removeStopFromStore, renderFeatureFromOl, roundCoordTo, roundCoordToString, scaleExtent, searchSourceServiceFactory, setRowsInMapExtent, setSelectedOnly, sliceOlGeometry, sliceOlPolygon, sortLayersByZindex, sourceCanReverseSearch, sourceCanReverseSearchAsSummary, sourceCanSearch, squareMetersToAcres, squareMetersToHectares, squareMetersToSquareFeet, squareMetersToSquareKilometers, squareMetersToSquareMiles, squareMetersToUnit, standardizeUrl, storedqueriesReverseSearchSourceFactory, storedqueriesSearchSourceFactory, stringToLonLat, translateManeuverBearing, translateManeuverModifier, tryAddLoadingStrategy, tryAddSelectionStrategy, tryBindStoreLayer, updateOlGeometryCenter, updateOlGeometryMidpoints, updateOlTooltipAtCenter, updateOlTooltipDrawAtCenter, updateOlTooltipsAtMidpoints, updateOlTooltipsDrawAtMidpoints, updateStoreSorting, utmZoneFromLonLat, viewStatesAreEqual, withCadastreSource, withCoordinatesReverseSource, withIChercheReverseSource, withIChercheSource, withILayerSource, withNominatimSource, withOsrmSource, withStoredQueriesReverseSource, withStoredQueriesSource, withWorkspaceSource, workspaceSearchSourceFactory, zoneMtm, zoneUtm };
42401
+ export { AddCatalogDialogComponent, ArcGISRestCapabilitiesLayerTypes, ArcGISRestDataSource, BaseLayersSwitcherComponent, CATALOG_DIRECTIVES, CATALOG_LIBRARY_DIRECTIVES, CadastreSearchSource, CapabilitiesService, CartoDataSource, Catalog, CatalogBrowserComponent, CatalogItemType, CatalogLibraryComponent, CatalogService, ClusterDataSource, ConfigFileToGeoDBService, ConfirmationPopupComponent, CoordinatesReverseSearchSource, CoordinatesReverseSearchSourceFactory, CoordinatesSearchResultFormatter, CoordinatesUnit, CsvSeparator, DDtoDMS, DataService, DataSource, DataSourceService, DirectionRelativePositionType, DirectionSourceKind, DirectionsButtonsComponent, DirectionsComponent, DirectionsFormat, DirectionsInputsComponent, DirectionsResultsComponent, DirectionsService, DirectionsSource, DirectionsType, DownloadButtonComponent, DownloadService, DrawComponent, DrawControl, DrawIconService, DrawStyleService, DropGeoFileDirective, EditionWorkspace, EditionWorkspaceService, EpsgSelectorModalComponent, EsriStyleGenerator, EventRefresh, ExportButtonComponent, ExportError, ExportFormat, ExportFormatLegacy, ExportInvalidFileError, ExportNothingToExportError, ExportService, FEATURE, FEATURE_DETAILS_DIRECTIVES, FEATURE_DIRECTIVES, FILTER_DIRECTIVES, FeatureDataSource, FeatureDetailsComponent, FeatureDetailsDirective, FeatureFormComponent, FeatureMotion, FeatureStore, FeatureStoreInMapExtentStrategy, FeatureStoreInMapResolutionStrategy, FeatureStoreLoadingLayerStrategy, FeatureStoreLoadingStrategy, FeatureStoreSearchIndexStrategy, FeatureStoreSelectionStrategy, FeatureWorkspace, FeatureWorkspaceService, FilterableDataSourcePipe, GEOMETRY_FORM_FIELD_DIRECTIVES, GeoDB, GeoNetworkService, GeoPropertiesStrategy, GeolocateButtonComponent, GeolocationOverlayType, GeometryFormFieldComponent, GeometryFormFieldInputComponent, GeometrySliceError, GeometrySliceLineStringError, GeometrySliceMultiPolygonError, GeometrySliceTooManyIntersectionError, GeometryType, GoogleLinks, HomeExtentButtonComponent, HoverFeatureDirective, IChercheReverseSearchSource, IChercheSearchResultFormatter, IChercheSearchSource, ID_GROUP_PREFIX, ILayerSearchResultFormatter, ILayerSearchSource, IMPORT_EXPORT_DIRECTIVES, IgoCatalogBrowserModule, IgoCatalogLibraryModule, IgoCatalogModule, IgoConfirmationPopupModule, IgoDirectionsModule, IgoDownloadModule, IgoDrawModule, IgoDrawingToolModule, IgoFeatureDetailsModule, IgoFeatureFormModule, IgoFeatureModule, IgoFilterModule, IgoGeoModule, IgoGeoWorkspaceModule, IgoGeometryFormFieldModule, IgoGeometryModule, IgoHttpParameterCodec, IgoImportExportModule, IgoLayerModule, IgoMap, IgoMapModule, IgoMeasureModule, IgoMeasurerModule, IgoMetadataModule, IgoOgcFilterModule, IgoPrintModule, IgoQueryModule, IgoSearchBarModule, IgoSearchModule, IgoSearchResultsModule, IgoSearchSelectorModule, IgoSearchSettingsModule, IgoStyleListModule, IgoStyleModule, IgoToastModule, IgoWktModule, IgoWorkspaceSelectorModule, IgoWorkspaceUpdatorModule, ImageArcGISRestDataSource, ImageLayer, ImageWatcher, ImportError, ImportExportComponent, ImportInvalidFileError, ImportNothingToImportError, ImportOgreServerError, ImportSRSError, ImportService, ImportSizeError, ImportUnreadableFileError, InfoSectionComponent, InsertSourceInsertDBEnum, InteractiveSelectionFormWidget, LAYER, LAYER_DIRECTIVES, LabelType, LaneType, Layer, LayerBase, LayerController, LayerDB, LayerGroup, LayerGroupBase, LayerGroupComponent, LayerItemComponent, LayerLegendComponent, LayerLegendItemComponent, LayerLegendListBindingDirective, LayerLegendListComponent, LayerListComponent, LayerListControlsEnum, LayerListToolComponent, LayerListToolService, LayerSearchComponent, LayerService, LayerUnavailableComponent, LayerUnavailableListComponent, LayerViewerBottomActionsComponent, LayerViewerComponent, LayerVisibilityButtonComponent, Linked, LinkedProperties, MAP_DIRECTIVES, MEASURER_DIRECTIVES, MEASURE_UNIT_AUTO, METADATA_DIRECTIVES, MVTDataSource, ManeuverModifier, ManeuverType, MapBase, MapBrowserComponent, MapCenterComponent, MapController, MapGeolocationController, MapOfflineDirective, MapService, MapViewAction, MapViewController, MeasureAreaUnit, MeasureAreaUnitAbbreviation, MeasureFormatPipe, MeasureLengthUnit, MeasureLengthUnitAbbreviation, MeasureType, MeasurerComponent, MenuButtonComponent, MetadataAbstractComponent, MetadataButtonComponent, MetadataService, MiniBaseMapComponent, ModifyControl, NominatimSearchSource, OGCFilterService, OSMDataSource, OfflineButtonComponent, OgcFilterButtonComponent, OgcFilterComponent, OgcFilterFormComponent, OgcFilterOperator, OgcFilterOperatorType, OgcFilterSelectionComponent, OgcFilterTimeComponent, OgcFilterTimeSliderComponent, OgcFilterWidget, OgcFilterWriter, OgcFilterableFormComponent, OgcFilterableItemComponent, OgcFilterableListBindingDirective, OgcFilterableListComponent, OgcSelectorFields, OlDragSelectInteraction, OptionsApiService, OptionsService, OsmLinks, OsrmDirectionsSource, Overlay, OverlayAction, PointerPositionDirective, PrintComponent, PrintFormComponent, PrintLegendPosition, PrintOrientation, PrintOutputFormat, PrintPaperFormat, PrintResolution, PrintSaveImageFormat, PrintService, ProjectionService, PropertyTypeDetectorService, ProposalType, QueryDirective, QueryFormat, QueryFormatMimeType, QueryHtmlTarget, QuerySearchSource, QueryService, RADIUS_NAME, RotationButtonComponent, RoutesFeatureStore, SEARCH_DIRECTIVES, SEARCH_RESULTS_DIRECTIVES, SEARCH_TYPES, STYLELIST_OPTIONS, SearchBarComponent, SearchPointerSummaryDirective, SearchResultAddButtonComponent, SearchResultMode, SearchResultsComponent, SearchSelectorComponent, SearchService, SearchSettingsComponent, SearchSource, SearchSourceKind, SearchSourceService, SliceControl, SourceDirectionsType, SpatialFilterItemComponent, SpatialFilterItemType, SpatialFilterListComponent, SpatialFilterQueryType, SpatialFilterService, SpatialFilterType, SpatialFilterTypeComponent, StepsFeatureStore, StopsFeatureStore, StopsStore, StoredQueriesReverseSearchSource, StoredQueriesSearchSource, StyleListService, StyleModalDrawingComponent, StyleModalLayerButtonComponent, StyleModalLayerComponent, StyleService, SwipeControlComponent, TileArcGISRestDataSource, TileDebugDataSource, TileLayer, TileWatcher, TimeFilterButtonComponent, TimeFilterFormComponent, TimeFilterItemComponent, TimeFilterListBindingDirective, TimeFilterListComponent, TimeFilterService, TimeFilterStyle, TimeFilterType, ToastComponent, TooltipType, TrackFeatureButtonComponent, TypeCapabilities, TypeCatalog, VectorLayer, VectorTileLayer, VectorWatcher, WFSDataSource, WFSService, WMSDataSource, WMTSDataSource, WakeLockButtonComponent, WebSocketDataSource, WfsWorkspace, WfsWorkspaceService, WktService, WorkspaceSearchSource, WorkspaceSelectorDirective, WorkspaceUpdatorDirective, XYZDataSource, ZoomButtonComponent, addLayerAndFeaturesStyledToMap, addLayerAndFeaturesToMap, addLinearRingToOlPolygon, addOrRemoveLayer, addRouteToRoutesFeatureStore, addStopToStopsFeatureStore, addStopToStore, bufferOlGeometry, buildUrl, cadastreSearchSourceFactory, checkWfsParams, clearOlGeometryMidpoints, computeBestAreaUnit, computeBestLengthUnit, computeLayerTitleFromFile, computeMVTOptionsOnHover, computeOlFeatureExtent, computeOlFeaturesDiff, computeOlFeaturesExtent, computeProjectionsConstraints, computeRelativePosition, computeStopsPosition, computeTermSimilarity, convertDDToDMS, createDefaultTileGrid, createDrawHoleInteractionStyle, createDrawInteractionStyle, createFilterInMapExtentOrResolutionStrategy, createInteractionStyle, createMeasureInteractionStyle, createMeasureLayerStyle, createOlTooltipAtPoint, createOlTooltipDrawAtPoint, createOverlayDefaultStyle, createOverlayLayer, createOverlayLayerStyle, createOverlayMarkerStyle, createTableTemplate, ctrlKeyDown, defaultCoordinatesSearchResultFormatterFactory, defaultEpsg, defaultFieldNameGeometry, defaultIChercheSearchResultFormatterFactory, defaultMaxFeatures, defaultWfsVersion, detectFileEPSG, directionsStyle, doesOlGeometryIntersects, entitiesToRowData, exportToCSV, featureFromOl, featureRandomStyle, featureRandomStyleFunction, featureToOl, featureToSearchResult, featuresAreOutOfView, featuresAreTooDeepInView, findDiff, findLayerByLinkId, findParentId, formatDistance, formatDuration, formatMeasure, formatScale, formatStep, formatWFSQueryString, generateArcgisRestIdFromSourceOptions, generateFeatureIdFromSourceOptions, generateId, generateIdFromSourceOptions, generateWMSIdFromSourceOptions, generateWMTSIdFromSourceOptions, generateWfsIdFromSourceOptions, generateXYZIdFromSourceOptions, getAllChildLayersByDeletion, getAllChildLayersByProperty, getCommonVectorSelectedStyle, getCommonVectorStyle, getFileExtension, getFilterBadge, getFormatFromOptions, getGeoServiceAction, getLayerOptionIdentifier, getLayersByDeletion, getLayersLegends, getLinkedLayersOptions, getMousePositionFromOlGeometryEvent, getOlTooltipAtCenter, getOlTooltipsAtMidpoints, getResolutionFromScale, getRootParentByDeletion, getRootParentByProperty, getRowsInMapExtent, getSaveableOgcParams, getScaleFromResolution, getSelectedOnly, getTooltipsOfOlGeometry, gmlRegex, handleFileExportError, handleFileExportSuccess, handleFileImportError, handleFileImportSuccess, handleInvalidFileImportError, handleLayerPropertyChange, handleNothingToExportError, handleNothingToImportError, handleOgreServerImportError, handleSRSImportError, handleSizeFileImportError, handleUnreadbleFileImportError, hideOlFeature, hoverFeatureMarkerStyle, ichercheReverseSearchSourceFactory, ichercheSearchSourceFactory, ilayerSearchResultFormatterFactory, ilayerSearchSourceFactory, initRoutesFeatureStore, initStepsFeatureStore, initStopsFeatureStore, interactiveSelectionFormWidgetFactory, isBaseLayer, isBaseLayerLinked, isCsvExport, isLayerGroup, isLayerGroupOptions, isLayerItem, isLayerItemOptions, isLayerLinked, isLayerLinkedOptions, isLayerLinkedTogether, isLinkMaster, isSaveableLayer, jsonRegex, layerFeatureIsQueryable, layerIsQueryable, lonLatConversion, mapExtentStrategyActiveToolTip, measureOlGeometry, measureOlGeometryArea, measureOlGeometryLength, mergeLayersOptions, metersToFeet, metersToKilometers, metersToMiles, metersToUnit, moveToOlFeatures, mtmZoneFromLonLat, noElementSelected, nominatimSearchSourceFactory, ogcFilterWidgetFactory, olLayerFeatureIsQueryable, olLayerIsQueryable, olStyleToBasicIgoStyle, optionsApiFactory, osrmDirectionsSourcesFactory, pointerPositionSummaryMarkerStyle, provideCadastreSearchSource, provideCoordinatesReverseSearchSource, provideDefaultCoordinatesSearchResultFormatter, provideDefaultIChercheSearchResultFormatter, provideDirection, provideIChercheReverseSearchSource, provideIChercheSearchSource, provideILayerSearchResultFormatter, provideILayerSearchSource, provideInteractiveSelectionFormWidget, provideNominatimSearchSource, provideOffline, provideOgcFilterWidget, provideOptionsApi, provideOsrmDirectionsSource, provideQuerySearchSource, provideSearch, provideSearchSourceService, provideStoredQueriesReverseSearchSource, provideStoredQueriesSearchSource, provideStyleListLoader, provideStyleListOptions, provideWorkspaceSearchSource, querySearchSourceFactory, removeStopFromStore, renderFeatureFromOl, roundCoordTo, roundCoordToString, scaleExtent, searchSourceServiceFactory, setRowsInMapExtent, setSelectedOnly, sliceOlGeometry, sliceOlPolygon, sortLayersByZindex, sourceCanReverseSearch, sourceCanReverseSearchAsSummary, sourceCanSearch, squareMetersToAcres, squareMetersToHectares, squareMetersToSquareFeet, squareMetersToSquareKilometers, squareMetersToSquareMiles, squareMetersToUnit, standardizeUrl, storedqueriesReverseSearchSourceFactory, storedqueriesSearchSourceFactory, stringToLonLat, translateManeuverBearing, translateManeuverModifier, tryAddLoadingStrategy, tryAddSelectionStrategy, tryBindStoreLayer, updateOlGeometryCenter, updateOlGeometryMidpoints, updateOlTooltipAtCenter, updateOlTooltipDrawAtCenter, updateOlTooltipsAtMidpoints, updateOlTooltipsDrawAtMidpoints, updateStoreSorting, utmZoneFromLonLat, viewStatesAreEqual, withCadastreSource, withCoordinatesReverseSource, withIChercheReverseSource, withIChercheSource, withILayerSource, withNominatimSource, withOsrmSource, withStoredQueriesReverseSource, withStoredQueriesSource, withWorkspaceSource, workspaceSearchSourceFactory, zoneMtm, zoneUtm };
42380
42402
  //# sourceMappingURL=igo2-geo.mjs.map