From 857478576cf21894420d019ec196d05f8a1546a1 Mon Sep 17 00:00:00 2001 From: Matthias Mohr Date: Tue, 14 Nov 2023 18:05:29 +0100 Subject: [PATCH] WMS support for web-map-links extension + Metadata for links (#382) * Implement WMS support for web-map-links extension * Metadata rendering for links, e.g. for WMS --- package.json | 2 +- src/components/Link.vue | 68 ++++++++++++++++++++++++++++--- src/components/Map.vue | 81 ++++++++++++++++++++++++++----------- src/components/Metadata.vue | 14 ++++++- src/components/Provider.vue | 4 +- src/locales/de/fields.json | 10 ++--- src/locales/en/fields.json | 15 ++++--- src/locales/es/fields.json | 9 ++--- src/locales/fr/fields.json | 7 ++-- src/locales/it/fields.json | 7 ++-- src/locales/ro/fields.json | 7 ++-- src/views/Catalog.vue | 2 +- 12 files changed, 165 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index 34fdc1a9..e95aa874 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "dependencies": { "@apidevtools/json-schema-ref-parser": "^10.1.0", "@musement/iso-duration": "^1.0.0", - "@radiantearth/stac-fields": "1.3.0", + "@radiantearth/stac-fields": "1.3.2", "@radiantearth/stac-migrate": "~1.6.0", "axios": "^1.2.0", "bootstrap-vue": "^2.21.2", diff --git a/src/components/Link.vue b/src/components/Link.vue index ca360946..5ccfcf31 100644 --- a/src/components/Link.vue +++ b/src/components/Link.vue @@ -1,9 +1,13 @@ @@ -20,7 +24,9 @@ export default { components: { BPopover, HrefActions, - StacLink + StacLink, + Description: () => import('./Description.vue'), + Metadata: () => import('./Metadata.vue') }, props: { link: { @@ -32,6 +38,11 @@ export default { required: true } }, + data() { + return { + ignore: ['href', 'type', 'rel', 'title', 'description'] + }; + }, computed: { popoverId() { return "popover-link-" + linkId; @@ -42,3 +53,50 @@ export default { } }; + + diff --git a/src/components/Map.vue b/src/components/Map.vue index 5d522d21..8e224646 100644 --- a/src/components/Map.vue +++ b/src/components/Map.vue @@ -8,10 +8,8 @@ v-for="basemap of basemaps" :is="basemap.is" :key="basemap.key" ref="basemaps" layerType="base" v-bind="basemap" /> - + + Utils.isObject(map)); }, showLayerControl() { - return this.xyzLinks.length > 0 || this.basemaps.length > 1; + return this.xyzLinks.length > 0 || this.wmsLinks.length > 0 || this.basemaps.length > 1; }, xyzLinks() { - if (!(this.stac instanceof STAC)) { - return []; - } - let links = this.stac.getLinksWithRels('xyz'); - if (links.length === 0) { - return []; + const links = this.getWebMapLinks('xyz'); + return links.map(link => ({ + url: link.href, + name: link.title || Utils.titleForHref(link.href), + subdomains: link.servers, + attribution: link.attribution || this.stac.getMetadata('attribution') + })); + }, + wmsLinks() { + const links = this.getWebMapLinks('wms'); + const wmsLinks = []; + for(const link of links) { + if (!Array.isArray(link['wms:layers'])) { + continue; + } + for(const i in link['wms:layers']) { + const layers = link['wms:layers'][i]; + let styles; + if (Array.isArray(link['wms:styles']) && typeof link['wms:styles'][i] === 'string') { + styles = link['wms:styles'][i]; + } + const name = [link.title, layers].filter(x => Boolean(x)).join(' - '); + const props = { + baseUrl: link.href, + name, + attribution: link.attribution || this.stac.getMetadata('attribution'), + version: '1.3.0', + layers, + transparent: String(link['wms:transparent'] || false), + styles + }; + if (typeof link['type'] === 'string' && link['type'].startsWith('image/')) { + props.format = link['type']; + } + if (Utils.isObject(link['wms:dimensions'])) { + props.options = link['wms:dimensions']; + } + wmsLinks.push(props); + } } - return links.map(link => { - return { - url: link.href, - name: link.title, - subdomains: link.servers, - options: {} - }; - }); + return wmsLinks; } }, watch: { @@ -210,12 +234,23 @@ export default { this.addBoundsSelector(); } }, + getWebMapLinks(rel) { + if (!(this.stac instanceof STAC)) { + return []; + } + let links = this.stac.getLinksWithRels(rel); + if (links.length === 0) { + return []; + } + return links; + }, updateLayerControl() { if (this.showLayerControl) { - let basemaps = Array.isArray(this.$refs.basemaps) ? this.$refs.basemaps : []; - basemaps.forEach(layer => this.$refs.layerControl.addLayer(layer)); - let overlays = Array.isArray(this.$refs.overlays) ? this.$refs.overlays : []; - overlays.forEach(layer => this.$refs.layerControl.addLayer(layer)); + const basemaps = Array.isArray(this.$refs.basemaps) ? this.$refs.basemaps : []; + const xyzOverlays = Array.isArray(this.$refs.xyzOverlays) ? this.$refs.xyzOverlays : []; + const wmsOverlays = Array.isArray(this.$refs.wmsOverlays) ? this.$refs.wmsOverlays : []; + const layers = basemaps.concat(xyzOverlays).concat(wmsOverlays); + layers.forEach(layer => this.$refs.layerControl.addLayer(layer)); } }, viewChanged(event) { diff --git a/src/components/Metadata.vue b/src/components/Metadata.vue index ca9fb325..42f1a386 100644 --- a/src/components/Metadata.vue +++ b/src/components/Metadata.vue @@ -1,6 +1,6 @@