@eodash/eodash 5.0.0-alpha.2.26 → 5.0.0-alpha.2.27
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/asWebComponent.js +2 -3
- package/core/client/components/DashboardLayout.vue +35 -13
- package/core/client/components/Loading.vue +6 -9
- package/core/client/components/MobileLayout.vue +16 -14
- package/core/client/composables/DefineEodash.js +13 -3
- package/core/client/composables/DefineTemplate.js +67 -0
- package/core/client/composables/DefineWidgets.js +3 -2
- package/core/client/composables/EodashMap.js +39 -14
- package/core/client/composables/EodashProcess.js +574 -0
- package/core/client/composables/index.js +54 -11
- package/core/client/eodash.js +383 -125
- package/core/client/{utils/eodashSTAC.js → eodashSTAC/EodashCollection.js} +75 -41
- package/core/client/{utils → eodashSTAC}/createLayers.js +10 -8
- package/core/client/{utils → eodashSTAC}/helpers.js +47 -75
- package/core/client/eodashSTAC/triggers.js +43 -0
- package/core/client/plugins/vuetify.js +2 -1
- package/core/client/store/{Actions.js → actions.js} +16 -2
- package/core/client/store/index.js +4 -18
- package/core/client/store/stac.js +4 -4
- package/core/client/store/{States.js → states.js} +2 -0
- package/{dist/types/core/client/types.d.ts → core/client/types.ts} +47 -8
- package/core/client/utils/keys.js +2 -0
- package/core/client/utils/states.js +8 -3
- package/core/client/views/Dashboard.vue +6 -4
- package/core/client/vite-env.d.ts +1 -16
- package/dist/client/{DashboardLayout-E_JzgCH5.js → DashboardLayout-232tRmjz.js} +23 -25
- package/dist/client/{DynamicWebComponent-C9pVUfT3.js → DynamicWebComponent-Cl4LqHU6.js} +1 -1
- package/dist/client/{EodashDatePicker-CjU8R2ia.js → EodashDatePicker-Pok6bZwU.js} +78 -165
- package/dist/client/EodashItemFilter-16eMMjTV.js +151 -0
- package/dist/client/{EodashLayerControl-mKfwru42.js → EodashLayerControl-De7IlCm_.js} +19 -11
- package/dist/client/EodashLayoutSwitcher-C-3-jjn5.js +52 -0
- package/dist/client/{EodashMap-BpwL82-w.js → EodashMap-CMvbfI6-.js} +116 -39
- package/dist/client/EodashMapBtns-BeknGDtc.js +107 -0
- package/dist/client/EodashProcess-BwKAa9Ee.js +1476 -0
- package/dist/client/EodashStacInfo-_BfonNUG.js +85 -0
- package/dist/client/EodashTools-PD3XPYuR.js +103 -0
- package/dist/client/{ExportState-ByVuIAQb.js → ExportState-DOrT7M15.js} +5 -5
- package/dist/client/{Footer-D691KLtK.js → Footer-CCigxYBo.js} +1 -1
- package/dist/client/{Header-B8UBQstf.js → Header-C2cdx4gb.js} +3 -3
- package/dist/client/{MobileLayout-6bHjYguI.js → MobileLayout-BdiFjHg7.js} +28 -31
- package/dist/client/{PopUp-CdFcnKMY.js → PopUp--_xn1Cms.js} +37 -9
- package/dist/client/{VImg-fKGJ7xyb.js → VImg-9xu2l99m.js} +2 -2
- package/dist/client/{VMain-Hf5R6yWY.js → VMain-BUs3kDTd.js} +1 -1
- package/dist/client/{VOverlay-ClFjEtlD.js → VOverlay-D89omJis.js} +3 -3
- package/dist/client/VTooltip-CDu3bErh.js +86 -0
- package/dist/client/{WidgetsContainer-XXYJfaPR.js → WidgetsContainer-aFG9yFT6.js} +1 -1
- package/dist/client/{asWebComponent-BsbKnhGV.js → asWebComponent-BRGyP_j5.js} +1495 -1142
- package/dist/client/{style.css → eo-dash.css} +2 -2
- package/dist/client/eo-dash.js +1 -1
- package/dist/client/{forwardRefs-I2EA3z3_.js → forwardRefs-CYrR6bMw.js} +1 -1
- package/dist/client/{index-B3dnMr8a.js → index-BZwk0V42.js} +1 -1
- package/dist/client/{transition-DJ9gfiuP.js → transition-DG9nRSW4.js} +1 -1
- package/dist/node/cli.js +3 -3
- package/package.json +56 -34
- package/widgets/EodashDatePicker.vue +68 -54
- package/widgets/EodashItemFilter.vue +60 -105
- package/widgets/EodashLayerControl.vue +19 -8
- package/widgets/EodashLayoutSwitcher.vue +36 -0
- package/widgets/EodashMap.vue +27 -28
- package/widgets/EodashMapBtns.vue +41 -4
- package/widgets/EodashProcess.vue +143 -0
- package/widgets/EodashStacInfo.vue +82 -0
- package/widgets/EodashTools.vue +83 -0
- package/widgets/ExportState.vue +3 -3
- package/widgets/PopUp.vue +24 -2
- package/core/client/asWebComponent.d.ts +0 -23
- package/core/client/types.d.ts +0 -279
- package/dist/client/EodashItemFilter-VGQasaBJ.js +0 -194
- package/dist/client/EodashMapBtns-GNNBdBW9.js +0 -66
- package/dist/types/core/client/App.vue.d.ts +0 -7
- package/dist/types/core/client/asWebComponent.d.ts +0 -9
- package/dist/types/core/client/components/DashboardLayout.vue.d.ts +0 -2
- package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +0 -18
- package/dist/types/core/client/components/ErrorAlert.vue.d.ts +0 -2
- package/dist/types/core/client/components/Footer.vue.d.ts +0 -2
- package/dist/types/core/client/components/Header.vue.d.ts +0 -2
- package/dist/types/core/client/components/IframeWrapper.vue.d.ts +0 -7
- package/dist/types/core/client/components/Loading.vue.d.ts +0 -2
- package/dist/types/core/client/components/MobileLayout.vue.d.ts +0 -2
- package/dist/types/core/client/composables/DefineEodash.d.ts +0 -2
- package/dist/types/core/client/composables/DefineWidgets.d.ts +0 -14
- package/dist/types/core/client/composables/EodashMap.d.ts +0 -5
- package/dist/types/core/client/composables/index.d.ts +0 -29
- package/dist/types/core/client/eodash.d.ts +0 -8
- package/dist/types/core/client/main.d.ts +0 -2
- package/dist/types/core/client/plugins/axios.d.ts +0 -2
- package/dist/types/core/client/plugins/index.d.ts +0 -3
- package/dist/types/core/client/plugins/vuetify.d.ts +0 -82
- package/dist/types/core/client/render.d.ts +0 -1
- package/dist/types/core/client/store/Actions.d.ts +0 -11
- package/dist/types/core/client/store/States.d.ts +0 -21
- package/dist/types/core/client/store/index.d.ts +0 -2
- package/dist/types/core/client/store/stac.d.ts +0 -25
- package/dist/types/core/client/utils/createLayers.d.ts +0 -45
- package/dist/types/core/client/utils/eodashSTAC.d.ts +0 -82
- package/dist/types/core/client/utils/helpers.d.ts +0 -84
- package/dist/types/core/client/utils/index.d.ts +0 -2
- package/dist/types/core/client/utils/keys.d.ts +0 -6
- package/dist/types/core/client/utils/states.d.ts +0 -14
- package/dist/types/core/client/views/Dashboard.vue.d.ts +0 -9
- package/dist/types/widgets/EodashDatePicker.vue.d.ts +0 -7
- package/dist/types/widgets/EodashItemFilter.vue.d.ts +0 -33
- package/dist/types/widgets/EodashLayerControl.vue.d.ts +0 -7
- package/dist/types/widgets/EodashMap.vue.d.ts +0 -7
- package/dist/types/widgets/EodashMapBtns.vue.d.ts +0 -9
- package/dist/types/widgets/ExportState.vue.d.ts +0 -7
- package/dist/types/widgets/PopUp.vue.d.ts +0 -14
- package/dist/types/widgets/WidgetsContainer.vue.d.ts +0 -7
|
@@ -1,58 +1,13 @@
|
|
|
1
|
-
import { ref, reactive, watch, onScopeDispose, effectScope, Fragment, computed, watchEffect, toRefs, capitalize, shallowRef, warn, getCurrentInstance as getCurrentInstance$1, unref, provide, inject as inject$1, defineComponent as defineComponent$1, camelize, h, toRaw, createVNode, mergeProps, onBeforeUnmount, readonly, onMounted, onDeactivated, onActivated, nextTick, shallowReactive,
|
|
1
|
+
import { ref, reactive, watch, onScopeDispose, effectScope, Fragment, computed, watchEffect, toRefs, capitalize, shallowRef, warn, getCurrentInstance as getCurrentInstance$1, unref, provide, inject as inject$1, defineComponent as defineComponent$1, camelize, h, toRaw, createVNode, mergeProps, onBeforeUnmount, readonly, onMounted, onDeactivated, onActivated, nextTick, shallowReactive, onUnmounted, isRef, toRef, onUpdated, Text, Transition, resolveDynamicComponent, withDirectives, useModel, openBlock, createBlock, withCtx, createTextVNode, toDisplayString, createElementVNode, createCommentVNode, defineAsyncComponent, onErrorCaptured, Suspense, normalizeProps, createElementBlock, withAsyncContext, normalizeStyle, defineCustomElement } from 'vue';
|
|
2
|
+
import { defineStore, storeToRefs, createPinia } from 'pinia';
|
|
3
|
+
import { setupCache } from 'axios-cache-interceptor';
|
|
2
4
|
import log from 'loglevel';
|
|
5
|
+
import { mdiViewDashboardVariant, mdiViewDashboard, mdiAlertCircle, mdiClose, mdiChevronRight, mdiChevronLeft, mdiMenuDown, mdiPlus } from '@mdi/js';
|
|
6
|
+
import { useEventBus, createSharedComposable } from '@vueuse/core';
|
|
3
7
|
import { toAbsolute } from 'stac-js/src/http.js';
|
|
4
|
-
import { setupCache } from 'axios-cache-interceptor';
|
|
5
|
-
import { defineStore, storeToRefs, createPinia } from 'pinia';
|
|
6
8
|
import { Collection, Item } from 'stac-js';
|
|
7
|
-
import { mdiAlertCircle, mdiClose, mdiChevronRight, mdiChevronLeft, mdiMenuDown } from '@mdi/js';
|
|
8
9
|
import VCalendar from 'v-calendar';
|
|
9
10
|
|
|
10
|
-
/** setting default log level globally to warning */
|
|
11
|
-
log.setLevel(log.levels.WARN, true);
|
|
12
|
-
|
|
13
|
-
/** Currently selected STAC endpoint */
|
|
14
|
-
const currentUrl = ref("");
|
|
15
|
-
|
|
16
|
-
/** Currently selected compare STAC endpoint */
|
|
17
|
-
const currentCompareUrl = ref("");
|
|
18
|
-
|
|
19
|
-
/** Currently selected datetime */
|
|
20
|
-
const datetime = ref(new Date().toISOString());
|
|
21
|
-
|
|
22
|
-
/** Currently selected indicator */
|
|
23
|
-
const indicator = ref("");
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Current map position
|
|
27
|
-
*
|
|
28
|
-
* @type {import("vue").Ref<(number | undefined)[]>}
|
|
29
|
-
*/
|
|
30
|
-
const mapPosition = ref([]);
|
|
31
|
-
|
|
32
|
-
const registeredProjections = ["EPSG:4326", "EPSG:3857"];
|
|
33
|
-
|
|
34
|
-
/** available projection to be rendered by `EodashMap` */
|
|
35
|
-
const availableMapProjection = ref("EPSG:3857");
|
|
36
|
-
|
|
37
|
-
/** @type {import("vue").Ref<HTMLElement & Record<string,any> | null>} */
|
|
38
|
-
const mapEl = ref(null);
|
|
39
|
-
|
|
40
|
-
/** @type {import("vue").Ref<HTMLElement & Record<string,any> | null>} */
|
|
41
|
-
const mapCompareEl = ref(null);
|
|
42
|
-
|
|
43
|
-
const __vite_glob_0_1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
44
|
-
__proto__: null,
|
|
45
|
-
availableMapProjection,
|
|
46
|
-
currentCompareUrl,
|
|
47
|
-
currentUrl,
|
|
48
|
-
datetime,
|
|
49
|
-
indicator,
|
|
50
|
-
mapCompareEl,
|
|
51
|
-
mapEl,
|
|
52
|
-
mapPosition,
|
|
53
|
-
registeredProjections
|
|
54
|
-
}, Symbol.toStringTag, { value: 'Module' }));
|
|
55
|
-
|
|
56
11
|
function bind(fn, thisArg) {
|
|
57
12
|
return function wrap() {
|
|
58
13
|
return fn.apply(thisArg, arguments);
|
|
@@ -1204,7 +1159,7 @@ function encode(val) {
|
|
|
1204
1159
|
*
|
|
1205
1160
|
* @param {string} url The base of the url (e.g., http://www.google.com)
|
|
1206
1161
|
* @param {object} [params] The params to be appended
|
|
1207
|
-
* @param {?object} options
|
|
1162
|
+
* @param {?(object|Function)} options
|
|
1208
1163
|
*
|
|
1209
1164
|
* @returns {string} The formatted url
|
|
1210
1165
|
*/
|
|
@@ -1216,6 +1171,12 @@ function buildURL(url, params, options) {
|
|
|
1216
1171
|
|
|
1217
1172
|
const _encode = options && options.encode || encode;
|
|
1218
1173
|
|
|
1174
|
+
if (utils$1.isFunction(options)) {
|
|
1175
|
+
options = {
|
|
1176
|
+
serialize: options
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1219
1180
|
const serializeFn = options && options.serialize;
|
|
1220
1181
|
|
|
1221
1182
|
let serializedParams;
|
|
@@ -2198,68 +2159,18 @@ const progressEventDecorator = (total, throttled) => {
|
|
|
2198
2159
|
|
|
2199
2160
|
const asyncDecorator = (fn) => (...args) => utils$1.asap(() => fn(...args));
|
|
2200
2161
|
|
|
2201
|
-
const isURLSameOrigin = platform.hasStandardBrowserEnv ?
|
|
2202
|
-
|
|
2203
|
-
// Standard browser envs have full support of the APIs needed to test
|
|
2204
|
-
// whether the request URL is of the same origin as current location.
|
|
2205
|
-
(function standardBrowserEnv() {
|
|
2206
|
-
const msie = platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent);
|
|
2207
|
-
const urlParsingNode = document.createElement('a');
|
|
2208
|
-
let originURL;
|
|
2209
|
-
|
|
2210
|
-
/**
|
|
2211
|
-
* Parse a URL to discover its components
|
|
2212
|
-
*
|
|
2213
|
-
* @param {String} url The URL to be parsed
|
|
2214
|
-
* @returns {Object}
|
|
2215
|
-
*/
|
|
2216
|
-
function resolveURL(url) {
|
|
2217
|
-
let href = url;
|
|
2218
|
-
|
|
2219
|
-
if (msie) {
|
|
2220
|
-
// IE needs attribute set twice to normalize properties
|
|
2221
|
-
urlParsingNode.setAttribute('href', href);
|
|
2222
|
-
href = urlParsingNode.href;
|
|
2223
|
-
}
|
|
2224
|
-
|
|
2225
|
-
urlParsingNode.setAttribute('href', href);
|
|
2226
|
-
|
|
2227
|
-
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
|
|
2228
|
-
return {
|
|
2229
|
-
href: urlParsingNode.href,
|
|
2230
|
-
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
|
|
2231
|
-
host: urlParsingNode.host,
|
|
2232
|
-
search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
|
|
2233
|
-
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
|
2234
|
-
hostname: urlParsingNode.hostname,
|
|
2235
|
-
port: urlParsingNode.port,
|
|
2236
|
-
pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
|
|
2237
|
-
urlParsingNode.pathname :
|
|
2238
|
-
'/' + urlParsingNode.pathname
|
|
2239
|
-
};
|
|
2240
|
-
}
|
|
2241
|
-
|
|
2242
|
-
originURL = resolveURL(window.location.href);
|
|
2243
|
-
|
|
2244
|
-
/**
|
|
2245
|
-
* Determine if a URL shares the same origin as the current location
|
|
2246
|
-
*
|
|
2247
|
-
* @param {String} requestURL The URL to test
|
|
2248
|
-
* @returns {boolean} True if URL shares the same origin, otherwise false
|
|
2249
|
-
*/
|
|
2250
|
-
return function isURLSameOrigin(requestURL) {
|
|
2251
|
-
const parsed = (utils$1.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
|
|
2252
|
-
return (parsed.protocol === originURL.protocol &&
|
|
2253
|
-
parsed.host === originURL.host);
|
|
2254
|
-
};
|
|
2255
|
-
})() :
|
|
2162
|
+
const isURLSameOrigin = platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => {
|
|
2163
|
+
url = new URL(url, platform.origin);
|
|
2256
2164
|
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2165
|
+
return (
|
|
2166
|
+
origin.protocol === url.protocol &&
|
|
2167
|
+
origin.host === url.host &&
|
|
2168
|
+
(isMSIE || origin.port === url.port)
|
|
2169
|
+
);
|
|
2170
|
+
})(
|
|
2171
|
+
new URL(platform.origin),
|
|
2172
|
+
platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)
|
|
2173
|
+
) : () => true;
|
|
2263
2174
|
|
|
2264
2175
|
const cookies = platform.hasStandardBrowserEnv ?
|
|
2265
2176
|
|
|
@@ -2361,7 +2272,7 @@ function mergeConfig(config1, config2) {
|
|
|
2361
2272
|
config2 = config2 || {};
|
|
2362
2273
|
const config = {};
|
|
2363
2274
|
|
|
2364
|
-
function getMergedValue(target, source, caseless) {
|
|
2275
|
+
function getMergedValue(target, source, prop, caseless) {
|
|
2365
2276
|
if (utils$1.isPlainObject(target) && utils$1.isPlainObject(source)) {
|
|
2366
2277
|
return utils$1.merge.call({caseless}, target, source);
|
|
2367
2278
|
} else if (utils$1.isPlainObject(source)) {
|
|
@@ -2373,11 +2284,11 @@ function mergeConfig(config1, config2) {
|
|
|
2373
2284
|
}
|
|
2374
2285
|
|
|
2375
2286
|
// eslint-disable-next-line consistent-return
|
|
2376
|
-
function mergeDeepProperties(a, b, caseless) {
|
|
2287
|
+
function mergeDeepProperties(a, b, prop , caseless) {
|
|
2377
2288
|
if (!utils$1.isUndefined(b)) {
|
|
2378
|
-
return getMergedValue(a, b, caseless);
|
|
2289
|
+
return getMergedValue(a, b, prop , caseless);
|
|
2379
2290
|
} else if (!utils$1.isUndefined(a)) {
|
|
2380
|
-
return getMergedValue(undefined, a, caseless);
|
|
2291
|
+
return getMergedValue(undefined, a, prop , caseless);
|
|
2381
2292
|
}
|
|
2382
2293
|
}
|
|
2383
2294
|
|
|
@@ -2435,7 +2346,7 @@ function mergeConfig(config1, config2) {
|
|
|
2435
2346
|
socketPath: defaultToConfig2,
|
|
2436
2347
|
responseEncoding: defaultToConfig2,
|
|
2437
2348
|
validateStatus: mergeDirectKeys,
|
|
2438
|
-
headers: (a, b) => mergeDeepProperties(headersToObject(a), headersToObject(b), true)
|
|
2349
|
+
headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)
|
|
2439
2350
|
};
|
|
2440
2351
|
|
|
2441
2352
|
utils$1.forEach(Object.keys(Object.assign({}, config1, config2)), function computeConfigValue(prop) {
|
|
@@ -3177,7 +3088,7 @@ function dispatchRequest(config) {
|
|
|
3177
3088
|
});
|
|
3178
3089
|
}
|
|
3179
3090
|
|
|
3180
|
-
const VERSION = "1.7.
|
|
3091
|
+
const VERSION = "1.7.9";
|
|
3181
3092
|
|
|
3182
3093
|
const validators$1 = {};
|
|
3183
3094
|
|
|
@@ -3228,6 +3139,14 @@ validators$1.transitional = function transitional(validator, version, message) {
|
|
|
3228
3139
|
};
|
|
3229
3140
|
};
|
|
3230
3141
|
|
|
3142
|
+
validators$1.spelling = function spelling(correctSpelling) {
|
|
3143
|
+
return (value, opt) => {
|
|
3144
|
+
// eslint-disable-next-line no-console
|
|
3145
|
+
console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);
|
|
3146
|
+
return true;
|
|
3147
|
+
}
|
|
3148
|
+
};
|
|
3149
|
+
|
|
3231
3150
|
/**
|
|
3232
3151
|
* Assert object's properties type
|
|
3233
3152
|
*
|
|
@@ -3297,9 +3216,9 @@ class Axios {
|
|
|
3297
3216
|
return await this._request(configOrUrl, config);
|
|
3298
3217
|
} catch (err) {
|
|
3299
3218
|
if (err instanceof Error) {
|
|
3300
|
-
let dummy;
|
|
3219
|
+
let dummy = {};
|
|
3301
3220
|
|
|
3302
|
-
Error.captureStackTrace ? Error.captureStackTrace(dummy
|
|
3221
|
+
Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());
|
|
3303
3222
|
|
|
3304
3223
|
// slice off the Error: ... line
|
|
3305
3224
|
const stack = dummy.stack ? dummy.stack.replace(/^.+\n/, '') : '';
|
|
@@ -3354,6 +3273,11 @@ class Axios {
|
|
|
3354
3273
|
}
|
|
3355
3274
|
}
|
|
3356
3275
|
|
|
3276
|
+
validator.assertOptions(config, {
|
|
3277
|
+
baseUrl: validators.spelling('baseURL'),
|
|
3278
|
+
withXsrfToken: validators.spelling('withXSRFToken')
|
|
3279
|
+
}, true);
|
|
3280
|
+
|
|
3357
3281
|
// Set config.method
|
|
3358
3282
|
config.method = (config.method || this.defaults.method || 'get').toLowerCase();
|
|
3359
3283
|
|
|
@@ -3791,445 +3715,54 @@ const instance = axios$1.create();
|
|
|
3791
3715
|
|
|
3792
3716
|
const axios = setupCache(instance, { cacheTakeover: false });
|
|
3793
3717
|
|
|
3794
|
-
/**
|
|
3795
|
-
|
|
3796
|
-
/**
|
|
3797
|
-
* @type {{
|
|
3798
|
-
* type: string;
|
|
3799
|
-
* geometry: {
|
|
3800
|
-
* type: string;
|
|
3801
|
-
* coordinates: [number, number];
|
|
3802
|
-
* };
|
|
3803
|
-
* }[]}
|
|
3804
|
-
*/
|
|
3805
|
-
const features = [];
|
|
3806
|
-
links?.forEach((element) => {
|
|
3807
|
-
if (element.rel === "item" && "latlng" in element) {
|
|
3808
|
-
const [lat, lon] = /** @type {string} */ (element.latlng)
|
|
3809
|
-
.split(",")
|
|
3810
|
-
.map((it) => Number(it));
|
|
3811
|
-
features.push({
|
|
3812
|
-
type: "Feature",
|
|
3813
|
-
geometry: {
|
|
3814
|
-
type: "Point",
|
|
3815
|
-
coordinates: [lon, lat],
|
|
3816
|
-
},
|
|
3817
|
-
});
|
|
3818
|
-
}
|
|
3819
|
-
});
|
|
3820
|
-
const geojsonObject = {
|
|
3821
|
-
type: "FeatureCollection",
|
|
3822
|
-
crs: {
|
|
3823
|
-
type: "name",
|
|
3824
|
-
properties: {
|
|
3825
|
-
name: "EPSG:4326",
|
|
3826
|
-
},
|
|
3827
|
-
},
|
|
3828
|
-
features,
|
|
3829
|
-
};
|
|
3830
|
-
return geojsonObject;
|
|
3831
|
-
}
|
|
3718
|
+
/** setting default log level globally to warning */
|
|
3719
|
+
log.setLevel(log.levels.WARN, true);
|
|
3832
3720
|
|
|
3833
|
-
/**
|
|
3834
|
-
|
|
3835
|
-
/** @type {Record<string,unknown> | undefined} */
|
|
3836
|
-
let layerConfig = undefined;
|
|
3837
|
-
if (style?.jsonform) {
|
|
3838
|
-
layerConfig = { schema: style.jsonform, type: "style" };
|
|
3839
|
-
style = { ...style };
|
|
3840
|
-
delete style.jsonform;
|
|
3841
|
-
if (style?.legend) {
|
|
3842
|
-
layerConfig.legend = style.legend;
|
|
3843
|
-
delete style.legend;
|
|
3844
|
-
}
|
|
3845
|
-
}
|
|
3846
|
-
log.debug(
|
|
3847
|
-
"extracted layerConfig",
|
|
3848
|
-
JSON.parse(JSON.stringify({ layerConfig, style })),
|
|
3849
|
-
);
|
|
3721
|
+
/** Currently selected STAC endpoint */
|
|
3722
|
+
const currentUrl = ref("");
|
|
3850
3723
|
|
|
3851
|
-
|
|
3852
|
-
|
|
3724
|
+
/** Currently selected compare STAC endpoint */
|
|
3725
|
+
const currentCompareUrl = ref("");
|
|
3853
3726
|
|
|
3854
|
-
/**
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
const setMapProjFromCol = async (STAcCollection) => {
|
|
3860
|
-
// if a projection exists on the collection level
|
|
3861
|
-
log.debug("Checking for available map projection in indicator");
|
|
3862
|
-
const projection =
|
|
3863
|
-
/** @type {number | string | {name: string, def: string} | undefined} */
|
|
3864
|
-
(
|
|
3865
|
-
STAcCollection?.["eodash:mapProjection"] ||
|
|
3866
|
-
STAcCollection?.["proj:epsg"] ||
|
|
3867
|
-
STAcCollection?.["eodash:proj4_def"]
|
|
3868
|
-
);
|
|
3869
|
-
if (projection) {
|
|
3870
|
-
log.debug("Projection found", projection);
|
|
3871
|
-
await registerProjection(projection);
|
|
3872
|
-
const projectionCode = getProjectionCode(projection);
|
|
3873
|
-
if (availableMapProjection.value !== projectionCode) {
|
|
3874
|
-
log.debug(
|
|
3875
|
-
"Changing map projection",
|
|
3876
|
-
availableMapProjection.value,
|
|
3877
|
-
projectionCode,
|
|
3878
|
-
);
|
|
3879
|
-
await changeMapProjection(projection);
|
|
3880
|
-
}
|
|
3881
|
-
// set it for `EodashMapBtns`
|
|
3882
|
-
availableMapProjection.value = /** @type {string} */ (projectionCode);
|
|
3883
|
-
} else {
|
|
3884
|
-
// reset to default projection
|
|
3885
|
-
log.debug("Resetting projection to default EPSG:3857");
|
|
3886
|
-
await changeMapProjection((availableMapProjection.value = ""));
|
|
3887
|
-
}
|
|
3888
|
-
};
|
|
3727
|
+
/** Currently selected datetime */
|
|
3728
|
+
const datetime = ref(new Date().toISOString());
|
|
3729
|
+
|
|
3730
|
+
/** Currently selected indicator */
|
|
3731
|
+
const indicator = ref("");
|
|
3889
3732
|
|
|
3890
3733
|
/**
|
|
3891
|
-
*
|
|
3892
|
-
*
|
|
3893
|
-
*
|
|
3894
|
-
* | import("stac-ts").StacItem
|
|
3895
|
-
* | null
|
|
3896
|
-
* } stacObject
|
|
3897
|
-
* @param {string} basepath
|
|
3898
|
-
* @returns {string[]}
|
|
3734
|
+
* Current map position
|
|
3735
|
+
*
|
|
3736
|
+
* @type {import("vue").Ref<(number | undefined)[]>}
|
|
3899
3737
|
*/
|
|
3900
|
-
|
|
3901
|
-
const collectionUrls = [];
|
|
3902
|
-
// Support for two structure types, flat and indicator, simplified here:
|
|
3903
|
-
// Flat assumes Catalog-Collection-Item
|
|
3904
|
-
// Indicator assumes Catalog-Collection-Collection-Item
|
|
3905
|
-
// TODO: this is not the most stable test approach,
|
|
3906
|
-
// we should discuss potential other approaches
|
|
3907
|
-
if (stacObject?.links && stacObject?.links[1]?.rel === "item") {
|
|
3908
|
-
collectionUrls.push(basepath);
|
|
3909
|
-
} else if (stacObject?.links[1]?.rel === "child") {
|
|
3910
|
-
// TODO: Iterate through all children to create collections
|
|
3911
|
-
stacObject.links.forEach((link) => {
|
|
3912
|
-
if (link.rel === "child") {
|
|
3913
|
-
collectionUrls.push(toAbsolute(link.href, basepath));
|
|
3914
|
-
}
|
|
3915
|
-
});
|
|
3916
|
-
}
|
|
3917
|
-
return collectionUrls;
|
|
3918
|
-
}
|
|
3738
|
+
const mapPosition = ref([]);
|
|
3919
3739
|
|
|
3920
|
-
|
|
3921
|
-
* Assign extracted roles to layer properties
|
|
3922
|
-
* @param {Record<string,any>} properties
|
|
3923
|
-
* @param {import("stac-ts").StacLink | import("stac-ts").StacAsset} linkOrAsset
|
|
3924
|
-
* */
|
|
3925
|
-
const extractRoles = (properties, linkOrAsset) => {
|
|
3926
|
-
const roles = /** @type {string[]} */ (linkOrAsset.roles);
|
|
3927
|
-
roles?.forEach((role) => {
|
|
3928
|
-
if (role === "visible") {
|
|
3929
|
-
properties.visible = true;
|
|
3930
|
-
}
|
|
3931
|
-
if (role === "overlay" || role === "baselayer") {
|
|
3932
|
-
properties.group = role;
|
|
3933
|
-
//remove all the properties and replace the random ID with baselayer
|
|
3934
|
-
// provided ID
|
|
3935
|
-
// const [_colId, _itemId, _isAsset, _random, proj] =
|
|
3936
|
-
// properties.id.split(";:;");
|
|
3937
|
-
// properties.id = ["", "", "", "", linkOrAsset.id, proj].join(";:;");
|
|
3938
|
-
}
|
|
3740
|
+
const registeredProjections = ["EPSG:4326", "EPSG:3857"];
|
|
3939
3741
|
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
};
|
|
3742
|
+
/** available projection to be rendered by `EodashMap` */
|
|
3743
|
+
const availableMapProjection = ref("EPSG:3857");
|
|
3943
3744
|
|
|
3944
|
-
/**
|
|
3945
|
-
|
|
3946
|
-
* @param {string} itemUrl
|
|
3947
|
-
**/
|
|
3948
|
-
const fetchStyle = async (item, itemUrl) => {
|
|
3949
|
-
const styleLink = item.links.find((link) => link.rel.includes("style"));
|
|
3950
|
-
if (styleLink) {
|
|
3951
|
-
let url = "";
|
|
3952
|
-
if (styleLink.href.startsWith("http")) {
|
|
3953
|
-
url = styleLink.href;
|
|
3954
|
-
} else {
|
|
3955
|
-
url = toAbsolute(styleLink.href, itemUrl);
|
|
3956
|
-
}
|
|
3745
|
+
/** @type {import("vue").Ref<HTMLElement & Record<string,any> | null>} */
|
|
3746
|
+
const mapEl = ref(null);
|
|
3957
3747
|
|
|
3958
|
-
|
|
3959
|
-
|
|
3748
|
+
/** @type {import("vue").Ref<HTMLElement & Record<string,any> | null>} */
|
|
3749
|
+
const mapCompareEl = ref(null);
|
|
3960
3750
|
|
|
3961
|
-
|
|
3962
|
-
return { ...styleJson };
|
|
3963
|
-
}
|
|
3964
|
-
};
|
|
3751
|
+
const activeTemplate = ref("");
|
|
3965
3752
|
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
break;
|
|
3980
|
-
case "object":
|
|
3981
|
-
code = projection?.name;
|
|
3982
|
-
}
|
|
3983
|
-
return /** @type {string} */ (code);
|
|
3984
|
-
};
|
|
3985
|
-
|
|
3986
|
-
/**
|
|
3987
|
-
* @param {import("stac-ts").StacLink[]} [links]
|
|
3988
|
-
* @param {string|null} [currentStep]
|
|
3989
|
-
**/
|
|
3990
|
-
const extractLayerDatetime = (links, currentStep) => {
|
|
3991
|
-
if (!currentStep || !links?.length) {
|
|
3992
|
-
return undefined;
|
|
3993
|
-
}
|
|
3994
|
-
|
|
3995
|
-
// check if links has a datetime value
|
|
3996
|
-
const hasDatetime = links.some((l) => typeof l.datetime === "string");
|
|
3997
|
-
if (!hasDatetime) {
|
|
3998
|
-
return undefined;
|
|
3999
|
-
}
|
|
4000
|
-
|
|
4001
|
-
/** @type {string[]} */
|
|
4002
|
-
const controlValues = [];
|
|
4003
|
-
try {
|
|
4004
|
-
currentStep = new Date(currentStep).toISOString();
|
|
4005
|
-
|
|
4006
|
-
links.reduce((vals, link) => {
|
|
4007
|
-
if (link.datetime && link.rel === "item") {
|
|
4008
|
-
vals.push(
|
|
4009
|
-
new Date(/** @type {string} */ (link.datetime)).toISOString(),
|
|
4010
|
-
);
|
|
4011
|
-
}
|
|
4012
|
-
return vals;
|
|
4013
|
-
}, controlValues);
|
|
4014
|
-
} catch (e) {
|
|
4015
|
-
console.warn("[eodash] not supported datetime format was provided", e);
|
|
4016
|
-
return undefined;
|
|
4017
|
-
}
|
|
4018
|
-
// not enough controlValues
|
|
4019
|
-
if (controlValues.length <= 1) {
|
|
4020
|
-
return undefined;
|
|
4021
|
-
}
|
|
4022
|
-
|
|
4023
|
-
// item datetime is not included in the item links datetime
|
|
4024
|
-
if (!controlValues.includes(currentStep)) {
|
|
4025
|
-
return undefined;
|
|
4026
|
-
}
|
|
4027
|
-
|
|
4028
|
-
return {
|
|
4029
|
-
controlValues,
|
|
4030
|
-
currentStep,
|
|
4031
|
-
slider: true,
|
|
4032
|
-
disablePlay: true,
|
|
4033
|
-
};
|
|
4034
|
-
};
|
|
4035
|
-
|
|
4036
|
-
/**
|
|
4037
|
-
* Find layer by ID
|
|
4038
|
-
* @param {string} layer
|
|
4039
|
-
* @param {Record<string, any>[]} layers
|
|
4040
|
-
* @returns {Record<string,any> | undefined}
|
|
4041
|
-
**/
|
|
4042
|
-
const findLayer = (layers, layer) => {
|
|
4043
|
-
for (const lyr of layers) {
|
|
4044
|
-
if (lyr.type === "Group") {
|
|
4045
|
-
const found = findLayer(lyr.layers, layer);
|
|
4046
|
-
if (!found) {
|
|
4047
|
-
continue;
|
|
4048
|
-
}
|
|
4049
|
-
return found;
|
|
4050
|
-
}
|
|
4051
|
-
if (lyr.properties.id === layer) {
|
|
4052
|
-
return lyr;
|
|
4053
|
-
}
|
|
4054
|
-
}
|
|
4055
|
-
};
|
|
4056
|
-
|
|
4057
|
-
/**
|
|
4058
|
-
* @param {Record<string,any>[]} currentLayers
|
|
4059
|
-
* @param {Record<string,any>} oldLayer
|
|
4060
|
-
* @param {Record<string,any>[]} newLayers
|
|
4061
|
-
* @returns {Record<string,any>[] | undefined}
|
|
4062
|
-
*/
|
|
4063
|
-
const replaceLayer = (currentLayers, oldLayer, newLayers) => {
|
|
4064
|
-
const oldLayerIdx = currentLayers.findIndex(
|
|
4065
|
-
(l) => l.properties.id === oldLayer.properties.id,
|
|
4066
|
-
);
|
|
4067
|
-
if (oldLayerIdx !== -1) {
|
|
4068
|
-
currentLayers.splice(oldLayerIdx, 1, ...newLayers);
|
|
4069
|
-
return currentLayers;
|
|
4070
|
-
}
|
|
4071
|
-
|
|
4072
|
-
for (const l of currentLayers) {
|
|
4073
|
-
if (l.type === "Group") {
|
|
4074
|
-
const updatedGroupLyrs = replaceLayer(l.layers, oldLayer, newLayers);
|
|
4075
|
-
if (updatedGroupLyrs?.length) {
|
|
4076
|
-
l.layers = updatedGroupLyrs;
|
|
4077
|
-
return currentLayers;
|
|
4078
|
-
}
|
|
4079
|
-
}
|
|
4080
|
-
}
|
|
4081
|
-
};
|
|
4082
|
-
/**
|
|
4083
|
-
* @param {import('./eodashSTAC.js').EodashCollection[]} indicators
|
|
4084
|
-
* @param {import('ol/layer').Layer} layer
|
|
4085
|
-
*/
|
|
4086
|
-
const getColFromLayer = async (indicators, layer) => {
|
|
4087
|
-
// init cols
|
|
4088
|
-
const collections = await Promise.all(
|
|
4089
|
-
indicators.map((ind) => ind.fetchCollection()),
|
|
4090
|
-
);
|
|
4091
|
-
const [collectionId, itemId, ..._other] = layer.get("id").split(";:;");
|
|
4092
|
-
|
|
4093
|
-
const chosen = collections.find((col) => {
|
|
4094
|
-
const isInd =
|
|
4095
|
-
col.id === collectionId &&
|
|
4096
|
-
col.links?.some(
|
|
4097
|
-
(link) => link.rel === "item" && link.href.includes(itemId),
|
|
4098
|
-
);
|
|
4099
|
-
return isInd ?? false;
|
|
4100
|
-
});
|
|
4101
|
-
return indicators.find((ind) => ind.collectionStac?.id === chosen?.id);
|
|
4102
|
-
};
|
|
4103
|
-
|
|
4104
|
-
/**
|
|
4105
|
-
* generates layer specific ID, related functions are: {@link assignProjID} & {@link extractRoles}
|
|
4106
|
-
* @param {string} collectionId
|
|
4107
|
-
* @param {string} itemId
|
|
4108
|
-
* @param {import('stac-ts').StacLink} link
|
|
4109
|
-
* @param {string} projectionCode
|
|
4110
|
-
*
|
|
4111
|
-
*/
|
|
4112
|
-
const createLayerID = (collectionId, itemId, link, projectionCode) => {
|
|
4113
|
-
const linkId = link.id || link.title || link.href;
|
|
4114
|
-
let lId = `${collectionId ?? ""};:;${itemId ?? ""};:;${linkId ?? ""};:;${projectionCode ?? ""}`;
|
|
4115
|
-
// If we are looking at base layers and overlays we remove the collection and item part
|
|
4116
|
-
// as we want to make sure tiles are not reloaded when switching layers
|
|
4117
|
-
if (
|
|
4118
|
-
link.roles &&
|
|
4119
|
-
// @ts-expect-error it seems roles it not defined for links yet
|
|
4120
|
-
link.roles.find((r) => ["baselayer", "overlay"].includes(r))
|
|
4121
|
-
) {
|
|
4122
|
-
lId = `${linkId ?? ""};:;${projectionCode ?? ""}`;
|
|
4123
|
-
}
|
|
4124
|
-
log.debug("Generated Layer ID", lId);
|
|
4125
|
-
return lId;
|
|
4126
|
-
};
|
|
4127
|
-
|
|
4128
|
-
/**
|
|
4129
|
-
* generates layer specific ID, related functions are: {@link assignProjID} & {@link extractRoles}
|
|
4130
|
-
* @param {string} collectionId
|
|
4131
|
-
* @param {string} itemId
|
|
4132
|
-
* @param {number} index
|
|
4133
|
-
*
|
|
4134
|
-
*/
|
|
4135
|
-
const createAssetID = (collectionId, itemId, index) => {
|
|
4136
|
-
let lId = `${collectionId ?? ""};:;${itemId ?? ""};:;${index ?? ""}`;
|
|
4137
|
-
log.debug("Generated Asset ID", lId);
|
|
4138
|
-
return lId;
|
|
4139
|
-
};
|
|
4140
|
-
|
|
4141
|
-
/**
|
|
4142
|
-
* creates a structured clone from the layers and
|
|
4143
|
-
* removes all properties from the clone
|
|
4144
|
-
* except the ID and title
|
|
4145
|
-
*
|
|
4146
|
-
* @param {Record<string,any>[]} layers
|
|
4147
|
-
*/
|
|
4148
|
-
const removeUnneededProperties = (layers) => {
|
|
4149
|
-
const cloned = structuredClone(layers);
|
|
4150
|
-
cloned.forEach((layer) => {
|
|
4151
|
-
const id = layer.properties.id;
|
|
4152
|
-
const title = layer.properties.title;
|
|
4153
|
-
layer.properties = { id, title };
|
|
4154
|
-
if (layer["interactions"]) {
|
|
4155
|
-
delete layer["interactions"];
|
|
4156
|
-
}
|
|
4157
|
-
if (layer.type === "Group") {
|
|
4158
|
-
layer.layers = removeUnneededProperties(layer.layers);
|
|
4159
|
-
}
|
|
4160
|
-
});
|
|
4161
|
-
return cloned;
|
|
4162
|
-
};
|
|
4163
|
-
|
|
4164
|
-
/**
|
|
4165
|
-
* Returns the current layers of {@link mapEl}
|
|
4166
|
-
* @returns {Record<string,any>[]}
|
|
4167
|
-
*/
|
|
4168
|
-
const getLayers = () => mapEl.value?.layers.toReversed();
|
|
4169
|
-
|
|
4170
|
-
/**
|
|
4171
|
-
* Returns the current layers of {@link mapCompareEl}
|
|
4172
|
-
* @returns {Record<string,any>[]}
|
|
4173
|
-
*/
|
|
4174
|
-
const getCompareLayers = () => mapCompareEl.value?.layers.toReversed();
|
|
4175
|
-
|
|
4176
|
-
/**
|
|
4177
|
-
* Register EPSG projection in `eox-map`
|
|
4178
|
-
* @param {string|number|{name: string, def: string, extent?:number[]}} [projection]*/
|
|
4179
|
-
const registerProjection = async (projection) => {
|
|
4180
|
-
let code = getProjectionCode(projection);
|
|
4181
|
-
if (!code || registeredProjections.includes(code)) {
|
|
4182
|
-
return;
|
|
4183
|
-
}
|
|
4184
|
-
log.debug("Unregistered projection found, registering it", code);
|
|
4185
|
-
registeredProjections.push(code);
|
|
4186
|
-
if (typeof projection === "object") {
|
|
4187
|
-
// registering whole projection definition
|
|
4188
|
-
await mapEl.value?.registerProjection(
|
|
4189
|
-
code,
|
|
4190
|
-
projection.def,
|
|
4191
|
-
projection.extent,
|
|
4192
|
-
);
|
|
4193
|
-
// also registering for comparison map
|
|
4194
|
-
await mapCompareEl.value?.registerProjection(
|
|
4195
|
-
code,
|
|
4196
|
-
projection.def,
|
|
4197
|
-
projection.extent,
|
|
4198
|
-
);
|
|
4199
|
-
} else {
|
|
4200
|
-
await mapEl.value?.registerProjectionFromCode(code);
|
|
4201
|
-
// also registering for comparison map
|
|
4202
|
-
await mapCompareEl.value?.registerProjectionFromCode(code);
|
|
4203
|
-
}
|
|
4204
|
-
};
|
|
4205
|
-
/**
|
|
4206
|
-
* Change `eox-map` projection from an `EPSG` projection
|
|
4207
|
-
* @param {string|number|{name: string, def: string}} [projection]*/
|
|
4208
|
-
const changeMapProjection = async (projection) => {
|
|
4209
|
-
let code = getProjectionCode(projection);
|
|
4210
|
-
|
|
4211
|
-
if (!code) {
|
|
4212
|
-
mapEl.value?.setAttribute("projection", "EPSG:3857");
|
|
4213
|
-
mapCompareEl.value?.setAttribute("projection", "EPSG:3857");
|
|
4214
|
-
return;
|
|
4215
|
-
}
|
|
4216
|
-
|
|
4217
|
-
if (!registeredProjections.includes(code)) {
|
|
4218
|
-
await registerProjection(projection);
|
|
4219
|
-
}
|
|
4220
|
-
|
|
4221
|
-
code = mapEl.value?.getAttribute("projection") === code ? "EPSG:3857" : code;
|
|
4222
|
-
mapEl.value?.setAttribute("projection", code);
|
|
4223
|
-
mapCompareEl.value?.setAttribute("projection", code);
|
|
4224
|
-
};
|
|
4225
|
-
|
|
4226
|
-
const __vite_glob_0_0 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
4227
|
-
__proto__: null,
|
|
4228
|
-
changeMapProjection,
|
|
4229
|
-
getCompareLayers,
|
|
4230
|
-
getLayers,
|
|
4231
|
-
registerProjection
|
|
4232
|
-
}, Symbol.toStringTag, { value: 'Module' }));
|
|
3753
|
+
const states = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
3754
|
+
__proto__: null,
|
|
3755
|
+
activeTemplate,
|
|
3756
|
+
availableMapProjection,
|
|
3757
|
+
currentCompareUrl,
|
|
3758
|
+
currentUrl,
|
|
3759
|
+
datetime,
|
|
3760
|
+
indicator,
|
|
3761
|
+
mapCompareEl,
|
|
3762
|
+
mapEl,
|
|
3763
|
+
mapPosition,
|
|
3764
|
+
registeredProjections
|
|
3765
|
+
}, Symbol.toStringTag, { value: 'Module' }));
|
|
4233
3766
|
|
|
4234
3767
|
/**
|
|
4235
3768
|
* Reactive Edoash Instance Object. provided globally in the app, and used as an
|
|
@@ -4240,165 +3773,423 @@ const __vite_glob_0_0 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.definePro
|
|
|
4240
3773
|
const eodash = reactive({
|
|
4241
3774
|
id: "demo",
|
|
4242
3775
|
stacEndpoint:
|
|
4243
|
-
"https://
|
|
3776
|
+
// "https://eurodatacube.github.io/eodash-catalog/RACE/catalog.json",
|
|
3777
|
+
// "https://gtif-cerulean.github.io/catalog/cerulean/catalog.json",
|
|
3778
|
+
"https://eodashcatalog.eox.at/samplecatalog/samples/catalog.json",
|
|
3779
|
+
// "https://eodashcatalog.eox.at/test-style/trilateral/catalog.json",
|
|
4244
3780
|
// "https://gtif-cerulean.github.io/catalog/cerulean/catalog.json",
|
|
4245
3781
|
brand: {
|
|
4246
3782
|
noLayout: true,
|
|
4247
3783
|
name: "Demo",
|
|
4248
3784
|
theme: {
|
|
4249
3785
|
colors: {
|
|
4250
|
-
primary: "#
|
|
4251
|
-
secondary: "#
|
|
4252
|
-
surface: "#
|
|
3786
|
+
primary: "#002742",
|
|
3787
|
+
secondary: "#0071C2",
|
|
3788
|
+
surface: "#ffff",
|
|
3789
|
+
},
|
|
3790
|
+
variables: {
|
|
3791
|
+
"surface-opacity": 0.6,
|
|
3792
|
+
"primary-opacity": 0.8,
|
|
4253
3793
|
},
|
|
4254
3794
|
},
|
|
4255
3795
|
footerText: "Demo configuration of eodash client",
|
|
4256
3796
|
},
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
widget: {
|
|
4262
|
-
// https://uiball.com/ldrs/
|
|
4263
|
-
link: "https://cdn.jsdelivr.net/npm/ldrs/dist/auto/mirage.js",
|
|
4264
|
-
tagName: "l-mirage",
|
|
4265
|
-
properties: {
|
|
4266
|
-
class: "align-self-center justify-self-center",
|
|
4267
|
-
size: "120",
|
|
4268
|
-
speed: "2.5",
|
|
4269
|
-
color: "#004170",
|
|
4270
|
-
},
|
|
4271
|
-
},
|
|
4272
|
-
},
|
|
4273
|
-
background: {
|
|
4274
|
-
id: Symbol(),
|
|
4275
|
-
type: "internal",
|
|
4276
|
-
widget: {
|
|
4277
|
-
name: "EodashMap",
|
|
4278
|
-
properties: {
|
|
4279
|
-
enableCompare: true,
|
|
4280
|
-
},
|
|
4281
|
-
},
|
|
4282
|
-
},
|
|
4283
|
-
widgets: [
|
|
4284
|
-
{
|
|
3797
|
+
templates: {
|
|
3798
|
+
light: {
|
|
3799
|
+
gap: 16,
|
|
3800
|
+
loading: {
|
|
4285
3801
|
id: Symbol(),
|
|
4286
|
-
type: "
|
|
4287
|
-
title: "Indicators",
|
|
4288
|
-
layout: { x: 0, y: 0, w: 3, h: 6 },
|
|
3802
|
+
type: "web-component",
|
|
4289
3803
|
widget: {
|
|
4290
|
-
|
|
3804
|
+
// https://uiball.com/ldrs/
|
|
3805
|
+
link: "https://cdn.jsdelivr.net/npm/ldrs/dist/auto/mirage.js",
|
|
3806
|
+
tagName: "l-mirage",
|
|
4291
3807
|
properties: {
|
|
4292
|
-
|
|
4293
|
-
|
|
3808
|
+
class: "align-self-center justify-self-center",
|
|
3809
|
+
size: "120",
|
|
3810
|
+
speed: "2.5",
|
|
3811
|
+
color: "#004170",
|
|
4294
3812
|
},
|
|
4295
3813
|
},
|
|
4296
3814
|
},
|
|
4297
|
-
{
|
|
3815
|
+
background: {
|
|
4298
3816
|
id: Symbol(),
|
|
4299
3817
|
type: "internal",
|
|
4300
|
-
title: "Layer Control",
|
|
4301
|
-
layout: { x: 0, y: 6, w: 3, h: 6 },
|
|
4302
3818
|
widget: {
|
|
4303
|
-
name: "
|
|
3819
|
+
name: "EodashMap",
|
|
3820
|
+
properties: {
|
|
3821
|
+
enableCompare: true,
|
|
3822
|
+
},
|
|
4304
3823
|
},
|
|
4305
3824
|
},
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
3825
|
+
widgets: [
|
|
3826
|
+
{
|
|
3827
|
+
id: Symbol(),
|
|
3828
|
+
type: "internal",
|
|
3829
|
+
title: "Tools",
|
|
3830
|
+
layout: { x: 0, y: 0, w: 3, h: 1 },
|
|
3831
|
+
widget: {
|
|
3832
|
+
name: "EodashTools",
|
|
3833
|
+
properties: {
|
|
3834
|
+
layoutTarget: "expert",
|
|
3835
|
+
layoutIcon: mdiViewDashboardVariant,
|
|
3836
|
+
itemFilterConfig: {
|
|
3837
|
+
resultType: "cards",
|
|
3838
|
+
filtersTitle: "",
|
|
3839
|
+
style: "--padding: 72px",
|
|
3840
|
+
filterProperties: [],
|
|
3841
|
+
resultsTitle: "Explore more indicators",
|
|
3842
|
+
subTitleProperty: "subtitle",
|
|
3843
|
+
imageProperty: "thumbnail",
|
|
3844
|
+
},
|
|
3845
|
+
},
|
|
3846
|
+
},
|
|
4323
3847
|
},
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
summary {cursor: pointer;}
|
|
4349
|
-
#properties li > .value { font-weight: normal !important;}
|
|
4350
|
-
main {padding-bottom: 10px;}
|
|
4351
|
-
.footer-container {line-height:1;}
|
|
4352
|
-
.footer-container button {margin-top: -10px;}
|
|
4353
|
-
.footer-container small {font-size:10px;line-height:1;}`,
|
|
4354
|
-
header: '["title"]',
|
|
4355
|
-
tags: '["themes"]',
|
|
4356
|
-
subheader: "[]",
|
|
4357
|
-
properties: '["satellite","sensor","agency","extent"]',
|
|
4358
|
-
featured: '["description","providers","assets","links"]',
|
|
4359
|
-
footer: '["sci:citation"]',
|
|
3848
|
+
{
|
|
3849
|
+
defineWidget: (selectedSTAC) => {
|
|
3850
|
+
return selectedSTAC
|
|
3851
|
+
? {
|
|
3852
|
+
id: "layercontrol-light",
|
|
3853
|
+
type: "internal",
|
|
3854
|
+
title: "Layers",
|
|
3855
|
+
layout: { x: 0, y: 1, w: 3, h: 3 },
|
|
3856
|
+
widget: {
|
|
3857
|
+
name: "EodashLayerControl",
|
|
3858
|
+
properties: {
|
|
3859
|
+
slider: false,
|
|
3860
|
+
tools: ["datetime", "info", "legend"],
|
|
3861
|
+
cssVars: {
|
|
3862
|
+
"--list-padding": "0",
|
|
3863
|
+
"--tools-button-visibility": "none",
|
|
3864
|
+
"--layer-input-visibility": "none",
|
|
3865
|
+
"--layer-type-visibility": "none",
|
|
3866
|
+
"--padding": "16px",
|
|
3867
|
+
"--padding-vertical": "16px",
|
|
3868
|
+
"--layer-tools-button-visibility": "none",
|
|
3869
|
+
"--layer-summary-visibility": "none",
|
|
3870
|
+
},
|
|
3871
|
+
},
|
|
4360
3872
|
},
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
: null;
|
|
3873
|
+
}
|
|
3874
|
+
: null;
|
|
3875
|
+
},
|
|
4365
3876
|
},
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
3877
|
+
{
|
|
3878
|
+
defineWidget: (selectedSTAC) => {
|
|
3879
|
+
return selectedSTAC
|
|
3880
|
+
? {
|
|
3881
|
+
id: "stacinfo-light",
|
|
3882
|
+
type: "internal",
|
|
3883
|
+
title: "Information",
|
|
3884
|
+
layout: { x: 9, y: 0, w: 3, h: 6 },
|
|
3885
|
+
widget: {
|
|
3886
|
+
name: "EodashStacInfo",
|
|
3887
|
+
properties: {
|
|
3888
|
+
tags: [],
|
|
3889
|
+
header: [],
|
|
3890
|
+
footer: [],
|
|
3891
|
+
body: ["description"],
|
|
3892
|
+
styleOverride: "",
|
|
3893
|
+
featured: [],
|
|
3894
|
+
},
|
|
4380
3895
|
},
|
|
4381
|
-
}
|
|
4382
|
-
|
|
4383
|
-
|
|
3896
|
+
}
|
|
3897
|
+
: null;
|
|
3898
|
+
},
|
|
4384
3899
|
},
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
3900
|
+
{
|
|
3901
|
+
defineWidget: (selectedSTAC) => {
|
|
3902
|
+
return selectedSTAC
|
|
3903
|
+
? {
|
|
3904
|
+
id: "Datepicker",
|
|
3905
|
+
type: "internal",
|
|
3906
|
+
layout: { x: 5, y: 8, w: 2, h: 4 },
|
|
3907
|
+
title: "Date",
|
|
3908
|
+
widget: {
|
|
3909
|
+
name: "EodashDatePicker",
|
|
3910
|
+
properties: {
|
|
3911
|
+
hideArrows: true,
|
|
3912
|
+
hideInputField: true,
|
|
3913
|
+
hintText: `<b>Hint:</b> closest available date is displayed <br />
|
|
3914
|
+
on map (see Analysis Layers)`,
|
|
3915
|
+
},
|
|
3916
|
+
},
|
|
3917
|
+
}
|
|
3918
|
+
: null;
|
|
3919
|
+
},
|
|
3920
|
+
},
|
|
3921
|
+
],
|
|
3922
|
+
},
|
|
3923
|
+
expert: {
|
|
3924
|
+
loading: {
|
|
3925
|
+
id: Symbol(),
|
|
3926
|
+
type: "web-component",
|
|
3927
|
+
widget: {
|
|
3928
|
+
// https://uiball.com/ldrs/
|
|
3929
|
+
link: "https://cdn.jsdelivr.net/npm/ldrs/dist/auto/mirage.js",
|
|
3930
|
+
tagName: "l-mirage",
|
|
3931
|
+
properties: {
|
|
3932
|
+
class: "align-self-center justify-self-center",
|
|
3933
|
+
size: "120",
|
|
3934
|
+
speed: "2.5",
|
|
3935
|
+
color: "#004170",
|
|
3936
|
+
},
|
|
3937
|
+
},
|
|
3938
|
+
},
|
|
3939
|
+
background: {
|
|
3940
|
+
id: Symbol(),
|
|
3941
|
+
type: "internal",
|
|
3942
|
+
widget: {
|
|
3943
|
+
name: "EodashMap",
|
|
3944
|
+
properties: {
|
|
3945
|
+
enableCompare: true,
|
|
3946
|
+
},
|
|
3947
|
+
},
|
|
3948
|
+
},
|
|
3949
|
+
widgets: [
|
|
3950
|
+
{
|
|
3951
|
+
id: Symbol(),
|
|
3952
|
+
type: "internal",
|
|
3953
|
+
title: "Tools",
|
|
3954
|
+
layout: { x: 0, y: 0, w: 3, h: 1 },
|
|
3955
|
+
widget: {
|
|
3956
|
+
name: "EodashTools",
|
|
3957
|
+
properties: {
|
|
3958
|
+
layoutTarget: "light",
|
|
3959
|
+
layoutIcon: mdiViewDashboard,
|
|
3960
|
+
itemFilterConfig: {
|
|
3961
|
+
resultType: "cards",
|
|
3962
|
+
subTitleProperty: "subtitle",
|
|
3963
|
+
imageProperty: "thumbnail",
|
|
3964
|
+
aggregateResults: "collection_group",
|
|
3965
|
+
style: {
|
|
3966
|
+
"--form-flex-direction": "row",
|
|
3967
|
+
},
|
|
3968
|
+
},
|
|
3969
|
+
},
|
|
3970
|
+
},
|
|
3971
|
+
},
|
|
3972
|
+
{
|
|
3973
|
+
id: Symbol(),
|
|
3974
|
+
type: "internal",
|
|
3975
|
+
title: "Layers",
|
|
3976
|
+
layout: { x: 0, y: 1, w: 3, h: 6 },
|
|
3977
|
+
widget: {
|
|
3978
|
+
name: "EodashLayerControl",
|
|
3979
|
+
},
|
|
3980
|
+
},
|
|
3981
|
+
{
|
|
3982
|
+
defineWidget: (selectedSTAC) => {
|
|
3983
|
+
return selectedSTAC
|
|
3984
|
+
? {
|
|
3985
|
+
id: "Information",
|
|
3986
|
+
title: "Information",
|
|
3987
|
+
layout: { x: 9, y: 0, w: 3, h: 6 },
|
|
3988
|
+
type: "internal",
|
|
3989
|
+
widget: {
|
|
3990
|
+
name: "EodashStacInfo",
|
|
3991
|
+
properties: {
|
|
3992
|
+
showIndicatorsBtn: false,
|
|
3993
|
+
showLayoutSwitcher: false,
|
|
3994
|
+
},
|
|
3995
|
+
},
|
|
3996
|
+
}
|
|
3997
|
+
: null;
|
|
3998
|
+
},
|
|
3999
|
+
},
|
|
4000
|
+
{
|
|
4001
|
+
defineWidget: (selectedSTAC) => {
|
|
4002
|
+
return selectedSTAC
|
|
4003
|
+
? {
|
|
4004
|
+
id: "Datepicker",
|
|
4005
|
+
type: "internal",
|
|
4006
|
+
layout: { x: 5, y: 8, w: 2, h: 4 },
|
|
4007
|
+
title: "Date",
|
|
4008
|
+
widget: {
|
|
4009
|
+
name: "EodashDatePicker",
|
|
4010
|
+
properties: {
|
|
4011
|
+
hintText: `<b>Hint:</b> closest available date is displayed <br />
|
|
4012
|
+
on map (see Analysis Layers)`,
|
|
4013
|
+
},
|
|
4014
|
+
},
|
|
4015
|
+
}
|
|
4016
|
+
: null;
|
|
4017
|
+
},
|
|
4018
|
+
},
|
|
4019
|
+
{
|
|
4020
|
+
defineWidget: (selected) => {
|
|
4021
|
+
return selected
|
|
4022
|
+
? {
|
|
4023
|
+
id: "Buttons",
|
|
4024
|
+
layout: { x: 8, y: 0, w: 1, h: 2 },
|
|
4025
|
+
title: "Buttons",
|
|
4026
|
+
type: "internal",
|
|
4027
|
+
widget: {
|
|
4028
|
+
name: "EodashMapBtns",
|
|
4029
|
+
},
|
|
4030
|
+
}
|
|
4031
|
+
: null;
|
|
4032
|
+
},
|
|
4033
|
+
},
|
|
4034
|
+
{
|
|
4035
|
+
defineWidget: (selectedSTAC) =>
|
|
4036
|
+
selectedSTAC?.links.some((l) => l.rel === "service")
|
|
4037
|
+
? {
|
|
4038
|
+
id: Symbol(),
|
|
4039
|
+
type: "internal",
|
|
4040
|
+
title: "Processes",
|
|
4041
|
+
layout: { x: 0, y: 7, w: 3, h: 5 },
|
|
4042
|
+
widget: {
|
|
4043
|
+
name: "EodashProcess",
|
|
4044
|
+
},
|
|
4045
|
+
}
|
|
4046
|
+
: null,
|
|
4047
|
+
},
|
|
4048
|
+
],
|
|
4049
|
+
},
|
|
4050
|
+
compare: {
|
|
4051
|
+
gap: 16,
|
|
4052
|
+
loading: {
|
|
4053
|
+
id: Symbol(),
|
|
4054
|
+
type: "web-component",
|
|
4055
|
+
widget: {
|
|
4056
|
+
// https://uiball.com/ldrs/
|
|
4057
|
+
link: "https://cdn.jsdelivr.net/npm/ldrs/dist/auto/mirage.js",
|
|
4058
|
+
tagName: "l-mirage",
|
|
4059
|
+
properties: {
|
|
4060
|
+
class: "align-self-center justify-self-center",
|
|
4061
|
+
size: "120",
|
|
4062
|
+
speed: "2.5",
|
|
4063
|
+
color: "#004170",
|
|
4064
|
+
},
|
|
4065
|
+
},
|
|
4066
|
+
},
|
|
4067
|
+
background: {
|
|
4068
|
+
id: Symbol(),
|
|
4069
|
+
type: "internal",
|
|
4070
|
+
widget: {
|
|
4071
|
+
name: "EodashMap",
|
|
4072
|
+
properties: {
|
|
4073
|
+
enableCompare: true,
|
|
4074
|
+
},
|
|
4399
4075
|
},
|
|
4400
4076
|
},
|
|
4401
|
-
|
|
4077
|
+
widgets: [
|
|
4078
|
+
{
|
|
4079
|
+
id: Symbol(),
|
|
4080
|
+
type: "internal",
|
|
4081
|
+
title: "Tools",
|
|
4082
|
+
layout: { x: 0, y: 0, w: 3, h: 1 },
|
|
4083
|
+
widget: {
|
|
4084
|
+
name: "EodashTools",
|
|
4085
|
+
properties: {
|
|
4086
|
+
layoutTarget: "expert",
|
|
4087
|
+
layoutIcon: mdiViewDashboardVariant,
|
|
4088
|
+
itemFilterConfig: {
|
|
4089
|
+
cssVars: {
|
|
4090
|
+
"--form-flex-direction": "row",
|
|
4091
|
+
},
|
|
4092
|
+
},
|
|
4093
|
+
},
|
|
4094
|
+
},
|
|
4095
|
+
},
|
|
4096
|
+
// compare indicators
|
|
4097
|
+
{
|
|
4098
|
+
id: Symbol(),
|
|
4099
|
+
type: "internal",
|
|
4100
|
+
title: "Tools",
|
|
4101
|
+
layout: { x: 9, y: 0, w: 3, h: 1 },
|
|
4102
|
+
widget: {
|
|
4103
|
+
name: "EodashTools",
|
|
4104
|
+
properties: {
|
|
4105
|
+
showLayoutSwitcher: false,
|
|
4106
|
+
indicatorBtnText: "Select an indicator to compare",
|
|
4107
|
+
itemFilterConfig: {
|
|
4108
|
+
enableCompare: true,
|
|
4109
|
+
// resultsTitle:"Select an indicator to compare",
|
|
4110
|
+
filtersTitle: "Select an indicator to compare",
|
|
4111
|
+
// filterProperties: [],
|
|
4112
|
+
cssVars: {
|
|
4113
|
+
"--form-flex-direction": "row",
|
|
4114
|
+
},
|
|
4115
|
+
},
|
|
4116
|
+
},
|
|
4117
|
+
},
|
|
4118
|
+
},
|
|
4119
|
+
{
|
|
4120
|
+
id: Symbol(),
|
|
4121
|
+
type: "internal",
|
|
4122
|
+
title: "Layers",
|
|
4123
|
+
layout: { x: 0, y: 1, w: 3, h: 6 },
|
|
4124
|
+
widget: {
|
|
4125
|
+
name: "EodashLayerControl",
|
|
4126
|
+
},
|
|
4127
|
+
},
|
|
4128
|
+
{
|
|
4129
|
+
id: Symbol(),
|
|
4130
|
+
title: "Comparison Layers",
|
|
4131
|
+
layout: { x: 9, y: 1, w: 3, h: 6 },
|
|
4132
|
+
type: "internal",
|
|
4133
|
+
widget: {
|
|
4134
|
+
name: "EodashLayerControl",
|
|
4135
|
+
properties: {
|
|
4136
|
+
map: "second",
|
|
4137
|
+
},
|
|
4138
|
+
},
|
|
4139
|
+
},
|
|
4140
|
+
{
|
|
4141
|
+
defineWidget: (selectedSTAC) =>
|
|
4142
|
+
selectedSTAC?.links.some((l) => l.rel === "service")
|
|
4143
|
+
? {
|
|
4144
|
+
id: Symbol(),
|
|
4145
|
+
type: "internal",
|
|
4146
|
+
title: "Processes",
|
|
4147
|
+
layout: { x: 0, y: 7, w: 3, h: 5 },
|
|
4148
|
+
widget: {
|
|
4149
|
+
name: "EodashProcess",
|
|
4150
|
+
},
|
|
4151
|
+
}
|
|
4152
|
+
: null,
|
|
4153
|
+
},
|
|
4154
|
+
{
|
|
4155
|
+
defineWidget: (selected) => {
|
|
4156
|
+
return selected
|
|
4157
|
+
? {
|
|
4158
|
+
id: "Buttons",
|
|
4159
|
+
layout: { x: 8, y: 0, w: 1, h: 2 },
|
|
4160
|
+
title: "Buttons",
|
|
4161
|
+
type: "internal",
|
|
4162
|
+
widget: {
|
|
4163
|
+
name: "EodashMapBtns",
|
|
4164
|
+
properties: {
|
|
4165
|
+
compareIndicators: false,
|
|
4166
|
+
},
|
|
4167
|
+
},
|
|
4168
|
+
}
|
|
4169
|
+
: null;
|
|
4170
|
+
},
|
|
4171
|
+
},
|
|
4172
|
+
{
|
|
4173
|
+
defineWidget: (selectedSTAC) => {
|
|
4174
|
+
return selectedSTAC
|
|
4175
|
+
? {
|
|
4176
|
+
id: "Datepicker",
|
|
4177
|
+
type: "internal",
|
|
4178
|
+
layout: { x: 5, y: 8, w: 2, h: 4 },
|
|
4179
|
+
title: "Date",
|
|
4180
|
+
widget: {
|
|
4181
|
+
name: "EodashDatePicker",
|
|
4182
|
+
properties: {
|
|
4183
|
+
hintText: `<b>Hint:</b> closest available date is displayed <br />
|
|
4184
|
+
on map (see Analysis Layers)`,
|
|
4185
|
+
},
|
|
4186
|
+
},
|
|
4187
|
+
}
|
|
4188
|
+
: null;
|
|
4189
|
+
},
|
|
4190
|
+
},
|
|
4191
|
+
],
|
|
4192
|
+
},
|
|
4402
4193
|
},
|
|
4403
4194
|
});
|
|
4404
4195
|
|
|
@@ -5544,6 +5335,11 @@ const en = {
|
|
|
5544
5335
|
counter: '{0} files',
|
|
5545
5336
|
counterSize: '{0} files ({1} in total)'
|
|
5546
5337
|
},
|
|
5338
|
+
fileUpload: {
|
|
5339
|
+
title: 'Drag and drop files here',
|
|
5340
|
+
divider: 'or',
|
|
5341
|
+
browse: 'Browse Files'
|
|
5342
|
+
},
|
|
5547
5343
|
timePicker: {
|
|
5548
5344
|
am: 'AM',
|
|
5549
5345
|
pm: 'PM',
|
|
@@ -6885,7 +6681,8 @@ const aliases = {
|
|
|
6885
6681
|
calendar: 'mdi-calendar',
|
|
6886
6682
|
treeviewCollapse: 'mdi-menu-down',
|
|
6887
6683
|
treeviewExpand: 'mdi-menu-right',
|
|
6888
|
-
eyeDropper: 'mdi-eyedropper'
|
|
6684
|
+
eyeDropper: 'mdi-eyedropper',
|
|
6685
|
+
upload: 'mdi-cloud-upload'
|
|
6889
6686
|
};
|
|
6890
6687
|
const mdi = {
|
|
6891
6688
|
// Not using mergeProps here, functional components merge props by default (?)
|
|
@@ -7719,7 +7516,7 @@ function createVuetify() {
|
|
|
7719
7516
|
goTo
|
|
7720
7517
|
};
|
|
7721
7518
|
}
|
|
7722
|
-
const version = "3.7.
|
|
7519
|
+
const version = "3.7.6";
|
|
7723
7520
|
createVuetify.version = version;
|
|
7724
7521
|
function inject(key) {
|
|
7725
7522
|
const vm = this.$;
|
|
@@ -7729,8 +7526,38 @@ function inject(key) {
|
|
|
7729
7526
|
}
|
|
7730
7527
|
}
|
|
7731
7528
|
|
|
7529
|
+
/**
|
|
7530
|
+
* `eodash` injection key.
|
|
7531
|
+
*
|
|
7532
|
+
* @see {@link "@/plugins/index.js"}
|
|
7533
|
+
*/
|
|
7534
|
+
const eodashKey = Symbol("eodash");
|
|
7535
|
+
/** @type {import("@vueuse/core").EventBusKey<"layers:updated"|"time:updated">} */
|
|
7536
|
+
const eoxLayersKey = Symbol("eoxMapLayers");
|
|
7537
|
+
|
|
7538
|
+
/**
|
|
7539
|
+
* Array of eodash STAC Collections extracted from the current selected indicator.
|
|
7540
|
+
* Updated in {@link file://./../store/stac.js `loadSelectedSTAC`} widget
|
|
7541
|
+
*
|
|
7542
|
+
* @type {import('../eodashSTAC/EodashCollection').EodashCollection[]}
|
|
7543
|
+
* @private
|
|
7544
|
+
*/
|
|
7545
|
+
const eodashCollections = shallowReactive([]);
|
|
7546
|
+
|
|
7547
|
+
/**
|
|
7548
|
+
* Array of eodash STAC Collections extracted from the current selected COMPARE indicator.
|
|
7549
|
+
* Updated in {@link file://./../store/stac.js ` loadSelectedCompareSTAC`} widget
|
|
7550
|
+
*
|
|
7551
|
+
* @type {import('../eodashSTAC/EodashCollection').EodashCollection[]}
|
|
7552
|
+
* @private
|
|
7553
|
+
*/
|
|
7554
|
+
const eodashCompareCollections = shallowReactive([]);
|
|
7555
|
+
|
|
7556
|
+
/** whether the map postion was set in URL params on first load */
|
|
7557
|
+
const posIsSetFromUrl = ref(false);
|
|
7558
|
+
|
|
7732
7559
|
// functions of this folder can only be consumed inside setup stores,
|
|
7733
|
-
// setup functions or vue composition api components
|
|
7560
|
+
// setup functions or vue composition api components https://vuejs.org/guide/reusability/composables
|
|
7734
7561
|
|
|
7735
7562
|
|
|
7736
7563
|
/**
|
|
@@ -7740,11 +7567,11 @@ function inject(key) {
|
|
|
7740
7567
|
* @param {string} [base=eodash.stacEndpoint] - Base URL, default value is the
|
|
7741
7568
|
* root stac catalog. Default is `eodash.stacEndpoint`
|
|
7742
7569
|
* @returns {import("vue").Ref<string>} - Returns `currentUrl`
|
|
7743
|
-
* @see {@link '@/store/
|
|
7570
|
+
* @see {@link '@/store/states.js'}
|
|
7744
7571
|
*/
|
|
7745
7572
|
const useAbsoluteUrl = (rel = "", base = eodash.stacEndpoint) => {
|
|
7746
7573
|
if (!rel || rel.includes("http")) {
|
|
7747
|
-
currentUrl.value =
|
|
7574
|
+
currentUrl.value = rel;
|
|
7748
7575
|
return currentUrl;
|
|
7749
7576
|
}
|
|
7750
7577
|
|
|
@@ -7763,181 +7590,616 @@ const useAbsoluteUrl = (rel = "", base = eodash.stacEndpoint) => {
|
|
|
7763
7590
|
};
|
|
7764
7591
|
|
|
7765
7592
|
/**
|
|
7766
|
-
* Use the absolute compare URL from a relative link
|
|
7593
|
+
* Use the absolute compare URL from a relative link
|
|
7594
|
+
*
|
|
7595
|
+
* @param {string} [rel=''] Default is `''`
|
|
7596
|
+
* @param {string} [base=eodash.stacEndpoint] - Base URL, default value is the
|
|
7597
|
+
* root stac catalog. Default is `eodash.stacEndpoint`
|
|
7598
|
+
* @returns {import("vue").Ref<string>} - Returns `currentUrl`
|
|
7599
|
+
* @see {@link '@/store/states.js'}
|
|
7600
|
+
*/
|
|
7601
|
+
const useCompareAbsoluteUrl = (rel = "", base = eodash.stacEndpoint) => {
|
|
7602
|
+
if (!rel || rel.includes("http")) {
|
|
7603
|
+
currentCompareUrl.value = base;
|
|
7604
|
+
return currentCompareUrl;
|
|
7605
|
+
}
|
|
7606
|
+
|
|
7607
|
+
const st = base.split("/");
|
|
7608
|
+
const arr = rel.split("/");
|
|
7609
|
+
st.pop();
|
|
7610
|
+
|
|
7611
|
+
for (let i = 0; i < arr.length; i++) {
|
|
7612
|
+
if (arr[i] == ".") continue;
|
|
7613
|
+
if (arr[i] == "..") st.pop();
|
|
7614
|
+
else st.push(arr[i]);
|
|
7615
|
+
}
|
|
7616
|
+
|
|
7617
|
+
currentCompareUrl.value = st.join("/");
|
|
7618
|
+
return currentCompareUrl;
|
|
7619
|
+
};
|
|
7620
|
+
|
|
7621
|
+
/**
|
|
7622
|
+
* Updates an existing Vuetify theme. updates only the values provided in the
|
|
7623
|
+
* `ThemeDefinition`
|
|
7624
|
+
*
|
|
7625
|
+
* @param {string} themeName - Name of the theme to be updated
|
|
7626
|
+
* @param {import("vuetify").ThemeDefinition} [themeDefinition={}] - New
|
|
7627
|
+
* defintion to be updated to. Default is `{}`
|
|
7628
|
+
* @returns {import("vuetify").ThemeInstance}
|
|
7629
|
+
*/
|
|
7630
|
+
const useUpdateTheme = (themeName, themeDefinition = {}) => {
|
|
7631
|
+
const theme = useTheme();
|
|
7632
|
+
|
|
7633
|
+
/** @type {(keyof import("vuetify").ThemeDefinition)[]} */ (
|
|
7634
|
+
Object.keys(themeDefinition)
|
|
7635
|
+
).forEach((key) => {
|
|
7636
|
+
if (key === "dark") {
|
|
7637
|
+
theme.themes.value[themeName][key] = /** @type {Boolean} */ (
|
|
7638
|
+
themeDefinition[key]
|
|
7639
|
+
);
|
|
7640
|
+
} else {
|
|
7641
|
+
//@ts-expect-error to do
|
|
7642
|
+
theme.themes.value[themeName][key] = {
|
|
7643
|
+
...theme.themes.value[themeName][key],
|
|
7644
|
+
...themeDefinition[key],
|
|
7645
|
+
};
|
|
7646
|
+
}
|
|
7647
|
+
});
|
|
7648
|
+
return theme;
|
|
7649
|
+
};
|
|
7650
|
+
|
|
7651
|
+
/** Composable that syncs store and URLSearchParameters */
|
|
7652
|
+
const useURLSearchParametersSync = () => {
|
|
7653
|
+
onMounted(async () => {
|
|
7654
|
+
// Analyze currently set url params when first loaded and set them in the store
|
|
7655
|
+
if (window.location.search) {
|
|
7656
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
7657
|
+
|
|
7658
|
+
/** @type {number | undefined} */
|
|
7659
|
+
let x,
|
|
7660
|
+
/** @type {number | undefined} */
|
|
7661
|
+
y,
|
|
7662
|
+
/** @type {number | undefined} */
|
|
7663
|
+
z;
|
|
7664
|
+
for (const [key, value] of searchParams) {
|
|
7665
|
+
switch (key) {
|
|
7666
|
+
case "template": {
|
|
7667
|
+
activeTemplate.value = value;
|
|
7668
|
+
break;
|
|
7669
|
+
}
|
|
7670
|
+
case "indicator": {
|
|
7671
|
+
log.debug("Found indicator key in url");
|
|
7672
|
+
const { loadSelectedSTAC, stac } = useSTAcStore();
|
|
7673
|
+
const match = stac?.find((link) => link.id == value);
|
|
7674
|
+
if (match) {
|
|
7675
|
+
log.debug("Found match, loading stac item", match);
|
|
7676
|
+
await loadSelectedSTAC(match.href);
|
|
7677
|
+
}
|
|
7678
|
+
break;
|
|
7679
|
+
}
|
|
7680
|
+
|
|
7681
|
+
case "x":
|
|
7682
|
+
x = Number(value);
|
|
7683
|
+
break;
|
|
7684
|
+
|
|
7685
|
+
case "y":
|
|
7686
|
+
y = Number(value);
|
|
7687
|
+
break;
|
|
7688
|
+
|
|
7689
|
+
case "z":
|
|
7690
|
+
z = Number(value);
|
|
7691
|
+
break;
|
|
7692
|
+
|
|
7693
|
+
case "datetime":
|
|
7694
|
+
try {
|
|
7695
|
+
const datetimeiso = new Date(value).toISOString();
|
|
7696
|
+
log.debug("Valid datetime found", datetimeiso);
|
|
7697
|
+
datetime.value = datetimeiso;
|
|
7698
|
+
} catch {
|
|
7699
|
+
datetime.value = new Date().toISOString();
|
|
7700
|
+
}
|
|
7701
|
+
break;
|
|
7702
|
+
}
|
|
7703
|
+
}
|
|
7704
|
+
|
|
7705
|
+
if (x && y && z) {
|
|
7706
|
+
log.debug("Coordinates found, applying map poisition", x, y, z);
|
|
7707
|
+
mapPosition.value = [x, y, z];
|
|
7708
|
+
if (!posIsSetFromUrl.value) {
|
|
7709
|
+
posIsSetFromUrl.value = true;
|
|
7710
|
+
}
|
|
7711
|
+
}
|
|
7712
|
+
}
|
|
7713
|
+
|
|
7714
|
+
watch(
|
|
7715
|
+
[indicator, mapPosition, datetime, activeTemplate],
|
|
7716
|
+
([
|
|
7717
|
+
updatedIndicator,
|
|
7718
|
+
updatedMapPosition,
|
|
7719
|
+
updatedDatetime,
|
|
7720
|
+
updatedTemplate,
|
|
7721
|
+
]) => {
|
|
7722
|
+
if ("URLSearchParams" in window) {
|
|
7723
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
7724
|
+
if (updatedIndicator !== "") {
|
|
7725
|
+
searchParams.set("indicator", updatedIndicator);
|
|
7726
|
+
}
|
|
7727
|
+
|
|
7728
|
+
if (updatedMapPosition && updatedMapPosition.length === 3) {
|
|
7729
|
+
searchParams.set("x", updatedMapPosition[0]?.toFixed(4) ?? "");
|
|
7730
|
+
searchParams.set("y", updatedMapPosition[1]?.toFixed(4) ?? "");
|
|
7731
|
+
searchParams.set("z", updatedMapPosition[2]?.toFixed(4) ?? "");
|
|
7732
|
+
}
|
|
7733
|
+
|
|
7734
|
+
if (updatedDatetime) {
|
|
7735
|
+
searchParams.set("datetime", updatedDatetime.split("T")?.[0] ?? "");
|
|
7736
|
+
}
|
|
7737
|
+
if (updatedTemplate) {
|
|
7738
|
+
searchParams.set("template", updatedTemplate);
|
|
7739
|
+
}
|
|
7740
|
+
const newRelativePathQuery =
|
|
7741
|
+
window.location.pathname + "?" + searchParams.toString();
|
|
7742
|
+
history.pushState(null, "", newRelativePathQuery);
|
|
7743
|
+
}
|
|
7744
|
+
},
|
|
7745
|
+
);
|
|
7746
|
+
});
|
|
7747
|
+
};
|
|
7748
|
+
|
|
7749
|
+
/**
|
|
7750
|
+
* Converts eox-layout-item to transparent
|
|
7751
|
+
*
|
|
7752
|
+
* @param {import("vue").Ref<HTMLElement|null>} root - components root element ref*/
|
|
7753
|
+
const makePanelTransparent = (root) => {
|
|
7754
|
+
onMounted(() => {
|
|
7755
|
+
const eoxItem = root.value?.parentElement;
|
|
7756
|
+
if (eoxItem?.tagName === "EOX-LAYOUT-ITEM") {
|
|
7757
|
+
eoxItem.classList.remove("bg-surface");
|
|
7758
|
+
}
|
|
7759
|
+
});
|
|
7760
|
+
};
|
|
7761
|
+
|
|
7762
|
+
/**
|
|
7763
|
+
* Listens to the `layers:updated` and `time:updated` events and calls
|
|
7764
|
+
*
|
|
7765
|
+
* @param {import("@vueuse/core").EventBusListener<
|
|
7766
|
+
* "layers:updated"|"time:updated",
|
|
7767
|
+
* {layers:Record<string,any>[]| undefined}
|
|
7768
|
+
* >} listener
|
|
7769
|
+
*/
|
|
7770
|
+
const useOnLayersUpdate = (listener) => {
|
|
7771
|
+
const layersEvents = useEventBus(eoxLayersKey);
|
|
7772
|
+
|
|
7773
|
+
const unsubscribe = layersEvents.on(listener);
|
|
7774
|
+
|
|
7775
|
+
onUnmounted(() => {
|
|
7776
|
+
unsubscribe();
|
|
7777
|
+
});
|
|
7778
|
+
};
|
|
7779
|
+
|
|
7780
|
+
/** @param {import("stac-ts").StacLink[]} [links] */
|
|
7781
|
+
function generateFeatures(links) {
|
|
7782
|
+
/**
|
|
7783
|
+
* @type {import("geojson").Feature[]}
|
|
7784
|
+
*/
|
|
7785
|
+
const features = [];
|
|
7786
|
+
links?.forEach((element) => {
|
|
7787
|
+
if (element.rel === "item" && "latlng" in element) {
|
|
7788
|
+
const [lat, lon] = /** @type {string} */ (element.latlng)
|
|
7789
|
+
.split(",")
|
|
7790
|
+
.map((it) => Number(it));
|
|
7791
|
+
features.push({
|
|
7792
|
+
type: "Feature",
|
|
7793
|
+
geometry: {
|
|
7794
|
+
type: "Point",
|
|
7795
|
+
coordinates: [lon, lat],
|
|
7796
|
+
},
|
|
7797
|
+
properties: { id: element.id },
|
|
7798
|
+
});
|
|
7799
|
+
}
|
|
7800
|
+
});
|
|
7801
|
+
const geojsonObject = {
|
|
7802
|
+
type: "FeatureCollection",
|
|
7803
|
+
crs: {
|
|
7804
|
+
type: "name",
|
|
7805
|
+
properties: {
|
|
7806
|
+
name: "EPSG:4326",
|
|
7807
|
+
},
|
|
7808
|
+
},
|
|
7809
|
+
features,
|
|
7810
|
+
};
|
|
7811
|
+
return geojsonObject;
|
|
7812
|
+
}
|
|
7813
|
+
|
|
7814
|
+
/**
|
|
7815
|
+
* Sperates and extracts layerConfig (jsonform schema & legend) from a style json
|
|
7816
|
+
*
|
|
7817
|
+
* @param { import("ol/layer/WebGLTile").Style & { jsonform?: Record<string,any> } & { legend?: Record<string,any> } } [style] */
|
|
7818
|
+
function extractLayerConfig(style) {
|
|
7819
|
+
/** @type {Record<string,unknown> | undefined} */
|
|
7820
|
+
let layerConfig = undefined;
|
|
7821
|
+
if (style?.jsonform) {
|
|
7822
|
+
layerConfig = { schema: style.jsonform, type: "style" };
|
|
7823
|
+
style = { ...style };
|
|
7824
|
+
delete style.jsonform;
|
|
7825
|
+
if (style?.legend) {
|
|
7826
|
+
layerConfig.legend = style.legend;
|
|
7827
|
+
delete style.legend;
|
|
7828
|
+
}
|
|
7829
|
+
}
|
|
7830
|
+
log.debug(
|
|
7831
|
+
"extracted layerConfig",
|
|
7832
|
+
JSON.parse(JSON.stringify({ layerConfig, style })),
|
|
7833
|
+
);
|
|
7834
|
+
|
|
7835
|
+
return { layerConfig, style };
|
|
7836
|
+
}
|
|
7837
|
+
|
|
7838
|
+
/**
|
|
7839
|
+
* Function to extract collection urls from an indicator
|
|
7840
|
+
* @param {import("stac-ts").StacCatalog
|
|
7841
|
+
* | import("stac-ts").StacCollection
|
|
7842
|
+
* | import("stac-ts").StacItem
|
|
7843
|
+
* | null
|
|
7844
|
+
* } stacObject
|
|
7845
|
+
* @param {string} basepath
|
|
7846
|
+
*/
|
|
7847
|
+
function extractCollectionUrls(stacObject, basepath) {
|
|
7848
|
+
/** @type {string[]} */
|
|
7849
|
+
const collectionUrls = [];
|
|
7850
|
+
// Support for two structure types, flat and indicator, simplified here:
|
|
7851
|
+
// Flat assumes Catalog-Collection-Item
|
|
7852
|
+
// Indicator assumes Catalog-Collection-Collection-Item
|
|
7853
|
+
|
|
7854
|
+
const children = stacObject?.links?.filter(
|
|
7855
|
+
(link) => link.rel === "child" && link.type?.includes("json"),
|
|
7856
|
+
);
|
|
7857
|
+
if (!children?.length) {
|
|
7858
|
+
collectionUrls.push(basepath);
|
|
7859
|
+
return collectionUrls;
|
|
7860
|
+
}
|
|
7861
|
+
children.forEach((link) => {
|
|
7862
|
+
collectionUrls.push(toAbsolute(link.href, basepath));
|
|
7863
|
+
});
|
|
7864
|
+
return collectionUrls;
|
|
7865
|
+
}
|
|
7866
|
+
|
|
7867
|
+
/**
|
|
7868
|
+
* Assign extracted roles to layer properties
|
|
7869
|
+
* @param {Record<string,any>} properties
|
|
7870
|
+
* @param {import("stac-ts").StacLink | import("stac-ts").StacAsset} linkOrAsset
|
|
7871
|
+
* */
|
|
7872
|
+
const extractRoles = (properties, linkOrAsset) => {
|
|
7873
|
+
const roles = /** @type {string[]} */ (linkOrAsset.roles);
|
|
7874
|
+
roles?.forEach((role) => {
|
|
7875
|
+
if (role === "visible") {
|
|
7876
|
+
properties.visible = true;
|
|
7877
|
+
}
|
|
7878
|
+
if (role === "overlay" || role === "baselayer") {
|
|
7879
|
+
properties.group = role;
|
|
7880
|
+
}
|
|
7881
|
+
|
|
7882
|
+
return properties;
|
|
7883
|
+
});
|
|
7884
|
+
};
|
|
7885
|
+
|
|
7886
|
+
/**
|
|
7887
|
+
* Extracts style JSON from a STAC Item
|
|
7888
|
+
* @param {import("stac-ts").StacItem} item
|
|
7889
|
+
* @param {string} itemUrl
|
|
7890
|
+
* @returns
|
|
7891
|
+
**/
|
|
7892
|
+
const fetchStyle = async (item, itemUrl) => {
|
|
7893
|
+
const styleLink = item.links.find((link) => link.rel.includes("style"));
|
|
7894
|
+
if (styleLink) {
|
|
7895
|
+
let url = "";
|
|
7896
|
+
if (styleLink.href.startsWith("http")) {
|
|
7897
|
+
url = styleLink.href;
|
|
7898
|
+
} else {
|
|
7899
|
+
url = toAbsolute(styleLink.href, itemUrl);
|
|
7900
|
+
}
|
|
7901
|
+
|
|
7902
|
+
/** @type {import("ol/layer/WebGLTile").Style & {jsonform?:Record<string,any>}} */
|
|
7903
|
+
const styleJson = await axios.get(url).then((resp) => resp.data);
|
|
7904
|
+
|
|
7905
|
+
log.debug("fetched styles JSON", JSON.parse(JSON.stringify(styleJson)));
|
|
7906
|
+
return { ...styleJson };
|
|
7907
|
+
}
|
|
7908
|
+
};
|
|
7909
|
+
|
|
7910
|
+
/**
|
|
7911
|
+
* Return projection code which is to be registered in `eox-map`
|
|
7912
|
+
* @param {string|number|{name: string, def: string}} [projection]
|
|
7913
|
+
* @returns {string}
|
|
7914
|
+
*/
|
|
7915
|
+
const getProjectionCode = (projection) => {
|
|
7916
|
+
let code = projection;
|
|
7917
|
+
switch (typeof projection) {
|
|
7918
|
+
case "number":
|
|
7919
|
+
code = `EPSG:${projection}`;
|
|
7920
|
+
break;
|
|
7921
|
+
case "string":
|
|
7922
|
+
code = projection;
|
|
7923
|
+
break;
|
|
7924
|
+
case "object":
|
|
7925
|
+
code = projection?.name;
|
|
7926
|
+
}
|
|
7927
|
+
return /** @type {string} */ (code);
|
|
7928
|
+
};
|
|
7929
|
+
|
|
7930
|
+
/**
|
|
7931
|
+
* Extracts layercontrol LayerDatetime property from STAC Links
|
|
7932
|
+
* @param {import("stac-ts").StacLink[]} [links]
|
|
7933
|
+
* @param {string|null} [currentStep]
|
|
7934
|
+
**/
|
|
7935
|
+
const extractLayerDatetime = (links, currentStep) => {
|
|
7936
|
+
if (!currentStep || !links?.length) {
|
|
7937
|
+
return undefined;
|
|
7938
|
+
}
|
|
7939
|
+
|
|
7940
|
+
// check if links has a datetime value
|
|
7941
|
+
// TODO: consider datetime ranges
|
|
7942
|
+
const hasDatetime = links.some((l) => typeof l.datetime === "string");
|
|
7943
|
+
if (!hasDatetime) {
|
|
7944
|
+
return undefined;
|
|
7945
|
+
}
|
|
7946
|
+
|
|
7947
|
+
/** @type {string[]} */
|
|
7948
|
+
const controlValues = [];
|
|
7949
|
+
try {
|
|
7950
|
+
currentStep = new Date(currentStep).toISOString();
|
|
7951
|
+
|
|
7952
|
+
links.reduce((vals, link) => {
|
|
7953
|
+
if (link.datetime && link.rel === "item") {
|
|
7954
|
+
vals.push(
|
|
7955
|
+
new Date(/** @type {string} */ (link.datetime)).toISOString(),
|
|
7956
|
+
);
|
|
7957
|
+
}
|
|
7958
|
+
return vals;
|
|
7959
|
+
}, controlValues);
|
|
7960
|
+
} catch (e) {
|
|
7961
|
+
console.warn("[eodash] not supported datetime format was provided", e);
|
|
7962
|
+
return undefined;
|
|
7963
|
+
}
|
|
7964
|
+
// not enough controlValues
|
|
7965
|
+
if (controlValues.length <= 1) {
|
|
7966
|
+
return undefined;
|
|
7967
|
+
}
|
|
7968
|
+
|
|
7969
|
+
// item datetime is not included in the item links datetime
|
|
7970
|
+
if (!controlValues.includes(currentStep)) {
|
|
7971
|
+
return undefined;
|
|
7972
|
+
}
|
|
7973
|
+
|
|
7974
|
+
return {
|
|
7975
|
+
controlValues,
|
|
7976
|
+
currentStep,
|
|
7977
|
+
slider: true,
|
|
7978
|
+
play: false,
|
|
7979
|
+
displayFormat: "DD MMMM YYYY",
|
|
7980
|
+
};
|
|
7981
|
+
};
|
|
7982
|
+
|
|
7983
|
+
/**
|
|
7984
|
+
* Find JSON layer by ID
|
|
7985
|
+
* @param {string} layer
|
|
7986
|
+
* @param {Record<string, any>[]} layers
|
|
7987
|
+
* @returns {Record<string,any> | undefined}
|
|
7988
|
+
**/
|
|
7989
|
+
const findLayer = (layers, layer) => {
|
|
7990
|
+
for (const lyr of layers) {
|
|
7991
|
+
if (lyr.type === "Group") {
|
|
7992
|
+
const found = findLayer(lyr.layers, layer);
|
|
7993
|
+
if (!found) {
|
|
7994
|
+
continue;
|
|
7995
|
+
}
|
|
7996
|
+
return found;
|
|
7997
|
+
}
|
|
7998
|
+
if (lyr.properties.id === layer) {
|
|
7999
|
+
return lyr;
|
|
8000
|
+
}
|
|
8001
|
+
}
|
|
8002
|
+
};
|
|
8003
|
+
|
|
8004
|
+
/**
|
|
8005
|
+
* Removes the layer with the id provided and injects an array of layers in its position
|
|
8006
|
+
* @param {Record<string,any>[]} currentLayers
|
|
8007
|
+
* @param {string} oldLayer - id of the layer to be replaced
|
|
8008
|
+
* @param {Record<string,any>[]} newLayers - array of layers to replace the old layer
|
|
8009
|
+
* @returns {Record<string,any>[] | undefined}
|
|
8010
|
+
*/
|
|
8011
|
+
const replaceLayer = (currentLayers, oldLayer, newLayers) => {
|
|
8012
|
+
const oldLayerIdx = currentLayers.findIndex(
|
|
8013
|
+
(l) => l.properties.id === oldLayer,
|
|
8014
|
+
);
|
|
8015
|
+
|
|
8016
|
+
if (oldLayerIdx !== -1) {
|
|
8017
|
+
log.debug(
|
|
8018
|
+
"Replacing layer",
|
|
8019
|
+
oldLayer,
|
|
8020
|
+
"with",
|
|
8021
|
+
newLayers.map((l) => l.properties.id),
|
|
8022
|
+
);
|
|
8023
|
+
currentLayers.splice(oldLayerIdx, 1, ...newLayers);
|
|
8024
|
+
return currentLayers;
|
|
8025
|
+
}
|
|
8026
|
+
|
|
8027
|
+
for (const l of currentLayers) {
|
|
8028
|
+
if (l.type === "Group") {
|
|
8029
|
+
const updatedGroupLyrs = replaceLayer(l.layers, oldLayer, newLayers);
|
|
8030
|
+
if (updatedGroupLyrs?.length) {
|
|
8031
|
+
l.layers = updatedGroupLyrs;
|
|
8032
|
+
return currentLayers;
|
|
8033
|
+
}
|
|
8034
|
+
}
|
|
8035
|
+
}
|
|
8036
|
+
};
|
|
8037
|
+
|
|
8038
|
+
/**
|
|
8039
|
+
* Extracts the STAC collection which the layer was created from.
|
|
8040
|
+
*
|
|
8041
|
+
* @param {import('../eodashSTAC/EodashCollection.js').EodashCollection[]} indicators
|
|
8042
|
+
* @param {import('ol/layer').Layer} layer
|
|
8043
|
+
*/
|
|
8044
|
+
const getColFromLayer = async (indicators, layer) => {
|
|
8045
|
+
// init cols
|
|
8046
|
+
const collections = await Promise.all(
|
|
8047
|
+
indicators.map((ind) => ind.fetchCollection()),
|
|
8048
|
+
);
|
|
8049
|
+
const [collectionId, itemId, ..._other] = layer.get("id").split(";:;");
|
|
8050
|
+
|
|
8051
|
+
const chosen = collections.find((col) => {
|
|
8052
|
+
const isInd =
|
|
8053
|
+
col.id === collectionId &&
|
|
8054
|
+
col.links?.some(
|
|
8055
|
+
(link) => link.rel === "item" && link.href.includes(itemId),
|
|
8056
|
+
);
|
|
8057
|
+
return isInd;
|
|
8058
|
+
});
|
|
8059
|
+
return indicators.find((ind) => ind.collectionStac?.id === chosen?.id);
|
|
8060
|
+
};
|
|
8061
|
+
|
|
8062
|
+
/**
|
|
8063
|
+
* Generates layer specific ID from STAC Links
|
|
8064
|
+
* related functions are: {@link assignProjID} & {@link createAssetID}
|
|
8065
|
+
*
|
|
8066
|
+
* @param {string} collectionId
|
|
8067
|
+
* @param {string} itemId
|
|
8068
|
+
* @param {import('stac-ts').StacLink} link
|
|
8069
|
+
* @param {string} projectionCode
|
|
8070
|
+
*
|
|
8071
|
+
*/
|
|
8072
|
+
const createLayerID = (collectionId, itemId, link, projectionCode) => {
|
|
8073
|
+
const linkId = link.id || link.title || link.href;
|
|
8074
|
+
let lId = `${collectionId ?? ""};:;${itemId ?? ""};:;${linkId ?? ""};:;${projectionCode ?? ""}`;
|
|
8075
|
+
// If we are looking at base layers and overlays we remove the collection and item part
|
|
8076
|
+
// as we want to make sure tiles are not reloaded when switching layers
|
|
8077
|
+
if (
|
|
8078
|
+
/** @type {string[]} */
|
|
8079
|
+
(link.roles)?.find((r) => ["baselayer", "overlay"].includes(r))
|
|
8080
|
+
) {
|
|
8081
|
+
lId = `${linkId ?? ""};:;${projectionCode ?? ""}`;
|
|
8082
|
+
}
|
|
8083
|
+
log.debug("Generated Layer ID", lId);
|
|
8084
|
+
return lId;
|
|
8085
|
+
};
|
|
8086
|
+
|
|
8087
|
+
/**
|
|
8088
|
+
* Generates layer specific ID from STAC assets, related functions are: {@link assignProjID} & {@link createLayerID}
|
|
8089
|
+
*
|
|
8090
|
+
* @param {string} collectionId
|
|
8091
|
+
* @param {string} itemId
|
|
8092
|
+
* @param {number} index
|
|
7767
8093
|
*
|
|
7768
|
-
* @param {string} [rel=''] Default is `''`
|
|
7769
|
-
* @param {string} [base=eodash.stacEndpoint] - Base URL, default value is the
|
|
7770
|
-
* root stac catalog. Default is `eodash.stacEndpoint`
|
|
7771
|
-
* @returns {import("vue").Ref<string>} - Returns `currentUrl`
|
|
7772
|
-
* @see {@link '@/store/States.js'}
|
|
7773
8094
|
*/
|
|
7774
|
-
const
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
}
|
|
7779
|
-
|
|
7780
|
-
const st = base.split("/");
|
|
7781
|
-
const arr = rel.split("/");
|
|
7782
|
-
st.pop();
|
|
7783
|
-
|
|
7784
|
-
for (let i = 0; i < arr.length; i++) {
|
|
7785
|
-
if (arr[i] == ".") continue;
|
|
7786
|
-
if (arr[i] == "..") st.pop();
|
|
7787
|
-
else st.push(arr[i]);
|
|
7788
|
-
}
|
|
7789
|
-
|
|
7790
|
-
currentCompareUrl.value = st.join("/");
|
|
7791
|
-
return currentCompareUrl;
|
|
8095
|
+
const createAssetID = (collectionId, itemId, index) => {
|
|
8096
|
+
let lId = `${collectionId ?? ""};:;${itemId ?? ""};:;${index ?? ""}`;
|
|
8097
|
+
log.debug("Generated Asset ID", lId);
|
|
8098
|
+
return lId;
|
|
7792
8099
|
};
|
|
7793
8100
|
|
|
7794
8101
|
/**
|
|
7795
|
-
*
|
|
7796
|
-
*
|
|
8102
|
+
* creates a structured clone from the layers and
|
|
8103
|
+
* removes all properties from the clone
|
|
8104
|
+
* except the ID and title
|
|
7797
8105
|
*
|
|
7798
|
-
* @param {string}
|
|
7799
|
-
* @param {import("vuetify").ThemeDefinition} [themeDefinition={}] - New
|
|
7800
|
-
* defintion to be updated to. Default is `{}`
|
|
7801
|
-
* @returns {import("vuetify").ThemeInstance}
|
|
8106
|
+
* @param {Record<string,any>[]} layers
|
|
7802
8107
|
*/
|
|
7803
|
-
const
|
|
7804
|
-
const
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
|
|
7808
|
-
|
|
7809
|
-
if (
|
|
7810
|
-
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
//@ts-expect-error to do
|
|
7815
|
-
theme.themes.value[themeName][key] = {
|
|
7816
|
-
...theme.themes.value[themeName][key],
|
|
7817
|
-
...themeDefinition[key],
|
|
7818
|
-
};
|
|
8108
|
+
const removeUnneededProperties = (layers) => {
|
|
8109
|
+
const cloned = structuredClone(layers);
|
|
8110
|
+
cloned.forEach((layer) => {
|
|
8111
|
+
const id = layer.properties.id;
|
|
8112
|
+
const title = layer.properties.title;
|
|
8113
|
+
layer.properties = { id, title };
|
|
8114
|
+
if (layer["interactions"]) {
|
|
8115
|
+
delete layer["interactions"];
|
|
8116
|
+
}
|
|
8117
|
+
if (layer.type === "Group") {
|
|
8118
|
+
layer.layers = removeUnneededProperties(layer.layers);
|
|
7819
8119
|
}
|
|
7820
8120
|
});
|
|
7821
|
-
return
|
|
8121
|
+
return cloned;
|
|
7822
8122
|
};
|
|
7823
8123
|
|
|
7824
|
-
/**
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
const searchParams = new URLSearchParams(window.location.search);
|
|
7830
|
-
|
|
7831
|
-
/** @type {number | undefined} */
|
|
7832
|
-
let x,
|
|
7833
|
-
/** @type {number | undefined} */
|
|
7834
|
-
y,
|
|
7835
|
-
/** @type {number | undefined} */
|
|
7836
|
-
z;
|
|
7837
|
-
for (const [key, value] of searchParams) {
|
|
7838
|
-
switch (key) {
|
|
7839
|
-
case "indicator": {
|
|
7840
|
-
log.debug("Found indicator key in url");
|
|
7841
|
-
const { loadSelectedSTAC, stac } = useSTAcStore();
|
|
7842
|
-
const match = stac?.find((link) => link.id == value);
|
|
7843
|
-
if (match) {
|
|
7844
|
-
log.debug("Found match, loading stac item", match);
|
|
7845
|
-
await loadSelectedSTAC(match.href);
|
|
7846
|
-
}
|
|
7847
|
-
break;
|
|
7848
|
-
}
|
|
7849
|
-
|
|
7850
|
-
case "x":
|
|
7851
|
-
x = Number(value);
|
|
7852
|
-
break;
|
|
7853
|
-
|
|
7854
|
-
case "y":
|
|
7855
|
-
y = Number(value);
|
|
7856
|
-
break;
|
|
7857
|
-
|
|
7858
|
-
case "z":
|
|
7859
|
-
z = Number(value);
|
|
7860
|
-
break;
|
|
7861
|
-
|
|
7862
|
-
case "datetime":
|
|
7863
|
-
try {
|
|
7864
|
-
const datetimeiso = new Date(value).toISOString();
|
|
7865
|
-
log.debug("Valid datetime found", datetimeiso);
|
|
7866
|
-
datetime.value = datetimeiso;
|
|
7867
|
-
} catch {
|
|
7868
|
-
datetime.value = new Date().toISOString();
|
|
7869
|
-
}
|
|
7870
|
-
break;
|
|
7871
|
-
}
|
|
7872
|
-
}
|
|
7873
|
-
|
|
7874
|
-
if (x && y && z) {
|
|
7875
|
-
log.debug("Coordinates found, applying map poisition", x, y, z);
|
|
7876
|
-
mapPosition.value = [x, y, z];
|
|
7877
|
-
}
|
|
7878
|
-
}
|
|
7879
|
-
|
|
7880
|
-
watch(
|
|
7881
|
-
[indicator, mapPosition, datetime],
|
|
7882
|
-
([updatedIndicator, updatedMapPosition, updatedDatetime]) => {
|
|
7883
|
-
if ("URLSearchParams" in window) {
|
|
7884
|
-
const searchParams = new URLSearchParams(window.location.search);
|
|
7885
|
-
if (updatedIndicator !== "") {
|
|
7886
|
-
searchParams.set("indicator", updatedIndicator);
|
|
7887
|
-
}
|
|
8124
|
+
/**
|
|
8125
|
+
* Returns the current layers of {@link mapEl}
|
|
8126
|
+
* @returns {Record<string,any>[]}
|
|
8127
|
+
*/
|
|
8128
|
+
const getLayers = () => mapEl.value?.layers.toReversed();
|
|
7888
8129
|
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
8130
|
+
/**
|
|
8131
|
+
* Returns the current layers of {@link mapCompareEl}
|
|
8132
|
+
* @returns {Record<string,any>[]}
|
|
8133
|
+
*/
|
|
8134
|
+
const getCompareLayers = () => mapCompareEl.value?.layers.toReversed();
|
|
7894
8135
|
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
8136
|
+
/**
|
|
8137
|
+
* Register EPSG projection in `eox-map`
|
|
8138
|
+
* @param {string|number|{name: string, def: string, extent?:number[]}} [projection]*/
|
|
8139
|
+
const registerProjection = async (projection) => {
|
|
8140
|
+
let code = getProjectionCode(projection);
|
|
8141
|
+
if (!code || registeredProjections.includes(code)) {
|
|
8142
|
+
return;
|
|
8143
|
+
}
|
|
8144
|
+
log.debug("Unregistered projection found, registering it", code);
|
|
8145
|
+
registeredProjections.push(code);
|
|
8146
|
+
if (typeof projection === "object") {
|
|
8147
|
+
// registering whole projection definition
|
|
8148
|
+
await mapEl.value?.registerProjection(
|
|
8149
|
+
code,
|
|
8150
|
+
projection.def,
|
|
8151
|
+
projection.extent,
|
|
7903
8152
|
);
|
|
7904
|
-
|
|
8153
|
+
// also registering for comparison map
|
|
8154
|
+
await mapCompareEl.value?.registerProjection(
|
|
8155
|
+
code,
|
|
8156
|
+
projection.def,
|
|
8157
|
+
projection.extent,
|
|
8158
|
+
);
|
|
8159
|
+
} else {
|
|
8160
|
+
await mapEl.value?.registerProjectionFromCode(code);
|
|
8161
|
+
// also registering for comparison map
|
|
8162
|
+
await mapCompareEl.value?.registerProjectionFromCode(code);
|
|
8163
|
+
}
|
|
7905
8164
|
};
|
|
8165
|
+
/**
|
|
8166
|
+
* Change `eox-map` projection from an `EPSG` projection
|
|
8167
|
+
* @param {string|number|{name: string, def: string}} [projection]*/
|
|
8168
|
+
const changeMapProjection = async (projection) => {
|
|
8169
|
+
let code = getProjectionCode(projection);
|
|
7906
8170
|
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
8171
|
+
if (!code) {
|
|
8172
|
+
mapEl.value?.setAttribute("projection", "EPSG:3857");
|
|
8173
|
+
mapCompareEl.value?.setAttribute("projection", "EPSG:3857");
|
|
8174
|
+
return;
|
|
8175
|
+
}
|
|
8176
|
+
|
|
8177
|
+
if (!registeredProjections.includes(code)) {
|
|
8178
|
+
await registerProjection(projection);
|
|
8179
|
+
}
|
|
8180
|
+
|
|
8181
|
+
code = mapEl.value?.getAttribute("projection") === code ? "EPSG:3857" : code;
|
|
8182
|
+
mapEl.value?.setAttribute("projection", code);
|
|
8183
|
+
mapCompareEl.value?.setAttribute("projection", code);
|
|
7917
8184
|
};
|
|
7918
8185
|
|
|
7919
8186
|
/**
|
|
7920
|
-
* `eodash` injection key.
|
|
7921
8187
|
*
|
|
7922
|
-
* @
|
|
7923
|
-
*/
|
|
7924
|
-
const eodashKey = Symbol("eodash");
|
|
7925
|
-
|
|
7926
|
-
/**
|
|
7927
|
-
* Array of eodash STAC Collections extracted from the current selected indicator.
|
|
7928
|
-
* Updated in {@link file://./../store/stac.js `loadSelectedSTAC`} widget
|
|
7929
|
-
* @type {import('./eodashSTAC').EodashCollection[]}
|
|
7930
|
-
* @private
|
|
8188
|
+
* @param {string} template
|
|
7931
8189
|
*/
|
|
7932
|
-
const
|
|
8190
|
+
const setActiveTemplate = (template) => {
|
|
8191
|
+
activeTemplate.value = template;
|
|
8192
|
+
log.debug("Setting active template to", template);
|
|
8193
|
+
};
|
|
7933
8194
|
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
8195
|
+
const actions = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
8196
|
+
__proto__: null,
|
|
8197
|
+
changeMapProjection,
|
|
8198
|
+
getCompareLayers,
|
|
8199
|
+
getLayers,
|
|
8200
|
+
registerProjection,
|
|
8201
|
+
setActiveTemplate
|
|
8202
|
+
}, Symbol.toStringTag, { value: 'Module' }));
|
|
7941
8203
|
|
|
7942
8204
|
/**
|
|
7943
8205
|
* @param {string} collectionId
|
|
@@ -7996,10 +8258,11 @@ async function createLayersFromAssets(
|
|
|
7996
8258
|
},
|
|
7997
8259
|
...(!style?.variables && { style }),
|
|
7998
8260
|
};
|
|
8261
|
+
|
|
7999
8262
|
extractRoles(layer.properties, assets[ast]);
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8263
|
+
|
|
8264
|
+
layer.properties = { ...layer.properties, ...(extraProperties ?? {}) };
|
|
8265
|
+
|
|
8003
8266
|
jsonArray.push(layer);
|
|
8004
8267
|
} else if (assets[ast]?.type === "image/tiff") {
|
|
8005
8268
|
geoTIFFIdx = idx;
|
|
@@ -8027,7 +8290,7 @@ async function createLayersFromAssets(
|
|
|
8027
8290
|
},
|
|
8028
8291
|
style,
|
|
8029
8292
|
};
|
|
8030
|
-
if (extraProperties
|
|
8293
|
+
if (extraProperties) {
|
|
8031
8294
|
layer.properties = { ...layer.properties, ...extraProperties };
|
|
8032
8295
|
}
|
|
8033
8296
|
jsonArray.push(layer);
|
|
@@ -8081,10 +8344,11 @@ const createLayersFromLinks = async (
|
|
|
8081
8344
|
viewProjectionCode,
|
|
8082
8345
|
);
|
|
8083
8346
|
log.debug("WMS Layer added", linkId);
|
|
8084
|
-
const tileSize =
|
|
8347
|
+
const tileSize = /** @type {number[]} */ (
|
|
8085
8348
|
"wms:tilesize" in wmsLink
|
|
8086
8349
|
? [wmsLink["wms:tilesize"], wmsLink["wms:tilesize"]]
|
|
8087
|
-
: [512, 512]
|
|
8350
|
+
: [512, 512]
|
|
8351
|
+
);
|
|
8088
8352
|
let json = {
|
|
8089
8353
|
type: "Tile",
|
|
8090
8354
|
properties: {
|
|
@@ -8249,11 +8513,6 @@ class EodashCollection {
|
|
|
8249
8513
|
/** @type {import("stac-ts").StacCollection | undefined} */
|
|
8250
8514
|
#collectionStac;
|
|
8251
8515
|
|
|
8252
|
-
// read only
|
|
8253
|
-
get collectionStac() {
|
|
8254
|
-
return this.#collectionStac;
|
|
8255
|
-
}
|
|
8256
|
-
|
|
8257
8516
|
/**
|
|
8258
8517
|
* @type {import("stac-ts").StacLink
|
|
8259
8518
|
* | import("stac-ts").StacItem
|
|
@@ -8261,6 +8520,11 @@ class EodashCollection {
|
|
|
8261
8520
|
*/
|
|
8262
8521
|
selectedItem;
|
|
8263
8522
|
|
|
8523
|
+
// read only
|
|
8524
|
+
get collectionStac() {
|
|
8525
|
+
return this.#collectionStac;
|
|
8526
|
+
}
|
|
8527
|
+
|
|
8264
8528
|
/** @param {string} collectionUrl */
|
|
8265
8529
|
constructor(collectionUrl) {
|
|
8266
8530
|
this.#collectionUrl = collectionUrl;
|
|
@@ -8309,9 +8573,7 @@ class EodashCollection {
|
|
|
8309
8573
|
this.selectedItem = this.getItem();
|
|
8310
8574
|
|
|
8311
8575
|
if (this.selectedItem) {
|
|
8312
|
-
layersJson =
|
|
8313
|
-
await this.createLayersJson(this.selectedItem)
|
|
8314
|
-
);
|
|
8576
|
+
layersJson = await this.createLayersJson(this.selectedItem);
|
|
8315
8577
|
} else {
|
|
8316
8578
|
console.warn(
|
|
8317
8579
|
"[eodash] the selected collection does not include any items",
|
|
@@ -8337,7 +8599,7 @@ class EodashCollection {
|
|
|
8337
8599
|
* @param {string} title
|
|
8338
8600
|
* @param {boolean} isGeoDB
|
|
8339
8601
|
* @param {string} [itemDatetime]
|
|
8340
|
-
* @returns {Promise<Record<string,any>[]>}
|
|
8602
|
+
* @returns {Promise<Record<string,any>[]>} layers
|
|
8341
8603
|
* */
|
|
8342
8604
|
async buildJsonArray(item, itemUrl, title, isGeoDB, itemDatetime) {
|
|
8343
8605
|
log.debug(
|
|
@@ -8360,30 +8622,9 @@ class EodashCollection {
|
|
|
8360
8622
|
|
|
8361
8623
|
const jsonArray = [];
|
|
8362
8624
|
|
|
8363
|
-
if (isGeoDB) {
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
return [
|
|
8367
|
-
{
|
|
8368
|
-
type: "Vector",
|
|
8369
|
-
properties: {
|
|
8370
|
-
id: this.#collectionStac?.id ?? "",
|
|
8371
|
-
title: this.#collectionStac?.title || item.id,
|
|
8372
|
-
},
|
|
8373
|
-
source: {
|
|
8374
|
-
type: "Vector",
|
|
8375
|
-
url: "data:," + encodeURIComponent(JSON.stringify(allFeatures)),
|
|
8376
|
-
format: "GeoJSON",
|
|
8377
|
-
},
|
|
8378
|
-
style: {
|
|
8379
|
-
"circle-radius": 5,
|
|
8380
|
-
"circle-fill-color": "#00417077",
|
|
8381
|
-
"circle-stroke-color": "#004170",
|
|
8382
|
-
"fill-color": "#00417077",
|
|
8383
|
-
"stroke-color": "#004170",
|
|
8384
|
-
},
|
|
8385
|
-
},
|
|
8386
|
-
];
|
|
8625
|
+
if (isGeoDB) {
|
|
8626
|
+
// handled by getGeoDBLayer
|
|
8627
|
+
return [];
|
|
8387
8628
|
}
|
|
8388
8629
|
|
|
8389
8630
|
// I propose following approach, we "manually" create configurations
|
|
@@ -8416,7 +8657,7 @@ class EodashCollection {
|
|
|
8416
8657
|
let extraProperties = null;
|
|
8417
8658
|
if (this.#collectionStac?.assets?.legend?.href) {
|
|
8418
8659
|
extraProperties = {
|
|
8419
|
-
description: `<div style="
|
|
8660
|
+
description: `<div style="width: 100%">
|
|
8420
8661
|
<img src="${this.#collectionStac.assets.legend.href}" style="max-height:70px; margin-top:-15px; margin-bottom:-20px;" />
|
|
8421
8662
|
</div>`,
|
|
8422
8663
|
};
|
|
@@ -8570,14 +8811,14 @@ class EodashCollection {
|
|
|
8570
8811
|
currentLayers = getCompareLayers();
|
|
8571
8812
|
}
|
|
8572
8813
|
|
|
8573
|
-
|
|
8814
|
+
/** @type {string | undefined} */
|
|
8815
|
+
const oldLayerID = findLayer(currentLayers, layer)?.properties.id;
|
|
8574
8816
|
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
|
|
8578
|
-
|
|
8579
|
-
|
|
8580
|
-
);
|
|
8817
|
+
if (!oldLayerID) {
|
|
8818
|
+
return;
|
|
8819
|
+
}
|
|
8820
|
+
|
|
8821
|
+
const updatedLayers = replaceLayer(currentLayers, oldLayerID, newLayers);
|
|
8581
8822
|
|
|
8582
8823
|
return updatedLayers;
|
|
8583
8824
|
}
|
|
@@ -8620,6 +8861,63 @@ class EodashCollection {
|
|
|
8620
8861
|
)),
|
|
8621
8862
|
];
|
|
8622
8863
|
}
|
|
8864
|
+
|
|
8865
|
+
/**
|
|
8866
|
+
* Returns GeoDB layer from a list of EodashCollections
|
|
8867
|
+
*
|
|
8868
|
+
* @param {EodashCollection[]} eodashCollections
|
|
8869
|
+
*
|
|
8870
|
+
**/
|
|
8871
|
+
static getGeoDBLayer(eodashCollections) {
|
|
8872
|
+
const allFeatures = [];
|
|
8873
|
+
for (const collection of eodashCollections) {
|
|
8874
|
+
const isGeoDB = collection.#collectionStac?.endpointtype === "GeoDB";
|
|
8875
|
+
if (!isGeoDB) {
|
|
8876
|
+
continue;
|
|
8877
|
+
}
|
|
8878
|
+
const collectionFeatures = generateFeatures(
|
|
8879
|
+
collection.#collectionStac?.links,
|
|
8880
|
+
).features;
|
|
8881
|
+
if (collectionFeatures.length) {
|
|
8882
|
+
allFeatures.push(
|
|
8883
|
+
generateFeatures(collection.#collectionStac?.links).features,
|
|
8884
|
+
);
|
|
8885
|
+
}
|
|
8886
|
+
}
|
|
8887
|
+
if (allFeatures.length) {
|
|
8888
|
+
const featureCollection = {
|
|
8889
|
+
type: "FeatureCollection",
|
|
8890
|
+
crs: {
|
|
8891
|
+
type: "name",
|
|
8892
|
+
properties: {
|
|
8893
|
+
name: "EPSG:4326",
|
|
8894
|
+
},
|
|
8895
|
+
},
|
|
8896
|
+
features: allFeatures.flat(),
|
|
8897
|
+
};
|
|
8898
|
+
return {
|
|
8899
|
+
type: "Vector",
|
|
8900
|
+
properties: {
|
|
8901
|
+
id: "geodb-collection",
|
|
8902
|
+
title: "GeoDB Collection",
|
|
8903
|
+
},
|
|
8904
|
+
source: {
|
|
8905
|
+
type: "Vector",
|
|
8906
|
+
url: "data:," + encodeURIComponent(JSON.stringify(featureCollection)),
|
|
8907
|
+
format: "GeoJSON",
|
|
8908
|
+
},
|
|
8909
|
+
style: {
|
|
8910
|
+
"circle-radius": 5,
|
|
8911
|
+
"circle-fill-color": "#00417077",
|
|
8912
|
+
"circle-stroke-color": "#004170",
|
|
8913
|
+
"fill-color": "#00417077",
|
|
8914
|
+
"stroke-color": "#004170",
|
|
8915
|
+
},
|
|
8916
|
+
interactions: [],
|
|
8917
|
+
};
|
|
8918
|
+
}
|
|
8919
|
+
return null;
|
|
8920
|
+
}
|
|
8623
8921
|
}
|
|
8624
8922
|
|
|
8625
8923
|
const useSTAcStore = defineStore("stac", () => {
|
|
@@ -8739,7 +9037,7 @@ const useSTAcStore = defineStore("stac", () => {
|
|
|
8739
9037
|
.get(absoluteUrl.value)
|
|
8740
9038
|
.then(async (resp) => {
|
|
8741
9039
|
// init eodash collections
|
|
8742
|
-
const collectionUrls = extractCollectionUrls(
|
|
9040
|
+
const collectionUrls = await extractCollectionUrls(
|
|
8743
9041
|
resp.data,
|
|
8744
9042
|
absoluteUrl.value,
|
|
8745
9043
|
);
|
|
@@ -8783,31 +9081,12 @@ const useSTAcStore = defineStore("stac", () => {
|
|
|
8783
9081
|
};
|
|
8784
9082
|
});
|
|
8785
9083
|
|
|
8786
|
-
|
|
8787
|
-
__proto__: null,
|
|
8788
|
-
useSTAcStore
|
|
8789
|
-
}, Symbol.toStringTag, { value: 'Module' }));
|
|
9084
|
+
//export all actions, states, and pinia stores
|
|
8790
9085
|
|
|
8791
|
-
const
|
|
8792
|
-
|
|
8793
|
-
const store = /** @type {import("@/types").EodashStore} */ (
|
|
8794
|
-
(() => {
|
|
8795
|
-
const stores = {};
|
|
8796
|
-
for (const [filePath, importedstore] of Object.entries(storesImport)) {
|
|
8797
|
-
const storeType =
|
|
8798
|
-
filePath.split("/").at(-1)?.slice(0, -3).toLowerCase() ?? "";
|
|
8799
|
-
if (!["keys"].includes(storeType)) {
|
|
8800
|
-
//@ts-expect-error `importedstore` cant be typed individually
|
|
8801
|
-
stores[storeType] = importedstore;
|
|
8802
|
-
}
|
|
8803
|
-
}
|
|
8804
|
-
return stores;
|
|
8805
|
-
})()
|
|
8806
|
-
);
|
|
9086
|
+
const store = { stac: { useSTAcStore }, actions, states };
|
|
8807
9087
|
|
|
8808
9088
|
/**
|
|
8809
|
-
*
|
|
8810
|
-
* it to `eodash`
|
|
9089
|
+
* Handles importing user defined instance of Eodash
|
|
8811
9090
|
*
|
|
8812
9091
|
* @async
|
|
8813
9092
|
* @param {string | undefined} runtimeConfig
|
|
@@ -8818,6 +9097,17 @@ const useEodashRuntime = async (runtimeConfig) => {
|
|
|
8818
9097
|
const eodash = /** @type {import("@/types").Eodash} */ (inject$1(eodashKey));
|
|
8819
9098
|
/** @param {import("@/types").Eodash} config */
|
|
8820
9099
|
const assignInstance = (config) => {
|
|
9100
|
+
if ("template" in config) {
|
|
9101
|
+
//@ts-expect-error to do
|
|
9102
|
+
delete eodash.templates;
|
|
9103
|
+
//@ts-expect-error to do
|
|
9104
|
+
eodash.template = config.template;
|
|
9105
|
+
} else if ("templates" in config) {
|
|
9106
|
+
//@ts-expect-error to do
|
|
9107
|
+
delete eodash.template;
|
|
9108
|
+
//@ts-expect-error to do
|
|
9109
|
+
eodash.templates = config.templates;
|
|
9110
|
+
}
|
|
8821
9111
|
/** @type {(keyof import("@/types").Eodash)[]} */ (
|
|
8822
9112
|
Object.keys(eodash)
|
|
8823
9113
|
).forEach((key) => {
|
|
@@ -8837,232 +9127,74 @@ const useEodashRuntime = async (runtimeConfig) => {
|
|
|
8837
9127
|
return eodash;
|
|
8838
9128
|
}
|
|
8839
9129
|
|
|
8840
|
-
try {
|
|
8841
|
-
const configJs = "/config.js";
|
|
8842
|
-
assignInstance(
|
|
8843
|
-
(await import(/* @vite-ignore */ new URL(configJs, import.meta.url).href))
|
|
8844
|
-
.default,
|
|
8845
|
-
);
|
|
8846
|
-
} catch {
|
|
8847
|
-
try {
|
|
8848
|
-
assignInstance(
|
|
8849
|
-
await Promise.resolve().then(() => eodash$1).then(async (m) => await m["default"]),
|
|
8850
|
-
);
|
|
8851
|
-
} catch {
|
|
8852
|
-
console.error("no dashboard configuration defined");
|
|
8853
|
-
}
|
|
8854
|
-
}
|
|
8855
|
-
return eodash;
|
|
8856
|
-
};
|
|
8857
|
-
|
|
8858
|
-
/**
|
|
8859
|
-
* Loads font in the app using `webfontloader`
|
|
8860
|
-
*
|
|
8861
|
-
* @param {string} [family]
|
|
8862
|
-
* @param {string} [link]
|
|
8863
|
-
* @param {boolean} [isWebComponent]
|
|
8864
|
-
* @returns {Promise<string>} - Font family name
|
|
8865
|
-
* @see {@link "https://github.com/typekit/webfontloader"}
|
|
8866
|
-
*/
|
|
8867
|
-
const loadFont = async (
|
|
8868
|
-
family = "",
|
|
8869
|
-
link = "",
|
|
8870
|
-
isWebComponent = false,
|
|
8871
|
-
) => {
|
|
8872
|
-
if (family && link) {
|
|
8873
|
-
const WebFontLoader = (await import('webfontloader')).default;
|
|
8874
|
-
WebFontLoader.load({
|
|
8875
|
-
classes: false,
|
|
8876
|
-
custom: {
|
|
8877
|
-
// Use FVD notation to include families https://github.com/typekit/fvd
|
|
8878
|
-
families: [family],
|
|
8879
|
-
// Path to stylesheet that defines font-face
|
|
8880
|
-
urls: [link],
|
|
8881
|
-
},
|
|
8882
|
-
fontactive(familyName, _fvd) {
|
|
8883
|
-
const stylesheet = new CSSStyleSheet();
|
|
8884
|
-
const styles = isWebComponent
|
|
8885
|
-
? `eo-dash {font-family: ${familyName};}`
|
|
8886
|
-
: `* {font-family: ${familyName};}`;
|
|
8887
|
-
stylesheet.replaceSync(styles);
|
|
8888
|
-
document.adoptedStyleSheets.push(stylesheet);
|
|
8889
|
-
},
|
|
8890
|
-
fontinactive(familyName, _fvd) {
|
|
8891
|
-
throw new Error(`error loading font: ${familyName}`);
|
|
8892
|
-
},
|
|
8893
|
-
});
|
|
8894
|
-
}
|
|
8895
|
-
return family;
|
|
8896
|
-
};
|
|
8897
|
-
|
|
8898
|
-
/**
|
|
8899
|
-
* @param {string} text
|
|
8900
|
-
* @param {import("vue").Ref<boolean>} showIcon
|
|
8901
|
-
**/
|
|
8902
|
-
const copyToClipBoard = async (text, showIcon) => {
|
|
8903
|
-
await navigator.clipboard.writeText(text);
|
|
8904
|
-
showIcon.value = true;
|
|
8905
|
-
setTimeout(() => {
|
|
8906
|
-
showIcon.value = false;
|
|
8907
|
-
}, 2000);
|
|
8908
|
-
};
|
|
8909
|
-
|
|
8910
|
-
/**
|
|
8911
|
-
* @typedef {{
|
|
8912
|
-
* component: import("vue").Component | null;
|
|
8913
|
-
* props: Record<string, unknown>;
|
|
8914
|
-
* title: string;
|
|
8915
|
-
* id: string | number | symbol;
|
|
8916
|
-
* layout: { x: number; y: number; h: number; w: number };
|
|
8917
|
-
* }} DefinedWidget
|
|
8918
|
-
*/
|
|
8919
|
-
|
|
8920
|
-
/** @typedef {import("vue").ShallowRef<DefinedWidget>} ReactiveDefinedWidget */
|
|
8921
|
-
|
|
8922
|
-
const internalWidgets = (() => {
|
|
8923
|
-
/** @type {Record<string, () => Promise<import("vue").Component>>} */
|
|
8924
|
-
const importMap = {
|
|
8925
|
-
.../* #__PURE__ */ Object.assign({"/widgets/EodashDatePicker.vue": () => import('./EodashDatePicker-CjU8R2ia.js'),"/widgets/EodashItemFilter.vue": () => import('./EodashItemFilter-VGQasaBJ.js'),"/widgets/EodashLayerControl.vue": () => import('./EodashLayerControl-mKfwru42.js'),"/widgets/EodashMap.vue": () => import('./EodashMap-BpwL82-w.js'),"/widgets/EodashMapBtns.vue": () => import('./EodashMapBtns-GNNBdBW9.js'),"/widgets/ExportState.vue": () => import('./ExportState-ByVuIAQb.js'),"/widgets/PopUp.vue": () => import('./PopUp-CdFcnKMY.js'),"/widgets/WidgetsContainer.vue": () => import('./WidgetsContainer-XXYJfaPR.js')}),
|
|
8926
|
-
.../* #__PURE__ */ Object.assign({}),
|
|
8927
|
-
};
|
|
8928
|
-
for (const key in importMap) {
|
|
8929
|
-
const newKey = /** @type {string} */ (key.split("/").at(-1)).slice(0, -4);
|
|
8930
|
-
Object.defineProperty(
|
|
8931
|
-
importMap,
|
|
8932
|
-
newKey,
|
|
8933
|
-
/** @type {PropertyDescriptor} */ (
|
|
8934
|
-
Object.getOwnPropertyDescriptor(importMap, key)
|
|
8935
|
-
),
|
|
8936
|
-
);
|
|
8937
|
-
delete importMap[key];
|
|
8938
|
-
}
|
|
8939
|
-
return importMap;
|
|
8940
|
-
})();
|
|
8941
|
-
|
|
8942
|
-
/**
|
|
8943
|
-
* Composable that converts widgets Configurations to defined imported widgets
|
|
8944
|
-
*
|
|
8945
|
-
* @param {(
|
|
8946
|
-
* | import("@/types").Widget
|
|
8947
|
-
* | import("@/types").BackgroundWidget
|
|
8948
|
-
* | Omit<import("@/types").Widget, "layout">
|
|
8949
|
-
* | undefined
|
|
8950
|
-
* )[]
|
|
8951
|
-
* | undefined} widgetConfigs
|
|
8952
|
-
* @returns {ReactiveDefinedWidget[]}
|
|
8953
|
-
*/
|
|
8954
|
-
const useDefineWidgets = (widgetConfigs) => {
|
|
8955
|
-
/** @type {ReactiveDefinedWidget[]} */
|
|
8956
|
-
const definedWidgets = [];
|
|
8957
|
-
|
|
8958
|
-
for (const config of widgetConfigs ?? []) {
|
|
8959
|
-
/** @type {ReactiveDefinedWidget} */
|
|
8960
|
-
const definedWidget = shallowRef({
|
|
8961
|
-
component: null,
|
|
8962
|
-
props: {},
|
|
8963
|
-
title: "",
|
|
8964
|
-
id: Symbol(),
|
|
8965
|
-
layout: { x: 0, y: 0, h: 0, w: 0 },
|
|
8966
|
-
});
|
|
8967
|
-
|
|
8968
|
-
if ("defineWidget" in (config ?? {})) {
|
|
8969
|
-
const { selectedStac } = storeToRefs(useSTAcStore());
|
|
8970
|
-
watch(
|
|
8971
|
-
selectedStac,
|
|
8972
|
-
(updatedStac) => {
|
|
8973
|
-
let definedConfig =
|
|
8974
|
-
/** @type {import("@/types").FunctionalWidget} */ (
|
|
8975
|
-
config
|
|
8976
|
-
)?.defineWidget(updatedStac);
|
|
8977
|
-
if (definedConfig) {
|
|
8978
|
-
definedConfig = reactive(definedConfig);
|
|
8979
|
-
}
|
|
8980
|
-
definedWidget.value =
|
|
8981
|
-
definedWidget.value.id === definedConfig?.id
|
|
8982
|
-
? definedWidget.value
|
|
8983
|
-
: getWidgetDefinition(definedConfig);
|
|
8984
|
-
},
|
|
8985
|
-
{ immediate: true },
|
|
8986
|
-
);
|
|
8987
|
-
} else {
|
|
8988
|
-
definedWidget.value = getWidgetDefinition(
|
|
8989
|
-
/** @type {import("@/types").StaticWidget} */ (config),
|
|
8990
|
-
);
|
|
8991
|
-
}
|
|
8992
|
-
definedWidgets.push(definedWidget);
|
|
8993
|
-
}
|
|
8994
|
-
return definedWidgets;
|
|
8995
|
-
};
|
|
8996
|
-
|
|
8997
|
-
/**
|
|
8998
|
-
* Converts a static widget configuration to a defined imported widget
|
|
8999
|
-
*
|
|
9000
|
-
* @param {import("@/types").StaticWidget
|
|
9001
|
-
* | Omit<import("@/types").StaticWidget, "layout">
|
|
9002
|
-
* | undefined
|
|
9003
|
-
* | null} [config]
|
|
9004
|
-
* @returns {DefinedWidget}
|
|
9005
|
-
*/
|
|
9006
|
-
const getWidgetDefinition = (config) => {
|
|
9007
|
-
/** @type {DefinedWidget} */
|
|
9008
|
-
const importedWidget = {
|
|
9009
|
-
component: null,
|
|
9010
|
-
props: {},
|
|
9011
|
-
title: "",
|
|
9012
|
-
id: Symbol(),
|
|
9013
|
-
layout: reactive({ x: 0, y: 0, h: 0, w: 0 }),
|
|
9014
|
-
};
|
|
9015
|
-
switch (config?.type) {
|
|
9016
|
-
case "internal":
|
|
9017
|
-
importedWidget.component = defineAsyncComponent({
|
|
9018
|
-
loader:
|
|
9019
|
-
internalWidgets[
|
|
9020
|
-
/** @type {import("@/types").InternalComponentWidget} * */ (config)
|
|
9021
|
-
?.widget.name
|
|
9022
|
-
],
|
|
9023
|
-
suspensible: true,
|
|
9024
|
-
});
|
|
9025
|
-
importedWidget.props = reactive(
|
|
9026
|
-
/** @type {import("@/types").InternalComponentWidget} * */ (config)
|
|
9027
|
-
?.widget.properties ?? {},
|
|
9028
|
-
);
|
|
9029
|
-
|
|
9030
|
-
break;
|
|
9031
|
-
|
|
9032
|
-
case "web-component":
|
|
9033
|
-
importedWidget.component = defineAsyncComponent({
|
|
9034
|
-
loader: () => import('./DynamicWebComponent-C9pVUfT3.js'),
|
|
9035
|
-
suspensible: true,
|
|
9036
|
-
});
|
|
9037
|
-
importedWidget.props = reactive(config.widget);
|
|
9038
|
-
|
|
9039
|
-
break;
|
|
9040
|
-
case "iframe":
|
|
9041
|
-
importedWidget.component = defineAsyncComponent({
|
|
9042
|
-
loader: () => import('./IframeWrapper-BgM9aU8f.js'),
|
|
9043
|
-
suspensible: true,
|
|
9044
|
-
});
|
|
9045
|
-
importedWidget.props = reactive(config.widget);
|
|
9046
|
-
break;
|
|
9047
|
-
|
|
9048
|
-
default:
|
|
9049
|
-
if (!config) {
|
|
9050
|
-
return importedWidget;
|
|
9051
|
-
} else {
|
|
9052
|
-
console.error("Widget type not found");
|
|
9053
|
-
}
|
|
9054
|
-
break;
|
|
9130
|
+
try {
|
|
9131
|
+
const configJs = "/config.js";
|
|
9132
|
+
assignInstance(
|
|
9133
|
+
(await import(/* @vite-ignore */ new URL(configJs, import.meta.url).href))
|
|
9134
|
+
.default,
|
|
9135
|
+
);
|
|
9136
|
+
} catch {
|
|
9137
|
+
try {
|
|
9138
|
+
assignInstance(
|
|
9139
|
+
await Promise.resolve().then(() => eodash$1).then(async (m) => await m["default"]),
|
|
9140
|
+
);
|
|
9141
|
+
} catch {
|
|
9142
|
+
console.error("no dashboard configuration defined");
|
|
9143
|
+
}
|
|
9055
9144
|
}
|
|
9056
|
-
|
|
9057
|
-
|
|
9145
|
+
return eodash;
|
|
9146
|
+
};
|
|
9058
9147
|
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9148
|
+
/**
|
|
9149
|
+
* Loads font in the app using `webfontloader`
|
|
9150
|
+
*
|
|
9151
|
+
* @param {string} [family]
|
|
9152
|
+
* @param {string} [link]
|
|
9153
|
+
* @param {boolean} [isWebComponent]
|
|
9154
|
+
* @returns {Promise<string>} - Font family name
|
|
9155
|
+
* @see {@link "https://github.com/typekit/webfontloader"}
|
|
9156
|
+
*/
|
|
9157
|
+
const loadFont = async (
|
|
9158
|
+
family = "",
|
|
9159
|
+
link = "",
|
|
9160
|
+
isWebComponent = false,
|
|
9161
|
+
) => {
|
|
9162
|
+
if (family && link) {
|
|
9163
|
+
const WebFontLoader = (await import('webfontloader')).default;
|
|
9164
|
+
WebFontLoader.load({
|
|
9165
|
+
classes: false,
|
|
9166
|
+
custom: {
|
|
9167
|
+
// Use FVD notation to include families https://github.com/typekit/fvd
|
|
9168
|
+
families: [family],
|
|
9169
|
+
// Path to stylesheet that defines font-face
|
|
9170
|
+
urls: [link],
|
|
9171
|
+
},
|
|
9172
|
+
fontactive(familyName, _fvd) {
|
|
9173
|
+
const stylesheet = new CSSStyleSheet();
|
|
9174
|
+
const styles = isWebComponent
|
|
9175
|
+
? `eo-dash {font-family: ${familyName};}`
|
|
9176
|
+
: `* {font-family: ${familyName};}`;
|
|
9177
|
+
stylesheet.replaceSync(styles);
|
|
9178
|
+
document.adoptedStyleSheets.push(stylesheet);
|
|
9179
|
+
},
|
|
9180
|
+
fontinactive(familyName, _fvd) {
|
|
9181
|
+
throw new Error(`error loading font: ${familyName}`);
|
|
9182
|
+
},
|
|
9183
|
+
});
|
|
9064
9184
|
}
|
|
9065
|
-
return
|
|
9185
|
+
return family;
|
|
9186
|
+
};
|
|
9187
|
+
|
|
9188
|
+
/**
|
|
9189
|
+
* @param {string} text
|
|
9190
|
+
* @param {import("vue").Ref<boolean>} showIcon
|
|
9191
|
+
**/
|
|
9192
|
+
const copyToClipBoard = async (text, showIcon) => {
|
|
9193
|
+
await navigator.clipboard.writeText(text);
|
|
9194
|
+
showIcon.value = true;
|
|
9195
|
+
setTimeout(() => {
|
|
9196
|
+
showIcon.value = false;
|
|
9197
|
+
}, 2000);
|
|
9066
9198
|
};
|
|
9067
9199
|
|
|
9068
9200
|
const _export_sfc = (sfc, props) => {
|
|
@@ -11042,6 +11174,226 @@ return (_ctx, _cache) => {
|
|
|
11042
11174
|
};
|
|
11043
11175
|
const ErrorAlert = /*#__PURE__*/_export_sfc(_sfc_main$3, [['__scopeId',"data-v-ac10aa7f"]]);
|
|
11044
11176
|
|
|
11177
|
+
/**
|
|
11178
|
+
* @typedef {{
|
|
11179
|
+
* component: import("vue").Component | null;
|
|
11180
|
+
* props: Record<string, unknown>;
|
|
11181
|
+
* title: string;
|
|
11182
|
+
* id: string | number | symbol;
|
|
11183
|
+
* layout: { x: number; y: number; h: number; w: number };
|
|
11184
|
+
* }} DefinedWidget
|
|
11185
|
+
*/
|
|
11186
|
+
|
|
11187
|
+
/** @typedef {import("vue").ShallowRef<DefinedWidget>} ReactiveDefinedWidget */
|
|
11188
|
+
/**
|
|
11189
|
+
* Widgets import map that is created from eodash internals and user defined widgets
|
|
11190
|
+
*/
|
|
11191
|
+
const internalWidgets = (() => {
|
|
11192
|
+
/** @type {Record<string, () => Promise<import("vue").Component>>} */
|
|
11193
|
+
const importMap = {
|
|
11194
|
+
.../* #__PURE__ */ Object.assign({"/widgets/EodashDatePicker.vue": () => import('./EodashDatePicker-Pok6bZwU.js'),"/widgets/EodashItemFilter.vue": () => import('./EodashItemFilter-16eMMjTV.js'),"/widgets/EodashLayerControl.vue": () => import('./EodashLayerControl-De7IlCm_.js'),"/widgets/EodashLayoutSwitcher.vue": () => import('./EodashLayoutSwitcher-C-3-jjn5.js'),"/widgets/EodashMap.vue": () => import('./EodashMap-CMvbfI6-.js'),"/widgets/EodashMapBtns.vue": () => import('./EodashMapBtns-BeknGDtc.js'),"/widgets/EodashProcess.vue": () => import('./EodashProcess-BwKAa9Ee.js'),"/widgets/EodashStacInfo.vue": () => import('./EodashStacInfo-_BfonNUG.js'),"/widgets/EodashTools.vue": () => import('./EodashTools-PD3XPYuR.js'),"/widgets/ExportState.vue": () => import('./ExportState-DOrT7M15.js'),"/widgets/PopUp.vue": () => import('./PopUp--_xn1Cms.js'),"/widgets/WidgetsContainer.vue": () => import('./WidgetsContainer-aFG9yFT6.js')}),
|
|
11195
|
+
.../* #__PURE__ */ Object.assign({}),
|
|
11196
|
+
};
|
|
11197
|
+
for (const key in importMap) {
|
|
11198
|
+
const newKey = /** @type {string} */ (key.split("/").at(-1)).slice(0, -4);
|
|
11199
|
+
Object.defineProperty(
|
|
11200
|
+
importMap,
|
|
11201
|
+
newKey,
|
|
11202
|
+
/** @type {PropertyDescriptor} */ (
|
|
11203
|
+
Object.getOwnPropertyDescriptor(importMap, key)
|
|
11204
|
+
),
|
|
11205
|
+
);
|
|
11206
|
+
delete importMap[key];
|
|
11207
|
+
}
|
|
11208
|
+
return importMap;
|
|
11209
|
+
})();
|
|
11210
|
+
|
|
11211
|
+
/**
|
|
11212
|
+
* Composable that converts widgets Configurations to defined imported widgets
|
|
11213
|
+
*
|
|
11214
|
+
* @param {(
|
|
11215
|
+
* | import("@/types").Widget
|
|
11216
|
+
* | import("@/types").BackgroundWidget
|
|
11217
|
+
* | Omit<import("@/types").Widget, "layout">
|
|
11218
|
+
* | undefined
|
|
11219
|
+
* )[]
|
|
11220
|
+
* | undefined} widgetConfigs
|
|
11221
|
+
*/
|
|
11222
|
+
const useDefineWidgets = (widgetConfigs) => {
|
|
11223
|
+
/** @type {ReactiveDefinedWidget[]} */
|
|
11224
|
+
const definedWidgets = [];
|
|
11225
|
+
|
|
11226
|
+
for (const config of widgetConfigs ?? []) {
|
|
11227
|
+
/** @type {ReactiveDefinedWidget} */
|
|
11228
|
+
const definedWidget = shallowRef({
|
|
11229
|
+
component: null,
|
|
11230
|
+
props: {},
|
|
11231
|
+
title: "",
|
|
11232
|
+
id: Symbol(),
|
|
11233
|
+
layout: { x: 0, y: 0, h: 0, w: 0 },
|
|
11234
|
+
});
|
|
11235
|
+
|
|
11236
|
+
if ("defineWidget" in (config ?? {})) {
|
|
11237
|
+
const { selectedStac } = storeToRefs(useSTAcStore());
|
|
11238
|
+
watch(
|
|
11239
|
+
selectedStac,
|
|
11240
|
+
(updatedStac) => {
|
|
11241
|
+
let definedConfig =
|
|
11242
|
+
/** @type {import("@/types").FunctionalWidget} */ (
|
|
11243
|
+
config
|
|
11244
|
+
)?.defineWidget(updatedStac);
|
|
11245
|
+
if (definedConfig) {
|
|
11246
|
+
definedConfig = reactive(definedConfig);
|
|
11247
|
+
}
|
|
11248
|
+
definedWidget.value =
|
|
11249
|
+
definedWidget.value.id === definedConfig?.id
|
|
11250
|
+
? definedWidget.value
|
|
11251
|
+
: getWidgetDefinition(definedConfig);
|
|
11252
|
+
},
|
|
11253
|
+
{ immediate: true },
|
|
11254
|
+
);
|
|
11255
|
+
} else {
|
|
11256
|
+
definedWidget.value = getWidgetDefinition(
|
|
11257
|
+
/** @type {import("@/types").StaticWidget} */ (config),
|
|
11258
|
+
);
|
|
11259
|
+
}
|
|
11260
|
+
definedWidgets.push(definedWidget);
|
|
11261
|
+
}
|
|
11262
|
+
return definedWidgets;
|
|
11263
|
+
};
|
|
11264
|
+
|
|
11265
|
+
/**
|
|
11266
|
+
* Converts a static widget configuration to a defined imported widget
|
|
11267
|
+
*
|
|
11268
|
+
* @param {import("@/types").StaticWidget
|
|
11269
|
+
* | Omit<import("@/types").StaticWidget, "layout">
|
|
11270
|
+
* | undefined
|
|
11271
|
+
* | null} [config]
|
|
11272
|
+
* @returns {DefinedWidget}
|
|
11273
|
+
*/
|
|
11274
|
+
const getWidgetDefinition = (config) => {
|
|
11275
|
+
/** @type {DefinedWidget} */
|
|
11276
|
+
const importedWidget = {
|
|
11277
|
+
component: null,
|
|
11278
|
+
props: {},
|
|
11279
|
+
title: "",
|
|
11280
|
+
id: Symbol(),
|
|
11281
|
+
layout: reactive({ x: 0, y: 0, h: 0, w: 0 }),
|
|
11282
|
+
};
|
|
11283
|
+
switch (config?.type) {
|
|
11284
|
+
case "internal":
|
|
11285
|
+
importedWidget.component = defineAsyncComponent({
|
|
11286
|
+
loader:
|
|
11287
|
+
internalWidgets[
|
|
11288
|
+
/** @type {import("@/types").InternalComponentWidget} * */ (config)
|
|
11289
|
+
?.widget.name
|
|
11290
|
+
],
|
|
11291
|
+
suspensible: true,
|
|
11292
|
+
});
|
|
11293
|
+
importedWidget.props = reactive(
|
|
11294
|
+
/** @type {import("@/types").InternalComponentWidget} * */ (config)
|
|
11295
|
+
?.widget.properties ?? {},
|
|
11296
|
+
);
|
|
11297
|
+
|
|
11298
|
+
break;
|
|
11299
|
+
|
|
11300
|
+
case "web-component":
|
|
11301
|
+
importedWidget.component = defineAsyncComponent({
|
|
11302
|
+
loader: () => import('./DynamicWebComponent-Cl4LqHU6.js'),
|
|
11303
|
+
suspensible: true,
|
|
11304
|
+
});
|
|
11305
|
+
importedWidget.props = reactive(config.widget);
|
|
11306
|
+
|
|
11307
|
+
break;
|
|
11308
|
+
case "iframe":
|
|
11309
|
+
importedWidget.component = defineAsyncComponent({
|
|
11310
|
+
loader: () => import('./IframeWrapper-BgM9aU8f.js'),
|
|
11311
|
+
suspensible: true,
|
|
11312
|
+
});
|
|
11313
|
+
importedWidget.props = reactive(config.widget);
|
|
11314
|
+
break;
|
|
11315
|
+
|
|
11316
|
+
default:
|
|
11317
|
+
if (!config) {
|
|
11318
|
+
return importedWidget;
|
|
11319
|
+
} else {
|
|
11320
|
+
console.error("Widget type not found");
|
|
11321
|
+
}
|
|
11322
|
+
break;
|
|
11323
|
+
}
|
|
11324
|
+
importedWidget.title = config?.title ?? "";
|
|
11325
|
+
importedWidget.id = config?.id ?? importedWidget.id;
|
|
11326
|
+
|
|
11327
|
+
if ("layout" in config) {
|
|
11328
|
+
importedWidget.layout.x = config.layout.x;
|
|
11329
|
+
importedWidget.layout.y = config.layout.y;
|
|
11330
|
+
importedWidget.layout.h = config.layout.h;
|
|
11331
|
+
importedWidget.layout.w = config.layout.w;
|
|
11332
|
+
}
|
|
11333
|
+
return importedWidget;
|
|
11334
|
+
};
|
|
11335
|
+
|
|
11336
|
+
/**
|
|
11337
|
+
* @typedef {{
|
|
11338
|
+
* bgWidget:ReturnType< typeof import("./DefineWidgets").useDefineWidgets>[number]| import("vue").ShallowRef<null>
|
|
11339
|
+
* loading: ReturnType< typeof import("./DefineWidgets").useDefineWidgets>[number]| import("vue").ShallowRef<null>
|
|
11340
|
+
* importedWidgets:ReturnType< typeof import("./DefineWidgets").useDefineWidgets>
|
|
11341
|
+
* gap: import("vue").Ref<number>
|
|
11342
|
+
* }} DefinedTemplate
|
|
11343
|
+
**/
|
|
11344
|
+
|
|
11345
|
+
const useTemplate = () => {
|
|
11346
|
+
const eodash = /** @type {import("@/types").Eodash} */ (inject$1(eodashKey));
|
|
11347
|
+
|
|
11348
|
+
/** @type {DefinedTemplate} */
|
|
11349
|
+
const definedTemplate = shallowReactive({
|
|
11350
|
+
bgWidget: shallowRef(null),
|
|
11351
|
+
importedWidgets: [],
|
|
11352
|
+
loading: shallowRef(null),
|
|
11353
|
+
gap: ref(16),
|
|
11354
|
+
});
|
|
11355
|
+
|
|
11356
|
+
if ("template" in eodash) {
|
|
11357
|
+
[definedTemplate.bgWidget] = useDefineWidgets([eodash.template.background]);
|
|
11358
|
+
[definedTemplate.loading] = useDefineWidgets([eodash.template.loading]);
|
|
11359
|
+
definedTemplate.importedWidgets = useDefineWidgets(eodash.template.widgets);
|
|
11360
|
+
definedTemplate.gap.value = eodash.template.gap ?? 16;
|
|
11361
|
+
} else {
|
|
11362
|
+
watch(
|
|
11363
|
+
activeTemplate,
|
|
11364
|
+
(template) => {
|
|
11365
|
+
log.debug("Active template watcher triggered, changing to:", template);
|
|
11366
|
+
if (!template) {
|
|
11367
|
+
template = Object.keys(eodash.templates)[0];
|
|
11368
|
+
activeTemplate.value = template ?? "";
|
|
11369
|
+
log.debug("No template found, setting to first template", template);
|
|
11370
|
+
}
|
|
11371
|
+
|
|
11372
|
+
if (!template || !eodash.templates[template]) {
|
|
11373
|
+
console.error(`[eodash] template not found`);
|
|
11374
|
+
return;
|
|
11375
|
+
}
|
|
11376
|
+
|
|
11377
|
+
const templateConfig = eodash.templates[template];
|
|
11378
|
+
[definedTemplate.bgWidget] = useDefineWidgets([
|
|
11379
|
+
templateConfig.background,
|
|
11380
|
+
]);
|
|
11381
|
+
|
|
11382
|
+
[definedTemplate.loading] = useDefineWidgets([templateConfig.loading]);
|
|
11383
|
+
|
|
11384
|
+
definedTemplate.importedWidgets = useDefineWidgets(
|
|
11385
|
+
templateConfig.widgets,
|
|
11386
|
+
);
|
|
11387
|
+
definedTemplate.gap.value = templateConfig.gap ?? 16;
|
|
11388
|
+
},
|
|
11389
|
+
{ immediate: true },
|
|
11390
|
+
);
|
|
11391
|
+
}
|
|
11392
|
+
return toRefs(definedTemplate);
|
|
11393
|
+
};
|
|
11394
|
+
|
|
11395
|
+
const useDefineTemplate = createSharedComposable(useTemplate);
|
|
11396
|
+
|
|
11045
11397
|
// Styles
|
|
11046
11398
|
const breakpointProps = (() => {
|
|
11047
11399
|
return breakpoints.reduce((props, val) => {
|
|
@@ -11286,9 +11638,7 @@ const _sfc_main$2 = {
|
|
|
11286
11638
|
__name: 'Loading',
|
|
11287
11639
|
setup(__props) {
|
|
11288
11640
|
|
|
11289
|
-
const
|
|
11290
|
-
|
|
11291
|
-
const [loading] = useDefineWidgets([eodash.template.loading]);
|
|
11641
|
+
const { loading } = useDefineTemplate();
|
|
11292
11642
|
|
|
11293
11643
|
const error = ref("");
|
|
11294
11644
|
onErrorCaptured((e, inst, info) => {
|
|
@@ -11316,8 +11666,8 @@ return (_ctx, _cache) => {
|
|
|
11316
11666
|
createElementVNode("div", { class: "text-center" }, "Loading...", -1 /* HOISTED */)
|
|
11317
11667
|
])),
|
|
11318
11668
|
default: withCtx(() => [
|
|
11319
|
-
(unref(loading)
|
|
11320
|
-
? (openBlock(), createBlock(resolveDynamicComponent(unref(loading)
|
|
11669
|
+
(unref(loading)?.component)
|
|
11670
|
+
? (openBlock(), createBlock(resolveDynamicComponent(unref(loading)?.component), normalizeProps(mergeProps({ key: 0 }, unref(loading)?.props)), null, 16 /* FULL_PROPS */))
|
|
11321
11671
|
: (openBlock(), createElementBlock("div", _hoisted_1$1, "Loading..."))
|
|
11322
11672
|
]),
|
|
11323
11673
|
_: 1 /* STABLE */
|
|
@@ -11381,15 +11731,17 @@ const { loadSTAC } = useSTAcStore();
|
|
|
11381
11731
|
);
|
|
11382
11732
|
|
|
11383
11733
|
const { smAndDown } = useDisplay();
|
|
11384
|
-
const TemplateComponent =
|
|
11385
|
-
|
|
11386
|
-
|
|
11734
|
+
const TemplateComponent = computed(() =>
|
|
11735
|
+
smAndDown.value
|
|
11736
|
+
? defineAsyncComponent(() => import('./MobileLayout-BdiFjHg7.js'))
|
|
11737
|
+
: defineAsyncComponent(() => import('./DashboardLayout-232tRmjz.js')),
|
|
11738
|
+
);
|
|
11387
11739
|
|
|
11388
11740
|
const HeaderComponent = defineAsyncComponent(
|
|
11389
|
-
() => import('./Header-
|
|
11741
|
+
() => import('./Header-C2cdx4gb.js'),
|
|
11390
11742
|
);
|
|
11391
11743
|
const FooterComponent = defineAsyncComponent(
|
|
11392
|
-
() => import('./Footer-
|
|
11744
|
+
() => import('./Footer-CCigxYBo.js'),
|
|
11393
11745
|
);
|
|
11394
11746
|
|
|
11395
11747
|
const templateHeight = props.isWebComponent ? "100%" : "100dvh";
|
|
@@ -11541,6 +11893,7 @@ const vuetify = createVuetify({
|
|
|
11541
11893
|
next: [mdiChevronRight],
|
|
11542
11894
|
prev: [mdiChevronLeft],
|
|
11543
11895
|
subgroup: [mdiMenuDown],
|
|
11896
|
+
plus: [mdiPlus],
|
|
11544
11897
|
},
|
|
11545
11898
|
},
|
|
11546
11899
|
theme: {
|
|
@@ -11574,7 +11927,7 @@ function registerPlugins(app) {
|
|
|
11574
11927
|
* @type {import("vue").VueElementConstructor<
|
|
11575
11928
|
* import("vue").ExtractPropTypes<{ config: string }>>}
|
|
11576
11929
|
* */
|
|
11577
|
-
const
|
|
11930
|
+
const EodashConstructor = defineCustomElement(_sfc_main, {
|
|
11578
11931
|
shadowRoot: false,
|
|
11579
11932
|
configureApp(app) {
|
|
11580
11933
|
registerPlugins(app);
|
|
@@ -11582,9 +11935,9 @@ const Eodash = defineCustomElement(_sfc_main, {
|
|
|
11582
11935
|
});
|
|
11583
11936
|
|
|
11584
11937
|
function register() {
|
|
11585
|
-
customElements.define("eo-dash",
|
|
11938
|
+
customElements.define("eo-dash", EodashConstructor);
|
|
11586
11939
|
}
|
|
11587
11940
|
|
|
11588
11941
|
register();
|
|
11589
11942
|
|
|
11590
|
-
export { useSTAcStore as $, makeDensityProps as A, useDensity as B, useBackgroundColor as C, provideDefaults as D, isObject as E,
|
|
11943
|
+
export { useSTAcStore as $, makeDensityProps as A, useDensity as B, useBackgroundColor as C, provideDefaults as D, isObject as E, useDefineTemplate as F, useLayout as G, makeDimensionProps as H, IconValue as I, useDimension as J, makeBorderProps as K, makeElevationProps as L, makeRoundedProps as M, useBorder as N, useElevation as O, useRounded as P, VDefaultsProvider as Q, clamp as R, consoleWarn as S, makeLayoutItemProps as T, useToggleScope as U, VBtn as V, useLayoutItem as W, eodashKey as X, consoleError as Y, datetime as Z, _export_sfc as _, useRender as a, eodashCollections as a0, makePanelTransparent as a1, mapCompareEl as a2, mapEl as a3, eodashCompareCollections as a4, getColFromLayer as a5, registerProjection as a6, getProjectionCode as a7, availableMapProjection as a8, changeMapProjection as a9, useLink as aA, LoaderSlot as aB, removeUnneededProperties as aC, VRow as aD, VCol as aE, copyToClipBoard as aF, SUPPORTS_INTERSECTION as aG, getCurrentInstance as aH, useDefineWidgets as aI, isOn as aJ, eventName as aK, destructComputed as aL, parseAnchor as aM, flipSide as aN, flipAlign as aO, flipCorner as aP, getAxis as aQ, defer as aR, templateRef as aS, matchesSelector as aT, useRouter as aU, useBackButton as aV, EodashConstructor as aW, register as aX, store as aY, eoxLayersKey as aa, posIsSetFromUrl as ab, EodashCollection as ac, mapPosition as ad, setActiveTemplate as ae, axios$1 as af, getLayers as ag, extractLayerConfig as ah, useOnLayersUpdate as ai, currentUrl as aj, activeTemplate as ak, getUid as al, createSimpleFunctional as am, makeSizeProps as an, makeVariantProps as ao, useVariant as ap, useSize as aq, genOverlays as ar, makeLoaderProps as as, makeLocationProps as at, makePositionProps as au, makeRouterProps as av, Ripple as aw, useLoader as ax, useLocation as ay, usePosition as az, makeComponentProps as b, makeTagProps as c, makeThemeProps as d, provideTheme as e, useRtl as f, genericComponent as g, useLocale as h, useGroup as i, useProxiedModel as j, keys as k, makeGroupItemProps as l, makeVBtnProps as m, useGroupItem as n, omit as o, propsFactory as p, convertToUnit as q, makeDisplayProps as r, makeGroupProps as s, useDisplay as t, useTextColor as u, useResizeObserver as v, useGoTo as w, IN_BROWSER as x, VIcon as y, focusableChildren as z };
|