@eodash/eodash 5.7.1 → 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.
- package/core/client/eodashSTAC/EodashCollection.js +14 -5
- package/core/client/eodashSTAC/createLayers.js +193 -80
- package/core/client/eodashSTAC/helpers.js +330 -39
- package/core/client/eodashSTAC/mosaic.js +10 -4
- package/core/client/store/stac.js +29 -0
- package/core/client/types.ts +5 -0
- package/dist/client/{DashboardLayout-ePbdvUTE.js → DashboardLayout-DEs4f_Vy.js} +2 -2
- package/dist/client/{DynamicWebComponent-g5SdRbjY.js → DynamicWebComponent-PvnV88BA.js} +1 -1
- package/dist/client/EodashChart-D-3AGKZY.js +260 -0
- package/dist/client/{EodashDatePicker-CY1TrsDo.js → EodashDatePicker-Dm_goZzs.js} +3 -3
- package/dist/client/{EodashItemFilter-DzshHDlS.js → EodashItemFilter-CJy3zYzD.js} +2 -2
- package/dist/client/{EodashLayerControl-DMCeMkSd.js → EodashLayerControl-rL8UnpkA.js} +11 -19
- package/dist/client/{EodashLayoutSwitcher-iJ8mX1rF.js → EodashLayoutSwitcher-ZRlESI9O.js} +3 -3
- package/dist/client/{EodashMapBtns-C7Cr7q5Y.js → EodashMapBtns-CG7u2Aq8.js} +34 -33
- package/dist/client/{EodashStacInfo-K7-iuXa7.js → EodashStacInfo-CJhhxthD.js} +2 -2
- package/dist/client/{EodashTools-BEK7e7JM.js → EodashTools-CWyK8QJT.js} +4 -4
- package/dist/client/{ExportState-CqIzfMYQ.js → ExportState-BXhy5TOU.js} +19 -11
- package/dist/client/{Footer-1P0cmBOZ.js → Footer-DZPvnhcT.js} +1 -1
- package/dist/client/{Header-CkkBaBNh.js → Header-CiGsDE_a.js} +2 -2
- package/dist/client/{MobileLayout-BPf49kDU.js → MobileLayout-BJHW7x5V.js} +2 -2
- package/dist/client/{PopUp-DPZq5SWI.js → PopUp-7_XnhvCc.js} +3 -3
- package/dist/client/{ProcessList-DuI6WpS1.js → ProcessList-LL_UCbvc.js} +4 -4
- package/dist/client/{VDivider-Bj9LG_JV.js → VDivider-DWYM0WUr.js} +2 -2
- package/dist/client/{VImg-Ddv5OyMz.js → VImg-B75dgw2K.js} +2 -2
- package/dist/client/{VMain-7yqk_qC3.js → VMain-DvMmOL4f.js} +1 -1
- package/dist/client/{VTooltip-2hAJyEoa.js → VTooltip-ClWHUmWL.js} +2 -2
- package/dist/client/{WidgetsContainer-2DOrlwCB.js → WidgetsContainer-BqaWs4ch.js} +1 -1
- package/dist/client/{asWebComponent-BlFN2lkB.js → asWebComponent-IZanwL-A.js} +239 -91
- package/dist/client/{async-B2H8ZwUK.js → async-CiNIOBVz.js} +31 -29
- package/dist/client/{create-layers-config-u_vn5hPk.js → create-layers-config-3S3y_kZg.js} +1 -1
- package/dist/client/{dialog-transition-BrMkMiNa.js → dialog-transition-c4ZSnzac.js} +2 -2
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-DAlror6d.js → forwardRefs-B-c1_6yo.js} +2 -2
- package/dist/client/{handling-B6I1V5eG.js → handling-NvY8Csry.js} +3 -4
- package/dist/client/{helpers-CBqIUSXJ.js → helpers-BFuh19CP.js} +328 -40
- package/dist/client/{index-DhKU6KqM.js → index-1wMAyuNL.js} +17 -9
- package/dist/client/{index-DXLz4sFR.js → index-B8jGJSTA.js} +4 -4
- package/dist/client/{index-DjQlbWbJ.js → index-BKQQJkhy.js} +166 -61
- package/dist/client/{index-BWq1ZKaV.js → index-D0jUyol8.js} +10 -11
- package/dist/client/{index-CJ9UI3ln.js → index-KGxz5Egv.js} +2 -2
- package/dist/client/{mosaic-BFYLEwyx.js → mosaic-vHvSuih6.js} +10 -6
- package/dist/client/templates.js +6 -7
- package/dist/client/{transition-D_W6Wn9v.js → transition-BkyUsZh_.js} +1 -1
- package/dist/types/core/client/eodashSTAC/helpers.d.ts +47 -7
- package/dist/types/core/client/store/stac.d.ts +8 -2
- package/dist/types/core/client/types.d.ts +5 -0
- package/dist/types/templates/explore.d.ts +1 -0
- package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +1 -1
- package/package.json +5 -5
- package/templates/baseConfig.js +2 -1
- package/templates/compare.js +0 -1
- package/templates/expert.js +2 -3
- package/templates/explore.js +1 -0
- package/templates/lite.js +0 -1
- package/widgets/EodashChart.vue +161 -21
- package/widgets/EodashItemCatalog/methods/map.js +0 -1
- package/widgets/EodashLayerControl.vue +10 -15
- package/widgets/EodashMap/index.vue +3 -1
- package/widgets/EodashMap/methods/btns.js +27 -26
- package/widgets/EodashMap/methods/use-map-loading.js +8 -2
- package/widgets/EodashProcess/index.vue +135 -16
- package/widgets/EodashProcess/methods/composables.js +13 -0
- package/widgets/EodashProcess/methods/outputs.js +0 -1
- package/widgets/EodashProcess/methods/utils.js +29 -27
- package/widgets/ExportState.vue +13 -4
- package/dist/client/EodashChart-ChrkA5oS.js +0 -145
|
@@ -19,7 +19,9 @@ export const useSTAcStore: import("pinia").StoreDefinition<"stac", Pick<{
|
|
|
19
19
|
url: string;
|
|
20
20
|
titilerVersion?: 1 | 2;
|
|
21
21
|
})[]>;
|
|
22
|
-
|
|
22
|
+
colormapRegistry: import("vue").Ref<Record<string, string[]> | null, Record<string, string[]> | null>;
|
|
23
|
+
loadColormapRegistry: (registry: string | Record<string, string[]>) => Promise<void>;
|
|
24
|
+
}, "stac" | "stacEndpoint" | "rasterEndpoint" | "isApi" | "selectedStac" | "selectedCompareStac" | "selectedItem" | "selectedCompareItem" | "supportedUpscalingEndpoints" | "colormapRegistry">, Pick<{
|
|
23
25
|
stacEndpoint: import("vue").Ref<string | null, string | null>;
|
|
24
26
|
rasterEndpoint: import("vue").Ref<string | null, string | null>;
|
|
25
27
|
isApi: import("vue").Ref<boolean, boolean>;
|
|
@@ -40,6 +42,8 @@ export const useSTAcStore: import("pinia").StoreDefinition<"stac", Pick<{
|
|
|
40
42
|
url: string;
|
|
41
43
|
titilerVersion?: 1 | 2;
|
|
42
44
|
})[]>;
|
|
45
|
+
colormapRegistry: import("vue").Ref<Record<string, string[]> | null, Record<string, string[]> | null>;
|
|
46
|
+
loadColormapRegistry: (registry: string | Record<string, string[]>) => Promise<void>;
|
|
43
47
|
}, never>, Pick<{
|
|
44
48
|
stacEndpoint: import("vue").Ref<string | null, string | null>;
|
|
45
49
|
rasterEndpoint: import("vue").Ref<string | null, string | null>;
|
|
@@ -61,4 +65,6 @@ export const useSTAcStore: import("pinia").StoreDefinition<"stac", Pick<{
|
|
|
61
65
|
url: string;
|
|
62
66
|
titilerVersion?: 1 | 2;
|
|
63
67
|
})[]>;
|
|
64
|
-
|
|
68
|
+
colormapRegistry: import("vue").Ref<Record<string, string[]> | null, Record<string, string[]> | null>;
|
|
69
|
+
loadColormapRegistry: (registry: string | Record<string, string[]>) => Promise<void>;
|
|
70
|
+
}, "init" | "loadSTAC" | "loadSelectedSTAC" | "loadSelectedCompareSTAC" | "resetSelectedCompareSTAC" | "loadColormapRegistry">>;
|
|
@@ -259,6 +259,7 @@ export type StacEndpoint = string | {
|
|
|
259
259
|
url: string;
|
|
260
260
|
titilerVersion?: 1 | 2;
|
|
261
261
|
}>;
|
|
262
|
+
colormapRegistry?: string | Record<string, string[]>;
|
|
262
263
|
};
|
|
263
264
|
/** @group Eodash */
|
|
264
265
|
export interface EodashFont {
|
|
@@ -518,6 +519,10 @@ export interface Render {
|
|
|
518
519
|
expression?: string;
|
|
519
520
|
/** Zoom levels range applicable for the visualization */
|
|
520
521
|
minmax_zoom?: number[];
|
|
522
|
+
/** Band indexes to apply the rendering to. */
|
|
523
|
+
bidx?: number[];
|
|
524
|
+
/** Tile size to request from the tile server. */
|
|
525
|
+
tilesize?: number;
|
|
521
526
|
}
|
|
522
527
|
/** @ignore */
|
|
523
528
|
export interface TitilerSTACParameters {
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
*
|
|
3
3
|
* @param {import("../../../../EodashProcess/types").CustomEnpointInput} param0
|
|
4
4
|
*/
|
|
5
|
-
export function handleEOxHubEndpoint({ links, jsonformValue, isPolling, selectedStac, jobs, enableCompare, }: import("../../../../EodashProcess/types").CustomEnpointInput): Promise<(import("@eox/map/src/layers").EOxLayerType<"Vector", "Vector"> | import("@eox/map/src/layers").EOxLayerType<"Vector", "FlatGeoBuf"> | import("@eox/map/src/layers").EOxLayerType<"Vector", "Cluster"> | import("@eox/map/src/layers").EOxLayerType<"VectorTile", "VectorTile"> | import("@eox/map/src/layers").EOxLayerType<"WebGLTile", "GeoTIFF"> | import("@eox/map/src/layers").EOxLayerType<"WebGLTile", "GeoZarr"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "OSM"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "WMTSCapabilities"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "StadiaMaps"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "WMTS"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "XYZ"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "TileJSON"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "TileArcGISRest"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "TileDebug"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "TileImage"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "TileWMS"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "UrlTile"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "BingMaps"> | import("@eox/map/src/layers").EOxLayerType<"Image", "Image"> | import("@eox/map/src/layers").EOxLayerType<"Image", "ImageCanvas"> | import("@eox/map/src/layers").EOxLayerType<"Image", "ImageStatic"> | import("@eox/map/src/layers").EOxLayerType<"Image", "ImageWMS"> | import("@eox/map/src/layers").EOxLayerType<"Image", "Raster"> | import("@eox/map/src/layers").EOxLayerType<"Image", "IIIF"> | import("@eox/map/src/layers").EOxLayerTypeMapboxStyle | import("@eox/map/src/layers").EOxLayerTypeGroup)[] | undefined>;
|
|
5
|
+
export function handleEOxHubEndpoint({ links, jsonformValue, isPolling, selectedStac, jobs, enableCompare, }: import("../../../../EodashProcess/types").CustomEnpointInput): Promise<(import("@eox/map/src/layers").EOxLayerType<"Vector", "Vector"> | import("@eox/map/src/layers").EOxLayerType<"Vector", "FlatGeoBuf"> | import("@eox/map/src/layers").EOxLayerType<"Vector", "Cluster"> | import("@eox/map/src/layers").EOxLayerType<"VectorImage", "Vector"> | import("@eox/map/src/layers").EOxLayerType<"Heatmap", "Vector"> | import("@eox/map/src/layers").EOxLayerType<"WebGLVector", "Vector"> | import("@eox/map/src/layers").EOxLayerType<"WebGLPoints", "Vector"> | import("@eox/map/src/layers").EOxLayerType<"Graticule", never> | import("@eox/map/src/layers").EOxLayerType<"VectorTile", "VectorTile"> | import("@eox/map/src/layers").EOxLayerType<"WebGLTile", "GeoTIFF"> | import("@eox/map/src/layers").EOxLayerType<"WebGLTile", "GeoZarr"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "OSM"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "WMTSCapabilities"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "StadiaMaps"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "WMTS"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "XYZ"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "TileJSON"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "TileArcGISRest"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "TileDebug"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "TileImage"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "TileWMS"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "UrlTile"> | import("@eox/map/src/layers").EOxLayerType<"Tile", "BingMaps"> | import("@eox/map/src/layers").EOxLayerType<"Image", "Image"> | import("@eox/map/src/layers").EOxLayerType<"Image", "ImageCanvas"> | import("@eox/map/src/layers").EOxLayerType<"Image", "ImageStatic"> | import("@eox/map/src/layers").EOxLayerType<"Image", "ImageWMS"> | import("@eox/map/src/layers").EOxLayerType<"Image", "Raster"> | import("@eox/map/src/layers").EOxLayerType<"Image", "IIIF"> | import("@eox/map/src/layers").EOxLayerType<"STAC", never> | import("@eox/map/src/layers").EOxLayerTypeMapboxStyle | import("@eox/map/src/layers").EOxLayerTypeGroup)[] | undefined>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eodash/eodash",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "./dist/types/core/client/types.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -76,11 +76,11 @@
|
|
|
76
76
|
"@eox/geosearch": "^1.2.0",
|
|
77
77
|
"@eox/itemfilter": "^1.17.3",
|
|
78
78
|
"@eox/jsonform": "^1.12.1",
|
|
79
|
-
"@eox/layercontrol": "^1.
|
|
79
|
+
"@eox/layercontrol": "^1.8.0",
|
|
80
80
|
"@eox/layout": "^1.0.0",
|
|
81
|
-
"@eox/map": "^2.
|
|
81
|
+
"@eox/map": "^2.7.0",
|
|
82
82
|
"@eox/stacinfo": "^1.2.0",
|
|
83
|
-
"@eox/timecontrol": "
|
|
83
|
+
"@eox/timecontrol": "^2.6.0",
|
|
84
84
|
"@eox/ui": "^1.1.0",
|
|
85
85
|
"@mdi/js": "^7.4.47",
|
|
86
86
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"devDependencies": {
|
|
113
113
|
"@babel/types": "^7.29.7",
|
|
114
114
|
"@eox/eslint-config": "^2.1.0",
|
|
115
|
-
"@eox/pages-theme-eox": "^1.
|
|
115
|
+
"@eox/pages-theme-eox": "^1.9.0",
|
|
116
116
|
"@pinia/testing": "^1.0.3",
|
|
117
117
|
"@types/json-schema": "^7.0.15",
|
|
118
118
|
"@types/mustache": "^4.2.6",
|
package/templates/baseConfig.js
CHANGED
|
@@ -20,7 +20,8 @@ const baseConfig = {
|
|
|
20
20
|
{ url: "openveda.cloud", titilerVersion: 1 },
|
|
21
21
|
{ url: "api.explorer.eopf.copernicus.eu", titilerVersion: 2 },
|
|
22
22
|
],
|
|
23
|
-
|
|
23
|
+
colormapRegistry:
|
|
24
|
+
"https://raw.githubusercontent.com/eurodatacube/eodash-assets/refs/heads/main/defaults/colormaps.json",
|
|
24
25
|
},
|
|
25
26
|
brand: {
|
|
26
27
|
noLayout: true,
|
package/templates/compare.js
CHANGED
package/templates/expert.js
CHANGED
|
@@ -40,7 +40,6 @@ export default {
|
|
|
40
40
|
},
|
|
41
41
|
source: {
|
|
42
42
|
type: "XYZ",
|
|
43
|
-
//@ts-expect-error todo
|
|
44
43
|
url: "https://s2maps-tiles.eu/wmts/1.0.0/terrain-light_3857/default/g/{z}/{y}/{x}.jpeg",
|
|
45
44
|
},
|
|
46
45
|
},
|
|
@@ -96,7 +95,7 @@ export default {
|
|
|
96
95
|
id: "Layercontrol",
|
|
97
96
|
type: "internal",
|
|
98
97
|
title: "Layers",
|
|
99
|
-
layout: { x: 0, y: 1, w: "3/3/2", h:
|
|
98
|
+
layout: { x: 0, y: 1, w: "3/3/2", h: 10 },
|
|
100
99
|
widget: {
|
|
101
100
|
name: "EodashLayerControl",
|
|
102
101
|
properties: {
|
|
@@ -147,7 +146,7 @@ export default {
|
|
|
147
146
|
id: "Processes",
|
|
148
147
|
type: "internal",
|
|
149
148
|
title: "Processes",
|
|
150
|
-
layout: { x: "9/9/10", y: 6, w: "3/3/2", h:
|
|
149
|
+
layout: { x: "9/9/10", y: 6, w: "3/3/2", h: 6 },
|
|
151
150
|
widget: {
|
|
152
151
|
name: "EodashProcess",
|
|
153
152
|
},
|
package/templates/explore.js
CHANGED
package/templates/lite.js
CHANGED
package/widgets/EodashChart.vue
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div ref="container">
|
|
3
|
-
<div
|
|
2
|
+
<div ref="container" class="eodash-chart-wrapper">
|
|
3
|
+
<div
|
|
4
|
+
class="chart-frame"
|
|
5
|
+
:style="{ paddingBottom: hasBindings ? '25px' : '0px' }"
|
|
6
|
+
>
|
|
4
7
|
<button
|
|
5
8
|
v-if="usedChartData && usedChartSpec"
|
|
6
9
|
class="chart-toggle"
|
|
@@ -12,9 +15,8 @@
|
|
|
12
15
|
</svg>
|
|
13
16
|
</button>
|
|
14
17
|
<eox-chart
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
.spec="toRaw(usedChartSpec)"
|
|
18
|
+
v-if="usedChartData && renderedChartSpec"
|
|
19
|
+
.spec="toRaw(renderedChartSpec)"
|
|
18
20
|
:key="chartRenderKey"
|
|
19
21
|
.dataValues="toRaw(usedChartData)"
|
|
20
22
|
@click:item="onChartClick"
|
|
@@ -33,6 +35,8 @@ import {
|
|
|
33
35
|
ref,
|
|
34
36
|
onMounted,
|
|
35
37
|
onBeforeUnmount,
|
|
38
|
+
watch,
|
|
39
|
+
nextTick,
|
|
36
40
|
} from "vue";
|
|
37
41
|
import { onChartClick } from "./EodashProcess/methods/handling";
|
|
38
42
|
import {
|
|
@@ -67,27 +71,136 @@ const usedChartSpec = computed(() => {
|
|
|
67
71
|
return enableCompare ? compareChartSpec.value : chartSpec.value;
|
|
68
72
|
});
|
|
69
73
|
|
|
74
|
+
const hasBindings = computed(() => {
|
|
75
|
+
const spec = usedChartSpec.value;
|
|
76
|
+
if (!spec) return false;
|
|
77
|
+
|
|
78
|
+
// Recursively search for any object with a 'bind' key that represents a physical UI input
|
|
79
|
+
let found = false;
|
|
80
|
+
/** @param {any} obj */
|
|
81
|
+
const searchBindings = (obj) => {
|
|
82
|
+
if (found || !obj || typeof obj !== "object") return;
|
|
83
|
+
|
|
84
|
+
// UI bindings that take up physical DOM space are objects with an 'input' property.
|
|
85
|
+
if (
|
|
86
|
+
"bind" in obj &&
|
|
87
|
+
typeof obj.bind === "object" &&
|
|
88
|
+
obj.bind !== null &&
|
|
89
|
+
"input" in obj.bind
|
|
90
|
+
) {
|
|
91
|
+
found = true;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
Object.values(obj).forEach(searchBindings);
|
|
95
|
+
};
|
|
96
|
+
searchBindings(spec);
|
|
97
|
+
return found;
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const renderedChartSpec = ref(null);
|
|
101
|
+
|
|
102
|
+
watch(
|
|
103
|
+
usedChartSpec,
|
|
104
|
+
(newSpec) => {
|
|
105
|
+
if (!newSpec) {
|
|
106
|
+
renderedChartSpec.value = null;
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Create a deep copy so we can safely mutate it
|
|
111
|
+
const adjustedSpec = JSON.parse(JSON.stringify(newSpec));
|
|
112
|
+
|
|
113
|
+
// Force the chart to be fully responsive to its CSS container
|
|
114
|
+
adjustedSpec.height = "container";
|
|
115
|
+
adjustedSpec.width = "container";
|
|
116
|
+
|
|
117
|
+
// Delay passing the spec to eox-chart until the next DOM update cycle.
|
|
118
|
+
// This ensures the dynamic chartStyles are physically applied
|
|
119
|
+
// to the container BEFORE Vega calculates its canvas size.
|
|
120
|
+
nextTick(() => {
|
|
121
|
+
renderedChartSpec.value = adjustedSpec;
|
|
122
|
+
chartRenderKey.value = Math.random(); // Force eox-chart to completely remount
|
|
123
|
+
|
|
124
|
+
// Force a browser-level resize event after the chart mounts.
|
|
125
|
+
// This tells Vega to re-read the container dimensions once the CSS has finished painting.
|
|
126
|
+
setTimeout(() => {
|
|
127
|
+
window.dispatchEvent(new Event("resize"));
|
|
128
|
+
}, 150);
|
|
129
|
+
});
|
|
130
|
+
},
|
|
131
|
+
{ immediate: true },
|
|
132
|
+
);
|
|
133
|
+
|
|
70
134
|
const chartRenderKey = ref(0);
|
|
71
|
-
const frameHeight = ref(225);
|
|
72
135
|
const containerEl = useTemplateRef("container");
|
|
73
136
|
|
|
74
|
-
/**
|
|
75
|
-
@type { MutationObserver | null}
|
|
76
|
-
*/
|
|
137
|
+
/** @type {MutationObserver | null} */
|
|
77
138
|
let observer = null;
|
|
139
|
+
/** @type {number | null} */
|
|
140
|
+
let styleInterval = null;
|
|
78
141
|
|
|
79
142
|
onMounted(() => {
|
|
80
143
|
const el = containerEl.value;
|
|
81
144
|
if (!el) return;
|
|
82
145
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
146
|
+
// Continuously inject basic styling for the bindings form to make it look decent
|
|
147
|
+
styleInterval = window.setInterval(() => {
|
|
148
|
+
if (el) {
|
|
149
|
+
const eoxChart = el.querySelector("eox-chart");
|
|
150
|
+
if (eoxChart && eoxChart.shadowRoot) {
|
|
151
|
+
if (!eoxChart.shadowRoot.querySelector("#eodash-chart-styles")) {
|
|
152
|
+
const style = document.createElement("style");
|
|
153
|
+
style.id = "eodash-chart-styles";
|
|
154
|
+
style.innerHTML = `
|
|
155
|
+
* {
|
|
156
|
+
box-sizing: border-box !important;
|
|
157
|
+
}
|
|
158
|
+
#vis {
|
|
159
|
+
min-height: 100px !important;
|
|
160
|
+
flex: 1 1 auto !important;
|
|
161
|
+
}
|
|
162
|
+
:host, .vega-embed {
|
|
163
|
+
display: flex !important;
|
|
164
|
+
flex-direction: column !important;
|
|
165
|
+
height: 100% !important;
|
|
166
|
+
padding: 0 !important;
|
|
167
|
+
margin: 0 !important;
|
|
168
|
+
}
|
|
169
|
+
.vega-bindings {
|
|
170
|
+
flex: 0 0 auto !important;
|
|
171
|
+
display: flex !important;
|
|
172
|
+
flex-wrap: wrap;
|
|
173
|
+
gap: 2px !important;
|
|
174
|
+
background: rgba(255, 255, 255, 0.85);
|
|
175
|
+
padding: 6px 12px !important;
|
|
176
|
+
border-radius: 6px;
|
|
177
|
+
box-shadow: 0 2px 5px rgba(0,0,0,0.15);
|
|
178
|
+
margin: 0 !important;
|
|
179
|
+
margin-top: -10px !important;
|
|
180
|
+
z-index: 10;
|
|
181
|
+
}
|
|
182
|
+
.vega-bindings:empty {
|
|
183
|
+
display: none !important;
|
|
184
|
+
}
|
|
185
|
+
.vega-embed > canvas, .vega-embed > svg {
|
|
186
|
+
height: 100% !important;
|
|
187
|
+
max-width: 100% !important;
|
|
188
|
+
object-fit: contain;
|
|
189
|
+
}
|
|
190
|
+
.vega-bind {
|
|
191
|
+
display: flex;
|
|
192
|
+
align-items: center;
|
|
193
|
+
gap: 6px;
|
|
194
|
+
margin-bottom: 0 !important;
|
|
195
|
+
}
|
|
196
|
+
`;
|
|
197
|
+
eoxChart.shadowRoot.appendChild(style);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}, 200);
|
|
88
202
|
|
|
89
|
-
//
|
|
90
|
-
// we create an observer when display of overlay is not none anymore
|
|
203
|
+
// For mobile view, handle overlay display changes
|
|
91
204
|
const overlay = getOverlayParent(el);
|
|
92
205
|
if (!overlay) return;
|
|
93
206
|
|
|
@@ -95,7 +208,6 @@ onMounted(() => {
|
|
|
95
208
|
const style = getComputedStyle(overlay);
|
|
96
209
|
const visible = style.display !== "none";
|
|
97
210
|
if (visible) {
|
|
98
|
-
// forcibly rerender chart, otherwise size of canvas is 0
|
|
99
211
|
chartRenderKey.value = Math.random();
|
|
100
212
|
}
|
|
101
213
|
});
|
|
@@ -108,13 +220,14 @@ onMounted(() => {
|
|
|
108
220
|
|
|
109
221
|
onBeforeUnmount(() => {
|
|
110
222
|
observer?.disconnect();
|
|
223
|
+
if (styleInterval) window.clearInterval(styleInterval);
|
|
111
224
|
});
|
|
112
225
|
|
|
113
226
|
const chartStyles = computed(() => {
|
|
114
|
-
|
|
115
|
-
height:
|
|
227
|
+
return {
|
|
228
|
+
height: "100%",
|
|
229
|
+
width: "100%",
|
|
116
230
|
};
|
|
117
|
-
return styles;
|
|
118
231
|
});
|
|
119
232
|
|
|
120
233
|
const toggleIcon = computed(() =>
|
|
@@ -125,14 +238,41 @@ function toggleLayout() {
|
|
|
125
238
|
areChartsSeparateLayout.value = !areChartsSeparateLayout.value;
|
|
126
239
|
}
|
|
127
240
|
</script>
|
|
241
|
+
|
|
242
|
+
<style>
|
|
243
|
+
/* Force the outer dashboard panel wrapping this component to utilize 100% height in fullscreen mode */
|
|
244
|
+
.bg-surface:has(.eodash-chart-wrapper) {
|
|
245
|
+
height: 100%;
|
|
246
|
+
display: flex;
|
|
247
|
+
flex-direction: column;
|
|
248
|
+
}
|
|
249
|
+
</style>
|
|
250
|
+
|
|
128
251
|
<style scoped>
|
|
252
|
+
.eodash-chart-wrapper {
|
|
253
|
+
height: 100%; /* Force full height in fullscreen layout */
|
|
254
|
+
flex-grow: 1;
|
|
255
|
+
min-height: 180px; /* Prevent chart from becoming unusably small */
|
|
256
|
+
display: flex;
|
|
257
|
+
flex-direction: column;
|
|
258
|
+
}
|
|
259
|
+
|
|
129
260
|
.chart-frame {
|
|
130
261
|
position: relative;
|
|
262
|
+
flex-grow: 1;
|
|
263
|
+
min-height: 180px; /* Prevent chart from becoming unusably small */
|
|
264
|
+
display: flex;
|
|
265
|
+
flex-direction: column;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
eox-chart {
|
|
269
|
+
flex-grow: 1;
|
|
270
|
+
min-height: 0;
|
|
131
271
|
}
|
|
132
272
|
|
|
133
273
|
.chart-toggle {
|
|
134
274
|
position: absolute;
|
|
135
|
-
top:
|
|
275
|
+
top: 8px;
|
|
136
276
|
right: 46px;
|
|
137
277
|
z-index: 2;
|
|
138
278
|
cursor: pointer;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
:key="mapElement"
|
|
6
6
|
v-bind="config"
|
|
7
7
|
:for="mapElement"
|
|
8
|
+
.colormapRegistry="colormapRegistry"
|
|
8
9
|
.showLayerZoomState="true"
|
|
9
10
|
.customEditorInterfaces="bandsEditorInterface"
|
|
10
11
|
@datetime:updated="debouncedHandleDateTime"
|
|
@@ -29,16 +30,19 @@
|
|
|
29
30
|
<script setup>
|
|
30
31
|
import "color-legend-element";
|
|
31
32
|
import "@eox/timecontrol";
|
|
32
|
-
import { computed, ref
|
|
33
|
+
import { computed, ref } from "vue";
|
|
33
34
|
import { mapEl, mapCompareEl } from "@/store/states";
|
|
34
|
-
import { getColFromLayer } from "@/eodashSTAC/helpers";
|
|
35
35
|
import {
|
|
36
36
|
eodashCollections,
|
|
37
37
|
eodashCompareCollections,
|
|
38
38
|
layerControlFormValue,
|
|
39
39
|
layerControlFormValueCompare,
|
|
40
40
|
} from "@/utils/states";
|
|
41
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
getColFromLayer,
|
|
43
|
+
updateGeoZarrBands,
|
|
44
|
+
updateLayerUrl,
|
|
45
|
+
} from "@/eodashSTAC/helpers";
|
|
42
46
|
import { storeToRefs } from "pinia";
|
|
43
47
|
import { useSTAcStore } from "@/store/stac";
|
|
44
48
|
import { bandsEditorInterface } from "@/utils/bands-editor";
|
|
@@ -99,7 +103,8 @@ const enableLayoutSwitcher = computed(
|
|
|
99
103
|
() => !!props.layoutTarget && !!props.layoutIcon,
|
|
100
104
|
);
|
|
101
105
|
|
|
102
|
-
const { selectedCompareStac, selectedStac } =
|
|
106
|
+
const { selectedCompareStac, selectedStac, colormapRegistry } =
|
|
107
|
+
storeToRefs(useSTAcStore());
|
|
103
108
|
|
|
104
109
|
const showControls = computed(() => {
|
|
105
110
|
if (props.map === "second") {
|
|
@@ -115,20 +120,9 @@ const mapElement = props.map === "second" ? mapCompareEl : mapEl;
|
|
|
115
120
|
/** @type { import("vue").Ref<import("@eox/layercontrol").EOxLayerControl | null>} */
|
|
116
121
|
const eoxLayercontrol = ref(null);
|
|
117
122
|
|
|
118
|
-
// eox-timecontrol re-fires datetime:updated after layer reassignment;
|
|
119
|
-
// dedupe by (collectionId, datetime)
|
|
120
|
-
const processedDatetimes = new Map();
|
|
121
|
-
watch([selectedStac, selectedCompareStac], () => processedDatetimes.clear());
|
|
122
|
-
|
|
123
123
|
/** @param {CustomEvent<{layer:import('ol/layer').Layer; datetime:string;}>} evt */
|
|
124
124
|
const handleDatetimeUpdate = async (evt) => {
|
|
125
125
|
const { layer, datetime } = evt.detail;
|
|
126
|
-
const collectionId = layer.get("id")?.split(";:;")[0] ?? layer.get("id");
|
|
127
|
-
if (processedDatetimes.get(collectionId) === datetime) return;
|
|
128
|
-
// First event per collection is eox-timecontrol's mount echo.
|
|
129
|
-
const isFirstEvent = !processedDatetimes.has(collectionId);
|
|
130
|
-
processedDatetimes.set(collectionId, datetime);
|
|
131
|
-
if (isFirstEvent) return;
|
|
132
126
|
|
|
133
127
|
const ec = await getColFromLayer(eodashCols, layer);
|
|
134
128
|
|
|
@@ -185,6 +179,7 @@ const debouncedHandleDateTime = (evt) => {
|
|
|
185
179
|
*/
|
|
186
180
|
const onLayerConfigChange = (evt) => {
|
|
187
181
|
updateGeoZarrBands(evt.detail.layer, evt.detail.jsonformValue);
|
|
182
|
+
updateLayerUrl(evt.detail.layer, evt.detail.jsonformValue);
|
|
188
183
|
|
|
189
184
|
if (props.map === "second") {
|
|
190
185
|
layerControlFormValueCompare.value = evt.detail.jsonformValue;
|
|
@@ -271,7 +271,9 @@ const controls = computed(() => {
|
|
|
271
271
|
controlsObj.MousePosition = {
|
|
272
272
|
projection: "EPSG:4326",
|
|
273
273
|
coordinateFormat: (c) => {
|
|
274
|
-
|
|
274
|
+
if (!c) return "";
|
|
275
|
+
const [lon, lat] = c;
|
|
276
|
+
return `${Math.abs(lat).toFixed(3)} °${lat >= 0 ? "N" : "S"}, ${Math.abs(lon).toFixed(3)} °${lon >= 0 ? "E" : "W"}`;
|
|
275
277
|
},
|
|
276
278
|
target: cursorCoordsRef.value,
|
|
277
279
|
};
|
|
@@ -76,37 +76,38 @@ function showAllPanels() {
|
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
78
|
*
|
|
79
|
-
* @param {import("@eox/map").EoxLayer[]} layers
|
|
80
|
-
* @
|
|
79
|
+
* @param {import("@eox/map").EoxLayer[]} layers - eox map layers
|
|
80
|
+
* @returns {import("@eox/map").EoxLayer[]} anonymized Cors
|
|
81
81
|
*/
|
|
82
82
|
function addCorsAnonym(layers) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
83
|
+
return /** @type {import("@eox/map").EoxLayer[]} */ (
|
|
84
|
+
layers.map((layer) => {
|
|
85
|
+
if (layer.type === "Group") {
|
|
86
|
+
layer.layers = addCorsAnonym([...(layer.layers ?? [])]);
|
|
87
|
+
return layer;
|
|
88
|
+
}
|
|
89
|
+
// check if not mapbox style as a fix for ts error
|
|
90
|
+
if (layer.type === "MapboxStyle") {
|
|
91
|
+
return layer;
|
|
92
|
+
}
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
crossOrigin: "anonymous",
|
|
100
|
-
},
|
|
101
|
-
...(layer.sources && {
|
|
102
|
-
sources: layer.sources.map((source) => ({
|
|
103
|
-
...source,
|
|
94
|
+
return {
|
|
95
|
+
...layer,
|
|
96
|
+
...("source" in layer && {
|
|
97
|
+
source: {
|
|
98
|
+
...layer.source,
|
|
104
99
|
crossOrigin: "anonymous",
|
|
105
|
-
}
|
|
100
|
+
},
|
|
101
|
+
...(layer.sources && {
|
|
102
|
+
sources: layer.sources.map((source) => ({
|
|
103
|
+
...source,
|
|
104
|
+
crossOrigin: "anonymous",
|
|
105
|
+
})),
|
|
106
|
+
}),
|
|
106
107
|
}),
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
108
|
+
};
|
|
109
|
+
})
|
|
110
|
+
);
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
export const onMapZoomOut = () => {
|
|
@@ -10,11 +10,15 @@ import { loading } from "@/store/states";
|
|
|
10
10
|
* @param {import("vue").Ref<import("@eox/map").EOxMap | null>} compareMapElement
|
|
11
11
|
*/
|
|
12
12
|
export const useMapLoading = (mapElement, compareMapElement) => {
|
|
13
|
+
// This instance's outstanding loads, so unmount subtracts only its share.
|
|
14
|
+
let localLoads = 0;
|
|
13
15
|
const startHandler = () => {
|
|
16
|
+
localLoads++;
|
|
14
17
|
loading.activeLoads++;
|
|
15
18
|
};
|
|
16
19
|
const endHandler = () => {
|
|
17
|
-
|
|
20
|
+
localLoads = Math.max(0, localLoads - 1);
|
|
21
|
+
loading.activeLoads = Math.max(0, loading.activeLoads - 1);
|
|
18
22
|
};
|
|
19
23
|
|
|
20
24
|
/** @param {import("@eox/map").EOxMap | null} newMapEl */
|
|
@@ -45,8 +49,10 @@ export const useMapLoading = (mapElement, compareMapElement) => {
|
|
|
45
49
|
onUnmounted(() => {
|
|
46
50
|
mapElement.value?.map.removeEventListener("loadstart", startHandler);
|
|
47
51
|
mapElement.value?.map.removeEventListener("loadend", endHandler);
|
|
52
|
+
compareMapElement.value?.map.removeEventListener("loadstart", startHandler);
|
|
53
|
+
compareMapElement.value?.map.removeEventListener("loadend", endHandler);
|
|
48
54
|
stopMainWatcher();
|
|
49
55
|
stopCompareWatcher();
|
|
50
|
-
loading.activeLoads = 0;
|
|
56
|
+
loading.activeLoads = Math.max(0, loading.activeLoads - localLoads);
|
|
51
57
|
});
|
|
52
58
|
};
|