@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.
Files changed (155) hide show
  1. package/README.md +1 -0
  2. package/core/client/App.vue +8 -2
  3. package/core/client/asWebComponent.js +5 -5
  4. package/core/client/components/DashboardLayout.vue +42 -25
  5. package/core/client/components/EodashOverlay.vue +1 -1
  6. package/core/client/components/ErrorAlert.vue +2 -2
  7. package/core/client/components/Footer.vue +4 -4
  8. package/core/client/components/Header.vue +3 -3
  9. package/core/client/components/MobileLayout.vue +9 -10
  10. package/core/client/composables/DefineEodash.js +38 -43
  11. package/core/client/composables/DefineTemplate.js +4 -2
  12. package/core/client/composables/DefineWidgets.js +14 -8
  13. package/core/client/composables/index.js +273 -23
  14. package/core/client/eodashSTAC/EodashCollection.js +80 -47
  15. package/core/client/eodashSTAC/helpers.js +136 -27
  16. package/core/client/eodashSTAC/parquet.js +145 -0
  17. package/core/client/eodashSTAC/triggers.js +6 -3
  18. package/core/client/plugins/index.js +4 -3
  19. package/core/client/plugins/vuetify.js +3 -0
  20. package/core/client/store/actions.js +21 -4
  21. package/core/client/store/stac.js +93 -56
  22. package/core/client/store/states.js +15 -5
  23. package/core/client/types.ts +59 -43
  24. package/core/client/utils/index.js +79 -0
  25. package/core/client/utils/keys.js +2 -2
  26. package/core/client/utils/states.js +30 -5
  27. package/core/client/views/Dashboard.vue +36 -32
  28. package/core/client/vite-env.d.ts +7 -0
  29. package/dist/client/{DashboardLayout-t_PavJPO.js → DashboardLayout-ByVs1DrY.js} +23 -12
  30. package/dist/client/{DynamicWebComponent-y07rVJch.js → DynamicWebComponent-C3W7HSQm.js} +1 -1
  31. package/dist/client/{EodashDatePicker-CcOfyzGD.js → EodashDatePicker-BIAf1sMT.js} +59 -32
  32. package/dist/client/{EodashItemFilter-B9HCvIMi.js → EodashItemFilter-DPznh8UB.js} +20 -10
  33. package/dist/client/{EodashLayerControl-KStn7Nb_.js → EodashLayerControl-Bhxjw4V2.js} +29 -16
  34. package/dist/client/EodashLayoutSwitcher-C5qTEffW.js +61 -0
  35. package/dist/client/EodashMapBtns-WoGq8MuV.js +173 -0
  36. package/dist/client/{EodashStacInfo-C_hDy6Pd.js → EodashStacInfo-CSvvF2jI.js} +3 -18
  37. package/dist/client/{EodashTools-BXflvRf8.js → EodashTools-Cv1SXQ5y.js} +13 -13
  38. package/dist/client/{ExportState-C0QRemK1.js → ExportState-D-iuwaad.js} +58 -52
  39. package/dist/client/{Footer-7VGyGUAs.js → Footer-CyF0zRAk.js} +15 -13
  40. package/dist/client/{Header-BQJnXHYq.js → Header-CgD8jDKU.js} +33 -28
  41. package/dist/client/{MobileLayout-b8nQ-Vyl.js → MobileLayout-EKQ_kpSh.js} +69 -60
  42. package/dist/client/{PopUp-DgNrh9Df.js → PopUp-BsYLvWch.js} +19 -10
  43. package/dist/client/ProcessList-C2xsLU2_.js +191 -0
  44. package/dist/client/{VImg-D4eT3IQ1.js → VImg-OHe8YTs2.js} +24 -24
  45. package/dist/client/{VMain-C3hN2-H3.js → VMain-PryTLU4a.js} +7 -7
  46. package/dist/client/{VOverlay-tAeNygaA.js → VOverlay-yUn7p-Uf.js} +64 -27
  47. package/dist/client/{VTooltip-B0Q3iHMZ.js → VTooltip-DZ0fjpB3.js} +13 -10
  48. package/dist/client/{WidgetsContainer-CtDHfCYf.js → WidgetsContainer-B9LBadcC.js} +1 -1
  49. package/dist/client/asWebComponent-By_7_JjS.js +19193 -0
  50. package/dist/client/async-DkSu_u2K.js +740 -0
  51. package/dist/client/eo-dash.js +1 -1
  52. package/dist/client/{forwardRefs-CIFAqXaZ.js → forwardRefs-BXxrv98s.js} +31 -4
  53. package/dist/client/handling-CgmFXkW6.js +1212 -0
  54. package/dist/client/helpers-Dy0Q13tP.js +4534 -0
  55. package/dist/client/{index-DvcUndod.js → index-BuhOHXKv.js} +2 -4
  56. package/dist/client/{index-BQ16n4Sk.js → index-Ch_HchK3.js} +39 -32
  57. package/dist/client/{index-Cv7HBz49.js → index-Dqj4tbx2.js} +2 -2
  58. package/dist/client/index-skjhlH8u.js +376 -0
  59. package/dist/client/{ssrBoot-BP7SYRyC.js → ssrBoot-Zgc_Ttvi.js} +2 -2
  60. package/dist/client/templates.js +850 -0
  61. package/dist/client/transition-C98Yn4Vo.js +40 -0
  62. package/dist/node/cli.js +16 -6
  63. package/dist/node/types.d.ts +1 -1
  64. package/dist/types/core/client/App.vue.d.ts +2 -2
  65. package/dist/types/core/client/asWebComponent.d.ts +1 -1
  66. package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +1 -3
  67. package/dist/types/core/client/components/Footer.vue.d.ts +1 -105
  68. package/dist/types/core/client/components/IframeWrapper.vue.d.ts +1 -1
  69. package/dist/types/core/client/components/MobileLayout.vue.d.ts +1 -324
  70. package/dist/types/core/client/composables/DefineEodash.d.ts +2 -2
  71. package/dist/types/core/client/composables/DefineTemplate.d.ts +1 -1
  72. package/dist/types/core/client/composables/DefineWidgets.d.ts +4 -4
  73. package/dist/types/core/client/composables/index.d.ts +24 -2
  74. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +9 -6
  75. package/dist/types/core/client/eodashSTAC/helpers.d.ts +20 -5
  76. package/dist/types/core/client/eodashSTAC/parquet.d.ts +2 -0
  77. package/dist/types/core/client/plugins/vuetify.d.ts +7 -4
  78. package/dist/types/core/client/store/actions.d.ts +3 -2
  79. package/dist/types/core/client/store/stac.d.ts +16 -13
  80. package/dist/types/core/client/store/states.d.ts +14 -4
  81. package/dist/types/core/client/types.d.ts +45 -30
  82. package/dist/types/core/client/utils/index.d.ts +2 -0
  83. package/dist/types/core/client/utils/keys.d.ts +4 -4
  84. package/dist/types/core/client/utils/states.d.ts +59 -47
  85. package/dist/types/core/client/views/Dashboard.vue.d.ts +2 -2
  86. package/dist/types/templates/baseConfig.d.ts +4 -0
  87. package/dist/types/templates/compare.d.ts +210 -0
  88. package/dist/types/templates/expert.d.ts +151 -0
  89. package/dist/types/templates/index.d.ts +6 -0
  90. package/dist/types/templates/light.d.ts +145 -0
  91. package/dist/types/widgets/EodashDatePicker.vue.d.ts +1 -458
  92. package/dist/types/widgets/EodashItemFilter.vue.d.ts +3 -3
  93. package/dist/types/widgets/EodashLayerControl.vue.d.ts +14 -7
  94. package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +1 -3
  95. package/dist/types/widgets/EodashMap/index.vue.d.ts +1 -4
  96. package/dist/types/widgets/EodashMapBtns.vue.d.ts +8 -8
  97. package/dist/types/widgets/EodashProcess/ProcessList.vue.d.ts +8 -1
  98. package/dist/types/widgets/EodashProcess/index.vue.d.ts +8 -4
  99. package/dist/types/widgets/EodashProcess/methods/async.d.ts +18 -18
  100. package/dist/types/widgets/EodashProcess/methods/composables.d.ts +3 -2
  101. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/index.d.ts +1 -0
  102. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.d.ts +6 -0
  103. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.d.ts +4 -0
  104. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +5 -0
  105. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/index.d.ts +1 -0
  106. package/dist/types/widgets/EodashProcess/methods/handling.d.ts +12 -5
  107. package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +72 -41
  108. package/dist/types/widgets/EodashProcess/methods/utils.d.ts +41 -21
  109. package/dist/types/widgets/EodashProcess/states.d.ts +11 -0
  110. package/dist/types/widgets/EodashProcess/types.d.ts +41 -0
  111. package/dist/types/widgets/EodashStacInfo.vue.d.ts +14 -14
  112. package/dist/types/widgets/EodashTools.vue.d.ts +3 -3
  113. package/dist/types/widgets/ExportState.vue.d.ts +1 -1
  114. package/dist/types/widgets/PopUp.vue.d.ts +11 -16
  115. package/dist/types/widgets/WidgetsContainer.vue.d.ts +3 -6
  116. package/package.json +53 -45
  117. package/templates/baseConfig.js +68 -0
  118. package/templates/compare.js +162 -0
  119. package/templates/expert.js +123 -0
  120. package/templates/index.js +8 -0
  121. package/templates/light.js +130 -0
  122. package/widgets/EodashDatePicker.vue +80 -31
  123. package/widgets/EodashItemFilter.vue +26 -11
  124. package/widgets/EodashLayerControl.vue +20 -11
  125. package/widgets/EodashLayoutSwitcher.vue +6 -3
  126. package/widgets/EodashMap/index.vue +3 -8
  127. package/widgets/EodashMap/methods/create-layers-config.js +4 -3
  128. package/widgets/EodashMap/methods/index.js +33 -23
  129. package/widgets/EodashMapBtns.vue +83 -41
  130. package/widgets/EodashProcess/ProcessList.vue +34 -10
  131. package/widgets/EodashProcess/index.vue +55 -20
  132. package/widgets/EodashProcess/methods/async.js +77 -59
  133. package/widgets/EodashProcess/methods/composables.js +21 -14
  134. package/widgets/EodashProcess/methods/custom-endpoints/chart/index.js +35 -0
  135. package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +275 -0
  136. package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +116 -0
  137. package/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.js +94 -0
  138. package/widgets/EodashProcess/methods/custom-endpoints/layers/index.js +33 -0
  139. package/widgets/EodashProcess/methods/handling.js +127 -80
  140. package/widgets/EodashProcess/methods/outputs.js +376 -125
  141. package/widgets/EodashProcess/methods/utils.js +398 -10
  142. package/widgets/EodashProcess/states.js +13 -0
  143. package/widgets/EodashProcess/types.ts +46 -0
  144. package/widgets/EodashStacInfo.vue +2 -17
  145. package/widgets/EodashTools.vue +13 -13
  146. package/widgets/WidgetsContainer.vue +1 -1
  147. package/core/client/eodash.js +0 -454
  148. package/dist/client/EodashLayoutSwitcher-DqeFO3RN.js +0 -52
  149. package/dist/client/EodashMapBtns-5BF27qJB.js +0 -131
  150. package/dist/client/ProcessList-C62SOVO6.js +0 -484
  151. package/dist/client/asWebComponent-BJ2NWunV.js +0 -12479
  152. package/dist/client/eo-dash.css +0 -5
  153. package/dist/client/index-Da5xXX6Q.js +0 -780
  154. package/dist/client/transition-Cdb4K27U.js +0 -37
  155. 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 === "item" && "latlng" in element) {
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
- // TODO: consider datetime ranges
181
- const hasDatetime = links.some((l) => typeof l.datetime === "string");
182
- if (!hasDatetime) {
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.datetime && link.rel === "item") {
192
+ if (link[dateProperty] && link.rel === "item") {
193
193
  vals.push(
194
- new Date(/** @type {string} */ (link.datetime)).toISOString(),
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
- return undefined;
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 {Record<string, any>[]} layers
227
- * @returns {Record<string,any> | undefined}
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.id === layer) {
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 {Record<string,any>[]} currentLayers
251
+ * @param {import("@eox/map").EoxLayer[]} currentLayers
247
252
  * @param {string} oldLayer - id of the layer to be replaced
248
- * @param {Record<string,any>[]} newLayers - array of layers to replace the old layer
249
- * @returns {Record<string,any>[] | undefined}
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.id === oldLayer,
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.id),
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 = async (indicators, layer) => {
288
+ export const getColFromLayer = (indicators, layer) => {
285
289
  // init cols
286
- const collections = await Promise.all(
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.id === collectionId &&
294
- col.links?.some(
295
- (link) => link.rel === "item" && link.href.includes(itemId),
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 = mapElement.layers.find(
56
- (layer) => layer.properties?.id === "AnalysisGroup",
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
- .provide(eodashKey, eodash);
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 {Record<string,any>[]}
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 {Record<string,any>[]}
20
+ * * @returns {import("@eox/map").EoxLayer[]}
19
21
  */
20
- export const getCompareLayers = () => mapCompareEl.value?.layers.toReversed();
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
+ };