@eodash/eodash 5.0.0-alpha.2.14 → 5.0.0-alpha.2.16
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 -1
- package/core/client/composables/EodashMap.js +245 -0
- package/core/client/composables/index.js +2 -2
- package/core/client/eodash.js +1 -2
- package/core/client/store/Actions.js +30 -10
- package/core/client/store/States.js +4 -1
- package/core/client/store/stac.js +52 -2
- package/core/client/types.d.ts +6 -2
- package/core/client/utils/createLayers.js +147 -40
- package/core/client/utils/eodashSTAC.js +94 -19
- package/core/client/utils/helpers.js +189 -11
- package/core/client/utils/states.js +17 -0
- package/dist/client/{DashboardLayout-ulCTLwXv.js → DashboardLayout-CCtyOil0.js} +2 -2
- package/dist/client/{DynamicWebComponent-CZJjeckP.js → DynamicWebComponent-But2r1Sj.js} +2 -2
- package/dist/client/EodashDatePicker-jeYiWflv.js +247 -0
- package/dist/client/{EodashItemFilter-9hK-3-7Y.js → EodashItemFilter-BFlfWeE_.js} +2028 -2024
- package/dist/client/EodashLayerControl-BhZL4pYM.js +24358 -0
- package/dist/client/{EodashMap-jqF-NaSp.js → EodashMap-C5tOgVOv.js} +22268 -24006
- package/dist/client/{EodashMapBtns-F7rE6A-2.js → EodashMapBtns-CdDfVQj0.js} +2 -2
- package/dist/client/{ExportState-CHU5c0uO.js → ExportState-CKCCN_VI.js} +142 -136
- package/dist/client/{Footer-DjkwaDHV.js → Footer-B9yVgyzx.js} +67 -65
- package/dist/client/{Header-V8pZw2HR.js → Header-CPIlUEOq.js} +4 -4
- package/dist/client/{IframeWrapper-C8EZZnHk.js → IframeWrapper-DRw1kHJm.js} +1 -1
- package/dist/client/{MobileLayout-zOO_ZJVe.js → MobileLayout-CPxVee5U.js} +6 -6
- package/dist/client/{PopUp-BNnXTHYD.js → PopUp-Dca-gx9a.js} +5 -5
- package/dist/client/{VImg-Cj6-XkWV.js → VImg-PHLA1nP1.js} +2 -2
- package/dist/client/{VMain-BXL9EwGV.js → VMain-Ck81LJfb.js} +2 -2
- package/dist/client/{VOverlay-C9MeDzGb.js → VOverlay-CL4hiJB8.js} +92 -92
- package/dist/client/{WidgetsContainer-Cw4LFyGR.js → WidgetsContainer-jxk3kw-d.js} +1 -1
- package/dist/client/asWebComponent-3OsFQJVx.js +23633 -0
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-DF-jCteQ.js → forwardRefs-BxZaq9ml.js} +1 -1
- package/dist/client/{index-BfF7LPVL.js → index-Vul961Xy.js} +23 -23
- package/dist/client/{lerc-B4lXefGh-WUagmXWl.js → lerc-B4lXefGh-BESXOHWk.js} +1 -1
- package/dist/client/{ssrBoot-DNvPtEea.js → ssrBoot-BFMBrCqY.js} +1 -1
- package/dist/client/style.css +2 -2
- package/dist/client/{transition-Dc2dpya2.js → transition-U5aFjJtV.js} +1 -1
- package/dist/client/{webfontloader-qotgY98I.js → webfontloader-D_JbBwHu.js} +1 -1
- package/package.json +5 -3
- package/widgets/EodashDatePicker.vue +32 -40
- package/widgets/EodashItemFilter.vue +2 -0
- package/widgets/EodashLayerControl.vue +69 -7
- package/widgets/EodashMap.vue +35 -208
- package/widgets/ExportState.vue +8 -7
- package/dist/client/EodashDatePicker-BClSZg9g.js +0 -252
- package/dist/client/EodashLayerControl-p5FdBiiJ.js +0 -20969
- package/dist/client/_commonjsHelpers-DaMA6jEr.js +0 -8
- package/dist/client/asWebComponent-GN3G-Gdj.js +0 -20451
- package/dist/client/helpers-XtsCspQr.js +0 -1390
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { registerProjection } from "@/store/Actions";
|
|
2
|
-
import { extractRoles } from "./helpers";
|
|
2
|
+
import { extractRoles, getProjectionCode } from "./helpers";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @param {string} id
|
|
@@ -7,6 +7,7 @@ import { extractRoles } from "./helpers";
|
|
|
7
7
|
* @param {Record<string,import("stac-ts").StacAsset>} assets
|
|
8
8
|
* @param {import("ol/layer/WebGLTile").Style} [style]
|
|
9
9
|
* @param {Record<string, unknown>} [layerConfig]
|
|
10
|
+
* @param {Record<string, unknown>} [layerDatetime]
|
|
10
11
|
**/
|
|
11
12
|
export async function createLayersFromDataAssets(
|
|
12
13
|
id,
|
|
@@ -14,14 +15,17 @@ export async function createLayersFromDataAssets(
|
|
|
14
15
|
assets,
|
|
15
16
|
style,
|
|
16
17
|
layerConfig,
|
|
18
|
+
layerDatetime,
|
|
17
19
|
) {
|
|
18
20
|
let jsonArray = [];
|
|
19
21
|
let geoTIFFSources = [];
|
|
20
22
|
for (const ast in assets) {
|
|
21
23
|
// register projection if exists
|
|
22
|
-
|
|
23
|
-
/** @type {number | undefined} */ (
|
|
24
|
-
|
|
24
|
+
const assetProjection =
|
|
25
|
+
/** @type {string | number | {name: string, def: string, extent?:number[]} | undefined} */ (
|
|
26
|
+
assets[ast]?.["proj:epsg"] || assets[ast]?.["eodash:proj4_def"]
|
|
27
|
+
);
|
|
28
|
+
await registerProjection(assetProjection);
|
|
25
29
|
|
|
26
30
|
if (assets[ast]?.type === "application/geo+json") {
|
|
27
31
|
const layer = {
|
|
@@ -34,6 +38,7 @@ export async function createLayersFromDataAssets(
|
|
|
34
38
|
properties: {
|
|
35
39
|
id,
|
|
36
40
|
title,
|
|
41
|
+
layerDatetime,
|
|
37
42
|
...(layerConfig && {
|
|
38
43
|
layerConfig: {
|
|
39
44
|
...layerConfig,
|
|
@@ -41,9 +46,13 @@ export async function createLayersFromDataAssets(
|
|
|
41
46
|
},
|
|
42
47
|
}),
|
|
43
48
|
},
|
|
44
|
-
...(!style?.variables && {style}),
|
|
49
|
+
...(!style?.variables && { style }),
|
|
45
50
|
};
|
|
46
|
-
extractRoles(
|
|
51
|
+
extractRoles(
|
|
52
|
+
layer.properties,
|
|
53
|
+
assets[ast]?.roles ?? [],
|
|
54
|
+
/** @type {string} */ (assets[ast].id || assets[ast].title || ""),
|
|
55
|
+
);
|
|
47
56
|
jsonArray.push(layer);
|
|
48
57
|
} else if (assets[ast]?.type === "image/tiff") {
|
|
49
58
|
geoTIFFSources.push({ url: assets[ast].href });
|
|
@@ -62,6 +71,7 @@ export async function createLayersFromDataAssets(
|
|
|
62
71
|
id,
|
|
63
72
|
title,
|
|
64
73
|
layerConfig,
|
|
74
|
+
layerDatetime,
|
|
65
75
|
},
|
|
66
76
|
style,
|
|
67
77
|
});
|
|
@@ -74,59 +84,156 @@ export async function createLayersFromDataAssets(
|
|
|
74
84
|
* @param {import('stac-ts').StacItem} item
|
|
75
85
|
* @param {string} id
|
|
76
86
|
* @param {string} title
|
|
87
|
+
* @param {Record<string,any>} [layerDatetime]
|
|
77
88
|
*/
|
|
78
|
-
export const createLayersFromLinks = (id, title, item) => {
|
|
89
|
+
export const createLayersFromLinks = async (id, title, item, layerDatetime) => {
|
|
79
90
|
/** @type {Record<string,any>[]} */
|
|
80
91
|
const jsonArray = [];
|
|
81
92
|
const wmsArray = item.links.filter((l) => l.rel === "wms");
|
|
82
|
-
const
|
|
93
|
+
const wmtsArray = item.links.filter((l) => l.rel === "wmts");
|
|
94
|
+
const xyzArray = item.links.filter((l) => l.rel === "xyz") ?? [];
|
|
95
|
+
|
|
96
|
+
for (const wmsLink of wmsArray ?? []) {
|
|
97
|
+
// Registering setting sub wms link projection
|
|
98
|
+
|
|
99
|
+
const wmsLinkProjection =
|
|
100
|
+
/** @type {number | string | {name: string, def: string} | undefined} */
|
|
101
|
+
(wmsLink?.["proj:epsg"] || wmsLink?.["eodash:proj4_def"]);
|
|
102
|
+
|
|
103
|
+
await registerProjection(wmsLinkProjection);
|
|
104
|
+
const projectionCode = getProjectionCode(wmsLinkProjection || "EPSG:4326");
|
|
105
|
+
let json = {
|
|
106
|
+
type: "Tile",
|
|
107
|
+
properties: {
|
|
108
|
+
id,
|
|
109
|
+
title: wmsLink.title || title || item.id,
|
|
110
|
+
layerDatetime,
|
|
111
|
+
},
|
|
112
|
+
source: {
|
|
113
|
+
type: "TileWMS",
|
|
114
|
+
url: wmsLink.href,
|
|
115
|
+
projection: projectionCode,
|
|
116
|
+
params: {
|
|
117
|
+
LAYERS: wmsLink["wms:layers"],
|
|
118
|
+
TILED: true,
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
83
122
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
123
|
+
extractRoles(
|
|
124
|
+
json.properties,
|
|
125
|
+
/** @type {string[]} */ (wmsLink.roles),
|
|
126
|
+
/** @type {string} */ (wmsLink.id) ||
|
|
127
|
+
/** @type {string} */ (wmsLink.title) ||
|
|
128
|
+
"",
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
if ("wms:dimensions" in wmsLink) {
|
|
132
|
+
// Expand all dimensions into the params attribute
|
|
133
|
+
Object.assign(json.source.params, wmsLink["wms:dimensions"]);
|
|
134
|
+
}
|
|
135
|
+
jsonArray.push(json);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
for (const wmtsLink of wmtsArray ?? []) {
|
|
139
|
+
// Registering setting sub wmts link projection
|
|
140
|
+
|
|
141
|
+
const wmtsLinkProjection =
|
|
142
|
+
/** @type {number | string | {name: string, def: string} | undefined} */
|
|
143
|
+
(wmtsLink?.["proj:epsg"] || wmtsLink?.["eodash:proj4_def"]);
|
|
144
|
+
|
|
145
|
+
await registerProjection(wmtsLinkProjection);
|
|
146
|
+
const projectionCode = getProjectionCode(wmtsLinkProjection || "EPSG:3857");
|
|
147
|
+
// TODO: WARNING! This is a temporary project specific implementation
|
|
148
|
+
// that needs to be removed once catalog and wmts creation from capabilities
|
|
149
|
+
// combined with custom view projections is solved
|
|
150
|
+
let json;
|
|
151
|
+
if (wmtsLink.title === "wmts capabilities") {
|
|
152
|
+
json = {
|
|
87
153
|
type: "Tile",
|
|
88
154
|
properties: {
|
|
89
|
-
id
|
|
90
|
-
title: title ||
|
|
155
|
+
id,
|
|
156
|
+
title: title || item.id,
|
|
157
|
+
layerDatetime,
|
|
91
158
|
},
|
|
92
159
|
source: {
|
|
93
|
-
type: "
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
160
|
+
type: "WMTS",
|
|
161
|
+
// TODO: Hard coding url as the current one set is for capabilities
|
|
162
|
+
url: "https://wmts.marine.copernicus.eu/teroWmts",
|
|
163
|
+
layer: wmtsLink["wmts:layer"],
|
|
164
|
+
style: wmtsLink.style || "default",
|
|
165
|
+
// TODO: Hard coding matrixSet until we find solution to wmts creation from capabilities
|
|
166
|
+
matrixSet: "EPSG:3857",
|
|
167
|
+
projection: projectionCode,
|
|
168
|
+
tileGrid: {
|
|
169
|
+
tileSize: [128, 128],
|
|
98
170
|
},
|
|
171
|
+
dimensions: wmtsLink["wmts:dimensions"],
|
|
99
172
|
},
|
|
100
173
|
};
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if ("wms:dimensions" in link) {
|
|
105
|
-
// Expand all dimensions into the params attribute
|
|
106
|
-
Object.assign(json.source.params, link["wms:dimensions"]);
|
|
107
|
-
}
|
|
108
|
-
jsonArray.push(json);
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (xyzArray.length) {
|
|
113
|
-
xyzArray.forEach((link) => {
|
|
114
|
-
let json = {
|
|
174
|
+
} else {
|
|
175
|
+
json = {
|
|
115
176
|
type: "Tile",
|
|
116
177
|
properties: {
|
|
117
|
-
id
|
|
118
|
-
title: title ||
|
|
119
|
-
|
|
178
|
+
id,
|
|
179
|
+
title: wmtsLink.title || title || item.id,
|
|
180
|
+
layerDatetime,
|
|
120
181
|
},
|
|
121
182
|
source: {
|
|
122
|
-
type: "
|
|
123
|
-
url:
|
|
183
|
+
type: "WMTS",
|
|
184
|
+
url: wmtsLink,
|
|
185
|
+
layer: wmtsLink["wmts:layer"],
|
|
186
|
+
style: wmtsLink.style || "default",
|
|
187
|
+
matrixSet: wmtsLink.matrixSet || "EPSG:3857",
|
|
188
|
+
projection: projectionCode,
|
|
189
|
+
tileGrid: {
|
|
190
|
+
tileSize: [128, 128],
|
|
191
|
+
},
|
|
192
|
+
dimensions: wmtsLink["wmts:dimensions"],
|
|
124
193
|
},
|
|
125
194
|
};
|
|
195
|
+
}
|
|
126
196
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
197
|
+
extractRoles(
|
|
198
|
+
json.properties,
|
|
199
|
+
/** @type {string[]} */ (wmtsLink.roles),
|
|
200
|
+
/** @type {string} */ (wmtsLink.id) ||
|
|
201
|
+
/** @type {string} */ (wmtsLink.title) ||
|
|
202
|
+
"",
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
jsonArray.push(json);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
for (const xyzLink of xyzArray ?? []) {
|
|
209
|
+
const xyzLinkProjection =
|
|
210
|
+
/** @type {number | string | {name: string, def: string} | undefined} */
|
|
211
|
+
(xyzLink?.["proj:epsg"] || xyzLink?.["eodash:proj4_def"]);
|
|
212
|
+
|
|
213
|
+
await registerProjection(xyzLinkProjection);
|
|
214
|
+
|
|
215
|
+
const projectionCode = getProjectionCode(xyzLinkProjection || "EPSG:3857");
|
|
216
|
+
let json = {
|
|
217
|
+
type: "Tile",
|
|
218
|
+
properties: {
|
|
219
|
+
id,
|
|
220
|
+
title: xyzLink.title || title || item.id,
|
|
221
|
+
roles: xyzLink.roles,
|
|
222
|
+
layerDatetime,
|
|
223
|
+
},
|
|
224
|
+
source: {
|
|
225
|
+
type: "XYZ",
|
|
226
|
+
url: xyzLink.href,
|
|
227
|
+
projection: projectionCode,
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
extractRoles(
|
|
232
|
+
json.properties,
|
|
233
|
+
/** @type {string[]} */ (xyzLink.roles),
|
|
234
|
+
/** @type {string} */ (xyzLink.id || xyzLink.title || ""),
|
|
235
|
+
);
|
|
236
|
+
jsonArray.push(json);
|
|
130
237
|
}
|
|
131
238
|
return jsonArray;
|
|
132
239
|
};
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { Collection, Item } from "stac-js";
|
|
2
2
|
import { toAbsolute } from "stac-js/src/http.js";
|
|
3
3
|
import {
|
|
4
|
+
createLayerID,
|
|
4
5
|
extractLayerConfig,
|
|
6
|
+
extractLayerDatetime,
|
|
5
7
|
extractRoles,
|
|
6
8
|
fetchStyle,
|
|
9
|
+
findLayer,
|
|
7
10
|
generateFeatures,
|
|
8
|
-
|
|
11
|
+
replaceLayer,
|
|
9
12
|
} from "./helpers";
|
|
10
|
-
import { registerProjection } from "@/store/Actions";
|
|
13
|
+
import { getLayers, registerProjection } from "@/store/Actions";
|
|
11
14
|
import {
|
|
12
15
|
createLayersFromDataAssets,
|
|
13
16
|
createLayersFromLinks,
|
|
@@ -20,6 +23,11 @@ export class EodashCollection {
|
|
|
20
23
|
/** @type {import("stac-ts").StacCollection | undefined} */
|
|
21
24
|
#collectionStac;
|
|
22
25
|
|
|
26
|
+
// read only
|
|
27
|
+
get collectionStac() {
|
|
28
|
+
return this.#collectionStac;
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
/**
|
|
24
32
|
* @type {import("stac-ts").StacLink
|
|
25
33
|
* | import("stac-ts").StacItem
|
|
@@ -52,13 +60,7 @@ export class EodashCollection {
|
|
|
52
60
|
let layersJson = [];
|
|
53
61
|
|
|
54
62
|
// Load collectionstac if not yet initialized
|
|
55
|
-
|
|
56
|
-
stac = await axios.get(this.#collectionUrl).then((resp) => resp.data);
|
|
57
|
-
this.#collectionStac = new Collection(stac);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// set availabe map projection
|
|
61
|
-
setMapProjFromCol(this.#collectionStac);
|
|
63
|
+
stac = await this.fetchCollection();
|
|
62
64
|
|
|
63
65
|
const isGeoDB = stac?.endpointtype === "GeoDB";
|
|
64
66
|
|
|
@@ -94,7 +96,8 @@ export class EodashCollection {
|
|
|
94
96
|
// specific item was requested
|
|
95
97
|
const item = new Item(stac);
|
|
96
98
|
this.selectedItem = item;
|
|
97
|
-
const title =
|
|
99
|
+
const title =
|
|
100
|
+
this.#collectionStac?.title || this.#collectionStac?.id || "";
|
|
98
101
|
layersJson.unshift(
|
|
99
102
|
...(await this.buildJsonArray(item, stacItemUrl, title, isGeoDB)),
|
|
100
103
|
);
|
|
@@ -107,11 +110,18 @@ export class EodashCollection {
|
|
|
107
110
|
* @param {string} itemUrl
|
|
108
111
|
* @param {string} title
|
|
109
112
|
* @param {boolean} isGeoDB
|
|
113
|
+
* @param {string} [itemDatetime]
|
|
110
114
|
* @returns {Promise<Record<string,any>[]>} arrays
|
|
111
115
|
* */
|
|
112
|
-
async buildJsonArray(item, itemUrl, title, isGeoDB) {
|
|
116
|
+
async buildJsonArray(item, itemUrl, title, isGeoDB, itemDatetime) {
|
|
117
|
+
await this.fetchCollection();
|
|
118
|
+
// registering top level indicator projection
|
|
119
|
+
const indicatorProjection =
|
|
120
|
+
item?.["proj:epsg"] || item?.["eodash:proj4_def"];
|
|
113
121
|
await registerProjection(
|
|
114
|
-
/** @type {number | undefined} */ (
|
|
122
|
+
/** @type {number | string | {name: string, def: string; extent: number[] | undefined;} } */ (
|
|
123
|
+
indicatorProjection
|
|
124
|
+
),
|
|
115
125
|
);
|
|
116
126
|
|
|
117
127
|
const jsonArray = [];
|
|
@@ -123,7 +133,7 @@ export class EodashCollection {
|
|
|
123
133
|
{
|
|
124
134
|
type: "Vector",
|
|
125
135
|
properties: {
|
|
126
|
-
id: item.id,
|
|
136
|
+
id: createLayerID(this.#collectionStac?.id ?? "", item.id, false),
|
|
127
137
|
title: this.#collectionStac?.title || item.id,
|
|
128
138
|
},
|
|
129
139
|
source: {
|
|
@@ -152,6 +162,11 @@ export class EodashCollection {
|
|
|
152
162
|
await fetchStyle(item, itemUrl),
|
|
153
163
|
);
|
|
154
164
|
|
|
165
|
+
const layerDatetime = extractLayerDatetime(
|
|
166
|
+
this.getItems(),
|
|
167
|
+
item.properties?.datetime ?? itemDatetime,
|
|
168
|
+
);
|
|
169
|
+
|
|
155
170
|
const dataAssets = Object.keys(item?.assets ?? {}).reduce((data, ast) => {
|
|
156
171
|
if (item.assets[ast].roles?.includes("data")) {
|
|
157
172
|
data[ast] = item.assets[ast];
|
|
@@ -159,19 +174,25 @@ export class EodashCollection {
|
|
|
159
174
|
return data;
|
|
160
175
|
}, /** @type {Record<string,import('stac-ts').StacAsset>} */ ({}));
|
|
161
176
|
const isSupported =
|
|
162
|
-
item.links.some((link) => ["wms", "xyz"].includes(link.rel)) ||
|
|
177
|
+
item.links.some((link) => ["wms", "xyz", "wmts"].includes(link.rel)) ||
|
|
163
178
|
Object.keys(dataAssets).length;
|
|
164
179
|
|
|
165
180
|
if (isSupported) {
|
|
181
|
+
const links = await createLayersFromLinks(
|
|
182
|
+
createLayerID(this.#collectionStac?.id ?? "", item.id, false),
|
|
183
|
+
title,
|
|
184
|
+
item,
|
|
185
|
+
layerDatetime,
|
|
186
|
+
);
|
|
166
187
|
jsonArray.push(
|
|
167
|
-
...
|
|
168
|
-
|
|
188
|
+
...links,
|
|
169
189
|
...(await createLayersFromDataAssets(
|
|
170
|
-
|
|
190
|
+
createLayerID(this.#collectionStac?.id ?? "", item.id, true),
|
|
171
191
|
title || this.#collectionStac?.title || item.id,
|
|
172
192
|
dataAssets,
|
|
173
193
|
style,
|
|
174
194
|
layerConfig,
|
|
195
|
+
layerDatetime,
|
|
175
196
|
)),
|
|
176
197
|
);
|
|
177
198
|
} else {
|
|
@@ -182,19 +203,33 @@ export class EodashCollection {
|
|
|
182
203
|
displayFootprint: false,
|
|
183
204
|
data: item,
|
|
184
205
|
properties: {
|
|
185
|
-
id: item.id,
|
|
206
|
+
id: createLayerID(this.#collectionStac?.id ?? "", item.id, false),
|
|
186
207
|
title: title || item.id,
|
|
187
208
|
layerConfig,
|
|
188
209
|
},
|
|
189
210
|
style,
|
|
190
211
|
};
|
|
191
|
-
extractRoles(
|
|
212
|
+
extractRoles(
|
|
213
|
+
json.properties,
|
|
214
|
+
/** @type {string[]} */ (item?.roles),
|
|
215
|
+
item.id || /** @type {string} */ (item.title) || "" + " STAC",
|
|
216
|
+
);
|
|
192
217
|
jsonArray.push(json);
|
|
193
218
|
}
|
|
194
219
|
|
|
195
220
|
return jsonArray;
|
|
196
221
|
}
|
|
197
222
|
|
|
223
|
+
async fetchCollection() {
|
|
224
|
+
if (!this.#collectionStac) {
|
|
225
|
+
const col = await axios
|
|
226
|
+
.get(this.#collectionUrl)
|
|
227
|
+
.then((resp) => resp.data);
|
|
228
|
+
this.#collectionStac = new Collection(col);
|
|
229
|
+
}
|
|
230
|
+
return this.#collectionStac;
|
|
231
|
+
}
|
|
232
|
+
|
|
198
233
|
getItems() {
|
|
199
234
|
return (
|
|
200
235
|
this.#collectionStac?.links
|
|
@@ -254,4 +289,44 @@ export class EodashCollection {
|
|
|
254
289
|
})[0]
|
|
255
290
|
: this.getItems()?.at(-1);
|
|
256
291
|
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
*
|
|
295
|
+
* @param {string} datetime
|
|
296
|
+
* @param {string} layer
|
|
297
|
+
*/
|
|
298
|
+
async updateLayerJson(datetime, layer) {
|
|
299
|
+
await this.fetchCollection();
|
|
300
|
+
|
|
301
|
+
// get the link of the specified date
|
|
302
|
+
const specifiedLink = this.getItems()?.find(
|
|
303
|
+
(item) =>
|
|
304
|
+
typeof item.datetime === "string" &&
|
|
305
|
+
new Date(item.datetime).toISOString() === datetime,
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
if (!specifiedLink) {
|
|
309
|
+
console.warn(
|
|
310
|
+
"[eodash] no Item found for the provided datetime",
|
|
311
|
+
datetime,
|
|
312
|
+
);
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// create json layers from the item
|
|
317
|
+
const newLayers = await this.createLayersJson(specifiedLink);
|
|
318
|
+
|
|
319
|
+
const curentLayers = getLayers();
|
|
320
|
+
|
|
321
|
+
const oldLayer = findLayer(curentLayers, layer);
|
|
322
|
+
|
|
323
|
+
const updatedLayers = replaceLayer(
|
|
324
|
+
curentLayers,
|
|
325
|
+
/** @type {Record<string,any> & { properties:{ id:string; title:string } } } */
|
|
326
|
+
(oldLayer),
|
|
327
|
+
newLayers,
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
return updatedLayers;
|
|
331
|
+
}
|
|
257
332
|
}
|
|
@@ -60,23 +60,27 @@ export function extractLayerConfig(style) {
|
|
|
60
60
|
*/
|
|
61
61
|
export const setMapProjFromCol = (STAcCollection) => {
|
|
62
62
|
// if a projection exists on the collection level
|
|
63
|
-
|
|
63
|
+
|
|
64
|
+
const projection =
|
|
65
|
+
/** @type {number | string | {name: string, def: string} | undefined} */
|
|
66
|
+
(
|
|
67
|
+
STAcCollection?.["eodash:mapProjection"] ||
|
|
68
|
+
STAcCollection?.["proj:epsg"] ||
|
|
69
|
+
STAcCollection?.["eodash:proj4_def"]
|
|
70
|
+
);
|
|
71
|
+
if (projection) {
|
|
72
|
+
const projectionCode = getProjectionCode(projection);
|
|
64
73
|
if (
|
|
65
74
|
availableMapProjection.value &&
|
|
66
|
-
availableMapProjection.value !==
|
|
75
|
+
availableMapProjection.value !== projectionCode
|
|
67
76
|
) {
|
|
68
|
-
changeMapProjection(
|
|
69
|
-
/** @type {number} */
|
|
70
|
-
(STAcCollection["proj:epsg"]),
|
|
71
|
-
);
|
|
77
|
+
changeMapProjection(projection);
|
|
72
78
|
}
|
|
73
79
|
// set it for `EodashMapBtns`
|
|
74
|
-
availableMapProjection.value = /** @type {string} */ (
|
|
75
|
-
STAcCollection["proj:epsg"]
|
|
76
|
-
);
|
|
80
|
+
availableMapProjection.value = /** @type {string} */ (projectionCode);
|
|
77
81
|
} else {
|
|
78
82
|
// reset to default projection
|
|
79
|
-
changeMapProjection((availableMapProjection.value = ""));
|
|
83
|
+
changeMapProjection((availableMapProjection.value = "EPSG:3857"));
|
|
80
84
|
}
|
|
81
85
|
};
|
|
82
86
|
|
|
@@ -114,14 +118,17 @@ export function extractCollectionUrls(stacObject, basepath) {
|
|
|
114
118
|
* Assign extracted roles to layer properties
|
|
115
119
|
* @param {Record<string,any>} properties
|
|
116
120
|
* @param {string[]} roles
|
|
121
|
+
* @param {string} id - unique ID for baselayers and overlays
|
|
117
122
|
* */
|
|
118
|
-
export const extractRoles = (properties, roles) => {
|
|
123
|
+
export const extractRoles = (properties, roles, id) => {
|
|
119
124
|
roles?.forEach((role) => {
|
|
120
125
|
if (role === "visible") {
|
|
121
126
|
properties.visible = true;
|
|
122
127
|
}
|
|
123
128
|
if (role === "overlay" || role === "baselayer") {
|
|
124
129
|
properties.group = role;
|
|
130
|
+
const [colId, itemId, isAsset, _random] = properties.id.split(";:;");
|
|
131
|
+
properties.id = [colId, itemId, isAsset, id].join(";:;");
|
|
125
132
|
}
|
|
126
133
|
return properties;
|
|
127
134
|
});
|
|
@@ -146,3 +153,174 @@ export const fetchStyle = async (item, itemUrl) => {
|
|
|
146
153
|
return styleJson;
|
|
147
154
|
}
|
|
148
155
|
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Return projection code which is to be registered in `eox-map`
|
|
159
|
+
* @param {string|number|{name: string, def: string}} [projection]
|
|
160
|
+
* @returns {string}
|
|
161
|
+
*/
|
|
162
|
+
export const getProjectionCode = (projection) => {
|
|
163
|
+
let code = projection;
|
|
164
|
+
switch (typeof projection) {
|
|
165
|
+
case "number":
|
|
166
|
+
code = `EPSG:${projection}`;
|
|
167
|
+
break;
|
|
168
|
+
case "string":
|
|
169
|
+
code = projection;
|
|
170
|
+
break;
|
|
171
|
+
case "object":
|
|
172
|
+
code = projection?.name;
|
|
173
|
+
}
|
|
174
|
+
return /** @type {string} */ (code);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @param {import("stac-ts").StacLink[]} [links]
|
|
179
|
+
* @param {string|null} [current]
|
|
180
|
+
**/
|
|
181
|
+
export const extractLayerDatetime = (links, current) => {
|
|
182
|
+
if (!current || !links?.length) {
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// check if links has a datetime value
|
|
187
|
+
const hasDatetime = links.some((l) => typeof l.datetime === "string");
|
|
188
|
+
if (!hasDatetime) {
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** @type {string[]} */
|
|
193
|
+
const values = [];
|
|
194
|
+
try {
|
|
195
|
+
current = new Date(current).toISOString();
|
|
196
|
+
|
|
197
|
+
links.reduce((vals, link) => {
|
|
198
|
+
if (link.datetime && link.rel === "item") {
|
|
199
|
+
vals.push(
|
|
200
|
+
new Date(/** @type {string} */ (link.datetime)).toISOString(),
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
return vals;
|
|
204
|
+
}, values);
|
|
205
|
+
} catch (e) {
|
|
206
|
+
console.warn("[eodash] not supported datetime format was provided", e);
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
// not enough values
|
|
210
|
+
if (values.length <= 1) {
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// item datetime is not included in the item links datetime
|
|
215
|
+
if (!values.includes(current)) {
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
values,
|
|
221
|
+
current,
|
|
222
|
+
slider: false,
|
|
223
|
+
disablePlay: true,
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Find layer by ID
|
|
229
|
+
* @param {string} layer
|
|
230
|
+
* @param {Record<string, any>[]} layers
|
|
231
|
+
* @returns {Record<string,any> | undefined}
|
|
232
|
+
**/
|
|
233
|
+
export const findLayer = (layers, layer) => {
|
|
234
|
+
for (const lyr of layers) {
|
|
235
|
+
if (lyr.type === "Group") {
|
|
236
|
+
const found = findLayer(lyr.layers, layer);
|
|
237
|
+
if (!found) {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
return found;
|
|
241
|
+
}
|
|
242
|
+
if (lyr.properties.id === layer) {
|
|
243
|
+
return lyr;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @param {Record<string,any>[]} currentLayers
|
|
250
|
+
* @param {Record<string,any>} oldLayer
|
|
251
|
+
* @param {Record<string,any>[]} newLayers
|
|
252
|
+
* @returns {Record<string,any>[] | undefined}
|
|
253
|
+
*/
|
|
254
|
+
export const replaceLayer = (currentLayers, oldLayer, newLayers) => {
|
|
255
|
+
const oldLayerIdx = currentLayers.findIndex(
|
|
256
|
+
(l) => l.properties.id === oldLayer.properties.id,
|
|
257
|
+
);
|
|
258
|
+
if (oldLayerIdx !== -1) {
|
|
259
|
+
currentLayers.splice(oldLayerIdx, 1, ...newLayers);
|
|
260
|
+
return currentLayers;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
for (const l of currentLayers) {
|
|
264
|
+
if (l.type === "Group") {
|
|
265
|
+
const updatedGroupLyrs = replaceLayer(l.layers, oldLayer, newLayers);
|
|
266
|
+
if (updatedGroupLyrs?.length) {
|
|
267
|
+
l.layers = updatedGroupLyrs;
|
|
268
|
+
return currentLayers;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* @param {import('./eodashSTAC.js').EodashCollection[]} indicators
|
|
275
|
+
* @param {import('ol/layer').Layer} layer
|
|
276
|
+
*/
|
|
277
|
+
export const getColFromLayer = async (indicators, layer) => {
|
|
278
|
+
// init cols
|
|
279
|
+
const collections = await Promise.all(
|
|
280
|
+
indicators.map((ind) => ind.fetchCollection()),
|
|
281
|
+
);
|
|
282
|
+
const [collectionId, itemId, _asset, _random] = layer.get("id").split(";:;");
|
|
283
|
+
|
|
284
|
+
const chosen = collections.find((col) => {
|
|
285
|
+
const isInd =
|
|
286
|
+
col.id === collectionId &&
|
|
287
|
+
col.links?.some(
|
|
288
|
+
(link) => link.rel === "item" && link.href.includes(itemId),
|
|
289
|
+
);
|
|
290
|
+
return isInd ?? false;
|
|
291
|
+
});
|
|
292
|
+
return indicators.find((ind) => ind.collectionStac?.id === chosen?.id);
|
|
293
|
+
};
|
|
294
|
+
/**
|
|
295
|
+
*
|
|
296
|
+
* @param {string} colId
|
|
297
|
+
* @param {string} itemId
|
|
298
|
+
* @param {boolean} isAsset
|
|
299
|
+
* @returns
|
|
300
|
+
*/
|
|
301
|
+
export const createLayerID = (colId, itemId, isAsset) => {
|
|
302
|
+
return `${colId ?? ""};:;${itemId ?? ""};:;${isAsset ? "_asset" : ""};:;${Math.random().toString(16).slice(2)}`;
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* creates a structured clone from the layers and
|
|
307
|
+
* removes all properties from the clone
|
|
308
|
+
* except the ID and title
|
|
309
|
+
*
|
|
310
|
+
* @param {Record<string,any>[]} layers
|
|
311
|
+
*/
|
|
312
|
+
export const removeUnneededProperties = (layers) => {
|
|
313
|
+
const cloned = structuredClone(layers);
|
|
314
|
+
cloned.forEach((layer) => {
|
|
315
|
+
const id = layer.properties.id;
|
|
316
|
+
const title = layer.properties.title;
|
|
317
|
+
layer.properties = { id, title };
|
|
318
|
+
if (layer["interactions"]) {
|
|
319
|
+
delete layer["interactions"]
|
|
320
|
+
}
|
|
321
|
+
if (layer.type === "Group") {
|
|
322
|
+
layer.layers = removeUnneededProperties(layer.layers);
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
return cloned;
|
|
326
|
+
};
|