@eodash/eodash 5.7.0 → 5.8.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.
Files changed (119) hide show
  1. package/core/client/components/EodashOverlay.vue +27 -4
  2. package/core/client/composables/DefineEodash.js +0 -1
  3. package/core/client/composables/DefineWidgets.js +3 -1
  4. package/core/client/eodashSTAC/EodashCollection.js +87 -24
  5. package/core/client/eodashSTAC/cql.js +64 -0
  6. package/core/client/eodashSTAC/createLayers.js +353 -187
  7. package/core/client/eodashSTAC/helpers.js +694 -110
  8. package/core/client/eodashSTAC/mosaic.js +422 -0
  9. package/core/client/plugins/axios.js +31 -1
  10. package/core/client/store/actions.js +1 -1
  11. package/core/client/store/stac.js +54 -4
  12. package/core/client/store/states.js +20 -2
  13. package/core/client/types.ts +152 -28
  14. package/core/client/utils/bands-editor/exampleSchema.json +50 -50
  15. package/core/client/utils/states.js +10 -0
  16. package/dist/client/{DashboardLayout-kRsmsNW5.js → DashboardLayout-DEs4f_Vy.js} +2 -2
  17. package/dist/client/{DynamicWebComponent-CnKhYo0K.js → DynamicWebComponent-PvnV88BA.js} +1 -1
  18. package/dist/client/EodashChart-D-3AGKZY.js +260 -0
  19. package/dist/client/{EodashDatePicker-CMPDT-ce.js → EodashDatePicker-Dm_goZzs.js} +3 -3
  20. package/dist/client/{EodashItemFilter-BpdA8QQa.js → EodashItemFilter-CJy3zYzD.js} +2 -1
  21. package/dist/client/{EodashLayerControl-BHpDA4_0.js → EodashLayerControl-rL8UnpkA.js} +55 -33
  22. package/dist/client/{EodashLayoutSwitcher-B1fRUt7G.js → EodashLayoutSwitcher-ZRlESI9O.js} +3 -3
  23. package/dist/client/{EodashMapBtns-Cpned0tc.js → EodashMapBtns-CG7u2Aq8.js} +227 -112
  24. package/dist/client/EodashStacInfo-CJhhxthD.js +169 -0
  25. package/dist/client/{EodashTools-1zHz26gv.js → EodashTools-CWyK8QJT.js} +4 -4
  26. package/dist/client/{ExportState-DbOm8hBI.js → ExportState-BXhy5TOU.js} +20 -174
  27. package/dist/client/{Footer-BKg-VVkj.js → Footer-DZPvnhcT.js} +1 -1
  28. package/dist/client/{Header-DCrwCvmY.js → Header-CiGsDE_a.js} +2 -2
  29. package/dist/client/{MobileLayout-vWSHpluo.js → MobileLayout-BJHW7x5V.js} +2 -2
  30. package/dist/client/{PopUp-9uimfK49.js → PopUp-7_XnhvCc.js} +4 -168
  31. package/dist/client/{ProcessList-CTTIZa06.js → ProcessList-LL_UCbvc.js} +5 -5
  32. package/dist/client/VDivider-DWYM0WUr.js +168 -0
  33. package/dist/client/{VImg-CrmB76ZY.js → VImg-B75dgw2K.js} +2 -2
  34. package/dist/client/{VMain-OKZNpcEG.js → VMain-DvMmOL4f.js} +1 -1
  35. package/dist/client/{VTooltip-CJw2FyWk.js → VTooltip-ClWHUmWL.js} +2 -2
  36. package/dist/client/{WidgetsContainer-BaWOnE5R.js → WidgetsContainer-BqaWs4ch.js} +1 -1
  37. package/dist/client/{asWebComponent-BHWpMuE3.js → asWebComponent-IZanwL-A.js} +677 -379
  38. package/dist/client/{async-DSKj6g1f.js → async-CiNIOBVz.js} +31 -29
  39. package/dist/client/{create-layers-config-CBoYedqB.js → create-layers-config-3S3y_kZg.js} +17 -17
  40. package/dist/client/dialog-transition-c4ZSnzac.js +170 -0
  41. package/dist/client/eo-dash.js +1 -1
  42. package/dist/client/{forwardRefs-DH51zPUr.js → forwardRefs-B-c1_6yo.js} +8 -87
  43. package/dist/client/{handling-BrcDDlgS.js → handling-NvY8Csry.js} +3 -4
  44. package/dist/client/{helpers-DjZVl_WF.js → helpers-BFuh19CP.js} +1094 -194
  45. package/dist/client/{index-1JKE68n3.js → index-1wMAyuNL.js} +219 -67
  46. package/dist/client/{index-CSG_JoOA.js → index-B8jGJSTA.js} +62 -56
  47. package/dist/client/{index-Cu3-13Xg.js → index-BKQQJkhy.js} +167 -61
  48. package/dist/client/index-D0jUyol8.js +3167 -0
  49. package/dist/client/{index-CUjl-ZsI.js → index-KGxz5Egv.js} +2 -2
  50. package/dist/client/mosaic-vHvSuih6.js +459 -0
  51. package/dist/client/templates.js +251 -121
  52. package/dist/client/{transition-OHcz5Qq1.js → transition-BkyUsZh_.js} +1 -1
  53. package/dist/node/cli.js +5 -5
  54. package/dist/node/types.d.ts +4 -0
  55. package/dist/types/core/client/composables/DefineEodash.d.ts +1 -1
  56. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +57 -25
  57. package/dist/types/core/client/eodashSTAC/cql.d.ts +15 -0
  58. package/dist/types/core/client/eodashSTAC/createLayers.d.ts +42 -23
  59. package/dist/types/core/client/eodashSTAC/helpers.d.ts +118 -19
  60. package/dist/types/core/client/eodashSTAC/mosaic.d.ts +56 -0
  61. package/dist/types/core/client/store/stac.d.ts +38 -8
  62. package/dist/types/core/client/store/states.d.ts +24 -2
  63. package/dist/types/core/client/types.d.ts +128 -24
  64. package/dist/types/core/client/utils/states.d.ts +12 -0
  65. package/dist/types/templates/baseConfig.d.ts +1 -100
  66. package/dist/types/templates/compare.d.ts +32 -3
  67. package/dist/types/templates/expert.d.ts +18 -0
  68. package/dist/types/templates/explore.d.ts +10 -1
  69. package/dist/types/templates/lite.d.ts +11 -0
  70. package/dist/types/widgets/EodashChart.vue.d.ts +5 -3
  71. package/dist/types/widgets/EodashItemCatalog/index.vue.d.ts +129 -2
  72. package/dist/types/widgets/EodashItemCatalog/methods/filters.d.ts +28 -6
  73. package/dist/types/widgets/EodashItemCatalog/methods/handlers.d.ts +17 -4
  74. package/dist/types/widgets/EodashItemCatalog/methods/map.d.ts +16 -4
  75. package/dist/types/widgets/EodashLayerControl.vue.d.ts +35 -16
  76. package/dist/types/widgets/EodashMap/EodashMapBtns.vue.d.ts +14 -10
  77. package/dist/types/widgets/EodashMap/index.vue.d.ts +86 -37
  78. package/dist/types/widgets/EodashMap/methods/create-layers-config.d.ts +1 -1
  79. package/dist/types/widgets/EodashMap/methods/index.d.ts +5 -1
  80. package/dist/types/widgets/EodashMap/methods/use-map-loading.d.ts +1 -0
  81. package/dist/types/widgets/EodashProcess/index.vue.d.ts +5 -3
  82. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +1 -1
  83. package/dist/types/widgets/EodashProcess/states.d.ts +1 -1
  84. package/dist/types/widgets/EodashStacInfo.vue.d.ts +20 -0
  85. package/dist/types/widgets/EodashTimeSlider/index.vue.d.ts +20 -0
  86. package/dist/types/widgets/EodashTimeSlider/methods/index.d.ts +3 -8
  87. package/dist/types/widgets/EodashTimeSlider/types.d.ts +6 -16
  88. package/dist/types/widgets/EodashTools.vue.d.ts +5 -5
  89. package/package.json +34 -34
  90. package/templates/baseConfig.js +37 -6
  91. package/templates/compare.js +61 -7
  92. package/templates/expert.js +24 -2
  93. package/templates/explore.js +12 -5
  94. package/templates/lite.js +13 -0
  95. package/widgets/EodashChart.vue +162 -21
  96. package/widgets/EodashItemCatalog/index.vue +363 -35
  97. package/widgets/EodashItemCatalog/methods/filters.js +134 -70
  98. package/widgets/EodashItemCatalog/methods/handlers.js +113 -19
  99. package/widgets/EodashItemCatalog/methods/map.js +141 -28
  100. package/widgets/EodashLayerControl.vue +51 -25
  101. package/widgets/EodashMap/EodashMapBtns.vue +109 -48
  102. package/widgets/EodashMap/index.vue +91 -105
  103. package/widgets/EodashMap/methods/btns.js +64 -31
  104. package/widgets/EodashMap/methods/create-layers-config.js +16 -16
  105. package/widgets/EodashMap/methods/index.js +71 -8
  106. package/widgets/EodashMap/methods/use-map-loading.js +58 -0
  107. package/widgets/EodashProcess/index.vue +136 -16
  108. package/widgets/EodashProcess/methods/composables.js +13 -0
  109. package/widgets/EodashProcess/methods/outputs.js +0 -1
  110. package/widgets/EodashProcess/methods/utils.js +29 -27
  111. package/widgets/EodashProcess/states.js +1 -1
  112. package/widgets/EodashStacInfo.vue +64 -2
  113. package/widgets/EodashTimeSlider/index.vue +58 -2
  114. package/widgets/EodashTimeSlider/methods/index.js +5 -48
  115. package/widgets/EodashTimeSlider/types.ts +7 -17
  116. package/widgets/ExportState.vue +13 -4
  117. package/dist/client/EodashChart-CLDqE93C.js +0 -144
  118. package/dist/client/EodashStacInfo-BQspAHKH.js +0 -107
  119. package/dist/client/index-5Jhsa8Xe.js +0 -570
