@eodash/eodash 5.0.0-alpha.2.26 → 5.0.0-alpha.2.27

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 (108) hide show
  1. package/core/client/asWebComponent.js +2 -3
  2. package/core/client/components/DashboardLayout.vue +35 -13
  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 +39 -14
  9. package/core/client/composables/EodashProcess.js +574 -0
  10. package/core/client/composables/index.js +54 -11
  11. package/core/client/eodash.js +383 -125
  12. package/core/client/{utils/eodashSTAC.js → eodashSTAC/EodashCollection.js} +75 -41
  13. package/core/client/{utils → eodashSTAC}/createLayers.js +10 -8
  14. package/core/client/{utils → eodashSTAC}/helpers.js +47 -75
  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/keys.js +2 -0
  23. package/core/client/utils/states.js +8 -3
  24. package/core/client/views/Dashboard.vue +6 -4
  25. package/core/client/vite-env.d.ts +1 -16
  26. package/dist/client/{DashboardLayout-E_JzgCH5.js → DashboardLayout-232tRmjz.js} +23 -25
  27. package/dist/client/{DynamicWebComponent-C9pVUfT3.js → DynamicWebComponent-Cl4LqHU6.js} +1 -1
  28. package/dist/client/{EodashDatePicker-CjU8R2ia.js → EodashDatePicker-Pok6bZwU.js} +78 -165
  29. package/dist/client/EodashItemFilter-16eMMjTV.js +151 -0
  30. package/dist/client/{EodashLayerControl-mKfwru42.js → EodashLayerControl-De7IlCm_.js} +19 -11
  31. package/dist/client/EodashLayoutSwitcher-C-3-jjn5.js +52 -0
  32. package/dist/client/{EodashMap-BpwL82-w.js → EodashMap-CMvbfI6-.js} +116 -39
  33. package/dist/client/EodashMapBtns-BeknGDtc.js +107 -0
  34. package/dist/client/EodashProcess-BwKAa9Ee.js +1476 -0
  35. package/dist/client/EodashStacInfo-_BfonNUG.js +85 -0
  36. package/dist/client/EodashTools-PD3XPYuR.js +103 -0
  37. package/dist/client/{ExportState-ByVuIAQb.js → ExportState-DOrT7M15.js} +5 -5
  38. package/dist/client/{Footer-D691KLtK.js → Footer-CCigxYBo.js} +1 -1
  39. package/dist/client/{Header-B8UBQstf.js → Header-C2cdx4gb.js} +3 -3
  40. package/dist/client/{MobileLayout-6bHjYguI.js → MobileLayout-BdiFjHg7.js} +28 -31
  41. package/dist/client/{PopUp-CdFcnKMY.js → PopUp--_xn1Cms.js} +37 -9
  42. package/dist/client/{VImg-fKGJ7xyb.js → VImg-9xu2l99m.js} +2 -2
  43. package/dist/client/{VMain-Hf5R6yWY.js → VMain-BUs3kDTd.js} +1 -1
  44. package/dist/client/{VOverlay-ClFjEtlD.js → VOverlay-D89omJis.js} +3 -3
  45. package/dist/client/VTooltip-CDu3bErh.js +86 -0
  46. package/dist/client/{WidgetsContainer-XXYJfaPR.js → WidgetsContainer-aFG9yFT6.js} +1 -1
  47. package/dist/client/{asWebComponent-BsbKnhGV.js → asWebComponent-BRGyP_j5.js} +1495 -1142
  48. package/dist/client/{style.css → eo-dash.css} +2 -2
  49. package/dist/client/eo-dash.js +1 -1
  50. package/dist/client/{forwardRefs-I2EA3z3_.js → forwardRefs-CYrR6bMw.js} +1 -1
  51. package/dist/client/{index-B3dnMr8a.js → index-BZwk0V42.js} +1 -1
  52. package/dist/client/{transition-DJ9gfiuP.js → transition-DG9nRSW4.js} +1 -1
  53. package/dist/node/cli.js +3 -3
  54. package/package.json +56 -34
  55. package/widgets/EodashDatePicker.vue +68 -54
  56. package/widgets/EodashItemFilter.vue +60 -105
  57. package/widgets/EodashLayerControl.vue +19 -8
  58. package/widgets/EodashLayoutSwitcher.vue +36 -0
  59. package/widgets/EodashMap.vue +27 -28
  60. package/widgets/EodashMapBtns.vue +41 -4
  61. package/widgets/EodashProcess.vue +143 -0
  62. package/widgets/EodashStacInfo.vue +82 -0
  63. package/widgets/EodashTools.vue +83 -0
  64. package/widgets/ExportState.vue +3 -3
  65. package/widgets/PopUp.vue +24 -2
  66. package/core/client/asWebComponent.d.ts +0 -23
  67. package/core/client/types.d.ts +0 -279
  68. package/dist/client/EodashItemFilter-VGQasaBJ.js +0 -194
  69. package/dist/client/EodashMapBtns-GNNBdBW9.js +0 -66
  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/DefineWidgets.d.ts +0 -14
  82. package/dist/types/core/client/composables/EodashMap.d.ts +0 -5
  83. package/dist/types/core/client/composables/index.d.ts +0 -29
  84. package/dist/types/core/client/eodash.d.ts +0 -8
  85. package/dist/types/core/client/main.d.ts +0 -2
  86. package/dist/types/core/client/plugins/axios.d.ts +0 -2
  87. package/dist/types/core/client/plugins/index.d.ts +0 -3
  88. package/dist/types/core/client/plugins/vuetify.d.ts +0 -82
  89. package/dist/types/core/client/render.d.ts +0 -1
  90. package/dist/types/core/client/store/Actions.d.ts +0 -11
  91. package/dist/types/core/client/store/States.d.ts +0 -21
  92. package/dist/types/core/client/store/index.d.ts +0 -2
  93. package/dist/types/core/client/store/stac.d.ts +0 -25
  94. package/dist/types/core/client/utils/createLayers.d.ts +0 -45
  95. package/dist/types/core/client/utils/eodashSTAC.d.ts +0 -82
  96. package/dist/types/core/client/utils/helpers.d.ts +0 -84
  97. package/dist/types/core/client/utils/index.d.ts +0 -2
  98. package/dist/types/core/client/utils/keys.d.ts +0 -6
  99. package/dist/types/core/client/utils/states.d.ts +0 -14
  100. package/dist/types/core/client/views/Dashboard.vue.d.ts +0 -9
  101. package/dist/types/widgets/EodashDatePicker.vue.d.ts +0 -7
  102. package/dist/types/widgets/EodashItemFilter.vue.d.ts +0 -33
  103. package/dist/types/widgets/EodashLayerControl.vue.d.ts +0 -7
  104. package/dist/types/widgets/EodashMap.vue.d.ts +0 -7
  105. package/dist/types/widgets/EodashMapBtns.vue.d.ts +0 -9
  106. package/dist/types/widgets/ExportState.vue.d.ts +0 -7
  107. package/dist/types/widgets/PopUp.vue.d.ts +0 -14
  108. 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,29 +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
