diff --git a/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.html b/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.html index 79deb7dfc3..416bb8288e 100644 --- a/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.html +++ b/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.html @@ -16,9 +16,15 @@ -
+
-

+

{{ layer.name }}

diff --git a/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.ts b/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.ts index 681ff2d19a..4d98514fac 100644 --- a/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.ts +++ b/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.ts @@ -1,11 +1,22 @@ -import { Component, OnInit, Output, EventEmitter, ChangeDetectionStrategy, Input, ChangeDetectorRef } from '@angular/core'; -import { OgcApiEndpoint } from '@camptocamp/ogc-client'; -import { Subject, debounceTime } from 'rxjs'; -import { MapContextLayerModel, MapContextLayerTypeEnum } from '../map-context/map-context.model'; -import { TranslateModule } from '@ngx-translate/core'; -import { DropdownChoice, UiInputsModule } from '@geonetwork-ui/ui/inputs'; -import { CommonModule } from '@angular/common'; -import { MapLayer } from '../+state/map.models'; +import { + Component, + OnInit, + Output, + EventEmitter, + ChangeDetectionStrategy, + Input, + ChangeDetectorRef, +} from '@angular/core' +import { OgcApiEndpoint } from '@camptocamp/ogc-client' +import { Subject, debounceTime } from 'rxjs' +import { + MapContextLayerModel, + MapContextLayerTypeEnum, +} from '../map-context/map-context.model' +import { TranslateModule } from '@ngx-translate/core' +import { DropdownChoice, UiInputsModule } from '@geonetwork-ui/ui/inputs' +import { CommonModule } from '@angular/common' +import { MapLayer } from '../+state/map.models' @Component({ selector: 'gn-ui-add-layer-from-ogc-api', @@ -15,92 +26,100 @@ import { MapLayer } from '../+state/map.models'; imports: [CommonModule, TranslateModule, UiInputsModule], }) export class AddLayerFromOgcApiComponent implements OnInit { - @Input() ogcUrl: string; - @Output() layerAdded = new EventEmitter(); + @Input() ogcUrl: string + @Output() layerAdded = new EventEmitter() - urlChange = new Subject(); - loading = false; - layers: any[] = []; - errorMessage: string | null = null; - selectedLayerTypes: { [key: string]: DropdownChoice['value'] } = {}; + urlChange = new Subject() + loading = false + layers: any[] = [] + errorMessage: string | null = null + selectedLayerTypes: { [key: string]: DropdownChoice['value'] } = {} constructor(private changeDetectorRef: ChangeDetectorRef) {} ngOnInit() { this.urlChange.pipe(debounceTime(700)).subscribe(() => { - this.loadLayers(); - }); + this.loadLayers() + }) } async loadLayers() { - this.errorMessage = null; + this.errorMessage = null try { - this.loading = true; + this.loading = true if (!this.ogcUrl.trim()) { - this.layers = []; - return; + this.layers = [] + return } - const ogcEndpoint = await new OgcApiEndpoint(this.ogcUrl); - this.layers = await ogcEndpoint.allCollections; - this.setDefaultLayerTypes(); + const ogcEndpoint = await new OgcApiEndpoint(this.ogcUrl) + this.layers = await ogcEndpoint.allCollections + this.setDefaultLayerTypes() } catch (error) { - const err = error as Error; - this.layers = []; - this.errorMessage = 'Error loading layers: ' + err.message; + const err = error as Error + this.layers = [] + this.errorMessage = 'Error loading layers: ' + err.message } finally { - this.loading = false; - this.changeDetectorRef.markForCheck(); + this.loading = false + this.changeDetectorRef.markForCheck() } } setDefaultLayerTypes() { this.layers.forEach((layer) => { - const choices = this.getLayerChoices(layer); + const choices = this.getLayerChoices(layer) if (choices.length > 0) { - this.selectedLayerTypes[layer.name] = choices[0].value; + this.selectedLayerTypes[layer.name] = choices[0].value } - }); + }) } getLayerChoices(layer: any) { - const choices = []; + const choices = [] if (layer.hasRecords) { - choices.push({ label: 'Records', value: 'record' }); + choices.push({ label: 'Records', value: 'record' }) } if (layer.hasFeatures) { - choices.push({ label: 'Features', value: 'features' }); + choices.push({ label: 'Features', value: 'features' }) } if (layer.hasVectorTiles) { - choices.push({ label: 'Vector Tiles', value: 'vectorTiles' }); + choices.push({ label: 'Vector Tiles', value: 'vectorTiles' }) } if (layer.hasMapTiles) { - choices.push({ label: 'Map Tiles', value: 'mapTiles' }); + choices.push({ label: 'Map Tiles', value: 'mapTiles' }) } - return choices; + return choices } shouldDisplayLayer(layer: any) { - return layer.hasRecords || layer.hasFeatures || layer.hasVectorTiles || layer.hasMapTiles; + return ( + layer.hasRecords || + layer.hasFeatures || + layer.hasVectorTiles || + layer.hasMapTiles + ) } onLayerTypeSelect(layerName: string, selectedType: any) { - this.selectedLayerTypes[layerName] = selectedType ? selectedType : this.getLayerChoices(layerName)[0]?.value; + this.selectedLayerTypes[layerName] = selectedType + ? selectedType + : this.getLayerChoices(layerName)[0]?.value } async addLayer(layer: string, layerType: any) { try { console.log(layerType) - const ogcEndpoint = await new OgcApiEndpoint(this.ogcUrl); - const layerUrl = await ogcEndpoint.getCollectionItemsUrl(layer); + const ogcEndpoint = await new OgcApiEndpoint(this.ogcUrl) + const layerUrl = await ogcEndpoint.getCollectionItemsUrl(layer) const layerToAdd: MapContextLayerModel = { name: layer, url: layerUrl, type: MapContextLayerTypeEnum.OGCAPI, - }; - this.layerAdded.emit({ ...layerToAdd, title: layer }); + layerType: layerType, + } + this.layerAdded.emit({ ...layerToAdd, title: layer }) } catch (error) { - const err = error as Error; - console.error('Error adding layer:', err.message); + const err = error as Error + console.error('Error adding layer:', err.message) } } } diff --git a/libs/feature/map/src/lib/map-context/map-context.model.ts b/libs/feature/map/src/lib/map-context/map-context.model.ts index 12f07631ee..5c05111e7a 100644 --- a/libs/feature/map/src/lib/map-context/map-context.model.ts +++ b/libs/feature/map/src/lib/map-context/map-context.model.ts @@ -38,6 +38,7 @@ export interface MapContextLayerOgcapiModel { type: 'ogcapi' url: string name: string + layerType: 'feature' | 'vectorTile' | 'mapTile' | 'record' } interface LayerXyzModel { diff --git a/libs/feature/map/src/lib/map-context/map-context.service.ts b/libs/feature/map/src/lib/map-context/map-context.service.ts index 5e723badbe..025d5ee86d 100644 --- a/libs/feature/map/src/lib/map-context/map-context.service.ts +++ b/libs/feature/map/src/lib/map-context/map-context.service.ts @@ -25,6 +25,10 @@ import WMTS from 'ol/source/WMTS' import { Geometry } from 'ol/geom' import Feature from 'ol/Feature' import { WfsEndpoint, WmtsEndpoint } from '@camptocamp/ogc-client' +import OGCVectorTile from 'ol/source/OGCVectorTile.js'; +import { MVT } from 'ol/format' +import VectorTileLayer from 'ol/layer/VectorTile' +import OGCMapTile from 'ol/source/OGCMapTile.js'; export const DEFAULT_BASELAYER_CONTEXT: MapContextLayerXyzModel = { type: MapContextLayerTypeEnum.XYZ, @@ -78,14 +82,28 @@ export class MapContextService { const style = this.styleService.styles.default switch (type) { case MapContextLayerTypeEnum.OGCAPI: - return new VectorLayer({ - source: new VectorSource({ - format: new GeoJSON(), - url: layerModel.url, - }), - style, - }) - + if (layerModel.layerType === 'vectorTile') { + return new VectorTileLayer({ + source: new OGCVectorTile({ + url: layerModel.url, + format: new MVT(), + }), + }) + } else if (layerModel.layerType === 'mapTile') { + return new TileLayer({ + source: new OGCMapTile({ + url: layerModel.url, + }), + }) + } else { + return new VectorLayer({ + source: new VectorSource({ + format: new GeoJSON(), + url: layerModel.url, + }), + style, + }) + } case MapContextLayerTypeEnum.XYZ: return new TileLayer({ source: new XYZ({