@@ -1,14 +1,70 @@
1
- import { onMounted, onUnmounted, watch, computed, withAsyncContext, useTemplateRef, ref, toRaw, nextTick, openBlock, createElementBlock, createElementVNode, unref, normalizeStyle, createCommentVNode, createVNode } from 'vue';
1
+ import { watch, onUnmounted, onMounted, computed, withAsyncContext, useTemplateRef, ref, toRaw, nextTick, openBlock, createElementBlock, createElementVNode, unref, normalizeStyle, createCommentVNode, createVNode } from 'vue';
2
2
  import { transformExtent } from '@eox/map';
3
3
  import '@eox/map/src/plugins/advancedLayersAndSources';
4
- import { T as setMapProjFromCol, D as mapPosition, Q as sanitizeBbox, i as mapEl, R as mapCompareEl, E as indicator, H as compareIndicator, B as poi, U as isGlobe, A as datetime } from './helpers-DjZVl_WF.js';
4
+ import { a0 as loading, ab as isGlobe, ac as setMapProjFromCol, P as isFirstLoad, O as mapPosition, a3 as sanitizeBbox, q as mapEl, a5 as mapCompareEl, a4 as tooltipAdapter, Q as indicator, U as compareIndicator, M as poi, a9 as layerControlFormValue, a8 as layerControlFormValueCompare, L as datetime, T as eodashCompareCollections, W as eodashCollections } from './helpers-BFuh19CP.js';
5
5
  import { storeToRefs } from 'pinia';
