From 4e99bf55febf305e41a49813fc3717f71dda67f5 Mon Sep 17 00:00:00 2001 From: Olivia Date: Thu, 4 Jan 2024 20:55:50 +0100 Subject: [PATCH] Handle LatLon bbox elements for WMS, also make bbox inherited across layers --- fixtures/wms/capabilities-brgm-1-1-1.xml | 6 ++- fixtures/wms/capabilities-brgm-1-3-0.xml | 6 ++- src/wms/capabilities.spec.ts | 38 +++++++++++++++++- src/wms/capabilities.ts | 50 +++++++++++++++++++----- src/wms/endpoint.spec.ts | 13 +++++- src/wms/endpoint.ts | 4 +- 6 files changed, 99 insertions(+), 18 deletions(-) diff --git a/fixtures/wms/capabilities-brgm-1-1-1.xml b/fixtures/wms/capabilities-brgm-1-1-1.xml index 6f1c50a..7e9c65c 100644 --- a/fixtures/wms/capabilities-brgm-1-1-1.xml +++ b/fixtures/wms/capabilities-brgm-1-1-1.xml @@ -194,8 +194,6 @@ EPSG:32620 EPSG:32621 - + + INHERIT_BBOX + Inherited bounding boxes + diff --git a/fixtures/wms/capabilities-brgm-1-3-0.xml b/fixtures/wms/capabilities-brgm-1-3-0.xml index 3c9b0b7..97ca70d 100644 --- a/fixtures/wms/capabilities-brgm-1-3-0.xml +++ b/fixtures/wms/capabilities-brgm-1-3-0.xml @@ -205,8 +205,6 @@ 41.1701 51.1419 - 9000 251000 + + INHERIT_BBOX + Inherited bounding boxes + diff --git a/src/wms/capabilities.spec.ts b/src/wms/capabilities.spec.ts index 3005b1a..d4e96a7 100644 --- a/src/wms/capabilities.spec.ts +++ b/src/wms/capabilities.spec.ts @@ -69,7 +69,13 @@ describe('WMS capabilities', () => { abstract: 'Cartes géologiques', attribution, availableCrs, - boundingBoxes: {}, + boundingBoxes: { + 'CRS:84': ['-180', '-90', '180', '90'], + 'EPSG:2154': ['-1e+15', '-1e+15', '1e+15', '1e+15'], + 'EPSG:3857': ['-1e+15', '-1e+15', '1e+15', '1e+15'], + 'EPSG:4171': ['-180', '-90', '180', '90'], + 'EPSG:4326': ['-180', '-90', '180', '90'], + }, name: 'GEOLOGIE', styles, title: 'Cartes géologiques', @@ -202,6 +208,36 @@ describe('WMS capabilities', () => { styles, title: 'Carte géologique image de la France au 1/50 000e', }, + { + abstract: '', + attribution: { + logoUrl: 'http://mapsref.brgm.fr/legendes/brgm_logo.png', + title: 'Brgm', + url: 'http://www.brgm.fr/', + }, + availableCrs: [ + 'EPSG:4326', + 'CRS:84', + 'EPSG:3857', + 'EPSG:4171', + 'EPSG:2154', + ], + boundingBoxes: { + 'CRS:84': ['-180', '-90', '180', '90'], + 'EPSG:2154': ['-1e+15', '-1e+15', '1e+15', '1e+15'], + 'EPSG:3857': ['-1e+15', '-1e+15', '1e+15', '1e+15'], + 'EPSG:4171': ['-180', '-90', '180', '90'], + 'EPSG:4326': ['-180', '-90', '180', '90'], + }, + name: 'INHERIT_BBOX', + styles: [ + { + name: 'default', + title: 'default', + }, + ], + title: 'Inherited bounding boxes', + }, ], }, ], diff --git a/src/wms/capabilities.ts b/src/wms/capabilities.ts index a4a6103..840da70 100644 --- a/src/wms/capabilities.ts +++ b/src/wms/capabilities.ts @@ -13,7 +13,7 @@ import { WmsLayerFull, WmsVersion, } from './endpoint'; -import { CrsCode, GenericEndpointInfo } from '../shared/models'; +import { BoundingBox, CrsCode, GenericEndpointInfo } from '../shared/models'; /** * Will read a WMS version from the capabilities doc @@ -74,7 +74,8 @@ function parseLayer( version: WmsVersion, inheritedSrs: CrsCode[] = [], inheritedStyles: LayerStyle[] = [], - inheritedAttribution: LayerAttribution = null + inheritedAttribution: LayerAttribution = null, + inheritedBoundingBoxes: Record = null ): WmsLayerFull { const srsTag = version === '1.3.0' ? 'CRS' : 'SRS'; const srsList = findChildrenElement(layerEl, srsTag).map(getElementText); @@ -91,13 +92,48 @@ function parseLayer( : ['minx', 'miny', 'maxx', 'maxy']; return attrs.map((name) => getElementAttribute(bboxEl, name)); } + function parseExGeographicBoundingBox(bboxEl) { + return [ + 'westBoundLongitude', + 'southBoundLatitude', + 'eastBoundLongitude', + 'northBoundLatitude', + ].map((name) => getElementText(findChildElement(bboxEl, name))); + } + function parseLatLonBoundingBox(bboxEl) { + return ['minx', 'miny', 'maxx', 'maxy'].map((name) => + getElementAttribute(bboxEl, name) + ); + } const attributionEl = findChildElement(layerEl, 'Attribution'); const attribution = attributionEl !== null ? parseLayerAttribution(attributionEl) : inheritedAttribution; + const latLonBboxEl = + version === '1.3.0' + ? findChildElement(layerEl, 'EX_GeographicBoundingBox') + : findChildElement(layerEl, 'LatLonBoundingBox'); + const baseBoundingBox = {}; + if (latLonBboxEl) { + baseBoundingBox['EPSG:4326'] = + version === '1.3.0' + ? parseExGeographicBoundingBox(latLonBboxEl) + : parseLatLonBoundingBox(latLonBboxEl); + } + let boundingBoxes = findChildrenElement(layerEl, 'BoundingBox').reduce( + (prev, bboxEl) => ({ + ...prev, + [getElementAttribute(bboxEl, srsTag)]: parseBBox(bboxEl), + }), + baseBoundingBox + ); + boundingBoxes = + Object.keys(boundingBoxes).length > 0 || inheritedBoundingBoxes === null + ? boundingBoxes + : inheritedBoundingBoxes; const children = findChildrenElement(layerEl, 'Layer').map((layer) => - parseLayer(layer, version, availableCrs, styles, attribution) + parseLayer(layer, version, availableCrs, styles, attribution, boundingBoxes) ); return { name: getElementText(findChildElement(layerEl, 'Name')), @@ -106,13 +142,7 @@ function parseLayer( availableCrs, styles, attribution, - boundingBoxes: findChildrenElement(layerEl, 'BoundingBox').reduce( - (prev, bboxEl) => ({ - ...prev, - [getElementAttribute(bboxEl, srsTag)]: parseBBox(bboxEl), - }), - {} - ), + boundingBoxes, ...(children.length && { children }), }; } diff --git a/src/wms/endpoint.spec.ts b/src/wms/endpoint.spec.ts index 9fb6a9f..008556d 100644 --- a/src/wms/endpoint.spec.ts +++ b/src/wms/endpoint.spec.ts @@ -88,6 +88,11 @@ describe('WmsEndpoint', () => { name: 'SCAN_D_GEOL50', title: 'Carte géologique image de la France au 1/50 000e', }, + { + abstract: '', + name: 'INHERIT_BBOX', + title: 'Inherited bounding boxes', + }, ], name: 'GEOLOGIE', title: 'Cartes géologiques', @@ -117,7 +122,13 @@ describe('WmsEndpoint', () => { 'EPSG:4171', 'EPSG:2154', ], - boundingBoxes: {}, + boundingBoxes: { + 'CRS:84': ['-180', '-90', '180', '90'], + 'EPSG:2154': ['-1e+15', '-1e+15', '1e+15', '1e+15'], + 'EPSG:3857': ['-1e+15', '-1e+15', '1e+15', '1e+15'], + 'EPSG:4171': ['-180', '-90', '180', '90'], + 'EPSG:4326': ['-180', '-90', '180', '90'], + }, name: 'GEOLOGIE', styles: [ { diff --git a/src/wms/endpoint.ts b/src/wms/endpoint.ts index 2e913cd..a730715 100644 --- a/src/wms/endpoint.ts +++ b/src/wms/endpoint.ts @@ -2,7 +2,7 @@ import { EndpointError } from '../shared/errors'; import { parseWmsCapabilities } from '../worker'; import { useCache } from '../shared/cache'; import { setQueryParams } from '../shared/http-utils'; -import { CrsCode, GenericEndpointInfo } from '../shared/models'; +import { BoundingBox, CrsCode, GenericEndpointInfo } from '../shared/models'; export type LayerStyle = { name: string; @@ -44,7 +44,7 @@ export type WmsLayerFull = { /** * Dict of bounding boxes where keys are CRS codes */ - boundingBoxes: any; + boundingBoxes: Record; attribution?: LayerAttribution; /** * Not defined if the layer is a leaf in the tree