@eodash/eodash 5.0.0-alpha.2.8 → 5.0.0-processing

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 (138) hide show
  1. package/README.md +1 -1
  2. package/core/client/App.vue +13 -1
  3. package/core/client/asWebComponent.js +13 -3
  4. package/core/client/components/DashboardLayout.vue +6 -2
  5. package/core/client/composables/DefineEodash.js +1 -1
  6. package/core/client/composables/EodashMap.js +349 -0
  7. package/core/client/composables/EodashProcess.js +575 -0
  8. package/core/client/composables/index.js +107 -24
  9. package/core/client/eodash.js +83 -10
  10. package/core/client/plugins/axios.js +8 -0
  11. package/core/client/plugins/index.js +2 -1
  12. package/core/client/store/Actions.js +63 -12
  13. package/core/client/store/States.js +19 -0
  14. package/core/client/store/stac.js +98 -8
  15. package/core/client/types.d.ts +25 -18
  16. package/core/client/utils/createLayers.js +313 -0
  17. package/core/client/utils/eodashSTAC.js +320 -170
  18. package/core/client/utils/helpers.js +369 -9
  19. package/core/client/utils/keys.js +2 -0
  20. package/core/client/utils/states.js +17 -0
  21. package/core/client/views/Dashboard.vue +17 -46
  22. package/core/client/vite-env.d.ts +1 -9
  23. package/dist/client/DashboardLayout-CVMJ4l8M.js +87 -0
  24. package/dist/client/DynamicWebComponent-Cv8n457T.js +88 -0
  25. package/dist/client/EodashDatePicker-VVkiPmpc.js +394 -0
  26. package/dist/client/EodashItemFilter-CugWNQ86.js +194 -0
  27. package/dist/client/EodashLayerControl-53WghA8G.js +110 -0
  28. package/dist/client/EodashMap-CQnOePpy.js +486 -0
  29. package/dist/client/EodashMapBtns-uaRwFtfB.js +66 -0
  30. package/dist/client/EodashProcess-cF0unIy8.js +1477 -0
  31. package/dist/client/ExportState-BT8MLAW7.js +644 -0
  32. package/dist/client/Footer-C6GUG84G.js +141 -0
  33. package/dist/client/Header-D2dtCWp8.js +437 -0
  34. package/dist/client/IframeWrapper-BgM9aU8f.js +28 -0
  35. package/dist/client/MobileLayout-BAo8Wr8T.js +1210 -0
  36. package/dist/client/PopUp-Bm01q7Ko.js +389 -0
  37. package/dist/client/VImg-B8AbetCE.js +384 -0
  38. package/dist/client/VMain-DnGlQUyr.js +43 -0
  39. package/dist/client/VOverlay-B8Qj7LRG.js +1453 -0
  40. package/dist/client/WidgetsContainer-CwXRRLS1.js +83 -0
  41. package/dist/client/asWebComponent-DUUoR7MZ.js +11621 -0
  42. package/dist/client/eo-dash.js +2 -6
  43. package/dist/client/forwardRefs-CZJhEAKW.js +245 -0
  44. package/dist/client/index-DlIO7sJ3.js +199 -0
  45. package/dist/client/ssrBoot-BP7SYRyC.js +22 -0
  46. package/dist/client/style.css +2 -2
  47. package/dist/client/transition-BiR8wMn1.js +37 -0
  48. package/dist/node/cli.js +4 -4
  49. package/dist/node/types.d.ts +2 -0
  50. package/dist/types/core/client/App.vue.d.ts +7 -0
  51. package/dist/types/core/client/asWebComponent.d.ts +9 -0
  52. package/dist/types/core/client/components/DashboardLayout.vue.d.ts +2 -0
  53. package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +18 -0
  54. package/dist/types/core/client/components/ErrorAlert.vue.d.ts +2 -0
  55. package/dist/types/core/client/components/Footer.vue.d.ts +2 -0
  56. package/dist/types/core/client/components/Header.vue.d.ts +2 -0
  57. package/dist/types/core/client/components/IframeWrapper.vue.d.ts +7 -0
  58. package/dist/types/core/client/components/Loading.vue.d.ts +2 -0
  59. package/dist/types/core/client/components/MobileLayout.vue.d.ts +2 -0
  60. package/dist/types/core/client/composables/DefineEodash.d.ts +2 -0
  61. package/dist/types/core/client/composables/DefineTemplate.d.ts +15 -0
  62. package/dist/types/core/client/composables/DefineWidgets.d.ts +14 -0
  63. package/dist/types/core/client/composables/EodashMap.d.ts +5 -0
  64. package/dist/types/core/client/composables/index.d.ts +30 -0
  65. package/dist/types/core/client/eodash.d.ts +8 -0
  66. package/dist/types/core/client/main.d.ts +2 -0
  67. package/dist/types/core/client/plugins/axios.d.ts +2 -0
  68. package/dist/types/core/client/plugins/index.d.ts +3 -0
  69. package/dist/types/core/client/plugins/vuetify.d.ts +82 -0
  70. package/dist/types/core/client/render.d.ts +1 -0
  71. package/dist/types/core/client/store/Actions.d.ts +12 -0
  72. package/dist/types/core/client/store/States.d.ts +22 -0
  73. package/dist/types/core/client/store/index.d.ts +2 -0
  74. package/dist/types/core/client/store/stac.d.ts +25 -0
  75. package/dist/types/core/client/types.d.ts +279 -0
  76. package/dist/types/core/client/utils/createLayers.d.ts +45 -0
  77. package/dist/types/core/client/utils/eodashSTAC.d.ts +82 -0
  78. package/dist/types/core/client/utils/helpers.d.ts +84 -0
  79. package/dist/types/core/client/utils/index.d.ts +2 -0
  80. package/dist/types/core/client/utils/keys.d.ts +6 -0
  81. package/dist/types/core/client/utils/states.d.ts +14 -0
  82. package/dist/types/core/client/views/Dashboard.vue.d.ts +9 -0
  83. package/dist/types/widgets/EodashDatePicker.vue.d.ts +7 -0
  84. package/dist/types/widgets/EodashItemFilter.vue.d.ts +42 -0
  85. package/dist/types/widgets/EodashLayerControl.vue.d.ts +11 -0
  86. package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +9 -0
  87. package/dist/types/widgets/EodashMap.vue.d.ts +7 -0
  88. package/dist/types/widgets/EodashMapBtns.vue.d.ts +11 -0
  89. package/dist/types/widgets/EodashStacInfo.vue.d.ts +21 -0
  90. package/dist/types/widgets/EodashTools.vue.d.ts +15 -0
  91. package/dist/types/widgets/ExportState.vue.d.ts +7 -0
  92. package/dist/types/widgets/PopUp.vue.d.ts +22 -0
  93. package/dist/types/widgets/WidgetsContainer.vue.d.ts +7 -0
  94. package/package.json +58 -37
  95. package/widgets/EodashDatePicker.vue +128 -100
  96. package/widgets/EodashItemFilter.vue +149 -47
  97. package/widgets/EodashLayerControl.vue +98 -0
  98. package/widgets/EodashMap.vue +98 -122
  99. package/widgets/EodashMapBtns.vue +24 -7
  100. package/widgets/EodashProcess.vue +151 -0
  101. package/widgets/ExportState.vue +15 -11
  102. package/core/client/SuspensedDashboard.ce.vue +0 -105
  103. package/dist/client/DashboardLayout-CKOExc7r.js +0 -156
  104. package/dist/client/DynamicWebComponent-m1Zbbw6n.js +0 -57
  105. package/dist/client/EodashDatePicker-CGdJRGZJ.js +0 -252
  106. package/dist/client/EodashItemFilter-BjM_LHaE.js +0 -63
  107. package/dist/client/EodashMap-61UMC8sv.js +0 -86917
  108. package/dist/client/EodashMapBtns-DVITfAFx.js +0 -36
  109. package/dist/client/ExportState-DhpK09GR.js +0 -558
  110. package/dist/client/Footer-CIwjaddz.js +0 -115
  111. package/dist/client/Header-BcM-pZFi.js +0 -350
  112. package/dist/client/IframeWrapper-CAe6HPqe.js +0 -19
  113. package/dist/client/MobileLayout-DcZOQX8r.js +0 -945
  114. package/dist/client/PopUp-DCaITceG.js +0 -300
  115. package/dist/client/VImg-C-I_7puM.js +0 -291
  116. package/dist/client/VMain-Cd3P0YTG.js +0 -39
  117. package/dist/client/VOverlay-AcvFgk39.js +0 -967
  118. package/dist/client/WidgetsContainer-B0-q0EMO.js +0 -129
  119. package/dist/client/_commonjsHelpers-DaMA6jEr.js +0 -8
  120. package/dist/client/asWebComponent-zuKR9I1w.js +0 -20361
  121. package/dist/client/basedecoder-DHcBySSe-BmCFNFnw.js +0 -88
  122. package/dist/client/decoder-CP4lv0Kb-DdKalImK.js +0 -10
  123. package/dist/client/deflate-BXt-9JA_-CWfClgpK.js +0 -10
  124. package/dist/client/eodashSTAC-DGB50vNk.js +0 -2788
  125. package/dist/client/eox-itemfilter-TaBxgqq_.js +0 -7565
  126. package/dist/client/eox-stacinfo-l7ALSV90.js +0 -13969
  127. package/dist/client/forwardRefs-BnxE4iKQ.js +0 -185
  128. package/dist/client/index-hSIi5Ygk.js +0 -153
  129. package/dist/client/jpeg-BAgeD1d3-oeHbFPUL.js +0 -514
  130. package/dist/client/lerc-DzVumYtB-cTUap6k_.js +0 -1027
  131. package/dist/client/lzw-LAGDNbSC-DkP96qO9.js +0 -84
  132. package/dist/client/packbits-BlDR4Kj5-C66n1-zr.js +0 -24
  133. package/dist/client/pako.esm-CB1uQYY0-DB0PYm1P.js +0 -1081
  134. package/dist/client/raw-CMGvRjfu-BRi6E4i1.js +0 -9
  135. package/dist/client/ssrBoot-D3KF5Thc.js +0 -17
  136. package/dist/client/transition-D3a4tiJv.js +0 -34
  137. package/dist/client/webfontloader-qotgY98I.js +0 -435
  138. package/dist/client/webimage-BM_pbLN3-L2cGWK5l.js +0 -19