6
- import { H as useSTAcStore, R as useEmitLayersUpdate, S as isFirstLoad, N as useOnLayersUpdate, _ as _export_sfc, G as useDisplay, a as useLayout, Q as layerControlFormValue, P as layerControlFormValueCompare, M as eodashCompareCollections, L as eodashCollections } from './asWebComponent-BHWpMuE3.js';
7
- import { c as createLayersConfig } from './create-layers-config-CBoYedqB.js';
6
+ import { H as useSTAcStore, aa as useEmitLayersUpdate, L as useOnLayersUpdate, _ as _export_sfc, G as useDisplay, a as useLayout } from './asWebComponent-IZanwL-A.js';
7
+ import { c as createLayersConfig } from './create-layers-config-3S3y_kZg.js';
8
8
  import log from 'loglevel';
9
9
  import { i as inAndOut } from './easing-CH0-9wR8.js';
10
10
  import mustache from 'mustache';
11
- import EodashMapBtns from './EodashMapBtns-Cpned0tc.js';
11
+ import EodashMapBtns from './EodashMapBtns-CG7u2Aq8.js';
12
+
13
+ /**
14
+ * Tracks map loading state at the source level via `loading.activeLoads`,
15
+ * the same counter used by the axios plugin. Re-attaches source listeners
16
+ * whenever eox-map fires `layerschanged`, using `getFlatLayersArray`.
17
+ *
18
+ * @param {import("vue").Ref<import("@eox/map").EOxMap | null>} mapElement
19
+ * @param {import("vue").Ref<import("@eox/map").EOxMap | null>} compareMapElement
20
+ */
21
+ const useMapLoading = (mapElement, compareMapElement) => {
22
+ // This instance's outstanding loads, so unmount subtracts only its share.
23
+ let localLoads = 0;
24
+ const startHandler = () => {
25
+ localLoads++;
26
+ loading.activeLoads++;
27
+ };
28
+ const endHandler = () => {
29
+ localLoads = Math.max(0, localLoads - 1);
30
+ loading.activeLoads = Math.max(0, loading.activeLoads - 1);
31
+ };
32
+
33
+ /** @param {import("@eox/map").EOxMap | null} newMapEl */
34
+ const watcherHandler = (newMapEl) => {
35
+ if (!newMapEl) return;
36
+
37
+ const hasStartListener = newMapEl.map
38
+ .getListeners("loadstart")
39
+ ?.some((listner) => listner === startHandler);
40
+ const hasEndListener = newMapEl.map
41
+ .getListeners("loadend")
42
+ ?.some((listner) => listner === endHandler);
43
+
44
+ if (!hasStartListener) {
45
+ newMapEl.map.addEventListener("loadstart", startHandler);
46
+ }
47
+ if (!hasEndListener) {
48
+ newMapEl.map.addEventListener("loadend", endHandler);
49
+ }
50
+ };
51
+ const stopMainWatcher = watch(mapElement, watcherHandler, {
52
+ immediate: true,
53
+ });
54
+ const stopCompareWatcher = watch(compareMapElement, watcherHandler, {
55
+ immediate: true,
56
+ });
57
+
58
+ onUnmounted(() => {
59
+ mapElement.value?.map.removeEventListener("loadstart", startHandler);
60
+ mapElement.value?.map.removeEventListener("loadend", endHandler);
61
+ compareMapElement.value?.map.removeEventListener("loadstart", startHandler);
62
+ compareMapElement.value?.map.removeEventListener("loadend", endHandler);
63
+ stopMainWatcher();
64
+ stopCompareWatcher();
65
+ loading.activeLoads = Math.max(0, loading.activeLoads - localLoads);
66
+ });
67
+ };
12
68
 
