@eodash/eodash 5.0.0-alpha.1.9 → 5.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +1 -1
  2. package/bin/cli.js +15 -8
  3. package/bin/main.js +9 -0
  4. package/bin/serverConfig.js +58 -29
  5. package/bin/types.d.ts +52 -0
  6. package/bin/utils.js +70 -20
  7. package/core/App.vue +10 -12
  8. package/core/SuspensedDashboard.ce.vue +59 -0
  9. package/core/asWebComponent.d.ts +18 -0
  10. package/core/asWebComponent.js +12 -0
  11. package/core/components/DashboardLayout.vue +23 -27
  12. package/core/components/DynamicWebComponent.vue +6 -6
  13. package/core/components/Footer.vue +11 -12
  14. package/core/components/Header.vue +5 -29
  15. package/core/components/Loading.vue +27 -0
  16. package/core/components/MobileLayout.vue +34 -63
  17. package/core/composables/DefineEodash.js +57 -0
  18. package/core/composables/DefineWidgets.js +26 -15
  19. package/core/composables/index.js +139 -67
  20. package/core/eodash.js +100 -0
  21. package/core/main.js +2 -4
  22. package/core/plugins/index.js +3 -12
  23. package/core/plugins/vuetify.js +5 -2
  24. package/core/store/Actions.js +0 -28
  25. package/core/store/States.js +12 -3
  26. package/core/store/stac.js +7 -5
  27. package/core/types.d.ts +148 -124
  28. package/core/utils/eodashSTAC.js +164 -0
  29. package/core/utils/helpers.js +40 -0
  30. package/core/utils/index.js +28 -0
  31. package/core/utils/keys.js +6 -0
  32. package/core/views/Dashboard.vue +33 -23
  33. package/core/vite-env.d.ts +16 -2
  34. package/dist/.gitkeep +0 -0
  35. package/dist/DashboardLayout-YLfAa8wH.js +168 -0
  36. package/dist/DynamicWebComponent-BDOQsEcj.js +57 -0
  37. package/dist/EodashDatePicker-DlehqSgz.js +1645 -0
  38. package/dist/EodashItemFilter-TSp7XRGy.js +51 -0
  39. package/dist/EodashMap-DInb9cfS.js +53405 -0
  40. package/dist/Footer-CIzHgJbK.js +118 -0
  41. package/dist/Header-C5PSB8Uc.js +609 -0
  42. package/dist/IframeWrapper-DYHQQRUh.js +19 -0
  43. package/dist/MobileLayout-DZmqrpub.js +523 -0
  44. package/dist/VBtn-CFPhsIX8.js +1106 -0
  45. package/dist/VMain-deI9jyIf.js +35 -0
  46. package/dist/WidgetsContainer-D_PLP1qf.js +122 -0
  47. package/dist/_commonjsHelpers-DaMA6jEr.js +8 -0
  48. package/dist/asWebComponent-BKe6Spni.js +11323 -0
  49. package/dist/basedecoder-Qm25PwVp-CHo5Pomv.js +89 -0
  50. package/dist/color-D72nEBIR.js +115 -0
  51. package/dist/decoder-kAoyGIq9-HAkjSTCt.js +10 -0
  52. package/dist/deflate-Be2Arps5-hDqMz3RA.js +10 -0
  53. package/dist/dimensions-BZkmIizV.js +53 -0
  54. package/dist/eo-dash.js +6 -0
  55. package/dist/eox-itemfilter-DcQkRD2l.js +7537 -0
  56. package/dist/eox-map-BJ9SIixs.js +36205 -0
  57. package/dist/eox-stacinfo-B-YrT7Ug.js +13698 -0
  58. package/dist/forwardRefs-Bxeu9Obx.js +142 -0
  59. package/dist/index-8ch8xKfa.js +152 -0
  60. package/dist/index-DIt8GjSR.js +65 -0
  61. package/dist/jpeg-DNfUpLwy-Fjan-04T.js +515 -0
  62. package/dist/lerc-C9VL9kri-DyVxBvsf.js +1029 -0
  63. package/dist/lzw-BOMhmEDy-Dboc93VO.js +84 -0
  64. package/dist/packbits-DaUD6MLm-Bu1PoTGa.js +24 -0
  65. package/dist/pako.esm-C3kYPGGQ-BMki8cQY.js +1087 -0
  66. package/dist/raw-CcGKjn8q-DFOt-i8n.js +9 -0
  67. package/dist/ssrBoot-Cm5pWM14.js +17 -0
  68. package/dist/style.css +5 -0
  69. package/dist/webfontloader-CyOFAuFB.js +471 -0
  70. package/dist/webimage-D2c098k3-DLj1LQxB.js +19 -0
  71. package/package.json +40 -12
  72. package/widgets/EodashDatePicker.vue +56 -0
  73. package/widgets/EodashItemFilter.vue +60 -0
  74. package/widgets/EodashMap.vue +82 -0
  75. package/widgets/WidgetsContainer.vue +1 -1
  76. package/core/composables/DefineConfig.js +0 -45
  77. package/core/eodashConfig.js +0 -136
  78. package/core/plugins/router.js +0 -20
  79. package/core/store/Keys.js +0 -6
