Skip to content

Commit

Permalink
Alternate Asset support #247
Browse files Browse the repository at this point in the history
  • Loading branch information
m-mohr committed Mar 11, 2024
1 parent 4351677 commit 47dea4f
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 45 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,11 @@ You need to provide a field `stac_browser` and then you can set any of the follo

STAC Browser supports some non-standardized extensions to the STAC specification that you can use to improve the user-experience.

1. To the [Provider Object](https://github.com/radiantearth/stac-spec/blob/master/collection-spec/collection-spec.md#provider-object) you can add an `email` (or `mail`) field with an e-mail address and the mail will be shown in the Browser, too.
2. A link with relation type `icon` and a Browser-supported media type in any STAC entity will show an icon in the header and the lists.
1. [Provider Object](https://github.com/radiantearth/stac-spec/blob/master/collection-spec/collection-spec.md#provider-object):
Add an `email` (or `mail`) field with an e-mail address and the mail will be shown in the Browser.
2. [Alternative Assets Object](https://github.com/stac-extensions/alternate-assets?tab=readme-ov-file#alternate-asset-object):
Add a `name` field and it will be used as title in the tab header.
3. A link with relation type `icon` and a Browser-supported media type in any STAC entity will show an icon in the header and the lists of Catalogs, Collections and Items.

## Docker

Expand Down
81 changes: 38 additions & 43 deletions src/components/Asset.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,39 @@
</b-button>
</b-card-header>
<b-collapse :id="uid" v-model="expanded" :accordion="type" role="tabpanel" @input="collapseToggled">
<b-card-body>
<b-card-title><span v-html="fileFormat" /></b-card-title>
<HrefActions isAsset :data="asset" :shown="shown" @show="show" />
<b-card-text class="mt-4" v-if="asset.description">
<Description :description="asset.description" compact />
</b-card-text>
<Metadata class="mt-4" :data="asset" :context="context" :ignoreFields="ignore" title="" type="Asset" />
</b-card-body>
<template v-if="hasAlternatives">
<b-tabs card>
<b-tab :title="asset.name || $t('assets.alternate.main')" active>
<AssetAlternative :asset="asset" :context="context" :shown="shown" hasAlternatives />
</b-tab>
<b-tab v-for="(altAsset, key) in alternatives" :title="altAsset.name || key" :key="key">
<AssetAlternative :asset="altAsset" :context="context" :shown="shown" hasAlternatives :key="key" />
</b-tab>
</b-tabs>
</template>
<AssetAlternative v-else :asset="asset" :context="context" />
</b-collapse>
</b-card>
</template>

<script>
import { BCollapse, BIconCheck, BIconChevronRight, BIconChevronDown } from 'bootstrap-vue';
import { BCollapse, BIconCheck, BIconChevronRight, BIconChevronDown, BTabs, BTab } from 'bootstrap-vue';
import { formatMediaType } from '@radiantearth/stac-fields/formatters';
import { mapState } from 'vuex';
import Description from './Description.vue';
import HrefActions from './HrefActions.vue';
import AssetAlternative from './AssetAlternative.vue';
import StacFieldsMixin from './StacFieldsMixin';
import Utils from '../utils';
export default {
name: 'Asset',
components: {
AssetAlternative,
BCollapse,
BIconCheck,
BIconChevronDown,
BIconChevronRight,
Description,
HrefActions,
Metadata: () => import('./Metadata.vue')
BTabs,
BTab
},
mixins: [
StacFieldsMixin({ formatMediaType })
Expand Down Expand Up @@ -80,34 +83,11 @@ export default {
},
data() {
return {
expanded: false,
ignore: [
// Asset fields that are handled directly
'href',
'title',
'description',
'type',
'roles',
// Don't show these complex lists of coordinates: https://github.com/radiantearth/stac-browser/issues/141
'proj:bbox',
'proj:geometry',
// Don't show very specific options that can't be rendered nicely
'table:storage_options',
'xarray:open_kwargs',
'xarray:storage_options'
]
expanded: false
};
},
computed: {
...mapState(['buildTileUrlTemplate', 'useTileLayerAsFallback', 'url', 'stateQueryParameters']),
tileRendererType() {
if (this.buildTileUrlTemplate && !this.useTileLayerAsFallback) {
return 'server';
}
else {
return 'client';
}
},
...mapState(['stateQueryParameters']),
type() {
return this.definition ? 'itemdef' : 'asset';
},
Expand All @@ -125,6 +105,24 @@ export default {
return this.formatMediaType(this.asset.type, null, {shorten: true});
}
return null;
},
alternatives() {
if (!Utils.isObject(this.asset.alternate)) {
return {};
}
const asset = Object.assign({}, this.asset);
delete asset.alternate;
const merged = {};
for (const key in this.asset.alternate) {
merged[key] = Object.assign({}, asset, this.asset.alternate[key]);
}
return merged;
},
hasAlternatives() {
return Utils.size(this.alternatives) > 0;
}
},
created() {
Expand All @@ -148,9 +146,6 @@ export default {
}
return role;
},
show() {
this.$emit('show', ...arguments);
},
collapseToggled(isVisible) {
let event = isVisible ? 'openCollapsible' : 'closeCollapsible';
this.$store.commit(event, {type: this.type, uid: this.uid});
Expand All @@ -173,4 +168,4 @@ export default {
}
}
}
</style>
</style>
95 changes: 95 additions & 0 deletions src/components/AssetAlternative.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<template>
<component :is="component">
<b-card-title><span v-html="fileFormat" /></b-card-title>
<HrefActions isAsset :data="asset" :shown="shown" @show="show" />
<b-card-text class="mt-4" v-if="asset.description">
<Description :description="asset.description" compact />
</b-card-text>
<Metadata class="mt-4" :data="asset" :context="context" :ignoreFields="ignore" title="" type="Asset" />
</component>
</template>

<script>
import { formatMediaType } from '@radiantearth/stac-fields/formatters';
import { mapState } from 'vuex';
import Description from './Description.vue';
import HrefActions from './HrefActions.vue';
import StacFieldsMixin from './StacFieldsMixin';
export default {
name: 'Asset',
components: {
Description,
HrefActions,
Metadata: () => import('./Metadata.vue')
},
mixins: [
StacFieldsMixin({ formatMediaType })
],
props: {
asset: {
type: Object,
required: true
},
context: {
type: Object,
default: null
},
hasAlternatives: {
type: Boolean,
default: false
},
shown: {
type: Boolean,
default: false
}
},
data() {
return {
ignore: [
// Asset fields that are handled directly
'href',
'title',
'description',
'type',
'roles',
// Don't show these complex lists of coordinates: https://github.com/radiantearth/stac-browser/issues/141
'proj:bbox',
'proj:geometry',
// Don't show very specific options that can't be rendered nicely
'table:storage_options',
'xarray:open_kwargs',
'xarray:storage_options',
// Alternative Assets are displayed separately
'alternate',
'name'
]
};
},
computed: {
...mapState(['buildTileUrlTemplate', 'useTileLayerAsFallback']),
component() {
return this.hasAlternatives ? 'div' : 'b-card-body';
},
tileRendererType() {
if (this.buildTileUrlTemplate && !this.useTileLayerAsFallback) {
return 'server';
}
else {
return 'client';
}
},
fileFormat() {
if (typeof this.asset.type === "string" && this.asset.type.length > 0) {
return this.formatMediaType(this.asset.type);
}
return null;
}
},
methods: {
show() {
this.$emit('show', ...arguments);
}
}
};
</script>
3 changes: 3 additions & 0 deletions src/locales/de/texts.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"title": "Anonymisiert"
},
"assets": {
"alternate": {
"main": "Bevorzugt"
},
"copyGdalVfsUrl": {
"generic": "Kopiere GDAL VFS Adresse",
"withSource": "Kopiere GDAL VFS Adresse für {source}"
Expand Down
3 changes: 3 additions & 0 deletions src/locales/en/texts.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"title": "Anonymized"
},
"assets": {
"alternate": {
"main": "Preferred"
},
"copyGdalVfsUrl": {
"generic": "Copy GDAL VFS URL",
"withSource": "Copy GDAL VFS URL for {source}"
Expand Down

0 comments on commit 47dea4f

Please sign in to comment.