@eodash/eodash 5.1.0 → 5.3.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 (133) hide show
  1. package/core/client/components/DashboardLayout.vue +1 -2
  2. package/core/client/components/EodashOverlay.vue +4 -5
  3. package/core/client/components/MobileLayout.vue +42 -21
  4. package/core/client/composables/index.js +54 -60
  5. package/core/client/eodashSTAC/EodashCollection.js +199 -108
  6. package/core/client/eodashSTAC/auth.js +86 -0
  7. package/core/client/eodashSTAC/createLayers.js +234 -4
  8. package/core/client/eodashSTAC/helpers.js +281 -59
  9. package/core/client/eodashSTAC/parquet.js +0 -13
  10. package/core/client/eodashSTAC/triggers.js +1 -1
  11. package/core/client/store/actions.js +14 -0
  12. package/core/client/store/stac.js +46 -8
  13. package/core/client/store/states.js +6 -0
  14. package/core/client/types.ts +206 -3
  15. package/core/client/utils/bands-editor/arithmetic.js +144 -0
  16. package/core/client/utils/bands-editor/colors.js +36 -0
  17. package/core/client/utils/bands-editor/dom.js +196 -0
  18. package/core/client/utils/bands-editor/exampleSchema.json +1320 -0
  19. package/core/client/utils/bands-editor/index.js +68 -0
  20. package/core/client/utils/bands-editor/rgb.js +102 -0
  21. package/core/client/utils/index.js +5 -2
  22. package/core/client/views/Dashboard.vue +1 -1
  23. package/core/client/vite-env.d.ts +122 -0
  24. package/dist/client/{DashboardLayout-ByVs1DrY.js → DashboardLayout-Cq15p4TH.js} +5 -6
  25. package/dist/client/{DynamicWebComponent-C3W7HSQm.js → DynamicWebComponent-Cv-fPRG1.js} +1 -1
  26. package/dist/client/{EodashDatePicker-BIAf1sMT.js → EodashDatePicker-CPlJwEIO.js} +20 -22
  27. package/dist/client/{EodashItemFilter-DPznh8UB.js → EodashItemFilter-Ydebgbjj.js} +46 -31
  28. package/dist/client/EodashLayerControl-COhrkNEs.js +1517 -0
  29. package/dist/client/{EodashLayoutSwitcher-C5qTEffW.js → EodashLayoutSwitcher-pnKhTRZV.js} +4 -4
  30. package/dist/client/EodashMapBtns-Cj0Fx119.js +301 -0
  31. package/dist/client/{EodashStacInfo-CSvvF2jI.js → EodashStacInfo-Dadkg_Nj.js} +1 -1
  32. package/dist/client/EodashTimeSlider-CpoHX0S7.js +53 -0
  33. package/dist/client/{EodashTools-Cv1SXQ5y.js → EodashTools-UGBG7KC9.js} +10 -7
  34. package/dist/client/{ExportState-D-iuwaad.js → ExportState-GtJkAqeZ.js} +145 -121
  35. package/dist/client/{Footer-CyF0zRAk.js → Footer-D3ZPG5c4.js} +1 -1
  36. package/dist/client/{Header-CgD8jDKU.js → Header-z6AK-wpN.js} +2 -3
  37. package/dist/client/MobileLayout-BXNsNftb.js +118 -0
  38. package/dist/client/{PopUp-BsYLvWch.js → PopUp-BbQdjENV.js} +79 -44
  39. package/dist/client/{ProcessList-C2xsLU2_.js → ProcessList-C6VsdsYI.js} +18 -12
  40. package/dist/client/{VImg-OHe8YTs2.js → VImg-CxaMSB99.js} +203 -5
  41. package/dist/client/{VMain-PryTLU4a.js → VMain-Ds7yw0wj.js} +1 -1
  42. package/dist/client/{VTooltip-DZ0fjpB3.js → VTooltip-Cze6CEVh.js} +2 -3
  43. package/dist/client/{WidgetsContainer-B9LBadcC.js → WidgetsContainer-D66bj-JJ.js} +1 -1
  44. package/dist/client/asWebComponent-CWbNRdf9.js +8895 -0
  45. package/dist/client/{async-DkSu_u2K.js → async-BA7oWCMX.js} +69 -5
  46. package/dist/client/easing-CH0-9wR8.js +35 -0
  47. package/dist/client/eo-dash.js +1 -1
  48. package/dist/client/{VOverlay-yUn7p-Uf.js → forwardRefs-BUfxOIo-.js} +308 -28
  49. package/dist/client/{handling-CgmFXkW6.js → handling-DlNTtKB-.js} +27 -6
  50. package/dist/client/{helpers-Dy0Q13tP.js → helpers-CtE0W7iu.js} +595 -278
  51. package/dist/client/{index-skjhlH8u.js → index-CeEZIjO6.js} +26 -13
  52. package/dist/client/{index-Ch_HchK3.js → index-CsKbRDeN.js} +238 -77
  53. package/dist/client/{index-Dqj4tbx2.js → index-D4_NRKrf.js} +2 -2
  54. package/dist/client/index-DeECc3lV.js +571 -0
  55. package/dist/client/material-symbols-outlined.woff2 +0 -0
  56. package/dist/client/material-symbols-rounded.woff2 +0 -0
  57. package/dist/client/material-symbols-sharp.woff2 +0 -0
  58. package/dist/client/material-symbols-subset.woff2 +0 -0
  59. package/dist/client/templates.js +106 -49
  60. package/dist/client/{transition-C98Yn4Vo.js → transition-Byvp3L6Y.js} +1 -1
  61. package/dist/node/cli.js +6 -6
  62. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +24 -10
  63. package/dist/types/core/client/eodashSTAC/auth.d.ts +7 -0
  64. package/dist/types/core/client/eodashSTAC/createLayers.d.ts +15 -3
  65. package/dist/types/core/client/eodashSTAC/helpers.d.ts +51 -15
  66. package/dist/types/core/client/plugins/vuetify.d.ts +14 -14
  67. package/dist/types/core/client/store/actions.d.ts +2 -0
  68. package/dist/types/core/client/store/stac.d.ts +16 -7
  69. package/dist/types/core/client/store/states.d.ts +4 -0
  70. package/dist/types/core/client/types.d.ts +171 -3
  71. package/dist/types/core/client/utils/bands-editor/arithmetic.d.ts +8 -0
  72. package/dist/types/core/client/utils/bands-editor/colors.d.ts +15 -0
  73. package/dist/types/core/client/utils/bands-editor/dom.d.ts +42 -0
  74. package/dist/types/core/client/utils/bands-editor/index.d.ts +20 -0
  75. package/dist/types/core/client/utils/bands-editor/rgb.d.ts +15 -0
  76. package/dist/types/core/client/utils/index.d.ts +1 -1
  77. package/dist/types/templates/baseConfig.d.ts +87 -1
  78. package/dist/types/templates/compare.d.ts +0 -25
  79. package/dist/types/templates/expert.d.ts +17 -21
  80. package/dist/types/templates/explore.d.ts +67 -0
  81. package/dist/types/templates/index.d.ts +1 -1
  82. package/dist/types/templates/{light.d.ts → lite.d.ts} +9 -0
  83. package/dist/types/widgets/EodashItemCatalog/index.vue.d.ts +21 -0
  84. package/dist/types/widgets/EodashItemCatalog/methods/filters.d.ts +49 -0
  85. package/dist/types/widgets/EodashItemCatalog/methods/handlers.d.ts +4 -0
  86. package/dist/types/widgets/EodashItemCatalog/methods/map.d.ts +12 -0
  87. package/dist/types/widgets/EodashItemCatalog/types.d.ts +14 -0
  88. package/dist/types/widgets/{EodashMapBtns.vue.d.ts → EodashMap/EodashMapBtns.vue.d.ts} +6 -0
  89. package/dist/types/widgets/EodashMap/index.vue.d.ts +114 -0
  90. package/dist/types/widgets/EodashMap/methods/create-layers-config.d.ts +1 -1
  91. package/dist/types/widgets/EodashMap/methods/index.d.ts +1 -1
  92. package/dist/types/widgets/EodashProcess/methods/async.d.ts +1 -0
  93. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +1 -1
  94. package/dist/types/widgets/EodashTimeSlider.vue.d.ts +7 -0
  95. package/dist/types/widgets/EodashTools.vue.d.ts +10 -10
  96. package/dist/types/widgets/ExportState.vue.d.ts +2 -0
  97. package/package.json +31 -28
  98. package/templates/baseConfig.js +10 -5
  99. package/templates/compare.js +2 -22
  100. package/templates/expert.js +19 -18
  101. package/templates/explore.js +62 -0
  102. package/templates/index.js +1 -1
  103. package/templates/{light.js → lite.js} +11 -2
  104. package/widgets/EodashDatePicker.vue +15 -18
  105. package/widgets/EodashItemCatalog/index.vue +161 -0
  106. package/widgets/EodashItemCatalog/methods/filters.js +216 -0
  107. package/widgets/EodashItemCatalog/methods/handlers.js +50 -0
  108. package/widgets/EodashItemCatalog/methods/map.js +144 -0
  109. package/widgets/EodashItemCatalog/types.ts +15 -0
  110. package/widgets/EodashItemFilter.vue +35 -28
  111. package/widgets/EodashLayerControl.vue +10 -6
  112. package/widgets/EodashLayoutSwitcher.vue +1 -1
  113. package/widgets/EodashMap/EodashMapBtns.vue +278 -0
  114. package/widgets/EodashMap/index.vue +263 -38
  115. package/widgets/EodashMap/methods/create-layers-config.js +9 -6
  116. package/widgets/EodashMap/methods/index.js +27 -13
  117. package/widgets/EodashProcess/ProcessList.vue +13 -1
  118. package/widgets/EodashProcess/index.vue +17 -1
  119. package/widgets/EodashProcess/methods/async.js +22 -1
  120. package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +25 -3
  121. package/widgets/EodashProcess/methods/handling.js +2 -0
  122. package/widgets/EodashProcess/methods/outputs.js +1 -0
  123. package/widgets/EodashProcess/methods/utils.js +45 -1
  124. package/widgets/EodashTimeSlider.vue +40 -0
  125. package/widgets/EodashTools.vue +7 -3
  126. package/widgets/ExportState.vue +53 -22
  127. package/dist/client/EodashLayerControl-Bhxjw4V2.js +0 -154
  128. package/dist/client/EodashMapBtns-WoGq8MuV.js +0 -173
  129. package/dist/client/MobileLayout-EKQ_kpSh.js +0 -1226
  130. package/dist/client/asWebComponent-By_7_JjS.js +0 -19193
  131. package/dist/client/forwardRefs-BXxrv98s.js +0 -272
  132. package/dist/client/index-BuhOHXKv.js +0 -199
  133. package/widgets/EodashMapBtns.vue +0 -155
