@eodash/eodash 5.0.0-rc.3 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +1 -0
  2. package/core/client/App.vue +8 -2
  3. package/core/client/asWebComponent.js +5 -5
  4. package/core/client/components/DashboardLayout.vue +42 -25
  5. package/core/client/components/EodashOverlay.vue +1 -1
  6. package/core/client/components/ErrorAlert.vue +2 -2
  7. package/core/client/components/Footer.vue +4 -4
  8. package/core/client/components/Header.vue +3 -3
  9. package/core/client/components/MobileLayout.vue +9 -10
  10. package/core/client/composables/DefineEodash.js +38 -43
  11. package/core/client/composables/DefineTemplate.js +4 -2
  12. package/core/client/composables/DefineWidgets.js +14 -8
  13. package/core/client/composables/index.js +273 -23
  14. package/core/client/eodashSTAC/EodashCollection.js +80 -47
  15. package/core/client/eodashSTAC/helpers.js +136 -27
  16. package/core/client/eodashSTAC/parquet.js +145 -0
  17. package/core/client/eodashSTAC/triggers.js +6 -3
  18. package/core/client/plugins/index.js +4 -3
  19. package/core/client/plugins/vuetify.js +3 -0
  20. package/core/client/store/actions.js +21 -4
  21. package/core/client/store/stac.js +93 -56
  22. package/core/client/store/states.js +15 -5
  23. package/core/client/types.ts +59 -43
  24. package/core/client/utils/index.js +79 -0
  25. package/core/client/utils/keys.js +2 -2
  26. package/core/client/utils/states.js +30 -5
  27. package/core/client/views/Dashboard.vue +36 -32
  28. package/core/client/vite-env.d.ts +7 -0
  29. package/dist/client/{DashboardLayout-t_PavJPO.js → DashboardLayout-ByVs1DrY.js} +23 -12
  30. package/dist/client/{DynamicWebComponent-y07rVJch.js → DynamicWebComponent-C3W7HSQm.js} +1 -1
  31. package/dist/client/{EodashDatePicker-CcOfyzGD.js → EodashDatePicker-BIAf1sMT.js} +59 -32
  32. package/dist/client/{EodashItemFilter-B9HCvIMi.js → EodashItemFilter-DPznh8UB.js} +20 -10
  33. package/dist/client/{EodashLayerControl-KStn7Nb_.js → EodashLayerControl-Bhxjw4V2.js} +29 -16
  34. package/dist/client/EodashLayoutSwitcher-C5qTEffW.js +61 -0
  35. package/dist/client/EodashMapBtns-WoGq8MuV.js +173 -0
  36. package/dist/client/{EodashStacInfo-C_hDy6Pd.js → EodashStacInfo-CSvvF2jI.js} +3 -18
  37. package/dist/client/{EodashTools-BXflvRf8.js → EodashTools-Cv1SXQ5y.js} +13 -13
  38. package/dist/client/{ExportState-C0QRemK1.js → ExportState-D-iuwaad.js} +58 -52
  39. package/dist/client/{Footer-7VGyGUAs.js → Footer-CyF0zRAk.js} +15 -13
  40. package/dist/client/{Header-BQJnXHYq.js → Header-CgD8jDKU.js} +33 -28
  41. package/dist/client/{MobileLayout-b8nQ-Vyl.js → MobileLayout-EKQ_kpSh.js} +69 -60
  42. package/dist/client/{PopUp-DgNrh9Df.js → PopUp-BsYLvWch.js} +19 -10
  43. package/dist/client/ProcessList-C2xsLU2_.js +191 -0
  44. package/dist/client/{VImg-D4eT3IQ1.js → VImg-OHe8YTs2.js} +24 -24
  45. package/dist/client/{VMain-C3hN2-H3.js → VMain-PryTLU4a.js} +7 -7
  46. package/dist/client/{VOverlay-tAeNygaA.js → VOverlay-yUn7p-Uf.js} +64 -27
  47. package/dist/client/{VTooltip-B0Q3iHMZ.js → VTooltip-DZ0fjpB3.js} +13 -10
  48. package/dist/client/{WidgetsContainer-CtDHfCYf.js → WidgetsContainer-B9LBadcC.js} +1 -1
  49. package/dist/client/asWebComponent-By_7_JjS.js +19193 -0
  50. package/dist/client/async-DkSu_u2K.js +740 -0
  51. package/dist/client/eo-dash.js +1 -1
  52. package/dist/client/{forwardRefs-CIFAqXaZ.js → forwardRefs-BXxrv98s.js} +31 -4
  53. package/dist/client/handling-CgmFXkW6.js +1212 -0
  54. package/dist/client/helpers-Dy0Q13tP.js +4534 -0
  55. package/dist/client/{index-DvcUndod.js → index-BuhOHXKv.js} +2 -4
  56. package/dist/client/{index-BQ16n4Sk.js → index-Ch_HchK3.js} +39 -32
  57. package/dist/client/{index-Cv7HBz49.js → index-Dqj4tbx2.js} +2 -2
  58. package/dist/client/index-skjhlH8u.js +376 -0
  59. package/dist/client/{ssrBoot-BP7SYRyC.js → ssrBoot-Zgc_Ttvi.js} +2 -2
  60. package/dist/client/templates.js +850 -0
  61. package/dist/client/transition-C98Yn4Vo.js +40 -0
  62. package/dist/node/cli.js +16 -6
  63. package/dist/node/types.d.ts +1 -1
  64. package/dist/types/core/client/App.vue.d.ts +2 -2
  65. package/dist/types/core/client/asWebComponent.d.ts +1 -1
  66. package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +1 -3
  67. package/dist/types/core/client/components/Footer.vue.d.ts +1 -105
  68. package/dist/types/core/client/components/IframeWrapper.vue.d.ts +1 -1
  69. package/dist/types/core/client/components/MobileLayout.vue.d.ts +1 -324
  70. package/dist/types/core/client/composables/DefineEodash.d.ts +2 -2
  71. package/dist/types/core/client/composables/DefineTemplate.d.ts +1 -1
  72. package/dist/types/core/client/composables/DefineWidgets.d.ts +4 -4
  73. package/dist/types/core/client/composables/index.d.ts +24 -2
  74. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +9 -6
  75. package/dist/types/core/client/eodashSTAC/helpers.d.ts +20 -5
  76. package/dist/types/core/client/eodashSTAC/parquet.d.ts +2 -0
  77. package/dist/types/core/client/plugins/vuetify.d.ts +7 -4
  78. package/dist/types/core/client/store/actions.d.ts +3 -2
  79. package/dist/types/core/client/store/stac.d.ts +16 -13
  80. package/dist/types/core/client/store/states.d.ts +14 -4
  81. package/dist/types/core/client/types.d.ts +45 -30
  82. package/dist/types/core/client/utils/index.d.ts +2 -0
  83. package/dist/types/core/client/utils/keys.d.ts +4 -4
  84. package/dist/types/core/client/utils/states.d.ts +59 -47
  85. package/dist/types/core/client/views/Dashboard.vue.d.ts +2 -2
  86. package/dist/types/templates/baseConfig.d.ts +4 -0
  87. package/dist/types/templates/compare.d.ts +210 -0
  88. package/dist/types/templates/expert.d.ts +151 -0
  89. package/dist/types/templates/index.d.ts +6 -0
  90. package/dist/types/templates/light.d.ts +145 -0
  91. package/dist/types/widgets/EodashDatePicker.vue.d.ts +1 -458
  92. package/dist/types/widgets/EodashItemFilter.vue.d.ts +3 -3
  93. package/dist/types/widgets/EodashLayerControl.vue.d.ts +14 -7
  94. package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +1 -3
  95. package/dist/types/widgets/EodashMap/index.vue.d.ts +1 -4
  96. package/dist/types/widgets/EodashMapBtns.vue.d.ts +8 -8
  97. package/dist/types/widgets/EodashProcess/ProcessList.vue.d.ts +8 -1
  98. package/dist/types/widgets/EodashProcess/index.vue.d.ts +8 -4
  99. package/dist/types/widgets/EodashProcess/methods/async.d.ts +18 -18
  100. package/dist/types/widgets/EodashProcess/methods/composables.d.ts +3 -2
  101. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/index.d.ts +1 -0
  102. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.d.ts +6 -0
  103. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.d.ts +4 -0
  104. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +5 -0
  105. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/index.d.ts +1 -0
  106. package/dist/types/widgets/EodashProcess/methods/handling.d.ts +12 -5
  107. package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +72 -41
  108. package/dist/types/widgets/EodashProcess/methods/utils.d.ts +41 -21
  109. package/dist/types/widgets/EodashProcess/states.d.ts +11 -0
  110. package/dist/types/widgets/EodashProcess/types.d.ts +41 -0
  111. package/dist/types/widgets/EodashStacInfo.vue.d.ts +14 -14
  112. package/dist/types/widgets/EodashTools.vue.d.ts +3 -3
  113. package/dist/types/widgets/ExportState.vue.d.ts +1 -1
  114. package/dist/types/widgets/PopUp.vue.d.ts +11 -16
  115. package/dist/types/widgets/WidgetsContainer.vue.d.ts +3 -6
  116. package/package.json +53 -45
  117. package/templates/baseConfig.js +68 -0
  118. package/templates/compare.js +162 -0
  119. package/templates/expert.js +123 -0
  120. package/templates/index.js +8 -0
  121. package/templates/light.js +130 -0
  122. package/widgets/EodashDatePicker.vue +80 -31
  123. package/widgets/EodashItemFilter.vue +26 -11
  124. package/widgets/EodashLayerControl.vue +20 -11
  125. package/widgets/EodashLayoutSwitcher.vue +6 -3
  126. package/widgets/EodashMap/index.vue +3 -8
  127. package/widgets/EodashMap/methods/create-layers-config.js +4 -3
  128. package/widgets/EodashMap/methods/index.js +33 -23
  129. package/widgets/EodashMapBtns.vue +83 -41
  130. package/widgets/EodashProcess/ProcessList.vue +34 -10
  131. package/widgets/EodashProcess/index.vue +55 -20
  132. package/widgets/EodashProcess/methods/async.js +77 -59
  133. package/widgets/EodashProcess/methods/composables.js +21 -14
  134. package/widgets/EodashProcess/methods/custom-endpoints/chart/index.js +35 -0
  135. package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +275 -0
  136. package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +116 -0
  137. package/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.js +94 -0
  138. package/widgets/EodashProcess/methods/custom-endpoints/layers/index.js +33 -0
  139. package/widgets/EodashProcess/methods/handling.js +127 -80
  140. package/widgets/EodashProcess/methods/outputs.js +376 -125
  141. package/widgets/EodashProcess/methods/utils.js +398 -10
  142. package/widgets/EodashProcess/states.js +13 -0
  143. package/widgets/EodashProcess/types.ts +46 -0
  144. package/widgets/EodashStacInfo.vue +2 -17
  145. package/widgets/EodashTools.vue +13 -13
  146. package/widgets/WidgetsContainer.vue +1 -1
  147. package/core/client/eodash.js +0 -454
  148. package/dist/client/EodashLayoutSwitcher-DqeFO3RN.js +0 -52
  149. package/dist/client/EodashMapBtns-5BF27qJB.js +0 -131
  150. package/dist/client/ProcessList-C62SOVO6.js +0 -484
  151. package/dist/client/asWebComponent-BJ2NWunV.js +0 -12479
  152. package/dist/client/eo-dash.css +0 -5
  153. package/dist/client/index-Da5xXX6Q.js +0 -780
  154. package/dist/client/transition-Cdb4K27U.js +0 -37
  155. package/dist/types/core/client/eodash.d.ts +0 -8
