@eodash/eodash 5.0.0-alpha.2.15 → 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.
Files changed (49) hide show
  1. package/README.md +1 -1
  2. package/core/client/composables/EodashMap.js +245 -0
  3. package/core/client/composables/index.js +2 -2
  4. package/core/client/eodash.js +1 -2
  5. package/core/client/store/Actions.js +30 -10
  6. package/core/client/store/States.js +4 -1
  7. package/core/client/store/stac.js +52 -2
  8. package/core/client/types.d.ts +6 -2
  9. package/core/client/utils/createLayers.js +146 -39
  10. package/core/client/utils/eodashSTAC.js +94 -19
  11. package/core/client/utils/helpers.js +189 -11
  12. package/core/client/utils/states.js +17 -0
  13. package/dist/client/{DashboardLayout-DQE4aB6e.js → DashboardLayout-CCtyOil0.js} +2 -2
  14. package/dist/client/{DynamicWebComponent-TrDsJuF8.js → DynamicWebComponent-But2r1Sj.js} +2 -2
  15. package/dist/client/EodashDatePicker-jeYiWflv.js +247 -0
  16. package/dist/client/{EodashItemFilter-Bp0lcvbI.js → EodashItemFilter-BFlfWeE_.js} +2028 -2024
  17. package/dist/client/EodashLayerControl-BhZL4pYM.js +24358 -0
  18. package/dist/client/{EodashMap--2y6XErO.js → EodashMap-C5tOgVOv.js} +22268 -24006
  19. package/dist/client/{EodashMapBtns-BSf3iUAb.js → EodashMapBtns-CdDfVQj0.js} +2 -2
  20. package/dist/client/{ExportState-BTONkMIz.js → ExportState-CKCCN_VI.js} +142 -136
  21. package/dist/client/{Footer-B7JDXdxT.js → Footer-B9yVgyzx.js} +67 -65
  22. package/dist/client/{Header-Dlumetq0.js → Header-CPIlUEOq.js} +4 -4
  23. package/dist/client/{IframeWrapper-DRjSqhFx.js → IframeWrapper-DRw1kHJm.js} +1 -1
  24. package/dist/client/{MobileLayout-9z2X_rmU.js → MobileLayout-CPxVee5U.js} +6 -6
  25. package/dist/client/{PopUp-CXbMBYGh.js → PopUp-Dca-gx9a.js} +5 -5
  26. package/dist/client/{VImg-Dgk5tryv.js → VImg-PHLA1nP1.js} +2 -2
  27. package/dist/client/{VMain-Ubv9jyyL.js → VMain-Ck81LJfb.js} +2 -2
  28. package/dist/client/{VOverlay-CqZC2CbA.js → VOverlay-CL4hiJB8.js} +92 -92
  29. package/dist/client/{WidgetsContainer-CHK_3dlD.js → WidgetsContainer-jxk3kw-d.js} +1 -1
  30. package/dist/client/asWebComponent-3OsFQJVx.js +23633 -0
  31. package/dist/client/eo-dash.js +1 -1
  32. package/dist/client/{forwardRefs-OX_5lLJW.js → forwardRefs-BxZaq9ml.js} +1 -1
  33. package/dist/client/{index-B_KfD-iF.js → index-Vul961Xy.js} +23 -23
  34. package/dist/client/{lerc-B4lXefGh-CplqAh1B.js → lerc-B4lXefGh-BESXOHWk.js} +1 -1
  35. package/dist/client/{ssrBoot-BZTPJZkq.js → ssrBoot-BFMBrCqY.js} +1 -1
  36. package/dist/client/style.css +2 -2
  37. package/dist/client/{transition-Dq8XIV_D.js → transition-U5aFjJtV.js} +1 -1
  38. package/dist/client/{webfontloader-qotgY98I.js → webfontloader-D_JbBwHu.js} +1 -1
  39. package/package.json +5 -3
  40. package/widgets/EodashDatePicker.vue +32 -40
  41. package/widgets/EodashItemFilter.vue +2 -0
  42. package/widgets/EodashLayerControl.vue +69 -2
  43. package/widgets/EodashMap.vue +35 -208
  44. package/widgets/ExportState.vue +8 -7
  45. package/dist/client/EodashDatePicker-CkA9rHp6.js +0 -252
  46. package/dist/client/EodashLayerControl-lfLYqyeU.js +0 -20963
  47. package/dist/client/_commonjsHelpers-DaMA6jEr.js +0 -8
  48. package/dist/client/asWebComponent-Ddg71BJk.js +0 -20451
  49. package/dist/client/helpers-BCawTwFg.js +0 -1390