@@ -1,13 +1,17 @@
1
1
  import { registerProjection } from "@/store/actions";
2
2
  import { mapEl } from "@/store/states";
3
+
3
4
  import {
4
5
  extractRoles,
5
6
  getProjectionCode,
6
7
  createLayerID,
7
8
  createAssetID,
8
9
  mergeGeojsons,
10
+ extractLayerConfig,
9
11
  addTooltipInteraction,
12
+ fetchStyle,
10
13
  } from "./helpers";
14
+ import { handleAuthenticationOfLink } from "./auth";
11
15
  import log from "loglevel";
12
16
 
13
17
  /**
@@ -41,7 +45,7 @@ export async function createLayersFromAssets(
41
45
 
42
46
  const geoJsonSources = [];
43
47
  let geoJsonRoles = {};
44
-
48
+ let projection = undefined;
45
49
  for (const [idx, ast] of Object.keys(assets).entries()) {
46
50
  // register projection if exists
47
51
  const assetProjection =
@@ -49,6 +53,7 @@ export async function createLayersFromAssets(
49
53
  assets[ast]?.["proj:epsg"] || assets[ast]?.["eodash:proj4_def"]
50
54
  );
51
55
  await registerProjection(assetProjection);
56
+ projection = getProjectionCode(assetProjection) || "EPSG:4326";
52
57
  if (assets[ast]?.type === "application/geo+json") {
53
58
  geoJsonSources.push(assets[ast].href);
54
59
  geoJsonIdx = idx;
@@ -64,7 +69,7 @@ export async function createLayersFromAssets(
64
69
  source: {
65
70
  type: "FlatGeoBuf",
66
71
  url: assets[ast].href,
67
- format: "GeoJSON",
72
+ projection,
68
73
  attributions: assets[ast].attribution,
69
74
  },
70
75
  properties: {
@@ -95,19 +100,49 @@ export async function createLayersFromAssets(
95
100
  url: assets[ast].href,
96
101
  attributions: assets[ast].attribution,
97
102
  });
103
+ } else if (assets[ast]?.type === "application/geodb+json") {
104
+ const responseData = await (await fetch(assets[ast].href)).json();
105
+ if (
106
+ !responseData ||
107
+ !Array.isArray(responseData) ||
108
+ responseData.length === 0
109
+ ) {
110
+ console.error(
111
+ "[eodash] GeoDB response data is not in expected format",
112
+ responseData,
113
+ );
114
+ continue;
115
+ }
116
+ const features = responseData.map((item) => {
117
+ return {
118
+ type: "Feature",
119
+ geometry: item.geometry,
120
+ // we pass the item making sure to remove geometry to avoid duplication
121
+ properties: { ...item, geometry: undefined },
122
+ };
123
+ });
124
+ const geojson = {
125
+ type: "FeatureCollection",
126
+ features: features,
127
+ };
128
+ geoJsonSources.push(
129
+ encodeURI(
130
+ "data:application/json;charset=utf-8," + JSON.stringify(geojson),
131
+ ),
132
+ );
98
133
  }
99
134
  }
100
135
 
101
136
  if (geoJsonSources.length) {
102
137
  const assetId = createAssetID(collectionId, item.id, geoJsonIdx);
103
138
  log.debug(`Creating Vector layer from GeoJsons`, assetId);
104
-
139
+ // assumption that each GeoJSON asset is in same projection due to their merging
105
140
  const layer = {
106
141
  type: "Vector",
107
142
  source: {
108
143
  type: "Vector",
109
144
  url: await mergeGeojsons(geoJsonSources),
110
- format: "GeoJSON",
145
+ format: {"type": "GeoJSON", "dataProjection": projection},
111
146
  attributions: geoJsonAttributions,
112
147
  },
113
148
  properties: {
@@ -163,6 +198,7 @@ export async function createLayersFromAssets(
163
198
  * @param {string} collectionId
164
199
  * @param {import('stac-ts').StacItem} item
165
200
  * @param {string} title
201
+ * @param {string} itemUrl
166
202
  * @param {Record<string,any>} [layerDatetime]
167
203
  * @param {object | null} [extraProperties]
168
204
  */
