@eodash/eodash 5.0.0-processing → 5.0.0-rc.1

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 (112) hide show
  1. package/core/client/asWebComponent.js +2 -3
  2. package/core/client/components/DashboardLayout.vue +35 -17
  3. package/core/client/components/Loading.vue +6 -9
  4. package/core/client/components/MobileLayout.vue +16 -14
  5. package/core/client/composables/DefineEodash.js +13 -3
  6. package/core/client/composables/DefineTemplate.js +67 -0
  7. package/core/client/composables/DefineWidgets.js +3 -2
  8. package/core/client/composables/EodashMap.js +23 -12
  9. package/core/client/composables/EodashProcess.js +10 -11
  10. package/core/client/composables/index.js +35 -10
  11. package/core/client/eodash.js +381 -139
  12. package/core/client/{utils/eodashSTAC.js → eodashSTAC/EodashCollection.js} +75 -42
  13. package/core/client/{utils → eodashSTAC}/createLayers.js +10 -8
  14. package/core/client/{utils → eodashSTAC}/helpers.js +45 -68
  15. package/core/client/eodashSTAC/triggers.js +43 -0
  16. package/core/client/plugins/vuetify.js +2 -1
  17. package/core/client/store/{Actions.js → actions.js} +16 -2
  18. package/core/client/store/index.js +4 -18
  19. package/core/client/store/stac.js +4 -4
  20. package/core/client/store/{States.js → states.js} +2 -0
  21. package/{dist/types/core/client/types.d.ts → core/client/types.ts} +47 -8
  22. package/core/client/utils/states.js +8 -3
  23. package/core/client/views/Dashboard.vue +6 -4
  24. package/core/client/vite-env.d.ts +1 -1
  25. package/dist/client/{DashboardLayout-CVMJ4l8M.js → DashboardLayout-FS5inBIm.js} +12 -15
  26. package/dist/client/{DynamicWebComponent-Cv8n457T.js → DynamicWebComponent-CBSgT677.js} +1 -1
  27. package/dist/client/{EodashDatePicker-VVkiPmpc.js → EodashDatePicker-BGSS2ZYK.js} +75 -163
  28. package/dist/client/EodashItemFilter-CFNKjm_Z.js +151 -0
  29. package/dist/client/{EodashLayerControl-53WghA8G.js → EodashLayerControl-CzffoPUs.js} +17 -7
  30. package/dist/client/EodashLayoutSwitcher-DM0zDhvI.js +52 -0
  31. package/dist/client/{EodashMap-CQnOePpy.js → EodashMap-BdFZ657e.js} +101 -38
  32. package/dist/client/EodashMapBtns-rC_IPD-Z.js +107 -0
  33. package/dist/client/EodashProcess-SLsTISKV.js +714 -0
  34. package/dist/client/EodashStacInfo-DFD0gtWm.js +85 -0
  35. package/dist/client/EodashTools-ImohD2ys.js +103 -0
  36. package/dist/client/{ExportState-BT8MLAW7.js → ExportState-LNZAovzM.js} +13 -13
  37. package/dist/client/{Footer-C6GUG84G.js → Footer-c19dV1ZR.js} +1 -1
  38. package/dist/client/{Header-D2dtCWp8.js → Header-CcvXFqqt.js} +3 -3
  39. package/dist/client/{MobileLayout-BAo8Wr8T.js → MobileLayout-OM6Wc-vj.js} +28 -31
  40. package/dist/client/{PopUp-Bm01q7Ko.js → PopUp-B0_c0207.js} +29 -8
  41. package/dist/client/{VImg-B8AbetCE.js → VImg-BpDhCbL0.js} +2 -2
  42. package/dist/client/{VMain-DnGlQUyr.js → VMain-DC05bDwX.js} +1 -1
  43. package/dist/client/{VOverlay-B8Qj7LRG.js → VOverlay-C7EUyVe_.js} +3 -3
  44. package/dist/client/VTooltip-C78suika.js +86 -0
  45. package/dist/client/{WidgetsContainer-CwXRRLS1.js → WidgetsContainer-sD1vDnhF.js} +1 -1
  46. package/dist/client/{asWebComponent-DUUoR7MZ.js → asWebComponent-D8bMMCEr.js} +1374 -1052
  47. package/dist/client/{style.css → eo-dash.css} +1 -1
  48. package/dist/client/eo-dash.js +1 -1
  49. package/dist/client/{forwardRefs-CZJhEAKW.js → forwardRefs-yw6tFXER.js} +1 -1
  50. package/dist/client/{index-DlIO7sJ3.js → index-CpK_Yaom.js} +1 -1
  51. package/dist/client/{transition-BiR8wMn1.js → transition-B2YwqAYJ.js} +1 -1
  52. package/dist/node/cli.js +2 -2
  53. package/package.json +48 -37
  54. package/widgets/EodashDatePicker.vue +68 -54
  55. package/widgets/EodashItemFilter.vue +60 -105
  56. package/widgets/EodashLayerControl.vue +17 -4
  57. package/widgets/EodashLayoutSwitcher.vue +36 -0
  58. package/widgets/EodashMap.vue +26 -27
  59. package/widgets/EodashMapBtns.vue +41 -4
  60. package/widgets/EodashProcess.vue +4 -12
  61. package/widgets/EodashStacInfo.vue +82 -0
  62. package/widgets/EodashTools.vue +83 -0
  63. package/widgets/ExportState.vue +12 -12
  64. package/widgets/PopUp.vue +24 -2
  65. package/core/client/asWebComponent.d.ts +0 -23
  66. package/core/client/types.d.ts +0 -279
  67. package/dist/client/EodashItemFilter-CugWNQ86.js +0 -194
  68. package/dist/client/EodashMapBtns-uaRwFtfB.js +0 -66
  69. package/dist/client/EodashProcess-cF0unIy8.js +0 -1477
  70. package/dist/types/core/client/App.vue.d.ts +0 -7
  71. package/dist/types/core/client/asWebComponent.d.ts +0 -9
  72. package/dist/types/core/client/components/DashboardLayout.vue.d.ts +0 -2
  73. package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +0 -18
  74. package/dist/types/core/client/components/ErrorAlert.vue.d.ts +0 -2
  75. package/dist/types/core/client/components/Footer.vue.d.ts +0 -2
  76. package/dist/types/core/client/components/Header.vue.d.ts +0 -2
  77. package/dist/types/core/client/components/IframeWrapper.vue.d.ts +0 -7
  78. package/dist/types/core/client/components/Loading.vue.d.ts +0 -2
  79. package/dist/types/core/client/components/MobileLayout.vue.d.ts +0 -2
  80. package/dist/types/core/client/composables/DefineEodash.d.ts +0 -2
  81. package/dist/types/core/client/composables/DefineTemplate.d.ts +0 -15
  82. package/dist/types/core/client/composables/DefineWidgets.d.ts +0 -14
  83. package/dist/types/core/client/composables/EodashMap.d.ts +0 -5
  84. package/dist/types/core/client/composables/index.d.ts +0 -30
  85. package/dist/types/core/client/eodash.d.ts +0 -8
  86. package/dist/types/core/client/main.d.ts +0 -2
  87. package/dist/types/core/client/plugins/axios.d.ts +0 -2
  88. package/dist/types/core/client/plugins/index.d.ts +0 -3
  89. package/dist/types/core/client/plugins/vuetify.d.ts +0 -82
  90. package/dist/types/core/client/render.d.ts +0 -1
  91. package/dist/types/core/client/store/Actions.d.ts +0 -12
  92. package/dist/types/core/client/store/States.d.ts +0 -22
  93. package/dist/types/core/client/store/index.d.ts +0 -2
  94. package/dist/types/core/client/store/stac.d.ts +0 -25
  95. package/dist/types/core/client/utils/createLayers.d.ts +0 -45
  96. package/dist/types/core/client/utils/eodashSTAC.d.ts +0 -82
  97. package/dist/types/core/client/utils/helpers.d.ts +0 -84
  98. package/dist/types/core/client/utils/index.d.ts +0 -2
  99. package/dist/types/core/client/utils/keys.d.ts +0 -6
  100. package/dist/types/core/client/utils/states.d.ts +0 -14
  101. package/dist/types/core/client/views/Dashboard.vue.d.ts +0 -9
  102. package/dist/types/widgets/EodashDatePicker.vue.d.ts +0 -7
  103. package/dist/types/widgets/EodashItemFilter.vue.d.ts +0 -42
  104. package/dist/types/widgets/EodashLayerControl.vue.d.ts +0 -11
  105. package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +0 -9
  106. package/dist/types/widgets/EodashMap.vue.d.ts +0 -7
  107. package/dist/types/widgets/EodashMapBtns.vue.d.ts +0 -11
  108. package/dist/types/widgets/EodashStacInfo.vue.d.ts +0 -21
  109. package/dist/types/widgets/EodashTools.vue.d.ts +0 -15
  110. package/dist/types/widgets/ExportState.vue.d.ts +0 -7
  111. package/dist/types/widgets/PopUp.vue.d.ts +0 -22
  112. package/dist/types/widgets/WidgetsContainer.vue.d.ts +0 -7
