@eodash/eodash 5.0.0 → 5.2.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.
- package/README.md +1 -0
- package/core/client/App.vue +8 -2
- package/core/client/asWebComponent.js +5 -5
- package/core/client/components/DashboardLayout.vue +43 -26
- package/core/client/components/EodashOverlay.vue +5 -6
- package/core/client/components/ErrorAlert.vue +2 -2
- package/core/client/components/Footer.vue +4 -4
- package/core/client/components/Header.vue +3 -3
- package/core/client/components/MobileLayout.vue +47 -27
- package/core/client/composables/DefineEodash.js +38 -43
- package/core/client/composables/DefineTemplate.js +4 -2
- package/core/client/composables/DefineWidgets.js +14 -8
- package/core/client/composables/index.js +273 -23
- package/core/client/eodashSTAC/EodashCollection.js +84 -62
- package/core/client/eodashSTAC/createLayers.js +30 -0
- package/core/client/eodashSTAC/helpers.js +159 -28
- package/core/client/eodashSTAC/parquet.js +145 -0
- package/core/client/eodashSTAC/triggers.js +6 -3
- package/core/client/plugins/index.js +4 -3
- package/core/client/plugins/vuetify.js +3 -0
- package/core/client/store/actions.js +21 -4
- package/core/client/store/stac.js +93 -56
- package/core/client/store/states.js +15 -5
- package/core/client/types.ts +59 -43
- package/core/client/utils/index.js +79 -0
- package/core/client/utils/keys.js +2 -2
- package/core/client/utils/states.js +30 -5
- package/core/client/views/Dashboard.vue +36 -32
- package/core/client/vite-env.d.ts +7 -0
- package/dist/client/{DashboardLayout-CkWvOMOW.js → DashboardLayout-Dq9Kfe6O.js} +24 -13
- package/dist/client/{DynamicWebComponent-DYBbpvUK.js → DynamicWebComponent-DCBMXskE.js} +1 -1
- package/dist/client/{EodashDatePicker-CALmW3SI.js → EodashDatePicker-DtngxU6s.js} +59 -32
- package/dist/client/{EodashItemFilter-DlQiE713.js → EodashItemFilter-ClQebJQt.js} +20 -10
- package/dist/client/{EodashLayerControl-DEzEbft7.js → EodashLayerControl-BLBds28C.js} +29 -16
- package/dist/client/EodashLayoutSwitcher-DQ8SfVDd.js +61 -0
- package/dist/client/EodashMapBtns-B89_YBDw.js +326 -0
- package/dist/client/{EodashStacInfo-DPPxDkF6.js → EodashStacInfo-Dt1nF06x.js} +3 -18
- package/dist/client/{EodashTools-CUaL9s4H.js → EodashTools-DV5ykmWc.js} +13 -13
- package/dist/client/{ExportState-DjyIZVhl.js → ExportState-B6zZQUmE.js} +57 -52
- package/dist/client/{Footer-DyL0JoWt.js → Footer-DNhXs8k6.js} +15 -13
- package/dist/client/{Header-B5Dgty9l.js → Header-BjhN5JY4.js} +32 -28
- package/dist/client/MobileLayout-JelB6w1G.js +118 -0
- package/dist/client/{PopUp-BfB8s_ki.js → PopUp-CgpvNr3o.js} +18 -10
- package/dist/client/ProcessList-vecpxThi.js +198 -0
- package/dist/client/{VImg-FD1WVphJ.js → VImg-CETuikH2.js} +221 -26
- package/dist/client/{VMain-DJKG4SvM.js → VMain-Ci9DyaGU.js} +7 -7
- package/dist/client/{VTooltip-CfeefrXI.js → VTooltip-J4ac48X7.js} +12 -10
- package/dist/client/{WidgetsContainer-C2TaTdb6.js → WidgetsContainer-CCML4TyV.js} +1 -1
- package/dist/client/asWebComponent-ZyEzWOOf.js +19092 -0
- package/dist/client/async-B7jIrM53.js +804 -0
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{VOverlay-BzOdRu9h.js → forwardRefs-BQclvjMq.js} +332 -28
- package/dist/client/handling-BS24aG1q.js +1227 -0
- package/dist/client/helpers-wXK7Ywio.js +4556 -0
- package/dist/client/index-4UCzZi8B.js +376 -0
- package/dist/client/{index-4CT7Tz83.js → index-9KR-G20t.js} +2 -2
- package/dist/client/{index-CIHH_3dW.js → index-B2XpdgR6.js} +227 -86
- package/dist/client/material-symbols-outlined.woff2 +0 -0
- package/dist/client/material-symbols-rounded.woff2 +0 -0
- package/dist/client/material-symbols-sharp.woff2 +0 -0
- package/dist/client/material-symbols-subset.woff2 +0 -0
- package/dist/client/{ssrBoot-BP7SYRyC.js → ssrBoot-Zgc_Ttvi.js} +2 -2
- package/dist/client/templates.js +840 -0
- package/dist/client/transition-yBii4fu6.js +40 -0
- package/dist/node/cli.js +16 -6
- package/dist/node/types.d.ts +1 -1
- package/dist/types/core/client/App.vue.d.ts +2 -2
- package/dist/types/core/client/asWebComponent.d.ts +1 -1
- package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +1 -3
- package/dist/types/core/client/components/Footer.vue.d.ts +1 -105
- package/dist/types/core/client/components/IframeWrapper.vue.d.ts +1 -1
- package/dist/types/core/client/components/MobileLayout.vue.d.ts +1 -324
- package/dist/types/core/client/composables/DefineEodash.d.ts +2 -2
- package/dist/types/core/client/composables/DefineTemplate.d.ts +1 -1
- package/dist/types/core/client/composables/DefineWidgets.d.ts +4 -4
- package/dist/types/core/client/composables/index.d.ts +24 -2
- package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +9 -6
- package/dist/types/core/client/eodashSTAC/helpers.d.ts +25 -5
- package/dist/types/core/client/eodashSTAC/parquet.d.ts +2 -0
- package/dist/types/core/client/plugins/vuetify.d.ts +7 -4
- package/dist/types/core/client/store/actions.d.ts +3 -2
- package/dist/types/core/client/store/stac.d.ts +16 -13
- package/dist/types/core/client/store/states.d.ts +14 -4
- package/dist/types/core/client/types.d.ts +46 -31
- package/dist/types/core/client/utils/index.d.ts +2 -0
- package/dist/types/core/client/utils/keys.d.ts +4 -4
- package/dist/types/core/client/utils/states.d.ts +59 -47
- package/dist/types/core/client/views/Dashboard.vue.d.ts +2 -2
- package/dist/types/templates/baseConfig.d.ts +4 -0
- package/dist/types/templates/compare.d.ts +185 -0
- package/dist/types/templates/expert.d.ts +147 -0
- package/dist/types/templates/index.d.ts +6 -0
- package/dist/types/templates/light.d.ts +154 -0
- package/dist/types/widgets/EodashDatePicker.vue.d.ts +1 -458
- package/dist/types/widgets/EodashItemFilter.vue.d.ts +3 -3
- package/dist/types/widgets/EodashLayerControl.vue.d.ts +14 -7
- package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +1 -3
- package/dist/types/widgets/{EodashMapBtns.vue.d.ts → EodashMap/EodashMapBtns.vue.d.ts} +12 -8
- package/dist/types/widgets/EodashMap/index.vue.d.ts +9 -4
- package/dist/types/widgets/EodashProcess/ProcessList.vue.d.ts +8 -1
- package/dist/types/widgets/EodashProcess/index.vue.d.ts +8 -4
- package/dist/types/widgets/EodashProcess/methods/async.d.ts +19 -18
- package/dist/types/widgets/EodashProcess/methods/composables.d.ts +3 -2
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/index.d.ts +1 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.d.ts +6 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.d.ts +4 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +5 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/index.d.ts +1 -0
- package/dist/types/widgets/EodashProcess/methods/handling.d.ts +12 -5
- package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +72 -41
- package/dist/types/widgets/EodashProcess/methods/utils.d.ts +41 -21
- package/dist/types/widgets/EodashProcess/states.d.ts +11 -0
- package/dist/types/widgets/EodashProcess/types.d.ts +41 -0
- package/dist/types/widgets/EodashStacInfo.vue.d.ts +14 -14
- package/dist/types/widgets/EodashTools.vue.d.ts +3 -3
- package/dist/types/widgets/ExportState.vue.d.ts +1 -1
- package/dist/types/widgets/PopUp.vue.d.ts +11 -16
- package/dist/types/widgets/WidgetsContainer.vue.d.ts +3 -6
- package/package.json +55 -45
- package/templates/baseConfig.js +68 -0
- package/templates/compare.js +142 -0
- package/templates/expert.js +124 -0
- package/templates/index.js +8 -0
- package/templates/light.js +139 -0
- package/widgets/EodashDatePicker.vue +80 -31
- package/widgets/EodashItemFilter.vue +26 -11
- package/widgets/EodashLayerControl.vue +20 -11
- package/widgets/EodashLayoutSwitcher.vue +6 -3
- package/widgets/EodashMap/EodashMapBtns.vue +269 -0
- package/widgets/EodashMap/index.vue +255 -45
- package/widgets/EodashMap/methods/create-layers-config.js +4 -3
- package/widgets/EodashMap/methods/index.js +33 -23
- package/widgets/EodashProcess/ProcessList.vue +47 -11
- package/widgets/EodashProcess/index.vue +55 -20
- package/widgets/EodashProcess/methods/async.js +99 -60
- package/widgets/EodashProcess/methods/composables.js +21 -14
- package/widgets/EodashProcess/methods/custom-endpoints/chart/index.js +35 -0
- package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +275 -0
- package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +132 -0
- package/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.js +94 -0
- package/widgets/EodashProcess/methods/custom-endpoints/layers/index.js +33 -0
- package/widgets/EodashProcess/methods/handling.js +127 -80
- package/widgets/EodashProcess/methods/outputs.js +376 -125
- package/widgets/EodashProcess/methods/utils.js +442 -10
- package/widgets/EodashProcess/states.js +13 -0
- package/widgets/EodashProcess/types.ts +46 -0
- package/widgets/EodashStacInfo.vue +2 -17
- package/widgets/EodashTools.vue +13 -13
- package/widgets/WidgetsContainer.vue +1 -1
- package/core/client/eodash.js +0 -454
- package/dist/client/EodashLayoutSwitcher-CDeCV8F-.js +0 -52
- package/dist/client/EodashMapBtns-CktQCfa-.js +0 -131
- package/dist/client/MobileLayout-CRsg_5Q4.js +0 -1217
- package/dist/client/ProcessList-DTefwQZx.js +0 -484
- package/dist/client/asWebComponent-CLhcT715.js +0 -12479
- package/dist/client/eo-dash.css +0 -5
- package/dist/client/forwardRefs-Bon_Kku1.js +0 -245
- package/dist/client/index-Bm9cbtx5.js +0 -201
- package/dist/client/index-DiGDvTQU.js +0 -780
- package/dist/client/transition-C5I57hn6.js +0 -37
- package/dist/types/core/client/eodash.d.ts +0 -8
- package/widgets/EodashMapBtns.vue +0 -113
|
@@ -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 {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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:
|
|
345
|
+
id: link.id + "_process",
|
|
82
346
|
title: "Results " + layerId,
|
|
83
|
-
...(layerConfig && { ...layerConfig
|
|
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
|
-
*
|
|
92
|
-
* @param {
|
|
93
|
-
* @param {
|
|
94
|
-
* @
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* @param {
|
|
144
|
-
* @param {string}
|
|
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
|
|
147
|
-
links
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
-
|
|
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
|
}
|