@eodash/eodash 5.0.0-rc.1.5 → 5.0.0-rc.1.6

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 (51) hide show
  1. package/README.md +1 -1
  2. package/core/client/composables/EodashMap.js +19 -5
  3. package/core/client/composables/EodashProcess.js +51 -5
  4. package/core/client/eodash.js +8 -7
  5. package/core/client/eodashSTAC/EodashCollection.js +16 -0
  6. package/core/client/eodashSTAC/createLayers.js +62 -6
  7. package/core/client/eodashSTAC/helpers.js +39 -4
  8. package/core/client/types.ts +7 -0
  9. package/core/client/utils/states.js +3 -0
  10. package/dist/client/{DashboardLayout-B-4X57-t.js → DashboardLayout-SZfMDUoR.js} +2 -2
  11. package/dist/client/{DynamicWebComponent-Dj3QYwag.js → DynamicWebComponent-I9gzMY0L.js} +1 -1
  12. package/dist/client/EodashDatePicker-B9_u6TTm.js +405 -0
  13. package/dist/client/{EodashItemFilter-DBQwJQPh.js → EodashItemFilter-G7YsYO3B.js} +1 -1
  14. package/dist/client/{EodashLayerControl-C5fOCvoI.js → EodashLayerControl-CJ94ul63.js} +10 -2
  15. package/dist/client/{EodashLayoutSwitcher-BMO9k_20.js → EodashLayoutSwitcher-DRKm8A8U.js} +2 -2
  16. package/dist/client/{EodashMap-D2bnMLAC.js → EodashMap-Dp44Ajbi.js} +60 -10
  17. package/dist/client/{EodashMapBtns-l9B977id.js → EodashMapBtns-BlPFwhPc.js} +4 -4
  18. package/dist/client/{EodashProcess-BtIlJvF1.js → EodashProcess-BLmIgUGT.js} +158 -25
  19. package/dist/client/{EodashStacInfo-CPVvp_Hm.js → EodashStacInfo-BIRcfcMo.js} +1 -1
  20. package/dist/client/{EodashTools-DY2dlNXW.js → EodashTools-PNfJ-Cw3.js} +4 -4
  21. package/dist/client/{ExportState-BvD5A0XG.js → ExportState-5JyTshJH.js} +4 -4
  22. package/dist/client/{Footer-w95gBnSH.js → Footer-CM9hgdQP.js} +1 -1
  23. package/dist/client/{Header-BpiorKy9.js → Header-BTq4DW1x.js} +3 -3
  24. package/dist/client/{MobileLayout-CmVlZe7S.js → MobileLayout-Atfoxf8d.js} +5 -5
  25. package/dist/client/{PopUp-CREaSybs.js → PopUp-Bmfn3N_4.js} +3 -3
  26. package/dist/client/{VImg-DF9esgdd.js → VImg-CUF4S39i.js} +2 -2
  27. package/dist/client/{VMain-BWLMf-rn.js → VMain-CQpXnzDR.js} +1 -1
  28. package/dist/client/{VOverlay-DmNfblmy.js → VOverlay-DUnITwM1.js} +3 -3
  29. package/dist/client/{VTooltip-C3PeE7iO.js → VTooltip-BYTlbKer.js} +3 -3
  30. package/dist/client/{WidgetsContainer-6FHEEXns.js → WidgetsContainer-BPbgxdb0.js} +1 -1
  31. package/dist/client/{asWebComponent-BnFMd0T6.js → asWebComponent-DW1XzZkL.js} +139 -29
  32. package/dist/client/eo-dash.css +1 -1
  33. package/dist/client/eo-dash.js +1 -1
  34. package/dist/client/{forwardRefs-BF3Me2RX.js → forwardRefs-gx1Fzngc.js} +1 -1
  35. package/dist/client/{index-CRd5-RSy.js → index-DvFppNyk.js} +1 -1
  36. package/dist/client/{transition-Cpn_g5jE.js → transition-j2eWJYMg.js} +1 -1
  37. package/dist/types/core/client/composables/EodashMap.d.ts +2 -1
  38. package/dist/types/core/client/composables/EodashProcess.d.ts +17 -11
  39. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +9 -4
  40. package/dist/types/core/client/eodashSTAC/createLayers.d.ts +6 -6
  41. package/dist/types/core/client/eodashSTAC/helpers.d.ts +75 -20
  42. package/dist/types/core/client/types.d.ts +10 -0
  43. package/dist/types/core/client/utils/states.d.ts +2 -0
  44. package/dist/types/widgets/EodashDatePicker.vue.d.ts +4 -2
  45. package/dist/types/widgets/PopUp.vue.d.ts +1 -2
  46. package/package.json +8 -8
  47. package/widgets/EodashDatePicker.vue +89 -6
  48. package/widgets/EodashLayerControl.vue +13 -1
  49. package/widgets/EodashMap.vue +51 -5
  50. package/widgets/EodashProcess.vue +57 -11
  51. package/dist/client/EodashDatePicker-DGRJrJ0s.js +0 -306
