import { Injectable } from '@angular/core' ; import { Layer } from 'ol/layer' ; import { Source } from 'ol/source' ; import { WMSCapabilities , WMTSCapabilities } from 'ol/format' ; import { Attribution , MetadataUrl , getAttribution , getCachedCapabilities , getLegends , getMaxResolutionDenominator , getMetadata , getSubLayers , setAttribution , setCacheCapabilities , setLegends , setMetadata , } from '../../common/layer-extensions' ; import { HsDimensionTimeService } from '../../common/get-capabilities/dimension-time.service' ; import { HsLayerDescriptor } from './layer-descriptor.interface' ; import { HsLayerUtilsService } from '../utils/layer-utils.service' ; import { HsLogService } from '../../common/log/log.service' ; import { HsWfsGetCapabilitiesService } from '../../common/get-capabilities/wfs-get-capabilities.service' ; import { HsWmsGetCapabilitiesService } from '../../common/get-capabilities/wms-get-capabilities.service' ; import { HsWmtsGetCapabilitiesService } from '../../common/get-capabilities/wmts-get-capabilities.service' ; import { WMSGetCapabilitiesResponse , WmsLayer , } from '../../common/get-capabilities/wms-get-capabilities-response.interface' ; @ Injectable ( { providedIn : 'root' , } ) export class HsLayerManagerMetadataService { constructor ( public HsWmtsGetCapabilitiesService , public HsWfsGetCapabilitiesService , public HsWmsGetCapabilitiesService , public HsDimensionTimeService , public HsLayerUtilsService , public hsLog ) { } param layerName param currentLayer returns identifyLayerObject ( layerName , currentLayer ) { if ( layerName == currentLayer . Name ) { return currentLayer ; } else if ( Array . isArray ( currentLayer . Layer ) ) { for ( const subLayer of currentLayer . Layer ) { const found = this . identifyLayerObject ( layerName , subLayer ) ; if ( found ) { return found ; } } } else if ( currentLayer . Layer ) { return this . identifyLayerObject ( layerName , currentLayer . Layer ) ; } return null ; } param layerDescriptor async fillMetadata ( layerDescriptor ) { const layer = layerDescriptor . layer ; await this . queryMetadata ( layerDescriptor ) ; const subLayers = getCachedCapabilities ( layer ) ?. Layer ; if ( subLayers != undefined && subLayers . length > 0 ) { if ( ! layerDescriptor . hasSublayers ) { layerDescriptor . hasSublayers = true ; } } } metadataArray ( layer ) { return getMetadata ( layer . layer ) ?. urls ; } param layer hasMetadata ( layer ) { if ( ! layer ) { return false ; } else { return layer && getMetadata ( layer . layer ) ?. urls ? true : false ; } } param properties returns { any } description searchForScaleDenominator ( properties ) { let maxScale = properties . MaxScaleDenominator ? this . HsLayerUtilsService . calculateResolutionFromScale ( properties . MaxScaleDenominator ) : null ; const layers = properties . Layer ; if ( layers ) { for ( const sublayer of layers ) { if ( sublayer . Layer ) { const subScale = this . searchForScaleDenominator ( sublayer ) ; maxScale = subScale > maxScale ? subScale : maxScale ; } else { if ( sublayer . MaxScaleDenominator ) { sublayer . maxResolution = this . HsLayerUtilsService . calculateResolutionFromScale ( sublayer . MaxScaleDenominator ) ; if ( maxScale < sublayer . MaxScaleDenominator ) { maxScale = this . HsLayerUtilsService . calculateResolutionFromScale ( sublayer . MaxScaleDenominator ) ; } } else if ( ! sublayer . maxResolution ) { sublayer . maxResolution = maxScale ; } } } } if ( maxScale ) { properties . maxResolution = maxScale ; } return maxScale ; } param layer param key param values setOrUpdate ( layer , key , values ) { const previousValue = layer . get ( key ) ; if ( previousValue ) { for ( const value of values ) { layer . set ( key , previousValue . push ( value ) ) ; } } else { layer . set ( key , values ) ; } } parseLayerInfo ( layerDescriptor , layerName , caps ) { const olLayer = layerDescriptor . layer ; const legends = [ ] ; const layerCaps = caps . Capability . Layer ; let layerObj ; if ( layerName . includes ( ',' ) ) { const layerObjs = [ ] ; for ( const subLayer of layerName . split ( ',' ) ) { const layerSubObject = this . identifyLayerObject ( subLayer , layerCaps ) ; layerObjs . push ( layerSubObject ) ; this . collectLegend ( layerSubObject , legends ) ; if ( layerSubObject && layerSubObject . Layer !== undefined && getSubLayers ( olLayer ) ) { delete layerSubObject . Layer ; } } if ( getCachedCapabilities ( olLayer ) === undefined ) { layerObj = Object . assign ( JSON . parse ( JSON . stringify ( layerObjs [ 0 ] ) ) , { maxResolution : Math . max ( ... layerObjs . map ( ( layer ) => this . searchForScaleDenominator ( layer ) ) ) , Layer : layerObjs , } ) ; } this . fillMetadataUrlsIfNotExist ( olLayer , caps ) ; } else { layerObj = this . identifyLayerObject ( layerName , layerCaps ) ; if ( layerObj == undefined ) { return ; } olLayer . setProperties ( layerObj ) ; if ( layerObj . Dimension ?. name === 'time' || layerObj . Dimension ?. filter ( ( dim ) => dim . name === 'time' ) . length > 0 ) { this . HsDimensionTimeService . setupTimeLayer ( layerDescriptor , layerObj ) ; } if ( layerObj . Layer && getSubLayers ( olLayer ) ) { layerObj . maxResolution = this . searchForScaleDenominator ( layerObj ) ; delete layerObj . Layer ; } this . collectLegend ( layerObj , legends ) ; } if ( getCachedCapabilities ( olLayer ) == undefined ) { setCacheCapabilities ( olLayer , layerObj ) ; } this . parseAttribution ( olLayer , getCachedCapabilities ( olLayer ) ) ; const existingLegends = getLegends ( olLayer ) ; if ( legends . length > 0 && existingLegends == undefined ) { setLegends ( olLayer , legends ) ; } } private collectLegend ( layerObject , legends ) { const styleWithLegend = layerObject . Style ?. find ( ( style ) => style . LegendURL !== undefined ) ; if ( styleWithLegend ) { legends . push ( styleWithLegend . LegendURL [ 0 ] . OnlineResource ) ; } } parseAttribution ( layer , caps ) { const attr = caps . Attribution ; if ( getAttribution ( layer ) ?. locked || attr == undefined ) { return ; } const parsedAttribution = { title : attr . Title , onlineResource : attr . OnlineResource , logoUrl : attr . LogoURL ? { format : attr . LogoURL . Format , onlineResource : attr . LogoURL . OnlineResource , } : undefined , } ; setAttribution ( layer , parsedAttribution ) ; } param layerDescriptor returns async queryMetadata ( layerDescriptor ) { const layer = layerDescriptor . layer ; const capabilities = '' ; const url = this . HsLayerUtilsService . getURL ( layer ) ; if ( ! url ) { return ; } if ( this . HsLayerUtilsService . isLayerWMS ( layer ) ) { const wrapper = await this . HsWmsGetCapabilitiesService . request ( url ) ; if ( wrapper . error ) { this . hsLog . warn ( 'GetCapabilities call invalid' , wrapper . response ) ; } const parser = new WMSCapabilities ( ) ; const caps = parser . read ( wrapper . response ) ; const params = this . HsLayerUtilsService . getLayerParams ( layer ) ; const layerNameInParams = params . LAYERS ; this . parseLayerInfo ( layerDescriptor , layerNameInParams , caps ) ; if ( getSubLayers ( layer ) ) { params . LAYERS = params . LAYERS . concat ( ',' , getSubLayers ( layer ) ) ; this . HsLayerUtilsService . updateLayerParams ( layer , params ) ; } this . fillMetadataUrlsIfNotExist ( layer , caps ) ; setTimeout ( ( ) => { if ( getMaxResolutionDenominator ( layer ) ) { layer . set ( 'maxResolution' , getMaxResolutionDenominator ( layer ) ) ; return ; } const maxScale = this . searchForScaleDenominator ( layer . getProperties ( ) ) ; if ( maxScale ) { layer . set ( 'maxResolution' , maxScale ) ; } } ) ; return true ; } else if ( this . HsLayerUtilsService . isLayerWMTS ( layer ) ) { const wrapper = await this . HsWmtsGetCapabilitiesService . request ( url ) ; if ( wrapper . error ) { return wrapper . response ; } else { const parser = new WMTSCapabilities ( ) ; const caps = parser . read ( wrapper . response ) ; layer . setProperties ( caps ) ; if ( ! getAttribution ( layer ) ?. locked ) { setAttribution ( layer , { onlineResource : caps . ServiceProvider . ProviderSite , } ) ; } return true ; } } else if ( this . HsLayerUtilsService . isLayerVectorLayer ( layer ) ) { if ( url ) { const wrapper = await this . HsWfsGetCapabilitiesService . request ( url ) ; if ( wrapper . error ) { return wrapper . response ; } else { const parser = new DOMParser ( ) ; const caps = parser . parseFromString ( wrapper . response . data , 'application/xml' ) ; const el = caps . getElementsByTagNameNS ( '*' , 'ProviderSite' ) ; if ( ! getAttribution ( layer ) ?. locked ) { setAttribution ( layer , { onlineResource : el [ 0 ] . getAttribute ( 'xlink:href' ) , } ) ; } return true ; } } } } private fillMetadataUrlsIfNotExist ( layer , caps ) { if ( getMetadata ( layer ) == undefined ) { setMetadata ( layer , { urls : [ { onlineResource : caps . Service . OnlineResource } ] , } ) ; } } }