@eodash/eodash 5.7.0 → 5.8.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/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 +87 -24
- package/core/client/eodashSTAC/cql.js +64 -0
- package/core/client/eodashSTAC/createLayers.js +353 -187
- package/core/client/eodashSTAC/helpers.js +694 -110
- package/core/client/eodashSTAC/mosaic.js +422 -0
- package/core/client/plugins/axios.js +31 -1
- package/core/client/store/actions.js +1 -1
- package/core/client/store/stac.js +54 -4
- package/core/client/store/states.js +20 -2
- package/core/client/types.ts +152 -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-DEs4f_Vy.js} +2 -2
- package/dist/client/{DynamicWebComponent-CnKhYo0K.js → DynamicWebComponent-PvnV88BA.js} +1 -1
- package/dist/client/EodashChart-D-3AGKZY.js +260 -0
- package/dist/client/{EodashDatePicker-CMPDT-ce.js → EodashDatePicker-Dm_goZzs.js} +3 -3
- package/dist/client/{EodashItemFilter-BpdA8QQa.js → EodashItemFilter-CJy3zYzD.js} +2 -1
- package/dist/client/{EodashLayerControl-BHpDA4_0.js → EodashLayerControl-rL8UnpkA.js} +55 -33
- package/dist/client/{EodashLayoutSwitcher-B1fRUt7G.js → EodashLayoutSwitcher-ZRlESI9O.js} +3 -3
- package/dist/client/{EodashMapBtns-Cpned0tc.js → EodashMapBtns-CG7u2Aq8.js} +227 -112
- package/dist/client/EodashStacInfo-CJhhxthD.js +169 -0
- package/dist/client/{EodashTools-1zHz26gv.js → EodashTools-CWyK8QJT.js} +4 -4
- package/dist/client/{ExportState-DbOm8hBI.js → ExportState-BXhy5TOU.js} +20 -174
- package/dist/client/{Footer-BKg-VVkj.js → Footer-DZPvnhcT.js} +1 -1
- package/dist/client/{Header-DCrwCvmY.js → Header-CiGsDE_a.js} +2 -2
- package/dist/client/{MobileLayout-vWSHpluo.js → MobileLayout-BJHW7x5V.js} +2 -2
- package/dist/client/{PopUp-9uimfK49.js → PopUp-7_XnhvCc.js} +4 -168
- package/dist/client/{ProcessList-CTTIZa06.js → ProcessList-LL_UCbvc.js} +5 -5
- package/dist/client/VDivider-DWYM0WUr.js +168 -0
- package/dist/client/{VImg-CrmB76ZY.js → VImg-B75dgw2K.js} +2 -2
- package/dist/client/{VMain-OKZNpcEG.js → VMain-DvMmOL4f.js} +1 -1
- package/dist/client/{VTooltip-CJw2FyWk.js → VTooltip-ClWHUmWL.js} +2 -2
- package/dist/client/{WidgetsContainer-BaWOnE5R.js → WidgetsContainer-BqaWs4ch.js} +1 -1
- package/dist/client/{asWebComponent-BHWpMuE3.js → asWebComponent-IZanwL-A.js} +677 -379
- package/dist/client/{async-DSKj6g1f.js → async-CiNIOBVz.js} +31 -29
- package/dist/client/{create-layers-config-CBoYedqB.js → create-layers-config-3S3y_kZg.js} +17 -17
- package/dist/client/dialog-transition-c4ZSnzac.js +170 -0
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-DH51zPUr.js → forwardRefs-B-c1_6yo.js} +8 -87
- package/dist/client/{handling-BrcDDlgS.js → handling-NvY8Csry.js} +3 -4
- package/dist/client/{helpers-DjZVl_WF.js → helpers-BFuh19CP.js} +1094 -194
- package/dist/client/{index-1JKE68n3.js → index-1wMAyuNL.js} +219 -67
- package/dist/client/{index-CSG_JoOA.js → index-B8jGJSTA.js} +62 -56
- package/dist/client/{index-Cu3-13Xg.js → index-BKQQJkhy.js} +167 -61
- package/dist/client/index-D0jUyol8.js +3167 -0
- package/dist/client/{index-CUjl-ZsI.js → index-KGxz5Egv.js} +2 -2
- package/dist/client/mosaic-vHvSuih6.js +459 -0
- package/dist/client/templates.js +251 -121
- package/dist/client/{transition-OHcz5Qq1.js → transition-BkyUsZh_.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 +118 -19
- package/dist/types/core/client/eodashSTAC/mosaic.d.ts +56 -0
- package/dist/types/core/client/store/stac.d.ts +38 -8
- package/dist/types/core/client/store/states.d.ts +24 -2
- package/dist/types/core/client/types.d.ts +128 -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 +10 -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/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +1 -1
- 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 +34 -34
- package/templates/baseConfig.js +37 -6
- package/templates/compare.js +61 -7
- package/templates/expert.js +24 -2
- package/templates/explore.js +12 -5
- package/templates/lite.js +13 -0
- package/widgets/EodashChart.vue +162 -21
- 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 +141 -28
- package/widgets/EodashLayerControl.vue +51 -25
- package/widgets/EodashMap/EodashMapBtns.vue +109 -48
- package/widgets/EodashMap/index.vue +91 -105
- package/widgets/EodashMap/methods/btns.js +64 -31
- 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 +58 -0
- package/widgets/EodashProcess/index.vue +136 -16
- package/widgets/EodashProcess/methods/composables.js +13 -0
- package/widgets/EodashProcess/methods/outputs.js +0 -1
- package/widgets/EodashProcess/methods/utils.js +29 -27
- 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/widgets/ExportState.vue +13 -4
- package/dist/client/EodashChart-CLDqE93C.js +0 -144
- package/dist/client/EodashStacInfo-BQspAHKH.js +0 -107
- package/dist/client/index-5Jhsa8Xe.js +0 -570
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="eodash-overlay">
|
|
3
|
+
<div class="progress-bar-wrapper">
|
|
4
|
+
<v-progress-linear
|
|
5
|
+
:active="loading.value"
|
|
6
|
+
color="secondary"
|
|
7
|
+
indeterminate
|
|
8
|
+
absolute
|
|
9
|
+
></v-progress-linear>
|
|
10
|
+
</div>
|
|
3
11
|
<p>
|
|
4
12
|
<a href="https://github.com/eodash/eodash" target="_blank"
|
|
5
13
|
>eodash v{{ version }}</a
|
|
@@ -12,12 +20,18 @@
|
|
|
12
20
|
</div>
|
|
13
21
|
</template>
|
|
14
22
|
<script setup>
|
|
15
|
-
import { useTheme } from "vuetify";
|
|
23
|
+
import { useTheme, useLayout } from "vuetify";
|
|
16
24
|
import pkgJson from "../../../package.json";
|
|
25
|
+
import { loading } from "@/store/states";
|
|
26
|
+
import { computed } from "vue";
|
|
27
|
+
|
|
17
28
|
const { computedThemes } = useTheme();
|
|
29
|
+
const { mainRect } = useLayout();
|
|
18
30
|
|
|
19
31
|
const version = pkgJson.version;
|
|
20
32
|
|
|
33
|
+
const topPosition = computed(() => `${mainRect.value.top}px`);
|
|
34
|
+
|
|
21
35
|
const eoxLogo = `<svg width="100%" height="100%" viewBox="0 0 355 85" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"><g id="ink_ext_XXXXXX"><path id="path5076" d="M152.986,40.52l-0.75,-0.019l-0.737,-0.056l-0.725,-0.093l-0.713,-0.127l-0.7,-0.162l-0.7,-0.196l-0.675,-0.228l-0.65,-0.261l-0.65,-0.292l-0.625,-0.319l-0.612,-0.352l-0.588,-0.377l-0.562,-0.407l-0.55,-0.431l-0.538,-0.457l-0.5,-0.481l-0.487,-0.505l-0.45,-0.528l-0.438,-0.55l-0.4,-0.57l-0.375,-0.59l-0.35,-0.609l-0.325,-0.627l-0.287,-0.645l-0.263,-0.66l-0.225,-0.676l-0.2,-0.69l-0.162,-0.704l-0.125,-0.717l-0.1,-0.728l-0.05,-0.739l-0.025,-0.748c0,-8.023 6.512,-14.532 14.537,-14.532c8.038,0 14.538,6.509 14.538,14.532c0,8.036 -6.5,14.544 -14.538,14.544Z" style="fill:none;"/><path id="path5078" d="M165.748,-0.002c-42.009,0 -76.06,18.985 -76.06,42.402c0,13.268 10.921,25.102 28.021,32.875c-8.081,-5.487 -13.403,-12.973 -14.584,-21.859c-2.685,-20.186 16.83,-40.82 45.148,-49.615c-14.687,6.665 -24.923,21.427 -24.923,38.599c0,23.218 18.648,42.046 41.773,42.383c-0.037,0.005 -0.087,0.015 -0.137,0.02c0.263,0 0.512,0.009 0.762,0.009c42.013,0 76.076,-18.984 76.076,-42.412c0,-13.261 -10.937,-25.097 -28.037,-32.871l0.75,0.522l0.736,0.531l0.713,0.543l0.7,0.555l0.687,0.566l0.664,0.578l0.649,0.588l0.625,0.6l0.613,0.609l0.588,0.621l0.574,0.631l0.562,0.643l0.538,0.652l0.513,0.662l0.5,0.672l0.475,0.684l0.449,0.693l0.438,0.703l0.425,0.713l0.387,0.723l0.375,0.73l0.352,0.74l0.336,0.75l0.3,0.76l0.287,0.77l0.264,0.777l0.25,0.787l0.211,0.795l0.188,0.805l0.175,0.812l0.151,0.82l0.125,0.831c2.675,20.19 -16.838,40.825 -45.151,49.619c14.688,-6.665 24.926,-21.426 24.926,-38.614c0,-23.202 -18.65,-42.026 -41.775,-42.367c0.05,-0.005 0.1,-0.015 0.15,-0.025c-0.262,0 -0.526,-0.01 -0.789,-0.01Zm-13.248,11.314c7.817,0 14.25,6.433 14.25,14.25c0,0.001 0,0.001 0,0.001c0,7.817 -6.433,14.249 -14.25,14.249c-7.817,0 -14.25,-6.432 -14.25,-14.249c0,-0.001 0,-0.001 0,-0.001c0,-7.817 6.433,-14.25 14.25,-14.25Z"
|
|
22
36
|
style="fill:${computedThemes.value["dashboardTheme"].colors["on-secondary"]};fill-rule:nonzero;"/><path id="path5080" d="M213.786,9.529l0.75,0.521l0.738,0.532l0.712,0.544l0.7,0.555l0.688,0.566l0.662,0.577l0.65,0.588l0.625,0.6l0.613,0.61l0.587,0.62l0.575,0.631l0.563,0.643l0.537,0.652l0.513,0.663l0.5,0.672l0.475,0.684l0.45,0.692l0.437,0.703l0.425,0.712l0.388,0.723l0.375,0.731l0.35,0.741l0.337,0.75l0.3,0.76l0.288,0.769l0.262,0.777l0.25,0.786l0.213,0.797l0.187,0.804l0.175,0.812l0.15,0.821l0.125,0.83c2.675,20.19 -16.837,40.825 -45.15,49.619c14.688,-6.665 24.925,-21.426 24.925,-38.614c0,-23.202 -18.65,-42.025 -41.775,-42.367c0.05,-0.005 0.1,-0.015 0.15,-0.025c-0.262,0 -0.525,-0.01 -0.787,-0.01c-42.01,0 -76.062,18.985 -76.062,42.402c0,13.268 10.922,25.103 28.022,32.876c-8.081,-5.487 -13.403,-12.973 -14.584,-21.859c-2.685,-20.187 16.831,-40.82 45.149,-49.615c-14.688,6.665 -24.925,21.426 -24.925,38.598c0,23.218 18.65,42.046 41.775,42.383c-0.038,0.005 -0.088,0.015 -0.138,0.02c0.263,0 0.513,0.01 0.763,0.01c42.012,-0.001 76.075,-18.985 76.075,-42.413c0,-13.261 -10.938,-25.097 -28.038,-32.871Z" style="fill:none;"/><path id="path5082" d="M354.323,82.586l-41.999,-42.002l38.524,-38.515l-29.913,0l-23.562,23.559l-23.563,-23.559l-29.924,0l38.525,38.515l-42,42.002l29.913,0l27.049,-27.046l27.05,27.046l29.9,0"
|
|
23
37
|
style="fill:${computedThemes.value["dashboardTheme"].colors["on-secondary"]};fill-rule:nonzero;"/><path id="path5084" d="M354.323,82.586l-41.999,-42.002l38.524,-38.515l-29.913,0l-23.562,23.559l-23.563,-23.559l-29.924,0l38.525,38.515l-42,42.002l29.913,0l27.049,-27.046l27.05,27.046l29.9,0Z" style="fill:none;"/><path id="path5086" d="M0,2.069l75.033,0l0,16.489l-51.629,0l0,14.931l40.258,0l0,16.495l-40.258,0l0,16.05l53.124,0l0,16.488l-76.528,0l0,-80.453"
|
|
@@ -26,7 +40,7 @@ const base64Logo = btoa(eoxLogo);
|
|
|
26
40
|
</script>
|
|
27
41
|
<style scoped lang="scss">
|
|
28
42
|
.eodash-overlay {
|
|
29
|
-
position:
|
|
43
|
+
position: absolute;
|
|
30
44
|
top: 0;
|
|
31
45
|
left: 0;
|
|
32
46
|
width: 100%;
|
|
@@ -40,10 +54,19 @@ const base64Logo = btoa(eoxLogo);
|
|
|
40
54
|
);
|
|
41
55
|
z-index: 9999;
|
|
42
56
|
pointer-events: none;
|
|
57
|
+
|
|
58
|
+
.progress-bar-wrapper {
|
|
59
|
+
position: absolute;
|
|
60
|
+
top: v-bind("topPosition");
|
|
61
|
+
left: 0;
|
|
62
|
+
width: 100%;
|
|
63
|
+
z-index: 10000;
|
|
64
|
+
}
|
|
65
|
+
|
|
43
66
|
p {
|
|
44
67
|
position: fixed;
|
|
45
|
-
bottom:
|
|
46
|
-
left:
|
|
68
|
+
bottom: 8px;
|
|
69
|
+
left: 162px;
|
|
47
70
|
color: rgba(var(--v-theme-on-secondary), 1);
|
|
48
71
|
}
|
|
49
72
|
a {
|
|
@@ -7,7 +7,6 @@ import { inject, reactive } from "vue";
|
|
|
7
7
|
*
|
|
8
8
|
* @async
|
|
9
9
|
* @param {string | undefined| (()=> Promise<import("@/types").Eodash>) | Function} runtimeConfig
|
|
10
|
-
* @returns {Promise<import("@/types").Eodash | null | undefined>}
|
|
11
10
|
* @see {@linkplain '@/eodash.js'}
|
|
12
11
|
*/
|
|
13
12
|
export const useEodashRuntime = async (
|
|
@@ -88,7 +88,9 @@ export const useDefineWidgets = (widgetConfigs) => {
|
|
|
88
88
|
config
|
|
89
89
|
)?.defineWidget(updatedStac, updatedCompareStac);
|
|
90
90
|
if (definedConfig) {
|
|
91
|
-
definedConfig =
|
|
91
|
+
definedConfig = /** @type {import("@/types").StaticWidget} */ (
|
|
92
|
+
reactive(definedConfig)
|
|
93
|
+
);
|
|
92
94
|
}
|
|
93
95
|
definedWidget.value =
|
|
94
96
|
definedConfig && definedWidget.value.id === definedConfig.id
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
extractLayerConfig,
|
|
5
5
|
extractRoles,
|
|
6
6
|
fetchApiItems,
|
|
7
|
+
fetchPreAggregations,
|
|
7
8
|
fetchStyle,
|
|
8
9
|
fetchAllStyles,
|
|
9
10
|
findLayer,
|
|
@@ -173,11 +174,13 @@ export class EodashCollection {
|
|
|
173
174
|
// will try to extract anything it supports but for which we have
|
|
174
175
|
// less control.
|
|
175
176
|
|
|
176
|
-
const
|
|
177
|
-
await this.getItems(),
|
|
177
|
+
const itemDate =
|
|
178
178
|
item.properties?.datetime ??
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
item.properties.start_datetime ??
|
|
180
|
+
itemDatetime;
|
|
181
|
+
const { layerDatetime, timeControlValues } = extractLayerTimeValues(
|
|
182
|
+
await this.getDates(itemDate),
|
|
183
|
+
itemDate,
|
|
181
184
|
);
|
|
182
185
|
|
|
183
186
|
const dataAssets = Object.keys(item?.assets ?? {}).reduce((data, ast) => {
|
|
@@ -189,9 +192,14 @@ export class EodashCollection {
|
|
|
189
192
|
|
|
190
193
|
const isSupported =
|
|
191
194
|
item.links.some((link) =>
|
|
192
|
-
[
|
|
193
|
-
|
|
194
|
-
|
|
195
|
+
[
|
|
196
|
+
"wms",
|
|
197
|
+
"xyz",
|
|
198
|
+
"wmts",
|
|
199
|
+
"vector-tile",
|
|
200
|
+
"mapbox-style-document",
|
|
201
|
+
"tilejson",
|
|
202
|
+
].includes(link.rel),
|
|
195
203
|
) || Object.keys(dataAssets).length;
|
|
196
204
|
|
|
197
205
|
if (isSupported) {
|
|
@@ -204,6 +212,10 @@ export class EodashCollection {
|
|
|
204
212
|
timeControlValues,
|
|
205
213
|
timeControlProperty: "TIME",
|
|
206
214
|
}),
|
|
215
|
+
...(!!this.#collectionStac?.["eodash:layerExclusive"] && {
|
|
216
|
+
layerControlExclusive: true,
|
|
217
|
+
layerControlExpand: false,
|
|
218
|
+
}),
|
|
207
219
|
};
|
|
208
220
|
|
|
209
221
|
const links = await createLayersFromLinks(
|
|
@@ -224,6 +236,7 @@ export class EodashCollection {
|
|
|
224
236
|
item,
|
|
225
237
|
layerDatetime,
|
|
226
238
|
extraProperties,
|
|
239
|
+
this.#collectionStac,
|
|
227
240
|
)),
|
|
228
241
|
...((this.rasterEndpoint &&
|
|
229
242
|
(await createLayerFromRender(
|
|
@@ -279,24 +292,33 @@ export class EodashCollection {
|
|
|
279
292
|
|
|
280
293
|
/**
|
|
281
294
|
* Returns all item links sorted by datetime ascendingly
|
|
282
|
-
* @param {boolean} [fields=false] if true, fetch items from API with only properties
|
|
295
|
+
* @param {boolean} [fields=false] if true, fetch items from API with only properties.datetime to optimize performance
|
|
283
296
|
* @param {boolean} [first] - if true, returns the first page of items only (for API collections)
|
|
297
|
+
* @param {string | Date} [centerDatetime] - Date to center the search around if items exceed maxNumber
|
|
284
298
|
* @returns {Promise<import("stac-ts").StacLink[] | import("stac-ts").StacItem[] | undefined>}
|
|
285
299
|
*/
|
|
286
|
-
async getItems(fields = false, first = false) {
|
|
300
|
+
async getItems(fields = false, first = false, centerDatetime = undefined) {
|
|
287
301
|
const items = this.#collectionStac?.links.filter((i) => i.rel === "item");
|
|
288
|
-
|
|
289
|
-
if (this.isAPI && !items?.length) {
|
|
302
|
+
if (this.isAPI && !items?.length && !first) {
|
|
290
303
|
const itemUrl = this.#collectionUrl + "/items";
|
|
291
304
|
if (fields) {
|
|
292
305
|
return await fetchApiItems(
|
|
293
306
|
itemUrl,
|
|
294
|
-
`fields=properties,-assets,-geometry,-links,-bbox`,
|
|
307
|
+
`fields=properties.datetime,-assets,-geometry,-links,-bbox`,
|
|
295
308
|
100,
|
|
296
309
|
first,
|
|
310
|
+
1000,
|
|
311
|
+
centerDatetime,
|
|
297
312
|
);
|
|
298
313
|
}
|
|
299
|
-
return await fetchApiItems(
|
|
314
|
+
return await fetchApiItems(
|
|
315
|
+
itemUrl,
|
|
316
|
+
undefined,
|
|
317
|
+
100,
|
|
318
|
+
first,
|
|
319
|
+
100,
|
|
320
|
+
centerDatetime,
|
|
321
|
+
);
|
|
300
322
|
}
|
|
301
323
|
|
|
302
324
|
const datetimeProperty = getDatetimeProperty(this.#collectionStac?.links);
|
|
@@ -315,9 +337,36 @@ export class EodashCollection {
|
|
|
315
337
|
);
|
|
316
338
|
}
|
|
317
339
|
|
|
318
|
-
|
|
319
|
-
|
|
340
|
+
/**
|
|
341
|
+
* Returns all available dates for the collection, sorted as the source
|
|
342
|
+
* provides. Tries the daily `pre-aggregation` link first (cheap, single
|
|
343
|
+
* request), falls back to fetching items via the API. Use anywhere the
|
|
344
|
+
* collection's date list is needed (date picker, mosaic time control,
|
|
345
|
+
* single-item time slider).
|
|
346
|
+
*
|
|
347
|
+
* NOTE: only the `daily` aggregation interval is consumed today. Other
|
|
348
|
+
* intervals (`monthly`, `hourly`) fall through to the API path.
|
|
349
|
+
*
|
|
350
|
+
* @param {string | Date} [centerDatetime]
|
|
351
|
+
* @returns {Promise<Date[]>}
|
|
352
|
+
*/
|
|
353
|
+
async getDates(centerDatetime) {
|
|
354
|
+
await this.fetchCollection();
|
|
355
|
+
|
|
356
|
+
const aggregation = await fetchPreAggregations(
|
|
357
|
+
this.#collectionStac,
|
|
358
|
+
this.#collectionUrl,
|
|
359
|
+
);
|
|
360
|
+
const datetimeAgg = aggregation?.aggregations?.find(
|
|
361
|
+
(/** @type {any} */ a) => a.key?.startsWith("datetime_") || a.interval,
|
|
362
|
+
);
|
|
363
|
+
if (datetimeAgg?.buckets) {
|
|
364
|
+
return datetimeAgg.buckets
|
|
365
|
+
.map((/** @type {any} */ b) => new Date(b.key))
|
|
366
|
+
.filter((/** @type {Date} */ d) => !isNaN(d.getTime()));
|
|
367
|
+
}
|
|
320
368
|
|
|
369
|
+
const items = await this.getItems(true, false, centerDatetime);
|
|
321
370
|
const datetimeProperty = getDatetimeProperty(items);
|
|
322
371
|
if (!datetimeProperty || !items?.length) {
|
|
323
372
|
return [];
|
|
@@ -329,7 +378,9 @@ export class EodashCollection {
|
|
|
329
378
|
new Date(/** @type {string} */ (i.properties?.[datetimeProperty]))
|
|
330
379
|
: //@ts-expect-error todo
|
|
331
380
|
(i) => new Date(/** @type {string} */ (i[datetimeProperty]));
|
|
332
|
-
return items
|
|
381
|
+
return (items ?? [])
|
|
382
|
+
.map(mapToDates)
|
|
383
|
+
.filter((/** @type {Date} */ d) => !isNaN(d.getTime()));
|
|
333
384
|
}
|
|
334
385
|
|
|
335
386
|
async getExtent() {
|
|
@@ -343,21 +394,33 @@ export class EodashCollection {
|
|
|
343
394
|
* @return {Promise<import("stac-ts").StacItem | import("stac-ts").StacLink | undefined>} item
|
|
344
395
|
**/
|
|
345
396
|
async getItem(date) {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
// in case no
|
|
397
|
+
let items = await this.getItems(false, true);
|
|
398
|
+
if (!(date instanceof Date) || isNaN(date.getTime())) {
|
|
399
|
+
// in case no date was provided, return the last item
|
|
349
400
|
return items && items.at(-1);
|
|
350
401
|
}
|
|
351
402
|
|
|
352
|
-
|
|
403
|
+
if (this.isAPI) {
|
|
404
|
+
const urlArr = this.#collectionUrl.split("/").slice(0, -2);
|
|
405
|
+
const searchURL = urlArr.join("/") + "/search";
|
|
406
|
+
const targetItem = await axios
|
|
407
|
+
.get(searchURL, {
|
|
408
|
+
params: {
|
|
409
|
+
collections: this.#collectionStac?.id,
|
|
410
|
+
datetime: `../${date.toISOString()}`,
|
|
411
|
+
limit: 1,
|
|
412
|
+
sortby: "-datetime",
|
|
413
|
+
},
|
|
414
|
+
})
|
|
415
|
+
.then((resp) => resp.data?.features?.[0]);
|
|
416
|
+
return targetItem;
|
|
417
|
+
}
|
|
353
418
|
const datetimeProperty = getDatetimeProperty(items);
|
|
354
419
|
if (!datetimeProperty) {
|
|
355
|
-
// in case no datetime property is found, return the last item
|
|
356
|
-
const items = await this.getItems(false, true);
|
|
357
420
|
// in case no datetime property is found, return the last item
|
|
358
421
|
return items && items.at(-1);
|
|
359
422
|
}
|
|
360
|
-
return
|
|
423
|
+
return items?.sort((a, b) => {
|
|
361
424
|
const distanceA = Math.abs(
|
|
362
425
|
new Date(
|
|
363
426
|
/** @type {number} */ (
|
|
@@ -404,7 +467,7 @@ export class EodashCollection {
|
|
|
404
467
|
async updateLayerJson(datetime, layerId, currentLayers) {
|
|
405
468
|
await this.fetchCollection();
|
|
406
469
|
const datetimeProperty = getDatetimeProperty(
|
|
407
|
-
await this.getItems(
|
|
470
|
+
await this.getItems(false, true),
|
|
408
471
|
);
|
|
409
472
|
if (!datetimeProperty) {
|
|
410
473
|
console.warn("[eodash] no datetime property found in collection");
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keys that are catalog based and have dedicated parameters
|
|
3
|
+
* sent to a remote API (e.g. TiTiler, eoAPI STAC search).
|
|
4
|
+
* @type {string[]}
|
|
5
|
+
*/
|
|
6
|
+
const SKIP_KEYS = ["collection", "datetime", "bbox"];
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Strips the "properties." prefix that eox-itemfilter catalog configs add to
|
|
10
|
+
* item property keys (e.g. "properties.eo:cloud_cover" -> "eo:cloud_cover").
|
|
11
|
+
* Keys without the prefix are returned unchanged.
|
|
12
|
+
* @param {string} key
|
|
13
|
+
* @returns {string}
|
|
14
|
+
*/
|
|
15
|
+
function normalizeFilterKey(key) {
|
|
16
|
+
return key.startsWith("properties.") ? key.slice("properties.".length) : key;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Builds a CQL2-text filter string from an eox-itemfilter filters record.
|
|
21
|
+
*
|
|
22
|
+
* Handles range, multiselect, and select filter types.
|
|
23
|
+
* - Strips "properties." prefix from keys (catalog eox-itemfilter convention).
|
|
24
|
+
* - Double-quotes property names that contain non-word characters (e.g. "eo:cloud_cover").
|
|
25
|
+
* - Skips catalog-only keys (e.g. "collection").
|
|
26
|
+
*
|
|
27
|
+
* Compatible with both TiTiler's `filter` param and the STAC API `filter` param
|
|
28
|
+
* (both accept CQL2-text).
|
|
29
|
+
*
|
|
30
|
+
* @param {import("@/types").ItemFilterFilters | null | undefined} filters
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
export function buildCqlFilter(filters) {
|
|
34
|
+
if (!filters) return "";
|
|
35
|
+
|
|
36
|
+
/** @type {string[]} */
|
|
37
|
+
const parts = [];
|
|
38
|
+
|
|
39
|
+
for (const filter of Object.values(filters)) {
|
|
40
|
+
if (!filter?.key || SKIP_KEYS.includes(filter.key)) continue;
|
|
41
|
+
|
|
42
|
+
const key = normalizeFilterKey(filter.key);
|
|
43
|
+
const prop = /\W/.test(key) ? `"${key}"` : key;
|
|
44
|
+
|
|
45
|
+
if (filter.type === "range" && filter.state) {
|
|
46
|
+
const { min, max } = filter.state;
|
|
47
|
+
if (min != null && min > (filter.min ?? -Infinity)) {
|
|
48
|
+
parts.push(`${prop} >= ${min}`);
|
|
49
|
+
}
|
|
50
|
+
if (max != null && max < (filter.max ?? Infinity)) {
|
|
51
|
+
parts.push(`${prop} <= ${max}`);
|
|
52
|
+
}
|
|
53
|
+
} else if (
|
|
54
|
+
filter.type === "multiselect" &&
|
|
55
|
+
filter.stringifiedState?.length
|
|
56
|
+
) {
|
|
57
|
+
parts.push(`${prop} IN (${filter.stringifiedState})`);
|
|
58
|
+
} else if (filter.type === "select" && filter.stringifiedState) {
|
|
59
|
+
parts.push(`${prop} = '${filter.stringifiedState}'`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return parts.join(" AND ");
|
|
64
|
+
}
|