package/core/types.d.ts CHANGED
@@ -1,279 +1,291 @@
1
- import { useSTAcStore } from "./store/stac"
2
- import type { Router } from "vue-router";
3
- import type { StacCatalog, StacCollection, StacItem } from "stac-ts";
4
- import type { Ref } from "vue"
5
- import type { ThemeDefinition } from "vuetify/lib/index.mjs";
6
- import type { Map } from "openlayers";
7
1
  /**
8
- * Web Component configuration
2
+ * @group Eodash
9
3
  */
10
4
  export interface WebComponentProps<T extends ExecutionTime = "compiletime"> {
11
- /** Web component definition file URL*/
5
+ /**
6
+ * Imports web component file, either using a URL or an import function.
7
+ * @example
8
+ * importing `eox-itemfilter` web component, after installing `@eox/itemfilter` it can be
9
+ * referenced:
10
+ * ```js
11
+ * link: async() => import("@eox/itemfilter")
12
+ * ```
13
+ *
14
+ * ::: warning
15
+ * import maps are not available in runtime config
16
+ * :::
17
+ **/
12
18
  link: T extends 'runtime' ? string : (string | (() => Promise<unknown>));
13
- /** Exported Constructor, needs to be provided if the web component is not registered by the `link` provided */
19
+ /**
20
+ * Exported Constructor, needs to be provided if the web component is not registered in by the
21
+ * [link](#link) provided
22
+ **/
14
23
  constructorProp?: string
15
- /** Custom tag name */
16
24
  tagName: `${string}-${string}`
17
25
  /** Object defining all the properties and attributes of the web component */
18
26
  properties?: Record<string, any>
19
27
  /**
20
- * Function that is triggered when the web component is mounted in the DOM.
28
+ * Triggered when the web component is mounted in the DOM.
21
29
  * @param el - web component
22
30
  * @param store - return value of the core STAC pinia store in `/core/store/stac.ts`
23
31
  */
24
- onMounted?: (el: Element | null, store: ReturnType<typeof useSTAcStore>, router: Router) => (Promise<void> | void)
32
+ onMounted?: (el: Element | null, store: ReturnType<typeof import("./store/stac").useSTAcStore>) => (Promise<void> | void)
25
33
  /**
26
- * Function that is triggered when the web component is unmounted from the DOM.
34
+ * Triggered when the web component is unmounted from the DOM.
27
35
  * @param el - web component
28
36
  * @param store - return value of the core STAC pinia store in `/core/store/stac.ts`
29
37
  */
30
- onUnmounted?: (el: Element | null, store: ReturnType<typeof useSTAcStore>, router: Router) => (Promise<void> | void)
38
+ onUnmounted?: (el: Element | null, store: ReturnType<typeof import("./store/stac").useSTAcStore>) => (Promise<void> | void)
31
39
  }