13
69
  /**
14
70
  * Holder for previous compare map view as it is overwritten by sync
@@ -40,14 +96,52 @@ const useHandleMapMoveEnd = (mapElement, mapPosition) => {
40
96
  }
41
97
  };
42
98
 
99
+ const handleGlobeMoveEnd = () => {
100
+ const camera = mapElement.value?.globe?.planet?.camera;
101
+ const lonLat = camera?.getLonLat();
102
+ if (!lonLat) return;
103
+ const { lon, lat, height } = lonLat;
104
+ if (![lon, lat, height].some(Number.isNaN)) {
105
+ mapPosition.value = [lon, lat, height];
106
+ }
107
+ };
108
+
109
+ /** @type {{ events: { off: Function } } | null} */
110
+ let subscribedCamera = null;
111
+
112
+ const subscribeGlobe = (retries = 3) => {
113
+ if (!isGlobe.value) return; // toggled back out during retry
114
+ const camera = mapElement.value?.globe?.planet?.camera;
115
+ if (camera) {
116
+ if (subscribedCamera === camera) return;
117
+ camera.events.on("moveend", handleGlobeMoveEnd);
118
+ subscribedCamera = camera;
119
+ handleGlobeMoveEnd();
120
+ return;
121
+ }
122
+ if (retries > 0) setTimeout(() => subscribeGlobe(retries - 1), 50);
123
+ };
124
+ const unsubscribeGlobe = () => {
125
+ subscribedCamera?.events.off("moveend", handleGlobeMoveEnd);
126
+ subscribedCamera = null;
127
+ };
128
+
129
+ const stopGlobeWatch = watch(isGlobe, (globe) =>
130
+ globe ? subscribeGlobe() : unsubscribeGlobe(),
131
+ );
132
+
43
133
  onMounted(() => {
44
- /** @type {import('ol/Map').default} */
45
- (mapElement.value?.map)?.on("moveend", handleMoveEnd);
134
+ const map = mapElement.value?.map;
135
+ map?.on("moveend", handleMoveEnd);
136
+ // Seed mapPosition from the initial view
137
+ handleMoveEnd(/** @type {any} */ ({ map }));
46
138
  });
47
139
 
48
140
  onUnmounted(() => {
49
141
  /** @type {import('ol/Map').default} */
50
142
  (mapElement.value?.map)?.un("moveend", handleMoveEnd);
143
+ unsubscribeGlobe();
144
+ stopGlobeWatch();
51
145
  });
52
146
  };
53
147
 
