@eodash/eodash 5.7.0 → 5.7.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/EodashOverlay.vue +27 -4
- package/core/client/composables/DefineEodash.js +0 -1
- package/core/client/composables/DefineWidgets.js +3 -1
- package/core/client/eodashSTAC/EodashCollection.js +74 -20
- package/core/client/eodashSTAC/cql.js +64 -0
- package/core/client/eodashSTAC/createLayers.js +169 -116
- package/core/client/eodashSTAC/helpers.js +391 -98
- package/core/client/eodashSTAC/mosaic.js +416 -0
- package/core/client/plugins/axios.js +31 -1
- package/core/client/store/actions.js +1 -1
- package/core/client/store/stac.js +25 -4
- package/core/client/store/states.js +20 -2
- package/core/client/types.ts +147 -28
- package/core/client/utils/bands-editor/exampleSchema.json +50 -50
- package/core/client/utils/states.js +10 -0
- package/dist/client/{DashboardLayout-kRsmsNW5.js → DashboardLayout-ePbdvUTE.js} +2 -2
- package/dist/client/{DynamicWebComponent-CnKhYo0K.js → DynamicWebComponent-g5SdRbjY.js} +1 -1
- package/dist/client/{EodashChart-CLDqE93C.js → EodashChart-ChrkA5oS.js} +7 -6
- package/dist/client/{EodashDatePicker-CMPDT-ce.js → EodashDatePicker-CY1TrsDo.js} +3 -3
- package/dist/client/{EodashItemFilter-BpdA8QQa.js → EodashItemFilter-DzshHDlS.js} +2 -1
- package/dist/client/{EodashLayerControl-BHpDA4_0.js → EodashLayerControl-DMCeMkSd.js} +50 -20
- package/dist/client/{EodashLayoutSwitcher-B1fRUt7G.js → EodashLayoutSwitcher-iJ8mX1rF.js} +3 -3
- package/dist/client/{EodashMapBtns-Cpned0tc.js → EodashMapBtns-C7Cr7q5Y.js} +200 -86
- package/dist/client/EodashStacInfo-K7-iuXa7.js +169 -0
- package/dist/client/{EodashTools-1zHz26gv.js → EodashTools-BEK7e7JM.js} +4 -4
- package/dist/client/{ExportState-DbOm8hBI.js → ExportState-CqIzfMYQ.js} +6 -168
- package/dist/client/{Footer-BKg-VVkj.js → Footer-1P0cmBOZ.js} +1 -1
- package/dist/client/{Header-DCrwCvmY.js → Header-CkkBaBNh.js} +2 -2
- package/dist/client/{MobileLayout-vWSHpluo.js → MobileLayout-BPf49kDU.js} +2 -2
- package/dist/client/{PopUp-9uimfK49.js → PopUp-DPZq5SWI.js} +4 -168
- package/dist/client/{ProcessList-CTTIZa06.js → ProcessList-DuI6WpS1.js} +5 -5
- package/dist/client/VDivider-Bj9LG_JV.js +168 -0
- package/dist/client/{VImg-CrmB76ZY.js → VImg-Ddv5OyMz.js} +2 -2
- package/dist/client/{VMain-OKZNpcEG.js → VMain-7yqk_qC3.js} +1 -1
- package/dist/client/{VTooltip-CJw2FyWk.js → VTooltip-2hAJyEoa.js} +2 -2
- package/dist/client/{WidgetsContainer-BaWOnE5R.js → WidgetsContainer-2DOrlwCB.js} +1 -1
- package/dist/client/{asWebComponent-BHWpMuE3.js → asWebComponent-BlFN2lkB.js} +456 -306
- package/dist/client/{async-DSKj6g1f.js → async-B2H8ZwUK.js} +2 -2
- package/dist/client/{create-layers-config-CBoYedqB.js → create-layers-config-u_vn5hPk.js} +17 -17
- package/dist/client/dialog-transition-BrMkMiNa.js +170 -0
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-DH51zPUr.js → forwardRefs-DAlror6d.js} +8 -87
- package/dist/client/{handling-BrcDDlgS.js → handling-B6I1V5eG.js} +3 -3
- package/dist/client/{helpers-DjZVl_WF.js → helpers-CBqIUSXJ.js} +794 -182
- package/dist/client/index-BWq1ZKaV.js +3168 -0
- package/dist/client/{index-CUjl-ZsI.js → index-CJ9UI3ln.js} +2 -2
- package/dist/client/{index-CSG_JoOA.js → index-DXLz4sFR.js} +62 -56
- package/dist/client/{index-1JKE68n3.js → index-DhKU6KqM.js} +211 -67
- package/dist/client/{index-Cu3-13Xg.js → index-DjQlbWbJ.js} +7 -6
- package/dist/client/mosaic-BFYLEwyx.js +455 -0
- package/dist/client/templates.js +250 -119
- package/dist/client/{transition-OHcz5Qq1.js → transition-D_W6Wn9v.js} +1 -1
- package/dist/node/cli.js +5 -5
- package/dist/node/types.d.ts +4 -0
- package/dist/types/core/client/composables/DefineEodash.d.ts +1 -1
- package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +57 -25
- package/dist/types/core/client/eodashSTAC/cql.d.ts +15 -0
- package/dist/types/core/client/eodashSTAC/createLayers.d.ts +42 -23
- package/dist/types/core/client/eodashSTAC/helpers.d.ts +77 -18
- package/dist/types/core/client/eodashSTAC/mosaic.d.ts +56 -0
- package/dist/types/core/client/store/stac.d.ts +31 -7
- package/dist/types/core/client/store/states.d.ts +24 -2
- package/dist/types/core/client/types.d.ts +123 -24
- package/dist/types/core/client/utils/states.d.ts +12 -0
- package/dist/types/templates/baseConfig.d.ts +1 -100
- package/dist/types/templates/compare.d.ts +32 -3
- package/dist/types/templates/expert.d.ts +18 -0
- package/dist/types/templates/explore.d.ts +9 -1
- package/dist/types/templates/lite.d.ts +11 -0
- package/dist/types/widgets/EodashChart.vue.d.ts +5 -3
- package/dist/types/widgets/EodashItemCatalog/index.vue.d.ts +129 -2
- package/dist/types/widgets/EodashItemCatalog/methods/filters.d.ts +28 -6
- package/dist/types/widgets/EodashItemCatalog/methods/handlers.d.ts +17 -4
- package/dist/types/widgets/EodashItemCatalog/methods/map.d.ts +16 -4
- package/dist/types/widgets/EodashLayerControl.vue.d.ts +35 -16
- package/dist/types/widgets/EodashMap/EodashMapBtns.vue.d.ts +14 -10
- package/dist/types/widgets/EodashMap/index.vue.d.ts +86 -37
- package/dist/types/widgets/EodashMap/methods/create-layers-config.d.ts +1 -1
- package/dist/types/widgets/EodashMap/methods/index.d.ts +5 -1
- package/dist/types/widgets/EodashMap/methods/use-map-loading.d.ts +1 -0
- package/dist/types/widgets/EodashProcess/index.vue.d.ts +5 -3
- package/dist/types/widgets/EodashProcess/states.d.ts +1 -1
- package/dist/types/widgets/EodashStacInfo.vue.d.ts +20 -0
- package/dist/types/widgets/EodashTimeSlider/index.vue.d.ts +20 -0
- package/dist/types/widgets/EodashTimeSlider/methods/index.d.ts +3 -8
- package/dist/types/widgets/EodashTimeSlider/types.d.ts +6 -16
- package/dist/types/widgets/EodashTools.vue.d.ts +5 -5
- package/package.json +33 -33
- package/templates/baseConfig.js +36 -6
- package/templates/compare.js +62 -7
- package/templates/expert.js +23 -0
- package/templates/explore.js +11 -5
- package/templates/lite.js +14 -0
- package/widgets/EodashChart.vue +1 -0
- package/widgets/EodashItemCatalog/index.vue +363 -35
- package/widgets/EodashItemCatalog/methods/filters.js +134 -70
- package/widgets/EodashItemCatalog/methods/handlers.js +113 -19
- package/widgets/EodashItemCatalog/methods/map.js +142 -28
- package/widgets/EodashLayerControl.vue +42 -11
- package/widgets/EodashMap/EodashMapBtns.vue +109 -48
- package/widgets/EodashMap/index.vue +89 -105
- package/widgets/EodashMap/methods/btns.js +37 -5
- package/widgets/EodashMap/methods/create-layers-config.js +16 -16
- package/widgets/EodashMap/methods/index.js +71 -8
- package/widgets/EodashMap/methods/use-map-loading.js +52 -0
- package/widgets/EodashProcess/index.vue +1 -0
- package/widgets/EodashProcess/states.js +1 -1
- package/widgets/EodashStacInfo.vue +64 -2
- package/widgets/EodashTimeSlider/index.vue +58 -2
- package/widgets/EodashTimeSlider/methods/index.js +5 -48
- package/widgets/EodashTimeSlider/types.ts +7 -17
- package/dist/client/EodashStacInfo-BQspAHKH.js +0 -107
- package/dist/client/index-5Jhsa8Xe.js +0 -570
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
import { useOnLayersUpdate } from "@/composables";
|
|
2
|
-
import { mapEl } from "@/store/states";
|
|
3
2
|
import { onMounted, onUnmounted } from "vue";
|
|
3
|
+
import { createOnSelectHandler } from "./handlers";
|
|
4
|
+
import { tooltipAdapter } from "@/store/states";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
*
|
|
7
8
|
* @param {import("@/types").GeoJsonFeature[]} features
|
|
9
|
+
* @param {import("vue").Ref<import("@eox/map").EOxMap | null>} mapElement
|
|
10
|
+
* @param {string[] | undefined} hoverProperties
|
|
11
|
+
* @param {object} [stacItemsStyle]
|
|
12
|
+
* @param {object} [stacItemsInteractionStyle]
|
|
8
13
|
*/
|
|
9
|
-
export function renderItemsFeatures(
|
|
14
|
+
export function renderItemsFeatures(
|
|
15
|
+
features,
|
|
16
|
+
mapElement,
|
|
17
|
+
hoverProperties,
|
|
18
|
+
stacItemsStyle,
|
|
19
|
+
stacItemsInteractionStyle,
|
|
20
|
+
) {
|
|
21
|
+
const currentMap = mapElement.value;
|
|
10
22
|
let analysisLayers =
|
|
11
23
|
/** @type {import("@eox/map/src/layers").EOxLayerTypeGroup} */ (
|
|
12
|
-
|
|
24
|
+
currentMap?.layers?.find((l) => l.properties?.id === "AnalysisGroup")
|
|
13
25
|
);
|
|
14
|
-
if (!
|
|
26
|
+
if (!currentMap || !features) {
|
|
15
27
|
return;
|
|
16
28
|
}
|
|
17
29
|
if (!analysisLayers) {
|
|
@@ -23,9 +35,9 @@ export function renderItemsFeatures(features) {
|
|
|
23
35
|
},
|
|
24
36
|
layers: [],
|
|
25
37
|
};
|
|
26
|
-
|
|
38
|
+
currentMap.layers = [...currentMap.layers, analysisLayers];
|
|
27
39
|
}
|
|
28
|
-
|
|
40
|
+
/** @type {import("@eox/map/src/layers").EOxLayerType<"Vector","Vector">} */
|
|
29
41
|
const stacItemsLayer = {
|
|
30
42
|
type: "Vector",
|
|
31
43
|
properties: {
|
|
@@ -34,14 +46,16 @@ export function renderItemsFeatures(features) {
|
|
|
34
46
|
},
|
|
35
47
|
source: {
|
|
36
48
|
type: "Vector",
|
|
49
|
+
//@ts-expect-error todo
|
|
37
50
|
url:
|
|
38
51
|
"data:application/geo+json," +
|
|
39
52
|
encodeURIComponent(
|
|
40
53
|
JSON.stringify({ type: "FeatureCollection", features }),
|
|
41
54
|
),
|
|
42
55
|
format: "GeoJSON",
|
|
56
|
+
projection: "EPSG:4326",
|
|
43
57
|
},
|
|
44
|
-
style: {
|
|
58
|
+
style: stacItemsStyle || {
|
|
45
59
|
"fill-color": "transparent",
|
|
46
60
|
"stroke-color": "#003170",
|
|
47
61
|
},
|
|
@@ -49,35 +63,47 @@ export function renderItemsFeatures(features) {
|
|
|
49
63
|
{
|
|
50
64
|
type: "select",
|
|
51
65
|
options: {
|
|
52
|
-
id: "stac-
|
|
66
|
+
id: "stac-item-hover",
|
|
53
67
|
condition: "pointermove",
|
|
54
|
-
|
|
68
|
+
tooltip: hoverProperties?.length,
|
|
69
|
+
style: stacItemsInteractionStyle || {
|
|
55
70
|
"stroke-color": "white",
|
|
56
71
|
"stroke-width": 3,
|
|
57
72
|
},
|
|
58
73
|
},
|
|
59
74
|
},
|
|
75
|
+
{
|
|
76
|
+
type: "select",
|
|
77
|
+
options: {
|
|
78
|
+
id: "stac-items",
|
|
79
|
+
condition: "click",
|
|
80
|
+
tooltip: false,
|
|
81
|
+
style: stacItemsInteractionStyle || {
|
|
82
|
+
"stroke-color": "#003047",
|
|
83
|
+
"stroke-width": 3.2,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
60
87
|
],
|
|
61
88
|
};
|
|
62
89
|
const exists = analysisLayers.layers.some(
|
|
63
|
-
(l) => l.properties?.id ===
|
|
90
|
+
(l) => l.properties?.id === stacItemsLayer.properties?.id,
|
|
64
91
|
);
|
|
65
92
|
if (exists) {
|
|
66
|
-
|
|
67
|
-
mapEl.value.addOrUpdateLayer(stacItemsLayer);
|
|
93
|
+
currentMap.addOrUpdateLayer(stacItemsLayer);
|
|
68
94
|
return;
|
|
69
95
|
} else {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
mapEl.value.layers = [...mapEl.value.layers];
|
|
96
|
+
analysisLayers.layers.unshift(stacItemsLayer);
|
|
97
|
+
currentMap.layers = [...currentMap.layers];
|
|
73
98
|
}
|
|
74
99
|
}
|
|
75
100
|
|
|
76
101
|
/**
|
|
77
102
|
* @param {import("vue").Ref<any>} itemFilter
|
|
78
103
|
* @param {boolean} bboxFilter
|
|
104
|
+
* @param {import("vue").Ref<import("@eox/map").EOxMap | null>} mapElement
|
|
79
105
|
*/
|
|
80
|
-
export const useSearchOnMapMove = (itemFilter, bboxFilter) => {
|
|
106
|
+
export const useSearchOnMapMove = (itemFilter, bboxFilter, mapElement) => {
|
|
81
107
|
if (!bboxFilter) {
|
|
82
108
|
return;
|
|
83
109
|
}
|
|
@@ -86,58 +112,146 @@ export const useSearchOnMapMove = (itemFilter, bboxFilter) => {
|
|
|
86
112
|
const handler = () => {
|
|
87
113
|
clearTimeout(timeout);
|
|
88
114
|
timeout = setTimeout(() => {
|
|
115
|
+
if (mapElement.value?.projection == "globe") {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
89
118
|
itemFilter.value?.search();
|
|
90
|
-
},
|
|
119
|
+
}, 500);
|
|
91
120
|
};
|
|
92
121
|
onMounted(() => {
|
|
93
|
-
|
|
122
|
+
mapElement.value?.map.on("moveend", handler);
|
|
94
123
|
});
|
|
95
124
|
onUnmounted(() => {
|
|
96
|
-
|
|
125
|
+
mapElement.value?.map.un("moveend", handler);
|
|
97
126
|
});
|
|
98
127
|
};
|
|
99
128
|
/**
|
|
100
129
|
*
|
|
101
130
|
* @param {import("vue").Ref<import("@/types").GeoJsonFeature[]>} currentItems
|
|
131
|
+
* @param {import("vue").Ref<import("@eox/map").EOxMap | null>} mapElement
|
|
132
|
+
* @param {string[] | undefined} hoverProperties
|
|
133
|
+
* @param {object} [stacItemsStyle]
|
|
134
|
+
* @param {object} [stacItemsInteractionStyle]
|
|
102
135
|
*/
|
|
103
|
-
export const useRenderItemsFeatures = (
|
|
136
|
+
export const useRenderItemsFeatures = (
|
|
137
|
+
currentItems,
|
|
138
|
+
mapElement,
|
|
139
|
+
hoverProperties,
|
|
140
|
+
stacItemsStyle,
|
|
141
|
+
stacItemsInteractionStyle,
|
|
142
|
+
) => {
|
|
104
143
|
onMounted(() => {
|
|
105
|
-
renderItemsFeatures(
|
|
144
|
+
renderItemsFeatures(
|
|
145
|
+
currentItems.value,
|
|
146
|
+
mapElement,
|
|
147
|
+
hoverProperties,
|
|
148
|
+
stacItemsStyle,
|
|
149
|
+
stacItemsInteractionStyle,
|
|
150
|
+
);
|
|
106
151
|
});
|
|
107
152
|
|
|
108
153
|
useOnLayersUpdate(() => {
|
|
109
154
|
// consider cases where this is not needed
|
|
110
|
-
renderItemsFeatures(
|
|
155
|
+
renderItemsFeatures(
|
|
156
|
+
currentItems.value,
|
|
157
|
+
mapElement,
|
|
158
|
+
hoverProperties,
|
|
159
|
+
stacItemsStyle,
|
|
160
|
+
stacItemsInteractionStyle,
|
|
161
|
+
);
|
|
111
162
|
});
|
|
112
163
|
};
|
|
164
|
+
/**
|
|
165
|
+
* Registers a tooltip adapter that displays item properties when hovering over map features.
|
|
166
|
+
* @param {string[]} [hoverProperties]
|
|
167
|
+
*/
|
|
168
|
+
export function useHoverTooltip(hoverProperties) {
|
|
169
|
+
/**
|
|
170
|
+
* @param {*} val
|
|
171
|
+
*/
|
|
172
|
+
const formatValue = (val) => {
|
|
173
|
+
if (typeof val === "number") {
|
|
174
|
+
return val.toFixed(0);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (typeof val === "string") {
|
|
178
|
+
// Attempt to parse as date if string looks like ISO date
|
|
179
|
+
if (val.length > 9 && /\d{4}-\d{2}-\d{2}/.test(val)) {
|
|
180
|
+
const timestamp = Date.parse(val);
|
|
181
|
+
if (!isNaN(timestamp)) {
|
|
182
|
+
return new Date(timestamp).toUTCString();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return val;
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* @param {string} key
|
|
190
|
+
*/
|
|
191
|
+
const formatKey = (key) => {
|
|
192
|
+
let formattedKey = key;
|
|
193
|
+
if (key.includes(":")) {
|
|
194
|
+
formattedKey = key.split(":")[1];
|
|
195
|
+
}
|
|
196
|
+
return formattedKey
|
|
197
|
+
.replace(/_/g, " ")
|
|
198
|
+
.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
199
|
+
};
|
|
200
|
+
onMounted(() => {
|
|
201
|
+
tooltipAdapter.value = ({ key, value }) => {
|
|
202
|
+
if (hoverProperties && hoverProperties.includes(key)) {
|
|
203
|
+
return { key: formatKey(key), value: formatValue(value) };
|
|
204
|
+
}
|
|
205
|
+
return undefined;
|
|
206
|
+
};
|
|
207
|
+
});
|
|
208
|
+
onUnmounted(() => {
|
|
209
|
+
tooltipAdapter.value = null;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
113
213
|
/**
|
|
114
214
|
*
|
|
115
215
|
* @param {import("vue").Ref<any>} itemfilterEl
|
|
216
|
+
* @param {ReturnType< typeof import("@/store/stac").useSTAcStore>} store
|
|
217
|
+
* @param {import("vue").Ref<import("@eox/map").EOxMap | null>} mapElement
|
|
218
|
+
* @param {boolean} enableCompare
|
|
116
219
|
*/
|
|
117
|
-
export function
|
|
220
|
+
export function useRenderOnFeatureClick(
|
|
221
|
+
itemfilterEl,
|
|
222
|
+
store,
|
|
223
|
+
mapElement,
|
|
224
|
+
enableCompare,
|
|
225
|
+
) {
|
|
226
|
+
const onSelectItem = createOnSelectHandler(store, enableCompare, mapElement);
|
|
118
227
|
/**
|
|
119
228
|
*
|
|
120
229
|
* @param {CustomEvent} evt
|
|
121
230
|
*/
|
|
122
231
|
const handler = (evt) => {
|
|
232
|
+
if (evt.detail.originalEvent.type !== "click") {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
123
235
|
const itemId = evt.detail?.feature?.getId();
|
|
124
236
|
if (!itemId) {
|
|
125
237
|
return;
|
|
126
238
|
}
|
|
127
|
-
const item = itemfilterEl.value.
|
|
239
|
+
const item = itemfilterEl.value.results?.find(
|
|
128
240
|
//@ts-expect-error todo
|
|
129
|
-
(r) => r
|
|
241
|
+
(r) => r?.id === itemId,
|
|
130
242
|
);
|
|
243
|
+
|
|
131
244
|
if (item) {
|
|
132
|
-
|
|
245
|
+
onSelectItem(new CustomEvent("select", { detail: item }));
|
|
133
246
|
}
|
|
134
247
|
};
|
|
248
|
+
|
|
135
249
|
onMounted(() => {
|
|
136
250
|
//@ts-expect-error todo
|
|
137
|
-
|
|
251
|
+
mapElement.value?.addEventListener("select", handler);
|
|
138
252
|
});
|
|
139
253
|
onUnmounted(() => {
|
|
140
254
|
//@ts-expect-error todo
|
|
141
|
-
|
|
255
|
+
mapElement.value?.removeEventListener("select", handler);
|
|
142
256
|
});
|
|
143
257
|
}
|
|
@@ -5,19 +5,24 @@
|
|
|
5
5
|
:key="mapElement"
|
|
6
6
|
v-bind="config"
|
|
7
7
|
:for="mapElement"
|
|
8
|
+
.showLayerZoomState="true"
|
|
8
9
|
.customEditorInterfaces="bandsEditorInterface"
|
|
9
10
|
@datetime:updated="debouncedHandleDateTime"
|
|
10
11
|
toolsAsList="true"
|
|
11
12
|
ref="eoxLayercontrol"
|
|
12
13
|
@layerConfig:change="onLayerConfigChange"
|
|
13
14
|
>
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
<span
|
|
16
|
+
slot="layerstitle"
|
|
17
|
+
class="d-flex justify-space-between ma-2 pa-2 flex-shrink-0"
|
|
18
|
+
>
|
|
19
|
+
<h4 v-if="title">{{ title }}</h4>
|
|
20
|
+
<EodashLayoutSwitcher
|
|
21
|
+
v-if="enableLayoutSwitcher"
|
|
22
|
+
:target="layoutTarget"
|
|
23
|
+
:icon="layoutIcon"
|
|
24
|
+
/>
|
|
25
|
+
</span>
|
|
21
26
|
</eox-layercontrol>
|
|
22
27
|
</span>
|
|
23
28
|
</template>
|
|
@@ -33,9 +38,12 @@ import {
|
|
|
33
38
|
layerControlFormValue,
|
|
34
39
|
layerControlFormValueCompare,
|
|
35
40
|
} from "@/utils/states";
|
|
41
|
+
import { updateGeoZarrBands } from "@/eodashSTAC/helpers";
|
|
36
42
|
import { storeToRefs } from "pinia";
|
|
37
43
|
import { useSTAcStore } from "@/store/stac";
|
|
38
44
|
import { bandsEditorInterface } from "@/utils/bands-editor";
|
|
45
|
+
import EodashLayoutSwitcher from "^/EodashLayoutSwitcher.vue";
|
|
46
|
+
import { mdiViewDashboard } from "@mdi/js";
|
|
39
47
|
import { useEmitLayersUpdate } from "@/composables";
|
|
40
48
|
|
|
41
49
|
if (!customElements.get("eox-layercontrol")) {
|
|
@@ -46,22 +54,39 @@ if (!customElements.get("eox-jsonform")) {
|
|
|
46
54
|
}
|
|
47
55
|
|
|
48
56
|
const props = defineProps({
|
|
57
|
+
/** Which map instance this control is bound to. Use `"second"` in a compare-mode layout. */
|
|
49
58
|
map: {
|
|
50
59
|
/** @type {import("vue").PropType<"first" | "second">} */
|
|
51
60
|
//@ts-expect-error todo
|
|
52
61
|
type: String,
|
|
53
62
|
default: "first",
|
|
54
63
|
},
|
|
64
|
+
/** Tool tabs shown inside `eox-layercontrol`. Remove entries to hide individual tabs. */
|
|
55
65
|
tools: {
|
|
56
|
-
type: Array,
|
|
66
|
+
type: /** @type {import("vue").PropType<string[]>} */ (Array),
|
|
57
67
|
default: () => ["datetime", "info", "config", "legend", "opacity"],
|
|
58
68
|
},
|
|
69
|
+
/** Heading rendered above the layer list. Set to `false` to hide it. */
|
|
59
70
|
title: {
|
|
60
|
-
type:
|
|
71
|
+
type: /** @type {import("vue").PropType<string | false>} */ ([
|
|
72
|
+
String,
|
|
73
|
+
Boolean,
|
|
74
|
+
]),
|
|
61
75
|
default: "Layers",
|
|
62
76
|
},
|
|
77
|
+
/** CSS custom-property overrides forwarded to the underlying `eox-layercontrol` element via its `style` attribute. */
|
|
63
78
|
cssVars: {
|
|
64
|
-
type:
|
|
79
|
+
type: /** @type {import("vue").PropType<Record<string, string>>} */ (
|
|
80
|
+
Object
|
|
81
|
+
),
|
|
82
|
+
default: {},
|
|
83
|
+
},
|
|
84
|
+
layoutIcon: {
|
|
85
|
+
type: String,
|
|
86
|
+
default: mdiViewDashboard,
|
|
87
|
+
},
|
|
88
|
+
layoutTarget: {
|
|
89
|
+
type: String,
|
|
65
90
|
},
|
|
66
91
|
});
|
|
67
92
|
|
|
@@ -70,6 +95,10 @@ const config = {
|
|
|
70
95
|
style: props.cssVars,
|
|
71
96
|
};
|
|
72
97
|
|
|
98
|
+
const enableLayoutSwitcher = computed(
|
|
99
|
+
() => !!props.layoutTarget && !!props.layoutIcon,
|
|
100
|
+
);
|
|
101
|
+
|
|
73
102
|
const { selectedCompareStac, selectedStac } = storeToRefs(useSTAcStore());
|
|
74
103
|
|
|
75
104
|
const showControls = computed(() => {
|
|
@@ -83,7 +112,7 @@ const eodashCols =
|
|
|
83
112
|
props.map === "second" ? eodashCompareCollections : eodashCollections;
|
|
84
113
|
const mapElement = props.map === "second" ? mapCompareEl : mapEl;
|
|
85
114
|
|
|
86
|
-
/** @type { import("vue").Ref<
|
|
115
|
+
/** @type { import("vue").Ref<import("@eox/layercontrol").EOxLayerControl | null>} */
|
|
87
116
|
const eoxLayercontrol = ref(null);
|
|
88
117
|
|
|
89
118
|
// eox-timecontrol re-fires datetime:updated after layer reassignment;
|
|
@@ -155,6 +184,8 @@ const debouncedHandleDateTime = (evt) => {
|
|
|
155
184
|
* @param {Event & {detail:{layer:import("ol/layer").Layer;jsonformValue:Record<string,any>}}} evt
|
|
156
185
|
*/
|
|
157
186
|
const onLayerConfigChange = (evt) => {
|
|
187
|
+
updateGeoZarrBands(evt.detail.layer, evt.detail.jsonformValue);
|
|
188
|
+
|
|
158
189
|
if (props.map === "second") {
|
|
159
190
|
layerControlFormValueCompare.value = evt.detail.jsonformValue;
|
|
160
191
|
} else {
|
|
@@ -5,30 +5,28 @@
|
|
|
5
5
|
class="primary small circle small-elevate"
|
|
6
6
|
@click="onMapZoomIn"
|
|
7
7
|
>
|
|
8
|
-
<i class="small"
|
|
9
|
-
|
|
8
|
+
<i class="small">
|
|
9
|
+
<svg viewBox="0 0 24 24"><path :d="mdiPlus"></path></svg>
|
|
10
10
|
</i>
|
|
11
11
|
<div class="tooltip left">Zoom in</div>
|
|
12
12
|
</button>
|
|
13
|
-
|
|
14
13
|
<button
|
|
15
14
|
v-if="enableZoom && !isGlobe"
|
|
16
15
|
class="primary small circle small-elevate"
|
|
17
16
|
@click="onMapZoomOut"
|
|
18
17
|
>
|
|
19
|
-
<i class="small"
|
|
20
|
-
|
|
18
|
+
<i class="small">
|
|
19
|
+
<svg viewBox="0 0 24 24"><path :d="mdiMinus"></path></svg>
|
|
21
20
|
</i>
|
|
22
21
|
<div class="tooltip left">Zoom out</div>
|
|
23
22
|
</button>
|
|
24
|
-
|
|
25
23
|
<button
|
|
26
24
|
v-if="exportMap"
|
|
27
25
|
class="primary small circle small-elevate"
|
|
28
26
|
@click="showMapState = !showMapState"
|
|
29
27
|
>
|
|
30
|
-
<i class="small"
|
|
31
|
-
|
|
28
|
+
<i class="small">
|
|
29
|
+
<svg viewBox="0 0 24 24"><path :d="mdiMapPlus"></path></svg>
|
|
32
30
|
</i>
|
|
33
31
|
<div class="tooltip left">Extract storytelling configuration</div>
|
|
34
32
|
</button>
|
|
@@ -39,8 +37,8 @@
|
|
|
39
37
|
class="primary small circle small-elevate"
|
|
40
38
|
@click="changeMapProjection(availableMapProjection)"
|
|
41
39
|
>
|
|
42
|
-
<i class="small"
|
|
43
|
-
|
|
40
|
+
<i class="small">
|
|
41
|
+
<svg viewBox="0 0 24 24"><path :d="mdiEarthBox"></path></svg>
|
|
44
42
|
</i>
|
|
45
43
|
<div class="tooltip left">Change map projection</div>
|
|
46
44
|
</button>
|
|
@@ -49,23 +47,11 @@
|
|
|
49
47
|
class="primary small circle small-elevate"
|
|
50
48
|
@click="onCompareClick(compareIndicators)"
|
|
51
49
|
>
|
|
52
|
-
<i class="small"
|
|
53
|
-
|
|
50
|
+
<i class="small">
|
|
51
|
+
<svg viewBox="0 0 24 24"><path :d="compareIcon"></path></svg>
|
|
54
52
|
</i>
|
|
55
53
|
<div class="tooltip left">Compare mode</div>
|
|
56
54
|
</button>
|
|
57
|
-
<button
|
|
58
|
-
v-if="backToPOIs && (poi || comparePoi)"
|
|
59
|
-
class="primary small circle small-elevate"
|
|
60
|
-
@click="loadPOiIndicator()"
|
|
61
|
-
>
|
|
62
|
-
<i class="small"
|
|
63
|
-
><svg viewBox="0 0 24 24">
|
|
64
|
-
<path :d="mdiStarFourPointsCircleOutline" />
|
|
65
|
-
</svg>
|
|
66
|
-
</i>
|
|
67
|
-
<div class="tooltip left">Back to POIs</div>
|
|
68
|
-
</button>
|
|
69
55
|
<button
|
|
70
56
|
v-if="enableGlobe && !isInCompareMode"
|
|
71
57
|
class="primary small circle small-elevate"
|
|
@@ -102,20 +88,36 @@
|
|
|
102
88
|
@close="showFeedback = false"
|
|
103
89
|
></eox-feedback>
|
|
104
90
|
</div>
|
|
105
|
-
<
|
|
91
|
+
<button
|
|
106
92
|
v-if="mapEl && !isGlobe && enableSearch"
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
93
|
+
class="primary small circle small-elevate"
|
|
94
|
+
>
|
|
95
|
+
<eox-geosearch
|
|
96
|
+
:for="mapEl"
|
|
97
|
+
:endpoint="opencageUrl"
|
|
98
|
+
:params="searchParams"
|
|
99
|
+
class="geosearch-detached"
|
|
100
|
+
label="Search"
|
|
101
|
+
small
|
|
102
|
+
button
|
|
103
|
+
list-direction="left"
|
|
104
|
+
results-direction="down"
|
|
105
|
+
tooltip="Search"
|
|
106
|
+
tooltip-direction="left"
|
|
107
|
+
></eox-geosearch>
|
|
108
|
+
</button>
|
|
109
|
+
<button
|
|
110
|
+
v-if="backToPOIs && (poi || comparePoi)"
|
|
111
|
+
class="primary small circle small-elevate"
|
|
112
|
+
@click="loadPOiIndicator()"
|
|
113
|
+
>
|
|
114
|
+
<i class="small">
|
|
115
|
+
<svg viewBox="0 0 24 24">
|
|
116
|
+
<path :d="mdiStarFourPointsCircleOutline"></path>
|
|
117
|
+
</svg>
|
|
118
|
+
</i>
|
|
119
|
+
<div class="tooltip left">Back to POIs</div>
|
|
120
|
+
</button>
|
|
119
121
|
<PopUp
|
|
120
122
|
v-model="showCompareIndicators"
|
|
121
123
|
:maxWidth="popupWidth"
|
|
@@ -126,9 +128,29 @@
|
|
|
126
128
|
<EodashItemFilter
|
|
127
129
|
v-bind="itemFilterConfig"
|
|
128
130
|
:enableCompare="true"
|
|
129
|
-
@select="onSelectCompareIndicator"
|
|
131
|
+
@select="onSelectCompareIndicator(compareIndicators)"
|
|
130
132
|
/>
|
|
131
133
|
</PopUp>
|
|
134
|
+
<v-alert
|
|
135
|
+
v-if="showMosaicHint"
|
|
136
|
+
class="mosaic-hint pa-2"
|
|
137
|
+
color="secondary"
|
|
138
|
+
type="info"
|
|
139
|
+
variant="elevated"
|
|
140
|
+
density="compact"
|
|
141
|
+
elevation="4"
|
|
142
|
+
>
|
|
143
|
+
<template v-if="showItemViewHint">
|
|
144
|
+
Viewing individual item —
|
|
145
|
+
<a class="mosaic-hint-link" @click.prevent="returnToOverview.emit()">
|
|
146
|
+
Back to overview
|
|
147
|
+
</a>
|
|
148
|
+
</template>
|
|
149
|
+
<template v-else-if="showZoomHint">Zoom in to explore the data</template>
|
|
150
|
+
<template v-else-if="showNoDataHint">
|
|
151
|
+
No data here - pan or change filters
|
|
152
|
+
</template>
|
|
153
|
+
</v-alert>
|
|
132
154
|
</div>
|
|
133
155
|
</template>
|
|
134
156
|
<script setup>
|
|
@@ -140,8 +162,10 @@ import {
|
|
|
140
162
|
comparePoi,
|
|
141
163
|
isGlobe,
|
|
142
164
|
mapEl,
|
|
165
|
+
mapPosition,
|
|
143
166
|
poi,
|
|
144
167
|
} from "@/store/states";
|
|
168
|
+
import { useMosaicState, normalizeGlobeZoom } from "@/eodashSTAC/mosaic";
|
|
145
169
|
import {
|
|
146
170
|
mdiCompare,
|
|
147
171
|
mdiCompareRemove,
|
|
@@ -195,11 +219,13 @@ const {
|
|
|
195
219
|
default: true,
|
|
196
220
|
},
|
|
197
221
|
compareIndicators: {
|
|
198
|
-
/**
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
222
|
+
/**
|
|
223
|
+
* @type {import("vue").PropType<boolean | {
|
|
224
|
+
* compareTemplate?:string;
|
|
225
|
+
* fallbackTemplate?:string;
|
|
226
|
+
* itemFilterConfig?:Partial<InstanceType<import("./EodashItemFilter.vue").default>["$props"]>
|
|
227
|
+
* }> }
|
|
228
|
+
*/
|
|
203
229
|
type: [Boolean, Object],
|
|
204
230
|
default: true,
|
|
205
231
|
},
|
|
@@ -267,6 +293,32 @@ useTransparentPanel(rootRef);
|
|
|
267
293
|
|
|
268
294
|
const opencageApiKey = process.env.EODASH_OPENCAGE || "NO_KEY_FOUND";
|
|
269
295
|
const opencageUrl = `https://api.opencagedata.com/geocode/v1/json?key=${opencageApiKey}`;
|
|
296
|
+
|
|
297
|
+
const {
|
|
298
|
+
latestLayer,
|
|
299
|
+
isItemView,
|
|
300
|
+
visibilityThreshold,
|
|
301
|
+
returnToOverview,
|
|
302
|
+
hasDataInView,
|
|
303
|
+
} = useMosaicState();
|
|
304
|
+
|
|
305
|
+
const showItemViewHint = computed(
|
|
306
|
+
() => isItemView.value && !!latestLayer.value,
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
const showZoomHint = computed(() => {
|
|
310
|
+
if (!latestLayer.value || isItemView.value) return false;
|
|
311
|
+
const rawZ = mapPosition.value?.[2] ?? 4;
|
|
312
|
+
return normalizeGlobeZoom(rawZ) < visibilityThreshold.value;
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
const showNoDataHint = computed(
|
|
316
|
+
() => !!latestLayer.value && !isItemView.value && !hasDataInView.value,
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
const showMosaicHint = computed(
|
|
320
|
+
() => showItemViewHint.value || showZoomHint.value || showNoDataHint.value,
|
|
321
|
+
);
|
|
270
322
|
</script>
|
|
271
323
|
|
|
272
324
|
<style scoped>
|
|
@@ -296,11 +348,20 @@ const opencageUrl = `https://api.opencagedata.com/geocode/v1/json?key=${opencage
|
|
|
296
348
|
pointer-events: auto !important;
|
|
297
349
|
}
|
|
298
350
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
overflow: visible !important;
|
|
351
|
+
.mosaic-hint {
|
|
352
|
+
position: fixed;
|
|
353
|
+
left: 50%;
|
|
354
|
+
transform: translateX(-50%);
|
|
304
355
|
z-index: 10;
|
|
356
|
+
opacity: 0.8;
|
|
357
|
+
border-radius: 8px;
|
|
358
|
+
pointer-events: auto;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.mosaic-hint-link {
|
|
362
|
+
color: inherit;
|
|
363
|
+
cursor: pointer;
|
|
364
|
+
text-decoration: underline;
|
|
365
|
+
pointer-events: auto;
|
|
305
366
|
}
|
|
306
367
|
</style>
|