@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,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) => {
|
|
@@ -204,6 +207,10 @@ export class EodashCollection {
|
|
|
204
207
|
timeControlValues,
|
|
205
208
|
timeControlProperty: "TIME",
|
|
206
209
|
}),
|
|
210
|
+
...(!!this.#collectionStac?.["eodash:layerExclusive"] && {
|
|
211
|
+
layerControlExclusive: true,
|
|
212
|
+
layerControlExpand: false,
|
|
213
|
+
}),
|
|
207
214
|
};
|
|
208
215
|
|
|
209
216
|
const links = await createLayersFromLinks(
|
|
@@ -224,6 +231,7 @@ export class EodashCollection {
|
|
|
224
231
|
item,
|
|
225
232
|
layerDatetime,
|
|
226
233
|
extraProperties,
|
|
234
|
+
this.#collectionStac,
|
|
227
235
|
)),
|
|
228
236
|
...((this.rasterEndpoint &&
|
|
229
237
|
(await createLayerFromRender(
|
|
@@ -279,24 +287,33 @@ export class EodashCollection {
|
|
|
279
287
|
|
|
280
288
|
/**
|
|
281
289
|
* Returns all item links sorted by datetime ascendingly
|
|
282
|
-
* @param {boolean} [fields=false] if true, fetch items from API with only properties
|
|
290
|
+
* @param {boolean} [fields=false] if true, fetch items from API with only properties.datetime to optimize performance
|
|
283
291
|
* @param {boolean} [first] - if true, returns the first page of items only (for API collections)
|
|
292
|
+
* @param {string | Date} [centerDatetime] - Date to center the search around if items exceed maxNumber
|
|
284
293
|
* @returns {Promise<import("stac-ts").StacLink[] | import("stac-ts").StacItem[] | undefined>}
|
|
285
294
|
*/
|
|
286
|
-
async getItems(fields = false, first = false) {
|
|
295
|
+
async getItems(fields = false, first = false, centerDatetime = undefined) {
|
|
287
296
|
const items = this.#collectionStac?.links.filter((i) => i.rel === "item");
|
|
288
|
-
|
|
289
|
-
if (this.isAPI && !items?.length) {
|
|
297
|
+
if (this.isAPI && !items?.length && !first) {
|
|
290
298
|
const itemUrl = this.#collectionUrl + "/items";
|
|
291
299
|
if (fields) {
|
|
292
300
|
return await fetchApiItems(
|
|
293
301
|
itemUrl,
|
|
294
|
-
`fields=properties,-assets,-geometry,-links,-bbox`,
|
|
302
|
+
`fields=properties.datetime,-assets,-geometry,-links,-bbox`,
|
|
295
303
|
100,
|
|
296
304
|
first,
|
|
305
|
+
1000,
|
|
306
|
+
centerDatetime,
|
|
297
307
|
);
|
|
298
308
|
}
|
|
299
|
-
return await fetchApiItems(
|
|
309
|
+
return await fetchApiItems(
|
|
310
|
+
itemUrl,
|
|
311
|
+
undefined,
|
|
312
|
+
100,
|
|
313
|
+
first,
|
|
314
|
+
100,
|
|
315
|
+
centerDatetime,
|
|
316
|
+
);
|
|
300
317
|
}
|
|
301
318
|
|
|
302
319
|
const datetimeProperty = getDatetimeProperty(this.#collectionStac?.links);
|
|
@@ -315,9 +332,34 @@ export class EodashCollection {
|
|
|
315
332
|
);
|
|
316
333
|
}
|
|
317
334
|
|
|
318
|
-
|
|
319
|
-
|
|
335
|
+
/**
|
|
336
|
+
* Returns all available dates for the collection, sorted as the source
|
|
337
|
+
* provides. Tries the daily `pre-aggregation` link first (cheap, single
|
|
338
|
+
* request), falls back to fetching items via the API. Use anywhere the
|
|
339
|
+
* collection's date list is needed (date picker, mosaic time control,
|
|
340
|
+
* single-item time slider).
|
|
341
|
+
*
|
|
342
|
+
* NOTE: only the `daily` aggregation interval is consumed today. Other
|
|
343
|
+
* intervals (`monthly`, `hourly`) fall through to the API path.
|
|
344
|
+
*
|
|
345
|
+
* @param {string | Date} [centerDatetime]
|
|
346
|
+
* @returns {Promise<Date[]>}
|
|
347
|
+
*/
|
|
348
|
+
async getDates(centerDatetime) {
|
|
349
|
+
await this.fetchCollection();
|
|
350
|
+
|
|
351
|
+
const aggregation = await fetchPreAggregations(
|
|
352
|
+
this.#collectionStac,
|
|
353
|
+
this.#collectionUrl,
|
|
354
|
+
);
|
|
355
|
+
const datetimeAgg = aggregation?.aggregations?.find(
|
|
356
|
+
(/** @type {any} */ a) => a.key?.startsWith("datetime_") || a.interval,
|
|
357
|
+
);
|
|
358
|
+
if (datetimeAgg?.buckets) {
|
|
359
|
+
return datetimeAgg.buckets.map((/** @type {any} */ b) => new Date(b.key));
|
|
360
|
+
}
|
|
320
361
|
|
|
362
|
+
const items = await this.getItems(true, false, centerDatetime);
|
|
321
363
|
const datetimeProperty = getDatetimeProperty(items);
|
|
322
364
|
if (!datetimeProperty || !items?.length) {
|
|
323
365
|
return [];
|
|
@@ -343,21 +385,33 @@ export class EodashCollection {
|
|
|
343
385
|
* @return {Promise<import("stac-ts").StacItem | import("stac-ts").StacLink | undefined>} item
|
|
344
386
|
**/
|
|
345
387
|
async getItem(date) {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
// in case no
|
|
388
|
+
let items = await this.getItems(false, true);
|
|
389
|
+
if (!(date instanceof Date) || isNaN(date.getTime())) {
|
|
390
|
+
// in case no date was provided, return the last item
|
|
349
391
|
return items && items.at(-1);
|
|
350
392
|
}
|
|
351
393
|
|
|
352
|
-
|
|
394
|
+
if (this.isAPI) {
|
|
395
|
+
const urlArr = this.#collectionUrl.split("/").slice(0, -2);
|
|
396
|
+
const searchURL = urlArr.join("/") + "/search";
|
|
397
|
+
const targetItem = await axios
|
|
398
|
+
.get(searchURL, {
|
|
399
|
+
params: {
|
|
400
|
+
collections: this.#collectionStac?.id,
|
|
401
|
+
datetime: `../${date.toISOString()}`,
|
|
402
|
+
limit: 1,
|
|
403
|
+
sortby: "-datetime",
|
|
404
|
+
},
|
|
405
|
+
})
|
|
406
|
+
.then((resp) => resp.data?.features?.[0]);
|
|
407
|
+
return targetItem;
|
|
408
|
+
}
|
|
353
409
|
const datetimeProperty = getDatetimeProperty(items);
|
|
354
410
|
if (!datetimeProperty) {
|
|
355
|
-
// in case no datetime property is found, return the last item
|
|
356
|
-
const items = await this.getItems(false, true);
|
|
357
411
|
// in case no datetime property is found, return the last item
|
|
358
412
|
return items && items.at(-1);
|
|
359
413
|
}
|
|
360
|
-
return
|
|
414
|
+
return items?.sort((a, b) => {
|
|
361
415
|
const distanceA = Math.abs(
|
|
362
416
|
new Date(
|
|
363
417
|
/** @type {number} */ (
|
|
@@ -404,7 +458,7 @@ export class EodashCollection {
|
|
|
404
458
|
async updateLayerJson(datetime, layerId, currentLayers) {
|
|
405
459
|
await this.fetchCollection();
|
|
406
460
|
const datetimeProperty = getDatetimeProperty(
|
|
407
|
-
await this.getItems(
|
|
461
|
+
await this.getItems(false, true),
|
|
408
462
|
);
|
|
409
463
|
if (!datetimeProperty) {
|
|
410
464
|
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
|
+
}
|