@@ -1,43 +1,34 @@
1
1
  import { Collection, Item } from "stac-js";
2
2
  import { toAbsolute } from "stac-js/src/http.js";
3
- import { generateFeatures } from "./helpers";
4
- import axios from "axios";
5
-
6
- /**
7
- * Function to extract collection urls from an indicator
8
- * @param {import("stac-ts").StacCatalog
9
- * | import("stac-ts").StacCollection
10
- * | import("stac-ts").StacItem
11
- * | null
12
- * } stacObject
13
- * @param {string} basepath
14
- * @returns {string[]}
15
- */
16
- export function extractCollectionUrls(stacObject, basepath) {
17
- const collectionUrls = [];
18
- // Support for two structure types, flat and indicator, simplified here:
19
- // Flat assumes Catalog-Collection-Item
20
- // Indicator assumes Catalog-Collection-Collection-Item
21
- // TODO: this is not the most stable test approach,
22
- // we should discuss potential other approaches
23
- //
24
- if (stacObject?.links && stacObject?.links[1].rel === "item") {
25
- collectionUrls.push(basepath);
26
- } else if (stacObject?.links[1].rel === "child") {
27
- // TODO: Iterate through all children to create collections
28
- stacObject.links.forEach((link) => {
29
- if (link.rel === "child") {
30
- collectionUrls.push(toAbsolute(link.href, basepath));
31
- }
32
- });
33
- }
34
- return collectionUrls;
35
- }
3
+ import {
4
+ extractLayerConfig,
5
+ extractLayerDatetime,
6
+ extractRoles,
7
+ fetchStyle,
8
+ findLayer,
9
+ generateFeatures,
10
+ replaceLayer,
11
+ } from "./helpers";
12
+ import {
13
+ getLayers,
14
+ getCompareLayers,
15
+ registerProjection,
16
+ } from "@/store/Actions";
17
+ import { createLayersFromAssets, createLayersFromLinks } from "./createLayers";
18
+ import axios from "@/plugins/axios";
19
+ import log from "loglevel";
20
+
36
21
  export class EodashCollection {
37
- /** @type {string} */
38
22
  #collectionUrl = "";
23
+
39
24
  /** @type {import("stac-ts").StacCollection | undefined} */
40
25
  #collectionStac;
26
+
27
+ // read only
28
+ get collectionStac() {
29
+ return this.#collectionStac;
30
+ }
31
+
41
32
  /**
42
33
  * @type {import("stac-ts").StacLink
43
34
  * | import("stac-ts").StacItem
@@ -49,175 +40,225 @@ export class EodashCollection {
49
40
  constructor(collectionUrl) {
50
41
  this.#collectionUrl = collectionUrl;
51
42
  }
43
+
52
44
  /**
53
45
  * @async
54
- * @param {any} item
46
+ * @param {import('stac-ts').StacLink | Date} [linkOrDate]
55
47
  * @returns
56
48
  */
57
- createLayersJson = async (item = null) => {
58
- /** @type {import("stac-ts").StacLink | undefined} */
59
- let stacItem,
60
- /** @type {import("stac-ts").StacCollection | undefined} */
61
- stac;
49
+ createLayersJson = async (linkOrDate) => {
50
+ /**
51
+ * @type {import("stac-ts").StacLink | undefined}
52
+ **/
53
+ let stacItem;
54
+
55
+ /**
56
+ * @type {import("stac-ts").StacCollection | undefined}
57
+ **/
58
+ let stac;
62
59
  // TODO get auxiliary layers from collection
63
- /** @type {object[]} */
64
- let layersJson = [
65
- /*{
66
- type: "Tile",
67
- properties: {
68
- id: "OSM",
69
- },
70
- source: {
71
- type: "OSM",
72
- },
73
- },*/
74
- ];
60
+ /** @type {Record<string,any>[]} */
61
+ let layersJson = [];
62
+
75
63
  // Load collectionstac if not yet initialized
76
- if (!this.#collectionStac) {
77
- const response = await axios.get(this.#collectionUrl);
78
- stac = await response.data;
79
- this.#collectionStac = new Collection(stac);
80
- }
64
+ stac = await this.fetchCollection();
81
65
 
82
- if (stac && stac.endpointtype === "GeoDB") {
83
- // Special handling of point based data
84
- const allFeatures = generateFeatures(stac.links);
85
- layersJson.unshift({
86
- type: "Vector",
87
- properties: {
88
- id: stac.id,
89
- },
90
- source: {
91
- type: "Vector",
92
- url: "data:," + encodeURIComponent(JSON.stringify(allFeatures)),
93
- format: "GeoJSON",
94
- },
95
- style: {
96
- "circle-radius": 5,
97
- "circle-fill-color": "#00417077",
98
- "circle-stroke-color": "#004170",
99
- "fill-color": "#00417077",
100
- "stroke-color": "#004170",
101
- },
102
- });
103
- return layersJson;
66
+ const isGeoDB = stac?.endpointtype === "GeoDB";
67
+
68
+ if (linkOrDate instanceof Date) {
69
+ // if collectionStac not yet initialized we do it here
70
+ stacItem = this.getItem(linkOrDate);
104
71
  } else {
105
- if (item instanceof Date) {
106
- // if collectionStac not yet initialized we do it here
107
- stacItem = this.getItems()?.sort((a, b) => {
108
- const distanceA = Math.abs(
109
- new Date(/** @type {number} */ (a.datetime)).getTime() -
110
- item.getTime(),
111
- );
112
- const distanceB = Math.abs(
113
- new Date(/** @type {number} */ (b.datetime)).getTime() -
114
- item.getTime(),
115
- );
116
- return distanceA - distanceB;
117
- })[0];
118
- this.selectedItem = stacItem;
72
+ stacItem = linkOrDate;
73
+ }
74
+
75
+ const stacItemUrl = stacItem
76
+ ? toAbsolute(stacItem.href, this.#collectionUrl)
77
+ : this.#collectionUrl;
78
+
79
+ stac = await axios.get(stacItemUrl).then((resp) => resp.data);
80
+
81
+ if (!stacItem) {
82
+ // no specific item was requested; render last item
83
+ this.#collectionStac = new Collection(stac);
84
+ this.selectedItem = this.getItem();
85
+
86
+ if (this.selectedItem) {
87
+ layersJson = /** @type {Record<string,any>[]} */ (
88
+ await this.createLayersJson(this.selectedItem)
89
+ );
119
90
  } else {
120
- stacItem = item;
91
+ console.warn(
92
+ "[eodash] the selected collection does not include any items",
93
+ );
121
94
  }
122
- const response = await fetch(
123
- stacItem
124
- ? toAbsolute(stacItem.href, this.#collectionUrl)
125
- : this.#collectionUrl,
95
+ return [];
96
+ } else {
97
+ // specific item was requested
98
+ const item = new Item(stac);
99
+ this.selectedItem = item;
100
+ const title =
101
+ this.#collectionStac?.title || this.#collectionStac?.id || "";
102
+ layersJson.unshift(
103
+ ...(await this.buildJsonArray(item, stacItemUrl, title, isGeoDB)),
126
104
  );
127
- stac = await response.json();
128
-
129
- if (!stacItem) {
130
- // no specific item was requested; render last item
131
- this.#collectionStac = new Collection(stac);
132
- const items = this.getItems();
133
- this.selectedItem = items?.[items.length - 1];
134
- if (this.selectedItem) {
135
- layersJson = await this.createLayersJson(this.selectedItem);
136
- } else {
137
- if (import.meta.env.DEV) {
138
- console.warn(
139
- "[eodash] the selected collection does not include any items",
140
- );
141
- }
142
- }
143
- return [];
144
- } else {
145
- // specific item was requested
146
- const item = new Item(stac);
147
- this.selectedItem = item;
148
- layersJson.unshift(...this.buildJsonArray(item));
149
- return layersJson;
150
- }
105
+ return layersJson;
151
106
  }
152
107
  };
153
108
 
154
- /** @param {import("stac-ts").StacItem} item */
155
- buildJsonArray(item) {
109
+ /**
110
+ * @param {import("stac-ts").StacItem} item
111
+ * @param {string} itemUrl
112
+ * @param {string} title
113
+ * @param {boolean} isGeoDB
114
+ * @param {string} [itemDatetime]
115
+ * @returns {Promise<Record<string,any>[]>} arrays
116
+ * */
117
+ async buildJsonArray(item, itemUrl, title, isGeoDB, itemDatetime) {
118
+ log.debug(
119
+ "Building JSON array",
120
+ item,
121
+ itemUrl,
122
+ title,
123
+ isGeoDB,
124
+ itemDatetime,
125
+ );
126
+ await this.fetchCollection();
127
+ // registering top level indicator projection
128
+ const indicatorProjection =
129
+ item?.["proj:epsg"] || item?.["eodash:proj4_def"];
130
+ await registerProjection(
131
+ /** @type {number | string | {name: string, def: string; extent: number[] | undefined;} } */ (
132
+ indicatorProjection
133
+ ),
134
+ );
135
+
156
136
  const jsonArray = [];
157
- // TODO: this currently assumes only one layer will be extracted
158
- // from an item, although it think this is currently true
159
- // potentially this could return multiple layers
160
- // TODO: implement other types, such as COG
137
+
138
+ 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
+ ];
163
+ }
161
164
 
162
165
  // I propose following approach, we "manually" create configurations
163
166
  // for the rendering options we know and expect.
164
167
  // If we don't find any we fallback to using the STAC ol item that
165
168
  // will try to extract anything it supports but for which we have
166
169
  // less control.
167
- const wms = item.links.find((l) => l.rel === "wms");
168
- // const projDef = false; // TODO: add capability to find projection in item
169
- if (wms) {
170
- let json = {
171
- type: "Tile",
172
- properties: {
173
- id: item.id,
174
- },
175
- source: {
176
- // if no projection information is provided we should
177
- // assume one, else for WMS requests it will try to get
178
- // the map projection that might not be supported
179
- // projection: projDef ? projDef : "EPSG:4326",
180
- type: "TileWMS",
181
- url: wms.href,
182
- params: {
183
- LAYERS: wms["wms:layers"],
184
- TILED: true,
185
- },
186
- },
187
- };
188
- if ("wms:dimensions" in wms) {
189
- // @ts-expect-error: waiting for eox-map to provide type definition
190
- json.source.params.time = wms["wms:dimensions"];
170
+
171
+ let { layerConfig, style } = extractLayerConfig(
172
+ await fetchStyle(item, itemUrl),
173
+ );
174
+
175
+ const layerDatetime = extractLayerDatetime(
176
+ this.getItems(),
177
+ item.properties?.datetime ?? itemDatetime,
178
+ );
179
+
180
+ const dataAssets = Object.keys(item?.assets ?? {}).reduce((data, ast) => {
181
+ if (item.assets[ast].roles?.includes("data")) {
182
+ data[ast] = item.assets[ast];
191
183
  }
192
- jsonArray.push(json);
193
- } else if (item.links.find((l) => l.rel === "wmts" || l.rel === "xyz")) {
194
- jsonArray.push({
184
+ return data;
185
+ }, /** @type {Record<string,import('stac-ts').StacAsset>} */ ({}));
186
+ const isSupported =
187
+ item.links.some((link) => ["wms", "xyz", "wmts"].includes(link.rel)) ||
188
+ Object.keys(dataAssets).length;
189
+
190
+ if (isSupported) {
191
+ // Checking for potential legend asset
192
+ let extraProperties = null;
193
+ if (this.#collectionStac?.assets?.legend?.href) {
194
+ extraProperties = {
195
+ description: `<div style="text-align:center; width: 100%">
196
+ <img src="${this.#collectionStac.assets.legend.href}" style="max-height:70px; margin-top:-15px; margin-bottom:-20px;" />
197
+ </div>`,
198
+ };
199
+ }
200
+ // Check if collection has eox:colorlegend definition, if yes overwrite legend description
201
+ if (this.#collectionStac && this.#collectionStac["eox:colorlegend"]) {
202
+ extraProperties = {
203
+ layerLegend: this.#collectionStac["eox:colorlegend"],
204
+ };
205
+ }
206
+ const links = await createLayersFromLinks(
207
+ this.#collectionStac?.id ?? "",
208
+ title,
209
+ item,
210
+ layerDatetime,
211
+ extraProperties,
212
+ );
213
+ jsonArray.push(
214
+ ...links,
215
+ ...(await createLayersFromAssets(
216
+ this.#collectionStac?.id ?? "",
217
+ title || this.#collectionStac?.title || item.id,
218
+ dataAssets,
219
+ item,
220
+ style,
221
+ layerConfig,
222
+ layerDatetime,
223
+ extraProperties,
224
+ )),
225
+ );
226
+ } else {
227
+ // fallback to STAC
228
+ const json = {
195
229
  type: "STAC",
196
230
  displayWebMapLink: true,
197
231
  displayFootprint: false,
198
232
  data: item,
199
233
  properties: {
200
- id: item.id,
201
- },
202
- });
203
- } else {
204
- // fall back to rendering the feature
205
- jsonArray.push({
206
- type: "Vector",
207
- source: {
208
- type: "Vector",
209
- url: "data:," + encodeURIComponent(JSON.stringify(item.geometry)),
210
- format: "GeoJSON",
211
- },
212
- properties: {
213
- id: item.id,
234
+ id: this.#collectionStac?.id ?? "",
235
+ title: title || item.id,
236
+ layerConfig,
214
237
  },
215
- });
238
+ style,
239
+ };
240
+ extractRoles(
241
+ json.properties,
242
+ //@ts-expect-error using the item incase no self link is found
243
+ item.links.find((link) => link.rel === "self") ?? item,
244
+ );
245
+ jsonArray.push(json);
216
246
  }
217
247
 
218
248
  return jsonArray;
219
249
  }
220
250
 
251
+ async fetchCollection() {
252
+ if (!this.#collectionStac) {
253
+ log.debug("Fetching collection file", this.#collectionUrl);
254
+ const col = await axios
255
+ .get(this.#collectionUrl)
256
+ .then((resp) => resp.data);
257
+ this.#collectionStac = new Collection(col);
258
+ }
259
+ return this.#collectionStac;
260
+ }
261
+
221
262
  getItems() {
222
263
  return (
223
264
  this.#collectionStac?.links
@@ -246,4 +287,113 @@ export class EodashCollection {
246
287
  .map((i) => new Date(/** @type {number} */ (i.datetime)))
247
288
  );
248
289
  }
290
+
291
+ async getExtent() {
292
+ await this.fetchCollection();
293
+ return this.#collectionStac?.extent;
294
+ }
295
+
296
+ /**
297
+ * Get closest Item Link from a certain date,
298
+ * get the latest if no date provided
299
+ * @param {Date} [date]
300
+ **/
301
+ getItem(date) {
302
+ return date
303
+ ? this.getItems()?.sort((a, b) => {
304
+ const distanceA = Math.abs(
305
+ new Date(/** @type {number} */ (a.datetime)).getTime() -
306
+ date.getTime(),
307
+ );
308
+ const distanceB = Math.abs(
309
+ new Date(/** @type {number} */ (b.datetime)).getTime() -
310
+ date.getTime(),
311
+ );
312
+ return distanceA - distanceB;
313
+ })[0]
314
+ : this.getItems()?.at(-1);
315
+ }
316
+
317
+ /**
318
+ *
319
+ * @param {string} datetime
320
+ * @param {string} layer
321
+ * @param {string} map
322
+ */
323
+ async updateLayerJson(datetime, layer, map) {
324
+ await this.fetchCollection();
325
+
326
+ // get the link of the specified date
327
+ const specifiedLink = this.getItems()?.find(
328
+ (item) =>
329
+ typeof item.datetime === "string" &&
330
+ new Date(item.datetime).toISOString() === datetime,
331
+ );
332
+
333
+ if (!specifiedLink) {
334
+ console.warn(
335
+ "[eodash] no Item found for the provided datetime",
336
+ datetime,
337
+ );
338
+ return;
339
+ }
340
+
341
+ // create json layers from the item
342
+ const newLayers = await this.createLayersJson(specifiedLink);
343
+
344
+ let currentLayers = getLayers();
345
+ if (map === "second") {
346
+ currentLayers = getCompareLayers();
347
+ }
348
+
349
+ const oldLayer = findLayer(currentLayers, layer);
350
+
351
+ const updatedLayers = replaceLayer(
352
+ currentLayers,
353
+ /** @type {Record<string,any> & { properties:{ id:string; title:string } } } */
354
+ (oldLayer),
355
+ newLayers,
356
+ );
357
+
358
+ return updatedLayers;
359
+ }
360
+
361
+ /**
362
+ * Returns base layers and overlay layers of a STAC Collection
363
+ *
364
+ * @param {import("stac-ts").StacCollection} indicator */
365
+ static async getIndicatorLayers(indicator) {
366
+ const indicatorAssets = Object.keys(indicator?.assets ?? {}).reduce(
367
+ (assets, ast) => {
368
+ if (
369
+ indicator.assets?.[ast].roles?.includes("baselayer") ||
370
+ indicator.assets?.[ast].roles?.includes("overlay")
371
+ ) {
372
+ assets[ast] = indicator.assets[ast];
373
+ }
374
+ return assets;
375
+ },
376
+ /** @type {Record<string,import('stac-ts').StacAsset>} */ ({}),
377
+ );
378
+
379
+ return [
380
+ ...(await createLayersFromLinks(
381
+ indicator?.id ?? "",
382
+ indicator?.title || indicator.id,
383
+ //@ts-expect-error indicator instead of item
384
+ indicator,
385
+ // layerDatetime,
386
+ )),
387
+ ...(await createLayersFromAssets(
388
+ indicator?.id ?? "",
389
+ indicator?.title || indicator.id,
390
+ indicatorAssets,
391
+ //@ts-expect-error indicator instead of item
392
+ indicator,
393
+ // style,
394
+ // layerConfig,
395
+ // layerDatetime,
396
+ )),
397
+ ];
398
+ }
249
399
  }