@eodash/eodash 5.0.0-alpha.2.10 → 5.0.0-alpha.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/client/composables/index.js +37 -18
- package/core/client/eodash.js +3 -10
- package/core/client/store/Actions.js +9 -33
- package/core/client/store/States.js +3 -0
- package/core/client/utils/createLayers.js +131 -0
- package/core/client/utils/eodashSTAC.js +149 -227
- package/core/client/utils/helpers.js +49 -69
- package/dist/client/{DashboardLayout-C_3q8Y10.js → DashboardLayout-g4rqjeWc.js} +2 -2
- package/dist/client/{DynamicWebComponent-IiTTLBt-.js → DynamicWebComponent-BKV7nbud.js} +4 -4
- package/dist/client/{EodashDatePicker-DgC1lccp.js → EodashDatePicker-D4zsy9eq.js} +43 -43
- package/dist/client/EodashItemFilter-CRA5Ksjy.js +10067 -0
- package/dist/client/EodashLayerControl-CcFkORFA.js +31500 -0
- package/dist/client/{EodashMap-C96D3LLv.js → EodashMap-Bq6kJxfa.js} +8326 -8311
- package/dist/client/{EodashMapBtns-DDtzV94u.js → EodashMapBtns-Tzefzyf2.js} +5 -5
- package/dist/client/{ExportState-CduS2mFs.js → ExportState-CbK0FtDG.js} +37 -37
- package/dist/client/{Footer-DHQcutCv.js → Footer-BrNqLnRu.js} +1 -1
- package/dist/client/{Header-DC0y7rLK.js → Header-CbTE-BoI.js} +4 -4
- package/dist/client/{IframeWrapper-BK-10FbS.js → IframeWrapper-Ph5bZpJZ.js} +1 -1
- package/dist/client/{MobileLayout-BpLoMY4i.js → MobileLayout-kdgmpNhM.js} +6 -6
- package/dist/client/{PopUp-CNMCWL0z.js → PopUp-BWbFe1C1.js} +9 -9
- package/dist/client/{VImg-DT7eb8V-.js → VImg-CzQmrZjo.js} +2 -2
- package/dist/client/{VMain-OenWyy46.js → VMain-DfQqCpW9.js} +2 -2
- package/dist/client/{VOverlay-x3UXpKhr.js → VOverlay-sx4v7gXf.js} +71 -71
- package/dist/client/{WidgetsContainer-qMUwtN0W.js → WidgetsContainer-BrWo2pW8.js} +5 -5
- package/dist/client/{asWebComponent-DQrnLsI2.js → asWebComponent-CVFLR8Hh.js} +4117 -4117
- package/dist/client/{decoder-Cth6J7EK-CtUoHA6r.js → decoder-Cth6J7EK-DlG9ScOz.js} +1 -1
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-CpNjL95t.js → forwardRefs-BOAfCdT0.js} +1 -1
- package/dist/client/{helpers-KCSgmfim.js → helpers-BjdrMtvO.js} +206 -232
- package/dist/client/{index-DopVrUzM.js → index-Ct9AYlRj.js} +5 -5
- package/dist/client/{lerc-BgbQqdFI-D986ErVw.js → lerc-BgbQqdFI-B1NkI4BO.js} +1 -1
- package/dist/client/{ssrBoot-DkjdOWvj.js → ssrBoot-BfIptj2L.js} +1 -1
- package/dist/client/style.css +1 -1
- package/dist/client/{transition-BtJHh7JK.js → transition-YJj28Lgx.js} +1 -1
- package/dist/node/cli.js +2 -2
- package/package.json +6 -3
- package/widgets/EodashDatePicker.vue +4 -3
- package/widgets/EodashItemFilter.vue +17 -12
- package/widgets/EodashLayerControl.vue +18 -0
- package/widgets/EodashMap.vue +46 -75
- package/widgets/ExportState.vue +3 -2
- package/dist/client/EodashItemFilter-DoWZGe6r.js +0 -7671
- package/dist/client/eox-jsonform-DCErgjhw.js +0 -17515
- package/dist/client/eox-layercontrol-D0Ht7Mag.js +0 -21298
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { Collection, Item } from "stac-js";
|
|
2
2
|
import { toAbsolute } from "stac-js/src/http.js";
|
|
3
3
|
import {
|
|
4
|
-
createLayersFromDataAssets,
|
|
5
4
|
extractLayerConfig,
|
|
5
|
+
extractRoles,
|
|
6
|
+
fetchStyle,
|
|
6
7
|
generateFeatures,
|
|
7
8
|
setMapProjFromCol,
|
|
9
|
+
uid,
|
|
8
10
|
} from "./helpers";
|
|
9
|
-
import axios from "axios";
|
|
10
11
|
import { registerProjection } from "@/store/Actions";
|
|
12
|
+
import {
|
|
13
|
+
createLayersFromDataAssets,
|
|
14
|
+
createLayersFromLinks,
|
|
15
|
+
} from "./createLayers";
|
|
16
|
+
import axios from "axios";
|
|
11
17
|
|
|
12
18
|
export class EodashCollection {
|
|
13
|
-
/** @type {string} */
|
|
14
19
|
#collectionUrl = "";
|
|
20
|
+
|
|
15
21
|
/** @type {import("stac-ts").StacCollection | undefined} */
|
|
16
22
|
#collectionStac;
|
|
23
|
+
|
|
17
24
|
/**
|
|
18
25
|
* @type {import("stac-ts").StacLink
|
|
19
26
|
* | import("stac-ts").StacItem
|
|
@@ -25,262 +32,166 @@ export class EodashCollection {
|
|
|
25
32
|
constructor(collectionUrl) {
|
|
26
33
|
this.#collectionUrl = collectionUrl;
|
|
27
34
|
}
|
|
35
|
+
|
|
28
36
|
/**
|
|
29
37
|
* @async
|
|
30
|
-
* @param {import('stac-ts').StacLink | Date} [
|
|
38
|
+
* @param {import('stac-ts').StacLink | Date} [linkOrDate]
|
|
31
39
|
* @returns
|
|
32
40
|
*/
|
|
33
|
-
createLayersJson = async (
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
createLayersJson = async (linkOrDate) => {
|
|
42
|
+
/**
|
|
43
|
+
* @type {import("stac-ts").StacLink | undefined}
|
|
44
|
+
**/
|
|
45
|
+
let stacItem;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @type {import("stac-ts").StacCollection | undefined}
|
|
49
|
+
**/
|
|
50
|
+
let stac;
|
|
38
51
|
// TODO get auxiliary layers from collection
|
|
39
|
-
/** @type {
|
|
52
|
+
/** @type {Record<string,any>[]} */
|
|
40
53
|
let layersJson = [];
|
|
41
54
|
|
|
42
55
|
// Load collectionstac if not yet initialized
|
|
43
56
|
if (!this.#collectionStac) {
|
|
44
|
-
|
|
45
|
-
stac = await response.data;
|
|
57
|
+
stac = await axios.get(this.#collectionUrl).then((resp) => resp.data);
|
|
46
58
|
this.#collectionStac = new Collection(stac);
|
|
47
59
|
}
|
|
48
60
|
|
|
49
61
|
// set availabe map projection
|
|
50
62
|
setMapProjFromCol(this.#collectionStac);
|
|
51
63
|
|
|
52
|
-
|
|
53
|
-
// Special handling of point based data
|
|
54
|
-
const allFeatures = generateFeatures(stac.links);
|
|
55
|
-
layersJson.unshift({
|
|
56
|
-
type: "Vector",
|
|
57
|
-
properties: {
|
|
58
|
-
id: stac.id,
|
|
59
|
-
title: stac.title || stac.id,
|
|
60
|
-
},
|
|
61
|
-
source: {
|
|
62
|
-
type: "Vector",
|
|
63
|
-
url: "data:," + encodeURIComponent(JSON.stringify(allFeatures)),
|
|
64
|
-
format: "GeoJSON",
|
|
65
|
-
},
|
|
66
|
-
style: {
|
|
67
|
-
"circle-radius": 5,
|
|
68
|
-
"circle-fill-color": "#00417077",
|
|
69
|
-
"circle-stroke-color": "#004170",
|
|
70
|
-
"fill-color": "#00417077",
|
|
71
|
-
"stroke-color": "#004170",
|
|
72
|
-
},
|
|
73
|
-
});
|
|
64
|
+
const isGeoDB = stac?.endpointtype === "GeoDB";
|
|
74
65
|
|
|
75
|
-
|
|
66
|
+
if (linkOrDate instanceof Date) {
|
|
67
|
+
// if collectionStac not yet initialized we do it here
|
|
68
|
+
stacItem = this.getItem(linkOrDate);
|
|
76
69
|
} else {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
);
|
|
84
|
-
const distanceB = Math.abs(
|
|
85
|
-
new Date(/** @type {number} */ (b.datetime)).getTime() -
|
|
86
|
-
itemLinkOrDate.getTime(),
|
|
87
|
-
);
|
|
88
|
-
return distanceA - distanceB;
|
|
89
|
-
})[0];
|
|
90
|
-
this.selectedItem = stacItem;
|
|
91
|
-
} else {
|
|
92
|
-
stacItem = itemLinkOrDate;
|
|
93
|
-
}
|
|
70
|
+
stacItem = linkOrDate;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const stacItemUrl = stacItem
|
|
74
|
+
? toAbsolute(stacItem.href, this.#collectionUrl)
|
|
75
|
+
: this.#collectionUrl;
|
|
94
76
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
77
|
+
stac = await axios.get(stacItemUrl).then((resp) => resp.data);
|
|
78
|
+
|
|
79
|
+
if (!stacItem) {
|
|
80
|
+
// no specific item was requested; render last item
|
|
81
|
+
this.#collectionStac = new Collection(stac);
|
|
82
|
+
this.selectedItem = this.getItem();
|
|
99
83
|
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
this.selectedItem = items?.[items.length - 1];
|
|
105
|
-
if (this.selectedItem) {
|
|
106
|
-
layersJson = await this.createLayersJson(this.selectedItem);
|
|
107
|
-
} else {
|
|
108
|
-
if (import.meta.env.DEV) {
|
|
109
|
-
console.warn(
|
|
110
|
-
"[eodash] the selected collection does not include any items",
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return [];
|
|
84
|
+
if (this.selectedItem) {
|
|
85
|
+
layersJson = /** @type {Record<string,any>[]} */ (
|
|
86
|
+
await this.createLayersJson(this.selectedItem)
|
|
87
|
+
);
|
|
115
88
|
} else {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
this.selectedItem = item;
|
|
119
|
-
const title = this.#collectionStac.title || this.#collectionStac.id;
|
|
120
|
-
layersJson.unshift(
|
|
121
|
-
...(await this.buildJsonArray(item, stacItemUrl, title)),
|
|
89
|
+
console.warn(
|
|
90
|
+
"[eodash] the selected collection does not include any items",
|
|
122
91
|
);
|
|
123
|
-
return layersJson;
|
|
124
92
|
}
|
|
93
|
+
return [];
|
|
94
|
+
} else {
|
|
95
|
+
// specific item was requested
|
|
96
|
+
const item = new Item(stac);
|
|
97
|
+
this.selectedItem = item;
|
|
98
|
+
const title = this.#collectionStac.title || this.#collectionStac.id;
|
|
99
|
+
layersJson.unshift(
|
|
100
|
+
...(await this.buildJsonArray(item, stacItemUrl, title, isGeoDB)),
|
|
101
|
+
);
|
|
102
|
+
return layersJson;
|
|
125
103
|
}
|
|
126
104
|
};
|
|
127
105
|
|
|
128
|
-
async getExtent() {
|
|
129
|
-
if (!this.#collectionStac) {
|
|
130
|
-
const response = await axios.get(this.#collectionUrl);
|
|
131
|
-
const stac = await response.data;
|
|
132
|
-
this.#collectionStac = new Collection(stac);
|
|
133
|
-
}
|
|
134
|
-
return this.#collectionStac?.extent;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* @param {object} properties
|
|
138
|
-
* @param {[string]} roles
|
|
139
|
-
* */
|
|
140
|
-
extractRoles(properties, roles) {
|
|
141
|
-
roles?.forEach((role) => {
|
|
142
|
-
if (role === "visible") {
|
|
143
|
-
// @ts-expect-error visible does not need to exist in properties
|
|
144
|
-
properties.visible = true;
|
|
145
|
-
}
|
|
146
|
-
if (role === "overlay" || role === "baselayer") {
|
|
147
|
-
// @ts-expect-error group not expected to exist in properties
|
|
148
|
-
properties.group = role;
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
106
|
/**
|
|
153
107
|
* @param {import("stac-ts").StacItem} item
|
|
154
108
|
* @param {string} itemUrl
|
|
155
109
|
* @param {string} title
|
|
110
|
+
* @param {boolean} isGeoDB
|
|
111
|
+
* @returns {Promise<Record<string,any>[]>} arrays
|
|
156
112
|
* */
|
|
157
|
-
async buildJsonArray(item, itemUrl, title) {
|
|
113
|
+
async buildJsonArray(item, itemUrl, title, isGeoDB) {
|
|
114
|
+
await registerProjection(
|
|
115
|
+
/** @type {number | undefined} */ (item?.["proj:epsg"]),
|
|
116
|
+
);
|
|
117
|
+
|
|
158
118
|
const jsonArray = [];
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
119
|
+
|
|
120
|
+
if (isGeoDB) {
|
|
121
|
+
const allFeatures = generateFeatures(this.#collectionStac?.links);
|
|
122
|
+
|
|
123
|
+
return [
|
|
124
|
+
{
|
|
125
|
+
type: "Vector",
|
|
126
|
+
properties: {
|
|
127
|
+
id: item.id,
|
|
128
|
+
title: this.#collectionStac?.title || item.id,
|
|
129
|
+
},
|
|
130
|
+
source: {
|
|
131
|
+
type: "Vector",
|
|
132
|
+
url: "data:," + encodeURIComponent(JSON.stringify(allFeatures)),
|
|
133
|
+
format: "GeoJSON",
|
|
134
|
+
},
|
|
135
|
+
style: {
|
|
136
|
+
"circle-radius": 5,
|
|
137
|
+
"circle-fill-color": "#00417077",
|
|
138
|
+
"circle-stroke-color": "#004170",
|
|
139
|
+
"fill-color": "#00417077",
|
|
140
|
+
"stroke-color": "#004170",
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
];
|
|
144
|
+
}
|
|
163
145
|
|
|
164
146
|
// I propose following approach, we "manually" create configurations
|
|
165
147
|
// for the rendering options we know and expect.
|
|
166
148
|
// If we don't find any we fallback to using the STAC ol item that
|
|
167
149
|
// will try to extract anything it supports but for which we have
|
|
168
150
|
// less control.
|
|
169
|
-
let dataAssets = /** @type {Record<string,import('stac-ts').StacAsset>} */ ({});
|
|
170
|
-
if (item.assets) {
|
|
171
|
-
dataAssets = Object.keys(item.assets).reduce((data, ast) => {
|
|
172
|
-
if (item.assets[ast].roles?.includes("data")) {
|
|
173
|
-
data[ast] = item.assets[ast];
|
|
174
|
-
}
|
|
175
|
-
return data;
|
|
176
|
-
}, /** @type {Record<string,import('stac-ts').StacAsset>} */ ({}));
|
|
177
|
-
}
|
|
178
151
|
|
|
179
152
|
const { layerConfig, style } = extractLayerConfig(
|
|
180
|
-
await
|
|
153
|
+
await fetchStyle(item, itemUrl),
|
|
181
154
|
);
|
|
182
|
-
const wmsArray = item.links.filter((l) => l.rel === "wms");
|
|
183
|
-
const xyzArray = item.links.filter((l) => l.rel === "xyz");
|
|
184
|
-
const fallbackToStac = item.links.find((l) => l.rel === "wmts");
|
|
185
155
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
156
|
+
const dataAssets = Object.keys(item?.assets ?? {}).reduce((data, ast) => {
|
|
157
|
+
if (item.assets[ast].roles?.includes("data")) {
|
|
158
|
+
data[ast] = item.assets[ast];
|
|
159
|
+
}
|
|
160
|
+
return data;
|
|
161
|
+
}, /** @type {Record<string,import('stac-ts').StacAsset>} */ ({}));
|
|
190
162
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
id: link.id || item.id,
|
|
197
|
-
title: title || link.title || item.id,
|
|
198
|
-
},
|
|
199
|
-
source: {
|
|
200
|
-
// TODO: if no projection information is provided we should
|
|
201
|
-
// assume one, else for WMS requests it will try to get
|
|
202
|
-
// the map projection that might not be supported
|
|
203
|
-
// projection: projDef ? projDef : "EPSG:4326",
|
|
204
|
-
type: "TileWMS",
|
|
205
|
-
url: link.href,
|
|
206
|
-
params: {
|
|
207
|
-
LAYERS: link["wms:layers"],
|
|
208
|
-
TILED: true,
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
|
-
};
|
|
212
|
-
this.extractRoles(
|
|
213
|
-
json.properties,
|
|
214
|
-
/** @type {[string]} */ (link.roles),
|
|
215
|
-
);
|
|
216
|
-
if ("wms:dimensions" in link) {
|
|
217
|
-
// Expand all dimensions into the params attribute
|
|
218
|
-
json.source.params = Object.assign(
|
|
219
|
-
json.source.params,
|
|
220
|
-
link["wms:dimensions"],
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
jsonArray.push(json);
|
|
224
|
-
});
|
|
225
|
-
} else if (xyzArray.length > 0) {
|
|
226
|
-
xyzArray.forEach((link) => {
|
|
227
|
-
let json = {
|
|
228
|
-
type: "Tile",
|
|
229
|
-
properties: {
|
|
230
|
-
id: link.id || item.id,
|
|
231
|
-
title: title || link.title || item.id,
|
|
232
|
-
roles: link.roles,
|
|
233
|
-
},
|
|
234
|
-
source: {
|
|
235
|
-
type: "XYZ",
|
|
236
|
-
url: link.href,
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
|
-
this.extractRoles(
|
|
240
|
-
json.properties,
|
|
241
|
-
/** @type {[string]} */ (link.roles),
|
|
242
|
-
);
|
|
243
|
-
jsonArray.push(json);
|
|
244
|
-
});
|
|
245
|
-
} else if (fallbackToStac) {
|
|
246
|
-
jsonArray.push({
|
|
247
|
-
type: "STAC",
|
|
248
|
-
displayWebMapLink: true,
|
|
249
|
-
displayFootprint: false,
|
|
250
|
-
data: item,
|
|
251
|
-
properties: {
|
|
252
|
-
id: item.id,
|
|
253
|
-
title: title || item.id,
|
|
254
|
-
},
|
|
255
|
-
});
|
|
256
|
-
} else if (Object.keys(dataAssets).length) {
|
|
163
|
+
const isSupported =
|
|
164
|
+
item.links.some((link) => ["wms", "xyz"].includes(link.rel)) ||
|
|
165
|
+
Object.keys(dataAssets).length;
|
|
166
|
+
|
|
167
|
+
if (isSupported) {
|
|
257
168
|
jsonArray.push(
|
|
169
|
+
...createLayersFromLinks(uid(), title, item),
|
|
170
|
+
|
|
258
171
|
...(await createLayersFromDataAssets(
|
|
259
|
-
|
|
260
|
-
this.#collectionStac?.title || item.id,
|
|
172
|
+
uid(),
|
|
173
|
+
title || this.#collectionStac?.title || item.id,
|
|
261
174
|
dataAssets,
|
|
262
175
|
style,
|
|
263
176
|
layerConfig,
|
|
264
177
|
)),
|
|
265
178
|
);
|
|
266
|
-
} else
|
|
267
|
-
//
|
|
268
|
-
|
|
269
|
-
type: "
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
format: "GeoJSON",
|
|
274
|
-
},
|
|
179
|
+
} else {
|
|
180
|
+
// fallback to STAC
|
|
181
|
+
const json = {
|
|
182
|
+
type: "STAC",
|
|
183
|
+
displayWebMapLink: true,
|
|
184
|
+
displayFootprint: false,
|
|
185
|
+
data: item,
|
|
275
186
|
properties: {
|
|
276
187
|
id: item.id,
|
|
277
|
-
title:
|
|
278
|
-
layerConfig
|
|
279
|
-
...layerConfig,
|
|
280
|
-
style,
|
|
281
|
-
},
|
|
188
|
+
title: title || item.id,
|
|
189
|
+
layerConfig,
|
|
282
190
|
},
|
|
283
|
-
|
|
191
|
+
style,
|
|
192
|
+
};
|
|
193
|
+
extractRoles(json.properties, /** @type {string[]} */ (item?.roles));
|
|
194
|
+
jsonArray.push(json);
|
|
284
195
|
}
|
|
285
196
|
|
|
286
197
|
return jsonArray;
|
|
@@ -300,26 +211,6 @@ export class EodashCollection {
|
|
|
300
211
|
);
|
|
301
212
|
}
|
|
302
213
|
|
|
303
|
-
/**
|
|
304
|
-
* @param {import("stac-ts").StacItem} item
|
|
305
|
-
* @param {string} itemUrl
|
|
306
|
-
**/
|
|
307
|
-
async fetchStyle(item, itemUrl) {
|
|
308
|
-
const styleLink = item.links.find((link) => link.rel.includes("style"));
|
|
309
|
-
if (styleLink) {
|
|
310
|
-
let url = "";
|
|
311
|
-
if (styleLink.href.startsWith("http")) {
|
|
312
|
-
url = styleLink.href;
|
|
313
|
-
} else {
|
|
314
|
-
url = toAbsolute(styleLink.href, itemUrl);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/** @type {import("ol/layer/WebGLTile").Style & {jsonform?:object}} */
|
|
318
|
-
const styleJson = await axios.get(url).then((resp) => resp.data);
|
|
319
|
-
return styleJson;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
214
|
getDates() {
|
|
324
215
|
return (
|
|
325
216
|
this.#collectionStac?.links
|
|
@@ -334,4 +225,35 @@ export class EodashCollection {
|
|
|
334
225
|
.map((i) => new Date(/** @type {number} */ (i.datetime)))
|
|
335
226
|
);
|
|
336
227
|
}
|
|
228
|
+
|
|
229
|
+
async getExtent() {
|
|
230
|
+
if (!this.#collectionStac) {
|
|
231
|
+
const stac = await axios
|
|
232
|
+
.get(this.#collectionUrl)
|
|
233
|
+
.then((resp) => resp.data);
|
|
234
|
+
this.#collectionStac = new Collection(stac);
|
|
235
|
+
}
|
|
236
|
+
return this.#collectionStac?.extent;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Get closest Item Link from a certain date,
|
|
241
|
+
* get the latest if no date provided
|
|
242
|
+
* @param {Date} [date]
|
|
243
|
+
**/
|
|
244
|
+
getItem(date) {
|
|
245
|
+
return date
|
|
246
|
+
? this.getItems()?.sort((a, b) => {
|
|
247
|
+
const distanceA = Math.abs(
|
|
248
|
+
new Date(/** @type {number} */ (a.datetime)).getTime() -
|
|
249
|
+
date.getTime(),
|
|
250
|
+
);
|
|
251
|
+
const distanceB = Math.abs(
|
|
252
|
+
new Date(/** @type {number} */ (b.datetime)).getTime() -
|
|
253
|
+
date.getTime(),
|
|
254
|
+
);
|
|
255
|
+
return distanceA - distanceB;
|
|
256
|
+
})[0]
|
|
257
|
+
: this.getItems()?.at(-1);
|
|
258
|
+
}
|
|
337
259
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { changeMapProjection
|
|
1
|
+
import { changeMapProjection } from "@/store/Actions";
|
|
2
2
|
import { availableMapProjection } from "@/store/States";
|
|
3
3
|
import { toAbsolute } from "stac-js/src/http.js";
|
|
4
|
+
import axios from "axios";
|
|
4
5
|
|
|
5
|
-
/** @param {import("stac-ts").StacLink[]} links */
|
|
6
|
+
/** @param {import("stac-ts").StacLink[]} [links] */
|
|
6
7
|
export function generateFeatures(links) {
|
|
7
8
|
/**
|
|
8
9
|
* @type {{
|
|
@@ -14,7 +15,7 @@ export function generateFeatures(links) {
|
|
|
14
15
|
* }[]}
|
|
15
16
|
*/
|
|
16
17
|
const features = [];
|
|
17
|
-
links
|
|
18
|
+
links?.forEach((element) => {
|
|
18
19
|
if (element.rel === "item" && "latlng" in element) {
|
|
19
20
|
const [lat, lon] = /** @type {string} */ (element.latlng)
|
|
20
21
|
.split(",")
|
|
@@ -41,82 +42,21 @@ export function generateFeatures(links) {
|
|
|
41
42
|
return geojsonObject;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
/** @param { import("ol/layer/WebGLTile").Style & { jsonform?:
|
|
45
|
+
/** @param { import("ol/layer/WebGLTile").Style & { jsonform?: Record<string,any> } } [style] */
|
|
45
46
|
export function extractLayerConfig(style) {
|
|
46
|
-
/** @type {Record<string,unknown>} */
|
|
47
|
-
let layerConfig =
|
|
47
|
+
/** @type {Record<string,unknown> | undefined} */
|
|
48
|
+
let layerConfig = undefined;
|
|
48
49
|
if (style?.jsonform) {
|
|
49
50
|
layerConfig = { schema: style.jsonform, type: "style" };
|
|
50
|
-
delete style
|
|
51
|
+
delete style.jsonform;
|
|
51
52
|
}
|
|
52
53
|
return { layerConfig, style };
|
|
53
54
|
}
|
|
54
|
-
/**
|
|
55
|
-
* @param {string} id
|
|
56
|
-
* @param {string} title
|
|
57
|
-
* @param {Record<string,import("stac-ts").StacAsset>} assets
|
|
58
|
-
* @param {import("ol/layer/WebGLTile").Style} [style]
|
|
59
|
-
* @param {Record<string, unknown>} [layerConfig]
|
|
60
|
-
**/
|
|
61
|
-
export async function createLayersFromDataAssets(
|
|
62
|
-
id,
|
|
63
|
-
title,
|
|
64
|
-
assets,
|
|
65
|
-
style,
|
|
66
|
-
layerConfig,
|
|
67
|
-
) {
|
|
68
|
-
let jsonArray = [];
|
|
69
|
-
let geoTIFFSources = [];
|
|
70
|
-
for (const ast in assets) {
|
|
71
|
-
// register projection if exists
|
|
72
|
-
await registerProjection(
|
|
73
|
-
/** @type {number | undefined} */ (assets[ast]?.["proj:epsg"]),
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
if (assets[ast]?.type === "application/geo+json") {
|
|
77
|
-
jsonArray.push({
|
|
78
|
-
type: "Vector",
|
|
79
|
-
source: {
|
|
80
|
-
type: "Vector",
|
|
81
|
-
url: assets[ast].href,
|
|
82
|
-
format: "GeoJSON",
|
|
83
|
-
},
|
|
84
|
-
properties: {
|
|
85
|
-
id,
|
|
86
|
-
title,
|
|
87
|
-
layerConfig: {
|
|
88
|
-
...layerConfig,
|
|
89
|
-
style,
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
} else if (assets[ast]?.type === "image/tiff") {
|
|
94
|
-
geoTIFFSources.push({ url: assets[ast].href });
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
if (geoTIFFSources.length) {
|
|
98
|
-
jsonArray.push({
|
|
99
|
-
type: "WebGLTile",
|
|
100
|
-
source: {
|
|
101
|
-
type: "GeoTIFF",
|
|
102
|
-
normalize: style?.variables ? false : true,
|
|
103
|
-
sources: geoTIFFSources,
|
|
104
|
-
},
|
|
105
|
-
properties: {
|
|
106
|
-
id,
|
|
107
|
-
title,
|
|
108
|
-
layerConfig,
|
|
109
|
-
},
|
|
110
|
-
style,
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
return jsonArray;
|
|
114
|
-
}
|
|
115
55
|
|
|
116
56
|
/**
|
|
117
57
|
* checks if there's a projection on the Collection and
|
|
118
58
|
* updates {@link availableMapProjection}
|
|
119
|
-
* @param {import('stac-ts').StacCollection} STAcCollection
|
|
59
|
+
* @param {import('stac-ts').StacCollection} [STAcCollection]
|
|
120
60
|
*/
|
|
121
61
|
export const setMapProjFromCol = (STAcCollection) => {
|
|
122
62
|
// if a projection exists on the collection level
|
|
@@ -170,3 +110,43 @@ export function extractCollectionUrls(stacObject, basepath) {
|
|
|
170
110
|
}
|
|
171
111
|
return collectionUrls;
|
|
172
112
|
}
|
|
113
|
+
|
|
114
|
+
export const uid = () =>
|
|
115
|
+
Date.now().toString(36) + Math.random().toString(36).substring(2);
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Assign extracted roles to layer properties
|
|
119
|
+
* @param {Record<string,any>} properties
|
|
120
|
+
* @param {string[]} roles
|
|
121
|
+
* */
|
|
122
|
+
export const extractRoles = (properties, roles) => {
|
|
123
|
+
roles?.forEach((role) => {
|
|
124
|
+
if (role === "visible") {
|
|
125
|
+
properties.visible = true;
|
|
126
|
+
}
|
|
127
|
+
if (role === "overlay" || role === "baselayer") {
|
|
128
|
+
properties.group = role;
|
|
129
|
+
}
|
|
130
|
+
return properties;
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @param {import("stac-ts").StacItem} item
|
|
136
|
+
* @param {string} itemUrl
|
|
137
|
+
**/
|
|
138
|
+
export const fetchStyle = async (item, itemUrl) => {
|
|
139
|
+
const styleLink = item.links.find((link) => link.rel.includes("style"));
|
|
140
|
+
if (styleLink) {
|
|
141
|
+
let url = "";
|
|
142
|
+
if (styleLink.href.startsWith("http")) {
|
|
143
|
+
url = styleLink.href;
|
|
144
|
+
} else {
|
|
145
|
+
url = toAbsolute(styleLink.href, itemUrl);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** @type {import("ol/layer/WebGLTile").Style & {jsonform?:Record<string,any>}} */
|
|
149
|
+
const styleJson = await axios.get(url).then((resp) => resp.data);
|
|
150
|
+
return styleJson;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _ as y, x as m, W as x, X as d, $ as t, a0 as r, a1 as l, a9 as _, a3 as n, a6 as u, a2 as c, a4 as p, d as h, a5 as g, F as f, a7 as v, ab as w } from "./asWebComponent-
|
|
2
|
-
import { V as k } from "./VMain-
|
|
1
|
+
import { _ as y, x as m, W as x, X as d, $ as t, a0 as r, a1 as l, a9 as _, a3 as n, a6 as u, a2 as c, a4 as p, d as h, a5 as g, F as f, a7 as v, ab as w } from "./asWebComponent-CVFLR8Hh.js";
|
|
2
|
+
import { V as k } from "./VMain-DfQqCpW9.js";
|
|
3
3
|
class A extends HTMLElement {
|
|
4
4
|
static get observedAttributes() {
|
|
5
5
|
return ["gap"];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const h = { class: "d-flex flex-column fill-height overflow-auto" },
|
|
1
|
+
import { bE as i, aA as m, r as p, Z as d, aM as f, $ as c, a6 as g, a0 as y, d as _, a4 as k } from "./asWebComponent-CVFLR8Hh.js";
|
|
2
|
+
const h = { class: "d-flex flex-column fill-height overflow-auto" }, E = {
|
|
3
3
|
__name: "DynamicWebComponent",
|
|
4
4
|
props: {
|
|
5
5
|
link: {
|
|
@@ -38,7 +38,7 @@ const h = { class: "d-flex flex-column fill-height overflow-auto" }, N = {
|
|
|
38
38
|
e.onMounted?.(r.value, s);
|
|
39
39
|
}), f(() => {
|
|
40
40
|
e.onUnmounted?.(r.value, s);
|
|
41
|
-
}), (n,
|
|
41
|
+
}), (n, x) => (c(), g("span", h, [
|
|
42
42
|
(c(), y(
|
|
43
43
|
k(o.tagName),
|
|
44
44
|
_(o.properties, {
|
|
@@ -53,5 +53,5 @@ const h = { class: "d-flex flex-column fill-height overflow-auto" }, N = {
|
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
55
|
export {
|
|
56
|
-
|
|
56
|
+
E as default
|
|
57
57
|
};
|