Skip to content

Commit 6baf41f

Browse files
committed
started migration to stac-js and map/asset communication
1 parent 7fefce9 commit 6baf41f

15 files changed

+136
-171
lines changed

config.js

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ module.exports = {
3939
redirectLegacyUrls: false,
4040
itemsPerPage: 12,
4141
defaultThumbnailSize: null,
42-
maxPreviewsOnMap: 50,
4342
crossOriginMedia: null,
4443
requestHeaders: {},
4544
requestQueryParameters: {},

config.schema.json

-6
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,6 @@
176176
]
177177
}
178178
},
179-
"maxPreviewsOnMap": {
180-
"type": [
181-
"integer"
182-
],
183-
"minimum": 1
184-
},
185179
"crossOriginMedia": {
186180
"type": [
187181
"string",

docs/options.md

-5
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ The following ways to set config options are possible:
3535
- [displayGeoTiffByDefault](#displaygeotiffbydefault)
3636
- [redirectLegacyUrls](#redirectlegacyurls)
3737
- [itemsPerPage](#itemsperpage)
38-
- [maxPreviewsOnMap](#maxpreviewsonmap)
3938
- [cardViewMode](#cardviewmode)
4039
- [cardViewSort](#cardviewsort)
4140
- [showKeywordsInItemCards](#showkeywordsinitemcards)
@@ -237,10 +236,6 @@ If you are updating from on old version of STAC Browser, you can set this option
237236

238237
The number of items requested and shown per page by default. Only applies to APIs that support the `limit` query parameter.
239238

240-
## maxPreviewsOnMap
241-
242-
The maximum number of previews (thumbnails or overviews) of items that will be shown on the map when on Catalog or Collection pages.
243-
244239
## cardViewMode
245240

246241
The default view mode for lists of catalogs/collections. Either `"list"` or `"cards"` (default).

src/components/Asset.vue

+16-18
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<b-icon-chevron-down v-if="expanded" />
77
<b-icon-chevron-right v-else />
88
</span>
9-
<span class="title">{{ asset.title || id }}</span>
9+
<span class="title">{{ title }}</span>
1010
<div class="badges ml-1">
1111
<b-badge v-if="shown" variant="success" class="shown" :title="$t('assets.currentlyShown')">
1212
<b-icon-check /> {{ $t('assets.shown') }}
@@ -23,14 +23,14 @@
2323
<template v-if="hasAlternatives">
2424
<b-tabs card>
2525
<b-tab :title="asset['alternate:name'] || $t('assets.alternate.main')" active>
26-
<AssetAlternative :asset="asset" :context="context" :shown="shown" hasAlternatives @show="show" />
26+
<AssetAlternative :asset="asset" :shown="shown" hasAlternatives @show="show" />
2727
</b-tab>
2828
<b-tab v-for="(altAsset, key) in alternatives" :title="altAsset['alternate:name'] || key" :key="key">
29-
<AssetAlternative :asset="altAsset" :context="context" :shown="shown" hasAlternatives :key="key" @show="show" />
29+
<AssetAlternative :asset="altAsset" :shown="shown" hasAlternatives :key="key" @show="show" />
3030
</b-tab>
3131
</b-tabs>
3232
</template>
33-
<AssetAlternative v-else :asset="asset" :context="context" :shown="shown" @show="show" />
33+
<AssetAlternative v-else :asset="asset" :shown="shown" @show="show" />
3434
</b-collapse>
3535
</b-card>
3636
</template>
@@ -42,6 +42,7 @@ import { mapState } from 'vuex';
4242
import AssetAlternative from './AssetAlternative.vue';
4343
import StacFieldsMixin from './StacFieldsMixin';
4444
import Utils from '../utils';
45+
import { Asset } from 'stac-js';
4546
4647
export default {
4748
name: 'Asset',
@@ -62,14 +63,6 @@ export default {
6263
type: Object,
6364
required: true
6465
},
65-
id: {
66-
type: String,
67-
required: true
68-
},
69-
context: {
70-
type: Object,
71-
default: null
72-
},
7366
definition: {
7467
type: Boolean,
7568
default: false
@@ -94,7 +87,10 @@ export default {
9487
return this.definition ? 'itemdef' : 'asset';
9588
},
9689
uid() {
97-
return `${this.type}-${this.id.toLowerCase().replace(/[^\w]/g, '-')}`;
90+
return `${this.type}-${this.asset.getKey().toLowerCase().replace(/[^\w]/g, '-')}`;
91+
},
92+
title() {
93+
return this.asset.title || this.asset.getKey();
9894
},
9995
fileFormat() {
10096
if (typeof this.asset.type === "string" && this.asset.type.length > 0) {
@@ -113,15 +109,17 @@ export default {
113109
return {};
114110
}
115111
116-
const asset = Object.assign({}, this.asset);
117-
delete asset.alternate;
112+
const inherit = this.asset.toJSON();
113+
delete inherit.alternate;
118114
119-
const merged = {};
115+
const alternates = {};
120116
for (const key in this.asset.alternate) {
121-
merged[key] = Object.assign({}, asset, this.asset.alternate[key]);
117+
const alternate = this.asset.alternate[key];
118+
const merged = Object.assign({}, inherit, alternate.toJSON());
119+
alternates[key] = new Asset(merged, key, alternate.getContext());
122120
}
123121
124-
return merged;
122+
return alternates;
125123
},
126124
hasAlternatives() {
127125
return Utils.size(this.alternatives) > 0;

src/components/AssetAlternative.vue

+3-4
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ export default {
3232
type: Object,
3333
required: true
3434
},
35-
context: {
36-
type: Object,
37-
default: null
38-
},
3935
hasAlternatives: {
4036
type: Boolean,
4137
default: false
@@ -71,6 +67,9 @@ export default {
7167
},
7268
computed: {
7369
...mapState(['buildTileUrlTemplate', 'useTileLayerAsFallback']),
70+
context() {
71+
return this.asset.getContext();
72+
},
7473
component() {
7574
return this.hasAlternatives ? 'div' : 'b-card-body';
7675
},

src/components/Assets.vue

+10-11
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@
33
<h2 v-if="displayTitle">{{ displayTitle }}</h2>
44
<div class="accordion" role="tablist">
55
<Asset
6-
v-for="(asset, key) in assets" :asset="asset" :expand="expand" :context="context"
7-
:definition="definition" :shown="shown.includes(key)"
8-
:id="key" :key="key" @show="show"
6+
v-for="asset in assets" :asset="asset" :expand="expand" :context="context"
7+
:definition="definition" :shown="shownKeys.includes(asset.getKey())"
8+
:key="asset.getKey()" @show="show"
99
/>
1010
</div>
1111
</section>
1212
</template>
1313

1414
<script>
1515
import Asset from './Asset.vue';
16-
import Utils from '../utils';
1716
1817
export default {
1918
name: 'Assets',
@@ -22,7 +21,7 @@ export default {
2221
},
2322
props: {
2423
assets: {
25-
type: Object,
24+
type: Array,
2625
required: true
2726
},
2827
shown: {
@@ -43,13 +42,13 @@ export default {
4342
}
4443
},
4544
computed: {
46-
count() {
47-
return Utils.size(this.assets);
45+
shownKeys() {
46+
return this.shown.map(asset => asset.getKey());
4847
},
4948
displayTitle() {
5049
if (this.title === null) {
5150
let langKey = this.definition ? 'assets.inItems' : 'stacAssets';
52-
return this.$tc(langKey, this.count);
51+
return this.$tc(langKey, this.assets.length);
5352
}
5453
else {
5554
return this.title;
@@ -59,15 +58,15 @@ export default {
5958
if (this.definition) {
6059
return false; // Don't expand assets for Item Asset Definitions
6160
}
62-
else if (this.count === 1 && this.stac && this.stac.isItem()) {
61+
else if (this.assets.length === 1 && this.stac && this.stac.isItem()) {
6362
return true; // Expand asset if it's the only asset available and it is in an Item
6463
}
6564
return null; // Let asset decide (e.g. depending on roles)
6665
}
6766
},
6867
methods: {
69-
show(asset, id, isThumbnail) {
70-
this.$emit('showAsset', asset, id, isThumbnail);
68+
show() {
69+
this.$emit('showAsset', ...arguments);
7170
}
7271
}
7372
};

src/components/HrefActions.vue

+7-9
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@
4040
<script>
4141
import { BIconBoxArrowUpRight, BIconDownload, BIconEye, BIconLock, BListGroup, BPopover, BSpinner } from 'bootstrap-vue';
4242
import Description from './Description.vue';
43-
import STAC from '../models/stac';
4443
import Utils, { browserProtocols, imageMediaTypes, mapMediaTypes } from '../utils';
4544
import { mapGetters, mapState } from 'vuex';
4645
import AssetActions from '../../assetActions.config';
4746
import LinkActions from '../../linkActions.config';
4847
import { stacRequestOptions } from '../store/utils';
4948
import URI from 'urijs';
5049
import AuthUtils from './auth/utils';
50+
import { Asset } from 'stac-js';
5151
5252
let i = 0;
5353
@@ -197,7 +197,7 @@ export default {
197197
},
198198
isThumbnail() {
199199
if (this.isAsset) {
200-
return Array.isArray(this.data.roles) && this.data.roles.includes('thumbnail') && !this.data.roles.includes('overview');
200+
return this.data.isPreview() && this.data.canBrowserDisplayImage();
201201
}
202202
else {
203203
return this.data.rel === 'preview' && Utils.canBrowserDisplayImage(this.data);
@@ -210,12 +210,8 @@ export default {
210210
if (typeof this.data.href !== 'string') {
211211
return null;
212212
}
213-
let baseUrl = null;
214-
if (this.context instanceof STAC) {
215-
baseUrl = this.context.getAbsoluteUrl();
216-
}
217213
try {
218-
return this.getRequestUrl(this.data.href, baseUrl);
214+
return this.getRequestUrl(this.data.getAbsoluteHref());
219215
} catch (e) {
220216
return this.data.href;
221217
}
@@ -379,12 +375,14 @@ export default {
379375
return '';
380376
},
381377
show() {
382-
let data = Object.assign({}, this.data);
378+
let data = this.data;
383379
// Override asset href with absolute URL if not a GDAL VFS
384380
if (!this.isGdalVfs) {
381+
// Clone asset so that we can change the href
382+
data = new Asset(this.data);
385383
data.href = this.href;
386384
}
387-
this.$emit('show', data, this.id, this.isThumbnail);
385+
this.$emit('show', data);
388386
},
389387
handleAuthButton() {
390388
if (this.auth.length === 1) {

src/components/Map.vue

+5-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export default {
4848
default: null
4949
},
5050
assets: {
51-
type: Object,
51+
type: Array,
5252
default: null
5353
},
5454
items: {
@@ -123,7 +123,10 @@ export default {
123123
console.warn(error);
124124
this.fit();
125125
});
126-
this.stacLayer.on('assetsready', this.fit);
126+
this.stacLayer.on('assetsready', () => {
127+
this.fit();
128+
this.$emit('assets', this.getAssets());
129+
});
127130
this.map.addLayer(this.stacLayer);
128131
129132
if (this.popover) {

src/components/Metadata.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export default {
9999
!key.startsWith("_") && !this.ignoreFields.includes(key);
100100
switch (this.type) {
101101
case "Asset":
102-
return formatAsset(this.data, this.context, filter);
102+
return formatAsset(this.data.toJSON(), this.context, filter);
103103
case "Link":
104104
return formatLink(this.data, this.context, filter);
105105
case "Provider":

src/components/ShowAssetLinkMixin.js

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import Utils from '../utils';
2+
import { mapGetters, mapState } from 'vuex';
3+
import { stacBrowserSpecialHandling } from "../rels";
4+
import create from 'stac-js';
5+
6+
export default {
7+
data() {
8+
return {
9+
tab: null,
10+
shownOnMap: [],
11+
};
12+
},
13+
computed: {
14+
...mapState(['showThumbnailsAsAssets']),
15+
...mapGetters(['data']),
16+
// hasAsset also checks whether the assets have a href and thus are not item asset definitions
17+
data2() {
18+
// todo: remove once stac-js is implemented fully
19+
if (!this.data) {
20+
return null;
21+
}
22+
return create(this.data, false);
23+
},
24+
hasAssets() {
25+
return this.assets;
26+
},
27+
assets() {
28+
if (!this.data2) {
29+
return [];
30+
}
31+
let assets = this.data2.getAssets();
32+
if (!this.showThumbnailsAsAssets) {
33+
assets = assets.filter(asset => !asset.isPreview());
34+
}
35+
return assets;
36+
},
37+
hasThumbnails() {
38+
return this.thumbnails.length > 0;
39+
},
40+
thumbnails() {
41+
if (!this.data2) {
42+
return [];
43+
}
44+
return this.data2.getThumbnails();
45+
},
46+
additionalLinks() {
47+
if (!this.data) {
48+
return [];
49+
}
50+
return this.data.getLinksWithOtherRels(stacBrowserSpecialHandling)
51+
.filter(link => link.rel !== 'preview' || !Utils.canBrowserDisplayImage(link));
52+
},
53+
selectedAssets() {
54+
if (this.tab === 0) {
55+
return this.shownOnMap;
56+
}
57+
else {
58+
return this.thumbnails;
59+
}
60+
}
61+
},
62+
methods: {
63+
showAsset(asset) {
64+
if (asset.isPreview()) {
65+
this.tab = 1;
66+
}
67+
else {
68+
this.tab = 0;
69+
this.shownOnMap = [asset];
70+
}
71+
if (this.$refs.tabs) {
72+
Utils.scrollTo(this.$refs.tabs.$el);
73+
}
74+
},
75+
dataChanged(data) {
76+
this.shownOnMap = data;
77+
}
78+
}
79+
};

0 commit comments

Comments
 (0)