@@ -1,9 +1,272 @@
1
1
  import mustache from "mustache";
2
2
  import { extractLayerConfig } from "@/eodashSTAC/helpers";
3
3
  import axios from "@/plugins/axios";
4
- import { createLayerDefinition } from "./utils";
5
- import { pollProcessStatus } from "./async";
6
- import { indicator } from "@/store/states";
4
+ import { createTiffLayerDefinition, separateEndpointLinks } from "./utils";
5
+ import { useSTAcStore } from "@/store/stac";
6
+ import { isFirstLoad } from "@/utils/states";
7
+
8
+ ////// --- CHARTS --- //////
9
+ /**
10
+ * @param {object} options
11
+ * @param {import("stac-ts").StacLink[] | undefined} options.links
12
+ * @param {Record<string,any> | undefined} options.jsonformValue
13
+ * @param {string} options.specUrl
14
+ * @param {(input:import("^/EodashProcess/types").CustomEnpointInput)=>Promise<Record<string,any>[] | undefined | null>} [options.customEndpointsHandler]
15
+ * @param {import("vue").Ref<boolean>} options.isPolling
16
+ * @param {import("stac-ts").StacCollection} options.selectedStac
17
+ * @param {Record<string,any>} options.jsonformSchema
18
+ * @param {import("vue").Ref<import("../types").AsyncJob[]>} options.jobs
19
+ * @param {boolean} [options.enableCompare=false] - Whether to enable compare mode
20
+ * @returns {Promise<[import("@eox/chart").EOxChart["spec"] | null,Record<string,any>|null]>}
21
+ **/
22
+ export async function processCharts({
23
+ links,
24
+ jsonformValue,
25
+ specUrl,
26
+ customEndpointsHandler,
27
+ jsonformSchema,
28
+ selectedStac,
29
+ isPolling,
30
+ jobs,
31
+ enableCompare = false,
32
+ }) {
33
+ if (!specUrl || !links) return [null, null];
34
+ /** @type {import("vega-lite").TopLevelSpec} **/
35
+ const spec = await axios.get(specUrl).then((resp) => {
36
+ return resp.data;
37
+ });
38
+
39
+ /** @type {Record<string,any>} */
40
+ const dataValues = {};
41
+
42
+ const [standardLinks, endpointLinks] = separateEndpointLinks(
43
+ links,
44
+ "service",
45
+ undefined,
46
+ );
47
+
48
+ const data =
49
+ customEndpointsHandler &&
50
+ jsonformValue &&
51
+ (await customEndpointsHandler({
52
+ jsonformSchema,
53
+ jsonformValue,
54
+ links: endpointLinks,
55
+ selectedStac,
56
+ isPolling,
57
+ jobs,
58
+ enableCompare,
59
+ }));
60
+
61
+ if (data && data.length) {
62
+ //@ts-expect-error we assume data to exist in spec
63
+ spec.data.values = data;
64
+ return [spec, dataValues];
65
+ }
66
+
67
+ const dataLinks = standardLinks.filter((link) => link.rel === "service");
68
+ try {
69
+ checkForData: for (const link of dataLinks ?? []) {
70
+ switch (link.type) {
71
+ case undefined:
72
+ continue;
73
+ case "application/json":
74
+ await injectVegaInlineData(spec, {
75
+ url: link.href,
76
+ jsonformValue: jsonformValue,
77
+ link: link,
78
+ flatstyleUrl: /** @type string */ (link["eox:flatstyle"]),
79
+ jsonformSchema,
80
+ });
81
+ break checkForData;
82
+ case "text/csv":
83
+ await injectVegaUrlData(spec, {
84
+ url: link.href,
85
+ jsonformValue: jsonformValue,
86
+ flatstyleUrl: /** @type string */ (link["eox:flatstyle"]),
87
+ });
88
+ break checkForData;
89
+ default:
90
+ // this is not used anymore,
91
+ // but we should check it specific types may need this
92
+
93
+ // dataValues[/** @type {string} */ (link.id)] = await axios
94
+ // .get(
95
+ // mustache.render(link.href, {
96
+ // ...(jsonformValue ?? {}),
97
+ // ...(link["eox:flatstyle"] ?? {}), // TODO
98
+ // }),
99
+ // )
100
+ // .then((resp) => resp.data);
101
+ break;
102
+ }
103
+ }
104
+ } catch (e) {
105
+ console.error("[eodash] Error while injecting Vega data", e);
106
+ }
107
+ return [spec, dataValues];
108
+ }
109
+
110
+ /**
111
+ *
112
+ * @param {import("vega-lite").TopLevelSpec} spec
113
+ * @param {object} injectables
114
+ * @param {string} injectables.url
115
+ * @param {Record<string,any>} [injectables.jsonformValue]
116
+ * @param {import("stac-ts").StacLink} injectables.link
117
+ * @param {url} [injectables.flatstyleUrl]
118
+ * @param {import("json-schema").JSONSchema7} [injectables.jsonformSchema]
119
+ */
120
+ async function injectVegaInlineData(
121
+ spec,
122
+ { url, jsonformValue, link, flatstyleUrl, jsonformSchema },
123
+ ) {
124
+ if (!spec.data) {
125
+ return;
126
+ }
127
+ if (link.method == "GET") {
128
+ // we see if any of the multiQuery values match an array in the jsonformValue
129
+ // and if so, we can do multiple requests and merge all data together.
130
+ //@ts-expect-error type jsonform Schema
131
+ const multiQuery = jsonformSchema?.options?.multiQuery;
132
+ const matches = Object.keys(jsonformValue ?? {}).filter((key) => {
133
+ return Array.isArray(multiQuery)
134
+ ? multiQuery.includes(key)
135
+ : multiQuery === key;
136
+ });
137
+ if (matches.length > 0 && jsonformValue) {
138
+ const dataValues = [];
139
+ for (const match of matches) {
140
+ if (Array.isArray(jsonformValue[match])) {
141
+ for (const value of jsonformValue[match]) {
142
+ const dataUrl = await renderDataUrl(
143
+ url,
144
+ { ...jsonformValue, [match]: value },
145
+ flatstyleUrl,
146
+ );
147
+ dataValues.push(await axios.get(dataUrl).then((resp) => resp.data));
148
+ }
149
+ } else {
150
+ const dataUrl = await renderDataUrl(url, jsonformValue, flatstyleUrl);
151
+ dataValues.push(await axios.get(dataUrl).then((resp) => resp.data));
152
+ }
153
+ }
154
+ /** @type {import("vega-lite/build/src/data").InlineData} */
155
+ (spec.data).values = dataValues.flat();
156
+ return spec;
157
+ }
158
+ // if no array matches, we can just do a single request
159
+ const dataUrl = await renderDataUrl(url, jsonformValue, flatstyleUrl);
160
+ /** @type {import("vega-lite/build/src/data").InlineData} */
161
+ (spec.data).values = await axios.get(dataUrl).then((resp) => {
162
+ return resp.data;
163
+ });
164
+ } else if (link.method == "POST") {
165
+ // get body template to be used in POST request, check first if available
166
+ if (!link.body) {
167
+ console.error(
168
+ "[eodash] Inline data POST request requires a body template",
169
+ );
170
+ return spec;
171
+ }
172
+ /** @type {string} */
173
+ const bodyTemplate = await axios
174
+ // @ts-expect-error we assume link.body to be a string, not defined in stac-ts
175
+ .get(link.body, { responseType: "text" })
176
+ .then((resp) => {
177
+ return resp.data;
178
+ });
179
+ const body = JSON.parse(
180
+ mustache.render(bodyTemplate, {
181
+ ...(jsonformValue ?? {}),
182
+ }),
183
+ );
184
+ /** @type {import("vega-lite/build/src/data").InlineData} */
185
+ (spec.data).values = await axios.post(url, body).then((resp) => {
186
+ return resp.data;
187
+ });
188
+ }
189
+ return spec;
190
+ }
191
+
192
+ /**
193
+ * @param {import("vega-lite").TopLevelSpec} spec
194
+ * @param {object} injectables
195
+ * @param {string} injectables.url
196
+ * @param {Record<string,any>} [injectables.jsonformValue]
197
+ * @param {url} [injectables.flatstyleUrl]
198
+ */
199
+ async function injectVegaUrlData(spec, { url, jsonformValue, flatstyleUrl }) {
200
+ if (!spec.data) {
201
+ return;
202
+ }
203
+ const dataUrl = await renderDataUrl(url, jsonformValue, flatstyleUrl);
204
+ /** @type {import("vega").UrlData} */
205
+ (spec.data).url = dataUrl;
206
+ return spec;
207
+ }
208
+ /**
209
+ *
210
+ * @param {string} url
211
+ * @param {Record<string,any>} [jsonformValue]
212
+ * @param {string} [flatstyleUrl]
213
+ */
214
+ async function renderDataUrl(url, jsonformValue, flatstyleUrl) {
215
+ let flatStyles = {};
216
+ if (flatstyleUrl) {
217
+ flatStyles = await axios.get(flatstyleUrl).then((resp) => resp.data);
218
+ }
219
+
220
+ return mustache.render(url, {
221
+ ...(jsonformValue ?? {}),
222
+ ...flatStyles,
223
+ });
224
+ }
225
+
226
+ /////// MAP LAYERS ///////
227
+
228
+ /**
229
+ * @param {object} options
230
+ * @param {import("stac-ts").StacLink[] | undefined} options.links
231
+ * @param {Record<string,any> | undefined} options.jsonformValue
232
+ * @param {string} options.layerId
233
+ * @param {string} [options.projection]
234
+ */
235
+ export async function processGeoTiff({
236
+ links,
237
+ jsonformValue,
238
+ layerId,
239
+ projection,
240
+ }) {
241
+ if (!links) return;
242
+
243
+ const [geotiffLinks, _] = separateEndpointLinks(
244
+ links,
245
+ "service",
246
+ "image/tiff",
247
+ );
248
+
249
+ if (!geotiffLinks.length) {
250
+ return;
251
+ }
252
+ let urls = [];
253
+ let processId = "";
254
+ for (const link of geotiffLinks ?? []) {
255
+ urls.push(mustache.render(link.href, { ...(jsonformValue ?? {}) }));
256
+ }
257
+ const definitions = await Promise.all(
258
+ geotiffLinks.map((geotiffLink) =>
259
+ createTiffLayerDefinition(
260
+ geotiffLink,
261
+ layerId,
262
+ urls,
263
+ projection,
264
+ processId,
265
+ ),
266
+ ),
267
+ ).then((defs) => defs.filter((defs) => !!defs));
268
+ return definitions;
269
+ }
7
270
 
