@eodash/eodash 5.0.0-rc.3 → 5.1.0
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/README.md +1 -0
- package/core/client/App.vue +8 -2
- package/core/client/asWebComponent.js +5 -5
- package/core/client/components/DashboardLayout.vue +42 -25
- package/core/client/components/EodashOverlay.vue +1 -1
- package/core/client/components/ErrorAlert.vue +2 -2
- package/core/client/components/Footer.vue +4 -4
- package/core/client/components/Header.vue +3 -3
- package/core/client/components/MobileLayout.vue +9 -10
- package/core/client/composables/DefineEodash.js +38 -43
- package/core/client/composables/DefineTemplate.js +4 -2
- package/core/client/composables/DefineWidgets.js +14 -8
- package/core/client/composables/index.js +273 -23
- package/core/client/eodashSTAC/EodashCollection.js +80 -47
- package/core/client/eodashSTAC/helpers.js +136 -27
- package/core/client/eodashSTAC/parquet.js +145 -0
- package/core/client/eodashSTAC/triggers.js +6 -3
- package/core/client/plugins/index.js +4 -3
- package/core/client/plugins/vuetify.js +3 -0
- package/core/client/store/actions.js +21 -4
- package/core/client/store/stac.js +93 -56
- package/core/client/store/states.js +15 -5
- package/core/client/types.ts +59 -43
- package/core/client/utils/index.js +79 -0
- package/core/client/utils/keys.js +2 -2
- package/core/client/utils/states.js +30 -5
- package/core/client/views/Dashboard.vue +36 -32
- package/core/client/vite-env.d.ts +7 -0
- package/dist/client/{DashboardLayout-t_PavJPO.js → DashboardLayout-ByVs1DrY.js} +23 -12
- package/dist/client/{DynamicWebComponent-y07rVJch.js → DynamicWebComponent-C3W7HSQm.js} +1 -1
- package/dist/client/{EodashDatePicker-CcOfyzGD.js → EodashDatePicker-BIAf1sMT.js} +59 -32
- package/dist/client/{EodashItemFilter-B9HCvIMi.js → EodashItemFilter-DPznh8UB.js} +20 -10
- package/dist/client/{EodashLayerControl-KStn7Nb_.js → EodashLayerControl-Bhxjw4V2.js} +29 -16
- package/dist/client/EodashLayoutSwitcher-C5qTEffW.js +61 -0
- package/dist/client/EodashMapBtns-WoGq8MuV.js +173 -0
- package/dist/client/{EodashStacInfo-C_hDy6Pd.js → EodashStacInfo-CSvvF2jI.js} +3 -18
- package/dist/client/{EodashTools-BXflvRf8.js → EodashTools-Cv1SXQ5y.js} +13 -13
- package/dist/client/{ExportState-C0QRemK1.js → ExportState-D-iuwaad.js} +58 -52
- package/dist/client/{Footer-7VGyGUAs.js → Footer-CyF0zRAk.js} +15 -13
- package/dist/client/{Header-BQJnXHYq.js → Header-CgD8jDKU.js} +33 -28
- package/dist/client/{MobileLayout-b8nQ-Vyl.js → MobileLayout-EKQ_kpSh.js} +69 -60
- package/dist/client/{PopUp-DgNrh9Df.js → PopUp-BsYLvWch.js} +19 -10
- package/dist/client/ProcessList-C2xsLU2_.js +191 -0
- package/dist/client/{VImg-D4eT3IQ1.js → VImg-OHe8YTs2.js} +24 -24
- package/dist/client/{VMain-C3hN2-H3.js → VMain-PryTLU4a.js} +7 -7
- package/dist/client/{VOverlay-tAeNygaA.js → VOverlay-yUn7p-Uf.js} +64 -27
- package/dist/client/{VTooltip-B0Q3iHMZ.js → VTooltip-DZ0fjpB3.js} +13 -10
- package/dist/client/{WidgetsContainer-CtDHfCYf.js → WidgetsContainer-B9LBadcC.js} +1 -1
- package/dist/client/asWebComponent-By_7_JjS.js +19193 -0
- package/dist/client/async-DkSu_u2K.js +740 -0
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-CIFAqXaZ.js → forwardRefs-BXxrv98s.js} +31 -4
- package/dist/client/handling-CgmFXkW6.js +1212 -0
- package/dist/client/helpers-Dy0Q13tP.js +4534 -0
- package/dist/client/{index-DvcUndod.js → index-BuhOHXKv.js} +2 -4
- package/dist/client/{index-BQ16n4Sk.js → index-Ch_HchK3.js} +39 -32
- package/dist/client/{index-Cv7HBz49.js → index-Dqj4tbx2.js} +2 -2
- package/dist/client/index-skjhlH8u.js +376 -0
- package/dist/client/{ssrBoot-BP7SYRyC.js → ssrBoot-Zgc_Ttvi.js} +2 -2
- package/dist/client/templates.js +850 -0
- package/dist/client/transition-C98Yn4Vo.js +40 -0
- package/dist/node/cli.js +16 -6
- package/dist/node/types.d.ts +1 -1
- package/dist/types/core/client/App.vue.d.ts +2 -2
- package/dist/types/core/client/asWebComponent.d.ts +1 -1
- package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +1 -3
- package/dist/types/core/client/components/Footer.vue.d.ts +1 -105
- package/dist/types/core/client/components/IframeWrapper.vue.d.ts +1 -1
- package/dist/types/core/client/components/MobileLayout.vue.d.ts +1 -324
- package/dist/types/core/client/composables/DefineEodash.d.ts +2 -2
- package/dist/types/core/client/composables/DefineTemplate.d.ts +1 -1
- package/dist/types/core/client/composables/DefineWidgets.d.ts +4 -4
- package/dist/types/core/client/composables/index.d.ts +24 -2
- package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +9 -6
- package/dist/types/core/client/eodashSTAC/helpers.d.ts +20 -5
- package/dist/types/core/client/eodashSTAC/parquet.d.ts +2 -0
- package/dist/types/core/client/plugins/vuetify.d.ts +7 -4
- package/dist/types/core/client/store/actions.d.ts +3 -2
- package/dist/types/core/client/store/stac.d.ts +16 -13
- package/dist/types/core/client/store/states.d.ts +14 -4
- package/dist/types/core/client/types.d.ts +45 -30
- package/dist/types/core/client/utils/index.d.ts +2 -0
- package/dist/types/core/client/utils/keys.d.ts +4 -4
- package/dist/types/core/client/utils/states.d.ts +59 -47
- package/dist/types/core/client/views/Dashboard.vue.d.ts +2 -2
- package/dist/types/templates/baseConfig.d.ts +4 -0
- package/dist/types/templates/compare.d.ts +210 -0
- package/dist/types/templates/expert.d.ts +151 -0
- package/dist/types/templates/index.d.ts +6 -0
- package/dist/types/templates/light.d.ts +145 -0
- package/dist/types/widgets/EodashDatePicker.vue.d.ts +1 -458
- package/dist/types/widgets/EodashItemFilter.vue.d.ts +3 -3
- package/dist/types/widgets/EodashLayerControl.vue.d.ts +14 -7
- package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +1 -3
- package/dist/types/widgets/EodashMap/index.vue.d.ts +1 -4
- package/dist/types/widgets/EodashMapBtns.vue.d.ts +8 -8
- package/dist/types/widgets/EodashProcess/ProcessList.vue.d.ts +8 -1
- package/dist/types/widgets/EodashProcess/index.vue.d.ts +8 -4
- package/dist/types/widgets/EodashProcess/methods/async.d.ts +18 -18
- package/dist/types/widgets/EodashProcess/methods/composables.d.ts +3 -2
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/index.d.ts +1 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.d.ts +6 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.d.ts +4 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +5 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/index.d.ts +1 -0
- package/dist/types/widgets/EodashProcess/methods/handling.d.ts +12 -5
- package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +72 -41
- package/dist/types/widgets/EodashProcess/methods/utils.d.ts +41 -21
- package/dist/types/widgets/EodashProcess/states.d.ts +11 -0
- package/dist/types/widgets/EodashProcess/types.d.ts +41 -0
- package/dist/types/widgets/EodashStacInfo.vue.d.ts +14 -14
- package/dist/types/widgets/EodashTools.vue.d.ts +3 -3
- package/dist/types/widgets/ExportState.vue.d.ts +1 -1
- package/dist/types/widgets/PopUp.vue.d.ts +11 -16
- package/dist/types/widgets/WidgetsContainer.vue.d.ts +3 -6
- package/package.json +53 -45
- package/templates/baseConfig.js +68 -0
- package/templates/compare.js +162 -0
- package/templates/expert.js +123 -0
- package/templates/index.js +8 -0
- package/templates/light.js +130 -0
- package/widgets/EodashDatePicker.vue +80 -31
- package/widgets/EodashItemFilter.vue +26 -11
- package/widgets/EodashLayerControl.vue +20 -11
- package/widgets/EodashLayoutSwitcher.vue +6 -3
- package/widgets/EodashMap/index.vue +3 -8
- package/widgets/EodashMap/methods/create-layers-config.js +4 -3
- package/widgets/EodashMap/methods/index.js +33 -23
- package/widgets/EodashMapBtns.vue +83 -41
- package/widgets/EodashProcess/ProcessList.vue +34 -10
- package/widgets/EodashProcess/index.vue +55 -20
- package/widgets/EodashProcess/methods/async.js +77 -59
- package/widgets/EodashProcess/methods/composables.js +21 -14
- package/widgets/EodashProcess/methods/custom-endpoints/chart/index.js +35 -0
- package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +275 -0
- package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +116 -0
- package/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.js +94 -0
- package/widgets/EodashProcess/methods/custom-endpoints/layers/index.js +33 -0
- package/widgets/EodashProcess/methods/handling.js +127 -80
- package/widgets/EodashProcess/methods/outputs.js +376 -125
- package/widgets/EodashProcess/methods/utils.js +398 -10
- package/widgets/EodashProcess/states.js +13 -0
- package/widgets/EodashProcess/types.ts +46 -0
- package/widgets/EodashStacInfo.vue +2 -17
- package/widgets/EodashTools.vue +13 -13
- package/widgets/WidgetsContainer.vue +1 -1
- package/core/client/eodash.js +0 -454
- package/dist/client/EodashLayoutSwitcher-DqeFO3RN.js +0 -52
- package/dist/client/EodashMapBtns-5BF27qJB.js +0 -131
- package/dist/client/ProcessList-C62SOVO6.js +0 -484
- package/dist/client/asWebComponent-BJ2NWunV.js +0 -12479
- package/dist/client/eo-dash.css +0 -5
- package/dist/client/index-Da5xXX6Q.js +0 -780
- package/dist/client/transition-Cdb4K27U.js +0 -37
- package/dist/types/core/client/eodash.d.ts +0 -8
|
@@ -6,14 +6,15 @@ import { getStyleVariablesState } from "./triggers.js";
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {import("stac-ts").StacLink[]} [links]
|
|
8
8
|
* @param {Record<string,any>} [extraProperties]
|
|
9
|
+
* @param {string} [rel = "item"]
|
|
9
10
|
**/
|
|
10
|
-
export function generateFeatures(links, extraProperties = {}) {
|
|
11
|
+
export function generateFeatures(links, extraProperties = {}, rel = "item") {
|
|
11
12
|
/**
|
|
12
13
|
* @type {import("geojson").Feature[]}
|
|
13
14
|
*/
|
|
14
15
|
const features = [];
|
|
15
16
|
links?.forEach((element) => {
|
|
16
|
-
if (element.rel ===
|
|
17
|
+
if (element.rel === rel && "latlng" in element) {
|
|
17
18
|
const [lat, lon] = /** @type {string} */ (element.latlng)
|
|
18
19
|
.split(",")
|
|
19
20
|
.map((it) => Number(it));
|
|
@@ -177,9 +178,9 @@ export const extractLayerDatetime = (links, currentStep) => {
|
|
|
177
178
|
}
|
|
178
179
|
|
|
179
180
|
// check if links has a datetime value
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (!
|
|
181
|
+
const dateProperty = getDatetimeProperty(links);
|
|
182
|
+
|
|
183
|
+
if (!dateProperty) {
|
|
183
184
|
return undefined;
|
|
184
185
|
}
|
|
185
186
|
|
|
@@ -187,11 +188,10 @@ export const extractLayerDatetime = (links, currentStep) => {
|
|
|
187
188
|
const controlValues = [];
|
|
188
189
|
try {
|
|
189
190
|
currentStep = new Date(currentStep).toISOString();
|
|
190
|
-
|
|
191
191
|
links.reduce((vals, link) => {
|
|
192
|
-
if (link
|
|
192
|
+
if (link[dateProperty] && link.rel === "item") {
|
|
193
193
|
vals.push(
|
|
194
|
-
new Date(/** @type {string} */ (link
|
|
194
|
+
new Date(/** @type {string} */ (link[dateProperty])).toISOString(),
|
|
195
195
|
);
|
|
196
196
|
}
|
|
197
197
|
return vals;
|
|
@@ -207,7 +207,12 @@ export const extractLayerDatetime = (links, currentStep) => {
|
|
|
207
207
|
|
|
208
208
|
// item datetime is not included in the item links datetime
|
|
209
209
|
if (!controlValues.includes(currentStep)) {
|
|
210
|
-
|
|
210
|
+
const currentStepTime = new Date(currentStep).getTime();
|
|
211
|
+
currentStep = controlValues.reduce((a, b) => {
|
|
212
|
+
const aDiff = Math.abs(new Date(a).getTime() - currentStepTime);
|
|
213
|
+
const bDiff = Math.abs(new Date(b).getTime() - currentStepTime);
|
|
214
|
+
return bDiff < aDiff ? b : a;
|
|
215
|
+
});
|
|
211
216
|
}
|
|
212
217
|
|
|
213
218
|
return {
|
|
@@ -223,8 +228,8 @@ export const extractLayerDatetime = (links, currentStep) => {
|
|
|
223
228
|
/**
|
|
224
229
|
* Find JSON layer by ID
|
|
225
230
|
* @param {string} layer
|
|
226
|
-
* @param {
|
|
227
|
-
* @returns {
|
|
231
|
+
* @param {import("@eox/map").EoxLayer[]} layers
|
|
232
|
+
* @returns {import("@eox/map").EoxLayer | undefined}
|
|
228
233
|
**/
|
|
229
234
|
export const findLayer = (layers, layer) => {
|
|
230
235
|
for (const lyr of layers) {
|
|
@@ -235,7 +240,7 @@ export const findLayer = (layers, layer) => {
|
|
|
235
240
|
}
|
|
236
241
|
return found;
|
|
237
242
|
}
|
|
238
|
-
if (lyr.properties
|
|
243
|
+
if (lyr.properties?.id === layer) {
|
|
239
244
|
return lyr;
|
|
240
245
|
}
|
|
241
246
|
}
|
|
@@ -243,14 +248,14 @@ export const findLayer = (layers, layer) => {
|
|
|
243
248
|
|
|
244
249
|
/**
|
|
245
250
|
* Removes the layer with the id provided and injects an array of layers in its position
|
|
246
|
-
* @param {
|
|
251
|
+
* @param {import("@eox/map").EoxLayer[]} currentLayers
|
|
247
252
|
* @param {string} oldLayer - id of the layer to be replaced
|
|
248
|
-
*
|
|
249
|
-
* @returns {
|
|
253
|
+
* @param {import("@eox/map").EoxLayer[]} newLayers - array of layers to replace the old layer
|
|
254
|
+
* @returns {import("@eox/map").EoxLayer[]}
|
|
250
255
|
*/
|
|
251
256
|
export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
|
|
252
257
|
const oldLayerIdx = currentLayers.findIndex(
|
|
253
|
-
(l) => l.properties
|
|
258
|
+
(l) => l.properties?.id === oldLayer,
|
|
254
259
|
);
|
|
255
260
|
|
|
256
261
|
if (oldLayerIdx !== -1) {
|
|
@@ -258,10 +263,9 @@ export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
|
|
|
258
263
|
"Replacing layer",
|
|
259
264
|
oldLayer,
|
|
260
265
|
"with",
|
|
261
|
-
newLayers.map((l) => l.properties
|
|
266
|
+
newLayers.map((l) => l.properties?.id),
|
|
262
267
|
);
|
|
263
268
|
currentLayers.splice(oldLayerIdx, 1, ...newLayers);
|
|
264
|
-
return currentLayers;
|
|
265
269
|
}
|
|
266
270
|
|
|
267
271
|
for (const l of currentLayers) {
|
|
@@ -269,10 +273,10 @@ export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
|
|
|
269
273
|
const updatedGroupLyrs = replaceLayer(l.layers, oldLayer, newLayers);
|
|
270
274
|
if (updatedGroupLyrs?.length) {
|
|
271
275
|
l.layers = updatedGroupLyrs;
|
|
272
|
-
return currentLayers;
|
|
273
276
|
}
|
|
274
277
|
}
|
|
275
278
|
}
|
|
279
|
+
return currentLayers;
|
|
276
280
|
};
|
|
277
281
|
|
|
278
282
|
/**
|
|
@@ -281,18 +285,21 @@ export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
|
|
|
281
285
|
* @param {import('../eodashSTAC/EodashCollection.js').EodashCollection[]} indicators
|
|
282
286
|
* @param {import('ol/layer').Layer} layer
|
|
283
287
|
*/
|
|
284
|
-
export const getColFromLayer =
|
|
288
|
+
export const getColFromLayer = (indicators, layer) => {
|
|
285
289
|
// init cols
|
|
286
|
-
const collections =
|
|
287
|
-
indicators.map((ind) => ind.fetchCollection()),
|
|
288
|
-
);
|
|
290
|
+
const collections = indicators.map((ind) => ind.collectionStac);
|
|
289
291
|
const [collectionId, itemId, ..._other] = layer.get("id").split(";:;");
|
|
290
292
|
|
|
291
293
|
const chosen = collections.find((col) => {
|
|
292
294
|
const isInd =
|
|
293
|
-
col
|
|
294
|
-
col
|
|
295
|
-
(link) =>
|
|
295
|
+
col?.id === collectionId &&
|
|
296
|
+
col?.links?.some(
|
|
297
|
+
(link) =>
|
|
298
|
+
link.rel === "item" &&
|
|
299
|
+
(link.href.includes(itemId) ||
|
|
300
|
+
link.id === itemId ||
|
|
301
|
+
//@ts-expect-error attaching the item in link when parsing .parquet items, see @/eodashSTAC/parquet.js
|
|
302
|
+
(link["item"] && link["item"].id === itemId)),
|
|
296
303
|
);
|
|
297
304
|
return isInd;
|
|
298
305
|
});
|
|
@@ -306,7 +313,7 @@ export const getColFromLayer = async (indicators, layer) => {
|
|
|
306
313
|
* @param {string} collectionId
|
|
307
314
|
* @param {string} itemId
|
|
308
315
|
* @param {import('stac-ts').StacLink} link
|
|
309
|
-
* @param {string} projectionCode
|
|
316
|
+
* @param {string | import("ol/proj").ProjectionLike} projectionCode
|
|
310
317
|
*
|
|
311
318
|
*/
|
|
312
319
|
export const createLayerID = (collectionId, itemId, link, projectionCode) => {
|
|
@@ -419,6 +426,87 @@ export async function mergeGeojsons(geojsonUrls) {
|
|
|
419
426
|
);
|
|
420
427
|
}
|
|
421
428
|
|
|
429
|
+
/**
|
|
430
|
+
*
|
|
431
|
+
* @param {import("stac-ts").StacItem[]} items
|
|
432
|
+
*/
|
|
433
|
+
export function generateLinksFromItems(items) {
|
|
434
|
+
/**
|
|
435
|
+
* @param {string|Date} datetime
|
|
436
|
+
* @returns
|
|
437
|
+
*/
|
|
438
|
+
function formateDatetime(datetime) {
|
|
439
|
+
if (datetime instanceof Date) {
|
|
440
|
+
return datetime.toISOString();
|
|
441
|
+
}
|
|
442
|
+
if (typeof datetime === "string") {
|
|
443
|
+
const date = new Date(datetime);
|
|
444
|
+
return date.toISOString();
|
|
445
|
+
}
|
|
446
|
+
return datetime;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return items.map((item) => {
|
|
450
|
+
const itemBlob = new Blob([JSON.stringify(item)], {
|
|
451
|
+
type: "application/geo+json",
|
|
452
|
+
});
|
|
453
|
+
// urls are revoked when updating the collection. see updateEodashCollections in "../utils/index.js"
|
|
454
|
+
const itemUrl = URL.createObjectURL(itemBlob);
|
|
455
|
+
return {
|
|
456
|
+
id: item.id,
|
|
457
|
+
rel: "item",
|
|
458
|
+
type: "application/geo+json",
|
|
459
|
+
title: item.id,
|
|
460
|
+
href: itemUrl,
|
|
461
|
+
...(item.properties.datetime && {
|
|
462
|
+
datetime: formateDatetime(item.properties.datetime),
|
|
463
|
+
}),
|
|
464
|
+
...(item.properties.start_datetime && {
|
|
465
|
+
start_datetime: formateDatetime(item.properties.start_datetime),
|
|
466
|
+
}),
|
|
467
|
+
...(item.properties.end_datetime && {
|
|
468
|
+
end_datetime: formateDatetime(item.properties.end_datetime),
|
|
469
|
+
}),
|
|
470
|
+
//@ts-expect-error projection extension
|
|
471
|
+
...(item.properties?.["proj:epsg"] && {
|
|
472
|
+
"proj:epsg": /** @type {number} **/ (item.properties["proj:epsg"]),
|
|
473
|
+
}),
|
|
474
|
+
//@ts-expect-error eodash projection
|
|
475
|
+
...(item.properties?.["eodash:proj4_def"] && {
|
|
476
|
+
"eodash:proj4_def": item.properties["eodash:proj4_def"],
|
|
477
|
+
}),
|
|
478
|
+
|
|
479
|
+
...(item.geometry?.type == "Point" &&
|
|
480
|
+
item.geometry?.coordinates.length && {
|
|
481
|
+
latlng: item.geometry.coordinates.reverse().join(","),
|
|
482
|
+
}),
|
|
483
|
+
...(Object.values(item.assets ?? {}).some(
|
|
484
|
+
(asset) =>
|
|
485
|
+
asset.href.startsWith("s3://veda-data-store") &&
|
|
486
|
+
asset.type === "image/tiff; application=geotiff",
|
|
487
|
+
) && {
|
|
488
|
+
cog_href: Object.values(item.assets ?? {}).find((asset) =>
|
|
489
|
+
asset.href.startsWith("s3://veda-data-store"),
|
|
490
|
+
)?.href,
|
|
491
|
+
}),
|
|
492
|
+
};
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* @param {import("../eodashSTAC/EodashCollection.js").EodashCollection} collection
|
|
498
|
+
*/
|
|
499
|
+
export function revokeCollectionBlobUrls(collection) {
|
|
500
|
+
collection.collectionStac?.links.forEach((link) => {
|
|
501
|
+
if (!(link.rel === "item" && link.type === "application/geo+json")) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
if (link.href.startsWith("blob:")) {
|
|
505
|
+
URL.revokeObjectURL(link.href);
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
|
|
422
510
|
/**
|
|
423
511
|
* adds tooltip to the layer if the style has tooltip property
|
|
424
512
|
* @param {Record<string,any>} layer
|
|
@@ -441,3 +529,24 @@ export const addTooltipInteraction = (layer, style) => {
|
|
|
441
529
|
];
|
|
442
530
|
}
|
|
443
531
|
};
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
*
|
|
535
|
+
* @param {import("stac-ts").StacLink[]} [links]
|
|
536
|
+
*/
|
|
537
|
+
export function getDatetimeProperty(links) {
|
|
538
|
+
if (!links?.length) {
|
|
539
|
+
return undefined;
|
|
540
|
+
}
|
|
541
|
+
// TODO: consider other properties for datetime ranges
|
|
542
|
+
const datetimeProperties = ["datetime", "start_datetime", "end_datetime"];
|
|
543
|
+
for (const prop of datetimeProperties) {
|
|
544
|
+
const propExists = links.some(
|
|
545
|
+
(l) => l[prop] && typeof l[prop] === "string",
|
|
546
|
+
);
|
|
547
|
+
if (!propExists) {
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
return prop;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { parquetRead } from "hyparquet";
|
|
2
|
+
import WKB from "ol/format/WKB.js";
|
|
3
|
+
import GeoJSON from "ol/format/GeoJSON";
|
|
4
|
+
import log from "loglevel";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {string} url
|
|
8
|
+
*/
|
|
9
|
+
export const readParquetItems = async (url) => {
|
|
10
|
+
/** @type {import("stac-ts").StacItem[]} */
|
|
11
|
+
let items = [];
|
|
12
|
+
const response = await fetch(url, {
|
|
13
|
+
method: "GET",
|
|
14
|
+
headers: {
|
|
15
|
+
Accept: "application/octet-stream",
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
throw new Error(`Fetch failed: ${response.status} ${response.statusText}`);
|
|
21
|
+
}
|
|
22
|
+
const contentType = response.headers.get("Content-Type") || "";
|
|
23
|
+
if (
|
|
24
|
+
!contentType.includes("application") &&
|
|
25
|
+
!contentType.includes("octet-stream") &&
|
|
26
|
+
!url.endsWith(".parquet")
|
|
27
|
+
) {
|
|
28
|
+
console.warn(
|
|
29
|
+
"Response may not be a Parquet file. Content-Type:",
|
|
30
|
+
contentType,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
34
|
+
if (arrayBuffer.byteLength < 8) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
"Downloaded buffer is too small to be a valid Parquet file.",
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
await parquetRead({
|
|
40
|
+
file: arrayBuffer,
|
|
41
|
+
rowFormat: "object",
|
|
42
|
+
// set utf8 to false to avoid parsing wkb to string
|
|
43
|
+
utf8: false,
|
|
44
|
+
/*** @param {import("stac-ts").StacItem[]} data */
|
|
45
|
+
//@ts-expect-error rows are expected be array of arrays in hyparquet
|
|
46
|
+
onComplete: (data) => {
|
|
47
|
+
items.push(...(adjustParquetItems(data) ?? []));
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
log.debug("Adjusted Parquet items", items);
|
|
51
|
+
return items;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
* @param {import("stac-ts").StacItem[]} items
|
|
57
|
+
*/
|
|
58
|
+
export const adjustParquetItems = (items) => {
|
|
59
|
+
return items.map((item) => {
|
|
60
|
+
item = moveItemProperties(item);
|
|
61
|
+
item = adjustItemsBigInts(item);
|
|
62
|
+
|
|
63
|
+
return /** @type {import("stac-ts").StacItem} */ ({
|
|
64
|
+
...item,
|
|
65
|
+
//@ts-expect-error geometry wkb conversion by stac-geoparquet
|
|
66
|
+
geometry: wkbToGeometry(item.geometry),
|
|
67
|
+
|
|
68
|
+
assets: ((assets) => {
|
|
69
|
+
for (const [key, value] of Object.entries(assets)) {
|
|
70
|
+
if (!value || !value.href) {
|
|
71
|
+
delete assets[key];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return assets;
|
|
75
|
+
})(item.assets),
|
|
76
|
+
|
|
77
|
+
bbox: ((bbox) => {
|
|
78
|
+
//@ts-expect-error bbox conversion by stac-geoparquet
|
|
79
|
+
const { xmax, xmin, ymax, ymin } = bbox;
|
|
80
|
+
return [xmin, ymin, xmax, ymax].map((v) => parseFloat(v));
|
|
81
|
+
})(item.bbox),
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* @param {Uint8Array} wkb - Well Known Binary
|
|
87
|
+
*/
|
|
88
|
+
function wkbToGeometry(wkb) {
|
|
89
|
+
const geoJsonFormatter = new GeoJSON();
|
|
90
|
+
const wkbReader = new WKB();
|
|
91
|
+
const olGeometry = wkbReader.readGeometry(wkb);
|
|
92
|
+
return geoJsonFormatter.writeGeometryObject(olGeometry);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
*
|
|
97
|
+
* @param {import("stac-ts").StacItem} item
|
|
98
|
+
*/
|
|
99
|
+
function moveItemProperties(item) {
|
|
100
|
+
const stacProperties = [
|
|
101
|
+
"assets",
|
|
102
|
+
"links",
|
|
103
|
+
"bbox",
|
|
104
|
+
"geometry",
|
|
105
|
+
"stac_version",
|
|
106
|
+
"stac_extensions",
|
|
107
|
+
"type",
|
|
108
|
+
"id",
|
|
109
|
+
"collection",
|
|
110
|
+
"properties",
|
|
111
|
+
];
|
|
112
|
+
for (const key in item) {
|
|
113
|
+
if (!stacProperties.includes(key)) {
|
|
114
|
+
if (!item.properties) {
|
|
115
|
+
item.properties = {};
|
|
116
|
+
}
|
|
117
|
+
item.properties[key] = item[key];
|
|
118
|
+
delete item[key];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return item;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
*
|
|
126
|
+
* @param {import("stac-ts").StacItem} item
|
|
127
|
+
*/
|
|
128
|
+
function adjustItemsBigInts(item) {
|
|
129
|
+
/** @param {*} obj */
|
|
130
|
+
const adjustBigInt = (obj) => {
|
|
131
|
+
for (const key in obj ?? {}) {
|
|
132
|
+
if (typeof obj[key] === "bigint") {
|
|
133
|
+
obj[key] = parseFloat(obj[key].toString());
|
|
134
|
+
} else if (typeof obj[key] === "object" && obj[key] !== null) {
|
|
135
|
+
adjustBigInt(obj[key]);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
adjustBigInt(item.links);
|
|
140
|
+
adjustBigInt(item.properties);
|
|
141
|
+
adjustBigInt(item.assets);
|
|
142
|
+
adjustBigInt(item.bbox);
|
|
143
|
+
adjustBigInt(item.geometry);
|
|
144
|
+
return item;
|
|
145
|
+
}
|
|
@@ -52,9 +52,12 @@ export function getStyleVariablesState(collectionId, variables) {
|
|
|
52
52
|
return variables;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const analysisGroup =
|
|
56
|
-
(
|
|
57
|
-
|
|
55
|
+
const analysisGroup =
|
|
56
|
+
/** @type {import("@eox/map/src/layers").EOxLayerTypeGroup | undefined} */ (
|
|
57
|
+
mapElement.layers.find(
|
|
58
|
+
(layer) => layer.properties?.id === "AnalysisGroup",
|
|
59
|
+
)
|
|
60
|
+
);
|
|
58
61
|
if (!analysisGroup) {
|
|
59
62
|
return variables;
|
|
60
63
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import vuetify from "./vuetify";
|
|
2
2
|
import { createPinia } from "pinia";
|
|
3
|
-
import eodash from "@/eodash";
|
|
4
3
|
import VCalendar from "v-calendar";
|
|
5
|
-
import { eodashKey } from "@/utils/keys";
|
|
6
4
|
import store from "../store";
|
|
7
5
|
import log from "loglevel";
|
|
6
|
+
import { eodashKey } from "@/utils/keys";
|
|
7
|
+
import { reactive } from "vue";
|
|
8
8
|
|
|
9
9
|
export const pinia = createPinia();
|
|
10
10
|
|
|
@@ -17,5 +17,6 @@ export function registerPlugins(app) {
|
|
|
17
17
|
.use(pinia)
|
|
18
18
|
// Use plugin with optional defaults
|
|
19
19
|
.use(VCalendar, {})
|
|
20
|
-
|
|
20
|
+
//@ts-expect-error reactive placeholder for eodash
|
|
21
|
+
.provide(eodashKey, reactive({}));
|
|
21
22
|
}
|
|
@@ -6,11 +6,14 @@
|
|
|
6
6
|
|
|
7
7
|
// Styles
|
|
8
8
|
import "vuetify/styles";
|
|
9
|
+
import "@eox/ui/vuetify/style.css";
|
|
10
|
+
import { eox } from "@eox/ui/vuetify/blueprint.js";
|
|
9
11
|
|
|
10
12
|
import { createVuetify } from "vuetify";
|
|
11
13
|
import { mdiChevronLeft, mdiChevronRight, mdiMenuDown, mdiPlus } from "@mdi/js";
|
|
12
14
|
|
|
13
15
|
const vuetify = createVuetify({
|
|
16
|
+
blueprint: eox,
|
|
14
17
|
icons: {
|
|
15
18
|
aliases: {
|
|
16
19
|
// mapping v-date-picker and v-tabs default icons to `@mdi/js`
|
|
@@ -3,21 +3,24 @@ import {
|
|
|
3
3
|
mapCompareEl,
|
|
4
4
|
registeredProjections,
|
|
5
5
|
activeTemplate,
|
|
6
|
+
poi,
|
|
7
|
+
comparePoi,
|
|
6
8
|
} from "@/store/states";
|
|
7
9
|
import { getProjectionCode } from "@/eodashSTAC/helpers";
|
|
8
10
|
import log from "loglevel";
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* Returns the current layers of {@link mapEl}
|
|
12
|
-
* @returns {
|
|
14
|
+
* @returns {import("@eox/map").EoxLayer[]}
|
|
13
15
|
*/
|
|
14
|
-
export const getLayers = () => mapEl.value?.layers.toReversed();
|
|
16
|
+
export const getLayers = () => mapEl.value?.layers.toReversed() ?? [];
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* Returns the current layers of {@link mapCompareEl}
|
|
18
|
-
* @returns {
|
|
20
|
+
* * @returns {import("@eox/map").EoxLayer[]}
|
|
19
21
|
*/
|
|
20
|
-
export const getCompareLayers = () =>
|
|
22
|
+
export const getCompareLayers = () =>
|
|
23
|
+
mapCompareEl.value?.layers.toReversed() ?? [];
|
|
21
24
|
|
|
22
25
|
/**
|
|
23
26
|
* Register EPSG projection in `eox-map`
|
|
@@ -77,3 +80,17 @@ export const setActiveTemplate = (template) => {
|
|
|
77
80
|
activeTemplate.value = template;
|
|
78
81
|
log.debug("Setting active template to", template);
|
|
79
82
|
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Check whether the collection needs an EodashProcess Widget
|
|
86
|
+
* @param {import("stac-ts").StacCollection | null | undefined} collection
|
|
87
|
+
* @param {boolean} [compare=false] - Whether to check for compare collection
|
|
88
|
+
* @returns
|
|
89
|
+
*/
|
|
90
|
+
export const includesProcess = (collection, compare = false) => {
|
|
91
|
+
const isPoiAlive = compare ? !!comparePoi.value : !!poi.value;
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
collection?.links?.some((link) => link.rel === "service") || isPoiAlive
|
|
95
|
+
);
|
|
96
|
+
};
|