diff --git a/packages/context/src/lib/context-manager/shared/layer-context.directive.ts b/packages/context/src/lib/context-manager/shared/layer-context.directive.ts
index fb4a37a66..df0dc3757 100644
--- a/packages/context/src/lib/context-manager/shared/layer-context.directive.ts
+++ b/packages/context/src/lib/context-manager/shared/layer-context.directive.ts
@@ -83,6 +83,7 @@ export class LayerContextDirective implements OnInit, OnDestroy {
}
this.contextLayers = [];
+ this.layerService.unavailableLayers = [];
const layersAndIndex$ = merge(
...context.layers.map((layerOptions: LayerOptions) => {
return this.layerService.createAsyncLayer(layerOptions, context.uri);
diff --git a/packages/geo/src/lib/datasource/shared/datasources/any-datasource.interface.ts b/packages/geo/src/lib/datasource/shared/datasources/any-datasource.interface.ts
index fcdbd13c9..5b4eb9095 100644
--- a/packages/geo/src/lib/datasource/shared/datasources/any-datasource.interface.ts
+++ b/packages/geo/src/lib/datasource/shared/datasources/any-datasource.interface.ts
@@ -28,3 +28,12 @@ export type AnyDataSourceOptions =
| TileArcGISRestDataSourceOptions
| MVTDataSourceOptions
| ClusterDataSourceOptions;
+
+export type AnyDataSourceOptionsWithParams =
+ | FeatureDataSourceOptions
+ | WFSDataSourceOptions
+ | WMSDataSourceOptions
+ | CartoDataSourceOptions
+ | ArcGISRestDataSourceOptions
+ | ArcGISRestImageDataSourceOptions
+ | TileArcGISRestDataSourceOptions;
diff --git a/packages/geo/src/lib/layer/layer-item/layer-item.component.html b/packages/geo/src/lib/layer/layer-item/layer-item.component.html
index c7f3bd53c..14f82ec88 100644
--- a/packages/geo/src/lib/layer/layer-item/layer-item.component.html
+++ b/packages/geo/src/lib/layer/layer-item/layer-item.component.html
@@ -1,92 +1,134 @@
-
-
-
-
- {{ layer.title }}
-
-
-
-
-
-
+ {{ layer.title }}
+
-
+
+
+
+
- more_horiz
-
+
-
+
-
-
+
-
-
+
+ {{ unavailableLayerTitle }}
+
+
+
+
diff --git a/packages/geo/src/lib/layer/layer-item/layer-item.component.scss b/packages/geo/src/lib/layer/layer-item/layer-item.component.scss
index 71cb79ca9..24e89a12a 100644
--- a/packages/geo/src/lib/layer/layer-item/layer-item.component.scss
+++ b/packages/geo/src/lib/layer/layer-item/layer-item.component.scss
@@ -26,4 +26,8 @@
width: 16px;
padding-right: 0px;
}
+
+ .align-disabled-button-with-tooltip {
+ display: inline-block;
+ }
}
diff --git a/packages/geo/src/lib/layer/layer-item/layer-item.component.ts b/packages/geo/src/lib/layer/layer-item/layer-item.component.ts
index 4e13d9f4c..3c86ea2a5 100644
--- a/packages/geo/src/lib/layer/layer-item/layer-item.component.ts
+++ b/packages/geo/src/lib/layer/layer-item/layer-item.component.ts
@@ -26,6 +26,7 @@ import { BehaviorSubject, Subscription } from 'rxjs';
import { MetadataLayerOptions } from '../../metadata/shared/metadata.interface';
import { layerIsQueryable } from '../../query/shared/query.utils';
import { LayerLegendComponent } from '../layer-legend/layer-legend.component';
+import { AnyLayerOptions } from '../shared';
import { Layer } from '../shared/layers/layer';
import { TooltipType } from '../shared/layers/layer.interface';
@@ -131,6 +132,22 @@ export class LayerItemComponent implements OnInit, OnDestroy {
@Input() changeDetection;
+ @Input() unavailableLayer: AnyLayerOptions;
+
+ get unavailableLayerTitle(): string | undefined {
+ if (
+ this.unavailableLayer.sourceOptions &&
+ 'params' in this.unavailableLayer.sourceOptions
+ ) {
+ return this.unavailableLayer.sourceOptions.params.LAYERS;
+ } else if (
+ this.unavailableLayer.sourceOptions &&
+ 'layer' in this.unavailableLayer?.sourceOptions
+ ) {
+ return this.unavailableLayer.sourceOptions.layer;
+ }
+ }
+
get opacity() {
return this.layer.opacity * 100;
}
@@ -148,7 +165,9 @@ export class LayerItemComponent implements OnInit, OnDestroy {
}
}
- @Output() action: EventEmitter = new EventEmitter(undefined);
+ @Output() action: EventEmitter = new EventEmitter<
+ Layer | AnyLayerOptions
+ >(undefined);
@Output() checkbox = new EventEmitter<{
layer: Layer;
check: boolean;
@@ -162,46 +181,48 @@ export class LayerItemComponent implements OnInit, OnDestroy {
) {}
ngOnInit() {
- if (
- this.layer.visible &&
- this.expandLegendIfVisible &&
- this.layer.firstLoadComponent === true
- ) {
- this.layer.firstLoadComponent = false;
- this.layer.legendCollapsed = false;
- }
- this.toggleLegend(this.layer.legendCollapsed);
- this.updateQueryBadge();
-
- const resolution$ = this.layer.map.viewController.resolution$;
- this.resolution$$ = resolution$.subscribe(() => {
- this.onResolutionChange();
- });
- this.tooltipText = this.computeTooltip();
+ if (!this.unavailableLayer) {
+ if (
+ this.layer.visible &&
+ this.expandLegendIfVisible &&
+ this.layer.firstLoadComponent === true
+ ) {
+ this.layer.firstLoadComponent = false;
+ this.layer.legendCollapsed = false;
+ }
+ this.toggleLegend(this.layer.legendCollapsed);
+ this.updateQueryBadge();
- this.network$$ = this.networkService
- .currentState()
- .subscribe((state: ConnectionState) => {
- this.state = state;
+ const resolution$ = this.layer.map.viewController.resolution$;
+ this.resolution$$ = resolution$.subscribe(() => {
this.onResolutionChange();
});
+ this.tooltipText = this.computeTooltip();
+
+ this.network$$ = this.networkService
+ .currentState()
+ .subscribe((state: ConnectionState) => {
+ this.state = state;
+ this.onResolutionChange();
+ });
+
+ this.layers$$ = this.layers$.subscribe(() => {
+ if (this.layer && this.layer.options.active) {
+ this.layerTool$.next(true);
+ this.renderer.addClass(this.elRef.nativeElement, this.focusedCls);
+ }
+ });
- this.layers$$ = this.layers$.subscribe(() => {
- if (this.layer && this.layer.options.active) {
- this.layerTool$.next(true);
- this.renderer.addClass(this.elRef.nativeElement, this.focusedCls);
+ if (this.changeDetection) {
+ this.changeDetection.subscribe(() => this.cdRef.detectChanges());
}
- });
-
- if (this.changeDetection) {
- this.changeDetection.subscribe(() => this.cdRef.detectChanges());
}
}
ngOnDestroy() {
- this.resolution$$.unsubscribe();
- this.network$$.unsubscribe();
- this.layers$$.unsubscribe();
+ this.resolution$$?.unsubscribe();
+ this.network$$?.unsubscribe();
+ this.layers$$?.unsubscribe();
}
toggleLegend(collapsed: boolean) {
@@ -282,4 +303,8 @@ export class LayerItemComponent implements OnInit, OnDestroy {
this.layerCheck = !this.layerCheck;
this.checkbox.emit({ layer: this.layer, check: this.layerCheck });
}
+
+ deleteUnavailableLayer(anyLayerOptions: AnyLayerOptions) {
+ this.action.emit(anyLayerOptions);
+ }
}
diff --git a/packages/geo/src/lib/layer/layer-item/layer-item.theme.scss b/packages/geo/src/lib/layer/layer-item/layer-item.theme.scss
index 4720fd220..a91bd6e05 100644
--- a/packages/geo/src/lib/layer/layer-item/layer-item.theme.scss
+++ b/packages/geo/src/lib/layer/layer-item/layer-item.theme.scss
@@ -9,6 +9,7 @@
$foreground: map.get($theme, foreground);
$primary: map.get($theme, primary);
$accent: map.get($theme, accent);
+ $background: map.get($theme, background);
igo-layer-item {
&.igo-layer-item-focused > mat-list-item {
@@ -17,7 +18,7 @@
}
button {
- &:not(.mat-primary) {
+ &.mat-default {
mat-icon {
color: mat.m2-get-color-from-palette($foreground, base);
}
@@ -29,5 +30,12 @@
}
}
}
+
+ .unavailable-layer {
+ background-color: mat.get-color-from-palette(
+ $background,
+ disabled-list-option
+ );
+ }
}
}
diff --git a/packages/geo/src/lib/layer/layer-list/layer-list.component.html b/packages/geo/src/lib/layer/layer-list/layer-list.component.html
index 24c7dec43..057210734 100644
--- a/packages/geo/src/lib/layer/layer-list/layer-list.component.html
+++ b/packages/geo/src/lib/layer/layer-list/layer-list.component.html
@@ -28,6 +28,15 @@
+
+
+
+
+
(undefined);
private selectAllCheck$$: Subscription;
- constructor(private elRef: ElementRef) {}
+ constructor(
+ private elRef: ElementRef,
+ private layerService: LayerService
+ ) {}
/**
* Subscribe to the search term stream and trigger researches
@@ -998,4 +1007,8 @@ export class LayerListComponent implements OnInit, OnDestroy {
}
return layersList;
}
+
+ deleteUnavailableLayer(anyLayerOptions: AnyLayerOptions) {
+ this.layerService.deleteUnavailableLayers(anyLayerOptions);
+ }
}
diff --git a/packages/geo/src/lib/layer/shared/layer.service.ts b/packages/geo/src/lib/layer/shared/layer.service.ts
index 59d7fbce8..a0d8c01d2 100644
--- a/packages/geo/src/lib/layer/shared/layer.service.ts
+++ b/packages/geo/src/lib/layer/shared/layer.service.ts
@@ -16,7 +16,10 @@ import { catchError, concatMap, map } from 'rxjs/operators';
import { DataSourceService } from '../../datasource/shared/datasource.service';
import {
+ AnyDataSourceOptions,
+ AnyDataSourceOptionsWithParams,
ArcGISRestDataSource,
+ ArcGISRestDataSourceOptions,
CartoDataSource,
ClusterDataSource,
FeatureDataSource,
@@ -28,6 +31,7 @@ import {
WFSDataSource,
WMSDataSource,
WMTSDataSource,
+ WMTSDataSourceOptions,
WebSocketDataSource,
XYZDataSource
} from '../../datasource/shared/datasources';
@@ -53,6 +57,8 @@ import {
providedIn: 'root'
})
export class LayerService {
+ public unavailableLayers: AnyLayerOptions[] = [];
+
constructor(
private http: HttpClient,
private styleService: StyleService,
@@ -127,6 +133,13 @@ export class LayerService {
.pipe(
map((source) => {
if (source === undefined) {
+ const found = this.unavailableLayers.some(
+ (el) => el === layerOptions
+ );
+ if (!found) {
+ this.unavailableLayers.push(layerOptions);
+ }
+
return undefined;
}
return this.createLayer(Object.assign(layerOptions, { source }));
@@ -407,4 +420,38 @@ export class LayerService {
})
);
}
+
+ deleteUnavailableLayers(anyLayerOptions: AnyLayerOptions) {
+ const anyLayerSourceOptions = anyLayerOptions.sourceOptions;
+ const index = this.unavailableLayers.findIndex((item) => {
+ const baseSourceOptions = item.sourceOptions;
+ if (
+ this.sourceOptionsWithParams(baseSourceOptions) &&
+ this.sourceOptionsWithParams(anyLayerSourceOptions)
+ ) {
+ return (
+ baseSourceOptions.params.LAYERS ===
+ anyLayerSourceOptions.params.LAYERS
+ );
+ } else if (
+ this.sourceOptionsWithLayer(baseSourceOptions) &&
+ this.sourceOptionsWithLayer(anyLayerSourceOptions)
+ ) {
+ return baseSourceOptions.layer === anyLayerSourceOptions.layer;
+ }
+ });
+ this.unavailableLayers.splice(index, index >= 0 ? 1 : 0);
+ }
+
+ sourceOptionsWithParams(
+ sourceOptions: AnyDataSourceOptions
+ ): sourceOptions is AnyDataSourceOptionsWithParams {
+ return 'params' in sourceOptions;
+ }
+
+ sourceOptionsWithLayer(
+ sourceOptions: AnyDataSourceOptions
+ ): sourceOptions is ArcGISRestDataSourceOptions | WMTSDataSourceOptions {
+ return 'layer' in sourceOptions;
+ }
}
diff --git a/packages/geo/src/locale/en.geo.json b/packages/geo/src/locale/en.geo.json
index 49e8b3338..b1b7cec02 100644
--- a/packages/geo/src/locale/en.geo.json
+++ b/packages/geo/src/locale/en.geo.json
@@ -223,6 +223,7 @@
"lowerLayer": "Bring layer backward",
"hideSelectedLayers": "Hide selected layers",
"notInResolution": "Layer isn't visible at the active scale. Zoom in or out to display.",
+ "unavailableLayer": "Unavailable layer",
"filterLowerLayer": "The backward movement is always done according to the order of the map!",
"filterPlaceholder": "Filter the layers list",
"activateSelectionMode": "Activate multiple selection mode",
@@ -239,6 +240,7 @@
"removeLayer": "Remove this layer from the map",
"removeSelectedLayers": "Remove selected layers from the map",
"removeSelectedLayersRestriction": "Some selected layers cannot be removed",
+ "deleteLayer": "Delete layer",
"showFeaturesList": "Show features list",
"showLayer": "Show Layer",
"showSelectedLayers": "Show selected layers",
diff --git a/packages/geo/src/locale/fr.geo.json b/packages/geo/src/locale/fr.geo.json
index 0a9922da1..23c92f1a7 100644
--- a/packages/geo/src/locale/fr.geo.json
+++ b/packages/geo/src/locale/fr.geo.json
@@ -222,6 +222,7 @@
"hideLayer": "Masquer la couche",
"hideSelectedLayers": "Masquer les couches sélectionnées",
"notInResolution": "La couche n'est pas visible à l'échelle active. Veuillez zoomer ou dézoomer pour la visualiser.",
+ "unavailableLayer": "Couche non disponible",
"lowerLayer": "Mettre en arrière",
"filterLowerLayer": "Le déplacement arrière se fait toujours selon l'ordre de la carte!",
"filterPlaceholder": "Filtrer la liste de couches",
@@ -239,6 +240,7 @@
"removeLayer": "Retirer la couche de la carte",
"removeSelectedLayers": "Retirer les couches sélectionnées de la carte",
"removeSelectedLayersRestriction": "Certaines couches sélectionnées ne peuvent être supprimées",
+ "deleteLayer": "Supprimer la couche",
"showFeaturesList": "Afficher la liste des entités",
"showLayer": "Afficher la couche",
"showSelectedLayers": "Afficher les couches sélectionnées",