8
271
  /**
9
272
  * @param {import("stac-ts").StacLink[] | undefined} links
@@ -15,12 +278,13 @@ export function processImage(links, jsonformValue, origBbox) {
15
278
  const imageLinks = links.filter(
16
279
  (link) => link.rel === "service" && link.type === "image/png",
17
280
  );
281
+ /** @type {import("@eox/map/src/layers").EOxLayerType<"Image","ImageStatic">[]} */
18
282
  const layers = [];
19
283
  for (const link of imageLinks) {
20
284
  layers.push({
21
285
  type: "Image",
22
286
  properties: {
23
- id: link.id,
287
+ id: link.id + "_process",
24
288
  title: "Results " + link.id,
25
289
  },
26
290
  source: {
@@ -42,12 +306,12 @@ export function processImage(links, jsonformValue, origBbox) {
42
306
  */
43
307
  export async function processVector(links, jsonformValue, layerId) {
44
308
  if (!links) return;
45
- /** @type {Record<string,any>[]} */
309
+ /** @type {import("@eox/map/src/layers").EOxLayerType<"Vector",any>[]} */
46
310
  const layers = [];
47
311
  const vectorLinks = links.filter(
48
312
  (link) => link.rel === "service" && link.type === "application/geo+json",
49
313
  );
50
- if (vectorLinks.length === 0) return layers;
314
+ if (!vectorLinks.length) return layers;
51
315
 
52
316
  let flatStyleJSON = null;
53
317
 
@@ -63,12 +327,12 @@ export async function processVector(links, jsonformValue, layerId) {
63
327
  /** @type {Record<string,any>|undefined} */
64
328
  let style;
65
329
  if (flatStyleJSON) {
66
- const extracted = extractLayerConfig(flatStyleJSON);
330
+ const extracted = extractLayerConfig(layerId ?? "", flatStyleJSON);
67
331
  layerConfig = extracted.layerConfig;
68
332
  style = extracted.style;
69
333
  }
70
-
71
- layers.push({
334
+ /** @type {import("@eox/map/src/layers").EOxLayerType<"Vector","Vector"|"FlatGeoBuf">} */
335
+ const layer = {
72
336
  type: "Vector",
73
337
  source: {
74
338
  type: "Vector",
@@ -78,139 +342,126 @@ export async function processVector(links, jsonformValue, layerId) {
78
342
  format: "GeoJSON",
79
343
  },
80
344
  properties: {
81
- id: layerId + "_vector_process",
345
+ id: link.id + "_process",
82
346
  title: "Results " + layerId,
83
- ...(layerConfig && { ...layerConfig, ...(style && { style: style }) }),
347
+ ...(layerConfig && { ...layerConfig }),
84
348
  },
85
- });
349
+ ...(style && { style }),
350
+ };
351
+ layers.push(layer);
86
352
  }
87
353
  return layers;
88
354
  }
89
355
 
90
356
  /**
91
- * @param {import("stac-ts").StacLink[] | undefined} links
92
- * @param {Record<string,any> | undefined} jsonformValue
93
- * @param {string} specUrl
94
- * @returns {Promise<[import("@eox/chart").EOxChart["spec"] | null,Record<string,any>|null]>}
95
- **/
96
- export async function getChartValues(links, jsonformValue, specUrl) {
97
- if (!specUrl || !links) return [null, null];
98
- /** @type {import("vega").Spec} */
99
- const spec = await axios.get(specUrl).then((resp) => {
100
- return resp.data;
101
- });
102
- // //@ts-expect-error NamedData
103
- // const dataName = spec?.data?.name;
104
- const dataLinks = links.filter(
105
- (link) => link.rel === "service", // && dataName && link.id === dataName,
106
- );
357
+ * Unified wrapper for processing map layer types (Vector, Image, GeoTiff)
358
+ * @param {object} options
359
+ * @param {import("stac-ts").StacLink[] | undefined} options.links
360
+ * @param {Record<string,any> | undefined} options.jsonformValue
361
+ * @param {string} options.layerId
362
+ * @param {string} [options.projection] - Required for GeoTiff layers
363
+ * @param {number[]} options.origBbox - Required for Image layers
364
+ * @param {import("vue").Ref<boolean>} options.isPolling
365
+ * @param {import("stac-ts").StacCollection} options.selectedStac
366
+ * @param {import("json-schema").JSONSchema7} options.jsonformSchema
367
+ * @param {import("vue").Ref<import("../types").AsyncJob[]>} options.jobs
368
+ * @param {(input:import("../types").CustomEnpointInput)=>Promise<import("@eox/map").EoxLayer[]>} options.customLayersHandler
369
+ * @param {boolean} [options.enableCompare=false] - Whether to enable compare mode
370
+ */
371
+ export async function processLayers({
372
+ links,
373
+ jsonformValue,
374
+ layerId,
375
+ projection,
376
+ origBbox,
377
+ isPolling,
378
+ selectedStac,
379
+ jsonformSchema,
380
+ jobs,
381
+ customLayersHandler,
382
+ enableCompare = false,
383
+ }) {
384
+ if (!links) return [];
385
+ /** @type {import("@eox/map").EoxLayer[]} */
386
+ const layers = [];
107
387
 
108
- /** @type {Record<string,any>} */
109
- const dataValues = {};
110
- for (const link of dataLinks ?? []) {
111
- if (link.type && ["application/json", "text/csv"].includes(link.type)) {
112
- const dataUrl = mustache.render(link.href, {
113
- ...(jsonformValue ?? {}),
114
- ...(link["eox:flatstyle"] ?? {}),
388
+ const [standardLinks, endpointLinks] = separateEndpointLinks(
389
+ links,
390
+ "service",
391
+ undefined,
392
+ );
393
+ // Handle custom endpoints first if handler is provided
394
+ if (customLayersHandler && jsonformValue && selectedStac && jsonformSchema) {
395
+ if (endpointLinks.length > 0) {
396
+ const customLayers = await customLayersHandler({
397
+ jsonformValue,
398
+ links: endpointLinks,
399
+ selectedStac,
400
+ isPolling,
401
+ jsonformSchema,
402
+ jobs,
403
+ enableCompare,
115
404
  });
116
405
 
117
- // Wait for data to be retrieved
118
- const data = await axios.get(dataUrl).then((resp) => {
119
- return resp.data;
120
- });
121
- // @ts-expect-error we assume data to exist in spec
122
- spec.data.values = data;
123
- continue;
406
+ if (customLayers.length) {
407
+ layers.push(...customLayers);
408
+ }
124
409
  }
125
-
126
- dataValues[/** @type {string} */ (link.id)] = await axios
127
- .get(
128
- mustache.render(link.href, {
129
- ...(jsonformValue ?? {}),
130
- ...(link["eox:flatstyle"] ?? {}),
131
- }),
132
- )
133
- .then((resp) => resp.data);
134
410
  }
135
411
 
136
- return [spec, dataValues];
412
+ const vectorlayers = await processVector(
413
+ standardLinks,
414
+ jsonformValue,
415
+ layerId,
416
+ );
417
+
418
+ const imagelayers = processImage(standardLinks, jsonformValue, origBbox);
419
+
420
+ const geotiffLayers = await processGeoTiff({
421
+ links: standardLinks,
422
+ jsonformValue,
423
+ layerId,
424
+ projection,
425
+ });
426
+
427
+ layers.push(
428
+ ...[
429
+ ...(vectorlayers ?? []),
430
+ ...(imagelayers ?? []),
431
+ ...(geotiffLayers ?? []),
432
+ ],
433
+ );
434
+
435
+ return layers;
137
436
  }
138
437
 
438
+ ////// STAC PROCESSING /////
139
439
  /**
140
- * @param {import("stac-ts").StacLink[] | undefined} links
141
- * @param {Record<string,any> | undefined} jsonformValue
142
- * @param {import("vue").Ref<boolean>} isPolling
143
- * @param {string} layerId
144
- * @param {string} projection
440
+ * This function loads a STAC collection as a processing output.
441
+ * Currently, it only supports POI STAC collections
442
+ *
443
+ * @param {import("stac-ts").StacLink[]} links
444
+ * @param {Record<string,any>} jsonformValue
145
445
  */
146
- export async function processGeoTiff(
147
- links,
148
- jsonformValue,
149
- layerId,
150
- isPolling,
151
- projection,
152
- ) {
153
- if (!links) return;
154
- const geotiffLinks = links.filter(
155
- (link) => link.rel === "service" && link.type === "image/tiff",
446
+ export async function processSTAC(links, jsonformValue, enableCompare = false) {
447
+ const stacLink = links.find(
448
+ (link) =>
449
+ link.rel === "service" &&
450
+ link.type == "application/json; profile=collection" &&
451
+ link.endpoint === "STAC",
156
452
  );
157
- let urls = [];
158
- let processId = "";
159
- for (const link of geotiffLinks ?? []) {
160
- if (link.endpoint === "eoxhub_workspaces") {
161
- // TODO: prove of concept, needs to be reworked for sure
162
- // Special handling for eoxhub workspace process endpoints
163
- const postBody = await axios
164
- .get(/** @type {string} */ (link["body"]), { responseType: "text" })
165
- .then((resp) => resp.data);
166
- const jsonData = JSON.parse(
167
- mustache.render(postBody, { ...(jsonformValue ?? {}) }),
168
- );
169
- try {
170
- const responseProcess = await axios.post(link.href, jsonData, {
171
- headers: {
172
- "Content-Type": "application/json",
173
- },
174
- });
175
- console.log(responseProcess.headers.location);
176
- // We save the process status url into localstorage assigning it to the indicator id
177
- const currentJobs = JSON.parse(
178
- localStorage.getItem(indicator.value) || "[]",
179
- );
180
- currentJobs.push(responseProcess.headers.location);
181
- localStorage.setItem(indicator.value, JSON.stringify(currentJobs));
182
- await pollProcessStatus({
183
- processUrl: responseProcess.headers.location,
184
- isPolling,
185
- })
186
- .then((resultItem) => {
187
- // @ts-expect-error we have currently no definition of what is allowed as response
188
- const resultUrls = resultItem?.urls;
189
- if (resultUrls?.length < 1) {
190
- return;
191
- }
192
- //@ts-expect-error todo
193
- processId = resultItem?.id;
194
- urls = resultUrls;
195
- })
196
- .catch((error) => {
197
- if (error instanceof Error) {
198
- console.error("Polling failed:", error.message);
199
- } else {
200
- console.error("Unknown error occurred during polling:", error);
201
- }
202
- });
203
- } catch (error) {
204
- if (error instanceof Error) {
205
- console.error("Error sending POST request:", error.message);
206
- } else {
207
- console.error("Unknown error occurred:", error);
208
- }
209
- }
210
- } else {
211
- urls.push(mustache.render(link.href, { ...(jsonformValue ?? {}) }));
212
- }
213
- }
214
453
 
215
- return createLayerDefinition(links[0], layerId, urls, projection, processId);
454
+ if (!stacLink) return;
455
+ let poiUrl = mustache.render(stacLink.href, {
456
+ ...(jsonformValue ?? {}),
457
+ });
458
+ if (isFirstLoad.value) {
459
+ // prevent the map from jumping to the initial position
460
+ isFirstLoad.value = false;
461
+ }
462
+ const store = useSTAcStore();
463
+ const loadPOI = enableCompare
464
+ ? store.loadSelectedCompareSTAC
465
+ : store.loadSelectedSTAC;
466
+ await loadPOI(poiUrl, true);
216
467
  }