@@ -170,6 +206,7 @@ export const createLayersFromLinks = async (
170
206
  collectionId,
171
207
  title,
172
208
  item,
209
+ itemUrl,
173
210
  layerDatetime,
174
211
  extraProperties,
175
212
  ) => {
@@ -179,6 +216,7 @@ export const createLayersFromLinks = async (
179
216
  const wmsArray = item.links.filter((l) => l.rel === "wms");
180
217
  const wmtsArray = item.links.filter((l) => l.rel === "wmts");
181
218
  const xyzArray = item.links.filter((l) => l.rel === "xyz") ?? [];
219
+ const vectorTileArray = item.links.filter((l) => l.rel === "vector-tile") ?? [];
182
220
 
183
221
  // Taking projection code from main map view, as main view defines
184
222
  // projection for comparison map
@@ -368,5 +406,197 @@ export const createLayersFromLinks = async (
368
406
  }
369
407
  jsonArray.push(json);
370
408
  }
409
+
410
+ for (const vectorTileLink of vectorTileArray ?? []) {
411
+ const vectorTileLinkProjection =
412
+ /** @type {number | string | {name: string, def: string} | undefined} */
413
+ (vectorTileLink?.["proj:epsg"] || vectorTileLink?.["eodash:proj4_def"]);
414
+
415
+ await registerProjection(vectorTileLinkProjection);
416
+ const projectionCode = getProjectionCode(vectorTileLinkProjection || "EPSG:3857");
417
+ const linkId = createLayerID(
418
+ collectionId,
419
+ item.id,
420
+ vectorTileLink,
421
+ viewProjectionCode,
422
+ );
423
+ log.debug("Vector Tile Layer added", linkId);
424
+ const key = /** @type {string | undefined} */ (vectorTileLink["key"]) || undefined;
425
+ // fetch styles and separate them by their mapping between links and assets
426
+ const styles = await fetchStyle(item, itemUrl, key);
427
+ // get the correct style which is not attached to a link
428
+ let { layerConfig, style } = extractLayerConfig(
429
+ linkId ?? "",
430
+ styles,
431
+ );
432
+
433
+ let href = vectorTileLink.href;
434
+ if ("auth:schemes" in item && "auth:refs" in vectorTileLink) {
435
+ href = handleAuthenticationOfLink(/** @type { import("@/types").StacAuthItem} */ (item), /** @type { import("@/types").StacAuthLink} */ (vectorTileLink));
436
+ }
437
+ const json = {
438
+ type: "VectorTile",
439
+ declutter: true,
440
+ properties: {
441
+ id: linkId,
442
+ title: vectorTileLink.title || title || item.id,
443
+ roles: vectorTileLink.roles,
444
+ layerDatetime,
445
+ ...(layerConfig && {
446
+ layerConfig: {
447
+ ...layerConfig,
448
+ style,
449
+ },
450
+ }),
451
+ },
452
+ source: {
453
+ type: "VectorTile",
454
+ format: {
455
+ type: "MVT",
456
+ idProperty: vectorTileLink.idProperty,
457
+ },
458
+ url: href,
459
+ projection: projectionCode,
460
+ attributions: vectorTileLink.attribution,
461
+ },
462
+ interactions: [],
463
+ ...(!style?.variables && { style }),
464
+ };
465
+ addTooltipInteraction(json, style);
466
+ extractRoles(json.properties, vectorTileLink);
467
+ if (extraProperties !== null) {
468
+ json.properties = { ...json.properties, ...extraProperties };
469
+ }
470
+ jsonArray.push(json);
471
+ }
371
472
  return jsonArray;
372
473
  };