32
40
 
33
41
 
34
42
  /** @ignore */
35
43
  export interface WidgetsContainerProps {
36
- widgets: Omit<WidgetConfig, 'layout'>[]
44
+ widgets: Omit<Widget, 'layout' | 'slidable'>[]
37
45
  }
38
46
 
39
- // eodash config types:
47
+ // eodash types:
40
48
  /**
41
- * Widget type: `web-component` specification. The web component definition is imported using the `widget.link` property either from
42
- * an external endpoint, or an installed node_module.
43
- * Installed node_module web components import should be mapped in `/core/modulesMap.ts`,
44
- * then setting `widget.link`:`(import-map-key)` and `node_module`:`true`
49
+ * Widget type: `web-component` API
50
+ * @group Eodash
45
51
  */
46
- export interface WebComponentConfig<T extends ExecutionTime = "compiletime"> {
47
- /**
48
- * Unique Identifier, triggers rerender when using `defineWidget`
49
- **/
52
+ export interface WebComponentWidget<T extends ExecutionTime = "compiletime"> {
50
53
  id: number | string | symbol
51
- /**
52
- * Widget title
53
- */
54
54
  title: string
55
55
  /**
56
56
  * Widget position and size.
57
57
  */
58
58
  layout: {
59
59
  /**
60
- * Horizontal start position. Integer (1 - 12)
60
+ * Horizontal start position. Integer between 1 and 12
61
61
  */
62
62
  x: number
63
63
  /**
64
- * Vertical start position. Integer (1 - 12)
64
+ * Vertical start position. Integer between 1 and 12
65
65
  */
66
66
  y: number
67
67
  /**
68
- * Width. Integer (1 - 12)
68
+ * Width. Integer between 1 and 12
69
69
  */
70
70
  w: number
71
71
  /**
72
- * Height. Integer (1 - 12)
72
+ * Height. Integer between 1 and 12
73
73
  */
74
74
  h: number
75
- }
76
- widget: WebComponentProps<T>
75
+ },
77
76
  /**
78
- * Widget type
79
- */
77
+ * Enable/Disable widget sliding.
78
+ */
79
+ slidable?: boolean
80
+ widget: WebComponentProps<T>
80
81
  type: 'web-component'
81
82
  }
82
83
 
83
84
  /**
84
- * Widget type: `internal` specification.
85
- * Internal widgets are Vue components inside the `/widgets` directory.
85
+ * Widget type: `internal` API.
86
+ * Internal widgets are Vue components provided by eodash.
87
+ * @group Eodash
86
88
  */