- },
161
- ];
137
+ // handled by getGeoDBLayer
138
+ return [];
162
139
  }
163
140
 
164
141
  // I propose following approach, we "manually" create configurations
@@ -191,7 +168,7 @@ export class EodashCollection {
191
168
  let extraProperties = null;
192
169
  if (this.#collectionStac?.assets?.legend?.href) {
193
170
  extraProperties = {
194
- description: `<div style="text-align:center; width: 100%">
171
+ description: `<div style="width: 100%">
195
172
  <img src="${this.#collectionStac.assets.legend.href}" style="max-height:70px; margin-top:-15px; margin-bottom:-20px;" />
196
173
  </div>`,
197
174
  };
@@ -345,14 +322,14 @@ export class EodashCollection {
345
322
  currentLayers = getCompareLayers();
346
323
  }
347
324
 
348
- const oldLayer = findLayer(currentLayers, layer);
325
+ /** @type {string | undefined} */
326
+ const oldLayerID = findLayer(currentLayers, layer)?.properties.id;
349
327
 
350
- const updatedLayers = replaceLayer(
351
- currentLayers,
352
- /** @type {Record<string,any> & { properties:{ id:string; title:string } } } */
353
- (oldLayer),
354
- newLayers,
355
- );
328
+ if (!oldLayerID) {
329
+ return;
330
+ }
331
+
332
+ const updatedLayers = replaceLayer(currentLayers, oldLayerID, newLayers);
356
333
 
357
334
  return updatedLayers;
358
335
  }
@@ -395,4 +372,61 @@ export class EodashCollection {
395
372
  )),
396
373
  ];
397
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
+ }
398
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";
@@ -7,13 +5,7 @@ import log from "loglevel";
7
5
  /** @param {import("stac-ts").StacLink[]} [links] */
8
6
  export function generateFeatures(links) {
9
7
  /**
10
- * @type {{
11
- * type: string;
12
- * geometry: {
13
- * type: string;
14
- * coordinates: [number, number];
15
- * };
16
- * }[]}
8
+ * @type {import("geojson").Feature[]}
17
9
  */
18
10
  const features = [];
19
11
  links?.forEach((element) => {
@@ -27,6 +19,7 @@ export function generateFeatures(links) {
27
19
  type: "Point",
28
20
  coordinates: [lon, lat],
29
21
  },
22
+ properties: { id: element.id },
30
23
  });
31
24
  }
32
25
  });
@@ -43,7 +36,10 @@ export function generateFeatures(links) {
43
36
  return geojsonObject;
44
37
  }
45
38
 
46
- /** @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] */
47
43
  export function extractLayerConfig(style) {
48
44
  /** @type {Record<string,unknown> | undefined} */
49
45
  let layerConfig = undefined;
@@ -64,42 +60,6 @@ export function extractLayerConfig(style) {
64
60
  return { layerConfig, style };
65
61
  }
66
62
 
67
- /**
68
- * checks if there's a projection on the Collection and
69
- * updates {@link availableMapProjection}
70
- * @param {import('stac-ts').StacCollection} [STAcCollection]
71
- */
72
- export const setMapProjFromCol = async (STAcCollection) => {
73
- // if a projection exists on the collection level
74
- log.debug("Checking for available map projection in indicator");
75
- const projection =
76
- /** @type {number | string | {name: string, def: string} | undefined} */
77
- (
78
- STAcCollection?.["eodash:mapProjection"] ||
79
- STAcCollection?.["proj:epsg"] ||
80
- STAcCollection?.["eodash:proj4_def"]
81
- );
82
- if (projection) {
83
- log.debug("Projection found", projection);
84
- await registerProjection(projection);
85
- const projectionCode = getProjectionCode(projection);
86
- if (availableMapProjection.value !== projectionCode) {
87
- log.debug(
88
- "Changing map projection",
89
- availableMapProjection.value,
90
- projectionCode,
91
- );
92
- await changeMapProjection(projection);
93
- }
94
- // set it for `EodashMapBtns`
95
- availableMapProjection.value = /** @type {string} */ (projectionCode);
96
- } else {
97
- // reset to default projection
98
- log.debug("Resetting projection to default EPSG:3857");
99
- await changeMapProjection((availableMapProjection.value = ""));
100
- }
101
- };
102
-
103
63
  /**
104
64
  * Function to extract collection urls from an indicator
105
65
  * @param {import("stac-ts").StacCatalog
@@ -108,25 +68,24 @@ export const setMapProjFromCol = async (STAcCollection) => {
108
68
  * | null
109
69
  * } stacObject
110
70
  * @param {string} basepath
111
- * @returns {string[]}
112
71
  */
113
72
  export function extractCollectionUrls(stacObject, basepath) {
73
+ /** @type {string[]} */
114
74
  const collectionUrls = [];
115
75
  // Support for two structure types, flat and indicator, simplified here:
116
76
  // Flat assumes Catalog-Collection-Item
117
77
  // Indicator assumes Catalog-Collection-Collection-Item
118
- // TODO: this is not the most stable test approach,
119
- // we should discuss potential other approaches
120
- 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) {
121
83
  collectionUrls.push(basepath);
122
- } else if (stacObject?.links[1]?.rel === "child") {
123
- // TODO: Iterate through all children to create collections
124
- stacObject.links.forEach((link) => {
125
- if (link.rel === "child") {
126
- collectionUrls.push(toAbsolute(link.href, basepath));
127
- }
128
- });
84
+ return collectionUrls;
129
85
  }
86
+ children.forEach((link) => {
87
+ collectionUrls.push(toAbsolute(link.href, basepath));
88
+ });
130
89
  return collectionUrls;
131
90
  }
132
91
 
@@ -143,11 +102,6 @@ export const extractRoles = (properties, linkOrAsset) => {
143
102
  }
144
103
  if (role === "overlay" || role === "baselayer") {
145
104
  properties.group = role;
146
- //remove all the properties and replace the random ID with baselayer
147
- // provided ID
148
- // const [_colId, _itemId, _isAsset, _random, proj] =
149
- // properties.id.split(";:;");
150
- // properties.id = ["", "", "", "", linkOrAsset.id, proj].join(";:;");
151
105
  }
152
106
 
153
107
  return properties;
@@ -155,8 +109,10 @@ export const extractRoles = (properties, linkOrAsset) => {
155
109
  };
156
110
 
157
111
  /**
112
+ * Extracts style JSON from a STAC Item
158
113
  * @param {import("stac-ts").StacItem} item
159
114
  * @param {string} itemUrl
115
+ * @returns
160
116
  **/
161
117
  export const fetchStyle = async (item, itemUrl) => {
162
118
  const styleLink = item.links.find((link) => link.rel.includes("style"));
@@ -197,6 +153,7 @@ export const getProjectionCode = (projection) => {
197
153
  };
198
154
 
199
155
  /**
156
+ * Extracts layercontrol LayerDatetime property from STAC Links
200
157
  * @param {import("stac-ts").StacLink[]} [links]
201
158
  * @param {string|null} [currentStep]
202
159
  **/
@@ -206,6 +163,7 @@ export const extractLayerDatetime = (links, currentStep) => {
206
163
  }
207
164
 
208
165
  // check if links has a datetime value
166
+ // TODO: consider datetime ranges
209
167
  const hasDatetime = links.some((l) => typeof l.datetime === "string");
210
168
  if (!hasDatetime) {
211
169
  return undefined;
@@ -242,12 +200,13 @@ export const extractLayerDatetime = (links, currentStep) => {
242
200
  controlValues,
243
201
  currentStep,
244
202
  slider: true,
245
- disablePlay: true,
203
+ play: false,
204
+ displayFormat: "DD MMMM YYYY",
246
205
  };
247
206
  };
248
207
 
249
208
  /**
250
- * Find layer by ID
209
+ * Find JSON layer by ID
251
210
  * @param {string} layer
252
211
  * @param {Record<string, any>[]} layers
253
212
  * @returns {Record<string,any> | undefined}
@@ -268,16 +227,24 @@ export const findLayer = (layers, layer) => {
268
227
  };
269
228
 
270
229
  /**
230
+ * Removes the layer with the id provided and injects an array of layers in its position
271
231
  * @param {Record<string,any>[]} currentLayers
272
- * @param {Record<string,any>} oldLayer
273
- * @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
274
234
  * @returns {Record<string,any>[] | undefined}
275
235
  */
276
236
  export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
277
237
  const oldLayerIdx = currentLayers.findIndex(
278
- (l) => l.properties.id === oldLayer.properties.id,
238
+ (l) => l.properties.id === oldLayer,
279
239
  );
240
+
280
241
  if (oldLayerIdx !== -1) {
242
+ log.debug(
243
+ "Replacing layer",
244
+ oldLayer,
245
+ "with",
246
+ newLayers.map((l) => l.properties.id),
247
+ );
281
248
  currentLayers.splice(oldLayerIdx, 1, ...newLayers);
282
249
  return currentLayers;
283
250
  }
@@ -292,8 +259,11 @@ export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
292
259
  }
293
260
  }
294
261
  };
262
+
295
263
  /**
296
- * @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
297
267
  * @param {import('ol/layer').Layer} layer
298
268
  */
299
269
  export const getColFromLayer = async (indicators, layer) => {
@@ -309,13 +279,15 @@ export const getColFromLayer = async (indicators, layer) => {
309
279
  col.links?.some(
310
280
  (link) => link.rel === "item" && link.href.includes(itemId),
311
281
  );
312
- return isInd ?? false;
282
+ return isInd;
313
283
  });
314
284
  return indicators.find((ind) => ind.collectionStac?.id === chosen?.id);
315
285
  };
316
286
 
317
287
  /**
318
- * 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
+ *
319
291
  * @param {string} collectionId
320
292
  * @param {string} itemId
321
293
  * @param {import('stac-ts').StacLink} link
@@ -328,9 +300,8 @@ export const createLayerID = (collectionId, itemId, link, projectionCode) => {
328
300
  // If we are looking at base layers and overlays we remove the collection and item part
329
301
  // as we want to make sure tiles are not reloaded when switching layers
330
302
  if (
331
- link.roles &&
332
- // @ts-expect-error it seems roles it not defined for links yet
333
- link.roles.find((r) => ["baselayer", "overlay"].includes(r))
303
+ /** @type {string[]} */
304
+ (link.roles)?.find((r) => ["baselayer", "overlay"].includes(r))
334
305
  ) {
335
306
  lId = `${linkId ?? ""};:;${projectionCode ?? ""}`;
336
307
  }
@@ -339,7 +310,8 @@ export const createLayerID = (collectionId, itemId, link, projectionCode) => {
339
310
  };
340
311
 
341
312
  /**
342
- * 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
+ *
343
315
  * @param {string} collectionId
344
316
  * @param {string} itemId
345
317
  * @param {number} index
@@ -352,7 +324,7 @@ export const createAssetID = (collectionId, itemId, index) => {
352
324
  };
353
325
 
354
326
  /**
355
- *
327
+ * Assigns projection code to the layer ID
356
328
  * @param {import("stac-ts").StacItem} item
357
329
  * @param {import("stac-ts").StacLink | import("stac-ts").StacAsset} linkOrAsset
358
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("");