474
+ /**
475
+ * Implementation of a function that creates a layer from the render extention
476
+ * @param {import("stac-ts").StacCollection | undefined | null} collection
477
+ * @param {import("stac-ts").StacItem | undefined | null} item
478
+ * @param {string} rasterURL
479
+ * @param {Record<string, any>} [extraProperties]
480
+ * @returns {import("@eox/map/src/layers").EOxLayerType<"Tile","XYZ">[]}
481
+ */
482
+ export function createLayerFromRender(
483
+ rasterURL,
484
+ collection,
485
+ item,
486
+ extraProperties,
487
+ ) {
488
+ if (!collection || !collection.renders || !item) {
489
+ return [];
490
+ }
491
+
492
+ const renders = /** @type {Record<string,import("@/types").Render>} */ (
493
+ collection.renders ?? item?.renders
494
+ );
495
+ const layers = [];
496
+ // special case for rescale
497
+ for (const key in renders) {
498
+ const title = renders[key].title;
499
+
500
+ const assetsCollection =
501
+ renders[key].assets[0] in item["assets"] ? item : collection;
502
+
503
+ const paramsObject = {
504
+ assets: renders[key].assets,
505
+ expression:
506
+ renders[key].expression ??
507
+ assetsCollection["assets"]?.[renders[key].assets[0]]?.expression,
508
+ nodata:
509
+ renders[key].nodata ??
510
+ assetsCollection["assets"]?.[renders[key].assets[0]]?.nodata,
511
+ resampling:
512
+ renders[key].resampling ??
513
+ assetsCollection["assets"]?.[renders[key].assets[0]]?.resampling,
514
+ color_formula:
515
+ renders[key].color_formula ??
516
+ assetsCollection["assets"]?.[renders[key].assets[0]]?.color_formula,
517
+ colormap:
518
+ renders[key].colormap ??
519
+ assetsCollection["assets"]?.[renders[key].assets[0]]?.colormap,
520
+ colormap_name:
521
+ renders[key].colormap_name ??
522
+ assetsCollection["assets"]?.[renders[key].assets[0]]?.colormap_name,
523
+ rescale:
524
+ renders[key].rescale ??
525
+ assetsCollection["assets"]?.[renders[key].assets[0]]?.rescale,
526
+ };
527
+ const paramsStr = encodeURLObject(paramsObject);
528
+ const url = `${rasterURL}/collections/${collection.id}/items/${item.id}/tiles/WebMercatorQuad/{z}/{x}/{y}?${paramsStr}`;
529
+ layers.push({
530
+ /** @type {"Tile"} */
531
+ type: "Tile",
532
+ properties: {
533
+ id: createLayerID(
534
+ collection.id,
535
+ item.id,
536
+ { id: item.id, href: "", title, rel: "" },
537
+ "EPSG:3857",
538
+ ),
539
+ title,
540
+ roles: item.roles,
541
+ ...extraProperties,
542
+ },
543
+ source: {
544
+ /** @type {"XYZ"} */
545
+ type: "XYZ",
546
+ url,
547
+ projection: "EPSG:3857",
548
+ },
549
+ });
550
+ }
551
+
552
+ return layers;
553
+ }
554
+ /**
555
+ *
556
+ * @param {Record<string,any>} obj
557
+ * @returns {string}
558
+ */
559
+ function encodeURLObject(obj) {
560
+ let str = "";
561
+ for (const key in obj) {
562
+ const value = obj[key];
563
+ if (value === null || value === undefined || value === "") {
564
+ continue;
565
+ }
566
+
567
+ const valueType = Array.isArray(value) ? "array" : typeof value;
568
+
569
+ switch (valueType) {
570
+ case "array": {
571
+ // Check if any element in the array is itself an array (multi-dimensional)
572
+ const hasNestedArrays = value.some((/** @type {any} */ item) =>
573
+ Array.isArray(item),
574
+ );
575
+
576
+ if (hasNestedArrays) {
577
+ // For multi-dimensional arrays, repeat the key with different values
578
+ for (const val of value) {
579
+ if (Array.isArray(val)) {
580
+ str += `${key}=${val.join(",")}&`;
581
+ } else {
582
+ str += `${key}=${val}&`;
583
+ }
584
+ }
585
+ } else {
586
+ // For simple arrays, join with commas
587
+ str += `${key}=${value.join(",")}&`;
588
+ }
589
+ break;
590
+ }
591
+ case "object": {
592
+ str += `${key}=${encodeURI(JSON.stringify(value))}&`;
593
+ break;
594
+ }
595
+ default: {
596
+ str += `${key}=${encodeURIComponent(value)}&`;
597
+ break;
598
+ }
599
+ }
600
+ }
601
+ return str;
602
+ }