@@ -62,6 +156,7 @@ const useHandleMapMoveEnd = (mapElement, mapPosition) => {
62
156
  * @param {import("vue").Ref<import("@eox/map").EOxMap| null>} partnerMap
63
157
  * @param {boolean} zoomToExtent
64
158
  * @param {import("vue").Ref<import("stac-ts").StacItem | import("stac-ts").StacLink | null>} [selectedItem]
159
+ * @param {Record<string, any>[]} [defaultBaseLayers]
65
160
  */
66
161
  const useInitMap = (
67
162
  mapElement,
@@ -72,6 +167,7 @@ const useInitMap = (
72
167
  partnerMap,
73
168
  zoomToExtent,
74
169
  selectedItem,
170
+ defaultBaseLayers,
75
171
  ) => {
76
172
  log.debug(
77
173
  "InitMap",
@@ -101,12 +197,24 @@ const useInitMap = (
101
197
  );
102
198
 
103
199
  if (updatedStac) {
104
- if (
200
+ const isSameStac = updatedStac?.id === previousStac?.id;
201
+ const isSameItem = updatedItem?.id === previousItem?.id;
202
+
203
+ // Item deselect: overview render is owned by the item catalog widget.
204
+ const isItemDeselect =
205
+ previousItem &&
206
+ !updatedItem &&
207
+ isSameStac &&
208
+ updatedTime === previousTime;
209
+ if (isItemDeselect) return;
210
+
211
+ // Re-fire from our own datetime.value write, skip and clear
212
+ const isOwnDatetimeUpdate =
105
213
  internalDatetime !== null &&
106
214
  updatedTime === internalDatetime &&
107
- updatedStac?.id === previousStac?.id &&
108
- updatedItem?.id === previousItem?.id
109
- ) {
215
+ isSameStac &&
216
+ isSameItem;
217
+ if (isOwnDatetimeUpdate) {
110
218
  internalDatetime = null;
111
219
  return;
112
220
  }
@@ -154,7 +262,9 @@ const useInitMap = (
154
262
  updatedStac,
155
263
  eodashCols,
156
264
  updatedItem ?? updatedTime,
265
+ defaultBaseLayers,
157
266
  );
267
+
158
268
  log.debug(
159
269
  "Assigned layers after changing time only",
160
270
  JSON.parse(JSON.stringify(layersCollection)),
@@ -176,6 +286,11 @@ const useInitMap = (
176
286
  if (interval && interval.length > 0 && interval[0].length > 1) {
177
287
  // @ts-expect-error this is the defined STAC structure
178
288
  endInterval = new Date(interval[0][1]);
289
+ // If end interval is in the future, set to now,
290
+ // for item fetching based on search endpoint
291
+ if (endInterval.getTime() > Date.now()) {
292
+ endInterval = new Date();
293
+ }
179
294
  log.debug(
180
295
  "Indicator load: found stac extent, setting time to latest value",
181
296
  endInterval,
@@ -201,7 +316,8 @@ const useInitMap = (
201
316
  layersCollection = await createLayersConfig(
202
317
  updatedStac,
203
318
  eodashCols,
204
- resolvedTime,
319
+ updatedItem ?? resolvedTime,
320
+ defaultBaseLayers,
205
321
  );
206
322
 
207
323
  if (zoomToExtent) {
@@ -284,7 +400,7 @@ const useUpdateTooltipProperties = (
284
400
  });
285
401
  };
286
402
 
287
- const _style_0 = "#cursor-coordinates[data-v-5de71391]{position:fixed;left:24px;bottom:54px;color:#000000e6;font-size:10px;font-family:var(--eox-body-font-family);background:#fffe;border-radius:4px;border:none;padding:0 3px;max-height:24px}@media(max-width:959px){#cursor-coordinates[data-v-5de71391]{display:none}}#scale-line[data-v-5de71391]{position:fixed;left:24px;bottom:28px;color:#fff}@media(max-width:959px){#scale-line[data-v-5de71391]{bottom:102px}}[data-v-5de71391] .ol-scale-line{background:#fffe!important;border-radius:4px!important;border:none!important;padding:0 3px 3px!important;font-size:10px!important;font-family:var(--eox-body-font-family);max-height:20px}[data-v-5de71391] .ol-scale-line-inner{display:flex;justify-content:center;border:1px solid rgba(0,0,0,.5)!important;border-top:none!important;color:#333!important;font-weight:500!important;transform:translateY(1px)}.map-buttons-container[data-v-5de71391]{position:fixed;left:0;width:100%;height:100%;display:grid;grid-template-columns:repeat(12,1fr);grid-template-rows:repeat(12,1fr);pointer-events:none;z-index:1}.map-buttons-container[data-v-5de71391]>*{pointer-events:auto}";
403
+ const _style_0 = ".map-buttons-container[data-v-0ac5d70c]{position:fixed;left:0;width:100%;height:100%;display:grid;grid-template-columns:repeat(12,1fr);grid-template-rows:repeat(12,1fr);pointer-events:none;z-index:1}.map-buttons-container[data-v-0ac5d70c]>*{pointer-events:auto}";
288
404
 
289
405
  const _hoisted_1 = [".enabled"];
290
406
  const _hoisted_2 = [".animationOptions", ".center", ".zoom", ".layers", ".controls"];
@@ -306,42 +422,73 @@ const _hoisted_7 = {
306
422
  const _sfc_main = {
307
423
  __name: 'index',
308
424
  props: {
425
+ baseLayers: {
426
+ /** @type {import("vue").PropType<import("@eox/map").EoxLayer[]>} */
427
+ type: Array,
428
+ default: () => [
429
+ {
430
+ type: "Tile",
431
+ source: { type: "OSM" },
432
+ properties: {
433
+ id: "osm",
434
+ title: "Background",
435
+ layerControlExclusive: true,
436
+ },
437
+ },
438
+ ],
439
+ },
309
440
  enableCompare: {
310
441
  type: Boolean,
311
442
  default: false,
312
443
  },
313
- /** @type {import("vue").PropType<[number,number]>} */
444
+ /**
445
+ * Initial map center as [lon, lat]; falls back to the last stored map position.
446
+ * @default [15, 48]
447
+ */
314
448
  center: {
315
- //@ts-expect-error todo
316
- type: Array,
449
+ type: /** @type {import("vue").PropType<[number, number]>} */ (
450
+ /** @type {unknown} */ (Array)
451
+ ),
317
452
  default: () => [mapPosition.value?.[0] ?? 15, mapPosition.value?.[1] ?? 48],
318
453
  },
454
+ /**
455
+ * Initial zoom level; falls back to the last stored map position.
456
+ * @default 4
457
+ */
319
458
  zoom: {
320
459
  type: Number,
321
460
  default: mapPosition.value?.[2] ?? 4,
322
461
  },
462
+ /** Fly to the selected collection's spatial extent on selection. */
323
463
  zoomToExtent: {
324
464
  type: Boolean,
325
465
  default: true,
326
466
  },
467
+ /** Show live cursor coordinates as a fixed overlay at the bottom-left of the map. */
327
468
  enableCursorCoordinates: {
328
469
  type: Boolean,
329
470
  default: true,
330
471
  },
472
+ /** Show an OpenLayers scale-line control at the bottom-left of the map. */
331
473
  enableScaleLine: {
332
474
  type: Boolean,
333
475
  default: true,
334
476
  },
477
+ /** Grid position of the floating button toolbar. `x` accepts responsive `"mobile/tablet/desktop"` column notation. */
335
478
  btnsPosition: {
336
- type: Object,
479
+ type: /** @type {import("vue").PropType<{ x: string | number; y: number; gap: number }>} */ (
480
+ Object
481
+ ),
337
482
  default: () => ({
338
483
  x: "12/9/10",
339
484
  y: 1,
340
485
  gap: 16,
341
486
  }),
342
487
  },
488
+ /** Toolbar feature flags; set any flag to `false` to hide the corresponding button. */
343
489
  btns: {
344
- /** @type {import("vue").PropType<{
490
+ type: /**
491
+ * @type {import("vue").PropType<{
345
492
  * enableExportMap?: boolean;
346
493
  * enableChangeProjection?: boolean;
347
494
  * enableBackToPOIs?: boolean;
@@ -349,14 +496,14 @@ const _sfc_main = {
349
496
  * searchParams?: object;
350
497
  * enableZoom?: boolean;
351
498
  * enableGlobe?: boolean;
499
+ * enableMosaic?: boolean;
352
500
  * enableFeedback?: boolean;
353
501
  * enableCompareIndicators?: boolean | {
354
502
  * compareTemplate?:string;
355
503
  * fallbackTemplate?:string;
356
504
  * itemFilterConfig?:InstanceType<import("../EodashItemFilter.vue").default>["$props"]
357
505
  * };
358
- * }> }*/
359
- type: Object,
506
+ * }> } */ (Object),
360
507
  default: () => ({
361
508
  enableExportMap: true,
362
509
  enableChangeProjection: true,
@@ -365,6 +512,7 @@ const _sfc_main = {
365
512
  enableSearch: true,
366
513
  enableZoom: true,
367
514
  enableGlobe: true,
515
+ enableMosaic: true,
368
516
  enableFeedback: true,
369
517
  searchParams: {},
370
518
  }),
@@ -414,6 +562,7 @@ const btnsProps = computed(() => ({
414
562
  enableSearch: props.btns.enableSearch ?? true,
415
563
  enableZoom: props.btns.enableZoom ?? true,
416
564
  enableGlobe: props.btns.enableGlobe ?? true,
565
+ enableMosaic: props.btns.enableMosaic ?? true,
417
566
  enableFeedback: props.btns.enableFeedback ?? true,
418
567
  searchParams: props.btns.searchParams,
419
568
  }));
@@ -433,22 +582,13 @@ const cursorCoordsRef = useTemplateRef("cursor-coords");
433
582
  const tooltipProperties = ref([]);
434
583
  /** @type {import("vue").Ref<Exclude<import("@/types").EodashStyleJson["tooltip"], undefined>>} */
435
584
  const compareTooltipProperties = ref([]);
436
- /** @type {import("vue").ComputedRef<{
437
- Attribution: { collapsible: boolean };
438
- ScaleLine?: { target: HTMLElement };
439
- MousePosition?: { projection: string; coordinateFormat: (c: [number, number]) => string; target: HTMLElement };
440
- }>} */
585
+
441
586
  const controls = computed(() => {
442
- /** @type {{
443
- Attribution: { collapsible: boolean };
444
- ScaleLine?: { target: HTMLElement };
445
- MousePosition?: { projection: string; coordinateFormat: (c: [number, number]) => string; target: HTMLElement };
446
- }} */
447
- const controlsObj = {
587
+ const controlsObj = /** @type {import("@eox/map").ControlDictionary} */ ({
448
588
  Attribution: {
449
589
  collapsible: true,
450
590
  },
451
- };
591
+ });
452
592
 
453
593
  if (props.enableScaleLine && scaleLineRef.value) {
454
594
  controlsObj.ScaleLine = {
@@ -459,12 +599,10 @@ const controls = computed(() => {
459
599
  if (props.enableCursorCoordinates && cursorCoordsRef.value) {
460
600
  controlsObj.MousePosition = {
461
601
  projection: "EPSG:4326",
462
- coordinateFormat: (/** @type {[number, number]} */ c) => {
463
- const lat = c[1];
464
- const lng = c[0];
465
- const latStr = `${Math.abs(lat).toFixed(3)}°${lat >= 0 ? "N" : "S"}`;
466
- const lngStr = `${Math.abs(lng).toFixed(3)}°${lng >= 0 ? "E" : "W"}`;
467
- return `${latStr}, ${lngStr}`;
602
+ coordinateFormat: (c) => {
603
+ if (!c) return "";
604
+ const [lon, lat] = c;
605
+ return `${Math.abs(lat).toFixed(3)} °${lat >= 0 ? "N" : "S"}, ${Math.abs(lon).toFixed(3)} °${lon >= 0 ? "E" : "W"}`;
468
606
  },
469
607
  target: cursorCoordsRef.value,
470
608
  };
@@ -476,28 +614,17 @@ const controls = computed(() => {
476
614
  const initialCenter = toRaw(props.center);
477
615
  const initialZoom = toRaw(mapPosition.value?.[2] ?? props.zoom);
478
616
  /** @type {import("vue").Ref<Record<string,any>[]>} */
479
- const eoxMapLayers = ref([
480
- {
481
- type: "Tile",
482
- source: { type: "OSM" },
483
- properties: {
484
- id: "osm",
485
- title: "Background",
486
- },
487
- },
488
- ]);
617
+ const eoxMapLayers = ref(
618
+ /** @type {Record<string,any>[]} */ (
619
+ structuredClone(toRaw(props.baseLayers))
620
+ ),
621
+ );
489
622
 
490
- /** @type {import("vue").Ref<Record<string,any>[]>} */
491
- const eoxMapCompareLayers = ref([
492
- {
493
- type: "Tile",
494
- source: { type: "OSM" },
495
- properties: {
496
- id: "osm",
497
- title: "Background",
498
- },
499
- },
500
- ]);
623
+ const eoxMapCompareLayers = ref(
624
+ /** @type {Record<string,any>[]} */ (
625
+ structuredClone(toRaw(props.baseLayers))
626
+ ),
627
+ );
501
628
 
502
629
  const animationOptions = ref({
503
630
  duration: 0, // Initially set to 0 for an instant "jump"
@@ -505,9 +632,10 @@ const animationOptions = ref({
505
632
  });
506
633
 
507
634
  /** @type {import("vue").Ref<import("@eox/map").EOxMap | null>} */
508
- const eoxMap = ref(null);
635
+ const eoxMap = useTemplateRef("eoxMap");
509
636
  /** @type {import("vue").Ref<import("@eox/map").EOxMap | null>} */
510
- const compareMap = ref(null);
637
+ const compareMap = useTemplateRef("compareMap");
638
+
511
639
  const { selectedCompareStac } = storeToRefs(useSTAcStore());
512
640
  const showCompare = computed(() =>
513
641
  props.enableCompare && !!selectedCompareStac.value ? "" : "first",
@@ -516,10 +644,20 @@ const showCompare = computed(() =>
516
644
  useHandleMapMoveEnd(eoxMap, mapPosition);
517
645
 
518
646
  onMounted(() => {
519
- const { selectedCompareStac, selectedStac, selectedItem } =
520
- storeToRefs(useSTAcStore());
647
+ const {
648
+ selectedCompareStac,
649
+ selectedStac,
650
+ selectedItem,
651
+ selectedCompareItem,
652
+ } = storeToRefs(useSTAcStore());
653
+ if (!eoxMap.value) {
654
+ console.error("EOxMap reference is not available on mounted.");
655
+ return;
656
+ }
521
657
  // assign map Element state to eox map
522
658
  mapEl.value = eoxMap.value;
659
+ // enable terrain
660
+ mapEl.value.globeConfig.terrain = true;
523
661
 
524
662
  if (props.enableCompare) {
525
663
  mapCompareEl.value = compareMap.value;
@@ -534,6 +672,8 @@ onMounted(() => {
534
672
  eoxMapCompareLayers,
535
673
  eoxMap,
536
674
  false,
675
+ selectedCompareItem,
676
+ props.baseLayers,
537
677
  );
538
678
 
539
679
  useUpdateTooltipProperties(
@@ -552,6 +692,7 @@ onMounted(() => {
552
692
  compareMap,
553
693
  props.zoomToExtent,
554
694
  selectedItem,
695
+ props.baseLayers,
555
696
  );
556
697
  // After the initial mount and "jump", set the animation duration for subsequent flyTo calls
557
698
  nextTick(() => {
@@ -559,14 +700,23 @@ onMounted(() => {
559
700
  });
560
701
  });
561
702
 
703
+ // sync map loading with the global loading state
704
+ useMapLoading(eoxMap, compareMap);
705
+
562
706
  useUpdateTooltipProperties(eodashCollections, tooltipProperties);
563
707
 
564
708
  const mainTooltipStyles = computed(() => ({
565
- visibility: tooltipProperties.value.length ? "visible" : "hidden",
709
+ visibility:
710
+ tooltipProperties.value.length || !!tooltipAdapter.value
711
+ ? "visible"
712
+ : "hidden",
566
713
  }));
567
714
 
568
715
  const compareTooltipStyles = computed(() => ({
569
- visibility: compareTooltipProperties.value.length ? "visible" : "hidden",
716
+ visibility:
717
+ compareTooltipProperties.value.length || !!tooltipAdapter.value
718
+ ? "visible"
719
+ : "hidden",
570
720
  }));
571
721
  /**
572
722
  * @param {"main" | "compare"} map
@@ -592,6 +742,9 @@ const tooltipPropertyTransform = (map) => {
592
742
  (prop) => prop.id === param.key,
593
743
  );
594
744
  if (!tooltipProp) {
745
+ if (tooltipAdapter.value) {
746
+ return tooltipAdapter.value(param, map);
747
+ }
595
748
  return undefined;
596
749
  }
597
750
  if (typeof param.value === "object") {
@@ -603,7 +756,6 @@ const tooltipPropertyTransform = (map) => {
603
756
  : 4;
604
757
  param.value = Number(param.value).toFixed(decimals).toString();
605
758
  }
606
-
607
759
  return {
608
760
  key: tooltipProp.title || tooltipProp.id,
609
761
  value: param.value + " " + (tooltipProp.appendix || ""),
@@ -692,6 +844,6 @@ return (_ctx, _cache) => {
692
844
  }
693
845
 
694
846
  };
695
- const index = /*#__PURE__*/_export_sfc(_sfc_main, [['styles',[_style_0]],['__scopeId',"data-v-5de71391"]]);
847
+ const index = /*#__PURE__*/_export_sfc(_sfc_main, [['styles',[_style_0]],['__scopeId',"data-v-0ac5d70c"]]);
696
848
 
697
849
  export { index as default };