@eodash/eodash 5.0.0 → 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.
- 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 +42 -25
- package/core/client/components/EodashOverlay.vue +1 -1
- 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 +9 -10
- 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 +80 -47
- package/core/client/eodashSTAC/helpers.js +136 -27
- 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-ByVs1DrY.js} +23 -12
- package/dist/client/{DynamicWebComponent-DYBbpvUK.js → DynamicWebComponent-C3W7HSQm.js} +1 -1
- package/dist/client/{EodashDatePicker-CALmW3SI.js → EodashDatePicker-BIAf1sMT.js} +59 -32
- package/dist/client/{EodashItemFilter-DlQiE713.js → EodashItemFilter-DPznh8UB.js} +20 -10
- package/dist/client/{EodashLayerControl-DEzEbft7.js → EodashLayerControl-Bhxjw4V2.js} +29 -16
- package/dist/client/EodashLayoutSwitcher-C5qTEffW.js +61 -0
- package/dist/client/EodashMapBtns-WoGq8MuV.js +173 -0
- package/dist/client/{EodashStacInfo-DPPxDkF6.js → EodashStacInfo-CSvvF2jI.js} +3 -18
- package/dist/client/{EodashTools-CUaL9s4H.js → EodashTools-Cv1SXQ5y.js} +13 -13
- package/dist/client/{ExportState-DjyIZVhl.js → ExportState-D-iuwaad.js} +58 -52
- package/dist/client/{Footer-DyL0JoWt.js → Footer-CyF0zRAk.js} +15 -13
- package/dist/client/{Header-B5Dgty9l.js → Header-CgD8jDKU.js} +33 -28
- package/dist/client/{MobileLayout-CRsg_5Q4.js → MobileLayout-EKQ_kpSh.js} +69 -60
- package/dist/client/{PopUp-BfB8s_ki.js → PopUp-BsYLvWch.js} +19 -10
- package/dist/client/ProcessList-C2xsLU2_.js +191 -0
- package/dist/client/{VImg-FD1WVphJ.js → VImg-OHe8YTs2.js} +24 -24
- package/dist/client/{VMain-DJKG4SvM.js → VMain-PryTLU4a.js} +7 -7
- package/dist/client/{VOverlay-BzOdRu9h.js → VOverlay-yUn7p-Uf.js} +64 -27
- package/dist/client/{VTooltip-CfeefrXI.js → VTooltip-DZ0fjpB3.js} +13 -10
- package/dist/client/{WidgetsContainer-C2TaTdb6.js → WidgetsContainer-B9LBadcC.js} +1 -1
- package/dist/client/asWebComponent-By_7_JjS.js +19193 -0
- package/dist/client/async-DkSu_u2K.js +740 -0
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-Bon_Kku1.js → forwardRefs-BXxrv98s.js} +31 -4
- package/dist/client/handling-CgmFXkW6.js +1212 -0
- package/dist/client/helpers-Dy0Q13tP.js +4534 -0
- package/dist/client/{index-Bm9cbtx5.js → index-BuhOHXKv.js} +2 -4
- package/dist/client/{index-CIHH_3dW.js → index-Ch_HchK3.js} +39 -32
- package/dist/client/{index-4CT7Tz83.js → index-Dqj4tbx2.js} +2 -2
- package/dist/client/index-skjhlH8u.js +376 -0
- package/dist/client/{ssrBoot-BP7SYRyC.js → ssrBoot-Zgc_Ttvi.js} +2 -2
- package/dist/client/templates.js +850 -0
- package/dist/client/transition-C98Yn4Vo.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 +20 -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 +45 -30
- 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 +210 -0
- package/dist/types/templates/expert.d.ts +151 -0
- package/dist/types/templates/index.d.ts +6 -0
- package/dist/types/templates/light.d.ts +145 -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/EodashMap/index.vue.d.ts +1 -4
- package/dist/types/widgets/EodashMapBtns.vue.d.ts +8 -8
- 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 +18 -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 +53 -45
- package/templates/baseConfig.js +68 -0
- package/templates/compare.js +162 -0
- package/templates/expert.js +123 -0
- package/templates/index.js +8 -0
- package/templates/light.js +130 -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/index.vue +3 -8
- package/widgets/EodashMap/methods/create-layers-config.js +4 -3
- package/widgets/EodashMap/methods/index.js +33 -23
- package/widgets/EodashMapBtns.vue +83 -41
- package/widgets/EodashProcess/ProcessList.vue +34 -10
- package/widgets/EodashProcess/index.vue +55 -20
- package/widgets/EodashProcess/methods/async.js +77 -59
- 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 +116 -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 +398 -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/ProcessList-DTefwQZx.js +0 -484
- package/dist/client/asWebComponent-CLhcT715.js +0 -12479
- package/dist/client/eo-dash.css +0 -5
- 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
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEmitLayersUpdate } from "@/composables";
|
|
2
|
+
import {
|
|
3
|
+
extractLayerConfig,
|
|
4
|
+
mergeGeojsons,
|
|
5
|
+
replaceLayer,
|
|
6
|
+
} from "@/eodashSTAC/helpers";
|
|
2
7
|
import axios from "@/plugins/axios";
|
|
8
|
+
import { getCompareLayers, getLayers } from "@/store/actions";
|
|
3
9
|
import { isMulti } from "@eox/jsonform/src/custom-inputs/spatial/utils";
|
|
4
10
|
|
|
5
11
|
/**
|
|
@@ -53,14 +59,13 @@ export function extractGeometries(jsonformValue, jsonformSchema) {
|
|
|
53
59
|
|
|
54
60
|
/**
|
|
55
61
|
*
|
|
56
|
-
* @param {
|
|
57
|
-
* @param {
|
|
62
|
+
* @param {import("stac-ts").StacLink} link
|
|
63
|
+
* @param {string} layerId
|
|
58
64
|
* @param {string[]} urls
|
|
59
|
-
* @param {
|
|
60
|
-
* @param {
|
|
61
|
-
* @returns
|
|
65
|
+
* @param {import("openlayers").ProjectionLike} projection
|
|
66
|
+
* @param {string} processId
|
|
62
67
|
*/
|
|
63
|
-
export async function
|
|
68
|
+
export async function createTiffLayerDefinition(
|
|
64
69
|
link,
|
|
65
70
|
layerId,
|
|
66
71
|
urls,
|
|
@@ -74,9 +79,7 @@ export async function createLayerDefinition(
|
|
|
74
79
|
.then((resp) => resp.data);
|
|
75
80
|
}
|
|
76
81
|
|
|
77
|
-
/** @type {Record<string,any>|undefined} */
|
|
78
82
|
let layerConfig;
|
|
79
|
-
/** @type {Record<string,any>|undefined} */
|
|
80
83
|
let style;
|
|
81
84
|
if (flatStyleJSON) {
|
|
82
85
|
const extracted = extractLayerConfig(layerId ?? "", flatStyleJSON);
|
|
@@ -85,6 +88,7 @@ export async function createLayerDefinition(
|
|
|
85
88
|
}
|
|
86
89
|
// We want to make sure the urls are alphabetically sorted
|
|
87
90
|
urls = urls.sort();
|
|
91
|
+
/** @type {import("@eox/map/src/layers").EOxLayerType<"WebGLTile","GeoTIFF"> | undefined} */
|
|
88
92
|
const layerdef =
|
|
89
93
|
urls.length > 0
|
|
90
94
|
? {
|
|
@@ -95,7 +99,7 @@ export async function createLayerDefinition(
|
|
|
95
99
|
sources: urls.map((url) => ({ url })),
|
|
96
100
|
},
|
|
97
101
|
properties: {
|
|
98
|
-
id:
|
|
102
|
+
id: link.id + "_process" + processId,
|
|
99
103
|
title: "Results " + layerId,
|
|
100
104
|
...(layerConfig && { layerConfig: layerConfig }),
|
|
101
105
|
layerControlToolsExpand: true,
|
|
@@ -136,3 +140,387 @@ export const download = (fileName, content) => {
|
|
|
136
140
|
URL.revokeObjectURL(url);
|
|
137
141
|
link.remove();
|
|
138
142
|
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Generate time pairs from a temporal extent
|
|
146
|
+
* @param {import("stac-ts").TemporalExtent} stacExtent - [start, end]
|
|
147
|
+
* @param {import("stac-ts").TemporalExtent} [userExtent] -[start, end]
|
|
148
|
+
* @param {string} [distribution] - daily, weekly, monthly, or yearly
|
|
149
|
+
*/
|
|
150
|
+
export function generateTimePairs(stacExtent, userExtent, distribution) {
|
|
151
|
+
// check whether the userExtent is provided
|
|
152
|
+
// if it is check that it doesn't exceed the stacExtent
|
|
153
|
+
// and clamp it otherwise
|
|
154
|
+
|
|
155
|
+
/** @type {string|Date} */
|
|
156
|
+
let from = "";
|
|
157
|
+
|
|
158
|
+
/** @type {string|Date} */
|
|
159
|
+
let to = "";
|
|
160
|
+
[from, to] = /** @type {[string, string]} */ (userExtent ?? ["", ""]);
|
|
161
|
+
|
|
162
|
+
const [stacFrom, stacTo] = /** @type {[string, string]} */ (
|
|
163
|
+
stacExtent ?? ["", ""]
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
if (from && to) {
|
|
168
|
+
from = new Date(from);
|
|
169
|
+
to = new Date(to);
|
|
170
|
+
} else {
|
|
171
|
+
from = new Date(stacFrom);
|
|
172
|
+
to = new Date(stacTo);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (from < new Date(stacFrom) || from > new Date(stacTo)) {
|
|
176
|
+
console.warn(
|
|
177
|
+
"[eodash] warn: start date is outside of the collection temporal extent and will be clamped",
|
|
178
|
+
`\nprovided start date:${from.toISOString()}`,
|
|
179
|
+
`\ncollection start date:${stacFrom}`,
|
|
180
|
+
);
|
|
181
|
+
from = new Date(stacFrom);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (to > new Date(stacTo) || to < new Date(stacFrom)) {
|
|
185
|
+
console.warn(
|
|
186
|
+
"[eodash] warn: end date is outside of the collection temporal extent and will be clamped",
|
|
187
|
+
`\nprovided end date:${to.toISOString()}`,
|
|
188
|
+
`\ncollection end date:${stacTo}`,
|
|
189
|
+
);
|
|
190
|
+
to = new Date(stacTo);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (from > to) {
|
|
194
|
+
console.error(
|
|
195
|
+
"[eodash] Error: start date is greater than end date",
|
|
196
|
+
from,
|
|
197
|
+
to,
|
|
198
|
+
);
|
|
199
|
+
return [];
|
|
200
|
+
}
|
|
201
|
+
} catch (e) {
|
|
202
|
+
//@ts-expect-error e should be an error
|
|
203
|
+
console.error("[eodash] Invalid date:", e.message);
|
|
204
|
+
return [];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const startDate = /** @type {Date} */ (from).toISOString();
|
|
208
|
+
const endDate = /** @type {Date} */ (to).toISOString();
|
|
209
|
+
|
|
210
|
+
if (!startDate || !endDate) {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
const times = [];
|
|
214
|
+
let latest = new Date(endDate);
|
|
215
|
+
const start = new Date(startDate);
|
|
216
|
+
const oneDay = 24 * 60 * 60 * 1000;
|
|
217
|
+
// Use fixed step of 1 day (in milliseconds)
|
|
218
|
+
const step =
|
|
219
|
+
distribution === "daily"
|
|
220
|
+
? oneDay
|
|
221
|
+
: distribution === "weekly"
|
|
222
|
+
? oneDay * 7
|
|
223
|
+
: distribution === "monthly"
|
|
224
|
+
? oneDay * 30
|
|
225
|
+
: distribution === "yearly"
|
|
226
|
+
? oneDay * 365
|
|
227
|
+
: oneDay;
|
|
228
|
+
|
|
229
|
+
// Add dates, limiting to 31 dates (30 pairs maximum)
|
|
230
|
+
while (latest >= start && times.length < 31) {
|
|
231
|
+
times.push(new Date(latest));
|
|
232
|
+
latest.setTime(latest.getTime() - step);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const timePairs = [];
|
|
236
|
+
for (let i = 0; i < times.length - 1; i++) {
|
|
237
|
+
timePairs.push([times[i].toISOString(), times[i + 1].toISOString()]);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return timePairs;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Filter links to separate those with and without endpoint property
|
|
245
|
+
* @param {import("stac-ts").StacLink[] | undefined} links
|
|
246
|
+
* @param {string} [relType] - Optional relationship type
|
|
247
|
+
* @param {string} [contentType] - Optional content type
|
|
248
|
+
* @returns {[import("stac-ts").StacLink[], import("stac-ts").StacLink[]]}
|
|
249
|
+
*/
|
|
250
|
+
export function separateEndpointLinks(links, relType, contentType) {
|
|
251
|
+
if (!links) return [[], []];
|
|
252
|
+
const standardLinks = [];
|
|
253
|
+
const endpointLinks = [];
|
|
254
|
+
|
|
255
|
+
for (const link of links) {
|
|
256
|
+
// Check if the link matches the specified relType and contentType (if provided)
|
|
257
|
+
const relTypeMatch = relType ? link.rel === relType : true;
|
|
258
|
+
const contentTypeMatch = contentType ? link.type === contentType : true;
|
|
259
|
+
|
|
260
|
+
if (relTypeMatch && contentTypeMatch) {
|
|
261
|
+
if (link.endpoint) {
|
|
262
|
+
endpointLinks.push(link);
|
|
263
|
+
} else {
|
|
264
|
+
standardLinks.push(link);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return [standardLinks, endpointLinks];
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Generates layer definitions for asynchronous process results.
|
|
274
|
+
* using AsyncProcessResults data structure.
|
|
275
|
+
* @param {import("^/EodashProcess/types").AsyncProcessResults} processResults
|
|
276
|
+
* @param {import("stac-ts").StacLink} endpointLink
|
|
277
|
+
* @param {import("stac-ts").StacCollection|null} selectedStac
|
|
278
|
+
* @param {string} [postfixId=""] - Optional layers id postfix
|
|
279
|
+
* @returns
|
|
280
|
+
*/
|
|
281
|
+
export async function creatAsyncProcessLayerDefinitions(
|
|
282
|
+
processResults,
|
|
283
|
+
endpointLink,
|
|
284
|
+
selectedStac,
|
|
285
|
+
postfixId = "",
|
|
286
|
+
) {
|
|
287
|
+
/** @type {import("@eox/map").EoxLayer[]} */
|
|
288
|
+
const layers = [];
|
|
289
|
+
const flatStyles = await fetchProcessStyles(endpointLink);
|
|
290
|
+
|
|
291
|
+
for (const resultItem of processResults) {
|
|
292
|
+
const flatStyleJSON = extractStyleFromResult(resultItem, flatStyles);
|
|
293
|
+
let style, layerConfig;
|
|
294
|
+
if (flatStyleJSON) {
|
|
295
|
+
const extracted = extractLayerConfig(
|
|
296
|
+
selectedStac?.id ?? "",
|
|
297
|
+
flatStyleJSON,
|
|
298
|
+
);
|
|
299
|
+
layerConfig = extracted.layerConfig;
|
|
300
|
+
style = extracted.style;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
switch (resultItem.type) {
|
|
304
|
+
case "image/tiff": {
|
|
305
|
+
layers.push({
|
|
306
|
+
type: "WebGLTile",
|
|
307
|
+
properties: {
|
|
308
|
+
id: endpointLink.id + "_process" + resultItem.id + postfixId,
|
|
309
|
+
title:
|
|
310
|
+
"Results " +
|
|
311
|
+
(selectedStac?.id ?? "") +
|
|
312
|
+
" " +
|
|
313
|
+
(resultItem.id ?? ""),
|
|
314
|
+
layerControlToolsExpand: true,
|
|
315
|
+
...(layerConfig && { layerConfig }),
|
|
316
|
+
},
|
|
317
|
+
source: {
|
|
318
|
+
type: "GeoTIFF",
|
|
319
|
+
normalize: !style,
|
|
320
|
+
sources: resultItem.urls.map((url) => ({ url })),
|
|
321
|
+
//@ts-expect-error TODO
|
|
322
|
+
...(selectedStac["eodash:mapProjection"]?.["name"] && {
|
|
323
|
+
//@ts-expect-error TODO
|
|
324
|
+
projection: selectedStac["eodash:mapProjection"]["name"],
|
|
325
|
+
}),
|
|
326
|
+
},
|
|
327
|
+
...(style && { style }),
|
|
328
|
+
});
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
case "application/geo+json": {
|
|
332
|
+
const mergedUrl = await mergeGeojsons(resultItem.urls);
|
|
333
|
+
layers.push({
|
|
334
|
+
type: "Vector",
|
|
335
|
+
source: {
|
|
336
|
+
type: "Vector",
|
|
337
|
+
format: "GeoJSON",
|
|
338
|
+
...(mergedUrl && { url: mergedUrl }),
|
|
339
|
+
},
|
|
340
|
+
properties: {
|
|
341
|
+
id: endpointLink.id + "_process_" + resultItem.id + postfixId,
|
|
342
|
+
title:
|
|
343
|
+
"Results " +
|
|
344
|
+
(selectedStac?.id ?? "") +
|
|
345
|
+
" " +
|
|
346
|
+
(resultItem.id ?? ""),
|
|
347
|
+
...(layerConfig && {
|
|
348
|
+
layerConfig: {
|
|
349
|
+
...layerConfig,
|
|
350
|
+
style,
|
|
351
|
+
},
|
|
352
|
+
}),
|
|
353
|
+
},
|
|
354
|
+
...(!style?.variables && { style }),
|
|
355
|
+
interactions: [],
|
|
356
|
+
});
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
default:
|
|
360
|
+
console.warn(
|
|
361
|
+
`[eodash] Unsupported result type "${resultItem.type}" for ${resultItem.id} layer creation.`,
|
|
362
|
+
);
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return layers;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* @param {import("stac-ts").StacLink} endpointLink
|
|
371
|
+
* @returns
|
|
372
|
+
*/
|
|
373
|
+
async function fetchProcessStyles(endpointLink) {
|
|
374
|
+
/** @type {import("@/types").EodashStyleJson | (Record<string,import("@/types").EodashStyleJson> & {multipleStyles:true}) | null} */
|
|
375
|
+
let flatStyles = null;
|
|
376
|
+
if (endpointLink["eox:flatstyle"]) {
|
|
377
|
+
if (typeof endpointLink["eox:flatstyle"] === "string") {
|
|
378
|
+
flatStyles = await axios
|
|
379
|
+
.get(/** @type {string} */ (endpointLink["eox:flatstyle"]))
|
|
380
|
+
.then((resp) => /** @type {} */ resp.data);
|
|
381
|
+
} else if (
|
|
382
|
+
Array.isArray(endpointLink["eox:flatstyle"]) &&
|
|
383
|
+
endpointLink["eox:flatstyle"].length
|
|
384
|
+
) {
|
|
385
|
+
// multipleStyles as a flag to indicate it
|
|
386
|
+
flatStyles = { multipleStyles: true };
|
|
387
|
+
|
|
388
|
+
await Promise.all(
|
|
389
|
+
/** @type {{id:string;url:string}[]} */
|
|
390
|
+
(endpointLink["eox:flatstyle"]).map(async (styleDict) => {
|
|
391
|
+
//@ts-expect-error TODO
|
|
392
|
+
flatStyles[styleDict.id] = await axios
|
|
393
|
+
.get(styleDict.url)
|
|
394
|
+
.then(
|
|
395
|
+
(resp) =>
|
|
396
|
+
/** @type {import("@/types").EodashStyleJson} */ (resp.data),
|
|
397
|
+
);
|
|
398
|
+
}),
|
|
399
|
+
);
|
|
400
|
+
} else {
|
|
401
|
+
// multipleStyles as a flag to indicate it
|
|
402
|
+
flatStyles = { multipleStyles: true };
|
|
403
|
+
await Promise.all(
|
|
404
|
+
Object.keys(endpointLink["eox:flatstyle"] ?? {}).map((key) => {
|
|
405
|
+
//@ts-expect-error TODO
|
|
406
|
+
flatStyles[key] = axios
|
|
407
|
+
//@ts-expect-error TODO
|
|
408
|
+
.get(endpointLink["eox:flatstyle"][key])
|
|
409
|
+
.then((resp) => resp.data);
|
|
410
|
+
}),
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return flatStyles;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
*
|
|
419
|
+
* @param {import("^/EodashProcess/types").AsyncProcessResults[number]} processResult
|
|
420
|
+
* @param {null| import("@/types").EodashStyleJson | (Record<string,import("@/types").EodashStyleJson> & {multipleStyles:true})} flatStyles
|
|
421
|
+
*/
|
|
422
|
+
function extractStyleFromResult(processResult, flatStyles) {
|
|
423
|
+
if (!flatStyles) {
|
|
424
|
+
return undefined;
|
|
425
|
+
}
|
|
426
|
+
if (!("multipleStyles" in flatStyles)) {
|
|
427
|
+
return flatStyles;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const outputKey = processResult.id;
|
|
431
|
+
if (!outputKey || !(outputKey in flatStyles)) {
|
|
432
|
+
return undefined;
|
|
433
|
+
}
|
|
434
|
+
return flatStyles[outputKey];
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
*
|
|
439
|
+
* @param {import("^/EodashProcess/types").EOxHubProcessResults} resultItem
|
|
440
|
+
* @returns {import("^/EodashProcess/types").AsyncProcessResults}
|
|
441
|
+
*/
|
|
442
|
+
export function extractAsyncResults(resultItem) {
|
|
443
|
+
if (!resultItem) {
|
|
444
|
+
return [];
|
|
445
|
+
}
|
|
446
|
+
// if no type specified we assume the results are geotiff sources
|
|
447
|
+
if ("urls" in resultItem && Array.isArray(resultItem.urls)) {
|
|
448
|
+
return [{ id: "", urls: resultItem.urls, type: "image/tiff" }];
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const extracted = [];
|
|
452
|
+
for (const key in resultItem) {
|
|
453
|
+
if (key === "id") {
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
extracted.push({
|
|
457
|
+
// used as a key to identify the corresponding style
|
|
458
|
+
id: key,
|
|
459
|
+
//@ts-expect-error TODO
|
|
460
|
+
urls: /** @type {string[]} */ (resultItem[key].urls),
|
|
461
|
+
//@ts-expect-error TODO
|
|
462
|
+
type: /** @type {string} */ (resultItem[key].mimetype),
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
return extracted;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* @param {import("@eox/map").EOxMap | null} mapElement
|
|
469
|
+
* @param {import("@eox/map").EoxLayer[]} processLayers
|
|
470
|
+
*/
|
|
471
|
+
export const applyProcessLayersToMap = (mapElement, processLayers) => {
|
|
472
|
+
if (!processLayers.length || !mapElement) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const getMapLayers =
|
|
476
|
+
mapElement.id === "compare" ? getCompareLayers : getLayers;
|
|
477
|
+
const currentLayers = [...getMapLayers()];
|
|
478
|
+
|
|
479
|
+
let analysisGroup =
|
|
480
|
+
/*** @type {import("@eox/map/src/layers").EOxLayerTypeGroup | undefined} */ (
|
|
481
|
+
currentLayers.find((l) => l.properties?.id.includes("AnalysisGroup"))
|
|
482
|
+
);
|
|
483
|
+
if (!analysisGroup) {
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
for (const layer of processLayers) {
|
|
488
|
+
const exists = analysisGroup.layers.find(
|
|
489
|
+
(l) => l.properties?.id === layer.properties?.id,
|
|
490
|
+
);
|
|
491
|
+
if (!exists) {
|
|
492
|
+
analysisGroup.layers.unshift(layer);
|
|
493
|
+
} else {
|
|
494
|
+
analysisGroup.layers = replaceLayer(
|
|
495
|
+
analysisGroup.layers,
|
|
496
|
+
layer.properties?.id ?? "",
|
|
497
|
+
[layer],
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (mapElement) {
|
|
502
|
+
const layers = [...currentLayers];
|
|
503
|
+
const evtKey =
|
|
504
|
+
mapElement.id === "compare"
|
|
505
|
+
? "compareProcess:updated"
|
|
506
|
+
: "process:updated";
|
|
507
|
+
useEmitLayersUpdate(evtKey, mapElement, layers);
|
|
508
|
+
mapElement.layers = layers;
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
/**
|
|
512
|
+
* Updates the jsonform schema to target the compare map
|
|
513
|
+
* @param {import("json-schema").JSONSchema7 | null | undefined} jsonformSchema
|
|
514
|
+
*/
|
|
515
|
+
export function updateJsonformSchemaTarget(jsonformSchema) {
|
|
516
|
+
if (!jsonformSchema) {
|
|
517
|
+
return jsonformSchema;
|
|
518
|
+
}
|
|
519
|
+
const stringified = JSON.stringify(jsonformSchema).replaceAll(
|
|
520
|
+
"eox-map#main",
|
|
521
|
+
"eox-map#compare",
|
|
522
|
+
);
|
|
523
|
+
return /** @type {import("json-schema").JSONSchema7} */ (
|
|
524
|
+
JSON.parse(stringified)
|
|
525
|
+
);
|
|
526
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The list of job result from the server
|
|
5
|
+
* {job_start_datetime: string, job_end_datetime: string,status: string}
|
|
6
|
+
* @type {import("vue").Ref<import("./types").AsyncJob[]>}
|
|
7
|
+
**/
|
|
8
|
+
export const jobs = ref([]);
|
|
9
|
+
/**
|
|
10
|
+
* The list of jobs results from the server for the compare map
|
|
11
|
+
* @type {import("vue").Ref<import("./types").AsyncJob[]>}
|
|
12
|
+
*/
|
|
13
|
+
export const compareJobs = ref([]);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { StacLink, StacCollection } from "stac-ts";
|
|
2
|
+
import type { Ref } from "vue";
|
|
3
|
+
|
|
4
|
+
export interface CustomEnpointInput {
|
|
5
|
+
links: StacLink[];
|
|
6
|
+
jsonformSchema: Record<string, any>;
|
|
7
|
+
jsonformValue: Record<string, any>;
|
|
8
|
+
selectedStac: StacCollection;
|
|
9
|
+
isPolling?: Ref<boolean>;
|
|
10
|
+
enableCompare?: boolean;
|
|
11
|
+
jobs: Ref<AsyncJob[]>;
|
|
12
|
+
}
|
|
13
|
+
export interface AsyncJob {
|
|
14
|
+
type: string;
|
|
15
|
+
processID: string;
|
|
16
|
+
jobID: string;
|
|
17
|
+
status: "successful" | "failed" | "running";
|
|
18
|
+
message: string;
|
|
19
|
+
/** percentage of completion */
|
|
20
|
+
progress: number | string;
|
|
21
|
+
/** stringified object of parameters */
|
|
22
|
+
parameters: string;
|
|
23
|
+
/** ISO datetime string */
|
|
24
|
+
job_start_datetime: string;
|
|
25
|
+
/** ISO datetime string */
|
|
26
|
+
job_end_datetime: string;
|
|
27
|
+
/** typically contains links to differen types of the results */
|
|
28
|
+
links: StacLink[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type EOxHubProcessResults =
|
|
32
|
+
| {
|
|
33
|
+
urls: string[];
|
|
34
|
+
}
|
|
35
|
+
| {
|
|
36
|
+
[K in string as K extends "urls" ? never : K]: {
|
|
37
|
+
urls: string[];
|
|
38
|
+
mimetype: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type AsyncProcessResults = {
|
|
43
|
+
type: string;
|
|
44
|
+
urls: string[];
|
|
45
|
+
id: string;
|
|
46
|
+
}[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="flex-grow-1
|
|
2
|
+
<div class="flex-grow-1">
|
|
3
3
|
<eox-stacinfo
|
|
4
4
|
.for="currentUrl"
|
|
5
5
|
.allowHtml="allowHtml"
|
|
@@ -37,22 +37,7 @@ const {
|
|
|
37
37
|
|
|
38
38
|
styleOverride: {
|
|
39
39
|
type: String,
|
|
40
|
-
default:
|
|
41
|
-
.single-property {columns: 1!important;}
|
|
42
|
-
h1 {margin:0px!important;font-size:16px!important;}
|
|
43
|
-
header h1:after {
|
|
44
|
-
content:' ';
|
|
45
|
-
display:block;
|
|
46
|
-
border:1px solid #d0d0d0;
|
|
47
|
-
}
|
|
48
|
-
h2 {font-size:15px}
|
|
49
|
-
h3 {font-size:14px}
|
|
50
|
-
summary {cursor: pointer;}
|
|
51
|
-
#properties li > .value { font-weight: normal !important;}
|
|
52
|
-
main {padding-bottom: 10px;}
|
|
53
|
-
.footer-container {line-height:1;}
|
|
54
|
-
.footer-container button {margin-top: -10px;}
|
|
55
|
-
.footer-container small {font-size:10px;line-height:1;}`,
|
|
40
|
+
default: "",
|
|
56
41
|
},
|
|
57
42
|
header: {
|
|
58
43
|
/** @type {import("vue").PropType<string[]>} */
|
package/widgets/EodashTools.vue
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<div class="d-flex flex-row justify-space-between pa-4 align-center">
|
|
2
|
+
<div ref="rootEl" class="d-flex flex-column fill-height bg-primary">
|
|
3
|
+
<div
|
|
4
|
+
class="d-flex flex-row align-center fill-height justify-space-between pa-2 align-center"
|
|
5
|
+
>
|
|
7
6
|
<v-btn
|
|
8
7
|
v-if="props.showIndicatorsBtn"
|
|
9
8
|
color="secondary"
|
|
10
|
-
class="text-none
|
|
11
|
-
:append-icon="[
|
|
9
|
+
class="text-none"
|
|
10
|
+
:append-icon="[mdiPlusCircleOutline]"
|
|
12
11
|
:text="indicatorBtnText"
|
|
13
12
|
@click="dialog = !dialog"
|
|
14
13
|
>
|
|
@@ -40,16 +39,16 @@
|
|
|
40
39
|
import PopUp from "^/PopUp.vue";
|
|
41
40
|
import EodashItemFilter from "^/EodashItemFilter.vue";
|
|
42
41
|
import EodashLayoutSwitcher from "^/EodashLayoutSwitcher.vue";
|
|
43
|
-
import {
|
|
42
|
+
import { mdiPlusCircleOutline, mdiViewDashboard } from "@mdi/js";
|
|
44
43
|
import { computed, ref } from "vue";
|
|
45
|
-
import {
|
|
46
|
-
import { useDisplay } from "vuetify
|
|
44
|
+
import { useTransparentPanel } from "@/composables";
|
|
45
|
+
import { useDisplay } from "vuetify";
|
|
47
46
|
|
|
48
47
|
const dialog = ref(false);
|
|
49
48
|
|
|
50
49
|
const { smAndDown } = useDisplay();
|
|
51
|
-
const popupWidth = computed(() => (smAndDown.value ? "
|
|
52
|
-
const popupHeight = computed(() => (smAndDown.value ? "90%" : "
|
|
50
|
+
const popupWidth = computed(() => (smAndDown.value ? "90%" : "70%"));
|
|
51
|
+
const popupHeight = computed(() => (smAndDown.value ? "90%" : "70%"));
|
|
53
52
|
|
|
54
53
|
const props = defineProps({
|
|
55
54
|
showIndicatorsBtn: {
|
|
@@ -80,5 +79,6 @@ const props = defineProps({
|
|
|
80
79
|
},
|
|
81
80
|
});
|
|
82
81
|
const rootEl = ref(null);
|
|
83
|
-
|
|
82
|
+
useTransparentPanel(rootEl);
|
|
84
83
|
</script>
|
|
84
|
+
<style lang="scss" scoped></style>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import { useDefineWidgets } from "@/composables/DefineWidgets";
|
|
18
18
|
import { nextTick, onMounted } from "vue";
|
|
19
19
|
import { ref } from "vue";
|
|
20
|
-
import { useLayout } from "vuetify
|
|
20
|
+
import { useLayout } from "vuetify";
|
|
21
21
|
import "animated-details";
|
|
22
22
|
|
|
23
23
|
const props = defineProps({
|