@@ -13,7 +13,7 @@ import {
13
13
  getLayers,
14
14
  getCompareLayers,
15
15
  registerProjection,
16
- } from "@/store/Actions";
16
+ } from "@/store/actions";
17
17
  import { createLayersFromAssets, createLayersFromLinks } from "./createLayers";
18
18
  import axios from "@/plugins/axios";
19
19
  import log from "loglevel";
@@ -24,11 +24,6 @@ export class EodashCollection {
24
24
  /** @type {import("stac-ts").StacCollection | undefined} */
25
25
  #collectionStac;
26
26
 
27
- // read only
28
- get collectionStac() {
29
- return this.#collectionStac;
30
- }
31
-
32
27
  /**
33
28
  * @type {import("stac-ts").StacLink
34
29
  * | import("stac-ts").StacItem
@@ -36,6 +31,11 @@ export class EodashCollection {
36
31
  */
37
32
  selectedItem;
38
33
 
34
+ // read only
35
+ get collectionStac() {
36
+ return this.#collectionStac;
37
+ }
38
+
39
39
  /** @param {string} collectionUrl */
40
40
  constructor(collectionUrl) {
41
41
  this.#collectionUrl = collectionUrl;
@@ -84,9 +84,7 @@ export class EodashCollection {
84
84
  this.selectedItem = this.getItem();
85
85
 
86
86
  if (this.selectedItem) {
87
- layersJson = /** @type {Record<string,any>[]} */ (
88
- await this.createLayersJson(this.selectedItem)
89
- );
87
+ layersJson = await this.createLayersJson(this.selectedItem);
90
88
  } else {
91
89
  console.warn(
92
90
  "[eodash] the selected collection does not include any items",
@@ -112,7 +110,7 @@ export class EodashCollection {
112
110
  * @param {string} title
113
111
  * @param {boolean} isGeoDB
114
112
  * @param {string} [itemDatetime]
115
- * @returns {Promise<Record<string,any>[]>} arrays
113
+ * @returns {Promise<Record<string,any>[]>} layers
116
114
  * */
117
115
  async buildJsonArray(item, itemUrl, title, isGeoDB, itemDatetime) {
118
116
  log.debug(
@@ -136,30 +134,8 @@ export class EodashCollection {
136
134
  const jsonArray = [];
137
135
 
138
136
  if (isGeoDB) {
139
- const allFeatures = generateFeatures(this.#collectionStac?.links);
140
-
141
- return [
142
- {
143
- type: "Vector",
144
- properties: {
145
- id: this.#collectionStac?.id ?? "",
146
- title: this.#collectionStac?.title || item.id,
147
- },
148
- source: {
149
- type: "Vector",
150
- url: "data:," + encodeURIComponent(JSON.stringify(allFeatures)),
151
- format: "GeoJSON",
152
- },
153
- style: {
154
- "circle-radius": 5,
155
- "circle-fill-color": "#00417077",
156
- "circle-stroke-color": "#004170",
157
- "fill-color": "#00417077",
158
- "stroke-color": "#004170",
159
- },
160
- interactions: [],
161
- },
162
- ];
137
+ // handled by getGeoDBLayer
138
+ return [];
163
139
  }
164
140
 
165
141
  // I propose following approach, we "manually" create configurations
@@ -192,7 +168,7 @@ export class EodashCollection {
192
168
  let extraProperties = null;
193
169
  if (this.#collectionStac?.assets?.legend?.href) {
194
170
  extraProperties = {
195
- description: `<div style="text-align:center; width: 100%">
171
+ description: `<div style="width: 100%">
196
172
  <img src="${this.#collectionStac.assets.legend.href}" style="max-height:70px; margin-top:-15px; margin-bottom:-20px;" />
197
173
  </div>`,
198
174
  };
@@ -346,14 +322,14 @@ export class EodashCollection {
346
322
  currentLayers = getCompareLayers();
347
323
  }
348
324
 
349
- const oldLayer = findLayer(currentLayers, layer);
325
+ /** @type {string | undefined} */
326
+ const oldLayerID = findLayer(currentLayers, layer)?.properties.id;
350
327
 
351
- const updatedLayers = replaceLayer(
352
- currentLayers,
353
- /** @type {Record<string,any> & { properties:{ id:string; title:string } } } */
354
- (oldLayer),
355
- newLayers,
356
- );
328
+ if (!oldLayerID) {
329
+ return;
330
+ }
331
+
332
+ const updatedLayers = replaceLayer(currentLayers, oldLayerID, newLayers);
357
333
 
358
334
  return updatedLayers;
359
335
  }
@@ -396,4 +372,61 @@ export class EodashCollection {
396
372
  )),
397
373
  ];
398
374
  }
375
+
376
+ /**
377
+ * Returns GeoDB layer from a list of EodashCollections
378
+ *
379
+ * @param {EodashCollection[]} eodashCollections
380
+ *
381
+ **/
382
+ static getGeoDBLayer(eodashCollections) {
383
+ const allFeatures = [];
384
+ for (const collection of eodashCollections) {
385
+ const isGeoDB = collection.#collectionStac?.endpointtype === "GeoDB";
386
+ if (!isGeoDB) {
387
+ continue;
388
+ }
389
+ const collectionFeatures = generateFeatures(
390
+ collection.#collectionStac?.links,
391
+ ).features;
392
+ if (collectionFeatures.length) {
393
+ allFeatures.push(
394
+ generateFeatures(collection.#collectionStac?.links).features,
395
+ );
396
+ }
397
+ }
398
+ if (allFeatures.length) {
399
+ const featureCollection = {
400
+ type: "FeatureCollection",
401
+ crs: {
402
+ type: "name",
403
+ properties: {
404
+ name: "EPSG:4326",
405
+ },
406
+ },
407
+ features: allFeatures.flat(),
408
+ };
409
+ return {
410
+ type: "Vector",
411
+ properties: {
412
+ id: "geodb-collection",
413
+ title: "GeoDB Collection",
414
+ },
415
+ source: {
416
+ type: "Vector",
417
+ url: "data:," + encodeURIComponent(JSON.stringify(featureCollection)),
418
+ format: "GeoJSON",
419
+ },
420
+ style: {
421
+ "circle-radius": 5,
422
+ "circle-fill-color": "#00417077",
423
+ "circle-stroke-color": "#004170",
424
+ "fill-color": "#00417077",
425
+ "stroke-color": "#004170",
426
+ },
427
+ interactions: [],
428
+ };
429
+ }
430
+ return null;
431
+ }
399
432
  }
@@ -1,5 +1,5 @@
1
- import { registerProjection } from "@/store/Actions";
2
- import { mapEl } from "@/store/States";
1
+ import { registerProjection } from "@/store/actions";
2
+ import { mapEl } from "@/store/states";
3
3
  import {
4
4
  extractRoles,
5
5
  getProjectionCode,
@@ -65,10 +65,11 @@ export async function createLayersFromAssets(
65
65
  },
66
66
  ...(!style?.variables && { style }),
67
67
  };
68
+
68
69
  extractRoles(layer.properties, assets[ast]);
69
- if (extraProperties !== null) {
70
- layer.properties = { ...layer.properties, ...extraProperties };
71
- }
70
+
71
+ layer.properties = { ...layer.properties, ...(extraProperties ?? {}) };
72
+
72
73
  jsonArray.push(layer);
73
74
  } else if (assets[ast]?.type === "image/tiff") {
74
75
  geoTIFFIdx = idx;
@@ -96,7 +97,7 @@ export async function createLayersFromAssets(
96
97
  },
97
98
  style,
98
99
  };
99
- if (extraProperties !== null) {
100
+ if (extraProperties) {
100
101
  layer.properties = { ...layer.properties, ...extraProperties };
101
102
  }
102
103
  jsonArray.push(layer);
@@ -150,10 +151,11 @@ export const createLayersFromLinks = async (
150
151
  viewProjectionCode,
151
152
  );
152
153
  log.debug("WMS Layer added", linkId);
153
- const tileSize =
154
+ const tileSize = /** @type {number[]} */ (
154
155
  "wms:tilesize" in wmsLink
155
156
  ? [wmsLink["wms:tilesize"], wmsLink["wms:tilesize"]]
156
- : [512, 512];
157
+ : [512, 512]
158
+ );
157
159
  let json = {
158
160
  type: "Tile",
159
161
  properties: {
@@ -1,5 +1,3 @@
1
- import { changeMapProjection, registerProjection } from "@/store/Actions";
2
- import { availableMapProjection } from "@/store/States";
3
1
  import { toAbsolute } from "stac-js/src/http.js";
4
2
  import axios from "@/plugins/axios";
5
3
  import log from "loglevel";
@@ -38,7 +36,10 @@ export function generateFeatures(links) {
38
36
  return geojsonObject;
39
37
  }
40
38
 
41
- /** @param { import("ol/layer/WebGLTile").Style & { jsonform?: Record<string,any> } & { legend?: Record<string,any> } } [style] */
39
+ /**
40
+ * Sperates and extracts layerConfig (jsonform schema & legend) from a style json
41
+ *
42
+ * @param { import("ol/layer/WebGLTile").Style & { jsonform?: Record<string,any> } & { legend?: Record<string,any> } } [style] */
42
43
  export function extractLayerConfig(style) {
43
44
  /** @type {Record<string,unknown> | undefined} */
44
45
  let layerConfig = undefined;
@@ -59,42 +60,6 @@ export function extractLayerConfig(style) {
59
60
  return { layerConfig, style };
60
61
  }
61
62
 
62
- /**
63
- * checks if there's a projection on the Collection and
64
- * updates {@link availableMapProjection}
65
- * @param {import('stac-ts').StacCollection} [STAcCollection]
66
- */
67
- export const setMapProjFromCol = async (STAcCollection) => {
68
- // if a projection exists on the collection level
69
- log.debug("Checking for available map projection in indicator");
70
- const projection =
71
- /** @type {number | string | {name: string, def: string} | undefined} */
72
- (
73
- STAcCollection?.["eodash:mapProjection"] ||
74
- STAcCollection?.["proj:epsg"] ||
75
- STAcCollection?.["eodash:proj4_def"]
76
- );
77
- if (projection) {
78
- log.debug("Projection found", projection);
79
- await registerProjection(projection);
80
- const projectionCode = getProjectionCode(projection);
81
- if (availableMapProjection.value !== projectionCode) {
82
- log.debug(
83
- "Changing map projection",
84
- availableMapProjection.value,
85
- projectionCode,
86
- );
87
- await changeMapProjection(projection);
88
- }
89
- // set it for `EodashMapBtns`
90
- availableMapProjection.value = /** @type {string} */ (projectionCode);
91
- } else {
92
- // reset to default projection
93
- log.debug("Resetting projection to default EPSG:3857");
94
- await changeMapProjection((availableMapProjection.value = ""));
95
- }
96
- };
97
-
98
63
  /**
99
64
  * Function to extract collection urls from an indicator
100
65
  * @param {import("stac-ts").StacCatalog
@@ -103,25 +68,24 @@ export const setMapProjFromCol = async (STAcCollection) => {
103
68
  * | null
104
69
  * } stacObject
105
70
  * @param {string} basepath
106
- * @returns {string[]}
107
71
  */
108
72
  export function extractCollectionUrls(stacObject, basepath) {
73
+ /** @type {string[]} */
109
74
  const collectionUrls = [];
110
75
  // Support for two structure types, flat and indicator, simplified here:
111
76
  // Flat assumes Catalog-Collection-Item
112
77
  // Indicator assumes Catalog-Collection-Collection-Item
113
- // TODO: this is not the most stable test approach,
114
- // we should discuss potential other approaches
115
- if (stacObject?.links && stacObject?.links[1]?.rel === "item") {
78
+
79
+ const children = stacObject?.links?.filter(
80
+ (link) => link.rel === "child" && link.type?.includes("json"),
81
+ );
82
+ if (!children?.length) {
116
83
  collectionUrls.push(basepath);
117
- } else if (stacObject?.links[1]?.rel === "child") {
118
- // TODO: Iterate through all children to create collections
119
- stacObject.links.forEach((link) => {
120
- if (link.rel === "child") {
121
- collectionUrls.push(toAbsolute(link.href, basepath));
122
- }
123
- });
84
+ return collectionUrls;
124
85
  }
86
+ children.forEach((link) => {
87
+ collectionUrls.push(toAbsolute(link.href, basepath));
88
+ });
125
89
  return collectionUrls;
126
90
  }
127
91
 
@@ -138,11 +102,6 @@ export const extractRoles = (properties, linkOrAsset) => {
138
102
  }
139
103
  if (role === "overlay" || role === "baselayer") {
140
104
  properties.group = role;
141
- //remove all the properties and replace the random ID with baselayer
142
- // provided ID
143
- // const [_colId, _itemId, _isAsset, _random, proj] =
144
- // properties.id.split(";:;");
145
- // properties.id = ["", "", "", "", linkOrAsset.id, proj].join(";:;");
146
105
  }
147
106
 
148
107
  return properties;
@@ -150,8 +109,10 @@ export const extractRoles = (properties, linkOrAsset) => {
150
109
  };
151
110
 
152
111
  /**
112
+ * Extracts style JSON from a STAC Item
153
113
  * @param {import("stac-ts").StacItem} item
154
114
  * @param {string} itemUrl
115
+ * @returns
155
116
  **/
156
117
  export const fetchStyle = async (item, itemUrl) => {
157
118
  const styleLink = item.links.find((link) => link.rel.includes("style"));
@@ -192,6 +153,7 @@ export const getProjectionCode = (projection) => {
192
153
  };
193
154
 
194
155
  /**
156
+ * Extracts layercontrol LayerDatetime property from STAC Links
195
157
  * @param {import("stac-ts").StacLink[]} [links]
196
158
  * @param {string|null} [currentStep]
197
159
  **/
@@ -201,6 +163,7 @@ export const extractLayerDatetime = (links, currentStep) => {
201
163
  }
202
164
 
203
165
  // check if links has a datetime value
166
+ // TODO: consider datetime ranges
204
167
  const hasDatetime = links.some((l) => typeof l.datetime === "string");
205
168
  if (!hasDatetime) {
206
169
  return undefined;
@@ -237,12 +200,13 @@ export const extractLayerDatetime = (links, currentStep) => {
237
200
  controlValues,
238
201
  currentStep,
239
202
  slider: true,
240
- disablePlay: true,
203
+ play: false,
204
+ displayFormat: "DD MMMM YYYY",
241
205
  };
242
206
  };
243
207
 
244
208
  /**
245
- * Find layer by ID
209
+ * Find JSON layer by ID
246
210
  * @param {string} layer
247
211
  * @param {Record<string, any>[]} layers
248
212
  * @returns {Record<string,any> | undefined}
@@ -263,16 +227,24 @@ export const findLayer = (layers, layer) => {
263
227
  };
264
228
 
265
229
  /**
230
+ * Removes the layer with the id provided and injects an array of layers in its position
266
231
  * @param {Record<string,any>[]} currentLayers
267
- * @param {Record<string,any>} oldLayer
268
- * @param {Record<string,any>[]} newLayers
232
+ * @param {string} oldLayer - id of the layer to be replaced
233
+ * @param {Record<string,any>[]} newLayers - array of layers to replace the old layer
269
234
  * @returns {Record<string,any>[] | undefined}
270
235
  */
271
236
  export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
272
237
  const oldLayerIdx = currentLayers.findIndex(
273
- (l) => l.properties.id === oldLayer.properties.id,
238
+ (l) => l.properties.id === oldLayer,
274
239
  );
240
+
275
241
  if (oldLayerIdx !== -1) {
242
+ log.debug(
243
+ "Replacing layer",
244
+ oldLayer,
245
+ "with",
246
+ newLayers.map((l) => l.properties.id),
247
+ );
276
248
  currentLayers.splice(oldLayerIdx, 1, ...newLayers);
277
249
  return currentLayers;
278
250
  }
@@ -287,8 +259,11 @@ export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
287
259
  }
288
260
  }
289
261
  };
262
+
290
263
  /**
291
- * @param {import('./eodashSTAC.js').EodashCollection[]} indicators
264
+ * Extracts the STAC collection which the layer was created from.
265
+ *
266
+ * @param {import('../eodashSTAC/EodashCollection.js').EodashCollection[]} indicators
292
267
  * @param {import('ol/layer').Layer} layer
293
268
  */
294
269
  export const getColFromLayer = async (indicators, layer) => {
@@ -304,13 +279,15 @@ export const getColFromLayer = async (indicators, layer) => {
304
279
  col.links?.some(
305
280
  (link) => link.rel === "item" && link.href.includes(itemId),
306
281
  );
307
- return isInd ?? false;
282
+ return isInd;
308
283
  });
309
284
  return indicators.find((ind) => ind.collectionStac?.id === chosen?.id);
310
285
  };
311
286
 
312
287
  /**
313
- * generates layer specific ID, related functions are: {@link assignProjID} & {@link extractRoles}
288
+ * Generates layer specific ID from STAC Links
289
+ * related functions are: {@link assignProjID} & {@link createAssetID}
290
+ *
314
291
  * @param {string} collectionId
315
292
  * @param {string} itemId
316
293
  * @param {import('stac-ts').StacLink} link
@@ -323,9 +300,8 @@ export const createLayerID = (collectionId, itemId, link, projectionCode) => {
323
300
  // If we are looking at base layers and overlays we remove the collection and item part
324
301
  // as we want to make sure tiles are not reloaded when switching layers
325
302
  if (
326
- link.roles &&
327
- // @ts-expect-error it seems roles it not defined for links yet
328
- link.roles.find((r) => ["baselayer", "overlay"].includes(r))
303
+ /** @type {string[]} */
304
+ (link.roles)?.find((r) => ["baselayer", "overlay"].includes(r))
329
305
  ) {
330
306
  lId = `${linkId ?? ""};:;${projectionCode ?? ""}`;
331
307
  }
@@ -334,7 +310,8 @@ export const createLayerID = (collectionId, itemId, link, projectionCode) => {
334
310
  };
335
311
 
336
312
  /**
337
- * generates layer specific ID, related functions are: {@link assignProjID} & {@link extractRoles}
313
+ * Generates layer specific ID from STAC assets, related functions are: {@link assignProjID} & {@link createLayerID}
314
+ *
338
315
  * @param {string} collectionId
339
316
  * @param {string} itemId
340
317
  * @param {number} index
@@ -347,7 +324,7 @@ export const createAssetID = (collectionId, itemId, index) => {
347
324
  };
348
325
 
349
326
  /**
350
- *
327
+ * Assigns projection code to the layer ID
351
328
  * @param {import("stac-ts").StacItem} item
352
329
  * @param {import("stac-ts").StacLink | import("stac-ts").StacAsset} linkOrAsset
353
330
  * @param {string} id - {@link createLayerID} & {@link extractRoles}
@@ -0,0 +1,43 @@
1
+ /*
2
+ * eodashSTAC helpers that utilizes the app states or actions
3
+ */
4
+ import { changeMapProjection, registerProjection } from "@/store/actions";
5
+ import log from "loglevel";
6
+ import { getProjectionCode } from "./helpers";
7
+ import { availableMapProjection } from "@/store/states";
8
+
9
+ /**
10
+ * checks if there's a projection on the Collection and
11
+ * updates {@link availableMapProjection}
12
+ * @param {import('stac-ts').StacCollection} [STAcCollection]
13
+ */
14
+ export const setMapProjFromCol = async (STAcCollection) => {
15
+ // if a projection exists on the collection level
16
+ log.debug("Checking for available map projection in indicator");
17
+ const projection =
18
+ /** @type {number | string | {name: string, def: string} | undefined} */
19
+ (
20
+ STAcCollection?.["eodash:mapProjection"] ||
21
+ STAcCollection?.["proj:epsg"] ||
22
+ STAcCollection?.["eodash:proj4_def"]
23
+ );
24
+ if (projection) {
25
+ log.debug("Projection found", projection);
26
+ await registerProjection(projection);
27
+ const projectionCode = getProjectionCode(projection);
28
+ if (availableMapProjection.value !== projectionCode) {
29
+ log.debug(
30
+ "Changing map projection",
31
+ availableMapProjection.value,
32
+ projectionCode,
33
+ );
34
+ await changeMapProjection(projection);
35
+ }
36
+ // set it for `EodashMapBtns`
37
+ availableMapProjection.value = /** @type {string} */ (projectionCode);
38
+ } else {
39
+ // reset to default projection
40
+ log.debug("Resetting projection to default EPSG:3857");
41
+ await changeMapProjection((availableMapProjection.value = ""));
42
+ }
43
+ };
@@ -8,7 +8,7 @@
8
8
  import "vuetify/styles";
9
9
 
10
10
  import { createVuetify } from "vuetify";
11
- import { mdiChevronLeft, mdiChevronRight, mdiMenuDown } from "@mdi/js";
11
+ import { mdiChevronLeft, mdiChevronRight, mdiMenuDown, mdiPlus } from "@mdi/js";
12
12
 
13
13
  const vuetify = createVuetify({
14
14
  icons: {
@@ -17,6 +17,7 @@ const vuetify = createVuetify({
17
17
  next: [mdiChevronRight],
18
18
  prev: [mdiChevronLeft],
19
19
  subgroup: [mdiMenuDown],
20
+ plus: [mdiPlus],
20
21
  },
21
22
  },
22
23
  theme: {
@@ -1,5 +1,10 @@
1
- import { mapEl, mapCompareEl, registeredProjections } from "@/store/States";
2
- import { getProjectionCode } from "@/utils/helpers";
1
+ import {
2
+ mapEl,
3
+ mapCompareEl,
4
+ registeredProjections,
5
+ activeTemplate,
6
+ } from "@/store/states";
7
+ import { getProjectionCode } from "@/eodashSTAC/helpers";
3
8
  import log from "loglevel";
4
9
 
5
10
  /**
@@ -63,3 +68,12 @@ export const changeMapProjection = async (projection) => {
63
68
  mapEl.value?.setAttribute("projection", code);
64
69
  mapCompareEl.value?.setAttribute("projection", code);
65
70
  };
71
+
72
+ /**
73
+ *
74
+ * @param {string} template
75
+ */
76
+ export const setActiveTemplate = (template) => {
77
+ activeTemplate.value = template;
78
+ log.debug("Setting active template to", template);
79
+ };
@@ -1,20 +1,6 @@
1
1
  //export all actions, states, and pinia stores
2
+ import { useSTAcStore } from "./stac";
3
+ import * as actions from "./actions";
4
+ import * as states from "./states";
2
5
 
3
- const storesImport = import.meta.glob("../store/**.js", { eager: true });
4
-
5
- const store = /** @type {import("@/types").EodashStore} */ (
6
- (() => {
7
- const stores = {};
8
- for (const [filePath, importedstore] of Object.entries(storesImport)) {
9
- const storeType =
10
- filePath.split("/").at(-1)?.slice(0, -3).toLowerCase() ?? "";
11
- if (!["keys"].includes(storeType)) {
12
- //@ts-expect-error `importedstore` cant be typed individually
13
- stores[storeType] = importedstore;
14
- }
15
- }
16
- return stores;
17
- })()
18
- );
19
-
20
- export default store;
6
+ export default { stac: { useSTAcStore }, actions, states };
@@ -3,10 +3,10 @@ import { inject, ref } from "vue";
3
3
  import axios from "@/plugins/axios";
4
4
  import { useAbsoluteUrl, useCompareAbsoluteUrl } from "@/composables/index";
5
5
  import { eodashKey } from "@/utils/keys";
6
- import { indicator } from "@/store/States";
7
- import { extractCollectionUrls } from "@/utils/helpers";
6
+ import { indicator } from "@/store/states";
7
+ import { extractCollectionUrls } from "@/eodashSTAC/helpers";
8
8
  import { eodashCollections, eodashCompareCollections } from "@/utils/states";
9
- import { EodashCollection } from "@/utils/eodashSTAC";
9
+ import { EodashCollection } from "@/eodashSTAC/EodashCollection";
10
10
  import log from "loglevel";
11
11
 
12
12
  export const useSTAcStore = defineStore("stac", () => {
@@ -126,7 +126,7 @@ export const useSTAcStore = defineStore("stac", () => {
126
126
  .get(absoluteUrl.value)
127
127
  .then(async (resp) => {
128
128
  // init eodash collections
129
- const collectionUrls = extractCollectionUrls(
129
+ const collectionUrls = await extractCollectionUrls(
130
130
  resp.data,
131
131
  absoluteUrl.value,
132
132
  );
@@ -33,3 +33,5 @@ export const mapEl = ref(null);
33
33
 
34
34
  /** @type {import("vue").Ref<HTMLElement & Record<string,any> | null>} */
35
35
  export const mapCompareEl = ref(null);
36
+
37
+ export const activeTemplate = ref("");