@eodash/eodash 5.1.0 → 5.3.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 -2
- package/core/client/components/EodashOverlay.vue +4 -5
- package/core/client/components/MobileLayout.vue +42 -21
- package/core/client/composables/index.js +54 -60
- package/core/client/eodashSTAC/EodashCollection.js +199 -108
- package/core/client/eodashSTAC/auth.js +86 -0
- package/core/client/eodashSTAC/createLayers.js +234 -4
- package/core/client/eodashSTAC/helpers.js +281 -59
- 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-ByVs1DrY.js → DashboardLayout-Cq15p4TH.js} +5 -6
- package/dist/client/{DynamicWebComponent-C3W7HSQm.js → DynamicWebComponent-Cv-fPRG1.js} +1 -1
- package/dist/client/{EodashDatePicker-BIAf1sMT.js → EodashDatePicker-CPlJwEIO.js} +20 -22
- package/dist/client/{EodashItemFilter-DPznh8UB.js → EodashItemFilter-Ydebgbjj.js} +46 -31
- package/dist/client/EodashLayerControl-COhrkNEs.js +1517 -0
- package/dist/client/{EodashLayoutSwitcher-C5qTEffW.js → EodashLayoutSwitcher-pnKhTRZV.js} +4 -4
- package/dist/client/EodashMapBtns-Cj0Fx119.js +301 -0
- package/dist/client/{EodashStacInfo-CSvvF2jI.js → EodashStacInfo-Dadkg_Nj.js} +1 -1
- package/dist/client/EodashTimeSlider-CpoHX0S7.js +53 -0
- package/dist/client/{EodashTools-Cv1SXQ5y.js → EodashTools-UGBG7KC9.js} +10 -7
- package/dist/client/{ExportState-D-iuwaad.js → ExportState-GtJkAqeZ.js} +145 -121
- package/dist/client/{Footer-CyF0zRAk.js → Footer-D3ZPG5c4.js} +1 -1
- package/dist/client/{Header-CgD8jDKU.js → Header-z6AK-wpN.js} +2 -3
- package/dist/client/MobileLayout-BXNsNftb.js +118 -0
- package/dist/client/{PopUp-BsYLvWch.js → PopUp-BbQdjENV.js} +79 -44
- package/dist/client/{ProcessList-C2xsLU2_.js → ProcessList-C6VsdsYI.js} +18 -12
- package/dist/client/{VImg-OHe8YTs2.js → VImg-CxaMSB99.js} +203 -5
- package/dist/client/{VMain-PryTLU4a.js → VMain-Ds7yw0wj.js} +1 -1
- package/dist/client/{VTooltip-DZ0fjpB3.js → VTooltip-Cze6CEVh.js} +2 -3
- package/dist/client/{WidgetsContainer-B9LBadcC.js → WidgetsContainer-D66bj-JJ.js} +1 -1
- package/dist/client/asWebComponent-CWbNRdf9.js +8895 -0
- package/dist/client/{async-DkSu_u2K.js → async-BA7oWCMX.js} +69 -5
- package/dist/client/easing-CH0-9wR8.js +35 -0
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{VOverlay-yUn7p-Uf.js → forwardRefs-BUfxOIo-.js} +308 -28
- package/dist/client/{handling-CgmFXkW6.js → handling-DlNTtKB-.js} +27 -6
- package/dist/client/{helpers-Dy0Q13tP.js → helpers-CtE0W7iu.js} +595 -278
- package/dist/client/{index-skjhlH8u.js → index-CeEZIjO6.js} +26 -13
- package/dist/client/{index-Ch_HchK3.js → index-CsKbRDeN.js} +238 -77
- package/dist/client/{index-Dqj4tbx2.js → index-D4_NRKrf.js} +2 -2
- package/dist/client/index-DeECc3lV.js +571 -0
- 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 +106 -49
- package/dist/client/{transition-C98Yn4Vo.js → transition-Byvp3L6Y.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 +51 -15
- 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 +171 -3
- 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/compare.d.ts +0 -25
- package/dist/types/templates/expert.d.ts +17 -21
- 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} +9 -0
- 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/{EodashMapBtns.vue.d.ts → EodashMap/EodashMapBtns.vue.d.ts} +6 -0
- package/dist/types/widgets/EodashMap/index.vue.d.ts +114 -0
- 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/async.d.ts +1 -0
- 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 +31 -28
- package/templates/baseConfig.js +10 -5
- package/templates/compare.js +2 -22
- package/templates/expert.js +19 -18
- package/templates/explore.js +62 -0
- package/templates/index.js +1 -1
- package/templates/{light.js → lite.js} +11 -2
- 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 +278 -0
- package/widgets/EodashMap/index.vue +263 -38
- package/widgets/EodashMap/methods/create-layers-config.js +9 -6
- package/widgets/EodashMap/methods/index.js +27 -13
- package/widgets/EodashProcess/ProcessList.vue +13 -1
- package/widgets/EodashProcess/index.vue +17 -1
- package/widgets/EodashProcess/methods/async.js +22 -1
- package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +25 -3
- package/widgets/EodashProcess/methods/handling.js +2 -0
- package/widgets/EodashProcess/methods/outputs.js +1 -0
- package/widgets/EodashProcess/methods/utils.js +45 -1
- package/widgets/EodashTimeSlider.vue +40 -0
- package/widgets/EodashTools.vue +7 -3
- package/widgets/ExportState.vue +53 -22
- package/dist/client/EodashLayerControl-Bhxjw4V2.js +0 -154
- package/dist/client/EodashMapBtns-WoGq8MuV.js +0 -173
- package/dist/client/MobileLayout-EKQ_kpSh.js +0 -1226
- package/dist/client/asWebComponent-By_7_JjS.js +0 -19193
- package/dist/client/forwardRefs-BXxrv98s.js +0 -272
- package/dist/client/index-BuhOHXKv.js +0 -199
- package/widgets/EodashMapBtns.vue +0 -155
|
@@ -1,45 +1,84 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
.enabled="showCompare"
|
|
5
|
-
>
|
|
6
|
-
<eox-map
|
|
2
|
+
<span>
|
|
3
|
+
<eox-map-compare
|
|
7
4
|
class="fill-height fill-width overflow-none"
|
|
8
|
-
|
|
9
|
-
ref="eoxMap"
|
|
10
|
-
id="main"
|
|
11
|
-
.animationOptions="animationOptions"
|
|
12
|
-
.center="initialCenter"
|
|
13
|
-
.zoom="initialZoom"
|
|
14
|
-
.layers="eoxMapLayers"
|
|
15
|
-
.controls="controls"
|
|
5
|
+
.enabled="showCompare"
|
|
16
6
|
>
|
|
17
|
-
<eox-map
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
7
|
+
<eox-map
|
|
8
|
+
class="fill-height fill-width overflow-none"
|
|
9
|
+
slot="first"
|
|
10
|
+
ref="eoxMap"
|
|
11
|
+
id="main"
|
|
12
|
+
.animationOptions="animationOptions"
|
|
13
|
+
.center="initialCenter"
|
|
14
|
+
.zoom="initialZoom"
|
|
15
|
+
.layers="eoxMapLayers"
|
|
16
|
+
.controls="controls"
|
|
17
|
+
>
|
|
18
|
+
<eox-map-tooltip
|
|
19
|
+
:style="mainTooltipStyles"
|
|
20
|
+
.propertyTransform="tooltipPropertyTransform('main')"
|
|
21
|
+
/>
|
|
22
|
+
</eox-map>
|
|
23
|
+
<eox-map
|
|
24
|
+
class="fill-height fill-width overflow-none"
|
|
25
|
+
id="compare"
|
|
26
|
+
slot="second"
|
|
27
|
+
ref="compareMap"
|
|
28
|
+
.layers="eoxMapCompareLayers"
|
|
29
|
+
>
|
|
30
|
+
<eox-map-tooltip
|
|
31
|
+
:style="compareTooltipStyles"
|
|
32
|
+
.propertyTransform="tooltipPropertyTransform('compare')"
|
|
33
|
+
/>
|
|
34
|
+
</eox-map>
|
|
35
|
+
</eox-map-compare>
|
|
36
|
+
<div
|
|
37
|
+
v-if="enableCursorCoordinates"
|
|
38
|
+
id="cursor-coordinates"
|
|
39
|
+
ref="cursor-coords"
|
|
40
|
+
/>
|
|
41
|
+
<span v-if="enableScaleLine" id="scale-line" ref="scale-line" />
|
|
42
|
+
<div
|
|
43
|
+
class="map-buttons-container"
|
|
44
|
+
:style="`margin: ${btnsPosition.gap}px 0 ${btnsPosition.gap}px 0`"
|
|
28
45
|
>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
46
|
+
<!-- prettier-ignore -->
|
|
47
|
+
<EodashMapBtns
|
|
48
|
+
:style="{
|
|
49
|
+
gridColumn: (indicator || compareIndicator) ? responsiveX : '12',
|
|
50
|
+
gridRow: responsiveY,
|
|
51
|
+
}"
|
|
52
|
+
:exportMap="(indicator || compareIndicator) ? btnsProps.exportMap : false"
|
|
53
|
+
:changeProjection="(indicator || compareIndicator) ? btnsProps.changeProjection : false
|
|
54
|
+
"
|
|
55
|
+
:compareIndicators="(indicator || compareIndicator) ? btnsProps.compareIndicators : false
|
|
56
|
+
"
|
|
57
|
+
:backToPOIs="(indicator || compareIndicator) ? btnsProps.backToPOIs : false
|
|
58
|
+
"
|
|
59
|
+
:enableSearch="(indicator || compareIndicator) ? btnsProps.enableSearch : false
|
|
60
|
+
"
|
|
61
|
+
:enableZoom="(indicator || compareIndicator) ? btnsProps.enableZoom : false
|
|
62
|
+
"
|
|
32
63
|
/>
|
|
33
|
-
</
|
|
34
|
-
</
|
|
64
|
+
</div>
|
|
65
|
+
</span>
|
|
35
66
|
</template>
|
|
36
67
|
<script setup>
|
|
37
68
|
import "@eox/map";
|
|
38
69
|
import "@eox/map/src/plugins/advancedLayersAndSources";
|
|
39
|
-
import { computed, onMounted, ref, toRaw } from "vue";
|
|
40
|
-
import {
|
|
70
|
+
import { computed, onMounted, ref, toRaw, useTemplateRef } from "vue";
|
|
71
|
+
import {
|
|
72
|
+
datetime,
|
|
73
|
+
mapEl,
|
|
74
|
+
mapPosition,
|
|
75
|
+
mapCompareEl,
|
|
76
|
+
indicator,
|
|
77
|
+
compareIndicator,
|
|
78
|
+
} from "@/store/states";
|
|
41
79
|
import { storeToRefs } from "pinia";
|
|
42
80
|
import { useSTAcStore } from "@/store/stac";
|
|
81
|
+
import { useDisplay } from "vuetify";
|
|
43
82
|
import {
|
|
44
83
|
eodashCollections,
|
|
45
84
|
eodashCompareCollections,
|
|
@@ -53,6 +92,7 @@ import {
|
|
|
53
92
|
} from "^/EodashMap/methods";
|
|
54
93
|
import { inAndOut } from "ol/easing.js";
|
|
55
94
|
import mustache from "mustache";
|
|
95
|
+
import EodashMapBtns from "^/EodashMap/EodashMapBtns.vue";
|
|
56
96
|
|
|
57
97
|
const props = defineProps({
|
|
58
98
|
enableCompare: {
|
|
@@ -73,18 +113,130 @@ const props = defineProps({
|
|
|
73
113
|
type: Boolean,
|
|
74
114
|
default: true,
|
|
75
115
|
},
|
|
116
|
+
enableCursorCoordinates: {
|
|
117
|
+
type: Boolean,
|
|
118
|
+
default: true,
|
|
119
|
+
},
|
|
120
|
+
enableScaleLine: {
|
|
121
|
+
type: Boolean,
|
|
122
|
+
default: true,
|
|
123
|
+
},
|
|
124
|
+
btnsPosition: {
|
|
125
|
+
type: Object,
|
|
126
|
+
default: () => ({
|
|
127
|
+
x: "12/9/10",
|
|
128
|
+
y: 1,
|
|
129
|
+
gap: 16,
|
|
130
|
+
}),
|
|
131
|
+
},
|
|
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
|
+
* }> }*/
|
|
145
|
+
type: Object,
|
|
146
|
+
default: () => ({
|
|
147
|
+
enableExportMap: true,
|
|
148
|
+
enableChangeProjection: true,
|
|
149
|
+
enableCompareIndicators: true,
|
|
150
|
+
enableBackToPOIs: true,
|
|
151
|
+
enableSearch: true,
|
|
152
|
+
enableZoom: true,
|
|
153
|
+
}),
|
|
154
|
+
},
|
|
76
155
|
});
|
|
77
156
|
|
|
157
|
+
// Responsive positioning logic
|
|
158
|
+
const { width } = useDisplay();
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Parse responsive string values (e.g., "1/5/10") into values for different screen sizes
|
|
162
|
+
* Breakpoints: [0, 960, 1920] based on properties passed to eox-layout in DashboardLayout.vue
|
|
163
|
+
* @param {string | number} value
|
|
164
|
+
* @returns {number}
|
|
165
|
+
*/
|
|
166
|
+
const parseResponsiveValue = (value) => {
|
|
167
|
+
if (typeof value === "number") {
|
|
168
|
+
return value;
|
|
169
|
+
}
|
|
170
|
+
if (typeof value === "string") {
|
|
171
|
+
const parts = value.split("/");
|
|
172
|
+
const currentWidth = width.value;
|
|
173
|
+
|
|
174
|
+
if (currentWidth < 960) {
|
|
175
|
+
return parseInt(parts[0]) || 1;
|
|
176
|
+
} else if (currentWidth < 1920) {
|
|
177
|
+
return parseInt(parts[1] || parts[0]) || 1;
|
|
178
|
+
} else {
|
|
179
|
+
return parseInt(parts[2] || parts[1] || parts[0]) || 1;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return 1;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const responsiveX = computed(() => parseResponsiveValue(props.btnsPosition.x));
|
|
186
|
+
const responsiveY = computed(() => parseResponsiveValue(props.btnsPosition.y));
|
|
187
|
+
const btnsProps = computed(() => ({
|
|
188
|
+
exportMap: props.btns.enableExportMap ?? true,
|
|
189
|
+
changeProjection: props.btns.enableChangeProjection ?? true,
|
|
190
|
+
compareIndicators: props.btns.enableCompareIndicators ?? true,
|
|
191
|
+
backToPOIs: props.btns.enableBackToPOIs ?? true,
|
|
192
|
+
enableSearch: props.btns.enableSearch ?? true,
|
|
193
|
+
enableZoom: props.btns.enableZoom ?? true,
|
|
194
|
+
}));
|
|
195
|
+
|
|
196
|
+
// Prepare containers for scale line and cursor coordinates
|
|
197
|
+
const scaleLineRef = useTemplateRef("scale-line");
|
|
198
|
+
const cursorCoordsRef = useTemplateRef("cursor-coords");
|
|
199
|
+
|
|
78
200
|
/** @type {import("vue").Ref<Exclude<import("@/types").EodashStyleJson["tooltip"], undefined>>} */
|
|
79
201
|
const tooltipProperties = ref([]);
|
|
80
202
|
/** @type {import("vue").Ref<Exclude<import("@/types").EodashStyleJson["tooltip"], undefined>>} */
|
|
81
203
|
const compareTooltipProperties = ref([]);
|
|
82
|
-
/** @type {import("
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
204
|
+
/** @type {import("vue").ComputedRef<{
|
|
205
|
+
Attribution: { collapsible: boolean };
|
|
206
|
+
ScaleLine?: { target: HTMLElement };
|
|
207
|
+
MousePosition?: { projection: string; coordinateFormat: (c: [number, number]) => string; target: HTMLElement };
|
|
208
|
+
}>} */
|
|
209
|
+
const controls = computed(() => {
|
|
210
|
+
/** @type {{
|
|
211
|
+
Attribution: { collapsible: boolean };
|
|
212
|
+
ScaleLine?: { target: HTMLElement };
|
|
213
|
+
MousePosition?: { projection: string; coordinateFormat: (c: [number, number]) => string; target: HTMLElement };
|
|
214
|
+
}} */
|
|
215
|
+
const controlsObj = {
|
|
216
|
+
Attribution: {
|
|
217
|
+
collapsible: true,
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
if (props.enableScaleLine && scaleLineRef.value) {
|
|
222
|
+
controlsObj.ScaleLine = {
|
|
223
|
+
target: scaleLineRef.value,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (props.enableCursorCoordinates && cursorCoordsRef.value) {
|
|
228
|
+
controlsObj.MousePosition = {
|
|
229
|
+
projection: "EPSG:4326",
|
|
230
|
+
coordinateFormat: (/** @type {[number, number]} */ c) => {
|
|
231
|
+
return `${c[1].toFixed(3)} °N, ${c[0].toFixed(3)} °E`;
|
|
232
|
+
},
|
|
233
|
+
target: cursorCoordsRef.value,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return controlsObj;
|
|
238
|
+
});
|
|
239
|
+
|
|
88
240
|
const initialCenter = toRaw(props.center);
|
|
89
241
|
const initialZoom = toRaw(mapPosition.value?.[2] ?? props.zoom);
|
|
90
242
|
/** @type {import("vue").Ref<Record<string,any>[]>} */
|
|
@@ -128,7 +280,8 @@ const showCompare = computed(() =>
|
|
|
128
280
|
useHandleMapMoveEnd(eoxMap, mapPosition);
|
|
129
281
|
|
|
130
282
|
onMounted(() => {
|
|
131
|
-
const { selectedCompareStac, selectedStac } =
|
|
283
|
+
const { selectedCompareStac, selectedStac, selectedItem } =
|
|
284
|
+
storeToRefs(useSTAcStore());
|
|
132
285
|
// assign map Element state to eox map
|
|
133
286
|
mapEl.value = eoxMap.value;
|
|
134
287
|
|
|
@@ -158,6 +311,7 @@ onMounted(() => {
|
|
|
158
311
|
eoxMapLayers,
|
|
159
312
|
compareMap,
|
|
160
313
|
props.zoomToExtent,
|
|
314
|
+
selectedItem,
|
|
161
315
|
);
|
|
162
316
|
});
|
|
163
317
|
|
|
@@ -210,3 +364,74 @@ const tooltipPropertyTransform = (map) => {
|
|
|
210
364
|
};
|
|
211
365
|
};
|
|
212
366
|
</script>
|
|
367
|
+
|
|
368
|
+
<style scoped>
|
|
369
|
+
#cursor-coordinates {
|
|
370
|
+
position: fixed;
|
|
371
|
+
left: 24px;
|
|
372
|
+
bottom: 54px; /* Tighter spacing: watermark at 6px + ~48px */
|
|
373
|
+
color: rgba(0, 0, 0, 0.9);
|
|
374
|
+
font-size: 11px;
|
|
375
|
+
font-family: var(--eox-body-font-family);
|
|
376
|
+
background: #fffe;
|
|
377
|
+
border-radius: 4px;
|
|
378
|
+
border: none;
|
|
379
|
+
padding: 0px 3px;
|
|
380
|
+
max-height: 24px;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
@media (max-width: 959px) {
|
|
384
|
+
#cursor-coordinates {
|
|
385
|
+
display: none; /* Hidden in mobile mode */
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
#scale-line {
|
|
390
|
+
position: fixed;
|
|
391
|
+
left: 24px;
|
|
392
|
+
bottom: 28px; /* Tighter spacing: watermark at 6px + ~22px */
|
|
393
|
+
color: #fff;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
@media (max-width: 959px) {
|
|
397
|
+
#scale-line {
|
|
398
|
+
bottom: 102px; /* Adjusted for mobile bottom nav - closer to coordinates */
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
:deep(.ol-scale-line) {
|
|
403
|
+
background: #fffe !important;
|
|
404
|
+
border-radius: 4px !important;
|
|
405
|
+
border: none !important;
|
|
406
|
+
padding: 0px 3px 3px 3px !important;
|
|
407
|
+
font-size: 10px !important;
|
|
408
|
+
font-family: var(--eox-body-font-family);
|
|
409
|
+
max-height: 20px;
|
|
410
|
+
}
|
|
411
|
+
:deep(.ol-scale-line-inner) {
|
|
412
|
+
display: flex;
|
|
413
|
+
justify-content: center;
|
|
414
|
+
border: 1px solid rgba(0, 0, 0, 0.5) !important;
|
|
415
|
+
border-top: none !important;
|
|
416
|
+
color: #333 !important;
|
|
417
|
+
font-weight: 500 !important;
|
|
418
|
+
transform: translateY(1px);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.map-buttons-container {
|
|
422
|
+
position: fixed;
|
|
423
|
+
top: 0;
|
|
424
|
+
left: 0;
|
|
425
|
+
width: 100%;
|
|
426
|
+
height: 100%;
|
|
427
|
+
display: grid;
|
|
428
|
+
grid-template-columns: repeat(12, 1fr);
|
|
429
|
+
grid-template-rows: repeat(12, 1fr);
|
|
430
|
+
pointer-events: none;
|
|
431
|
+
z-index: 1;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.map-buttons-container > * {
|
|
435
|
+
pointer-events: auto;
|
|
436
|
+
}
|
|
437
|
+
</style>
|
|
@@ -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,
|
|
@@ -17,7 +17,14 @@
|
|
|
17
17
|
<tbody>
|
|
18
18
|
<tr v-for="item in currentJobs" :key="item.jobID">
|
|
19
19
|
<td>
|
|
20
|
-
|
|
20
|
+
<a
|
|
21
|
+
class="processUrl"
|
|
22
|
+
target="_blank"
|
|
23
|
+
:href="getJobStatusUrl(item.jobID, currentIndicator)"
|
|
24
|
+
>{{
|
|
25
|
+
new Date(item.job_start_datetime).toISOString().slice(0, 16)
|
|
26
|
+
}}</a
|
|
27
|
+
>
|
|
21
28
|
</td>
|
|
22
29
|
<td>{{ item.status }}</td>
|
|
23
30
|
<td style="padding: 0px">
|
|
@@ -73,6 +80,7 @@ import {
|
|
|
73
80
|
downloadPreviousResults,
|
|
74
81
|
loadProcess,
|
|
75
82
|
updateJobsStatus,
|
|
83
|
+
getJobStatusUrl,
|
|
76
84
|
} from "./methods/async";
|
|
77
85
|
import { useOnLayersUpdate } from "@/composables";
|
|
78
86
|
import { compareJobs, jobs } from "./states";
|
|
@@ -103,4 +111,8 @@ div.v-table__wrapper {
|
|
|
103
111
|
overflow: hidden !important;
|
|
104
112
|
height: max-content !important;
|
|
105
113
|
}
|
|
114
|
+
.processUrl {
|
|
115
|
+
text-decoration: none;
|
|
116
|
+
color: var(--v-theme-primary);
|
|
117
|
+
}
|
|
106
118
|
</style>
|
|
@@ -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 {
|
|
@@ -150,7 +150,15 @@ export const downloadPreviousResults = async (jobObject, selectedStac) => {
|
|
|
150
150
|
.get(link.href)
|
|
151
151
|
.then((response) => response.data)
|
|
152
152
|
.then((data) => {
|
|
153
|
-
|
|
153
|
+
// either urls is an Array
|
|
154
|
+
if (data.urls) {
|
|
155
|
+
results.push(...data.urls);
|
|
156
|
+
} else {
|
|
157
|
+
// or urls need to be aggregated from mapping objects
|
|
158
|
+
for (const outputMappingObject of Object.values(data)) {
|
|
159
|
+
results.push(...outputMappingObject.urls);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
154
162
|
});
|
|
155
163
|
results.forEach((result) => {
|
|
156
164
|
if (!result) {
|
|
@@ -225,3 +233,16 @@ export async function loadPreviousProcess({
|
|
|
225
233
|
log.debug("rendered layers after loading previous process:", layers);
|
|
226
234
|
applyProcessLayersToMap(mapElement, layers);
|
|
227
235
|
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* extracts job status url from local storage based on identifier
|
|
239
|
+
*
|
|
240
|
+
* @param {string} jobID
|
|
241
|
+
* @param {string} indicator
|
|
242
|
+
*/
|
|
243
|
+
export const getJobStatusUrl = (jobID, indicator) => {
|
|
244
|
+
/** @type {string[]} */
|
|
245
|
+
const jobsUrls = JSON.parse(localStorage.getItem(indicator) || "[]");
|
|
246
|
+
const jobUrl = jobsUrls.find((url) => url.includes(jobID));
|
|
247
|
+
return jobUrl;
|
|
248
|
+
};
|
|
@@ -2,7 +2,11 @@ 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";
|
|
9
|
+
import { readParquetItems } from "@/eodashSTAC/parquet";
|
|
6
10
|
|
|
7
11
|
/**
|
|
8
12
|
* @param {import("^/EodashProcess/types").CustomEnpointInput} inputs
|
|
@@ -75,7 +79,25 @@ async function fetchVedaCOGsConfig(selectedStac, absoluteUrl) {
|
|
|
75
79
|
collectionLinks.map((link) =>
|
|
76
80
|
axios
|
|
77
81
|
.get(toAbsolute(link.href, absoluteUrl))
|
|
78
|
-
.then((resp) => resp.data)
|
|
82
|
+
.then((resp) => resp.data)
|
|
83
|
+
.then(async (collection) => {
|
|
84
|
+
// items in geoparquet handling specially to get item links
|
|
85
|
+
const parquetAsset = Object.values(collection.assets ?? {}).find(
|
|
86
|
+
(asset) =>
|
|
87
|
+
asset.type === "application/vnd.apache.parquet" &&
|
|
88
|
+
asset.roles?.includes("collection-mirror"),
|
|
89
|
+
);
|
|
90
|
+
if (parquetAsset) {
|
|
91
|
+
const parquetAbsoluteUrl = toAbsolute(
|
|
92
|
+
parquetAsset.href,
|
|
93
|
+
toAbsolute(link.href, absoluteUrl),
|
|
94
|
+
);
|
|
95
|
+
await readParquetItems(parquetAbsoluteUrl).then((items) => {
|
|
96
|
+
collection.links.push(...generateLinksFromItems(items));
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return collection;
|
|
100
|
+
}),
|
|
79
101
|
),
|
|
80
102
|
)),
|
|
81
103
|
);
|
|
@@ -86,7 +108,7 @@ async function fetchVedaCOGsConfig(selectedStac, absoluteUrl) {
|
|
|
86
108
|
const datetimeProperty = /** @type string **/ (
|
|
87
109
|
getDatetimeProperty(collection.links)
|
|
88
110
|
);
|
|
89
|
-
|
|
111
|
+
const itemLinks = collection.links.filter((link) => link.rel == "item");
|
|
90
112
|
configs.push(
|
|
91
113
|
...itemLinks.map((link) => ({
|
|
92
114
|
endpoint: /** @type {string} */ (link["cog_href"]),
|
|
@@ -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
|
}
|