Skip to content

Commit

Permalink
WMS support for web-map-links extension + Metadata for links (#382)
Browse files Browse the repository at this point in the history
* Implement WMS support for web-map-links extension
* Metadata rendering for links, e.g. for WMS
  • Loading branch information
m-mohr authored Nov 14, 2023
1 parent 0332fc4 commit 8574785
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 61 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
68 changes: 63 additions & 5 deletions src/components/Link.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<template>
<li>
<li class="link">
<StacLink :id="popoverId" :data="link" :fallbackTitle="fallbackTitle" class="pr-1" />
<b-popover :target="popoverId" triggers="hover" placement="right" container="#stac-browser">
<h6 class="small text-muted text-center">{{ $t('additionalActions') }}</h6>
<HrefActions vertical :data="link" size="sm" />
<b-popover :target="popoverId" triggers="hover" placement="right" container="#stac-browser" custom-class="link-more">
<Description v-if="link.description" :description="link.description" compact />
<section class="link-actions">
<h3 class="first">{{ $t('additionalActions') }}</h3>
<HrefActions vertical :data="link" size="sm" />
</section>
<Metadata :data="link" type="Link" headerTag="h3" :ignoreFields="ignore" />
</b-popover>
</li>
</template>
Expand All @@ -20,7 +24,9 @@ export default {
components: {
BPopover,
HrefActions,
StacLink
StacLink,
Description: () => import('./Description.vue'),
Metadata: () => import('./Metadata.vue')
},
props: {
link: {
Expand All @@ -32,6 +38,11 @@ export default {
required: true
}
},
data() {
return {
ignore: ['href', 'type', 'rel', 'title', 'description']
};
},
computed: {
popoverId() {
return "popover-link-" + linkId;
Expand All @@ -42,3 +53,50 @@ export default {
}
};
</script>

<style lang="scss">
#stac-browser .link-more {
width: auto;
max-width: 600px;
.styled-description {
margin-bottom: 1rem;
}
h3 {
font-size: 0.85rem;
color: #6c757d;
text-align: center;
padding: 0;
font-weight: 600;
margin: 1rem 0 0.7rem;
&.first {
margin-top: 0;
}
}
.metadata {
min-width: 400px;
h4 {
font-size: 0.85rem;
font-weight: normal;
margin-top: 0;
margin-bottom: 0.5rem;
}
.card-columns {
column-count: 1;
}
.card {
border: 0;
margin-top: 0;
font-size: 0.8rem;
}
.card-body {
padding: 0;
}
}
}
</style>
81 changes: 58 additions & 23 deletions src/components/Map.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
v-for="basemap of basemaps" :is="basemap.is" :key="basemap.key"
ref="basemaps" layerType="base" v-bind="basemap"
/>
<l-tile-layer
v-for="xyz of xyzLinks" ref="overlays" :key="xyz.url" layerType="overlay"
:name="xyz.name" :url="xyz.url" :subdomains="xyz.subdomains" :options="xyz.options"
/>
<l-tile-layer v-for="xyz of xyzLinks" ref="overlays" :key="xyz.url" layerType="overlay" v-bind="xyz" />
<LWMSTileLayer v-for="wms of wmsLinks" ref="overlays" :key="wms.url" layerType="overlay" v-bind="wms" />
<l-geo-json v-if="geojson" ref="geojson" :geojson="geojson" :options="{onEachFeature: showPopup}" :optionsStyle="{color: secondaryColor, weight: secondaryWeight}" />
</l-map>
<b-popover
Expand Down Expand Up @@ -140,24 +138,50 @@ export default {
}).filter(map => 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: {
Expand Down Expand Up @@ -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) {
Expand Down
14 changes: 12 additions & 2 deletions src/components/Metadata.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<section v-if="formattedData.length > 0" class="metadata">
<h2 v-if="title">{{ title || $t('metadata.title') }}</h2>
<component :is="headerTag" v-if="title">{{ titleText }}</component>
<b-card-group columns :class="`count-${formattedData.length}`">
<MetadataGroup v-for="group in formattedData" v-bind="group" :key="group.extension" />
</b-card-group>
Expand Down Expand Up @@ -39,8 +39,12 @@ export default {
default: () => ([])
},
title: {
type: [Boolean, String],
default: true
},
headerTag: {
type: String,
default: null
default: 'h2'
}
},
data() {
Expand All @@ -50,6 +54,12 @@ export default {
},
computed: {
...mapState(['uiLanguage']),
titleText() {
if (typeof this.title === 'string') {
return this.title;
}
return this.$t('metadata.title');
}
},
watch: {
uiLanguage: {
Expand Down
4 changes: 2 additions & 2 deletions src/components/Provider.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<b-card-text class="mt-4" v-if="provider.description">
<Description :description="provider.description" compact />
</b-card-text>
<Metadata class="mt-4" :data="provider" :ignoreFields="ignore" title="" type="Provider" />
<Metadata class="mt-4" :data="provider" :ignoreFields="ignore" :title="false" type="Provider" />
</b-card-body>
</b-collapse>
</b-card>
Expand Down Expand Up @@ -76,4 +76,4 @@ export default {
}
}
}
</style>
</style>
10 changes: 5 additions & 5 deletions src/locales/de/fields.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
"Average spatial resolution": "Durchschnittliche räumliche Auflösung",
"Axis": "Achse",
"Azimuth Looks": "Bildaufnahmen senkrecht zur Flugrichtung",
"Azimuth Resolution": "Auflösung senkrecht zur Flugrichtung",
"Azimuth Pixel Spacing": "Pixelabstand senkrecht zur Flugrichtung",
"Azimuth Resolution": "Auflösung senkrecht zur Flugrichtung",
"Back-End Version": "Server-Version",
"Bands": "Bänder",
"Based on IANA relation types": "Basierend auf den IANA-Relationstypen",
Expand Down Expand Up @@ -212,6 +212,7 @@
"Language": "Sprache",
"Latest version": "Neuste Version",
"Latitude Band": "Breitengradband",
"Layers": "Ebenen",
"Level": "Stufe",
"Level 0 column cell": "Stufe-0-Zellenspalte",
"Level 0 row cell": "Stufe-0-Zellenreihe",
Expand Down Expand Up @@ -262,7 +263,7 @@
"Number": "Nummer",
"Number of Points": "Anzahl der Punkte",
"Number of bits": "Anzahl der Bits",
"OGC WMTS web map": "OGC-WMTS-Internetkarte",
"OGC Web Map Tile Service (WMTS)": "Kartendienst: OGC WMTS",
"Observation Direction": "Beobachtungsrichtung",
"Off-Nadir Angle": "Nebennadir-Winkel",
"Offset": "Versatz",
Expand Down Expand Up @@ -442,6 +443,7 @@
"Time of Data ends": "Letzter Zeitstempel der Daten",
"Title": "Titel",
"Transformation Matrix": "Transformationsmatrix",
"Transparency": "Transparenz",
"Type": "Typ",
"Types": "Art",
"URL": "Adresse",
Expand All @@ -468,8 +470,6 @@
"Vocabulary": "Vokabular",
"W/m²/μm": "W/m²/μm",
"WKT2": "WKT2",
"WMTS Dimensions": "WMTS-Dimensionen",
"WMTS Layers": "WMTS-Ebenen",
"WRS Path": "WRS-Pfad",
"WRS Row": "WRS-Reihe",
"WRS Type": "WRS-Typ",
Expand All @@ -487,7 +487,7 @@
"Worldwide Reference System Path": "Pfad im Weltweiten Referenzsystem",
"Worldwide Reference System Row": "Reihe im Weltweiten Referenzsystem",
"Worldwide Reference System Type": "Typ des Weltweiten Referenzsystems",
"XYZ web map": "XYZ-Internetkarte",
"XYZ Web Map": "Kartendienst: XYZ",
"Yaw Flip Configuration": "\"Yaw Flip\"-Konfiguration",
"ZIP archive": "ZIP-Archiv",
"bytes": "Bytes",
Expand Down
15 changes: 10 additions & 5 deletions src/locales/en/fields.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"32-bit float": "32-bit float",
"32-bit integer": "32-bit integer",
"3: 1x full disk, 3x continental US, 30x mesoscale region 1, 30x mesoscale region 2 (every 15 minutes)": "3: 1x full disk, 3x continental US, 30x mesoscale region 1, 30x mesoscale region 2 (every 15 minutes)",
"3D Tiles": "3D Tiles",
"4: 1x full disk (every 5 minutes)": "4: 1x full disk (every 5 minutes)",
"64-bit complex float": "64-bit complex float",
"64-bit float": "64-bit float",
Expand Down Expand Up @@ -212,6 +213,7 @@
"Language": "Language",
"Latest version": "Latest version",
"Latitude Band": "Latitude Band",
"Layers": "Layers",
"Level": "Level",
"Level 0 column cell": "Level 0 column cell",
"Level 0 row cell": "Level 0 row cell",
Expand Down Expand Up @@ -262,7 +264,8 @@
"Number": "Number",
"Number of Points": "Number of Points",
"Number of bits": "Number of bits",
"OGC WMTS web map": "OGC WMTS web map",
"OGC Web Map Service (WMS)": "OGC Web Map Service (WMS)",
"OGC Web Map Tile Service (WMTS)": "OGC Web Map Tile Service (WMTS)",
"Observation Direction": "Observation Direction",
"Off-Nadir Angle": "Off-Nadir Angle",
"Offset": "Offset",
Expand All @@ -282,6 +285,7 @@
"Overview": "Overview",
"Overviews": "Overviews",
"PDF document": "PDF document",
"PMTiles": "PMTiles",
"PNG image": "PNG image",
"PROJJSON": "PROJJSON",
"Parent STAC Catalog": "Parent STAC Catalog",
Expand Down Expand Up @@ -400,6 +404,7 @@
"Step": "Step",
"Storage Account": "Storage Account",
"Street / House": "Street / House",
"Styles": "Styles",
"Submitted": "Submitted",
"Successful Rectification Ratio": "Successful Rectification Ratio",
"Successor version": "Successor version",
Expand Down Expand Up @@ -435,6 +440,7 @@
"Tier Type": "Tier Type",
"Tile Matrix Set Links": "Tile Matrix Set Links",
"Tile Matrix Sets": "Tile Matrix Sets",
"TileJSON": "TileJSON",
"Tiled Assets": "Tiled Assets",
"Time Threshold in a Flash": "Time Threshold in a Flash",
"Time Threshold in a Group": "Time Threshold in a Group",
Expand All @@ -443,6 +449,7 @@
"Time of Data ends": "Time of Data ends",
"Title": "Title",
"Transformation Matrix": "Transformation Matrix",
"Transparency": "Transparency",
"Type": "Type",
"Types": "Types",
"URL": "URL",
Expand All @@ -469,8 +476,6 @@
"Vocabulary": "Vocabulary",
"W/m²/μm": "W/m²/μm",
"WKT2": "WKT2",
"WMTS Dimensions": "WMTS Dimensions",
"WMTS Layers": "WMTS Layers",
"WRS Path": "WRS Path",
"WRS Row": "WRS Row",
"WRS Type": "WRS Type",
Expand All @@ -488,7 +493,7 @@
"Worldwide Reference System Path": "Worldwide Reference System Path",
"Worldwide Reference System Row": "Worldwide Reference System Row",
"Worldwide Reference System Type": "Worldwide Reference System Type",
"XYZ web map": "XYZ web map",
"XYZ Web Map": "XYZ Web Map",
"Yaw Flip Configuration": "Yaw Flip Configuration",
"ZIP archive": "ZIP archive",
"bytes": "bytes",
Expand Down Expand Up @@ -516,4 +521,4 @@
"°E": "°E",
"°N": "°N",
"μm": "μm"
}
}
Loading

0 comments on commit 8574785

Please sign in to comment.