@eodash/eodash 5.6.0 → 5.7.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/core/client/components/DashboardLayout.vue +1 -1
- package/core/client/composables/index.js +6 -2
- package/core/client/eodashSTAC/EodashCollection.js +5 -21
- package/core/client/eodashSTAC/createLayers.js +23 -9
- package/core/client/eodashSTAC/helpers.js +37 -4
- package/core/client/types.ts +8 -1
- package/core/client/utils/index.js +4 -0
- package/dist/client/{DashboardLayout-DkKDhfgH.js → DashboardLayout-kRsmsNW5.js} +5 -5
- package/dist/client/{DynamicWebComponent-BrpkA-e3.js → DynamicWebComponent-CnKhYo0K.js} +1 -1
- package/dist/client/{EodashChart-p7_1FRlF.js → EodashChart-CLDqE93C.js} +4 -4
- package/dist/client/{EodashDatePicker-HK0Jl7wQ.js → EodashDatePicker-CMPDT-ce.js} +3 -3
- package/dist/client/{EodashItemFilter-BYQDA78B.js → EodashItemFilter-BpdA8QQa.js} +1 -1
- package/dist/client/{EodashLayerControl-NcrNncGn.js → EodashLayerControl-BHpDA4_0.js} +25 -7
- package/dist/client/{EodashLayoutSwitcher-CC2Znd0I.js → EodashLayoutSwitcher-B1fRUt7G.js} +3 -3
- package/dist/client/EodashMapBtns-Cpned0tc.js +478 -0
- package/dist/client/{EodashStacInfo-BA-0UjvT.js → EodashStacInfo-BQspAHKH.js} +31 -31
- package/dist/client/{EodashTools-CWmoH0g_.js → EodashTools-1zHz26gv.js} +4 -4
- package/dist/client/{ExportState-CfAfX4RN.js → ExportState-DbOm8hBI.js} +4 -4
- package/dist/client/{Footer-DLGxQTZt.js → Footer-BKg-VVkj.js} +1 -1
- package/dist/client/{Header-eyEyyzD6.js → Header-DCrwCvmY.js} +2 -2
- package/dist/client/MobileLayout-vWSHpluo.js +118 -0
- package/dist/client/{PopUp-WNs6Io2N.js → PopUp-9uimfK49.js} +2 -2
- package/dist/client/{ProcessList-RzVqbd5E.js → ProcessList-CTTIZa06.js} +4 -4
- package/dist/client/{VImg-GKUTFoV-.js → VImg-CrmB76ZY.js} +2 -2
- package/dist/client/{VMain-D7_72mHr.js → VMain-OKZNpcEG.js} +1 -1
- package/dist/client/{VTooltip-BbmvtvYw.js → VTooltip-CJw2FyWk.js} +2 -2
- package/dist/client/{WidgetsContainer-Dw5d7SOW.js → WidgetsContainer-BaWOnE5R.js} +1 -1
- package/dist/client/{asWebComponent-DDt7V3Bl.js → asWebComponent-BHWpMuE3.js} +47 -35
- package/dist/client/{async-CT3KEV52.js → async-DSKj6g1f.js} +29 -28
- package/dist/client/create-layers-config-CBoYedqB.js +182 -0
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-CVzxyoSq.js → forwardRefs-DH51zPUr.js} +2 -2
- package/dist/client/{handling-C285F_Mq.js → handling-BrcDDlgS.js} +452 -114
- package/dist/client/{helpers-CZFH0EVN.js → helpers-DjZVl_WF.js} +2277 -1504
- package/dist/client/{index-B-m7V3Kb.js → index-1JKE68n3.js} +49 -194
- package/dist/client/{index-CF3ZMzTz.js → index-5Jhsa8Xe.js} +3 -3
- package/dist/client/index-CSG_JoOA.js +436 -0
- package/dist/client/{index-DgOXD7wd.js → index-CUjl-ZsI.js} +2 -2
- package/dist/client/{index-B_6H-N14.js → index-Cu3-13Xg.js} +84 -90
- 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/templates.js +1 -1
- package/dist/client/{transition-C2gnrWg0.js → transition-OHcz5Qq1.js} +1 -1
- package/dist/node/cli.js +1 -1
- package/dist/types/core/client/composables/index.d.ts +1 -3
- package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +6 -7
- package/dist/types/core/client/eodashSTAC/createLayers.d.ts +3 -3
- package/dist/types/core/client/eodashSTAC/helpers.d.ts +1 -0
- package/dist/types/core/client/types.d.ts +8 -1
- package/dist/types/templates/baseConfig.d.ts +12 -0
- package/dist/types/widgets/EodashLayerControl.vue.d.ts +1 -1
- package/dist/types/widgets/EodashMap/EodashMapBtns.vue.d.ts +9 -0
- package/dist/types/widgets/EodashMap/index.vue.d.ts +7 -0
- package/dist/types/widgets/EodashMap/methods/create-layers-config.d.ts +1 -8
- package/dist/types/widgets/EodashProcess/methods/composables.d.ts +2 -3
- package/dist/types/widgets/EodashProcess/methods/handling.d.ts +15 -10
- package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +3 -1
- package/dist/types/widgets/EodashProcess/methods/template-helpers.d.ts +99 -0
- package/dist/types/widgets/EodashProcess/methods/utils.d.ts +1 -6
- package/dist/types/widgets/EodashProcess/types.d.ts +1 -0
- package/dist/types/widgets/EodashStacInfo.vue.d.ts +10 -10
- package/dist/types/widgets/EodashTimeSlider/index.vue.d.ts +34 -0
- package/dist/types/widgets/EodashTimeSlider/methods/index.d.ts +39 -0
- package/dist/types/widgets/EodashTimeSlider/types.d.ts +62 -0
- package/package.json +32 -32
- package/widgets/EodashLayerControl.vue +22 -3
- package/widgets/EodashMap/EodashMapBtns.vue +46 -1
- package/widgets/EodashMap/index.vue +17 -5
- package/widgets/EodashMap/methods/create-layers-config.js +2 -0
- package/widgets/EodashMap/methods/index.js +23 -5
- package/widgets/EodashProcess/index.vue +17 -13
- package/widgets/EodashProcess/methods/async.js +19 -8
- package/widgets/EodashProcess/methods/composables.js +63 -74
- package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +9 -5
- package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +7 -4
- package/widgets/EodashProcess/methods/handling.js +125 -76
- package/widgets/EodashProcess/methods/outputs.js +74 -29
- package/widgets/EodashProcess/methods/template-helpers.js +246 -0
- package/widgets/EodashProcess/methods/utils.js +7 -17
- package/widgets/EodashProcess/types.ts +1 -0
- package/widgets/EodashStacInfo.vue +30 -30
- package/widgets/EodashTimeSlider/index.vue +152 -0
- package/widgets/EodashTimeSlider/methods/index.js +279 -0
- package/widgets/EodashTimeSlider/types.ts +64 -0
- package/dist/client/EodashMapBtns-BJSh7qT-.js +0 -435
- package/dist/client/EodashTimeSlider-GDv1hbw7.js +0 -53
- package/dist/client/MobileLayout-RzLOyXwL.js +0 -118
- package/dist/types/widgets/EodashTimeSlider.vue.d.ts +0 -15
- package/widgets/EodashTimeSlider.vue +0 -40
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { initProcess, updateJsonformIdentifier } from "./handling";
|
|
2
|
-
import {
|
|
3
|
-
import { nextTick, onMounted, watch } from "vue";
|
|
4
|
-
import { eoxLayersKey } from "@/utils/keys";
|
|
2
|
+
import { nextTick, onMounted, onUnmounted, watch } from "vue";
|
|
5
3
|
import { useOnLayersUpdate } from "@/composables";
|
|
6
|
-
|
|
4
|
+
import { getCompareLayers, getLayers } from "@/store/actions";
|
|
7
5
|
/**
|
|
8
6
|
* Composable resposible of timing the Initialization of the process
|
|
9
7
|
*
|
|
@@ -11,17 +9,15 @@ import { useOnLayersUpdate } from "@/composables";
|
|
|
11
9
|
* @async
|
|
12
10
|
* @param {Object} params
|
|
13
11
|
* @param {import("vue").Ref<import("stac-ts").StacCollection | null>} params.selectedStac
|
|
14
|
-
* @param {import("vue").Ref<import("@eox/jsonform").EOxJSONForm | null>} params.jsonformEl
|
|
15
12
|
* @param {import("vue").Ref<Record<string,any> | null>} params.jsonformSchema
|
|
16
13
|
* @param {import("vue").Ref<any[]>} params.processResults
|
|
17
14
|
* @param {import("vue").Ref<boolean>} params.isProcessed
|
|
18
15
|
* @param {import("vue").Ref<boolean>} params.loading
|
|
19
16
|
* @param {import("vue").Ref<boolean>} params.isPolling
|
|
20
|
-
* @param {import("@eox/map").EOxMap | null} params.mapElement
|
|
17
|
+
* @param {import("vue").Ref<import("@eox/map").EOxMap | null>} params.mapElement
|
|
21
18
|
*/
|
|
22
19
|
export const useInitProcess = ({
|
|
23
20
|
selectedStac,
|
|
24
|
-
jsonformEl,
|
|
25
21
|
jsonformSchema,
|
|
26
22
|
isProcessed,
|
|
27
23
|
processResults,
|
|
@@ -29,64 +25,56 @@ export const useInitProcess = ({
|
|
|
29
25
|
isPolling,
|
|
30
26
|
mapElement,
|
|
31
27
|
}) => {
|
|
32
|
-
const layersEvents = useEventBus(eoxLayersKey);
|
|
33
|
-
|
|
34
28
|
onMounted(async () => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
isPolling,
|
|
46
|
-
});
|
|
47
|
-
} else {
|
|
48
|
-
layersEvents.once(async () => {
|
|
49
|
-
await initProcess({
|
|
50
|
-
enableCompare: mapElement?.id === "compare",
|
|
51
|
-
selectedStac,
|
|
52
|
-
jsonformEl,
|
|
53
|
-
jsonformSchema,
|
|
54
|
-
isProcessed,
|
|
55
|
-
loading,
|
|
56
|
-
processResults,
|
|
57
|
-
isPolling,
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
}
|
|
29
|
+
await initProcess({
|
|
30
|
+
enableCompare: mapElement.value?.id === "compare",
|
|
31
|
+
selectedStac,
|
|
32
|
+
jsonformSchema,
|
|
33
|
+
isProcessed,
|
|
34
|
+
processResults,
|
|
35
|
+
loading,
|
|
36
|
+
isPolling,
|
|
37
|
+
mapElement: mapElement.value,
|
|
38
|
+
});
|
|
61
39
|
});
|
|
62
40
|
|
|
63
|
-
|
|
64
|
-
mapElement?.id === "compare"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
41
|
+
useOnLayersUpdate(async (evt) => {
|
|
42
|
+
const enableCompare = mapElement.value?.id === "compare";
|
|
43
|
+
const layerUpdatedKey = enableCompare
|
|
44
|
+
? "compareLayers:updated"
|
|
45
|
+
: "layers:updated";
|
|
46
|
+
const timeUpdatedKeys = enableCompare
|
|
47
|
+
? ["compareLayertime:updated", "compareTime:updated"]
|
|
48
|
+
: ["layertime:updated", "time:updated"];
|
|
49
|
+
|
|
50
|
+
if (timeUpdatedKeys.includes(evt)) {
|
|
51
|
+
// we need to update jsonform on time change in cases
|
|
52
|
+
// when the feature selection layer was time-based,
|
|
53
|
+
// so that it attaches to a correct new layer
|
|
54
|
+
const newJsonForm = await updateJsonformIdentifier({
|
|
73
55
|
jsonformSchema: jsonformSchema.value,
|
|
74
|
-
|
|
75
|
-
|
|
56
|
+
newLayers: enableCompare ? getCompareLayers() : getLayers(),
|
|
57
|
+
enableCompare,
|
|
58
|
+
mapElement: mapElement.value,
|
|
76
59
|
});
|
|
60
|
+
|
|
61
|
+
if (newJsonForm) {
|
|
62
|
+
jsonformSchema.value = newJsonForm;
|
|
63
|
+
}
|
|
77
64
|
}
|
|
78
|
-
|
|
65
|
+
|
|
66
|
+
if (evt !== layerUpdatedKey) {
|
|
79
67
|
return;
|
|
80
68
|
}
|
|
81
69
|
await initProcess({
|
|
82
|
-
enableCompare
|
|
70
|
+
enableCompare,
|
|
83
71
|
selectedStac,
|
|
84
|
-
jsonformEl,
|
|
85
72
|
jsonformSchema,
|
|
86
73
|
isProcessed,
|
|
87
74
|
processResults,
|
|
88
75
|
loading,
|
|
89
76
|
isPolling,
|
|
77
|
+
mapElement: mapElement.value,
|
|
90
78
|
});
|
|
91
79
|
});
|
|
92
80
|
};
|
|
@@ -106,38 +94,39 @@ export function useAutoExec(
|
|
|
106
94
|
startProcess,
|
|
107
95
|
) {
|
|
108
96
|
/**
|
|
109
|
-
* @param {
|
|
97
|
+
* @param {any} _e
|
|
110
98
|
**/
|
|
111
99
|
const onJsonFormChange = async (_e) => {
|
|
112
100
|
await startProcess();
|
|
113
101
|
};
|
|
114
102
|
|
|
115
|
-
const addEventListener = async () => {
|
|
116
|
-
await nextTick(() => {
|
|
117
|
-
//@ts-expect-error TODO
|
|
118
|
-
jsonformEl.value?.addEventListener("change", onJsonFormChange);
|
|
119
|
-
});
|
|
120
|
-
};
|
|
121
|
-
const removeEventListener = () => {
|
|
122
|
-
//@ts-expect-error TODO
|
|
123
|
-
jsonformEl.value?.removeEventListener("change", onJsonFormChange);
|
|
124
|
-
};
|
|
125
|
-
|
|
126
103
|
watch(jsonformSchema, (updatedSchema) => {
|
|
127
104
|
autoExec.value = updatedSchema?.options?.["execute"] || false;
|
|
128
105
|
});
|
|
129
106
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
107
|
+
// Re-attach listener whenever the element or autoExec changes
|
|
108
|
+
const stop = watch(
|
|
109
|
+
[autoExec, jsonformEl],
|
|
110
|
+
async ([exec, el], [_prevExec, prevEl]) => {
|
|
111
|
+
// Cleanup if previous element existed
|
|
112
|
+
if (prevEl) {
|
|
113
|
+
prevEl.removeEventListener("change", onJsonFormChange);
|
|
114
|
+
}
|
|
115
|
+
// Add if enabled and we have an element
|
|
116
|
+
if (exec && el) {
|
|
117
|
+
// remove listener before adding to avoid duplicates in case of element change
|
|
118
|
+
el.removeEventListener("change", onJsonFormChange);
|
|
119
|
+
await nextTick();
|
|
120
|
+
el.addEventListener("change", onJsonFormChange);
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{ immediate: true },
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
onUnmounted(() => {
|
|
127
|
+
if (jsonformEl.value) {
|
|
128
|
+
jsonformEl.value.removeEventListener("change", onJsonFormChange);
|
|
129
|
+
}
|
|
130
|
+
stop();
|
|
142
131
|
});
|
|
143
132
|
}
|
|
@@ -58,7 +58,7 @@ export async function handleSentinelHubProcess({
|
|
|
58
58
|
);
|
|
59
59
|
|
|
60
60
|
// fetch data from sentinel hub
|
|
61
|
-
|
|
61
|
+
const results = await Promise.all(
|
|
62
62
|
timePairs.map(([to, from]) => {
|
|
63
63
|
return fetchSentinelHubData({
|
|
64
64
|
url: endpoint,
|
|
@@ -67,14 +67,18 @@ export async function handleSentinelHubProcess({
|
|
|
67
67
|
from,
|
|
68
68
|
to,
|
|
69
69
|
exampleLink: evalScriptLink,
|
|
70
|
-
}).catch((err) =>
|
|
70
|
+
}).catch((err) => {
|
|
71
71
|
console.error(
|
|
72
72
|
"[eodash] Error while fetching data from sentinel hub endpoint:",
|
|
73
73
|
err,
|
|
74
|
-
)
|
|
75
|
-
|
|
74
|
+
);
|
|
75
|
+
return [];
|
|
76
|
+
});
|
|
76
77
|
}),
|
|
77
|
-
)
|
|
78
|
+
)
|
|
79
|
+
.then((data) => data.filter((result) => result.length > 0))
|
|
80
|
+
.then((data) => data.flat().map((data) => data.outputs.data));
|
|
81
|
+
return results;
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
/**
|
|
@@ -37,7 +37,7 @@ export async function handleVedaEndpoint({
|
|
|
37
37
|
vedaLink,
|
|
38
38
|
);
|
|
39
39
|
// TODO: convert jsonform bbox type to geojson in the schema to avoid the conversion here
|
|
40
|
-
|
|
40
|
+
const results = await Promise.all(
|
|
41
41
|
configs.map(({ endpoint, datetime }) => {
|
|
42
42
|
const url = new URL(vedaEndpoint);
|
|
43
43
|
const key = vedaLink.endpoint === "veda_stac" ? "ids" : "url";
|
|
@@ -56,14 +56,17 @@ export async function handleVedaEndpoint({
|
|
|
56
56
|
fetchedSats.date = datetime;
|
|
57
57
|
return fetchedSats;
|
|
58
58
|
})
|
|
59
|
-
.catch((resp) =>
|
|
59
|
+
.catch((resp) => {
|
|
60
60
|
console.error(
|
|
61
61
|
"[eodash] Error while fetching data from veda endpoint:",
|
|
62
62
|
resp,
|
|
63
|
-
)
|
|
64
|
-
|
|
63
|
+
);
|
|
64
|
+
return null;
|
|
65
|
+
});
|
|
65
66
|
}),
|
|
66
67
|
);
|
|
68
|
+
// Filter out the nulls (failed requests) before returning
|
|
69
|
+
return results.filter((result) => result !== null);
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
/**
|
|
@@ -3,8 +3,7 @@ import {
|
|
|
3
3
|
applyProcessLayersToMap,
|
|
4
4
|
extractGeometries,
|
|
5
5
|
getBboxProperty,
|
|
6
|
-
|
|
7
|
-
updateJsonformSchemaTarget,
|
|
6
|
+
getDrawToolsProperties,
|
|
8
7
|
} from "./utils";
|
|
9
8
|
import {
|
|
10
9
|
compareIndicator,
|
|
@@ -17,13 +16,12 @@ import {
|
|
|
17
16
|
compareChartData,
|
|
18
17
|
compareChartSpec,
|
|
19
18
|
} from "@/store/states";
|
|
20
|
-
import axios from "@/plugins/axios";
|
|
21
19
|
import { processCharts, processLayers, processSTAC } from "./outputs";
|
|
22
20
|
import { handleLayersCustomEndpoints } from "./custom-endpoints/layers";
|
|
23
21
|
import { handleChartCustomEndpoints } from "./custom-endpoints/chart";
|
|
24
22
|
import { useSTAcStore } from "@/store/stac";
|
|
25
23
|
import { useGetSubCodeId } from "@/composables";
|
|
26
|
-
import { getLayers } from "@/store/actions";
|
|
24
|
+
import { getLayers, getCompareLayers } from "@/store/actions";
|
|
27
25
|
|
|
28
26
|
/**
|
|
29
27
|
* Fetch and set the jsonform schema to initialize the process
|
|
@@ -32,37 +30,58 @@ import { getLayers } from "@/store/actions";
|
|
|
32
30
|
* @async
|
|
33
31
|
* @param {Object} params
|
|
34
32
|
* @param {import("vue").Ref<import("stac-ts").StacCollection | null>} params.selectedStac
|
|
35
|
-
* @param {import("vue").Ref<import("@eox/jsonform").EOxJSONForm | null>} params.jsonformEl
|
|
36
33
|
* @param {import("vue").Ref<Record<string,any> | null>} params.jsonformSchema
|
|
37
34
|
* @param {import("vue").Ref<any[]>} params.processResults
|
|
38
35
|
* @param {import("vue").Ref<boolean>} params.isProcessed
|
|
39
36
|
* @param {import("vue").Ref<boolean>} params.loading
|
|
40
37
|
* @param {import("vue").Ref<boolean>} params.isPolling
|
|
38
|
+
* @param {import("@eox/map").EOxMap | null} params.mapElement
|
|
41
39
|
* @param {boolean} params.enableCompare
|
|
42
40
|
*/
|
|
43
41
|
export async function initProcess({
|
|
44
42
|
selectedStac,
|
|
45
|
-
jsonformEl,
|
|
46
43
|
jsonformSchema,
|
|
47
44
|
isProcessed,
|
|
48
45
|
processResults,
|
|
49
46
|
loading,
|
|
50
47
|
isPolling,
|
|
51
48
|
enableCompare,
|
|
49
|
+
mapElement,
|
|
52
50
|
}) {
|
|
53
51
|
const isPoiAlive = enableCompare ? !!comparePoi.value : !!poi.value;
|
|
54
52
|
let updatedJsonform = null;
|
|
55
53
|
if (selectedStac.value?.["eodash:jsonform"]) {
|
|
56
|
-
updatedJsonform = await
|
|
54
|
+
updatedJsonform = await fetch(
|
|
57
55
|
//@ts-expect-error eodash extention
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
selectedStac.value["eodash:jsonform"],
|
|
57
|
+
).then((resp) => resp.json());
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
if (!updatedJsonform && isPoiAlive) {
|
|
63
61
|
jsonformSchema.value = null;
|
|
64
62
|
return;
|
|
65
63
|
}
|
|
64
|
+
|
|
65
|
+
if (!updatedJsonform) {
|
|
66
|
+
resetProcess({
|
|
67
|
+
loading,
|
|
68
|
+
isProcessed,
|
|
69
|
+
jsonformSchema,
|
|
70
|
+
isPolling,
|
|
71
|
+
processResults,
|
|
72
|
+
enableCompare,
|
|
73
|
+
});
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const newJsonForm = await updateJsonformIdentifier({
|
|
78
|
+
jsonformSchema: updatedJsonform,
|
|
79
|
+
newLayers: enableCompare ? getCompareLayers() : getLayers(),
|
|
80
|
+
enableCompare,
|
|
81
|
+
mapElement,
|
|
82
|
+
});
|
|
83
|
+
if (!newJsonForm) return;
|
|
84
|
+
|
|
66
85
|
resetProcess({
|
|
67
86
|
loading,
|
|
68
87
|
isProcessed,
|
|
@@ -71,89 +90,109 @@ export async function initProcess({
|
|
|
71
90
|
processResults,
|
|
72
91
|
enableCompare,
|
|
73
92
|
});
|
|
93
|
+
jsonformSchema.value = newJsonForm;
|
|
94
|
+
}
|
|
74
95
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Recursively search grouped layer tree for a layer whose id starts with the given prefix
|
|
98
|
+
*
|
|
99
|
+
* @param {Record<string, any>[]} layers
|
|
100
|
+
* @param {string} prefix
|
|
101
|
+
* @returns {string | null}
|
|
102
|
+
*/
|
|
103
|
+
function findLayerIdByPrefix(layers, prefix) {
|
|
104
|
+
for (const layer of layers) {
|
|
105
|
+
if (layer.type === "Group" && Array.isArray(layer.layers)) {
|
|
106
|
+
const found = findLayerIdByPrefix(layer.layers, prefix);
|
|
107
|
+
if (found) return found;
|
|
108
|
+
} else if (layer.properties?.id?.startsWith(prefix)) {
|
|
109
|
+
return layer.properties.id;
|
|
85
110
|
}
|
|
86
|
-
// trigger jsonform update in next tick
|
|
87
|
-
jsonformSchema.value = null;
|
|
88
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
89
|
-
jsonformSchema.value = newJsonForm;
|
|
90
111
|
}
|
|
112
|
+
return null;
|
|
91
113
|
}
|
|
92
114
|
|
|
93
115
|
/**
|
|
94
|
-
*
|
|
116
|
+
* Wait until a layer's features are loaded for the drawtools to attach correctly
|
|
117
|
+
* Resolves immediately if already loaded.
|
|
118
|
+
*
|
|
119
|
+
* @param {import("@eox/map").AnyLayerWithSource | null | undefined} layer
|
|
120
|
+
* @returns {Promise<void>}
|
|
121
|
+
*/
|
|
122
|
+
function waitForLayerRender(layer) {
|
|
123
|
+
return new Promise((resolve, reject) => {
|
|
124
|
+
if (!layer || layer.get("type") !== "Vector" || !("getSource" in layer))
|
|
125
|
+
return resolve();
|
|
126
|
+
const source = /** @type {import("ol/source/Vector").default} */ (
|
|
127
|
+
layer.getSource()
|
|
128
|
+
);
|
|
129
|
+
if (!source || source.getFeatures().length > 0) return resolve();
|
|
130
|
+
source.once("featuresloadend", () => resolve());
|
|
131
|
+
source.once("featuresloaderror", () =>
|
|
132
|
+
reject(new Error(`Layer ${layer.get("id")} failed to load features`)),
|
|
133
|
+
);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Update the jsonform schema to have the correct layer id from the map.
|
|
139
|
+
* Returns null if any required layerId cannot be resolved (layer not yet in map).
|
|
140
|
+
* Callers should treat null as "retry when layers:updated fires".
|
|
95
141
|
*
|
|
96
142
|
* @export
|
|
97
|
-
* @async
|
|
98
143
|
* @param {Object} params
|
|
99
|
-
* @param {Record<string,any> | null} params.jsonformSchema
|
|
100
|
-
* @param {Record<string, any>[] | undefined} params.newLayers
|
|
101
|
-
* @
|
|
144
|
+
* @param {Record<string,any> | null} params.jsonformSchema
|
|
145
|
+
* @param {Record<string, any>[] | undefined} params.newLayers
|
|
146
|
+
* @param {boolean} params.enableCompare
|
|
147
|
+
* @param {import("@eox/map").EOxMap | null | undefined} params.mapElement
|
|
148
|
+
* @returns {Promise<Record<string,any> | null>} updated schema, or null if a layerId could not be resolved
|
|
102
149
|
*/
|
|
103
|
-
export async function updateJsonformIdentifier({
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
150
|
+
export async function updateJsonformIdentifier({
|
|
151
|
+
jsonformSchema,
|
|
152
|
+
newLayers,
|
|
153
|
+
enableCompare,
|
|
154
|
+
mapElement,
|
|
155
|
+
}) {
|
|
156
|
+
if (!jsonformSchema || !newLayers) return null;
|
|
157
|
+
|
|
158
|
+
const form = JSON.parse(JSON.stringify(jsonformSchema));
|
|
159
|
+
const drawToolsProperties = getDrawToolsProperties(form);
|
|
160
|
+
/** @type {Promise<void>[]} */
|
|
161
|
+
const renderPromises = [];
|
|
162
|
+
|
|
163
|
+
for (const drawToolsProperty of drawToolsProperties) {
|
|
164
|
+
if (!drawToolsProperty) continue;
|
|
165
|
+
|
|
166
|
+
const drawtoolsOptions =
|
|
167
|
+
form?.properties[drawToolsProperty]?.options?.drawtools;
|
|
168
|
+
if (!drawtoolsOptions) continue;
|
|
169
|
+
|
|
170
|
+
if (drawtoolsOptions.for && enableCompare) {
|
|
171
|
+
drawtoolsOptions.for = "eox-map#compare";
|
|
121
172
|
}
|
|
122
173
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
for (const layer of layersArray) {
|
|
136
|
-
if (layer.type === "Group" && Array.isArray(layer.layers)) {
|
|
137
|
-
traverseLayers(layer.layers);
|
|
138
|
-
} else {
|
|
139
|
-
if (layer.properties?.id?.startsWith(layerId)) {
|
|
140
|
-
matchedLayerId = layer.properties.id;
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
174
|
+
if (drawtoolsOptions.layerId) {
|
|
175
|
+
let layer = mapElement?.getLayerById(drawtoolsOptions.layerId);
|
|
176
|
+
if (!layer) {
|
|
177
|
+
const prefix = drawtoolsOptions.layerId.split(";:;")[0];
|
|
178
|
+
const resolvedId = findLayerIdByPrefix(newLayers, prefix);
|
|
179
|
+
if (!resolvedId) {
|
|
180
|
+
console.warn(
|
|
181
|
+
`Could not find matching layer for processing form with id: ${prefix}`,
|
|
182
|
+
);
|
|
183
|
+
return null;
|
|
143
184
|
}
|
|
185
|
+
drawtoolsOptions.layerId = resolvedId;
|
|
186
|
+
layer = mapElement?.getLayerById(resolvedId);
|
|
144
187
|
}
|
|
145
|
-
|
|
146
|
-
traverseLayers(layers);
|
|
147
|
-
if (matchedLayerId) {
|
|
148
|
-
form.properties.feature.options.drawtools.layerId = matchedLayerId;
|
|
149
|
-
return form;
|
|
150
|
-
} else {
|
|
151
|
-
console.warn(
|
|
152
|
-
`Could not find matching layer for processing form with id: ${layerId}`,
|
|
153
|
-
);
|
|
154
|
-
return null;
|
|
188
|
+
renderPromises.push(waitForLayerRender(layer));
|
|
155
189
|
}
|
|
156
190
|
}
|
|
191
|
+
|
|
192
|
+
await Promise.all(renderPromises).catch((err) => {
|
|
193
|
+
console.warn("[eodash] layer load failed before jsonform attach:", err);
|
|
194
|
+
});
|
|
195
|
+
|
|
157
196
|
return form;
|
|
158
197
|
}
|
|
159
198
|
|
|
@@ -192,6 +231,15 @@ export async function handleProcesses({
|
|
|
192
231
|
);
|
|
193
232
|
|
|
194
233
|
const bboxProperty = getBboxProperty(jsonformSchema.value);
|
|
234
|
+
// Preserve raw form value before extractGeometries mutates it.
|
|
235
|
+
// Needed so POST multiQuery can iterate original GeoJSON Feature objects.
|
|
236
|
+
// Uses JSON round-trip instead of structuredClone to handle OL Feature
|
|
237
|
+
// objects from drawtools (which contain non-cloneable methods).
|
|
238
|
+
const rawJsonformValue = JSON.parse(
|
|
239
|
+
JSON.stringify(
|
|
240
|
+
/** @type {Record<string, any>} */ (jsonformEl.value?.value ?? {}),
|
|
241
|
+
),
|
|
242
|
+
);
|
|
195
243
|
const jsonformValue = /** @type {Record<string,any>} */ (
|
|
196
244
|
jsonformEl.value?.value
|
|
197
245
|
);
|
|
@@ -210,6 +258,7 @@ export async function handleProcesses({
|
|
|
210
258
|
[tempChartSpec, usedChartData.value] = await processCharts({
|
|
211
259
|
links: serviceLinks,
|
|
212
260
|
jsonformValue: { ...(jsonformValue ?? {}) },
|
|
261
|
+
rawJsonformValue,
|
|
213
262
|
jsonformSchema: jsonformSchema.value,
|
|
214
263
|
enableCompare,
|
|
215
264
|
selectedStac: selectedStac.value,
|