package/README.md CHANGED
@@ -44,7 +44,7 @@ npm run build -- --lib
44
44
  ├── core # CLI & Client source code
45
45
  ├── docs # Documentation files
46
46
  ├── tests # CLI & Client component tests folder
47
- ├── widgets # Vue componenets as internal widgets.
47
+ ├── widgets # Vue components as internal widgets.
48
48
  ├── public # Statically served directory
49
49
  └── README.md
50
50
 
@@ -7,9 +7,10 @@ import { storeToRefs } from "pinia";
7
7
  import { useEventBus } from "@vueuse/core";
8
8
  import { eoxLayersKey } from "@/utils/keys";
9
9
  import { posIsSetFromUrl } from "@/utils/states";
10
+ import { useOnLayersUpdate } from ".";
10
11
  /**
11
12
  * Holder for previous compare map view as it is overwritten by sync
12
- * @type { {map:import("ol").View } | null} mapElement
13
+ * @type { import("ol").View | null} mapElement
13
14
  */
14
15
  let viewHolder = null;
15
16
 
@@ -203,12 +204,12 @@ const createLayersConfig = async (
203
204
  /**
204
205
  * Initializes the map and updates it based on changes in the selected indicator and datetime,
205
206
  *
206
- * @param {import("vue").Ref<HTMLElement & Record<string,any> | null>} mapElement
207
+ * @param {import("vue").Ref<import("@eox/map").EOxMap| null>} mapElement
207
208
  * @param {import("vue").Ref<import("stac-ts").StacCollection | null>} selectedIndicator
208
209
  * @param {EodashCollection[]} eodashCols
209
210
  * @param {import("vue").Ref<string>} datetime
210
211
  * @param {import("vue").Ref<Record<string,any>[]>} mapLayers
211
- * @param {import("vue").Ref<HTMLElement & Record<string,any> | null>} partnerMap
212
+ * @param {import("vue").Ref<import("@eox/map").EOxMap| null>} partnerMap
212
213
  */
213
214
  export const useInitMap = (
214
215
  mapElement,
@@ -260,7 +261,7 @@ export const useInitMap = (
260
261
  // Compare map being initialized
261
262
  if (selectedCompareStac.value !== null) {
262
263
  // save view of compare map
263
- viewHolder = mapElement?.value?.map.getView();
264
+ viewHolder = mapElement?.value?.map.getView() ?? null;
264
265
  /** @type {any} */
265
266
  (mapElement.value).sync = partnerMap.value;
266
267
  }
@@ -341,7 +342,6 @@ export const useInitMap = (
341
342
  "Assigned layers",
342
343
  JSON.parse(JSON.stringify(layersCollection)),
343
344
  );
344
-
345
345
  mapLayers.value = layersCollection;
346
346
  // Emit event to update layers
347
347
  await nextTick(() => {
@@ -358,3 +358,17 @@ export const useInitMap = (
358
358
  stopIndicatorWatcher();
359
359
  });
360
360
  };
361
+ /**
362
+ *
363
+ * @param {EodashCollection[]} eodashCols
364
+ * @param {import("vue").Ref<import("@/types").EodashStyleJson["tooltip"]>} tooltipProperties
365
+ */
366
+ export const useUpdateTooltipProperties = (eodashCols, tooltipProperties) => {
367
+ useOnLayersUpdate(async () => {
368
+ tooltipProperties.value = [];
369
+ for (const ec of eodashCols) {
370
+ tooltipProperties.value.push(...(await ec.getToolTipProperties()));
371
+ }
372
+ log.debug("Updated tooltip properties", tooltipProperties.value);
373
+ });
374
+ };
@@ -48,6 +48,10 @@ export async function pollProcessStatus({
48
48
  console.log("Result file fetched successfully:", resultResponse.data);
49
49
  return resultResponse.data; // Return the json result list
50
50
  }
51
+ if (processReport.status === "failed") {
52
+ isPolling.value = false;
53
+ throw new Error("Process failed.", processReport);
54
+ }
51
55
 
52
56
  // Log the current status if not successful
53
57
  console.log(
@@ -370,7 +374,7 @@ export async function processGeoTiff(links, jsonformValue, layerId, isPolling) {
370
374
  * @param {import("stac-ts").StacLink[] | undefined} links
371
375
  * @param {Record<string,any> | undefined} jsonformValue
372
376
  * @param {string} specUrl
373
- * @returns {Promise<[import("vega").Spec|null,Record<string,any>|null]>}
377
+ * @returns {Promise<[import("@eox/chart").EOxChart["spec"] | null,Record<string,any>|null]>}
374
378
  **/
375
379
  export async function getChartValues(links, jsonformValue, specUrl) {
376
380
  if (!specUrl || !links) return [null, null];
@@ -419,9 +423,10 @@ export async function getChartValues(links, jsonformValue, specUrl) {
419
423
  * @param {import("vue").Ref<import("stac-ts").StacCollection | null>} params.selectedStac
420
424
  * @param {import("vue").Ref<import("@eox/jsonform").EOxJSONForm | null>} params.jsonformEl
421
425
  * @param {import("vue").Ref<Record<string,any>|null>} params.jsonformSchema
422
- * @param {import("vue").Ref<import("@eox/chart").EOxChart["spec"]>} params.chartSpec
426
+ * @param {import("vue").Ref<import("@eox/chart").EOxChart["spec"] | null>} params.chartSpec
423
427
  * @param {import("vue").Ref<Record<string, any> | null>} params.chartData
424
428
  * @param {import("vue").Ref<boolean>} params.isPolling
429
+ * @param {import("vue").Ref<any[]>} params.processResults
425
430
  */
426
431
  export async function handleProcesses({
427
432
  loading,
@@ -431,6 +436,7 @@ export async function handleProcesses({
431
436
  chartSpec,
432
437
  chartData,
433
438
  isPolling,
439
+ processResults,
434
440
  }) {
435
441
  log.debug("Processing...");
436
442
  loading.value = true;
@@ -456,22 +462,50 @@ export async function handleProcesses({
456
462
  { ...(jsonformValue ?? {}) },
457
463
  specUrl,
458
464
  );
465
+ if (Object.keys(chartData.value ?? {}).length) {
466
+ processResults.value.push(chartData.value);
467
+ }
468
+ //@ts-expect-error we assume that the spec data is of type InlineData
469
+ if (chartSpec.value?.data?.values?.length) {
470
+ //@ts-expect-error we assume that the spec data is of type InlineData
471
+ processResults.value.push(chartSpec.value?.data.values);
472
+ }
473
+
459
474
  if (chartSpec.value && !("background" in chartSpec.value)) {
460
475
  chartSpec.value["background"] = "transparent";
461
476
  }
477
+
462
478
  const geotiffLayer = await processGeoTiff(
463
479
  serviceLinks,
464
480
  jsonformValue,
465
481
  selectedStac.value?.id ?? "",
466
482
  isPolling,
467
483
  );
484
+
485
+ if (geotiffLayer && geotiffLayer.source?.sources.length) {
486
+ processResults.value.push(
487
+ ...(geotiffLayer.source?.sources?.map((source) => source.url) ?? []),
488
+ );
489
+ }
490
+ // 3. vector geojson
468
491
  const vectorLayers = await processVector(
469
492
  serviceLinks,
470
493
  jsonformValue,
471
494
  selectedStac.value?.id ?? "",
472
495
  );
473
496
 
497
+ if (vectorLayers?.length) {
498
+ processResults.value.push(
499
+ ...vectorLayers.map((layer) => layer.source?.url),
500
+ );
501
+ }
502
+
474
503
  const imageLayers = processImage(serviceLinks, jsonformValue, origBbox);
504
+ if (imageLayers?.length) {
505
+ processResults.value.push(
506
+ ...imageLayers.map((layer) => layer.source?.url),
507
+ );
508
+ }
475
509
 
476
510
  log.debug(
477
511
  "rendered layers after processing:",
@@ -509,8 +543,9 @@ export async function handleProcesses({
509
543
  * @param {Object} params
510
544
  * @param {import("vue").Ref<boolean>} params.loading
511
545
  * @param {import("vue").Ref<boolean>} params.isProcessed
512
- * @param {import("vue").Ref<import("@eox/chart").EOxChart["spec"]>} params.chartSpec
546
+ * @param {import("vue").Ref<import("@eox/chart").EOxChart["spec"] | null>} params.chartSpec
513
547
  * @param {import("vue").Ref<boolean>} params.isPolling
548
+ * @param {import("vue").Ref<any[]>} params.processResults
514
549
  * @param {import("vue").Ref<Record<string,any>|null>} params.jsonformSchema
515
550
  */
516
551
  export function resetProcess({
@@ -518,12 +553,14 @@ export function resetProcess({
518
553
  isProcessed,
519
554
  chartSpec,
520
555
  jsonformSchema,
556
+ processResults,
521
557
  isPolling,
522
558
  }) {
523
559
  loading.value = false;
524
560
  isProcessed.value = false;
525
561
  isPolling.value = false;
526
562
  chartSpec.value = null;
563
+ processResults.value = [];
527
564
  jsonformSchema.value = null;
528
565
  }
529
566
 
@@ -536,7 +573,8 @@ export function resetProcess({
536
573
  * @param {import("vue").Ref<import("stac-ts").StacCollection>} params.selectedStac
537
574
  * @param {import("vue").Ref<import("@eox/jsonform").EOxJSONForm | null>} params.jsonformEl
538
575
  * @param {import("vue").Ref<Record<string,any> | null>} params.jsonformSchema
539
- * @param {import("vue").Ref<import("@eox/chart").EOxChart["spec"]>} params.chartSpec
576
+ * @param {import("vue").Ref<import("@eox/chart").EOxChart["spec"] | null>} params.chartSpec
577
+ * @param {import("vue").Ref<any[]>} params.processResults
540
578
  * @param {import("vue").Ref<boolean>} params.isProcessed
541
579
  * @param {import("vue").Ref<boolean>} params.loading
542
580
  * @param {import("vue").Ref<boolean>} params.isPolling
@@ -547,13 +585,21 @@ export async function initProcess({
547
585
  jsonformSchema,
548
586
  chartSpec,
549
587
  isProcessed,
588
+ processResults,
550
589
  loading,
551
590
  isPolling,
552
591
  }) {
553
592
  if (!selectedStac.value) {
554
593
  return;
555
594
  }
556
- resetProcess({ loading, isProcessed, chartSpec, jsonformSchema, isPolling });
595
+ resetProcess({
596
+ loading,
597
+ isProcessed,
598
+ chartSpec,
599
+ jsonformSchema,
600
+ isPolling,
601
+ processResults,
602
+ });
557
603
  if (selectedStac.value["eodash:jsonform"]) {
558
604
  jsonformEl.value?.editor.destroy();
559
605
  // wait for the layers to be rendered
@@ -12,9 +12,11 @@ export const eodash = reactive({
12
12
  stacEndpoint:
13
13
  // "https://eurodatacube.github.io/eodash-catalog/RACE/catalog.json",
14
14
  // "https://gtif-cerulean.github.io/catalog/cerulean/catalog.json",
15
- "https://eodashcatalog.eox.at/samplecatalog/samples/catalog.json",
16
- // "https://eodashcatalog.eox.at/test-style/trilateral/catalog.json",
17
- // "https://gtif-cerulean.github.io/catalog/cerulean/catalog.json",
15
+ // "https://eodashcatalog.eox.at/samplecatalog/samples/catalog.json",
16
+ // "https://eodashcatalog.eox.at/test-style/trilateral/catalog.json",
17
+ // "https://gtif-cerulean.github.io/catalog/cerulean/catalog.json",
18
+ // "https://gtif-cerulean.github.io/deside-catalog/deside/catalog.json",
19
+ "https://gtif-cerulean.github.io/cerulean-catalog/cerulean/catalog.json",
18
20
  brand: {
19
21
  noLayout: true,
20
22
  name: "Demo",
@@ -145,10 +147,9 @@ export const eodash = reactive({
145
147
  widget: {
146
148
  name: "EodashDatePicker",
147
149
  properties: {
148
- hideArrows: true,
149
- hideInputField: true,
150
150
  hintText: `<b>Hint:</b> closest available date is displayed <br />
151
151
  on map (see Analysis Layers)`,
152
+ toggleCalendar: true,
152
153
  },
153
154
  },
154
155
  }
@@ -272,10 +273,10 @@ export const eodash = reactive({
272
273
  defineWidget: (selectedSTAC) =>
273
274
  selectedSTAC?.links.some((l) => l.rel === "service")
274
275
  ? {
275
- id: Symbol(),
276
+ id: "Processes",
276
277
  type: "internal",
277
278
  title: "Processes",
278
- layout: { x: 0, y: 7, w: 3, h: 5 },
279
+ layout: { x: 9, y: 7, w: 3, h: 5 },
279
280
  widget: {
280
281
  name: "EodashProcess",
281
282
  },
@@ -31,6 +31,9 @@ export class EodashCollection {
31
31
  */
32
32
  selectedItem;
33
33
 
34
+ /** @type {import("@/types").EodashStyleJson["tooltip"]} */
35
+ #tooltipProperties = [];
36
+
34
37
  // read only
35
38
  get collectionStac() {
36
39
  return this.#collectionStac;
@@ -290,6 +293,19 @@ export class EodashCollection {
290
293
  : this.getItems()?.at(-1);
291
294
  }
292
295
 
296
+ async getToolTipProperties() {
297
+ if (!(this.selectedItem instanceof Item)) {
298
+ return [];
299
+ }
300
+ let styles = await fetchStyle(
301
+ this.selectedItem,
302
+ `${this.#collectionUrl}/${this.selectedItem.id}`,
303
+ );
304
+ const { tooltip } = styles || { tooltip: [] };
305
+ this.#tooltipProperties = tooltip ?? [];
306
+ return this.#tooltipProperties;
307
+ }
308
+
293
309
  /**
294
310
  *
295
311
  * @param {string} datetime
@@ -5,6 +5,7 @@ import {
5
5
  getProjectionCode,
6
6
  createLayerID,
7
7
  createAssetID,
8
+ mergeGeojsons,
8
9
  } from "./helpers";
9
10
  import log from "loglevel";
10
11
 
@@ -13,7 +14,7 @@ import log from "loglevel";
13
14
  * @param {string} title
14
15
  * @param {Record<string,import("stac-ts").StacAsset>} assets
15
16
  * @param {import("stac-ts").StacItem } item
16
- * @param {import("ol/layer/WebGLTile").Style} [style]
17
+ * @param {import("@/types").EodashStyleJson} [style]
17
18
  * @param {Record<string, unknown>} [layerConfig]
18
19
  * @param {Record<string, unknown>} [layerDatetime]
19
20
  * @param {object | null} [extraProperties]
@@ -33,6 +34,11 @@ export async function createLayersFromAssets(
33
34
  let geoTIFFSources = [];
34
35
  /** @type {number|null} */
35
36
  let geoTIFFIdx = null;
37
+ // let geoJsonLayers = [];
38
+ let geoJsonIdx = 0;
39
+
40
+ const geoJsonSources = [];
41
+ let geoJsonRoles = {};
36
42
 
37
43
  for (const [idx, ast] of Object.keys(assets).entries()) {
38
44
  // register projection if exists
@@ -41,15 +47,18 @@ export async function createLayersFromAssets(
41
47
  assets[ast]?.["proj:epsg"] || assets[ast]?.["eodash:proj4_def"]
42
48
  );
43
49
  await registerProjection(assetProjection);
44
-
45
- if (assets[ast]?.type === "application/geo+json" || assets[ast]?.type === "application/vnd.flatgeobuf") {
50
+ if (assets[ast]?.type === "application/geo+json") {
51
+ geoJsonSources.push(assets[ast].href);
52
+ geoJsonIdx = idx;
53
+ extractRoles(geoJsonRoles, assets[ast]);
54
+ } else if (assets[ast]?.type === "application/vnd.flatgeobuf") {
46
55
  const assetId = createAssetID(collectionId, item.id, idx);
47
- const sourceType = assets[ast]?.type === "application/geo+json" ? "GeoJSON" : "FlatGeoBuf";
48
- log.debug(`Creating Vector layer from ${sourceType}`, assetId);
56
+ log.debug(`Creating Vector layer from FlatGeoBuf`, assetId);
57
+
49
58
  const layer = {
50
59
  type: "Vector",
51
60
  source: {
52
- type: sourceType,
61
+ type: "FlatGeoBuf",
53
62
  url: assets[ast].href,
54
63
  format: "GeoJSON",
55
64
  },
@@ -66,6 +75,23 @@ export async function createLayersFromAssets(
66
75
  },
67
76
  ...(!style?.variables && { style }),
68
77
  };
78
+ // add tooltip interaction if style has tooltip
79
+ if (style?.tooltip) {
80
+ // @ts-expect-error no type for eox-map layer
81
+ layer.interactions = [
82
+ {
83
+ type: "select",
84
+ options: {
85
+ id: "selectInteraction",
86
+ condition: "pointermove",
87
+ style: {
88
+ "stroke-color": "#335267",
89
+ "stroke-width": 4,
90
+ },
91
+ },
92
+ },
93
+ ];
94
+ }
69
95
 
70
96
  extractRoles(layer.properties, assets[ast]);
71
97
 
@@ -78,6 +104,36 @@ export async function createLayersFromAssets(
78
104
  }
79
105
  }
80
106
 
107
+ if (geoJsonSources.length) {
108
+ const assetId = createAssetID(collectionId, item.id, geoJsonIdx);
109
+ log.debug(`Creating Vector layer from GeoJsons`, assetId);
110
+
111
+ const layer = {
112
+ type: "Vector",
113
+ source: {
114
+ type: "Vector",
115
+ url: await mergeGeojsons(geoJsonSources),
116
+ format: "GeoJSON",
117
+ },
118
+ properties: {
119
+ ...geoJsonRoles,
120
+ id: assetId,
121
+ title,
122
+ layerDatetime,
123
+ ...(layerConfig && {
124
+ layerConfig: {
125
+ ...layerConfig,
126
+ style,
127
+ },
128
+ }),
129
+ },
130
+ ...(!style?.variables && { style }),
131
+ };
132
+
133
+ layer.properties = { ...layer.properties, ...(extraProperties ?? {}) };
134
+
135
+ jsonArray.push(layer);
136
+ }
81
137
  if (geoTIFFSources.length && typeof geoTIFFIdx === "number") {
82
138
  const geotiffSourceID = collectionId + ";:;GeoTIFF";
83
139
  log.debug("Creating WebGLTile layer from GeoTIFF", geotiffSourceID);
@@ -39,13 +39,17 @@ export function generateFeatures(links) {
39
39
  /**
40
40
  * Sperates and extracts layerConfig (jsonform schema & legend) from a style json
41
41
  *
42
- * @param { import("ol/layer/WebGLTile").Style & { jsonform?: Record<string,any> } & { legend?: Record<string,any> } } [style] */
42
+ * @param { import("@/types").EodashStyleJson} [style] */
43
43
  export function extractLayerConfig(style) {
44
+ if (!style) {
45
+ return { layerConfig: undefined, style: undefined };
46
+ }
47
+ style = { ...style };
44
48
  /** @type {Record<string,unknown> | undefined} */
45
49
  let layerConfig = undefined;
50
+
46
51
  if (style?.jsonform) {
47
52
  layerConfig = { schema: style.jsonform, type: "style" };
48
- style = { ...style };
49
53
  delete style.jsonform;
50
54
  if (style?.legend) {
51
55
  layerConfig.legend = style.legend;
@@ -124,7 +128,7 @@ export const fetchStyle = async (item, itemUrl) => {
124
128
  url = toAbsolute(styleLink.href, itemUrl);
125
129
  }
126
130
 
127
- /** @type {import("ol/layer/WebGLTile").Style & {jsonform?:Record<string,any>}} */
131
+ /** @type {import("@/types").EodashStyleJson} */
128
132
  const styleJson = await axios.get(url).then((resp) => resp.data);
129
133
 
130
134
  log.debug("fetched styles JSON", JSON.parse(JSON.stringify(styleJson)));
@@ -200,8 +204,9 @@ export const extractLayerDatetime = (links, currentStep) => {
200
204
  controlValues,
201
205
  currentStep,
202
206
  slider: true,
207
+ navigation: true,
203
208
  play: false,
204
- displayFormat: "DD MMMM YYYY",
209
+ displayFormat: "DD.MM.YYYY HH:MM",
205
210
  };
206
211
  };
207
212
 
@@ -373,3 +378,33 @@ export const removeUnneededProperties = (layers) => {
373
378
  });
374
379
  return cloned;
375
380
  };
381
+
382
+ /**
383
+ * @param {string[]} geojsonUrls
384
+ */
385
+ export async function mergeGeojsons(geojsonUrls) {
386
+ if (!geojsonUrls.length) {
387
+ return undefined;
388
+ }
389
+ if (geojsonUrls.length === 1) {
390
+ return geojsonUrls[0];
391
+ }
392
+
393
+ const merged = {
394
+ type: "FeatureCollection",
395
+ /** @type {import("ol").Feature[]} */
396
+ features: [],
397
+ };
398
+ await Promise.all(
399
+ geojsonUrls.map((url) =>
400
+ axios.get(url).then((resp) => {
401
+ const geojson = resp.data;
402
+ merged.features.push(...(geojson.features ?? []));
403
+ }),
404
+ ),
405
+ );
406
+
407
+ return encodeURI(
408
+ "data:application/json;charset=utf-8," + JSON.stringify(merged),
409
+ );
410
+ }
@@ -316,3 +316,10 @@ export declare const store: typeof import("@/store").default;
316
316
  /////
317
317
 
318
318
  export * from "./main.js";
319
+
320
+ export type EodashStyleJson = import("ol/style/webgl.js").WebGLStyle & {
321
+ variables?: Record<string, any>;
322
+ legend?: Record<string, any>;
323
+ jsonform?: Record<string, any>;
324
+ tooltip?: { id: string; title?: string; appendix?: string }[];
325
+ };
@@ -20,3 +20,6 @@ export const eodashCompareCollections = shallowReactive([]);
20
20
 
21
21
  /** whether the map postion was set in URL params on first load */
22
22
  export const posIsSetFromUrl = ref(false);
23
+
24
+ /** @type {import("vue").Ref<Record<string,any>|undefined>} */
25
+ export const layerControlFormValue = ref({});
@@ -1,7 +1,7 @@
1
1
  import { openBlock, createBlock, withCtx, createElementVNode, unref, normalizeStyle, createElementBlock, Suspense, resolveDynamicComponent, mergeProps, createCommentVNode, Fragment, renderList, Transition } from 'vue';
2
2
  import '@eox/layout';
3
- import { _ as _export_sfc, F as useDefineTemplate } from './asWebComponent-BnFMd0T6.js';
4
- import { V as VMain } from './VMain-BWLMf-rn.js';
3
+ import { _ as _export_sfc, F as useDefineTemplate } from './asWebComponent-DW1XzZkL.js';
4
+ import { V as VMain } from './VMain-CQpXnzDR.js';
5
5
 
6
6
  const _hoisted_1 = ["gap"];
7
7
  const _hoisted_2 = ["id", "h", "w", "x", "y"];
@@ -1,5 +1,5 @@
1
1
  import { withAsyncContext, ref, onMounted, onUnmounted, openBlock, createElementBlock, createBlock, resolveDynamicComponent, mergeProps } from 'vue';
2
- import { $ as useSTAcStore } from './asWebComponent-BnFMd0T6.js';
2
+ import { $ as useSTAcStore } from './asWebComponent-DW1XzZkL.js';
3
3
 
4
4
  const _hoisted_1 = { class: "d-flex flex-column fill-height overflow-auto" };
5
5