@eodash/eodash 5.0.0 → 5.2.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/README.md +1 -0
- package/core/client/App.vue +8 -2
- package/core/client/asWebComponent.js +5 -5
- package/core/client/components/DashboardLayout.vue +43 -26
- package/core/client/components/EodashOverlay.vue +5 -6
- package/core/client/components/ErrorAlert.vue +2 -2
- package/core/client/components/Footer.vue +4 -4
- package/core/client/components/Header.vue +3 -3
- package/core/client/components/MobileLayout.vue +47 -27
- package/core/client/composables/DefineEodash.js +38 -43
- package/core/client/composables/DefineTemplate.js +4 -2
- package/core/client/composables/DefineWidgets.js +14 -8
- package/core/client/composables/index.js +273 -23
- package/core/client/eodashSTAC/EodashCollection.js +84 -62
- package/core/client/eodashSTAC/createLayers.js +30 -0
- package/core/client/eodashSTAC/helpers.js +159 -28
- package/core/client/eodashSTAC/parquet.js +145 -0
- package/core/client/eodashSTAC/triggers.js +6 -3
- package/core/client/plugins/index.js +4 -3
- package/core/client/plugins/vuetify.js +3 -0
- package/core/client/store/actions.js +21 -4
- package/core/client/store/stac.js +93 -56
- package/core/client/store/states.js +15 -5
- package/core/client/types.ts +59 -43
- package/core/client/utils/index.js +79 -0
- package/core/client/utils/keys.js +2 -2
- package/core/client/utils/states.js +30 -5
- package/core/client/views/Dashboard.vue +36 -32
- package/core/client/vite-env.d.ts +7 -0
- package/dist/client/{DashboardLayout-CkWvOMOW.js → DashboardLayout-Dq9Kfe6O.js} +24 -13
- package/dist/client/{DynamicWebComponent-DYBbpvUK.js → DynamicWebComponent-DCBMXskE.js} +1 -1
- package/dist/client/{EodashDatePicker-CALmW3SI.js → EodashDatePicker-DtngxU6s.js} +59 -32
- package/dist/client/{EodashItemFilter-DlQiE713.js → EodashItemFilter-ClQebJQt.js} +20 -10
- package/dist/client/{EodashLayerControl-DEzEbft7.js → EodashLayerControl-BLBds28C.js} +29 -16
- package/dist/client/EodashLayoutSwitcher-DQ8SfVDd.js +61 -0
- package/dist/client/EodashMapBtns-B89_YBDw.js +326 -0
- package/dist/client/{EodashStacInfo-DPPxDkF6.js → EodashStacInfo-Dt1nF06x.js} +3 -18
- package/dist/client/{EodashTools-CUaL9s4H.js → EodashTools-DV5ykmWc.js} +13 -13
- package/dist/client/{ExportState-DjyIZVhl.js → ExportState-B6zZQUmE.js} +57 -52
- package/dist/client/{Footer-DyL0JoWt.js → Footer-DNhXs8k6.js} +15 -13
- package/dist/client/{Header-B5Dgty9l.js → Header-BjhN5JY4.js} +32 -28
- package/dist/client/MobileLayout-JelB6w1G.js +118 -0
- package/dist/client/{PopUp-BfB8s_ki.js → PopUp-CgpvNr3o.js} +18 -10
- package/dist/client/ProcessList-vecpxThi.js +198 -0
- package/dist/client/{VImg-FD1WVphJ.js → VImg-CETuikH2.js} +221 -26
- package/dist/client/{VMain-DJKG4SvM.js → VMain-Ci9DyaGU.js} +7 -7
- package/dist/client/{VTooltip-CfeefrXI.js → VTooltip-J4ac48X7.js} +12 -10
- package/dist/client/{WidgetsContainer-C2TaTdb6.js → WidgetsContainer-CCML4TyV.js} +1 -1
- package/dist/client/asWebComponent-ZyEzWOOf.js +19092 -0
- package/dist/client/async-B7jIrM53.js +804 -0
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{VOverlay-BzOdRu9h.js → forwardRefs-BQclvjMq.js} +332 -28
- package/dist/client/handling-BS24aG1q.js +1227 -0
- package/dist/client/helpers-wXK7Ywio.js +4556 -0
- package/dist/client/index-4UCzZi8B.js +376 -0
- package/dist/client/{index-4CT7Tz83.js → index-9KR-G20t.js} +2 -2
- package/dist/client/{index-CIHH_3dW.js → index-B2XpdgR6.js} +227 -86
- 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/{ssrBoot-BP7SYRyC.js → ssrBoot-Zgc_Ttvi.js} +2 -2
- package/dist/client/templates.js +840 -0
- package/dist/client/transition-yBii4fu6.js +40 -0
- package/dist/node/cli.js +16 -6
- package/dist/node/types.d.ts +1 -1
- package/dist/types/core/client/App.vue.d.ts +2 -2
- package/dist/types/core/client/asWebComponent.d.ts +1 -1
- package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +1 -3
- package/dist/types/core/client/components/Footer.vue.d.ts +1 -105
- package/dist/types/core/client/components/IframeWrapper.vue.d.ts +1 -1
- package/dist/types/core/client/components/MobileLayout.vue.d.ts +1 -324
- package/dist/types/core/client/composables/DefineEodash.d.ts +2 -2
- package/dist/types/core/client/composables/DefineTemplate.d.ts +1 -1
- package/dist/types/core/client/composables/DefineWidgets.d.ts +4 -4
- package/dist/types/core/client/composables/index.d.ts +24 -2
- package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +9 -6
- package/dist/types/core/client/eodashSTAC/helpers.d.ts +25 -5
- package/dist/types/core/client/eodashSTAC/parquet.d.ts +2 -0
- package/dist/types/core/client/plugins/vuetify.d.ts +7 -4
- package/dist/types/core/client/store/actions.d.ts +3 -2
- package/dist/types/core/client/store/stac.d.ts +16 -13
- package/dist/types/core/client/store/states.d.ts +14 -4
- package/dist/types/core/client/types.d.ts +46 -31
- package/dist/types/core/client/utils/index.d.ts +2 -0
- package/dist/types/core/client/utils/keys.d.ts +4 -4
- package/dist/types/core/client/utils/states.d.ts +59 -47
- package/dist/types/core/client/views/Dashboard.vue.d.ts +2 -2
- package/dist/types/templates/baseConfig.d.ts +4 -0
- package/dist/types/templates/compare.d.ts +185 -0
- package/dist/types/templates/expert.d.ts +147 -0
- package/dist/types/templates/index.d.ts +6 -0
- package/dist/types/templates/light.d.ts +154 -0
- package/dist/types/widgets/EodashDatePicker.vue.d.ts +1 -458
- package/dist/types/widgets/EodashItemFilter.vue.d.ts +3 -3
- package/dist/types/widgets/EodashLayerControl.vue.d.ts +14 -7
- package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +1 -3
- package/dist/types/widgets/{EodashMapBtns.vue.d.ts → EodashMap/EodashMapBtns.vue.d.ts} +12 -8
- package/dist/types/widgets/EodashMap/index.vue.d.ts +9 -4
- package/dist/types/widgets/EodashProcess/ProcessList.vue.d.ts +8 -1
- package/dist/types/widgets/EodashProcess/index.vue.d.ts +8 -4
- package/dist/types/widgets/EodashProcess/methods/async.d.ts +19 -18
- package/dist/types/widgets/EodashProcess/methods/composables.d.ts +3 -2
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/index.d.ts +1 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.d.ts +6 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.d.ts +4 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +5 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/index.d.ts +1 -0
- package/dist/types/widgets/EodashProcess/methods/handling.d.ts +12 -5
- package/dist/types/widgets/EodashProcess/methods/outputs.d.ts +72 -41
- package/dist/types/widgets/EodashProcess/methods/utils.d.ts +41 -21
- package/dist/types/widgets/EodashProcess/states.d.ts +11 -0
- package/dist/types/widgets/EodashProcess/types.d.ts +41 -0
- package/dist/types/widgets/EodashStacInfo.vue.d.ts +14 -14
- package/dist/types/widgets/EodashTools.vue.d.ts +3 -3
- package/dist/types/widgets/ExportState.vue.d.ts +1 -1
- package/dist/types/widgets/PopUp.vue.d.ts +11 -16
- package/dist/types/widgets/WidgetsContainer.vue.d.ts +3 -6
- package/package.json +55 -45
- package/templates/baseConfig.js +68 -0
- package/templates/compare.js +142 -0
- package/templates/expert.js +124 -0
- package/templates/index.js +8 -0
- package/templates/light.js +139 -0
- package/widgets/EodashDatePicker.vue +80 -31
- package/widgets/EodashItemFilter.vue +26 -11
- package/widgets/EodashLayerControl.vue +20 -11
- package/widgets/EodashLayoutSwitcher.vue +6 -3
- package/widgets/EodashMap/EodashMapBtns.vue +269 -0
- package/widgets/EodashMap/index.vue +255 -45
- package/widgets/EodashMap/methods/create-layers-config.js +4 -3
- package/widgets/EodashMap/methods/index.js +33 -23
- package/widgets/EodashProcess/ProcessList.vue +47 -11
- package/widgets/EodashProcess/index.vue +55 -20
- package/widgets/EodashProcess/methods/async.js +99 -60
- package/widgets/EodashProcess/methods/composables.js +21 -14
- package/widgets/EodashProcess/methods/custom-endpoints/chart/index.js +35 -0
- package/widgets/EodashProcess/methods/custom-endpoints/chart/sentinelhub-endpoint.js +275 -0
- package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +132 -0
- package/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.js +94 -0
- package/widgets/EodashProcess/methods/custom-endpoints/layers/index.js +33 -0
- package/widgets/EodashProcess/methods/handling.js +127 -80
- package/widgets/EodashProcess/methods/outputs.js +376 -125
- package/widgets/EodashProcess/methods/utils.js +442 -10
- package/widgets/EodashProcess/states.js +13 -0
- package/widgets/EodashProcess/types.ts +46 -0
- package/widgets/EodashStacInfo.vue +2 -17
- package/widgets/EodashTools.vue +13 -13
- package/widgets/WidgetsContainer.vue +1 -1
- package/core/client/eodash.js +0 -454
- package/dist/client/EodashLayoutSwitcher-CDeCV8F-.js +0 -52
- package/dist/client/EodashMapBtns-CktQCfa-.js +0 -131
- package/dist/client/MobileLayout-CRsg_5Q4.js +0 -1217
- package/dist/client/ProcessList-DTefwQZx.js +0 -484
- package/dist/client/asWebComponent-CLhcT715.js +0 -12479
- package/dist/client/eo-dash.css +0 -5
- package/dist/client/forwardRefs-Bon_Kku1.js +0 -245
- package/dist/client/index-Bm9cbtx5.js +0 -201
- package/dist/client/index-DiGDvTQU.js +0 -780
- package/dist/client/transition-C5I57hn6.js +0 -37
- package/dist/types/core/client/eodash.d.ts +0 -8
- package/widgets/EodashMapBtns.vue +0 -113
|
@@ -7,7 +7,9 @@ import {
|
|
|
7
7
|
fetchStyle,
|
|
8
8
|
findLayer,
|
|
9
9
|
generateFeatures,
|
|
10
|
+
getDatetimeProperty,
|
|
10
11
|
replaceLayer,
|
|
12
|
+
extractLayerLegend,
|
|
11
13
|
} from "./helpers";
|
|
12
14
|
import {
|
|
13
15
|
getLayers,
|
|
@@ -57,10 +59,10 @@ export class EodashCollection {
|
|
|
57
59
|
/**
|
|
58
60
|
* @type {import("stac-ts").StacLink | undefined}
|
|
59
61
|
**/
|
|
60
|
-
let
|
|
62
|
+
let itemLink;
|
|
61
63
|
|
|
62
64
|
/**
|
|
63
|
-
* @type {import("stac-ts").StacCollection | undefined}
|
|
65
|
+
* @type {import("stac-ts").StacCollection | import("stac-ts").StacItem | undefined}
|
|
64
66
|
**/
|
|
65
67
|
let stac;
|
|
66
68
|
// TODO get auxiliary layers from collection
|
|
@@ -70,22 +72,26 @@ export class EodashCollection {
|
|
|
70
72
|
// Load collectionstac if not yet initialized
|
|
71
73
|
stac = await this.fetchCollection();
|
|
72
74
|
|
|
73
|
-
const
|
|
75
|
+
const isObservationPoint = stac?.endpointtype === "GeoDB";
|
|
74
76
|
|
|
75
77
|
if (linkOrDate instanceof Date) {
|
|
76
78
|
// if collectionStac not yet initialized we do it here
|
|
77
|
-
|
|
79
|
+
itemLink = this.getItem(linkOrDate);
|
|
78
80
|
} else {
|
|
79
|
-
|
|
81
|
+
itemLink = linkOrDate;
|
|
82
|
+
}
|
|
83
|
+
let stacItemUrl = "";
|
|
84
|
+
if (itemLink?.href.startsWith("blob:")) {
|
|
85
|
+
stacItemUrl = itemLink.href;
|
|
86
|
+
} else {
|
|
87
|
+
stacItemUrl = itemLink
|
|
88
|
+
? toAbsolute(itemLink.href, this.#collectionUrl)
|
|
89
|
+
: this.#collectionUrl;
|
|
80
90
|
}
|
|
81
|
-
|
|
82
|
-
const stacItemUrl = stacItem
|
|
83
|
-
? toAbsolute(stacItem.href, this.#collectionUrl)
|
|
84
|
-
: this.#collectionUrl;
|
|
85
91
|
|
|
86
92
|
stac = await axios.get(stacItemUrl).then((resp) => resp.data);
|
|
87
93
|
|
|
88
|
-
if (!
|
|
94
|
+
if (!itemLink) {
|
|
89
95
|
// no specific item was requested; render last item
|
|
90
96
|
this.#collectionStac = new Collection(stac);
|
|
91
97
|
this.selectedItem = this.getItem();
|
|
@@ -105,7 +111,12 @@ export class EodashCollection {
|
|
|
105
111
|
const title =
|
|
106
112
|
this.#collectionStac?.title || this.#collectionStac?.id || "";
|
|
107
113
|
layersJson.unshift(
|
|
108
|
-
...(await this.buildJsonArray(
|
|
114
|
+
...(await this.buildJsonArray(
|
|
115
|
+
item,
|
|
116
|
+
stacItemUrl,
|
|
117
|
+
title,
|
|
118
|
+
isObservationPoint,
|
|
119
|
+
)),
|
|
109
120
|
);
|
|
110
121
|
return layersJson;
|
|
111
122
|
}
|
|
@@ -115,20 +126,19 @@ export class EodashCollection {
|
|
|
115
126
|
* @param {import("stac-ts").StacItem} item
|
|
116
127
|
* @param {string} itemUrl
|
|
117
128
|
* @param {string} title
|
|
118
|
-
* @param {boolean}
|
|
129
|
+
* @param {boolean} isObservationPoint
|
|
119
130
|
* @param {string} [itemDatetime]
|
|
120
131
|
* @returns {Promise<Record<string,any>[]>} layers
|
|
121
132
|
* */
|
|
122
|
-
async buildJsonArray(item, itemUrl, title,
|
|
133
|
+
async buildJsonArray(item, itemUrl, title, isObservationPoint, itemDatetime) {
|
|
123
134
|
log.debug(
|
|
124
135
|
"Building JSON array",
|
|
125
136
|
item,
|
|
126
137
|
itemUrl,
|
|
127
138
|
title,
|
|
128
|
-
|
|
139
|
+
isObservationPoint,
|
|
129
140
|
itemDatetime,
|
|
130
141
|
);
|
|
131
|
-
await this.fetchCollection();
|
|
132
142
|
// registering top level indicator projection
|
|
133
143
|
const indicatorProjection =
|
|
134
144
|
item?.["proj:epsg"] || item?.["eodash:proj4_def"];
|
|
@@ -140,8 +150,8 @@ export class EodashCollection {
|
|
|
140
150
|
|
|
141
151
|
const jsonArray = [];
|
|
142
152
|
|
|
143
|
-
if (
|
|
144
|
-
// handled by
|
|
153
|
+
if (isObservationPoint) {
|
|
154
|
+
// handled by getObservationPointsLayer
|
|
145
155
|
return [];
|
|
146
156
|
}
|
|
147
157
|
|
|
@@ -158,7 +168,9 @@ export class EodashCollection {
|
|
|
158
168
|
|
|
159
169
|
const layerDatetime = extractLayerDatetime(
|
|
160
170
|
this.getItems(),
|
|
161
|
-
item.properties?.datetime ??
|
|
171
|
+
item.properties?.datetime ??
|
|
172
|
+
item.properties.start_datetime ??
|
|
173
|
+
itemDatetime,
|
|
162
174
|
);
|
|
163
175
|
|
|
164
176
|
const dataAssets = Object.keys(item?.assets ?? {}).reduce((data, ast) => {
|
|
@@ -173,24 +185,12 @@ export class EodashCollection {
|
|
|
173
185
|
|
|
174
186
|
if (isSupported) {
|
|
175
187
|
// Checking for potential legend asset
|
|
176
|
-
let extraProperties =
|
|
177
|
-
if (this.#collectionStac?.assets?.legend?.href) {
|
|
178
|
-
extraProperties = {
|
|
179
|
-
description: `<div style="width: 100%">
|
|
180
|
-
<img src="${this.#collectionStac.assets.legend.href}" style="max-height:70px; margin-top:-15px; margin-bottom:-20px;" />
|
|
181
|
-
</div>`,
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
// Check if collection has eox:colorlegend definition, if yes overwrite legend description
|
|
185
|
-
if (this.#collectionStac && this.#collectionStac["eox:colorlegend"]) {
|
|
186
|
-
extraProperties = {
|
|
187
|
-
layerLegend: this.#collectionStac["eox:colorlegend"],
|
|
188
|
-
};
|
|
189
|
-
}
|
|
188
|
+
let extraProperties = extractLayerLegend(this.#collectionStac);
|
|
190
189
|
extraProperties = {
|
|
191
190
|
...extraProperties,
|
|
192
191
|
...(this.color && { color: this.color }),
|
|
193
192
|
};
|
|
193
|
+
|
|
194
194
|
const links = await createLayersFromLinks(
|
|
195
195
|
this.#collectionStac?.id ?? "",
|
|
196
196
|
title,
|
|
@@ -198,8 +198,8 @@ export class EodashCollection {
|
|
|
198
198
|
layerDatetime,
|
|
199
199
|
extraProperties,
|
|
200
200
|
);
|
|
201
|
+
|
|
201
202
|
jsonArray.push(
|
|
202
|
-
...links,
|
|
203
203
|
...(await createLayersFromAssets(
|
|
204
204
|
this.#collectionStac?.id ?? "",
|
|
205
205
|
title || this.#collectionStac?.title || item.id,
|
|
@@ -210,6 +210,8 @@ export class EodashCollection {
|
|
|
210
210
|
layerDatetime,
|
|
211
211
|
extraProperties,
|
|
212
212
|
)),
|
|
213
|
+
...links,
|
|
214
|
+
// We add the links after the assets so they are layered underneath assets
|
|
213
215
|
);
|
|
214
216
|
} else {
|
|
215
217
|
// fallback to STAC
|
|
@@ -247,14 +249,21 @@ export class EodashCollection {
|
|
|
247
249
|
return this.#collectionStac;
|
|
248
250
|
}
|
|
249
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Returns all item links sorted by datetime ascendingly
|
|
254
|
+
*/
|
|
250
255
|
getItems() {
|
|
256
|
+
const datetimeProperty = getDatetimeProperty(this.#collectionStac?.links);
|
|
257
|
+
const items = this.#collectionStac?.links.filter((i) => i.rel === "item");
|
|
258
|
+
if (!datetimeProperty) {
|
|
259
|
+
return items;
|
|
260
|
+
}
|
|
251
261
|
return (
|
|
252
|
-
|
|
253
|
-
.filter((i) => i.rel === "item")
|
|
262
|
+
items
|
|
254
263
|
// sort by `datetime`, where oldest is first in array
|
|
255
|
-
|
|
256
|
-
/** @type {number} */ (a
|
|
257
|
-
/** @type {number} */ (b
|
|
264
|
+
?.sort((a, b) =>
|
|
265
|
+
/** @type {number} */ (a[datetimeProperty]) <
|
|
266
|
+
/** @type {number} */ (b[datetimeProperty])
|
|
258
267
|
? -1
|
|
259
268
|
: 1,
|
|
260
269
|
)
|
|
@@ -262,22 +271,16 @@ export class EodashCollection {
|
|
|
262
271
|
}
|
|
263
272
|
|
|
264
273
|
getDates() {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
/** @type {number} */ (b.datetime)
|
|
272
|
-
? -1
|
|
273
|
-
: 1,
|
|
274
|
-
)
|
|
275
|
-
.map((i) => new Date(/** @type {number} */ (i.datetime)))
|
|
274
|
+
const datetimeProperty = getDatetimeProperty(this.#collectionStac?.links);
|
|
275
|
+
if (!datetimeProperty) {
|
|
276
|
+
return [];
|
|
277
|
+
}
|
|
278
|
+
return this.getItems()?.map(
|
|
279
|
+
(i) => new Date(/** @type {number} */ (i[datetimeProperty])),
|
|
276
280
|
);
|
|
277
281
|
}
|
|
278
282
|
|
|
279
283
|
async getExtent() {
|
|
280
|
-
await this.fetchCollection();
|
|
281
284
|
return this.#collectionStac?.extent;
|
|
282
285
|
}
|
|
283
286
|
|
|
@@ -287,14 +290,19 @@ export class EodashCollection {
|
|
|
287
290
|
* @param {Date} [date]
|
|
288
291
|
**/
|
|
289
292
|
getItem(date) {
|
|
293
|
+
const datetimeProperty = getDatetimeProperty(this.#collectionStac?.links);
|
|
294
|
+
if (!datetimeProperty) {
|
|
295
|
+
// in case no datetime property is found, return the first item
|
|
296
|
+
return this.getItems()?.[0];
|
|
297
|
+
}
|
|
290
298
|
return date
|
|
291
299
|
? this.getItems()?.sort((a, b) => {
|
|
292
300
|
const distanceA = Math.abs(
|
|
293
|
-
new Date(/** @type {number} */ (a
|
|
301
|
+
new Date(/** @type {number} */ (a[datetimeProperty])).getTime() -
|
|
294
302
|
date.getTime(),
|
|
295
303
|
);
|
|
296
304
|
const distanceB = Math.abs(
|
|
297
|
-
new Date(/** @type {number} */ (b
|
|
305
|
+
new Date(/** @type {number} */ (b[datetimeProperty])).getTime() -
|
|
298
306
|
date.getTime(),
|
|
299
307
|
);
|
|
300
308
|
return distanceA - distanceB;
|
|
@@ -323,12 +331,16 @@ export class EodashCollection {
|
|
|
323
331
|
*/
|
|
324
332
|
async updateLayerJson(datetime, layer, map) {
|
|
325
333
|
await this.fetchCollection();
|
|
326
|
-
|
|
334
|
+
const datetimeProperty = getDatetimeProperty(this.#collectionStac?.links);
|
|
335
|
+
if (!datetimeProperty) {
|
|
336
|
+
console.warn("[eodash] no datetime property found in collection");
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
327
339
|
// get the link of the specified date
|
|
328
340
|
const specifiedLink = this.getItems()?.find(
|
|
329
341
|
(item) =>
|
|
330
|
-
typeof item
|
|
331
|
-
new Date(item
|
|
342
|
+
typeof item[datetimeProperty] === "string" &&
|
|
343
|
+
new Date(item[datetimeProperty]).toISOString() === datetime,
|
|
332
344
|
);
|
|
333
345
|
|
|
334
346
|
if (!specifiedLink) {
|
|
@@ -348,12 +360,13 @@ export class EodashCollection {
|
|
|
348
360
|
}
|
|
349
361
|
|
|
350
362
|
/** @type {string | undefined} */
|
|
351
|
-
const oldLayerID = findLayer(currentLayers, layer)?.properties
|
|
363
|
+
const oldLayerID = findLayer(currentLayers, layer)?.properties?.id;
|
|
352
364
|
|
|
353
365
|
if (!oldLayerID) {
|
|
354
366
|
return;
|
|
355
367
|
}
|
|
356
368
|
|
|
369
|
+
//@ts-expect-error TODO
|
|
357
370
|
const updatedLayers = replaceLayer(currentLayers, oldLayerID, newLayers);
|
|
358
371
|
|
|
359
372
|
return updatedLayers;
|
|
@@ -395,16 +408,18 @@ export class EodashCollection {
|
|
|
395
408
|
}
|
|
396
409
|
|
|
397
410
|
/**
|
|
398
|
-
* Returns
|
|
411
|
+
* Returns Observation points layer from a list of EodashCollections
|
|
399
412
|
*
|
|
400
413
|
* @param {EodashCollection[]} eodashCollections
|
|
401
414
|
*
|
|
402
415
|
**/
|
|
403
|
-
static
|
|
416
|
+
static getObservationPointsLayer(eodashCollections) {
|
|
404
417
|
const allFeatures = [];
|
|
405
418
|
for (const collection of eodashCollections) {
|
|
406
|
-
const
|
|
407
|
-
|
|
419
|
+
const isObservationPoint =
|
|
420
|
+
collection.#collectionStac?.endpointtype === "GeoDB" ||
|
|
421
|
+
/**@type {boolean} */ (collection.#collectionStac?.locations);
|
|
422
|
+
if (!isObservationPoint) {
|
|
408
423
|
continue;
|
|
409
424
|
}
|
|
410
425
|
const collectionFeatures = generateFeatures(
|
|
@@ -414,6 +429,7 @@ export class EodashCollection {
|
|
|
414
429
|
geoDBID: collection.#collectionStac?.geoDBID,
|
|
415
430
|
themes: collection.#collectionStac?.themes ?? [],
|
|
416
431
|
},
|
|
432
|
+
collection.#collectionStac?.locations ? "child" : "item",
|
|
417
433
|
).features;
|
|
418
434
|
|
|
419
435
|
if (collectionFeatures.length) {
|
|
@@ -475,13 +491,19 @@ export class EodashCollection {
|
|
|
475
491
|
"circle-radius": 10,
|
|
476
492
|
"circle-fill-color": "#00417077",
|
|
477
493
|
"circle-stroke-color": "#004170",
|
|
478
|
-
"fill-color": "#
|
|
494
|
+
"fill-color": "#00417077",
|
|
479
495
|
"stroke-color": "#004170",
|
|
480
496
|
},
|
|
481
497
|
},
|
|
482
498
|
];
|
|
483
499
|
})(),
|
|
484
|
-
interactions:
|
|
500
|
+
interactions: (() => {
|
|
501
|
+
const oldLayer = findLayer([...getLayers()], "geodb-collection");
|
|
502
|
+
if (!oldLayer || !oldLayer.interactions?.length) {
|
|
503
|
+
return [];
|
|
504
|
+
}
|
|
505
|
+
return [...oldLayer.interactions];
|
|
506
|
+
})(),
|
|
485
507
|
};
|
|
486
508
|
}
|
|
487
509
|
}
|
|
@@ -95,6 +95,36 @@ export async function createLayersFromAssets(
|
|
|
95
95
|
url: assets[ast].href,
|
|
96
96
|
attributions: assets[ast].attribution,
|
|
97
97
|
});
|
|
98
|
+
} else if (assets[ast]?.type === "application/geodb+json") {
|
|
99
|
+
const responseData = await (await fetch(assets[ast].href)).json();
|
|
100
|
+
if (
|
|
101
|
+
!responseData ||
|
|
102
|
+
!Array.isArray(responseData) ||
|
|
103
|
+
responseData.length === 0
|
|
104
|
+
) {
|
|
105
|
+
console.error(
|
|
106
|
+
"[eodash] GeoDB response data is not in expected format",
|
|
107
|
+
responseData,
|
|
108
|
+
);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const features = responseData.map((item) => {
|
|
112
|
+
return {
|
|
113
|
+
type: "Feature",
|
|
114
|
+
geometry: item.geometry,
|
|
115
|
+
// we pass the item making sure to remove geometry to avoid duplication
|
|
116
|
+
properties: { ...item, geometry: undefined },
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
const geojson = {
|
|
120
|
+
type: "FeatureCollection",
|
|
121
|
+
features: features,
|
|
122
|
+
};
|
|
123
|
+
geoJsonSources.push(
|
|
124
|
+
encodeURI(
|
|
125
|
+
"data:application/json;charset=utf-8," + JSON.stringify(geojson),
|
|
126
|
+
),
|
|
127
|
+
);
|
|
98
128
|
}
|
|
99
129
|
}
|
|
100
130
|
|
|
@@ -6,14 +6,15 @@ import { getStyleVariablesState } from "./triggers.js";
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {import("stac-ts").StacLink[]} [links]
|
|
8
8
|
* @param {Record<string,any>} [extraProperties]
|
|
9
|
+
* @param {string} [rel = "item"]
|
|
9
10
|
**/
|
|
10
|
-
export function generateFeatures(links, extraProperties = {}) {
|
|
11
|
+
export function generateFeatures(links, extraProperties = {}, rel = "item") {
|
|
11
12
|
/**
|
|
12
13
|
* @type {import("geojson").Feature[]}
|
|
13
14
|
*/
|
|
14
15
|
const features = [];
|
|
15
16
|
links?.forEach((element) => {
|
|
16
|
-
if (element.rel ===
|
|
17
|
+
if (element.rel === rel && "latlng" in element) {
|
|
17
18
|
const [lat, lon] = /** @type {string} */ (element.latlng)
|
|
18
19
|
.split(",")
|
|
19
20
|
.map((it) => Number(it));
|
|
@@ -177,9 +178,9 @@ export const extractLayerDatetime = (links, currentStep) => {
|
|
|
177
178
|
}
|
|
178
179
|
|
|
179
180
|
// check if links has a datetime value
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (!
|
|
181
|
+
const dateProperty = getDatetimeProperty(links);
|
|
182
|
+
|
|
183
|
+
if (!dateProperty) {
|
|
183
184
|
return undefined;
|
|
184
185
|
}
|
|
185
186
|
|
|
@@ -187,11 +188,10 @@ export const extractLayerDatetime = (links, currentStep) => {
|
|
|
187
188
|
const controlValues = [];
|
|
188
189
|
try {
|
|
189
190
|
currentStep = new Date(currentStep).toISOString();
|
|
190
|
-
|
|
191
191
|
links.reduce((vals, link) => {
|
|
192
|
-
if (link
|
|
192
|
+
if (link[dateProperty] && link.rel === "item") {
|
|
193
193
|
vals.push(
|
|
194
|
-
new Date(/** @type {string} */ (link
|
|
194
|
+
new Date(/** @type {string} */ (link[dateProperty])).toISOString(),
|
|
195
195
|
);
|
|
196
196
|
}
|
|
197
197
|
return vals;
|
|
@@ -207,7 +207,12 @@ export const extractLayerDatetime = (links, currentStep) => {
|
|
|
207
207
|
|
|
208
208
|
// item datetime is not included in the item links datetime
|
|
209
209
|
if (!controlValues.includes(currentStep)) {
|
|
210
|
-
|
|
210
|
+
const currentStepTime = new Date(currentStep).getTime();
|
|
211
|
+
currentStep = controlValues.reduce((a, b) => {
|
|
212
|
+
const aDiff = Math.abs(new Date(a).getTime() - currentStepTime);
|
|
213
|
+
const bDiff = Math.abs(new Date(b).getTime() - currentStepTime);
|
|
214
|
+
return bDiff < aDiff ? b : a;
|
|
215
|
+
});
|
|
211
216
|
}
|
|
212
217
|
|
|
213
218
|
return {
|
|
@@ -216,15 +221,15 @@ export const extractLayerDatetime = (links, currentStep) => {
|
|
|
216
221
|
slider: true,
|
|
217
222
|
navigation: true,
|
|
218
223
|
play: false,
|
|
219
|
-
displayFormat: "DD.MM.YYYY HH:
|
|
224
|
+
displayFormat: "DD.MM.YYYY HH:mm",
|
|
220
225
|
};
|
|
221
226
|
};
|
|
222
227
|
|
|
223
228
|
/**
|
|
224
229
|
* Find JSON layer by ID
|
|
225
230
|
* @param {string} layer
|
|
226
|
-
* @param {
|
|
227
|
-
* @returns {
|
|
231
|
+
* @param {import("@eox/map").EoxLayer[]} layers
|
|
232
|
+
* @returns {import("@eox/map").EoxLayer | undefined}
|
|
228
233
|
**/
|
|
229
234
|
export const findLayer = (layers, layer) => {
|
|
230
235
|
for (const lyr of layers) {
|
|
@@ -235,7 +240,7 @@ export const findLayer = (layers, layer) => {
|
|
|
235
240
|
}
|
|
236
241
|
return found;
|
|
237
242
|
}
|
|
238
|
-
if (lyr.properties
|
|
243
|
+
if (lyr.properties?.id === layer) {
|
|
239
244
|
return lyr;
|
|
240
245
|
}
|
|
241
246
|
}
|
|
@@ -243,14 +248,14 @@ export const findLayer = (layers, layer) => {
|
|
|
243
248
|
|
|
244
249
|
/**
|
|
245
250
|
* Removes the layer with the id provided and injects an array of layers in its position
|
|
246
|
-
* @param {
|
|
251
|
+
* @param {import("@eox/map").EoxLayer[]} currentLayers
|
|
247
252
|
* @param {string} oldLayer - id of the layer to be replaced
|
|
248
|
-
*
|
|
249
|
-
* @returns {
|
|
253
|
+
* @param {import("@eox/map").EoxLayer[]} newLayers - array of layers to replace the old layer
|
|
254
|
+
* @returns {import("@eox/map").EoxLayer[]}
|
|
250
255
|
*/
|
|
251
256
|
export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
|
|
252
257
|
const oldLayerIdx = currentLayers.findIndex(
|
|
253
|
-
(l) => l.properties
|
|
258
|
+
(l) => l.properties?.id === oldLayer,
|
|
254
259
|
);
|
|
255
260
|
|
|
256
261
|
if (oldLayerIdx !== -1) {
|
|
@@ -258,10 +263,9 @@ export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
|
|
|
258
263
|
"Replacing layer",
|
|
259
264
|
oldLayer,
|
|
260
265
|
"with",
|
|
261
|
-
newLayers.map((l) => l.properties
|
|
266
|
+
newLayers.map((l) => l.properties?.id),
|
|
262
267
|
);
|
|
263
268
|
currentLayers.splice(oldLayerIdx, 1, ...newLayers);
|
|
264
|
-
return currentLayers;
|
|
265
269
|
}
|
|
266
270
|
|
|
267
271
|
for (const l of currentLayers) {
|
|
@@ -269,10 +273,10 @@ export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
|
|
|
269
273
|
const updatedGroupLyrs = replaceLayer(l.layers, oldLayer, newLayers);
|
|
270
274
|
if (updatedGroupLyrs?.length) {
|
|
271
275
|
l.layers = updatedGroupLyrs;
|
|
272
|
-
return currentLayers;
|
|
273
276
|
}
|
|
274
277
|
}
|
|
275
278
|
}
|
|
279
|
+
return currentLayers;
|
|
276
280
|
};
|
|
277
281
|
|
|
278
282
|
/**
|
|
@@ -281,18 +285,21 @@ export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
|
|
|
281
285
|
* @param {import('../eodashSTAC/EodashCollection.js').EodashCollection[]} indicators
|
|
282
286
|
* @param {import('ol/layer').Layer} layer
|
|
283
287
|
*/
|
|
284
|
-
export const getColFromLayer =
|
|
288
|
+
export const getColFromLayer = (indicators, layer) => {
|
|
285
289
|
// init cols
|
|
286
|
-
const collections =
|
|
287
|
-
indicators.map((ind) => ind.fetchCollection()),
|
|
288
|
-
);
|
|
290
|
+
const collections = indicators.map((ind) => ind.collectionStac);
|
|
289
291
|
const [collectionId, itemId, ..._other] = layer.get("id").split(";:;");
|
|
290
292
|
|
|
291
293
|
const chosen = collections.find((col) => {
|
|
292
294
|
const isInd =
|
|
293
|
-
col
|
|
294
|
-
col
|
|
295
|
-
(link) =>
|
|
295
|
+
col?.id === collectionId &&
|
|
296
|
+
col?.links?.some(
|
|
297
|
+
(link) =>
|
|
298
|
+
link.rel === "item" &&
|
|
299
|
+
(link.href.includes(itemId) ||
|
|
300
|
+
link.id === itemId ||
|
|
301
|
+
//@ts-expect-error attaching the item in link when parsing .parquet items, see @/eodashSTAC/parquet.js
|
|
302
|
+
(link["item"] && link["item"].id === itemId)),
|
|
296
303
|
);
|
|
297
304
|
return isInd;
|
|
298
305
|
});
|
|
@@ -306,7 +313,7 @@ export const getColFromLayer = async (indicators, layer) => {
|
|
|
306
313
|
* @param {string} collectionId
|
|
307
314
|
* @param {string} itemId
|
|
308
315
|
* @param {import('stac-ts').StacLink} link
|
|
309
|
-
* @param {string} projectionCode
|
|
316
|
+
* @param {string | import("ol/proj").ProjectionLike} projectionCode
|
|
310
317
|
*
|
|
311
318
|
*/
|
|
312
319
|
export const createLayerID = (collectionId, itemId, link, projectionCode) => {
|
|
@@ -419,6 +426,87 @@ export async function mergeGeojsons(geojsonUrls) {
|
|
|
419
426
|
);
|
|
420
427
|
}
|
|
421
428
|
|
|
429
|
+
/**
|
|
430
|
+
*
|
|
431
|
+
* @param {import("stac-ts").StacItem[]} items
|
|
432
|
+
*/
|
|
433
|
+
export function generateLinksFromItems(items) {
|
|
434
|
+
/**
|
|
435
|
+
* @param {string|Date} datetime
|
|
436
|
+
* @returns
|
|
437
|
+
*/
|
|
438
|
+
function formateDatetime(datetime) {
|
|
439
|
+
if (datetime instanceof Date) {
|
|
440
|
+
return datetime.toISOString();
|
|
441
|
+
}
|
|
442
|
+
if (typeof datetime === "string") {
|
|
443
|
+
const date = new Date(datetime);
|
|
444
|
+
return date.toISOString();
|
|
445
|
+
}
|
|
446
|
+
return datetime;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return items.map((item) => {
|
|
450
|
+
const itemBlob = new Blob([JSON.stringify(item)], {
|
|
451
|
+
type: "application/geo+json",
|
|
452
|
+
});
|
|
453
|
+
// urls are revoked when updating the collection. see updateEodashCollections in "../utils/index.js"
|
|
454
|
+
const itemUrl = URL.createObjectURL(itemBlob);
|
|
455
|
+
return {
|
|
456
|
+
id: item.id,
|
|
457
|
+
rel: "item",
|
|
458
|
+
type: "application/geo+json",
|
|
459
|
+
title: item.id,
|
|
460
|
+
href: itemUrl,
|
|
461
|
+
...(item.properties.datetime && {
|
|
462
|
+
datetime: formateDatetime(item.properties.datetime),
|
|
463
|
+
}),
|
|
464
|
+
...(item.properties.start_datetime && {
|
|
465
|
+
start_datetime: formateDatetime(item.properties.start_datetime),
|
|
466
|
+
}),
|
|
467
|
+
...(item.properties.end_datetime && {
|
|
468
|
+
end_datetime: formateDatetime(item.properties.end_datetime),
|
|
469
|
+
}),
|
|
470
|
+
//@ts-expect-error projection extension
|
|
471
|
+
...(item.properties?.["proj:epsg"] && {
|
|
472
|
+
"proj:epsg": /** @type {number} **/ (item.properties["proj:epsg"]),
|
|
473
|
+
}),
|
|
474
|
+
//@ts-expect-error eodash projection
|
|
475
|
+
...(item.properties?.["eodash:proj4_def"] && {
|
|
476
|
+
"eodash:proj4_def": item.properties["eodash:proj4_def"],
|
|
477
|
+
}),
|
|
478
|
+
|
|
479
|
+
...(item.geometry?.type == "Point" &&
|
|
480
|
+
item.geometry?.coordinates.length && {
|
|
481
|
+
latlng: item.geometry.coordinates.reverse().join(","),
|
|
482
|
+
}),
|
|
483
|
+
...(Object.values(item.assets ?? {}).some(
|
|
484
|
+
(asset) =>
|
|
485
|
+
asset.href.startsWith("s3://veda-data-store") &&
|
|
486
|
+
asset.type === "image/tiff; application=geotiff",
|
|
487
|
+
) && {
|
|
488
|
+
cog_href: Object.values(item.assets ?? {}).find((asset) =>
|
|
489
|
+
asset.href.startsWith("s3://veda-data-store"),
|
|
490
|
+
)?.href,
|
|
491
|
+
}),
|
|
492
|
+
};
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* @param {import("../eodashSTAC/EodashCollection.js").EodashCollection} collection
|
|
498
|
+
*/
|
|
499
|
+
export function revokeCollectionBlobUrls(collection) {
|
|
500
|
+
collection.collectionStac?.links.forEach((link) => {
|
|
501
|
+
if (!(link.rel === "item" && link.type === "application/geo+json")) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
if (link.href.startsWith("blob:")) {
|
|
505
|
+
URL.revokeObjectURL(link.href);
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
|
|
422
510
|
/**
|
|
423
511
|
* adds tooltip to the layer if the style has tooltip property
|
|
424
512
|
* @param {Record<string,any>} layer
|
|
@@ -441,3 +529,46 @@ export const addTooltipInteraction = (layer, style) => {
|
|
|
441
529
|
];
|
|
442
530
|
}
|
|
443
531
|
};
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
*
|
|
535
|
+
* @param {import("stac-ts").StacLink[]} [links]
|
|
536
|
+
*/
|
|
537
|
+
export function getDatetimeProperty(links) {
|
|
538
|
+
if (!links?.length) {
|
|
539
|
+
return undefined;
|
|
540
|
+
}
|
|
541
|
+
// TODO: consider other properties for datetime ranges
|
|
542
|
+
const datetimeProperties = ["datetime", "start_datetime", "end_datetime"];
|
|
543
|
+
for (const prop of datetimeProperties) {
|
|
544
|
+
const propExists = links.some(
|
|
545
|
+
(l) => l[prop] && typeof l[prop] === "string",
|
|
546
|
+
);
|
|
547
|
+
if (!propExists) {
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
return prop;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* @param {import ("stac-ts").StacCollection | undefined | null} collection
|
|
556
|
+
* @returns {object}
|
|
557
|
+
*/
|
|
558
|
+
export function extractLayerLegend(collection) {
|
|
559
|
+
let extraProperties = {};
|
|
560
|
+
if (collection?.assets?.legend?.href) {
|
|
561
|
+
extraProperties = {
|
|
562
|
+
description: `<div style="width: 100%">
|
|
563
|
+
<img src="${collection.assets.legend.href}" style="max-height:70px; margin-top:-15px; margin-bottom:-20px;" />
|
|
564
|
+
</div>`,
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
// Check if collection has eox:colorlegend definition, if yes overwrite legend description
|
|
568
|
+
if (collection && collection["eox:colorlegend"]) {
|
|
569
|
+
extraProperties = {
|
|
570
|
+
layerLegend: collection["eox:colorlegend"],
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
return extraProperties;
|
|
574
|
+
}
|