@eodash/eodash 5.2.0 → 5.3.1
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 +0 -1
- package/core/client/composables/index.js +53 -59
- package/core/client/eodashSTAC/EodashCollection.js +196 -94
- package/core/client/eodashSTAC/auth.js +86 -0
- package/core/client/eodashSTAC/createLayers.js +204 -4
- package/core/client/eodashSTAC/helpers.js +254 -62
- package/core/client/eodashSTAC/parquet.js +0 -13
- package/core/client/eodashSTAC/triggers.js +1 -1
- package/core/client/store/actions.js +14 -0
- package/core/client/store/stac.js +46 -8
- package/core/client/store/states.js +6 -0
- package/core/client/types.ts +206 -3
- package/core/client/utils/bands-editor/arithmetic.js +144 -0
- package/core/client/utils/bands-editor/colors.js +36 -0
- package/core/client/utils/bands-editor/dom.js +196 -0
- package/core/client/utils/bands-editor/exampleSchema.json +1320 -0
- package/core/client/utils/bands-editor/index.js +68 -0
- package/core/client/utils/bands-editor/rgb.js +102 -0
- package/core/client/utils/index.js +5 -2
- package/core/client/views/Dashboard.vue +1 -1
- package/core/client/vite-env.d.ts +122 -0
- package/dist/client/{DashboardLayout-Dq9Kfe6O.js → DashboardLayout-BAstYnhU.js} +4 -5
- package/dist/client/{DynamicWebComponent-DCBMXskE.js → DynamicWebComponent-7v4_DFqP.js} +1 -1
- package/dist/client/{EodashDatePicker-DtngxU6s.js → EodashDatePicker-IVHLv9UN.js} +20 -22
- package/dist/client/{EodashItemFilter-ClQebJQt.js → EodashItemFilter-BPMpnXjo.js} +46 -31
- package/dist/client/EodashLayerControl-CSnQh2tb.js +1517 -0
- package/dist/client/{EodashLayoutSwitcher-DQ8SfVDd.js → EodashLayoutSwitcher-CPpGM8Pb.js} +4 -4
- package/dist/client/EodashMapBtns-C_jyUJ2x.js +301 -0
- package/dist/client/{EodashStacInfo-Dt1nF06x.js → EodashStacInfo-DjuWc0Iz.js} +1 -1
- package/dist/client/EodashTimeSlider-CDh9Lf02.js +53 -0
- package/dist/client/{EodashTools-DV5ykmWc.js → EodashTools-DSvDUUlL.js} +10 -7
- package/dist/client/{ExportState-B6zZQUmE.js → ExportState-BhjxS0jG.js} +145 -120
- package/dist/client/{Footer-DNhXs8k6.js → Footer-C3PPcdjv.js} +1 -1
- package/dist/client/{Header-BjhN5JY4.js → Header-E5NbT7HE.js} +2 -2
- package/dist/client/MobileLayout-DY7OHr1k.js +118 -0
- package/dist/client/{PopUp-CgpvNr3o.js → PopUp-CSPXdqKI.js} +79 -43
- package/dist/client/{ProcessList-vecpxThi.js → ProcessList-C3HV7G0b.js} +5 -6
- package/dist/client/{VImg-CETuikH2.js → VImg-FoXcOnWF.js} +6 -3
- package/dist/client/{VMain-Ci9DyaGU.js → VMain-Ck2g1QOG.js} +1 -1
- package/dist/client/{VTooltip-J4ac48X7.js → VTooltip-F_1Zcvhp.js} +2 -2
- package/dist/client/{WidgetsContainer-CCML4TyV.js → WidgetsContainer-Cq9uZEuN.js} +1 -1
- package/dist/client/asWebComponent-DZeEbWG0.js +8895 -0
- package/dist/client/{async-B7jIrM53.js → async-Dk79llLt.js} +2 -2
- package/dist/client/easing-CH0-9wR8.js +35 -0
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-BQclvjMq.js → forwardRefs-BbvoXHtj.js} +58 -45
- package/dist/client/{handling-BS24aG1q.js → handling-DxucYlYh.js} +12 -6
- package/dist/client/{helpers-wXK7Ywio.js → helpers-CI_7CUmn.js} +568 -281
- package/dist/client/index-BO5uGfUe.js +571 -0
- package/dist/client/{index-9KR-G20t.js → index-C13BiO9C.js} +2 -2
- package/dist/client/{index-4UCzZi8B.js → index-DcCcdbgR.js} +26 -13
- package/dist/client/{index-B2XpdgR6.js → index-KrGHjH-_.js} +63 -36
- package/dist/client/templates.js +82 -15
- package/dist/client/{transition-yBii4fu6.js → transition-Ctkv90El.js} +1 -1
- package/dist/node/cli.js +6 -6
- package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +24 -10
- package/dist/types/core/client/eodashSTAC/auth.d.ts +7 -0
- package/dist/types/core/client/eodashSTAC/createLayers.d.ts +15 -3
- package/dist/types/core/client/eodashSTAC/helpers.d.ts +47 -16
- package/dist/types/core/client/plugins/vuetify.d.ts +14 -14
- package/dist/types/core/client/store/actions.d.ts +2 -0
- package/dist/types/core/client/store/stac.d.ts +16 -7
- package/dist/types/core/client/store/states.d.ts +4 -0
- package/dist/types/core/client/types.d.ts +170 -2
- package/dist/types/core/client/utils/bands-editor/arithmetic.d.ts +8 -0
- package/dist/types/core/client/utils/bands-editor/colors.d.ts +15 -0
- package/dist/types/core/client/utils/bands-editor/dom.d.ts +42 -0
- package/dist/types/core/client/utils/bands-editor/index.d.ts +20 -0
- package/dist/types/core/client/utils/bands-editor/rgb.d.ts +15 -0
- package/dist/types/core/client/utils/index.d.ts +1 -1
- package/dist/types/templates/baseConfig.d.ts +87 -1
- package/dist/types/templates/expert.d.ts +6 -6
- package/dist/types/templates/explore.d.ts +67 -0
- package/dist/types/templates/index.d.ts +1 -1
- package/dist/types/templates/{light.d.ts → lite.d.ts} +5 -5
- package/dist/types/widgets/EodashItemCatalog/index.vue.d.ts +21 -0
- package/dist/types/widgets/EodashItemCatalog/methods/filters.d.ts +49 -0
- package/dist/types/widgets/EodashItemCatalog/methods/handlers.d.ts +4 -0
- package/dist/types/widgets/EodashItemCatalog/methods/map.d.ts +12 -0
- package/dist/types/widgets/EodashItemCatalog/types.d.ts +14 -0
- package/dist/types/widgets/EodashMap/EodashMapBtns.vue.d.ts +2 -0
- package/dist/types/widgets/EodashMap/index.vue.d.ts +108 -2
- package/dist/types/widgets/EodashMap/methods/create-layers-config.d.ts +1 -1
- package/dist/types/widgets/EodashMap/methods/index.d.ts +1 -1
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +1 -1
- package/dist/types/widgets/EodashTimeSlider.vue.d.ts +7 -0
- package/dist/types/widgets/EodashTools.vue.d.ts +10 -10
- package/dist/types/widgets/ExportState.vue.d.ts +2 -0
- package/package.json +28 -27
- package/templates/baseConfig.js +10 -5
- package/templates/compare.js +2 -2
- package/templates/expert.js +5 -5
- package/templates/explore.js +62 -0
- package/templates/index.js +1 -1
- package/templates/{light.js → lite.js} +1 -1
- package/widgets/EodashDatePicker.vue +15 -18
- package/widgets/EodashItemCatalog/index.vue +161 -0
- package/widgets/EodashItemCatalog/methods/filters.js +216 -0
- package/widgets/EodashItemCatalog/methods/handlers.js +50 -0
- package/widgets/EodashItemCatalog/methods/map.js +144 -0
- package/widgets/EodashItemCatalog/types.ts +15 -0
- package/widgets/EodashItemFilter.vue +35 -28
- package/widgets/EodashLayerControl.vue +10 -6
- package/widgets/EodashLayoutSwitcher.vue +1 -1
- package/widgets/EodashMap/EodashMapBtns.vue +18 -9
- package/widgets/EodashMap/index.vue +22 -12
- package/widgets/EodashMap/methods/create-layers-config.js +9 -6
- package/widgets/EodashMap/methods/index.js +27 -13
- package/widgets/EodashProcess/index.vue +17 -1
- package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +9 -3
- package/widgets/EodashProcess/methods/handling.js +2 -0
- package/widgets/EodashProcess/methods/outputs.js +1 -0
- package/widgets/EodashTimeSlider.vue +40 -0
- package/widgets/EodashTools.vue +7 -3
- package/widgets/ExportState.vue +53 -22
- package/dist/client/EodashLayerControl-BLBds28C.js +0 -154
- package/dist/client/EodashMapBtns-B89_YBDw.js +0 -326
- package/dist/client/MobileLayout-JelB6w1G.js +0 -118
- package/dist/client/asWebComponent-ZyEzWOOf.js +0 -19092
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { useOnLayersUpdate } from "@/composables";
|
|
2
|
+
import { mapEl } from "@/store/states";
|
|
3
|
+
import { onMounted, onUnmounted } from "vue";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {import("@/types").GeoJsonFeature[]} features
|
|
8
|
+
*/
|
|
9
|
+
export function renderItemsFeatures(features) {
|
|
10
|
+
let analysisLayers =
|
|
11
|
+
/** @type {import("@eox/map/src/layers").EOxLayerTypeGroup} */ (
|
|
12
|
+
mapEl.value?.layers?.find((l) => l.properties?.id === "AnalysisGroup")
|
|
13
|
+
);
|
|
14
|
+
if (!mapEl.value || !features) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (!analysisLayers) {
|
|
18
|
+
analysisLayers = {
|
|
19
|
+
type: "Group",
|
|
20
|
+
properties: {
|
|
21
|
+
id: "AnalysisGroup",
|
|
22
|
+
title: "Data Layers",
|
|
23
|
+
},
|
|
24
|
+
layers: [],
|
|
25
|
+
};
|
|
26
|
+
mapEl.value.layers = [analysisLayers, ...mapEl.value.layers.reverse()];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const stacItemsLayer = {
|
|
30
|
+
type: "Vector",
|
|
31
|
+
properties: {
|
|
32
|
+
id: "stac-items",
|
|
33
|
+
title: "STAC Items",
|
|
34
|
+
},
|
|
35
|
+
source: {
|
|
36
|
+
type: "Vector",
|
|
37
|
+
url:
|
|
38
|
+
"data:application/geo+json," +
|
|
39
|
+
encodeURIComponent(
|
|
40
|
+
JSON.stringify({ type: "FeatureCollection", features }),
|
|
41
|
+
),
|
|
42
|
+
format: "GeoJSON",
|
|
43
|
+
},
|
|
44
|
+
style: {
|
|
45
|
+
"fill-color": "transparent",
|
|
46
|
+
"stroke-color": "#003170",
|
|
47
|
+
},
|
|
48
|
+
interactions: [
|
|
49
|
+
{
|
|
50
|
+
type: "select",
|
|
51
|
+
options: {
|
|
52
|
+
id: "stac-items",
|
|
53
|
+
condition: "pointermove",
|
|
54
|
+
style: {
|
|
55
|
+
"stroke-color": "white",
|
|
56
|
+
"stroke-width": 3,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
};
|
|
62
|
+
const exists = analysisLayers.layers.some(
|
|
63
|
+
(l) => l.properties?.id === "stac-items",
|
|
64
|
+
);
|
|
65
|
+
if (exists) {
|
|
66
|
+
//@ts-expect-error todo
|
|
67
|
+
mapEl.value.addOrUpdateLayer(stacItemsLayer);
|
|
68
|
+
return;
|
|
69
|
+
} else {
|
|
70
|
+
//@ts-expect-error todo
|
|
71
|
+
analysisLayers.layers.unshift(stacItemsLayer);
|
|
72
|
+
mapEl.value.layers = [...mapEl.value.layers].reverse();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @param {import("vue").Ref<any>} itemFilter
|
|
78
|
+
* @param {boolean} bboxFilter
|
|
79
|
+
*/
|
|
80
|
+
export const useSearchOnMapMove = (itemFilter, bboxFilter) => {
|
|
81
|
+
if (!bboxFilter) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
/** @type {NodeJS.Timeout} */
|
|
85
|
+
let timeout;
|
|
86
|
+
const handler = () => {
|
|
87
|
+
clearTimeout(timeout);
|
|
88
|
+
timeout = setTimeout(() => {
|
|
89
|
+
itemFilter.value?.search();
|
|
90
|
+
}, 800); // 800ms debounce
|
|
91
|
+
};
|
|
92
|
+
onMounted(() => {
|
|
93
|
+
mapEl.value?.map.on("moveend", handler);
|
|
94
|
+
});
|
|
95
|
+
onUnmounted(() => {
|
|
96
|
+
mapEl.value?.map.un("moveend", handler);
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
*
|
|
101
|
+
* @param {import("vue").Ref<import("@/types").GeoJsonFeature[]>} currentItems
|
|
102
|
+
*/
|
|
103
|
+
export const useRenderItemsFeatures = (currentItems) => {
|
|
104
|
+
const renderOnUpdate = () =>
|
|
105
|
+
useOnLayersUpdate(() => {
|
|
106
|
+
// consider cases where this is not needed
|
|
107
|
+
renderItemsFeatures(currentItems.value);
|
|
108
|
+
});
|
|
109
|
+
onMounted(() => {
|
|
110
|
+
renderItemsFeatures(currentItems.value);
|
|
111
|
+
renderOnUpdate();
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
*
|
|
116
|
+
* @param {import("vue").Ref<any>} itemfilterEl
|
|
117
|
+
*/
|
|
118
|
+
export function useRenderOnFeatureHover(itemfilterEl) {
|
|
119
|
+
/**
|
|
120
|
+
*
|
|
121
|
+
* @param {CustomEvent} evt
|
|
122
|
+
*/
|
|
123
|
+
const handler = (evt) => {
|
|
124
|
+
const itemId = evt.detail?.feature?.getId();
|
|
125
|
+
if (!itemId) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const item = itemfilterEl.value.items?.find(
|
|
129
|
+
//@ts-expect-error todo
|
|
130
|
+
(r) => r.id === itemId,
|
|
131
|
+
);
|
|
132
|
+
if (item) {
|
|
133
|
+
itemfilterEl.value.selectedResult = item;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
onMounted(() => {
|
|
137
|
+
//@ts-expect-error todo
|
|
138
|
+
mapEl.value?.addEventListener("select", handler);
|
|
139
|
+
});
|
|
140
|
+
onUnmounted(() => {
|
|
141
|
+
//@ts-expect-error todo
|
|
142
|
+
mapEl.value?.removeEventListener("select", handler);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface FilterConfigItem {
|
|
2
|
+
property: string;
|
|
3
|
+
type: "range" | "multiselect" | "select";
|
|
4
|
+
title?: string;
|
|
5
|
+
min?: number;
|
|
6
|
+
max?: number;
|
|
7
|
+
filterKeys?: string[];
|
|
8
|
+
state?: Record<string, boolean>;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
/** svg icon */
|
|
11
|
+
icon?: string;
|
|
12
|
+
unitLabel?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type FiltersConfig = FilterConfigItem[];
|
|
@@ -5,22 +5,26 @@
|
|
|
5
5
|
ref="eoxItemFilter"
|
|
6
6
|
style="overflow: auto; --background-color: none"
|
|
7
7
|
@select="onSelect"
|
|
8
|
-
.items="
|
|
8
|
+
.items="items"
|
|
9
9
|
>
|
|
10
10
|
<h4 slot="filterstitle" style="margin: 14px 8px">{{ filtersTitle }}</h4>
|
|
11
|
-
|
|
12
11
|
<h4 slot="resultstitle" style="margin: 14px 8px">{{ resultsTitle }}</h4>
|
|
13
12
|
</eox-itemfilter>
|
|
14
13
|
</template>
|
|
15
14
|
<script setup>
|
|
16
15
|
import { useSTAcStore } from "@/store/stac";
|
|
17
16
|
import { isFirstLoad } from "@/utils/states";
|
|
18
|
-
import "@eox/itemfilter";
|
|
19
17
|
import { computed, ref } from "vue";
|
|
20
18
|
|
|
19
|
+
if (!customElements.get("eox-itemfilter")) {
|
|
20
|
+
await import("@eox/itemfilter");
|
|
21
|
+
}
|
|
22
|
+
|
|
21
23
|
const store = useSTAcStore();
|
|
22
24
|
const emit = defineEmits(["select"]);
|
|
23
|
-
|
|
25
|
+
const items = store.isApi
|
|
26
|
+
? store.stac
|
|
27
|
+
: store.stac?.filter((item) => item.rel === "child");
|
|
24
28
|
const props = defineProps({
|
|
25
29
|
enableCompare: {
|
|
26
30
|
type: Boolean,
|
|
@@ -87,31 +91,36 @@ const props = defineProps({
|
|
|
87
91
|
},
|
|
88
92
|
});
|
|
89
93
|
/**
|
|
90
|
-
*
|
|
94
|
+
*
|
|
95
|
+
* @param {Function} loader Function to load the item
|
|
96
|
+
* @param {Function} reset Function to reset the selection
|
|
91
97
|
*/
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
const createSelect = (loader, reset) => {
|
|
99
|
+
/**
|
|
100
|
+
* @param {import("stac-ts").StacLink | import("stac-ts").StacCollection} item
|
|
101
|
+
*/
|
|
102
|
+
return async (item) => {
|
|
103
|
+
if (item) {
|
|
104
|
+
if (isFirstLoad.value) {
|
|
105
|
+
// prevent the map from jumping to the initial position
|
|
106
|
+
isFirstLoad.value = false;
|
|
107
|
+
}
|
|
108
|
+
const href = /** @type {string} */ (store.isApi ? item.id : item.href);
|
|
109
|
+
await loader(href);
|
|
110
|
+
emit("select", item);
|
|
111
|
+
} else {
|
|
112
|
+
reset();
|
|
97
113
|
}
|
|
98
|
-
|
|
99
|
-
emit("select", item);
|
|
100
|
-
} else {
|
|
101
|
-
store.selectedStac = null;
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
/**
|
|
105
|
-
* @param {import("stac-ts").StacLink} item
|
|
106
|
-
*/
|
|
107
|
-
const selectCompareIndicator = (item) => {
|
|
108
|
-
if (item) {
|
|
109
|
-
store.loadSelectedCompareSTAC(item.href);
|
|
110
|
-
emit("select", item);
|
|
111
|
-
} else {
|
|
112
|
-
store.resetSelectedCompareSTAC();
|
|
113
|
-
}
|
|
114
|
+
};
|
|
114
115
|
};
|
|
116
|
+
const selectIndicator = createSelect(
|
|
117
|
+
store.loadSelectedSTAC,
|
|
118
|
+
() => (store.selectedStac = null),
|
|
119
|
+
);
|
|
120
|
+
const selectCompareIndicator = createSelect(
|
|
121
|
+
store.loadSelectedCompareSTAC,
|
|
122
|
+
store.resetSelectedCompareSTAC,
|
|
123
|
+
);
|
|
115
124
|
/** @param {any} evt*/
|
|
116
125
|
const onSelect = async (evt) => {
|
|
117
126
|
const item = /** @type {import('stac-ts').StacLink} */ evt.detail;
|
|
@@ -121,7 +130,6 @@ const onSelect = async (evt) => {
|
|
|
121
130
|
selectIndicator(item);
|
|
122
131
|
}
|
|
123
132
|
};
|
|
124
|
-
|
|
125
133
|
const config = computed(() => ({
|
|
126
134
|
titleProperty: props.titleProperty,
|
|
127
135
|
enableHighlighting: props.enableHighlighting,
|
|
@@ -138,7 +146,6 @@ const config = computed(() => ({
|
|
|
138
146
|
/** @type {import("vue").Ref<HTMLElement & Record<string,any> | null>} */
|
|
139
147
|
const eoxItemFilter = ref(null);
|
|
140
148
|
</script>
|
|
141
|
-
|
|
142
149
|
<style scoped>
|
|
143
150
|
eox-itemfilter {
|
|
144
151
|
--form-flex-direction: row;
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
:key="mapElement"
|
|
6
6
|
v-bind="config"
|
|
7
7
|
:for="mapElement"
|
|
8
|
+
.customEditorInterfaces="bandsEditorInterface"
|
|
8
9
|
@datetime:updated="debouncedHandleDateTime"
|
|
9
10
|
toolsAsList="true"
|
|
10
|
-
style="--eox-background-color: transparent"
|
|
11
11
|
ref="eoxLayercontrol"
|
|
12
12
|
@layerConfig:change="onLayerConfigChange"
|
|
13
13
|
>
|
|
@@ -22,12 +22,8 @@
|
|
|
22
22
|
</span>
|
|
23
23
|
</template>
|
|
24
24
|
<script setup>
|
|
25
|
-
import "@eox/layercontrol";
|
|
26
|
-
|
|
27
|
-
import "@eox/jsonform";
|
|
28
|
-
import "@eox/timecontrol";
|
|
29
25
|
import "color-legend-element";
|
|
30
|
-
|
|
26
|
+
import "@eox/timecontrol";
|
|
31
27
|
import { computed, ref } from "vue";
|
|
32
28
|
import { mapEl, mapCompareEl } from "@/store/states";
|
|
33
29
|
import { getColFromLayer } from "@/eodashSTAC/helpers";
|
|
@@ -39,6 +35,14 @@ import {
|
|
|
39
35
|
} from "@/utils/states";
|
|
40
36
|
import { storeToRefs } from "pinia";
|
|
41
37
|
import { useSTAcStore } from "@/store/stac";
|
|
38
|
+
import { bandsEditorInterface } from "@/utils/bands-editor";
|
|
39
|
+
|
|
40
|
+
if (!customElements.get("eox-layercontrol")) {
|
|
41
|
+
await import("@eox/layercontrol");
|
|
42
|
+
}
|
|
43
|
+
if (!customElements.get("eox-jsonform")) {
|
|
44
|
+
await import("@eox/jsonform");
|
|
45
|
+
}
|
|
42
46
|
|
|
43
47
|
const props = defineProps({
|
|
44
48
|
map: {
|
|
@@ -86,15 +86,8 @@
|
|
|
86
86
|
:height="popupHeight"
|
|
87
87
|
>
|
|
88
88
|
<EodashItemFilter
|
|
89
|
+
v-bind="itemFilterConfig"
|
|
89
90
|
:enableCompare="true"
|
|
90
|
-
:enableHighlighting="false"
|
|
91
|
-
resultType="cards"
|
|
92
|
-
style="--select-filter-max-items: 8"
|
|
93
|
-
filters-title="Select an indicator to compare"
|
|
94
|
-
subTitleProperty="subtitle"
|
|
95
|
-
imageProperty="thumbnail"
|
|
96
|
-
aggregateResults="collection_group"
|
|
97
|
-
results-title=""
|
|
98
91
|
@select="onSelectCompareIndicator"
|
|
99
92
|
/>
|
|
100
93
|
</PopUp>
|
|
@@ -148,7 +141,11 @@ const {
|
|
|
148
141
|
default: true,
|
|
149
142
|
},
|
|
150
143
|
compareIndicators: {
|
|
151
|
-
/** @type {import("vue").PropType<boolean | {
|
|
144
|
+
/** @type {import("vue").PropType<boolean | {
|
|
145
|
+
compareTemplate?:string;
|
|
146
|
+
fallbackTemplate?:string;
|
|
147
|
+
itemFilterConfig?:Partial<InstanceType<import("./EodashItemFilter.vue").default>["$props"]>
|
|
148
|
+
}> }*/
|
|
152
149
|
type: [Boolean, Object],
|
|
153
150
|
default: true,
|
|
154
151
|
},
|
|
@@ -181,6 +178,18 @@ const compareIcon = computed(() =>
|
|
|
181
178
|
? mdiCompareRemove
|
|
182
179
|
: mdiCompare,
|
|
183
180
|
);
|
|
181
|
+
const itemFilterConfig = {
|
|
182
|
+
enableHighlighting: false,
|
|
183
|
+
resultType: "cards",
|
|
184
|
+
style: "--select-filter-max-items: 8",
|
|
185
|
+
"filters-title": "Select an indicator to compare",
|
|
186
|
+
subTitleProperty: "subtitle",
|
|
187
|
+
imageProperty: "thumbnail",
|
|
188
|
+
aggregateResults: "collection_group",
|
|
189
|
+
"results-title": "",
|
|
190
|
+
...(typeof compareIndicators === "object" &&
|
|
191
|
+
compareIndicators.itemFilterConfig),
|
|
192
|
+
};
|
|
184
193
|
|
|
185
194
|
const onCompareClick = () => {
|
|
186
195
|
showCompareIndicators.value =
|
|
@@ -43,26 +43,22 @@
|
|
|
43
43
|
class="map-buttons-container"
|
|
44
44
|
:style="`margin: ${btnsPosition.gap}px 0 ${btnsPosition.gap}px 0`"
|
|
45
45
|
>
|
|
46
|
+
<!-- prettier-ignore -->
|
|
46
47
|
<EodashMapBtns
|
|
47
48
|
:style="{
|
|
48
|
-
gridColumn: indicator || compareIndicator ? responsiveX : '12',
|
|
49
|
+
gridColumn: (indicator || compareIndicator) ? responsiveX : '12',
|
|
49
50
|
gridRow: responsiveY,
|
|
50
51
|
}"
|
|
51
52
|
:exportMap="(indicator || compareIndicator) ? btnsProps.exportMap : false"
|
|
52
|
-
:changeProjection="
|
|
53
|
-
(indicator || compareIndicator) ? btnsProps.changeProjection : false
|
|
53
|
+
:changeProjection="(indicator || compareIndicator) ? btnsProps.changeProjection : false
|
|
54
54
|
"
|
|
55
|
-
:compareIndicators="
|
|
56
|
-
(indicator || compareIndicator) ? btnsProps.compareIndicators : false
|
|
55
|
+
:compareIndicators="(indicator || compareIndicator) ? btnsProps.compareIndicators : false
|
|
57
56
|
"
|
|
58
|
-
:backToPOIs="
|
|
59
|
-
(indicator || compareIndicator) ? btnsProps.backToPOIs : false
|
|
57
|
+
:backToPOIs="(indicator || compareIndicator) ? btnsProps.backToPOIs : false
|
|
60
58
|
"
|
|
61
|
-
:enableSearch="
|
|
62
|
-
(indicator || compareIndicator) ? btnsProps.enableSearch : false
|
|
59
|
+
:enableSearch="(indicator || compareIndicator) ? btnsProps.enableSearch : false
|
|
63
60
|
"
|
|
64
|
-
:enableZoom="
|
|
65
|
-
(indicator || compareIndicator) ? btnsProps.enableZoom : false
|
|
61
|
+
:enableZoom="(indicator || compareIndicator) ? btnsProps.enableZoom : false
|
|
66
62
|
"
|
|
67
63
|
/>
|
|
68
64
|
</div>
|
|
@@ -134,6 +130,18 @@ const props = defineProps({
|
|
|
134
130
|
}),
|
|
135
131
|
},
|
|
136
132
|
btns: {
|
|
133
|
+
/** @type {import("vue").PropType<{
|
|
134
|
+
* enableExportMap?: boolean;
|
|
135
|
+
* enableChangeProjection?: boolean;
|
|
136
|
+
* enableBackToPOIs?: boolean;
|
|
137
|
+
* enableSearch?: boolean;
|
|
138
|
+
* enableZoom?: boolean;
|
|
139
|
+
* enableCompareIndicators?: boolean | {
|
|
140
|
+
* compareTemplate?:string;
|
|
141
|
+
* fallbackTemplate?:string;
|
|
142
|
+
* itemFilterConfig?:InstanceType<import("../EodashItemFilter.vue").default>["$props"]
|
|
143
|
+
* };
|
|
144
|
+
* }> }*/
|
|
137
145
|
type: Object,
|
|
138
146
|
default: () => ({
|
|
139
147
|
enableExportMap: true,
|
|
@@ -272,7 +280,8 @@ const showCompare = computed(() =>
|
|
|
272
280
|
useHandleMapMoveEnd(eoxMap, mapPosition);
|
|
273
281
|
|
|
274
282
|
onMounted(() => {
|
|
275
|
-
const { selectedCompareStac, selectedStac } =
|
|
283
|
+
const { selectedCompareStac, selectedStac, selectedItem } =
|
|
284
|
+
storeToRefs(useSTAcStore());
|
|
276
285
|
// assign map Element state to eox map
|
|
277
286
|
mapEl.value = eoxMap.value;
|
|
278
287
|
|
|
@@ -302,6 +311,7 @@ onMounted(() => {
|
|
|
302
311
|
eoxMapLayers,
|
|
303
312
|
compareMap,
|
|
304
313
|
props.zoomToExtent,
|
|
314
|
+
selectedItem,
|
|
305
315
|
);
|
|
306
316
|
});
|
|
307
317
|
|
|
@@ -9,19 +9,19 @@ import log from "loglevel";
|
|
|
9
9
|
* | null
|
|
10
10
|
* } selectedIndicator
|
|
11
11
|
* @param {EodashCollection[]} eodashCols
|
|
12
|
-
* @param {string} [
|
|
12
|
+
* @param {string | import("stac-ts").StacItem | null} [timeOrItem] - time as a string, or a stac item
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
export const createLayersConfig = async (
|
|
16
16
|
selectedIndicator,
|
|
17
17
|
eodashCols,
|
|
18
|
-
|
|
18
|
+
timeOrItem,
|
|
19
19
|
) => {
|
|
20
20
|
log.debug(
|
|
21
21
|
"Creating layers config",
|
|
22
22
|
selectedIndicator,
|
|
23
23
|
eodashCols,
|
|
24
|
-
|
|
24
|
+
timeOrItem,
|
|
25
25
|
);
|
|
26
26
|
const layersCollection = [];
|
|
27
27
|
const dataLayers = {
|
|
@@ -35,11 +35,14 @@ export const createLayersConfig = async (
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
for (const ec of eodashCols) {
|
|
38
|
+
/** @type {Record<string,any>[]} */
|
|
38
39
|
let layers;
|
|
39
|
-
if (
|
|
40
|
-
|
|
40
|
+
if (timeOrItem) {
|
|
41
|
+
const dateOrItem =
|
|
42
|
+
typeof timeOrItem === "string" ? new Date(timeOrItem) : timeOrItem;
|
|
43
|
+
layers = await ec.createLayersJson(dateOrItem);
|
|
41
44
|
} else {
|
|
42
|
-
layers = await ec.createLayersJson();
|
|
45
|
+
layers = await ec.createLayersJson(undefined);
|
|
43
46
|
}
|
|
44
47
|
// Add expand to all analysis layers
|
|
45
48
|
layers.forEach((dl) => {
|
|
@@ -7,6 +7,7 @@ import { storeToRefs } from "pinia";
|
|
|
7
7
|
import { isFirstLoad } from "@/utils/states";
|
|
8
8
|
import { useEmitLayersUpdate, useOnLayersUpdate } from "@/composables";
|
|
9
9
|
import { mapPosition } from "@/store/states";
|
|
10
|
+
import { sanitizeBbox } from "@/eodashSTAC/helpers";
|
|
10
11
|
/**
|
|
11
12
|
* Holder for previous compare map view as it is overwritten by sync
|
|
12
13
|
* @type { import("ol").View | null} mapElement
|
|
@@ -58,6 +59,7 @@ export const useHandleMapMoveEnd = (mapElement, mapPosition) => {
|
|
|
58
59
|
* @param {import("vue").Ref<Record<string,any>[]>} mapLayers
|
|
59
60
|
* @param {import("vue").Ref<import("@eox/map").EOxMap| null>} partnerMap
|
|
60
61
|
* @param {boolean} zoomToExtent
|
|
62
|
+
* @param {import("vue").Ref<import("stac-ts").StacItem | import("stac-ts").StacLink | null>} [selectedItem]
|
|
61
63
|
*/
|
|
62
64
|
export const useInitMap = (
|
|
63
65
|
mapElement,
|
|
@@ -67,6 +69,7 @@ export const useInitMap = (
|
|
|
67
69
|
mapLayers,
|
|
68
70
|
partnerMap,
|
|
69
71
|
zoomToExtent,
|
|
72
|
+
selectedItem,
|
|
70
73
|
) => {
|
|
71
74
|
log.debug(
|
|
72
75
|
"InitMap",
|
|
@@ -75,10 +78,22 @@ export const useInitMap = (
|
|
|
75
78
|
eodashCols.values,
|
|
76
79
|
datetime.value,
|
|
77
80
|
);
|
|
78
|
-
|
|
81
|
+
// watch selectedItem if provided
|
|
82
|
+
const watching = selectedItem
|
|
83
|
+
? [selectedIndicator, datetime, selectedItem]
|
|
84
|
+
: [selectedIndicator, datetime];
|
|
79
85
|
const stopIndicatorWatcher = watch(
|
|
80
|
-
|
|
81
|
-
async (
|
|
86
|
+
watching,
|
|
87
|
+
async (updated, previous) => {
|
|
88
|
+
const [updatedStac, updatedTime, updatedItem] =
|
|
89
|
+
/** @type {[import("stac-ts").StacCollection, string, import("stac-ts").StacItem | null]} */ (
|
|
90
|
+
selectedItem ? updated : [updated[0], updated[1], null]
|
|
91
|
+
);
|
|
92
|
+
const [previousStac, previousTime, previousItem] =
|
|
93
|
+
/** @type {[import("stac-ts").StacCollection, string, import("stac-ts").StacItem]} */ (
|
|
94
|
+
selectedItem ? previous : [previous[0], previous[1], null]
|
|
95
|
+
);
|
|
96
|
+
|
|
82
97
|
if (updatedStac) {
|
|
83
98
|
log.debug(
|
|
84
99
|
"Selected Indicator watch triggered",
|
|
@@ -98,7 +113,9 @@ export const useInitMap = (
|
|
|
98
113
|
let layersCollection = [];
|
|
99
114
|
|
|
100
115
|
const onlyTimeChanged =
|
|
101
|
-
updatedStac?.id === previousStac?.id &&
|
|
116
|
+
updatedStac?.id === previousStac?.id &&
|
|
117
|
+
(updatedTime !== previousTime ||
|
|
118
|
+
(updatedItem && updatedItem?.id !== previousItem?.id));
|
|
102
119
|
|
|
103
120
|
const { selectedCompareStac } = storeToRefs(useSTAcStore());
|
|
104
121
|
if (mapElement?.value?.id === "main") {
|
|
@@ -115,12 +132,12 @@ export const useInitMap = (
|
|
|
115
132
|
}
|
|
116
133
|
}
|
|
117
134
|
|
|
118
|
-
// We re-
|
|
135
|
+
// We re-create the configuration if time changed
|
|
119
136
|
if (onlyTimeChanged) {
|
|
120
137
|
layersCollection = await createLayersConfig(
|
|
121
138
|
updatedStac,
|
|
122
139
|
eodashCols,
|
|
123
|
-
updatedTime,
|
|
140
|
+
updatedItem ?? updatedTime,
|
|
124
141
|
);
|
|
125
142
|
log.debug(
|
|
126
143
|
"Assigned layers after changing time only",
|
|
@@ -142,7 +159,7 @@ export const useInitMap = (
|
|
|
142
159
|
layersCollection = await createLayersConfig(
|
|
143
160
|
updatedStac,
|
|
144
161
|
eodashCols,
|
|
145
|
-
|
|
162
|
+
selectedItem ? updatedItem : updatedTime,
|
|
146
163
|
);
|
|
147
164
|
|
|
148
165
|
// We try to set the current time selection to latest extent date
|
|
@@ -157,6 +174,7 @@ export const useInitMap = (
|
|
|
157
174
|
);
|
|
158
175
|
}
|
|
159
176
|
if (
|
|
177
|
+
!updatedItem &&
|
|
160
178
|
endInterval !== null &&
|
|
161
179
|
endInterval.toISOString() !== datetime.value &&
|
|
162
180
|
!isFirstLoad.value
|
|
@@ -168,6 +186,7 @@ export const useInitMap = (
|
|
|
168
186
|
// Try to move map view to extent only when main
|
|
169
187
|
// indicator and map changes
|
|
170
188
|
if (
|
|
189
|
+
!updatedItem &&
|
|
171
190
|
mapElement?.value?.id === "main" &&
|
|
172
191
|
updatedStac.extent?.spatial.bbox &&
|
|
173
192
|
!(
|
|
@@ -178,12 +197,7 @@ export const useInitMap = (
|
|
|
178
197
|
) {
|
|
179
198
|
// Sanitize extent,
|
|
180
199
|
const b = updatedStac.extent?.spatial.bbox[0];
|
|
181
|
-
const sanitizedExtent = [
|
|
182
|
-
b?.[0] > -180 ? b?.[0] : -180,
|
|
183
|
-
b?.[1] > -90 ? b?.[1] : -90,
|
|
184
|
-
b?.[2] < 180 ? b?.[2] : 180,
|
|
185
|
-
b?.[3] < 90 ? b?.[3] : 90,
|
|
186
|
-
];
|
|
200
|
+
const sanitizedExtent = sanitizeBbox([...b]);
|
|
187
201
|
|
|
188
202
|
const reprojExtent = mapElement.value?.transformExtent(
|
|
189
203
|
sanitizedExtent,
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
.schema="jsonformSchema"
|
|
10
10
|
></eox-jsonform>
|
|
11
11
|
<eox-chart
|
|
12
|
+
ref="chartElRef"
|
|
12
13
|
class="chart"
|
|
13
14
|
v-if="isProcessed && chartSpec"
|
|
14
15
|
.spec="toRaw(chartSpec)"
|
|
@@ -45,7 +46,7 @@ import "@eox/drawtools";
|
|
|
45
46
|
import "@eox/jsonform";
|
|
46
47
|
import { useSTAcStore } from "@/store/stac";
|
|
47
48
|
import { storeToRefs } from "pinia";
|
|
48
|
-
import { computed, ref, toRaw, useTemplateRef } from "vue";
|
|
49
|
+
import { computed, ref, toRaw, useTemplateRef, watch } from "vue";
|
|
49
50
|
import ProcessList from "./ProcessList.vue";
|
|
50
51
|
import { handleProcesses, onChartClick } from "./methods/handling";
|
|
51
52
|
import { useInitProcess, useAutoExec } from "./methods/composables";
|
|
@@ -55,6 +56,8 @@ import {
|
|
|
55
56
|
indicator,
|
|
56
57
|
mapCompareEl,
|
|
57
58
|
mapEl,
|
|
59
|
+
chartEl,
|
|
60
|
+
compareChartEl,
|
|
58
61
|
} from "@/store/states";
|
|
59
62
|
import { download } from "./methods/utils";
|
|
60
63
|
import { compareJobs, jobs } from "./states";
|
|
@@ -86,6 +89,10 @@ const jsonformEl =
|
|
|
86
89
|
/** @type {Readonly<import("vue").ShallowRef<import("@eox/jsonform").EOxJSONForm | null>>} */ (
|
|
87
90
|
useTemplateRef("jsonformEl")
|
|
88
91
|
);
|
|
92
|
+
const chartElRef =
|
|
93
|
+
/** @type {Readonly<import("vue").ShallowRef<import("@eox/chart").EOxChart | null>>} */ (
|
|
94
|
+
useTemplateRef("chartElRef")
|
|
95
|
+
);
|
|
89
96
|
const isAsync = computed(
|
|
90
97
|
() =>
|
|
91
98
|
selectedStac.value?.links.filter((l) => l.endpoint === "eoxhub_workspaces")
|
|
@@ -208,6 +215,15 @@ const chartStyles = computed(() => {
|
|
|
208
215
|
}
|
|
209
216
|
return styles;
|
|
210
217
|
});
|
|
218
|
+
|
|
219
|
+
// Assign chart element to global state based on compare mode
|
|
220
|
+
watch(chartElRef, (newVal) => {
|
|
221
|
+
if (enableCompare) {
|
|
222
|
+
compareChartEl.value = newVal;
|
|
223
|
+
} else {
|
|
224
|
+
chartEl.value = newVal;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
211
227
|
</script>
|
|
212
228
|
<style>
|
|
213
229
|
eox-chart {
|
|
@@ -2,7 +2,10 @@ import axios from "@/plugins/axios";
|
|
|
2
2
|
import { getBboxProperty } from "../../utils";
|
|
3
3
|
import { toAbsolute } from "stac-js/src/http.js";
|
|
4
4
|
import { currentCompareUrl, currentUrl } from "@/store/states";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
getDatetimeProperty,
|
|
7
|
+
generateLinksFromItems,
|
|
8
|
+
} from "@/eodashSTAC/helpers";
|
|
6
9
|
import { readParquetItems } from "@/eodashSTAC/parquet";
|
|
7
10
|
|
|
8
11
|
/**
|
|
@@ -82,10 +85,13 @@ async function fetchVedaCOGsConfig(selectedStac, absoluteUrl) {
|
|
|
82
85
|
const parquetAsset = Object.values(collection.assets ?? {}).find(
|
|
83
86
|
(asset) =>
|
|
84
87
|
asset.type === "application/vnd.apache.parquet" &&
|
|
85
|
-
|
|
88
|
+
asset.roles?.includes("collection-mirror"),
|
|
86
89
|
);
|
|
87
90
|
if (parquetAsset) {
|
|
88
|
-
const parquetAbsoluteUrl = toAbsolute(
|
|
91
|
+
const parquetAbsoluteUrl = toAbsolute(
|
|
92
|
+
parquetAsset.href,
|
|
93
|
+
toAbsolute(link.href, absoluteUrl),
|
|
94
|
+
);
|
|
89
95
|
await readParquetItems(parquetAbsoluteUrl).then((items) => {
|
|
90
96
|
collection.links.push(...generateLinksFromItems(items));
|
|
91
97
|
});
|
|
@@ -181,7 +181,9 @@ export async function handleProcesses({
|
|
|
181
181
|
for (const layer of newLayers) {
|
|
182
182
|
if (layer.type === "WebGLTile" && layer.source?.type === "GeoTIFF") {
|
|
183
183
|
processResults.value.push(...(layer.source.sources ?? []));
|
|
184
|
+
//@ts-expect-error TODO
|
|
184
185
|
} else if (layer.source && "url" in layer.source) {
|
|
186
|
+
//@ts-expect-error TODO
|
|
185
187
|
processResults.value.push(layer.source.url);
|
|
186
188
|
}
|
|
187
189
|
}
|