@eodash/eodash 5.0.0-alpha.2.17 → 5.0.0-alpha.2.18

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.
Files changed (39) hide show
  1. package/core/client/App.vue +2 -0
  2. package/core/client/composables/EodashMap.js +93 -40
  3. package/core/client/eodash.js +8 -9
  4. package/core/client/plugins/index.js +2 -1
  5. package/core/client/utils/createLayers.js +7 -1
  6. package/core/client/utils/eodashSTAC.js +9 -0
  7. package/core/client/utils/helpers.js +16 -11
  8. package/core/client/vite-env.d.ts +1 -0
  9. package/dist/client/{DashboardLayout-BR1lU9ER.js → DashboardLayout-Dk6lzKZA.js} +2 -2
  10. package/dist/client/{DynamicWebComponent-7z8VFsrZ.js → DynamicWebComponent-BkMCGU7a.js} +1 -1
  11. package/dist/client/EodashDatePicker-D27wn0jP.js +276 -0
  12. package/dist/client/{EodashItemFilter-lNjVkidr.js → EodashItemFilter-DS1mOc2p.js} +1 -1
  13. package/dist/client/{EodashLayerControl-B0N8_XmX.js → EodashLayerControl-BqGA6jbV.js} +2247 -2198
  14. package/dist/client/{EodashMap-DFT2R2Rk.js → EodashMap-BnVrfBnA.js} +8671 -8650
  15. package/dist/client/{EodashMapBtns-CoGjVl8Y.js → EodashMapBtns-rv-U1nI_.js} +2 -2
  16. package/dist/client/{ExportState-Dwv37MRw.js → ExportState-C3Z1ET5c.js} +40 -40
  17. package/dist/client/{Footer-DuScuHSx.js → Footer-BBkNiqPm.js} +1 -1
  18. package/dist/client/{Header-C4Y0u0E5.js → Header-BQKHLO5P.js} +4 -4
  19. package/dist/client/{IframeWrapper-D1TfK4xH.js → IframeWrapper-BX4e2uxq.js} +1 -1
  20. package/dist/client/{MobileLayout-C-b8DIFO.js → MobileLayout-C2aqobN5.js} +6 -6
  21. package/dist/client/{PopUp-DBMZX3l3.js → PopUp-DG3zrW12.js} +15 -15
  22. package/dist/client/{VImg-bAMQHnMM.js → VImg-BLpHACcB.js} +2 -2
  23. package/dist/client/{VMain-Df5VMG9r.js → VMain-DOyRcpub.js} +2 -2
  24. package/dist/client/{VOverlay-D5GzAYRY.js → VOverlay-DAiInZQP.js} +32 -32
  25. package/dist/client/{WidgetsContainer-yZDmY6_u.js → WidgetsContainer-BqoX7R5Z.js} +3 -3
  26. package/dist/client/{asWebComponent-DhR2_xlP.js → asWebComponent-tNU8_fkz.js} +1210 -1184
  27. package/dist/client/eo-dash.js +1 -1
  28. package/dist/client/{forwardRefs-C0MQxvur.js → forwardRefs-BexjzXbg.js} +1 -1
  29. package/dist/client/{index-qNWeBhRh.js → index-F73os72i.js} +23 -23
  30. package/dist/client/{lerc-B4lXefGh-CsL-d8wY.js → lerc-B4lXefGh-DhdntrgS.js} +1 -1
  31. package/dist/client/{ssrBoot-Xmkz8T49.js → ssrBoot-C71RpKe4.js} +1 -1
  32. package/dist/client/style.css +1 -1
  33. package/dist/client/{transition-DRzZPWIN.js → transition-DNdd2Y-1.js} +1 -1
  34. package/dist/client/{webfontloader-CqD-lAx-.js → webfontloader-C7dpDL7m.js} +1 -1
  35. package/package.json +4 -5
  36. package/widgets/EodashDatePicker.vue +24 -12
  37. package/widgets/EodashLayerControl.vue +3 -1
  38. package/widgets/EodashMap.vue +43 -25
  39. package/dist/client/EodashDatePicker-o7ZOYIHL.js +0 -259
