@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
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { aa as useEmitLayersUpdate } from './asWebComponent-
|
|
1
|
+
import { C as replaceLayer, e as extractLayerConfig, G as extractLayerLegend, m as mergeGeojsons, g as axios, ag as getCompareLayers, F as getLayers, aj as axios$1, U as compareIndicator, Q as indicator } from './helpers-BFuh19CP.js';
|
|
2
|
+
import { aa as useEmitLayersUpdate } from './asWebComponent-IZanwL-A.js';
|
|
3
3
|
import { isMulti } from '@eox/jsonform/src/custom-inputs/spatial/utils';
|
|
4
4
|
import log from 'loglevel';
|
|
5
5
|
|
|
@@ -83,10 +83,10 @@ async function createTiffLayerDefinition(
|
|
|
83
83
|
}
|
|
84
84
|
// We want to make sure the urls are alphabetically sorted
|
|
85
85
|
urls = urls.sort();
|
|
86
|
-
|
|
86
|
+
|
|
87
87
|
const layerdef =
|
|
88
88
|
urls.length > 0
|
|
89
|
-
? {
|
|
89
|
+
? /** @type {import("@eox/map/src/layers").EOxLayerType<"WebGLTile","GeoTIFF">} */ ({
|
|
90
90
|
type: "WebGLTile",
|
|
91
91
|
source: {
|
|
92
92
|
type: "GeoTIFF",
|
|
@@ -100,7 +100,7 @@ async function createTiffLayerDefinition(
|
|
|
100
100
|
layerControlToolsExpand: true,
|
|
101
101
|
},
|
|
102
102
|
...(style && { style: style }),
|
|
103
|
-
}
|
|
103
|
+
})
|
|
104
104
|
: undefined;
|
|
105
105
|
|
|
106
106
|
// We want to see if the currently selected indicator uses a
|
|
@@ -303,31 +303,33 @@ async function creatAsyncProcessLayerDefinitions(
|
|
|
303
303
|
|
|
304
304
|
switch (resultItem.type) {
|
|
305
305
|
case "image/tiff": {
|
|
306
|
-
layers.push(
|
|
307
|
-
type
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
...(selectedStac["eodash:mapProjection"]?.["name"] && {
|
|
306
|
+
layers.push(
|
|
307
|
+
/** @type {import("@eox/map/src/layers").EOxLayerType<"WebGLTile","GeoTIFF">} */ ({
|
|
308
|
+
type: "WebGLTile",
|
|
309
|
+
properties: {
|
|
310
|
+
id: endpointLink.id + "_process" + resultItem.id + postfixId,
|
|
311
|
+
title:
|
|
312
|
+
"Results " +
|
|
313
|
+
(selectedStac?.id ?? "") +
|
|
314
|
+
" " +
|
|
315
|
+
(resultItem.id ?? ""),
|
|
316
|
+
layerControlToolsExpand: true,
|
|
317
|
+
...(layerConfig && { layerConfig }),
|
|
318
|
+
...extraProperties,
|
|
319
|
+
},
|
|
320
|
+
source: {
|
|
321
|
+
type: "GeoTIFF",
|
|
322
|
+
normalize: !style,
|
|
323
|
+
sources: resultItem.urls.map((url) => ({ url })),
|
|
325
324
|
//@ts-expect-error TODO
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
325
|
+
...(selectedStac["eodash:mapProjection"]?.["name"] && {
|
|
326
|
+
//@ts-expect-error TODO
|
|
327
|
+
projection: selectedStac["eodash:mapProjection"]["name"],
|
|
328
|
+
}),
|
|
329
|
+
},
|
|
330
|
+
...(style && { style }),
|
|
331
|
+
}),
|
|
332
|
+
);
|
|
331
333
|
break;
|
|
332
334
|
}
|
|
333
335
|
case "application/geo+json": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createVNode, Transition, mergeProps } from 'vue';
|
|
2
|
-
import { g as genericComponent, ar as PREFERS_REDUCED_MOTION, p as propsFactory, at as getTargetBox, au as acceleratedEasing, av as deceleratedEasing, aw as standardEasing } from './asWebComponent-
|
|
3
|
-
import { b as animate, n as nullifyTransforms } from './forwardRefs-
|
|
2
|
+
import { g as genericComponent, ar as PREFERS_REDUCED_MOTION, p as propsFactory, at as getTargetBox, au as acceleratedEasing, av as deceleratedEasing, aw as standardEasing } from './asWebComponent-IZanwL-A.js';
|
|
3
|
+
import { b as animate, n as nullifyTransforms } from './forwardRefs-B-c1_6yo.js';
|
|
4
4
|
|
|
5
5
|
// Utilities
|
|
6
6
|
const makeVDialogTransitionProps = propsFactory({
|
package/dist/client/eo-dash.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { aR as EodashConstructor, aS as register, aT as store } from './asWebComponent-
|
|
1
|
+
export { aR as EodashConstructor, aS as register, aT as store } from './asWebComponent-IZanwL-A.js';
|
|
2
2
|
import 'vue';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { computed, watch, onScopeDispose, nextTick, ref, watchEffect, effectScope, inject, mergeProps, toRef, toValue, shallowRef, onMounted, reactive, provide, toRaw, readonly, warn, onBeforeUnmount, createElementVNode, Fragment, createVNode, Teleport, withDirectives, vShow, Transition } from 'vue';
|
|
2
|
-
import { ax as Box, ay as isOn, az as eventName, p as propsFactory, aA as destructComputed, aB as parseAnchor, aC as flipSide, aD as flipAlign, aE as flipCorner, aF as CircularBuffer, aG as deepEqual, at as getTargetBox, aH as getElementBox, O as consoleError, aI as getAxis, q as convertToUnit, aJ as getOverflow, x as clamp, aK as IN_BROWSER, A as useToggleScope, aL as defer, N as getCurrentInstance, aM as templateRef, aN as matchesSelector, a8 as focusableChildren, G as useDisplay, r as makeThemeProps, d as makeDimensionProps, e as makeComponentProps, g as genericComponent, z as useProxiedModel, l as provideTheme, n as useRtl, f as useBackgroundColor, b as useDimension, aO as useRouter, aP as useBackButton, aw as standardEasing, c as useRender, C as omit } from './asWebComponent-
|
|
3
|
-
import { m as makeTransitionProps, M as MaybeTransition } from './transition-
|
|
2
|
+
import { ax as Box, ay as isOn, az as eventName, p as propsFactory, aA as destructComputed, aB as parseAnchor, aC as flipSide, aD as flipAlign, aE as flipCorner, aF as CircularBuffer, aG as deepEqual, at as getTargetBox, aH as getElementBox, O as consoleError, aI as getAxis, q as convertToUnit, aJ as getOverflow, x as clamp, aK as IN_BROWSER, A as useToggleScope, aL as defer, N as getCurrentInstance, aM as templateRef, aN as matchesSelector, a8 as focusableChildren, G as useDisplay, r as makeThemeProps, d as makeDimensionProps, e as makeComponentProps, g as genericComponent, z as useProxiedModel, l as provideTheme, n as useRtl, f as useBackgroundColor, b as useDimension, aO as useRouter, aP as useBackButton, aw as standardEasing, c as useRender, C as omit } from './asWebComponent-IZanwL-A.js';
|
|
3
|
+
import { m as makeTransitionProps, M as MaybeTransition } from './transition-BkyUsZh_.js';
|
|
4
4
|
|
|
5
5
|
// Utilities
|
|
6
6
|
/** @see https://stackoverflow.com/a/57876601/2074736 */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import log from 'loglevel';
|
|
2
|
-
import { s as separateEndpointLinks, c as createTiffLayerDefinition, p as pollProcessStatus, e as extractAsyncResults, u as updateJobsStatus, a as creatAsyncProcessLayerDefinitions, b as getBboxProperty, f as generateTimePairs, h as extractGeometries, i as applyProcessLayersToMap, g as getDrawToolsProperties } from './async-
|
|
3
|
-
import {
|
|
2
|
+
import { s as separateEndpointLinks, c as createTiffLayerDefinition, p as pollProcessStatus, e as extractAsyncResults, u as updateJobsStatus, a as creatAsyncProcessLayerDefinitions, b as getBboxProperty, f as generateTimePairs, h as extractGeometries, i as applyProcessLayersToMap, g as getDrawToolsProperties } from './async-CiNIOBVz.js';
|
|
3
|
+
import { g as axios, P as isFirstLoad, e as extractLayerConfig, U as compareIndicator, Q as indicator, H as extractCollectionUrls, S as currentCompareUrl, R as currentUrl, I as generateLinksFromItems, x as getDatetimeProperty, V as comparePoi, L as datetime, ah as compareChartData, ai as chartData, $ as compareChartSpec, _ as chartSpec, M as poi, ag as getCompareLayers, F as getLayers } from './helpers-BFuh19CP.js';
|
|
4
4
|
import mustache from 'mustache';
|
|
5
|
-
import { H as useSTAcStore, ae as readParquetItems, af as useGetSubCodeId } from './asWebComponent-
|
|
5
|
+
import { H as useSTAcStore, ae as readParquetItems, af as useGetSubCodeId } from './asWebComponent-IZanwL-A.js';
|
|
6
6
|
import { toAbsolute } from 'stac-js/src/http.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -643,7 +643,6 @@ async function processVector(links, jsonformValue, layerId) {
|
|
|
643
643
|
type: "Vector",
|
|
644
644
|
source: {
|
|
645
645
|
type: "Vector",
|
|
646
|
-
//@ts-expect-error TODO
|
|
647
646
|
url: mustache.render(link.href, {
|
|
648
647
|
...(jsonformValue ?? {}),
|
|
649
648
|
}),
|
|
@@ -2,6 +2,8 @@ import { toAbsolute } from 'stac-js/src/http.js';
|
|
|
2
2
|
import { setupCache } from 'axios-cache-interceptor';
|
|
3
3
|
import log from 'loglevel';
|
|
4
4
|
import { ref, shallowRef, reactive, shallowReactive } from 'vue';
|
|
5
|
+
import mustache from 'mustache';
|
|
6
|
+
import { updateVectorLayerStyle } from '@eox/layercontrol';
|
|
5
7
|
import { mdiWrench, mdiSnowflake, mdiVolleyball, mdiHiking, mdiLightningBolt, mdiLeaf, mdiAccountMultiple, mdiCurrencyEur, mdiWeatherWindy, mdiSetCenter, mdiHospitalBoxOutline, mdiImageFilterHdr, mdiWater, mdiBarley } from '@mdi/js';
|
|
6
8
|
|
|
7
9
|
/**
|
|
@@ -5363,6 +5365,26 @@ function generateFeatures(links, extraProperties = {}, rel = "item") {
|
|
|
5363
5365
|
return geojsonObject;
|
|
5364
5366
|
}
|
|
5365
5367
|
|
|
5368
|
+
/**
|
|
5369
|
+
* Fetches or extracts the raster form configuration for a STAC object.
|
|
5370
|
+
* Supports direct JSON objects, data URIs, and URL strings.
|
|
5371
|
+
*
|
|
5372
|
+
* @param {string|object|undefined} rasterform - The rasterform property from the STAC object.
|
|
5373
|
+
* @returns {Promise<import("@/types").EodashRasterJSONForm|undefined>}
|
|
5374
|
+
*/
|
|
5375
|
+
async function fetchRasterForm(rasterform) {
|
|
5376
|
+
if (!rasterform) {
|
|
5377
|
+
return undefined;
|
|
5378
|
+
}
|
|
5379
|
+
if (typeof rasterform === "object") {
|
|
5380
|
+
return /** @type {import("@/types").EodashRasterJSONForm} */ (rasterform);
|
|
5381
|
+
}
|
|
5382
|
+
if (typeof rasterform === "string") {
|
|
5383
|
+
return await axios.get(rasterform).then((resp) => resp.data);
|
|
5384
|
+
}
|
|
5385
|
+
return undefined;
|
|
5386
|
+
}
|
|
5387
|
+
|
|
5366
5388
|
/**
|
|
5367
5389
|
* Spearates and extracts layerConfig (jsonform schema & legend) from a style json
|
|
5368
5390
|
*
|
|
@@ -5419,6 +5441,39 @@ function extractLayerConfig(
|
|
|
5419
5441
|
return { layerConfig, style };
|
|
5420
5442
|
}
|
|
5421
5443
|
|
|
5444
|
+
/**
|
|
5445
|
+
* Recursively extracts URL keys from a JSON Schema.
|
|
5446
|
+
* Maps schema property names to their defined `url_key`.
|
|
5447
|
+
* @param {Record<string, any> | null | undefined} schema
|
|
5448
|
+
* @returns {Record<string, string>}
|
|
5449
|
+
*/
|
|
5450
|
+
function extractUrlKeys(schema) {
|
|
5451
|
+
/** @type {Record<string, string>} */
|
|
5452
|
+
const keys = {};
|
|
5453
|
+
if (!schema || typeof schema !== "object") return keys;
|
|
5454
|
+
|
|
5455
|
+
if (schema.properties) {
|
|
5456
|
+
for (const [key, propDef] of Object.entries(schema.properties)) {
|
|
5457
|
+
if (propDef && typeof propDef === "object") {
|
|
5458
|
+
if (typeof propDef.url_key === "string") {
|
|
5459
|
+
keys[key] = propDef.url_key;
|
|
5460
|
+
}
|
|
5461
|
+
Object.assign(keys, extractUrlKeys(propDef));
|
|
5462
|
+
}
|
|
5463
|
+
}
|
|
5464
|
+
}
|
|
5465
|
+
|
|
5466
|
+
for (const combinator of ["oneOf", "allOf", "anyOf"]) {
|
|
5467
|
+
if (Array.isArray(schema[combinator])) {
|
|
5468
|
+
for (const sub of schema[combinator]) {
|
|
5469
|
+
Object.assign(keys, extractUrlKeys(sub));
|
|
5470
|
+
}
|
|
5471
|
+
}
|
|
5472
|
+
}
|
|
5473
|
+
|
|
5474
|
+
return keys;
|
|
5475
|
+
}
|
|
5476
|
+
|
|
5422
5477
|
/**
|
|
5423
5478
|
*
|
|
5424
5479
|
* @param {number[]} bbox
|
|
@@ -5559,6 +5614,7 @@ const fetchAllStyles = async (stacObject) => {
|
|
|
5559
5614
|
link.rel.includes("style"),
|
|
5560
5615
|
);
|
|
5561
5616
|
const fetchPromises = styleLinks.map(async (link) => {
|
|
5617
|
+
/** @type {import("@/types").EodashStyleJson} */
|
|
5562
5618
|
const styleJson = await axios.get(link.href).then((resp) => resp.data);
|
|
5563
5619
|
log.debug("fetched styles JSON", JSON.parse(JSON.stringify(styleJson)));
|
|
5564
5620
|
return styleJson;
|
|
@@ -5853,20 +5909,147 @@ const createAssetID = (collectionId, itemId, index) => {
|
|
|
5853
5909
|
*
|
|
5854
5910
|
* @param {Record<string,any>[]} layers
|
|
5855
5911
|
*/
|
|
5856
|
-
const removeUnneededProperties = (layers) => {
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5912
|
+
const removeUnneededProperties = (layers, formValues = {}) => {
|
|
5913
|
+
/**
|
|
5914
|
+
* @param {Record<string,any>} layer
|
|
5915
|
+
* @returns {Record<string,any>[]}
|
|
5916
|
+
*/
|
|
5917
|
+
const processLayer = (layer) => {
|
|
5918
|
+
// If the layer (or group) is explicitly marked as not visible, skip it and all children
|
|
5919
|
+
if (layer.properties?.visible === false) {
|
|
5920
|
+
return [];
|
|
5864
5921
|
}
|
|
5865
|
-
|
|
5866
|
-
|
|
5922
|
+
|
|
5923
|
+
// If it's a Group, we just want its children
|
|
5924
|
+
if (layer.type === "Group" && Array.isArray(layer.layers)) {
|
|
5925
|
+
return layer.layers.flatMap(processLayer);
|
|
5867
5926
|
}
|
|
5868
|
-
|
|
5869
|
-
|
|
5927
|
+
|
|
5928
|
+
// Break any Vue Proxies/OpenLayers getters by stringifying first
|
|
5929
|
+
let clonedLayer;
|
|
5930
|
+
try {
|
|
5931
|
+
clonedLayer = JSON.parse(JSON.stringify(layer));
|
|
5932
|
+
} catch (_e) {
|
|
5933
|
+
clonedLayer = structuredClone(layer);
|
|
5934
|
+
}
|
|
5935
|
+
|
|
5936
|
+
// Flatten formValues to handle nested properties (e.g., vminmax: { vmin, vmax })
|
|
5937
|
+
/**
|
|
5938
|
+
* @param {Record<string,any>} obj
|
|
5939
|
+
* @returns {Record<string,any>}
|
|
5940
|
+
*/
|
|
5941
|
+
const flattenFormValues = (obj) => {
|
|
5942
|
+
/** @type {Record<string,any>} */
|
|
5943
|
+
let result = {};
|
|
5944
|
+
for (const key in obj) {
|
|
5945
|
+
if (
|
|
5946
|
+
obj[key] !== null &&
|
|
5947
|
+
typeof obj[key] === "object" &&
|
|
5948
|
+
!Array.isArray(obj[key])
|
|
5949
|
+
) {
|
|
5950
|
+
Object.assign(result, flattenFormValues(obj[key]));
|
|
5951
|
+
} else {
|
|
5952
|
+
result[key] = obj[key];
|
|
5953
|
+
}
|
|
5954
|
+
}
|
|
5955
|
+
return result;
|
|
5956
|
+
};
|
|
5957
|
+
const flatFormValues = flattenFormValues(formValues);
|
|
5958
|
+
|
|
5959
|
+
// Burn in style variables using Mustache if formValues are provided
|
|
5960
|
+
if (Object.keys(flatFormValues).length > 0) {
|
|
5961
|
+
// Stringify, render mustache, then parse back
|
|
5962
|
+
try {
|
|
5963
|
+
const renderedString = mustache.render(
|
|
5964
|
+
JSON.stringify(clonedLayer),
|
|
5965
|
+
flatFormValues,
|
|
5966
|
+
);
|
|
5967
|
+
clonedLayer = JSON.parse(renderedString);
|
|
5968
|
+
} catch (e) {
|
|
5969
|
+
log.warn(
|
|
5970
|
+
"[eodash] Failed to apply mustache templating during export cleanup:",
|
|
5971
|
+
e,
|
|
5972
|
+
);
|
|
5973
|
+
}
|
|
5974
|
+
}
|
|
5975
|
+
|
|
5976
|
+
const {
|
|
5977
|
+
id,
|
|
5978
|
+
title,
|
|
5979
|
+
mapboxStyle,
|
|
5980
|
+
projection,
|
|
5981
|
+
applyOptions,
|
|
5982
|
+
layerConfig,
|
|
5983
|
+
visible,
|
|
5984
|
+
} = clonedLayer.properties || {};
|
|
5985
|
+
|
|
5986
|
+
// If style was not at root but in properties (layerConfig), move it to root early
|
|
5987
|
+
if (!clonedLayer.style && layerConfig?.style) {
|
|
5988
|
+
clonedLayer.style = layerConfig.style;
|
|
5989
|
+
}
|
|
5990
|
+
|
|
5991
|
+
// Burn in OpenLayers ["var", "name"] variables using flatFormValues overriding style.variables
|
|
5992
|
+
const styleVariables = {
|
|
5993
|
+
...(clonedLayer.style?.variables || {}),
|
|
5994
|
+
...flatFormValues,
|
|
5995
|
+
};
|
|
5996
|
+
|
|
5997
|
+
if (clonedLayer.style && Object.keys(styleVariables).length > 0) {
|
|
5998
|
+
clonedLayer.style = updateVectorLayerStyle({
|
|
5999
|
+
...clonedLayer.style,
|
|
6000
|
+
variables: styleVariables,
|
|
6001
|
+
});
|
|
6002
|
+
}
|
|
6003
|
+
|
|
6004
|
+
clonedLayer.properties = {
|
|
6005
|
+
id,
|
|
6006
|
+
title,
|
|
6007
|
+
...(mapboxStyle && { mapboxStyle }),
|
|
6008
|
+
...(projection && { projection }),
|
|
6009
|
+
...(applyOptions && { applyOptions }),
|
|
6010
|
+
...(visible !== undefined && { visible }),
|
|
6011
|
+
};
|
|
6012
|
+
|
|
6013
|
+
if (clonedLayer["interactions"]) {
|
|
6014
|
+
delete clonedLayer["interactions"];
|
|
6015
|
+
}
|
|
6016
|
+
|
|
6017
|
+
// Cleanup unnecessary properties
|
|
6018
|
+
/**
|
|
6019
|
+
* @param {any} obj
|
|
6020
|
+
*/
|
|
6021
|
+
const cleanupProperties = (obj) => {
|
|
6022
|
+
if (!obj || typeof obj !== "object") return;
|
|
6023
|
+
|
|
6024
|
+
for (const key in obj) {
|
|
6025
|
+
if (obj[key] === null) {
|
|
6026
|
+
delete obj[key];
|
|
6027
|
+
} else if (Array.isArray(obj[key])) {
|
|
6028
|
+
if (obj[key].length === 0) {
|
|
6029
|
+
// Remove empty arrays like empty interactions
|
|
6030
|
+
delete obj[key];
|
|
6031
|
+
} else {
|
|
6032
|
+
obj[key].forEach(cleanupProperties);
|
|
6033
|
+
}
|
|
6034
|
+
} else if (typeof obj[key] === "object") {
|
|
6035
|
+
cleanupProperties(obj[key]);
|
|
6036
|
+
}
|
|
6037
|
+
}
|
|
6038
|
+
};
|
|
6039
|
+
cleanupProperties(clonedLayer);
|
|
6040
|
+
|
|
6041
|
+
return [clonedLayer];
|
|
6042
|
+
};
|
|
6043
|
+
|
|
6044
|
+
// ensure the top level array is also deeply un-proxied if needed
|
|
6045
|
+
let rawLayers = layers;
|
|
6046
|
+
try {
|
|
6047
|
+
rawLayers = JSON.parse(JSON.stringify(layers));
|
|
6048
|
+
} catch (_e) {
|
|
6049
|
+
rawLayers = structuredClone(layers);
|
|
6050
|
+
}
|
|
6051
|
+
|
|
6052
|
+
return rawLayers.flatMap(processLayer);
|
|
5870
6053
|
};
|
|
5871
6054
|
|
|
5872
6055
|
/**
|
|
@@ -6057,6 +6240,7 @@ function getDatetimeProperty(linksOrItems) {
|
|
|
6057
6240
|
return prop;
|
|
6058
6241
|
}
|
|
6059
6242
|
}
|
|
6243
|
+
|
|
6060
6244
|
/**
|
|
6061
6245
|
*
|
|
6062
6246
|
* @param {*} stacObject
|
|
@@ -6357,6 +6541,91 @@ function updateGeoZarrBands(olLayer, jsonformValue) {
|
|
|
6357
6541
|
return true;
|
|
6358
6542
|
}
|
|
6359
6543
|
|
|
6544
|
+
/**
|
|
6545
|
+
* Safely appends query parameters to a URL string, preserving templates like {z}/{x}/{y}
|
|
6546
|
+
* @param {string} url
|
|
6547
|
+
* @param {Record<string, string>} params
|
|
6548
|
+
* @returns {string}
|
|
6549
|
+
*/
|
|
6550
|
+
function appendQueryParams(url, params) {
|
|
6551
|
+
const [base, query] = url.split("?");
|
|
6552
|
+
const searchParams = new URLSearchParams(query || "");
|
|
6553
|
+
|
|
6554
|
+
for (const [key, val] of Object.entries(params)) {
|
|
6555
|
+
if (val !== undefined && val !== null && val !== "") {
|
|
6556
|
+
searchParams.set(key, val);
|
|
6557
|
+
} else {
|
|
6558
|
+
searchParams.delete(key);
|
|
6559
|
+
}
|
|
6560
|
+
}
|
|
6561
|
+
|
|
6562
|
+
const newQuery = searchParams.toString();
|
|
6563
|
+
return newQuery ? `${base}?${newQuery}` : base;
|
|
6564
|
+
}
|
|
6565
|
+
|
|
6566
|
+
/**
|
|
6567
|
+
* Checks whether a VectorTile layer's URL needs to be updated based on jsonform output.
|
|
6568
|
+
* If the style's jsonform schema has properties with `url_key` defined, their values
|
|
6569
|
+
* are injected as query parameters into the source URL.
|
|
6570
|
+
*
|
|
6571
|
+
* @param {import("ol/layer/Layer").default} olLayer - Layer from layerConfig:change event
|
|
6572
|
+
* @param {Record<string, any>} jsonformValue - Current jsonform output
|
|
6573
|
+
* @returns {boolean} true if the URL was updated
|
|
6574
|
+
*/
|
|
6575
|
+
function updateLayerUrl(olLayer, jsonformValue) {
|
|
6576
|
+
const jsonLayer = olLayer.get("_jsonDefinition");
|
|
6577
|
+
if (!jsonLayer || jsonLayer.type !== "VectorTile") {
|
|
6578
|
+
return false;
|
|
6579
|
+
}
|
|
6580
|
+
|
|
6581
|
+
const schema = jsonLayer.properties?.layerConfig?.schema;
|
|
6582
|
+
const urlKeys = extractUrlKeys(schema);
|
|
6583
|
+
|
|
6584
|
+
if (Object.keys(urlKeys).length === 0) {
|
|
6585
|
+
return false;
|
|
6586
|
+
}
|
|
6587
|
+
|
|
6588
|
+
let originalUrl = olLayer.get("originalUrl") || jsonLayer.source?.url;
|
|
6589
|
+
|
|
6590
|
+
if (!originalUrl || typeof originalUrl !== "string") {
|
|
6591
|
+
return false;
|
|
6592
|
+
}
|
|
6593
|
+
|
|
6594
|
+
if (!olLayer.get("originalUrl")) {
|
|
6595
|
+
olLayer.set("originalUrl", originalUrl);
|
|
6596
|
+
}
|
|
6597
|
+
|
|
6598
|
+
/** @type {Record<string, string>} */
|
|
6599
|
+
const queryParamsToInject = {};
|
|
6600
|
+
for (const [propName, urlKey] of Object.entries(urlKeys)) {
|
|
6601
|
+
queryParamsToInject[urlKey] = jsonformValue[propName];
|
|
6602
|
+
}
|
|
6603
|
+
|
|
6604
|
+
const newUrl = appendQueryParams(originalUrl, queryParamsToInject);
|
|
6605
|
+
|
|
6606
|
+
if (jsonLayer.source?.url) {
|
|
6607
|
+
if (jsonLayer.source.url === newUrl) {
|
|
6608
|
+
return false;
|
|
6609
|
+
}
|
|
6610
|
+
jsonLayer.source.url = newUrl;
|
|
6611
|
+
if (olLayer.get("injectedUrl") === newUrl) {
|
|
6612
|
+
return false;
|
|
6613
|
+
}
|
|
6614
|
+
const source = olLayer.getSource();
|
|
6615
|
+
olLayer.set("injectedUrl", newUrl);
|
|
6616
|
+
if (source && "setUrl" in source) {
|
|
6617
|
+
/** @type {any} */ (source).setUrl(newUrl);
|
|
6618
|
+
return true;
|
|
6619
|
+
}
|
|
6620
|
+
if (source && "setUrls" in source) {
|
|
6621
|
+
/** @type {any} */ (source).setUrls([newUrl]);
|
|
6622
|
+
return true;
|
|
6623
|
+
}
|
|
6624
|
+
}
|
|
6625
|
+
|
|
6626
|
+
return false;
|
|
6627
|
+
}
|
|
6628
|
+
|
|
6360
6629
|
/**
|
|
6361
6630
|
* Applies titiler upscaling to an XYZ tile URL based on the matched endpoint config.
|
|
6362
6631
|
* - titiler v1: appends `@2x` to the `{y}` tile coordinate
|
|
@@ -6390,26 +6659,56 @@ function applyTitilerUpscaling(url, upscalingEndpoints) {
|
|
|
6390
6659
|
}
|
|
6391
6660
|
|
|
6392
6661
|
/**
|
|
6393
|
-
* Picks the render presets for a collection, preferring
|
|
6394
|
-
*
|
|
6395
|
-
*
|
|
6662
|
+
* Picks the render presets for a collection, preferring client-provided config
|
|
6663
|
+
* (`options.renders[collectionId]`) and falling back to the collection's own STAC
|
|
6664
|
+
* `renders` extension when no config entry exists.
|
|
6396
6665
|
* @param {import("stac-ts").StacCollection | null | undefined} collection
|
|
6397
6666
|
* @param {Record<string, Record<string, import("@/types").Render>> | undefined} [configRenders]
|
|
6398
6667
|
* @returns {Record<string, import("@/types").Render> | undefined}
|
|
6399
6668
|
*/
|
|
6400
6669
|
function resolveRenders(collection, configRenders) {
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6670
|
+
const config = collection?.id ? configRenders?.[collection.id] : undefined;
|
|
6671
|
+
if (config) return config;
|
|
6672
|
+
return /** @type {Record<string, import("@/types").Render>|undefined} */ (
|
|
6673
|
+
collection?.renders ?? undefined
|
|
6674
|
+
);
|
|
6675
|
+
}
|
|
6676
|
+
|
|
6677
|
+
/**
|
|
6678
|
+
* TiTiler expects rescale as [min,max] pairs; chunks a flat numeric list
|
|
6679
|
+
* into pairs (e.g. [0,0.4,0,0.1] -> [[0,0.4],[0,0.1]]). Nested input passes through.
|
|
6680
|
+
* @param {number[]|number[][]|undefined} rescale - flat or nested rescale values
|
|
6681
|
+
* @returns {number[][]|undefined} rescale as [min,max] pairs
|
|
6682
|
+
*/
|
|
6683
|
+
function normalizeRescale(rescale) {
|
|
6684
|
+
if (!rescale?.length || Array.isArray(rescale[0])) {
|
|
6685
|
+
return /** @type {number[][]|undefined} */ (rescale);
|
|
6405
6686
|
}
|
|
6406
|
-
|
|
6687
|
+
const pairs = [];
|
|
6688
|
+
for (let i = 0; i < rescale.length; i += 2) {
|
|
6689
|
+
pairs.push(/** @type {number[]} */ (rescale).slice(i, i + 2));
|
|
6690
|
+
}
|
|
6691
|
+
return pairs;
|
|
6692
|
+
}
|
|
6693
|
+
|
|
6694
|
+
/**
|
|
6695
|
+
* Drops NaN nodata values; NaN is already the implicit fill for float data,
|
|
6696
|
+
* so forwarding `nodata=nan` to TiTiler is redundant.
|
|
6697
|
+
* @param {string|number|undefined} nodata - nodata value from render/asset metadata
|
|
6698
|
+
* @returns {string|number|undefined} nodata, or undefined when it is NaN
|
|
6699
|
+
*/
|
|
6700
|
+
function normalizeNodata(nodata) {
|
|
6701
|
+
if (typeof nodata === "number" && Number.isNaN(nodata)) return undefined;
|
|
6702
|
+
if (typeof nodata === "string" && nodata.trim().toLowerCase() === "nan")
|
|
6703
|
+
return undefined;
|
|
6704
|
+
return nodata;
|
|
6407
6705
|
}
|
|
6408
6706
|
|
|
6409
6707
|
/**
|
|
6410
|
-
* Serializes an object into a TiTiler query string. Arrays
|
|
6411
|
-
*
|
|
6412
|
-
*
|
|
6708
|
+
* Serializes an object into a TiTiler query string. Arrays repeat the key per
|
|
6709
|
+
* element (TiTiler list params, e.g. `assets=a&assets=b`); nested elements
|
|
6710
|
+
* comma-join (`rescale: [[0,1],[0,2]]` -> `rescale=0,1&rescale=0,2`); objects
|
|
6711
|
+
* are JSON-encoded. Shared by the render-extension and mosaic paths.
|
|
6413
6712
|
* @param {Record<string,any>} obj
|
|
6414
6713
|
* @returns {string}
|
|
6415
6714
|
*/
|
|
@@ -6425,23 +6724,12 @@ function encodeURLObject(obj) {
|
|
|
6425
6724
|
|
|
6426
6725
|
switch (valueType) {
|
|
6427
6726
|
case "array": {
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
if (hasNestedArrays) {
|
|
6434
|
-
// For multi-dimensional arrays, repeat the key with different values
|
|
6435
|
-
for (const val of value) {
|
|
6436
|
-
if (Array.isArray(val)) {
|
|
6437
|
-
str += `${key}=${val.join(",")}&`;
|
|
6438
|
-
} else {
|
|
6439
|
-
str += `${key}=${val}&`;
|
|
6440
|
-
}
|
|
6727
|
+
for (const val of value) {
|
|
6728
|
+
if (Array.isArray(val)) {
|
|
6729
|
+
str += `${key}=${val.join(",")}&`;
|
|
6730
|
+
} else {
|
|
6731
|
+
str += `${key}=${encodeURIComponent(val)}&`;
|
|
6441
6732
|
}
|
|
6442
|
-
} else {
|
|
6443
|
-
// For simple arrays, join with commas
|
|
6444
|
-
str += `${key}=${value.join(",")}&`;
|
|
6445
6733
|
}
|
|
6446
6734
|
break;
|
|
6447
6735
|
}
|
|
@@ -6458,4 +6746,4 @@ function encodeURLObject(obj) {
|
|
|
6458
6746
|
return str;
|
|
6459
6747
|
}
|
|
6460
6748
|
|
|
6461
|
-
export {
|
|
6749
|
+
export { compareChartSpec as $, findLayer as A, findLayersByLayerPrefix as B, replaceLayer as C, generateFeatures as D, dataThemesBrands as E, getLayers as F, extractLayerLegend as G, extractCollectionUrls as H, generateLinksFromItems as I, revokeCollectionBlobUrls as J, collectionsPalette as K, datetime as L, poi as M, activeTemplate as N, mapPosition as O, isFirstLoad as P, indicator as Q, currentUrl as R, currentCompareUrl as S, eodashCompareCollections as T, compareIndicator as U, comparePoi as V, eodashCollections as W, states as X, actions as Y, areChartsSeparateLayout as Z, chartSpec as _, extractRoles as a, loading as a0, includesProcess as a1, shouldShowChartWidget as a2, sanitizeBbox as a3, tooltipAdapter as a4, mapCompareEl as a5, updateGeoZarrBands as a6, updateLayerUrl as a7, layerControlFormValueCompare as a8, layerControlFormValue as a9, getColFromLayer as aa, isGlobe as ab, setMapProjFromCol as ac, setActiveTemplate as ad, availableMapProjection as ae, changeMapProjection as af, getCompareLayers as ag, compareChartData as ah, chartData as ai, axios$1 as aj, removeLayers as ak, removeUnneededProperties as al, extractEoxLegendLink as b, createLayerID as c, applyTitilerUpscaling as d, extractLayerConfig as e, fetchRasterForm as f, axios as g, resolveStyle as h, addTooltipInteraction as i, createAssetID as j, getBandsProperty as k, resolveRenders as l, mergeGeojsons as m, normalizeRescale as n, normalizeNodata as o, encodeURLObject as p, mapEl as q, registerProjection as r, getProjectionCode as s, isSTACItem as t, extractLayerTimeValues as u, fetchStyle as v, fetchApiItems as w, getDatetimeProperty as x, fetchPreAggregations as y, fetchAllStyles as z };
|