package/README.md CHANGED
@@ -4,7 +4,7 @@ A package for creating earth observation dashboards. To learn more about eodash
4
4
 
5
5
  ## Usage
6
6
 
7
- Checkout the [documentation](https://eodash.github.io/eodash/get-started.html) for a detailed guide.
7
+ Checkout the [documentation](https://eodash.github.io/eodash/) for a detailed guide.
8
8
 
9
9
  ## Get Started
10
10
 
@@ -0,0 +1,245 @@
1
+ import { EodashCollection } from "@/utils/eodashSTAC";
2
+ import { setMapProjFromCol } from "@/utils/helpers";
3
+ import { onMounted, onUnmounted, watch } from "vue";
4
+
5
+ /**
6
+ * Description placeholder
7
+ *
8
+ * @param {import("vue").Ref<HTMLElement & Record<string,any> & {map:import("ol").Map } | null>} mapElement
9
+ * @param {import("vue").Ref<(number | undefined)[]>} mapPosition
10
+ */
11
+ export const useHandleMapMoveEnd = (mapElement, mapPosition) => {
12
+ /** @type {import("openlayers").EventsListenerFunctionType} */
13
+ const handleMoveEnd = (evt) => {
14
+ const map = /** @type {import("openlayers").Map | undefined} */ (
15
+ /** @type {any} */ (evt).map
16
+ );
17
+ const lonlat = mapElement.value?.lonLatCenter;
18
+ const z = map?.getView().getZoom();
19
+ if (
20
+ lonlat &&
21
+ !Number.isNaN(lonlat[0]) &&
22
+ !Number.isNaN(lonlat[1]) &&
23
+ !Number.isNaN(z)
24
+ ) {
25
+ mapPosition.value = [lonlat[0], lonlat[1], z];
26
+ }
27
+ };
28
+
29
+ onMounted(() => {
30
+ /** @type {import('ol/Map').default} */
31
+ (mapElement.value?.map)?.on("moveend", handleMoveEnd);
32
+ });
33
+
34
+ onUnmounted(() => {
35
+ /** @type {import('ol/Map').default} */
36
+ (mapElement.value?.map)?.un("moveend", handleMoveEnd);
37
+ });
38
+ };
39
+
40
+ /**
41
+ *
42
+ * @param {string} indicatorUrl
43
+ * @param {import("@/utils/eodashSTAC").EodashCollection[]} eodashCols
44
+ * @param {string} updatedTime
45
+ * @param {import("stac-ts").StacCatalog
46
+ * | import("stac-ts").StacCollection
47
+ * | import("stac-ts").StacItem
48
+ * | null
49
+ * } selectedIndicator
50
+ */
51
+ const createLayersConfig = async (
52
+ indicatorUrl,
53
+ eodashCols,
54
+ updatedTime,
55
+ selectedIndicator,
56
+ ) => {
57
+ const layersCollection = [];
58
+ const dataLayers = {
59
+ type: "Group",
60
+ properties: {
61
+ id: "AnalysisGroup",
62
+ title: "Analysis Layers",
63
+ layerControlExpand: true,
64
+ },
65
+ layers: /** @type {Record<string,any>[]}*/ ([]),
66
+ };
67
+
68
+ for (const ec of eodashCols) {
69
+ let layers;
70
+ if (updatedTime) {
71
+ layers = await ec.createLayersJson(new Date(updatedTime));
72
+ } else {
73
+ layers = await ec.createLayersJson();
74
+ }
75
+ if (layers) {
76
+ dataLayers.layers.push(...layers);
77
+ }
78
+ }
79
+ // Add expand to all analysis layers
80
+ dataLayers.layers.forEach((dl) => {
81
+ dl.properties.layerControlExpand = true;
82
+ dl.properties.layerControlToolsExpand = true;
83
+ });
84
+
85
+ layersCollection.push(dataLayers);
86
+
87
+ const indicator = new EodashCollection(indicatorUrl);
88
+ const indicatorLayers = await indicator.buildJsonArray(
89
+ //@ts-expect-error we use this function to generate collection level visualization
90
+ selectedIndicator,
91
+ indicatorUrl,
92
+ selectedIndicator?.title ?? "",
93
+ selectedIndicator?.endpointtype === "GeoDB",
94
+ );
95
+
96
+ const baseLayers = {
97
+ type: "Group",
98
+ properties: {
99
+ id: "BaseLayersGroup",
100
+ title: "Base Layers",
101
+ },
102
+ layers: /** @type {Record<string,any>[]}*/ ([]),
103
+ };
104
+
105
+ const indicatorBaseLayers = indicatorLayers.filter(
106
+ (l) => l.properties.group === "baselayer",
107
+ );
108
+ // Only one baselayer can be set to visible, let's first set all to
109
+ // false that have not a dedicated property visible, then check
110
+ // if there are more then one visible and only allow one
111
+ let counter = 0;
112
+ let lastPos = 0;
113
+ indicatorBaseLayers.forEach((bl, indx) => {
114
+ if (!("visible" in bl.properties)) {
115
+ bl.properties.visible = false;
116
+ }
117
+ if (bl.properties.visible) {
118
+ counter++;
119
+ lastPos = indx;
120
+ }
121
+ });
122
+ // if none visible set the last one as visible
123
+ if (counter == 0 && indicatorBaseLayers.length > 0) {
124
+ indicatorBaseLayers[0].properties.visible = true;
125
+ }
126
+ // disable all apart from last
127
+ if (counter > 1) {
128
+ indicatorBaseLayers.forEach((bl, indx) => {
129
+ if (indx !== lastPos) {
130
+ bl.properties.visible = false;
131
+ }
132
+ });
133
+ }
134
+
135
+ if (indicatorBaseLayers.length) {
136
+ baseLayers.layers.push(...indicatorBaseLayers);
137
+
138
+ // Add exclusive to baselayers and make sure only one is selected
139
+ baseLayers.layers.forEach((bl) => {
140
+ bl.properties.layerControlExclusive = true;
141
+ });
142
+ } else {
143
+ // Default to some baselayer
144
+ baseLayers.layers.push({
145
+ type: "Tile",
146
+ properties: {
147
+ id: "osm",
148
+ title: "Background",
149
+ layerControlExclusive: true,
150
+ },
151
+ source: {
152
+ type: "OSM",
153
+ },
154
+ });
155
+ }
156
+
157
+ if (baseLayers.layers.length) {
158
+ layersCollection.push(baseLayers);
159
+ }
160
+
161
+ const overlayLayers = {
162
+ type: "Group",
163
+ properties: {
164
+ id: "OverlayGroup",
165
+ title: "Overlay Layers",
166
+ },
167
+ layers: /** @type {Record<string,any>[]}*/ ([]),
168
+ };
169
+
170
+ const indicatorOverlays = indicatorLayers.filter(
171
+ (l) => l.properties.group === "overlay",
172
+ );
173
+ if (indicatorOverlays.length) {
174
+ overlayLayers.layers.push(...indicatorOverlays);
175
+ layersCollection.unshift(overlayLayers);
176
+ }
177
+
178
+ return layersCollection;
179
+ };
180
+
181
+ /**
182
+ * Description placeholder
183
+ *
184
+ * @param {import("vue").Ref<HTMLElement & Record<string,any> | null>} mapElement
185
+ * @param {import("vue").Ref<import("stac-ts").StacCollection | null>} selectedIndicator
186
+ * @param {EodashCollection[]} eodashCols
187
+ * @param {import("vue").Ref<string>} indicatorUrl
188
+ * @param {import("vue").Ref<string>} datetime
189
+ */
190
+ export const useInitMap = (
191
+ mapElement,
192
+ selectedIndicator,
193
+ eodashCols,
194
+ indicatorUrl,
195
+ datetime,
196
+ ) => {
197
+ onMounted(() => {
198
+ watch(
199
+ [selectedIndicator, datetime],
200
+ async ([updatedStac, updatedTime], [previousSTAC, _previousTime]) => {
201
+ if (updatedStac) {
202
+ const layersCollection = await createLayersConfig(
203
+ indicatorUrl.value,
204
+ eodashCols,
205
+ updatedTime,
206
+ updatedStac,
207
+ );
208
+ /** @type {any} */
209
+ (mapElement.value).layers = layersCollection;
210
+
211
+ // only on different indicator selection and not on time change
212
+ if (previousSTAC?.id !== updatedStac.id) {
213
+ // Set projection based on indicator level information
214
+ setMapProjFromCol(
215
+ /** @type {import('stac-ts').StacCollection} */
216
+ (updatedStac),
217
+ );
218
+ // Try to move map view to extent
219
+ // Make sure for now we are always converting from 4326
220
+ // of stac items into current map projection
221
+ // TODO: This might change if we decide to use 4326 as default for zoom and extent
222
+ // Sanitize extent
223
+ // // @ts-expect-error we will need to change the approach to use
224
+ // // native eox-map transformation once included
225
+ const b = updatedStac.extent?.spatial.bbox[0];
226
+ const sanitizedExtent = [
227
+ b[0] > -180 ? b[0] : -180,
228
+ b[1] > -90 ? b[1] : -90,
229
+ b[2] < 180 ? b[2] : 180,
230
+ b[3] < 90 ? b[3] : 90,
231
+ ];
232
+ const reprojExtent = mapElement.value?.transformExtent(
233
+ sanitizedExtent,
234
+ "EPSG:4326",
235
+ mapElement.value?.map?.getView().getProjection(),
236
+ );
237
+ /** @type {any} */
238
+ (mapElement.value).zoomExtent = reprojExtent;
239
+ }
240
+ }
241
+ },
242
+ { immediate: true },
243
+ );
244
+ });
245
+ };
@@ -114,7 +114,7 @@ export const useURLSearchParametersSync = () => {
114
114
  y,
115
115
  /** @type {number | undefined} */
116
116
  z;
117
- searchParams.forEach(async (value, key) => {
117
+ for (const [key, value] of searchParams) {
118
118
  switch (key) {
119
119
  case "indicator": {
120
120
  const { loadSelectedSTAC, stac } = useSTAcStore();
@@ -143,7 +143,7 @@ export const useURLSearchParametersSync = () => {
143
143
  default:
144
144
  break;
145
145
  }
146
- });
146
+ }
147
147
 
148
148
  if (x && y && z) {
149
149
  mapPosition.value = [x, y, z];
@@ -9,8 +9,7 @@ import { currentUrl } from "./store/States";
9
9
  */
10
10
  export const eodash = reactive({
11
11
  id: "demo",
12
- stacEndpoint:
13
- "https://eodashcatalog.eox.at/test-style/trilateral/catalog.json",
12
+ stacEndpoint: "https://gtif-cerulean.github.io/catalog/cerulean/catalog.json",
14
13
  brand: {
15
14
  noLayout: true,
16
15
  name: "Demo",
@@ -1,4 +1,5 @@
1
- import { mapEl, registeredProjections } from "@/store/States";
1
+ import { mapEl, mapCompareEl, registeredProjections } from "@/store/States";
2
+ import { getProjectionCode } from "@/utils/helpers";
2
3
 
3
4
  /**
4
5
  * Returns the current layers of {@link mapEl}
@@ -8,31 +9,50 @@ export const getLayers = () => mapEl.value?.layers.toReversed();
8
9
 
9
10
  /**
10
11
  * Register EPSG projection in `eox-map`
11
- * @param {string|number} [code]*/
12
- export const registerProjection = async (code) => {
13
- code = typeof code === "number" ? `EPSG:${code}` : code;
12
+ * @param {string|number|{name: string, def: string, extent?:number[]}} [projection]*/
13
+ export const registerProjection = async (projection) => {
14
+ let code = getProjectionCode(projection);
14
15
  if (!code || registeredProjections.includes(code)) {
15
16
  return;
16
17
  }
17
18
 
18
19
  registeredProjections.push(code);
19
- await mapEl.value?.registerProjectionFromCode(code);
20
+ if (typeof projection === "object") {
21
+ // registering whole projection definition
22
+ await mapEl.value?.registerProjection(
23
+ code,
24
+ projection.def,
25
+ projection.extent,
26
+ );
27
+ // also registering for comparison map
28
+ await mapCompareEl.value?.registerProjection(
29
+ code,
30
+ projection.def,
31
+ projection.extent,
32
+ );
33
+ } else {
34
+ await mapEl.value?.registerProjectionFromCode(code);
35
+ // also registering for comparison map
36
+ await mapCompareEl.value?.registerProjectionFromCode(code);
37
+ }
20
38
  };
21
39
  /**
22
- * Change `eox-map` projection from an `EPSG` code
23
- * @param {string|number} [code]*/
24
- export const changeMapProjection = async (code) => {
25
- code = typeof code === "number" ? `EPSG:${code}` : code;
40
+ * Change `eox-map` projection from an `EPSG` projection
41
+ * @param {string|number|{name: string, def: string}} [projection]*/
42
+ export const changeMapProjection = async (projection) => {
43
+ let code = getProjectionCode(projection);
26
44
 
27
45
  if (!code) {
28
46
  mapEl.value?.setAttribute("projection", "EPSG:3857");
47
+ mapCompareEl.value?.setAttribute("projection", "EPSG:3857");
29
48
  return;
30
49
  }
31
50
 
32
51
  if (!registeredProjections.includes(code)) {
33
- await registerProjection(code);
52
+ await registerProjection(projection);
34
53
  }
35
54
 
36
55
  code = mapEl.value?.getAttribute("projection") === code ? "EPSG:3857" : code;
37
56
  mapEl.value?.setAttribute("projection", code);
57
+ mapCompareEl.value?.setAttribute("projection", code);
38
58
  };
@@ -22,7 +22,10 @@ export const mapPosition = ref([]);
22
22
  export const registeredProjections = ["EPSG:4326", "EPSG:3857"];
23
23
 
24
24
  /** available projection to be rendered by `EodashMap` */
25
- export const availableMapProjection = ref("");
25
+ export const availableMapProjection = ref("EPSG:3857");
26
26
 
27
27
  /** @type {import("vue").Ref<HTMLElement & Record<string,any> | null>} */
28
28
  export const mapEl = ref(null);
29
+
30
+ /** @type {import("vue").Ref<HTMLElement & Record<string,any> | null>} */
31
+ export const mapCompareEl = ref(null);
@@ -4,6 +4,9 @@ import axios from "axios";
4
4
  import { useAbsoluteUrl, useCompareAbsoluteUrl } from "@/composables/index";
5
5
  import { eodashKey } from "@/utils/keys";
6
6
  import { indicator } from "@/store/States";
7
+ import { extractCollectionUrls } from "@/utils/helpers";
8
+ import { eodashCollections, eodashCompareCollections } from "@/utils/states";
9
+ import { EodashCollection } from "@/utils/eodashSTAC";
7
10
 
8
11
  export const useSTAcStore = defineStore("stac", () => {
9
12
  /**
@@ -80,7 +83,26 @@ export const useSTAcStore = defineStore("stac", () => {
80
83
 
81
84
  await axios
82
85
  .get(absoluteUrl.value)
83
- .then((resp) => {
86
+ .then(async (resp) => {
87
+ // init eodash collections
88
+ const collectionUrls = extractCollectionUrls(
89
+ resp.data,
90
+ absoluteUrl.value,
91
+ );
92
+
93
+ await Promise.all(
94
+ collectionUrls.map((cu) => {
95
+ const ec = new EodashCollection(cu);
96
+ ec.fetchCollection();
97
+ return ec;
98
+ }),
99
+ ).then((collections) => {
100
+ // empty array from old collections
101
+ eodashCollections.length = 0;
102
+ // update eodashCollections
103
+ eodashCollections.push(...collections);
104
+ });
105
+
84
106
  selectedStac.value = resp.data;
85
107
  indicator.value = selectedStac.value?.id ?? "";
86
108
  })
@@ -102,7 +124,26 @@ export const useSTAcStore = defineStore("stac", () => {
102
124
 
103
125
  await axios
104
126
  .get(absoluteUrl.value)
105
- .then((resp) => {
127
+ .then(async (resp) => {
128
+ // init eodash collections
129
+ const collectionUrls = extractCollectionUrls(
130
+ resp.data,
131
+ absoluteUrl.value,
132
+ );
133
+
134
+ await Promise.all(
135
+ collectionUrls.map((cu) => {
136
+ const ec = new EodashCollection(cu);
137
+ ec.fetchCollection();
138
+ return ec;
139
+ }),
140
+ ).then((collections) => {
141
+ // empty array from old collections
142
+ eodashCompareCollections.length = 0;
143
+ // update eodashCompareCollections
144
+ eodashCompareCollections.push(...collections);
145
+ });
146
+
106
147
  selectedCompareStac.value = resp.data;
107
148
  })
108
149
  .catch((err) => {
@@ -110,11 +151,20 @@ export const useSTAcStore = defineStore("stac", () => {
110
151
  });
111
152
  }
112
153
 
154
+ /**
155
+ * Reset selected compare stac object
156
+ *
157
+ */
158
+ async function resetSelectedCompareSTAC() {
159
+ selectedCompareStac.value = null;
160
+ }
161
+
113
162
  return {
114
163
  stac,
115
164
  loadSTAC,
116
165
  loadSelectedSTAC,
117
166
  loadSelectedCompareSTAC,
167
+ resetSelectedCompareSTAC,
118
168
  selectedStac,
119
169
  selectedCompareStac,
120
170
  };
@@ -260,10 +260,14 @@ export interface EodashStore {
260
260
  /**
261
261
  * Register EPSG projection in `eox-map` and adds it to {@link EodashStore.states.availableMapProjection `availableMapProjection`` }
262
262
  * */
263
- registerProjection: (code?: number | string) => Promise<void>;
263
+ registerProjection: (
264
+ code?: number | string | { name: string; def: string },
265
+ ) => Promise<void>;
264
266
 
265
267
  /** Change `eox-map` projection from an `EPSG` code */
266
- changeMapProjection: (code?: number | string) => Promise<void>;
268
+ changeMapProjection: (
269
+ code?: number | string | { name: string; def: string },
270
+ ) => Promise<void>;
267
271
  };
268
272
 
269
273
  /** Pinia store definition used to navigate the root STAC catalog. */