@@ -15,6 +15,8 @@ import Dashboard from "@/views/Dashboard.vue";
15
15
  import ErrorAlert from "./components/ErrorAlert.vue";
16
16
  import { onErrorCaptured, ref } from "vue";
17
17
 
18
+ // window.setEodashLoglevel("DEBUG")
19
+
18
20
  const error = ref("");
19
21
  onErrorCaptured((e, inst, info) => {
20
22
  error.value = `
@@ -2,6 +2,16 @@ import { EodashCollection } from "@/utils/eodashSTAC";
2
2
  import { setMapProjFromCol } from "@/utils/helpers";
3
3
  import { onMounted, onUnmounted, watch } from "vue";
4
4
  import log from "loglevel";
5
+ import { datetime } from "@/store/States";
6
+ import { useSTAcStore } from "@/store/stac";
7
+ import { storeToRefs } from "pinia";
8
+
9
+ /**
10
+ * Holder for previous compare map view as it is overwritten by sync
11
+ * @type { {map:import("ol").View } | null} mapElement
12
+ */
13
+ let viewHolder = null;
14
+
5
15
  /**
6
16
  * Description placeholder
7
17
  *
@@ -55,9 +65,17 @@ const updateLayersConfig = async (
55
65
  eodashCols,
56
66
  updatedTime,
57
67
  );
68
+ const dataLayersGroup = layersCollection?.find(
69
+ (lyr) => lyr?.properties.id === "AnalysisGroup",
70
+ );
58
71
  /** @type {Record<string,any>[]} */
59
72
  const analysisLayers = [];
60
73
 
74
+ if (!dataLayersGroup) {
75
+ log.debug("no AnalysisGroup layer found to be updated");
76
+ return layersCollection;
77
+ }
78
+
61
79
  for (const ec of eodashCols) {
62
80
  let layers;
63
81
  if (updatedTime) {
@@ -76,12 +94,7 @@ const updateLayersConfig = async (
76
94
  dl.properties.layerControlToolsExpand = true;
77
95
  });
78
96
 
79
- const dataLayersGroup = layersCollection?.find(
80
- (lyr) => lyr?.properties.id === "AnalysisGroup",
81
- );
82
- if (dataLayersGroup) {
83
- dataLayersGroup.layers = analysisLayers;
84
- }
97
+ dataLayersGroup.layers = analysisLayers;
85
98
 
86
99
  return layersCollection;
87
100
  };
@@ -202,6 +215,18 @@ const createLayersConfig = async (selectedIndicator) => {
202
215
  layersCollection.unshift(overlayLayers);
203
216
  }
204
217
 
218
+ // We try to set the current time selection
219
+ // to latest extent date
220
+ // @ts-expect-error it seems the temporal extent is not defined in type
221
+ const interval = selectedIndicator?.extent?.temporal?.interval;
222
+ if (interval && interval.length > 0 && interval[0].length > 1) {
223
+ const endInterval = new Date(interval[0][1]);
224
+ log.debug(
225
+ "Datepicker: found stac extent, setting time to latest value",
226
+ endInterval,
227
+ );
228
+ datetime.value = endInterval.toISOString();
229
+ }
205
230
  return layersCollection;
206
231
  };
207
232
 
@@ -212,12 +237,16 @@ const createLayersConfig = async (selectedIndicator) => {
212
237
  * @param {import("vue").Ref<import("stac-ts").StacCollection | null>} selectedIndicator
213
238
  * @param {EodashCollection[]} eodashCols
214
239
  * @param {import("vue").Ref<string>} datetime
240
+ * @param {import("vue").Ref<Record<string,any>[]>} mapLayers
241
+ * @param {import("vue").Ref<HTMLElement & Record<string,any> | null>} partnerMap
215
242
  */
216
243
  export const useInitMap = (
217
244
  mapElement,
218
245
  selectedIndicator,
219
246
  eodashCols,
220
247
  datetime,
248
+ mapLayers,
249
+ partnerMap,
221
250
  ) => {
222
251
  log.debug(
223
252
  "InitMap",
@@ -228,21 +257,62 @@ export const useInitMap = (
228
257
  );
229
258
 
230
259
  const stopIndicatorWatcher = watch(
231
- selectedIndicator,
232
- async (updatedStac) => {
233
- log.debug(
234
- "SelectedIndicator watch triggered",
235
- selectedIndicator,
236
- updatedStac,
237
- );
260
+ [selectedIndicator, datetime],
261
+ async ([updatedStac, updatedTime], [previousStac, previousTime]) => {
238
262
  if (updatedStac) {
239
- const layersCollection = await createLayersConfig(updatedStac);
263
+ if (mapElement?.value?.id === "main") {
264
+ // Making sure main map gets the viewer that seems to be
265
+ // removed when the second map is no longer rendered
266
+ if (viewHolder !== null) {
267
+ mapElement?.value?.map.setView(viewHolder);
268
+ viewHolder = null;
269
+ }
270
+ }
271
+ log.debug(
272
+ "Selected Indicator watch triggered",
273
+ updatedStac,
274
+ updatedTime,
275
+ );
276
+ let layersCollection = [];
240
277
 
241
- // updates layersCollection in place
242
- await updateLayersConfig(layersCollection, eodashCols, datetime.value);
278
+ const onlyTimeChanged =
279
+ updatedStac?.id === previousStac?.id && updatedTime !== previousTime;
280
+
281
+ const { selectedCompareStac } = storeToRefs(useSTAcStore());
282
+ if (mapElement?.value?.id === "main") {
283
+ // Main map being initialized
284
+ // Set projection based on indicator level information for both maps
285
+ await setMapProjFromCol(updatedStac);
286
+ } else {
287
+ // Compare map being initialized
288
+ if (selectedCompareStac.value !== null) {
289
+ // save old view to set later
290
+ viewHolder = mapElement?.value?.map.getView();
291
+ /** @type {any} */
292
+ (mapElement.value).sync = partnerMap.value;
293
+ }
294
+ }
295
+
296
+ if (onlyTimeChanged) {
297
+ layersCollection =
298
+ (await updateLayersConfig(
299
+ [...(mapElement.value?.layers ?? [])].reverse(),
300
+ eodashCols,
301
+ updatedTime,
302
+ )) ?? [];
303
+ log.debug(
304
+ "Assigned layers after changing time only",
305
+ JSON.parse(JSON.stringify(layersCollection)),
306
+ );
307
+ mapLayers.value = layersCollection;
308
+ return;
309
+ }
310
+
311
+ /** @type {Record<string,any>[]} */
312
+ layersCollection = await createLayersConfig(updatedStac);
243
313
 
244
- // Set projection based on indicator level information
245
- setMapProjFromCol(updatedStac);
314
+ // updates layersCollection in place
315
+ await updateLayersConfig(layersCollection, eodashCols, updatedTime);
246
316
 
247
317
  // Try to move map view to extent
248
318
  // Sanitize extent,
@@ -253,6 +323,7 @@ export const useInitMap = (
253
323
  b[2] < 180 ? b[2] : 180,
254
324
  b[3] < 90 ? b[3] : 90,
255
325
  ];
326
+
256
327
  const reprojExtent = mapElement.value?.transformExtent(
257
328
  sanitizedExtent,
258
329
  "EPSG:4326",
@@ -261,36 +332,18 @@ export const useInitMap = (
261
332
  /** @type {any} */
262
333
  (mapElement.value).zoomExtent = reprojExtent;
263
334
 
264
- // TODO: resetting layers to empty array first because smart layer update has issues
265
335
  log.debug(
266
- "WARN: Map configuration being completely, should be changed once smart update of config is reworked",
336
+ "Assigned layers",
337
+ JSON.parse(JSON.stringify(layersCollection)),
267
338
  );
268
- /** @type {any} */
269
- (mapElement.value).layers = [];
270
- /** @type {any} */
271
- (mapElement.value).layers = layersCollection;
272
- }
273
- },
274
- { immediate: true },
275
- );
276
339
 
277
- const stopDatetimeWatcher = watch(
278
- datetime,
279
- async (updatedTime, previousTime) => {
280
- if (updatedTime && updatedTime !== previousTime) {
281
- const layersCollection = await updateLayersConfig(
282
- [...(mapElement.value?.layers ?? [])],
283
- eodashCols,
284
- updatedTime,
285
- );
286
- /** @type {any} */
287
- (mapElement.value).layers = layersCollection?.reverse();
340
+ mapLayers.value = layersCollection;
288
341
  }
289
342
  },
343
+ { immediate: true },
290
344
  );
291
345
 
292
346
  onUnmounted(() => {
293
347
  stopIndicatorWatcher();
294
- stopDatetimeWatcher();
295
348
  });
296
349
  };
@@ -1,9 +1,5 @@
1
1
  import { reactive } from "vue";
2
2
  import { currentUrl } from "./store/States";
3
- import log from "loglevel";
4
-
5
- /* set log level */
6
- log.setLevel("debug", true);
7
3
 
8
4
  /**
9
5
  * Reactive Edoash Instance Object. provided globally in the app, and used as an
@@ -13,9 +9,8 @@ log.setLevel("debug", true);
13
9
  */
14
10
  export const eodash = reactive({
15
11
  id: "demo",
16
- stacEndpoint: "https://gtif-cerulean.github.io/catalog/cerulean/catalog.json",
17
- // stacEndpoint: "https://eodashcatalog.eox.at/test-style/trilateral/catalog.json",
18
- //stacEndpoint: "https://eurodatacube.github.io/eodash-catalog/RACE/catalog.json",
12
+ stacEndpoint:
13
+ "https://eodashcatalog.eox.at/test-style/trilateral/catalog.json",
19
14
  brand: {
20
15
  noLayout: true,
21
16
  name: "Demo",
@@ -59,7 +54,7 @@ export const eodash = reactive({
59
54
  id: Symbol(),
60
55
  type: "internal",
61
56
  title: "Indicators",
62
- layout: { x: 0, y: 0, w: 3, h: 8 },
57
+ layout: { x: 0, y: 0, w: 3, h: 6 },
63
58
  widget: {
64
59
  name: "EodashItemFilter",
65
60
  properties: {
@@ -72,7 +67,7 @@ export const eodash = reactive({
72
67
  id: Symbol(),
73
68
  type: "internal",
74
69
  title: "Layer Control",
75
- layout: { x: 0, y: 8, w: 3, h: 4 },
70
+ layout: { x: 0, y: 6, w: 3, h: 6 },
76
71
  widget: {
77
72
  name: "EodashLayerControl",
78
73
  },
@@ -128,6 +123,10 @@ export const eodash = reactive({
128
123
  title: "Datepicker",
129
124
  widget: {
130
125
  name: "EodashDatePicker",
126
+ properties: {
127
+ hintText: `<b>Hint:</b> closest available date is displayed <br />
128
+ on map (see Analysis Layers)`,
129
+ },
131
130
  },
132
131
  }
133
132
  : null;
@@ -4,13 +4,14 @@ import eodash from "@/eodash";
4
4
  import VCalendar from "v-calendar";
5
5
  import { eodashKey } from "@/utils/keys";
6
6
  import store from "../store";
7
+ import log from "loglevel";
7
8
 
8
9
  export const pinia = createPinia();
9
10
 
10
11
  /** @param {import("vue").App} app */
11
12
  export function registerPlugins(app) {
12
13
  window.eodashStore = store;
13
-
14
+ window.setEodashLoglevel = log.setLevel;
14
15
  app
15
16
  .use(vuetify)
16
17
  .use(pinia)
@@ -72,7 +72,7 @@ export async function createLayersFromAssets(
72
72
 
73
73
  if (geoTIFFSources.length && typeof geoTIFFIdx === "number") {
74
74
  const geotiffSourceID = collectionId + ";:;GeoTIFF";
75
- log.debug("Creating Vector layer from GeoJSON", geotiffSourceID);
75
+ log.debug("Creating WebGLTile layer from GeoTIFF", geotiffSourceID);
76
76
  log.debug("Configured Sources", geoTIFFSources);
77
77
  const layer = {
78
78
  type: "WebGLTile",
@@ -100,12 +100,14 @@ export async function createLayersFromAssets(
100
100
  * @param {import('stac-ts').StacItem} item
101
101
  * @param {string} title
102
102
  * @param {Record<string,any>} [layerDatetime]
103
+ * @param {string | null} [legendInfo]
103
104
  */
104
105
  export const createLayersFromLinks = async (
105
106
  collectionId,
106
107
  title,
107
108
  item,
108
109
  layerDatetime,
110
+ legendInfo,
109
111
  ) => {
110
112
  log.debug("Creating layers from links");
111
113
  /** @type {Record<string,any>[]} */
@@ -155,6 +157,10 @@ export const createLayersFromLinks = async (
155
157
  // Expand all dimensions into the params attribute
156
158
  Object.assign(json.source.params, wmsLink["wms:dimensions"]);
157
159
  }
160
+ if (legendInfo !== null) {
161
+ // @ts-expect-error once we have a eox-map config type we can remove this
162
+ json.properties.description = legendInfo;
163
+ }
158
164
  jsonArray.push(json);
159
165
  }
160
166
 
@@ -183,11 +183,20 @@ export class EodashCollection {
183
183
  Object.keys(dataAssets).length;
184
184
 
185
185
  if (isSupported) {
186
+ // Checking for potential legend asset
187
+ let legendInfo = null;
188
+ if (this.#collectionStac?.assets?.legend?.href) {
189
+ legendInfo = `
190
+ <div style="text-align:center; width: 100%">
191
+ <img src="${this.#collectionStac.assets.legend.href}" style="max-height:70px; margin-top:-15px; margin-bottom:-20px;" />
192
+ </div>`;
193
+ }
186
194
  const links = await createLayersFromLinks(
187
195
  this.#collectionStac?.id ?? "",
188
196
  title,
189
197
  item,
190
198
  layerDatetime,
199
+ legendInfo,
191
200
  );
192
201
  jsonArray.push(
193
202
  ...links,
@@ -49,8 +49,14 @@ export function extractLayerConfig(style) {
49
49
  let layerConfig = undefined;
50
50
  if (style?.jsonform) {
51
51
  layerConfig = { schema: style.jsonform, type: "style" };
52
+ style = { ...style };
52
53
  delete style.jsonform;
53
54
  }
55
+ log.debug(
56
+ "extracted layerConfig",
57
+ JSON.parse(JSON.stringify({ layerConfig, style })),
58
+ );
59
+
54
60
  return { layerConfig, style };
55
61
  }
56
62
 
@@ -59,7 +65,7 @@ export function extractLayerConfig(style) {
59
65
  * updates {@link availableMapProjection}
60
66
  * @param {import('stac-ts').StacCollection} [STAcCollection]
61
67
  */
62
- export const setMapProjFromCol = (STAcCollection) => {
68
+ export const setMapProjFromCol = async (STAcCollection) => {
63
69
  // if a projection exists on the collection level
64
70
  log.debug("Checking for available map projection in indicator");
65
71
  const projection =
@@ -71,25 +77,22 @@ export const setMapProjFromCol = (STAcCollection) => {
71
77
  );
72
78
  if (projection) {
73
79
  log.debug("Projection found", projection);
74
- registerProjection(projection);
80
+ await registerProjection(projection);
75
81
  const projectionCode = getProjectionCode(projection);
76
- if (
77
- availableMapProjection.value &&
78
- availableMapProjection.value !== projectionCode
79
- ) {
82
+ if (availableMapProjection.value !== projectionCode) {
80
83
  log.debug(
81
84
  "Changing map projection",
82
85
  availableMapProjection.value,
83
86
  projectionCode,
84
87
  );
85
- changeMapProjection(projection);
88
+ await changeMapProjection(projection);
86
89
  }
87
90
  // set it for `EodashMapBtns`
88
91
  availableMapProjection.value = /** @type {string} */ (projectionCode);
89
92
  } else {
90
93
  // reset to default projection
91
- log.debug("Resetting projection to default");
92
- changeMapProjection((availableMapProjection.value = "EPSG:3857"));
94
+ log.debug("Resetting projection to default EPSG:3857");
95
+ await changeMapProjection((availableMapProjection.value = ""));
93
96
  }
94
97
  };
95
98
 
@@ -163,7 +166,9 @@ export const fetchStyle = async (item, itemUrl) => {
163
166
 
164
167
  /** @type {import("ol/layer/WebGLTile").Style & {jsonform?:Record<string,any>}} */
165
168
  const styleJson = await axios.get(url).then((resp) => resp.data);
166
- return styleJson;
169
+
170
+ log.debug("fetched styles JSON", JSON.parse(JSON.stringify(styleJson)));
171
+ return { ...styleJson };
167
172
  }
168
173
  };
169
174
 
@@ -232,7 +237,7 @@ export const extractLayerDatetime = (links, currentStep) => {
232
237
  return {
233
238
  controlValues,
234
239
  currentStep,
235
- slider: false,
240
+ slider: true,
236
241
  disablePlay: true,
237
242
  };
238
243
  };
@@ -7,6 +7,7 @@ declare module "*.vue" {
7
7
  }
8
8
  declare interface Window {
9
9
  eodashStore: import("@/types").EodashStore;
10
+ setEodashLoglevel: typeof import("loglevel").setLevel;
10
11
  }
11
12
  declare module "@eox/stacinfo" {
12
13
  export const EOxStacInfo: CustomElementConstructor;
@@ -1,5 +1,5 @@
1
- import { _ as y, x as m, W as x, X as d, $ as t, a0 as r, a1 as l, a9 as _, a3 as n, a6 as u, a2 as c, a4 as p, d as h, a5 as g, F as f, a7 as v, ab as w } from "./asWebComponent-DhR2_xlP.js";
2
- import { V as k } from "./VMain-Df5VMG9r.js";
1
+ import { _ as y, x as m, W as x, X as d, $ as t, a0 as r, a1 as l, a9 as _, a3 as n, a6 as u, a2 as c, a4 as p, d as h, a5 as g, F as f, a7 as v, ab as w } from "./asWebComponent-tNU8_fkz.js";
2
+ import { V as k } from "./VMain-DOyRcpub.js";
3
3
  class A extends HTMLElement {
4
4
  static get observedAttributes() {
5
5
  return ["gap"];
@@ -1,4 +1,4 @@
1
- import { bL as i, aD as m, r as p, Z as d, aQ as f, $ as c, a6 as g, a0 as y, d as _, a4 as k } from "./asWebComponent-DhR2_xlP.js";
1
+ import { bM as i, aD as m, r as p, Z as d, aR as f, $ as c, a6 as g, a0 as y, d as _, a4 as k } from "./asWebComponent-tNU8_fkz.js";
2
2
  const h = { class: "d-flex flex-column fill-height overflow-auto" }, N = {
3
3
  __name: "DynamicWebComponent",
4
4
  props: {