87
- export interface InternalComponentConfig {
88
- /**
89
- * Unique Identifier, triggers rerender when using `defineWidget`
90
- **/
89
+ export interface InternalComponentWidget {
91
90
  id: number | string | symbol
92
- /**
93
- * Widget title
94
- */
95
91
  title: string
96
92
  /**
97
93
  * Widget position and size.
98
94
  */
99
95
  layout: {
100
96
  /**
101
- * Horizontal start position. Integer (1 - 12)
97
+ * Horizontal start position. Integer between 1 and 12
102
98
  */
103
99
  x: number
104
100
  /**
105
- * Vertical start position. Integer (1 - 12)
101
+ * Vertical start position. Integer between 1 and 12
106
102
  */
107
103
  y: number
108
104
  /**
109
- * Width. Integer (1 - 12)
105
+ * Width. Integer between 1 and 12
110
106
  */
111
107
  w: number
112
108
  /**
113
- * Height. Integer (1 - 12)
109
+ * Height. Integer between 1 and 12
114
110
  */
115
111
  h: number
116
112
  }
113
+ /**
114
+ * Enable/Disable widget sliding.
115
+ */
116
+ slidable?: boolean
117
117
  widget: {
118
118
  /**
119
- * Internal Vue Component file name without the extention .vue
119
+ * Internal Vue Components inside the [widgets](https://github.com/eodash/eodash/tree/main/widgets) folder. Referenced
120
+ * using their name without the .vue extention
120
121
  */
121
122
  name: string;
122
123
  /**
123
124
  * Specified Vue component props
124
125
  */
125
- props?: Record<string, unknown>
126
+ properties?: Record<string, unknown>
126
127
  }
127
- /**
128
- * Widget type.
129
- */
130
128
  type: 'internal'
131
129
  }
132
130
 
133
131
  /**
134
- * Widget type: `iframe` specification.
132
+ * Widget type: `iframe` API
135
133
  * Renders an external HTML file as a widget.
136
134
  */
137
- export interface IFrameConfig {
138
- /**
139
- * Unique Identifier, triggers rerender when using `defineWidget`
140
- **/
135
+ /**
136
+ * @group Eodash
137
+ */
138
+ export interface IFrameWidget {
141
139
  id: number | string | symbol
142
- /**
143
- * Widget title
144
- */
145
140
  title: string
146
141
  /**
147
142
  * Widget position and size.
148
143
  */
149
144
  layout: {
150
145
  /**
151
- * Horizontal start position. Integer (1 - 12)
146
+ * Horizontal start position. Integer between 1 and 12
152
147
  */
153
148
  x: number
154
149
  /**
155
- * Vertical start position. Integer (1 - 12)
150
+ * Vertical start position. Integer between 1 and 12
156
151
  */
157
152
  y: number
158
153
  /**
159
- * Width. Integer (1 - 12)
154
+ * Width. Integer between 1 and 12
160
155
  */
161
156
  w: number
162
157
  /**
163
- * Height. Integer (1 - 12)
158
+ * Height. Integer between 1 and 12
164
159
  */
165
160
  h: number
166
161
  }
162
+ /**
163
+ * Enable/Disable widget sliding.
164
+ */
165
+ slidable?: boolean;
167
166
  widget: {
168
167
  /**
169
168
  * The URL of the page to embed
170
169
  */
171
170
  src: string
172
171
  }
173
- /**
174
- * Widget type
175
- */
176
172
  type: 'iframe'
177
173
  }
174
+ /**
175
+ * @group Eodash
176
+ */
178
177
  export interface FunctionalWidget<T extends ExecutionTime = "compiletime"> {
179
178
  /**
180
179
  * Provides a functional definition of the widget,
181
- * gets triggered whenever a stac object is selected.
182
- * @param selectedSTAC - currently selected stac object
180
+ * gets triggered whenever a STAC object is selected.
181
+ * @param selectedSTAC - Currently selected STAC object
183
182
  */
184
- defineWidget: (selectedSTAC: StacCatalog | StacCollection | StacItem | null) => Omit<StaticWidget<T>, 'layout'>
183
+ defineWidget: (selectedSTAC: import("stac-ts").StacCatalog |
184
+ import("stac-ts").StacCollection | import("stac-ts").StacItem
185
+ | null) => Omit<StaticWidget<T>, 'layout' | 'slidable'>
185
186
  layout: {
186
187
  /**
187
- * Horizontal start position. Integer (1 - 12)
188
+ * Horizontal start position. Integer between 1 and 12
188
189
  */
189
190
  x: number
190
191
  /**
191
- * Vertical start position. Integer (1 - 12)
192
+ * Vertical start position. Integer between 1 and 12
192
193
  */
193
194
  y: number
194
195
  /**
195
- * Width. Integer (1 - 12)
196
+ * Width. Integer between 1 and 12
196
197
  */
197
198
  w: number
198
199
  /**
199
- * Height. Integer (1 - 12)
200
+ * Height. Integer between 1 and 12
200
201
  */
201
202
  h: number
202
203
  }
204
+ /**
205
+ * Enable/Disable widget sliding.
206
+ */
207
+ slidable?: boolean
203
208
  }
204
- export type StaticWidget<T extends ExecutionTime = "compiletime"> = WebComponentConfig<T> | InternalComponentConfig | IFrameConfig
205
- export type WidgetConfig<T extends ExecutionTime = "compiletime"> = StaticWidget<T> | FunctionalWidget<T>
209
+ /**
210
+ * @group Eodash
211
+ */
212
+ export type StaticWidget<T extends ExecutionTime = "compiletime"> = WebComponentWidget<T> | InternalComponentWidget | IFrameWidget
213
+ /**
214
+ * @group Eodash
215
+ */
216
+ export type Widget<T extends ExecutionTime = "compiletime"> = StaticWidget<T> | FunctionalWidget<T>
206
217
 
207
218
 
208
- export type BackgroundWidgetConfig<T extends ExecutionTime = "compiletime"> = Omit<WebComponentConfig<T>, 'layout' | 'title'> | Omit<InternalComponentConfig, 'layout' | 'title'> | Omit<IFrameConfig, 'layout' | 'title'> | Omit<FunctionalWidget, 'layout'>
209
219
  /**
210
- * Dashboard rendered widgets configuration specification.
220
+ * @group Eodash
221
+ */
222
+ export type BackgroundWidget<T extends ExecutionTime = "compiletime"> = Omit<WebComponentWidget<T>, 'layout' | 'title' | 'slidable'> | Omit<InternalComponentWidget, 'layout' | 'title' | 'slidable'> | Omit<IFrameWidget, 'layout' | 'title' | 'slidable'> | Omit<FunctionalWidget<T>, 'layout' | 'slidable'>
223
+ /**
224
+ * Dashboard rendered widgets specification.
211
225
  * 3 types of widgets are supported: `"iframe"`, `"internal"`, and `"web-component"`.
212
- * A specific configuration should be provided based on the type of the widget.
226
+ * A specific object should be provided based on the type of the widget.
227
+ * @group Eodash
213
228
  */
214
- export interface TemplateConfig<T extends ExecutionTime = "compiletime"> {
229
+ export interface Template<T extends ExecutionTime = "compiletime"> {
215
230
  /**
216
231
  * Gap between widgets
217
232
  */
218
233
  gap?: number;
234
+ /**
235
+ * loading widget
236
+ */
237
+ loading?: BackgroundWidget<T>
219
238
  /**
220
239
  * Widget rendered as the dashboard background.
221
- * Has the same specifications of [WidgetConfig](../readme#widgetconfig) without the `title` and `layout` properties
240
+ * Has the same specifications of `Widget` without the `title` and `layout` properties
241
+ * @see {@link Widget}
222
242
  */
223
- background?: BackgroundWidgetConfig<T>
243
+ background?: BackgroundWidget<T>
224
244
  /**
225
245
  * Array of widgets that will be rendered as dashboard panels.
226
246
  */
227
- widgets: WidgetConfig<T>[]
247
+ widgets: Widget<T>[]
228
248
  }
229
249
 
230
- export type ExternalURL = `${'https://' | 'http://'}${string}`;
231
- export type InternalRoute = `/${string}`
250
+ /** @ignore */
232
251
  export type StacEndpoint = `${'https://' | 'http://'}${string}/catalog.json`
233
252
 
253
+ /**
254
+ * @ignore
255
+ * @group Eodash
256
+ */
234
257
  export type ExecutionTime = "runtime" | "compiletime";
235
258
 
236
259
  /**
237
- * Eodash configuration specification.
260
+ * Eodash instance API
261
+ * @group Eodash
238
262
  */
239
- export interface EodashConfig<T extends ExecutionTime = "compiletime"> {
263
+ export interface Eodash<T extends ExecutionTime = "compiletime"> {
240
264
  /**
241
- * Configuration ID that defines the route of the dashboard.
242
- * Rendered dashboard can be accessed on route `/dashboard/config-id`
265
+ * Instance ID.
243
266
  */
244
- id: string;
267
+ id?: string;
245
268
  /**
246
269
  * Root STAC catalog endpoint
247
270
  **/
248
271
  stacEndpoint: StacEndpoint
249
- /**
250
- * Renderes to navigation buttons on the app header.
251
- **/
252
- routes?: Array<{
253
- /**
254
- * button title
255
- **/
256
- title: string,
257
- /**
258
- * external URL or inner path to navigate to.
259
- **/
260
- to: ExternalURL | InternalRoute
261
- }>
262
272
  /**
263
273
  * Brand specifications.
264
274
  */
265
275
  brand: {
276
+ /** Removes the dashboard layout */
277
+ noLayout?: boolean
266
278
  /**
267
- * Automatically fetches the specified font family from google fonts. if the `link` property is specified
279
+ * Automatically fetches the specified font family from google fonts. if the [link](#font-link) property is specified
268
280
  * the font family will be fetched from the provided source instead.
269
281
  */
270
282
  font?: {
271
283
  /**
272
- * Link to stylesheet that defines font-face.
284
+ * Link to stylesheet that defines font-face. Could be either a relative or absolute URL.
273
285
  */
274
286
  link?: string;
275
287
  /**
276
- * Font family. Use FVD notation to include families https://github.com/typekit/fvd
288
+ * Font family. Use FVD notation to include families. see https://github.com/typekit/fvd
277
289
  */
278
290
  family: string
279
291
  }
@@ -282,26 +294,29 @@ export interface EodashConfig<T extends ExecutionTime = "compiletime"> {
282
294
  */
283
295
  name: string;
284
296
  /**
285
- * Alias that will be shown in the app footer if specified.
297
+ * Brand logo
286
298
  */
287
- shortName?: string
299
+ logo?: string;
288
300
  /**
289
- * brand logo
301
+ * Dashboard theme as a custom [vuetifyJs theme](https://vuetifyjs.com/en/features/theme/).
290
302
  */
291
- logo?: string;
303
+ theme?: import("vuetify/lib/index.mjs").ThemeDefinition
292
304
  /**
293
- * Dashboard theme as a custom vuetifyJs theme.
305
+ * Text applied to the footer.
294
306
  */
295
- theme?: ThemeDefinition
307
+ footerText?: string;
296
308
  }
297
309
  /**
298
- * Rendered widgets configuration
310
+ * Template configuration
299
311
  */
300
- template: TemplateConfig<T>
312
+ template: Template<T>
301
313
  }
302
314
  /////////
303
315
 
304
316
  /// eodash store types
317
+ /**
318
+ * @group EodashStore
319
+ */
305
320
  export interface EodashStore {
306
321
  /**
307
322
  * Stateful Reactive variables
@@ -310,22 +325,31 @@ export interface EodashStore {
310
325
  /**
311
326
  * Currently selected STAC endpoint
312
327
  */
313
- currentUrl: Ref<string>
328
+ currentUrl: import("vue").Ref<string>
314
329
  /**
315
- * OpenLayers map instance
330
+ * currently selected datetime
316
331
  */
317
- mapInstance: Ref<Map | null>
332
+ datetime: import("vue").Ref<string>
333
+ /**
334
+ * Currently selected indicator
335
+ */
336
+ indicator: import("vue").Ref<string>
318
337
  }
319
- // consider removing the actions ?
320
- actions: {
321
- loadFont: (family?: string, link?: string) => Promise<string>;
322
- };
338
+ actions: {};
323
339
  /**
324
340
  * Pinia store definition used to navigate the root STAC catalog.
325
341
  */
326
342
  stac: {
327
- useSTAcStore: typeof useSTAcStore
343
+ useSTAcStore: typeof import("./store/stac").useSTAcStore
328
344
  }
329
345
  }
330
346
  ///////
331
- export declare const defineConfig: (configCallback: (store: EodashStore) => EodashConfig | Promise<EodashConfig>) => EodashConfig
347
+ /**
348
+ * the project's entry point should export this function as a default
349
+ * to instantiate eodash
350
+ * @group Eodash
351
+ * @param configCallback
352
+ */
353
+ export declare const createEodash: typeof import("./composables/DefineEodash").createEodash
354
+ /** @group EodashStore */
355
+ export declare const store: EodashStore
@@ -0,0 +1,164 @@
1
+ import { Collection, Item } from 'stac-js';
2
+ import { toAbsolute } from 'stac-js/src/http.js';
3
+ import { generateFeatures } from './helpers'
4
+
5
+ export class EodashCollection {
6
+ /** @type {string | undefined} */
7
+ #collectionUrl = undefined;
8
+ #collectionStac = undefined;
9
+ /** @type {*} */
10
+ selectedItem = null;
11
+
12
+ /**
13
+ * @param {string} collectionUrl
14
+ */
15
+ constructor(collectionUrl) {
16
+ this.#collectionUrl = collectionUrl;
17
+ }
18
+ /**
19
+ * @param {*} item
20
+ * @returns
21
+ * @async
22
+ */
23
+ createLayersJson = async (item = null) => {
24
+ let stacItem, stac;
25
+ // TODO get auxiliary layers from collection
26
+ let layersJson = [
27
+ {
28
+ type: 'Tile',
29
+ properties: {
30
+ id: 'OSM',
31
+ },
32
+ source: {
33
+ type: 'OSM',
34
+ },
35
+ },
36
+ ];
37
+ // Load collectionstac if not yet initialized
38
+ if (!this.#collectionStac) {
39
+ //@ts-expect-error
40
+ const response = await fetch(this.#collectionUrl);
41
+ stac = await response.json();
42
+ this.#collectionStac = new Collection(stac);
43
+ }
44
+
45
+ if(stac && stac.endpointtype === "GeoDB") {
46
+ // Special handling of point based data
47
+ const allFeatures = generateFeatures(stac.links);
48
+ layersJson.unshift({
49
+ type: "Vector",
50
+ properties: {
51
+ id: stac.id,
52
+ },
53
+ source: {
54
+ type: "Vector",
55
+ // @ts-ignore
56
+ url: "data:," + encodeURIComponent(JSON.stringify(allFeatures)),
57
+ format: "GeoJSON",
58
+ },
59
+ style: {
60
+ "circle-radius": 5,
61
+ "circle-fill-color": "#00417077",
62
+ "circle-stroke-color": "#004170",
63
+ "fill-color": "#00417077",
64
+ "stroke-color": "#004170",
65
+ }
66
+ });
67
+ return layersJson;
68
+ } else {
69
+ if (item instanceof Date) {
70
+ // if collectionStac not yet initialized we do it here
71
+ stacItem = this.getItems().sort((a, b) => {
72
+ //@ts-expect-error
73
+ const distanceA = Math.abs(new Date(a.datetime) - item);
74
+ //@ts-expect-error
75
+ const distanceB = Math.abs(new Date(b.datetime) - item);
76
+ return distanceA - distanceB;
77
+ })[0];
78
+ this.selectedItem = stacItem;
79
+ } else {
80
+ stacItem = item;
81
+ }
82
+ const response = await fetch(
83
+ stacItem
84
+ ? toAbsolute(stacItem.href, this.#collectionUrl)
85
+ : this.#collectionUrl
86
+ );
87
+ stac = await response.json();
88
+
89
+ if (!stacItem) {
90
+ // no specific item was requested; render last item
91
+ this.#collectionStac = new Collection(stac);
92
+ const items = this.getItems();
93
+ this.selectedItem = items[items.length - 1];
94
+ layersJson = await this.createLayersJson(this.selectedItem);
95
+ return layersJson;
96
+ } else {
97
+ // specific item was requested
98
+ const item = new Item(stac);
99
+ this.selectedItem = item;
100
+ //@ts-expect-error
101
+ layersJson.unshift(this.buildJson(item));
102
+ return layersJson;
103
+ }
104
+ }
105
+ }
106
+
107
+ /**
108
+ * @param {*} item
109
+ */
110
+ buildJson(item) {
111
+ let json;
112
+ // TODO implement other types, such as COG
113
+ if (/** @type {import('stac-ts').StacLink[]} */(item.links)
114
+ .find((l) => l.rel === 'wms' || l.rel === 'wmts' || l.rel === 'xyz')) {
115
+ json = {
116
+ type: 'STAC',
117
+ displayWebMapLink: true,
118
+ displayFootprint: false,
119
+ data: item,
120
+ properties: {
121
+ id: item.id,
122
+ },
123
+ };
124
+ } else {
125
+ // fall back to rendering the feature
126
+ json = {
127
+ type: 'Vector',
128
+ source: {
129
+ type: 'Vector',
130
+ url: 'data:,' + encodeURIComponent(JSON.stringify(item.geometry)),
131
+ format: 'GeoJSON',
132
+ },
133
+ properties: {
134
+ id: item.id,
135
+ },
136
+ };
137
+ }
138
+
139
+ return json;
140
+ }
141
+
142
+ getItems() {
143
+ return (
144
+ //@ts-expect-error
145
+ // eslint-disable-next-line
146
+ /** @type {import('stac-ts').StacLink[]}*/(this.#collectionStac?.links)
147
+ .filter((i) => i.rel === 'item')
148
+ // sort by `datetime`, where oldest is first in array
149
+ .sort((a, b) => ( /** @type {number} */(a.datetime) < /** @type {number} */(b.datetime) ? -1 : 1))
150
+ );
151
+ }
152
+
153
+ getDates() {
154
+ return (
155
+ //@ts-expect-error
156
+ // eslint-disable-next-line
157
+ /** @type {import('stac-ts').StacLink[]}*/ (this.#collectionStac?.links)
158
+ .filter((i) => i.rel === 'item')
159
+ // sort by `datetime`, where oldest is first in array
160
+ .sort((a, b) => ( /** @type {number} */(a.datetime) < /** @type {number} */(b.datetime) ? -1 : 1))
161
+ .map((i) => new Date( /** @type {number} */(i.datetime)))
162
+ );
163
+ }
164
+ }
@@ -0,0 +1,40 @@
1
+
2
+ /**
3
+ * @param {import("stac-ts").StacLink[]} links
4
+ */
5
+ export function generateFeatures(links) {
6
+ /**
7
+ * @type {{
8
+ * type:string;
9
+ * geometry:{
10
+ * type: string;
11
+ * coordinates: [number, number],
12
+ * }
13
+ * }[]}
14
+ */
15
+ const features = [];
16
+ links.forEach(element => {
17
+ if (element.rel === "item" && "latlng" in element) {
18
+ //@ts-expect-error
19
+ const [lat, lon] = element.latlng.split(",").map((/** @type {string} */it) => Number(it))
20
+ features.push({
21
+ type: 'Feature',
22
+ geometry: {
23
+ type: 'Point',
24
+ coordinates: [lon, lat],
25
+ },
26
+ })
27
+ }
28
+ });
29
+ const geojsonObject = {
30
+ 'type': 'FeatureCollection',
31
+ 'crs': {
32
+ 'type': 'name',
33
+ 'properties': {
34
+ 'name': 'EPSG:4326',
35
+ },
36
+ },
37
+ features,
38
+ };
39
+ return geojsonObject;
40
+ }