ogm-viewer 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{index-CVTUnaNg.js → index-mu9UK_Fb.js} +66 -3
- package/dist/cjs/{lerc-TQEssgMv.js → lerc-Df0hDWkS.js} +7 -7
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/{ogm-image.ogm-map.ogm-menubar.ogm-metadata.ogm-settings.ogm-sidebar.ogm-viewer-ifPxRNEo.js → ogm-alerts.ogm-attributes.ogm-image.ogm-map.ogm-menubar.ogm-metadata.ogm-preview.ogm-previews.ogm-settings.ogm-sidebar.ogm-viewer-DMEfXquS.js} +13843 -6976
- package/dist/cjs/ogm-alerts_11.cjs.entry.js +18 -0
- package/dist/cjs/ogm-viewer.cjs.js +2 -2
- package/dist/collection/assets/icons/exclamation-triangle-fill.svg +3 -0
- package/dist/collection/assets/webawesome/styles/color/palettes/base.css +44 -0
- package/dist/collection/assets/webawesome/styles/color/palettes/bright.css +145 -0
- package/dist/collection/assets/webawesome/styles/color/palettes/default.css +146 -0
- package/dist/collection/assets/webawesome/styles/color/palettes/shoelace.css +146 -0
- package/dist/collection/assets/webawesome/styles/color/variants/brand.css +162 -0
- package/dist/collection/assets/webawesome/styles/color/variants/danger.css +162 -0
- package/dist/collection/assets/webawesome/styles/color/variants/neutral.css +162 -0
- package/dist/collection/assets/webawesome/styles/color/variants/success.css +162 -0
- package/dist/collection/assets/webawesome/styles/color/variants/warning.css +162 -0
- package/dist/collection/assets/webawesome/styles/color/variants.css +5 -0
- package/dist/collection/assets/webawesome/styles/component/form-control.styles.d.ts +2 -0
- package/dist/collection/assets/webawesome/styles/component/form-control.styles.ts +43 -0
- package/dist/collection/assets/webawesome/styles/component/host.styles.d.ts +2 -0
- package/dist/collection/assets/webawesome/styles/component/host.styles.ts +18 -0
- package/dist/collection/assets/webawesome/styles/component/segmented-field.styles.d.ts +19 -0
- package/dist/collection/assets/webawesome/styles/component/segmented-field.styles.ts +92 -0
- package/dist/collection/assets/webawesome/styles/component/size.styles.d.ts +2 -0
- package/dist/collection/assets/webawesome/styles/component/size.styles.ts +26 -0
- package/dist/collection/assets/webawesome/styles/component/variants.styles.d.ts +2 -0
- package/dist/collection/assets/webawesome/styles/component/variants.styles.ts +69 -0
- package/dist/collection/assets/webawesome/styles/component/visually-hidden.styles.d.ts +2 -0
- package/dist/collection/assets/webawesome/styles/component/visually-hidden.styles.ts +19 -0
- package/dist/collection/assets/webawesome/styles/layers.css +21 -0
- package/dist/collection/assets/webawesome/styles/native.css +1439 -0
- package/dist/collection/assets/webawesome/styles/themes/awesome.css +614 -0
- package/dist/collection/assets/webawesome/styles/themes/default.css +373 -0
- package/dist/collection/assets/webawesome/styles/themes/shoelace.css +648 -0
- package/dist/collection/assets/webawesome/styles/utilities/align-items.css +44 -0
- package/dist/collection/assets/webawesome/styles/utilities/border-radius.css +20 -0
- package/dist/collection/assets/webawesome/styles/utilities/flex-wrap.css +16 -0
- package/dist/collection/assets/webawesome/styles/utilities/fouce.css +17 -0
- package/dist/collection/assets/webawesome/styles/utilities/gap.css +56 -0
- package/dist/collection/assets/webawesome/styles/utilities/justify-content.css +32 -0
- package/dist/collection/assets/webawesome/styles/utilities/layout.css +159 -0
- package/dist/collection/assets/webawesome/styles/utilities/placeholder.css +9 -0
- package/dist/collection/assets/webawesome/styles/utilities/prose.css +161 -0
- package/dist/collection/assets/webawesome/styles/utilities/scroll-lock.css +20 -0
- package/dist/collection/assets/webawesome/styles/utilities/size.css +21 -0
- package/dist/collection/assets/webawesome/styles/utilities/text.css +262 -0
- package/dist/collection/assets/webawesome/styles/utilities/variants.css +62 -0
- package/dist/collection/assets/webawesome/styles/utilities/visually-hidden.css +17 -0
- package/dist/collection/assets/webawesome/styles/utilities.css +17 -0
- package/dist/collection/assets/webawesome/styles/webawesome.css +11 -0
- package/dist/collection/collection-manifest.json +4 -0
- package/dist/collection/components/ogm-alerts/ogm-alerts.css +51 -0
- package/dist/collection/components/ogm-alerts/ogm-alerts.js +71 -0
- package/dist/collection/components/ogm-alerts/ogm-alerts.test.js +26 -0
- package/dist/collection/components/ogm-attributes/ogm-attributes.css +68 -0
- package/dist/collection/components/ogm-attributes/ogm-attributes.js +112 -0
- package/dist/collection/components/ogm-image/ogm-image.css +1 -1
- package/dist/collection/components/ogm-image/ogm-image.js +70 -20
- package/dist/collection/components/ogm-map/ogm-map.css +43 -44
- package/dist/collection/components/ogm-map/ogm-map.js +229 -91
- package/dist/collection/components/ogm-menubar/ogm-menubar.css +16 -14
- package/dist/collection/components/ogm-menubar/ogm-menubar.js +3 -5
- package/dist/collection/components/ogm-menubar/ogm-menubar.test.js +28 -3
- package/dist/collection/components/ogm-metadata/ogm-metadata.css +6 -492
- package/dist/collection/components/ogm-metadata/ogm-metadata.js +3 -5
- package/dist/collection/components/ogm-metadata/ogm-metadata.test.js +1 -1
- package/dist/collection/components/ogm-preview/ogm-preview.css +16 -0
- package/dist/collection/components/ogm-preview/ogm-preview.js +144 -0
- package/dist/collection/components/ogm-preview/ogm-preview.test.js +37 -0
- package/dist/collection/components/ogm-previews/ogm-previews.css +45 -0
- package/dist/collection/components/ogm-previews/ogm-previews.js +162 -0
- package/dist/collection/components/ogm-previews/ogm-previews.test.js +83 -0
- package/dist/collection/components/ogm-settings/ogm-settings.js +7 -9
- package/dist/collection/components/ogm-sidebar/ogm-sidebar.css +50 -503
- package/dist/collection/components/ogm-sidebar/ogm-sidebar.js +8 -12
- package/dist/collection/components/ogm-viewer/ogm-viewer.css +4 -974
- package/dist/collection/components/ogm-viewer/ogm-viewer.js +69 -32
- package/dist/collection/lib/errors.js +137 -0
- package/dist/collection/lib/errors.test.js +96 -0
- package/dist/collection/lib/previewers/cog-deck.js +14 -9
- package/dist/collection/lib/previewers/cog.js +3 -3
- package/dist/collection/lib/previewers/geojson.js +3 -2
- package/dist/collection/lib/previewers/maplibre.js +9 -15
- package/dist/collection/lib/previewers/pmtiles-raster.js +1 -1
- package/dist/collection/lib/previewers/pmtiles-vector.js +7 -1
- package/dist/collection/lib/previewers/raster.js +1 -1
- package/dist/collection/lib/previewers/vector.js +65 -30
- package/dist/collection/lib/previewers/wms.js +1 -1
- package/dist/collection/lib/record.js +1 -1
- package/dist/collection/lib/record.test.js +1 -1
- package/dist/collection/lib/references.js +0 -65
- package/dist/collection/lib/references.test.js +0 -150
- package/dist/collection/lib/sources/cog.js +5 -2
- package/dist/collection/lib/sources/geojson.js +9 -2
- package/dist/collection/lib/sources/iiif-manifest.js +54 -0
- package/dist/collection/lib/sources/iiif-manifest.test.js +110 -0
- package/dist/collection/lib/sources/iiif.js +11 -0
- package/dist/collection/lib/sources/maplibre.js +8 -0
- package/dist/collection/lib/sources/openindexmap.js +3 -0
- package/dist/collection/lib/sources/pmtiles.js +10 -4
- package/dist/collection/lib/sources/raster.js +3 -3
- package/dist/collection/lib/sources/source.js +26 -7
- package/dist/collection/lib/sources/tilejson.js +7 -1
- package/dist/collection/lib/sources/tms.js +3 -0
- package/dist/collection/lib/sources/vector.js +3 -3
- package/dist/collection/lib/sources/wms.js +6 -11
- package/dist/collection/lib/sources/xyz.js +3 -0
- package/dist/collection/lib/themes/maplibre.js +46 -0
- package/dist/collection/lib/themes/theme.js +23 -0
- package/dist/esm/{index-BdFT_kJa.js → index-DTLAlWKQ.js} +66 -3
- package/dist/esm/{lerc-DFDScDrO.js → lerc-CB_Jcu33.js} +2 -2
- package/dist/esm/loader.js +3 -3
- package/dist/esm/{ogm-image.ogm-map.ogm-menubar.ogm-metadata.ogm-settings.ogm-sidebar.ogm-viewer-r5w_49n3.js → ogm-alerts.ogm-attributes.ogm-image.ogm-map.ogm-menubar.ogm-metadata.ogm-preview.ogm-previews.ogm-settings.ogm-sidebar.ogm-viewer-Dlc6USWB.js} +13840 -6977
- package/dist/esm/ogm-alerts_11.entry.js +2 -0
- package/dist/esm/ogm-viewer.js +3 -3
- package/dist/ogm-viewer/assets/icons/exclamation-triangle-fill.svg +3 -0
- package/dist/ogm-viewer/assets/webawesome/styles/color/palettes/base.css +44 -0
- package/dist/ogm-viewer/assets/webawesome/styles/color/palettes/bright.css +145 -0
- package/dist/ogm-viewer/assets/webawesome/styles/color/palettes/default.css +146 -0
- package/dist/ogm-viewer/assets/webawesome/styles/color/palettes/shoelace.css +146 -0
- package/dist/ogm-viewer/assets/webawesome/styles/color/variants/brand.css +162 -0
- package/dist/ogm-viewer/assets/webawesome/styles/color/variants/danger.css +162 -0
- package/dist/ogm-viewer/assets/webawesome/styles/color/variants/neutral.css +162 -0
- package/dist/ogm-viewer/assets/webawesome/styles/color/variants/success.css +162 -0
- package/dist/ogm-viewer/assets/webawesome/styles/color/variants/warning.css +162 -0
- package/dist/ogm-viewer/assets/webawesome/styles/color/variants.css +5 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/form-control.styles.d.ts +2 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/form-control.styles.ts +43 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/host.styles.d.ts +2 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/host.styles.ts +18 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/segmented-field.styles.d.ts +19 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/segmented-field.styles.ts +92 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/size.styles.d.ts +2 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/size.styles.ts +26 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/variants.styles.d.ts +2 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/variants.styles.ts +69 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/visually-hidden.styles.d.ts +2 -0
- package/dist/ogm-viewer/assets/webawesome/styles/component/visually-hidden.styles.ts +19 -0
- package/dist/ogm-viewer/assets/webawesome/styles/layers.css +21 -0
- package/dist/ogm-viewer/assets/webawesome/styles/native.css +1439 -0
- package/dist/ogm-viewer/assets/webawesome/styles/themes/awesome.css +614 -0
- package/dist/ogm-viewer/assets/webawesome/styles/themes/default.css +373 -0
- package/dist/ogm-viewer/assets/webawesome/styles/themes/shoelace.css +648 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/align-items.css +44 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/border-radius.css +20 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/flex-wrap.css +16 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/fouce.css +17 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/gap.css +56 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/justify-content.css +32 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/layout.css +159 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/placeholder.css +9 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/prose.css +161 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/scroll-lock.css +20 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/size.css +21 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/text.css +262 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/variants.css +62 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities/visually-hidden.css +17 -0
- package/dist/ogm-viewer/assets/webawesome/styles/utilities.css +17 -0
- package/dist/ogm-viewer/assets/webawesome/styles/webawesome.css +11 -0
- package/dist/ogm-viewer/ogm-viewer.esm.js +1 -1
- package/dist/ogm-viewer/p-7936ccc9.entry.js +1 -0
- package/dist/ogm-viewer/p-CWtUrqsM.js +2822 -0
- package/dist/ogm-viewer/p-DTLAlWKQ.js +2 -0
- package/dist/ogm-viewer/{p-BeA3REDA.js → p-DqRDI3AC.js} +1 -1
- package/dist/types/components/ogm-alerts/ogm-alerts.d.ts +6 -0
- package/dist/types/components/ogm-alerts/ogm-alerts.test.d.ts +1 -0
- package/dist/types/components/ogm-attributes/ogm-attributes.d.ts +10 -0
- package/dist/types/components/ogm-image/ogm-image.d.ts +8 -3
- package/dist/types/components/ogm-map/ogm-map.d.ts +38 -14
- package/dist/types/components/ogm-menubar/ogm-menubar.d.ts +1 -1
- package/dist/types/components/ogm-metadata/ogm-metadata.d.ts +1 -1
- package/dist/types/components/ogm-preview/ogm-preview.d.ts +13 -0
- package/dist/types/components/ogm-preview/ogm-preview.test.d.ts +1 -0
- package/dist/types/components/ogm-previews/ogm-previews.d.ts +12 -0
- package/dist/types/components/ogm-previews/ogm-previews.test.d.ts +1 -0
- package/dist/types/components/ogm-settings/ogm-settings.d.ts +2 -2
- package/dist/types/components/ogm-sidebar/ogm-sidebar.d.ts +1 -1
- package/dist/types/components/ogm-viewer/ogm-viewer.d.ts +17 -14
- package/dist/types/components.d.ts +122 -18
- package/dist/types/lib/errors.d.ts +13 -0
- package/dist/types/lib/errors.test.d.ts +1 -0
- package/dist/types/lib/previewers/cog-deck.d.ts +7 -3
- package/dist/types/lib/previewers/cog.d.ts +2 -2
- package/dist/types/lib/previewers/maplibre.d.ts +7 -9
- package/dist/types/lib/previewers/pmtiles-vector.d.ts +1 -0
- package/dist/types/lib/previewers/vector.d.ts +3 -15
- package/dist/types/lib/record.d.ts +1 -1
- package/dist/types/lib/references.d.ts +0 -8
- package/dist/types/lib/sources/cog.d.ts +3 -2
- package/dist/types/lib/sources/geojson.d.ts +3 -2
- package/dist/types/lib/sources/iiif-manifest.d.ts +12 -0
- package/dist/types/lib/sources/iiif-manifest.test.d.ts +1 -0
- package/dist/types/lib/sources/iiif.d.ts +5 -0
- package/dist/types/lib/sources/maplibre.d.ts +7 -0
- package/dist/types/lib/sources/openindexmap.d.ts +1 -0
- package/dist/types/lib/sources/pmtiles.d.ts +6 -4
- package/dist/types/lib/sources/raster.d.ts +3 -3
- package/dist/types/lib/sources/source.d.ts +7 -7
- package/dist/types/lib/sources/tilejson.d.ts +3 -2
- package/dist/types/lib/sources/tms.d.ts +1 -0
- package/dist/types/lib/sources/vector.d.ts +4 -5
- package/dist/types/lib/sources/wms.d.ts +4 -3
- package/dist/types/lib/sources/xyz.d.ts +1 -0
- package/dist/types/lib/themes/maplibre.d.ts +27 -0
- package/dist/types/lib/themes/theme.d.ts +7 -0
- package/package.json +3 -2
- package/dist/cjs/ogm-image_7.cjs.entry.js +0 -14
- package/dist/collection/lib/previewers/index.js +0 -36
- package/dist/collection/lib/sources/index.js +0 -29
- package/dist/esm/ogm-image_7.entry.js +0 -2
- package/dist/ogm-viewer/p-0b81e024.entry.js +0 -1
- package/dist/ogm-viewer/p-33R3d9fV.js +0 -1950
- package/dist/ogm-viewer/p-BdFT_kJa.js +0 -2
- package/dist/types/lib/previewers/index.d.ts +0 -3
- package/dist/types/lib/sources/index.d.ts +0 -3
|
@@ -1,27 +1,51 @@
|
|
|
1
|
-
import { setBasePath } from "@
|
|
2
|
-
import { getAssetPath, h } from "@stencil/core";
|
|
3
|
-
import
|
|
1
|
+
import { setBasePath, getBasePath, registerIconLibrary } from "@awesome.me/webawesome";
|
|
2
|
+
import { Host, getAssetPath, h } from "@stencil/core";
|
|
3
|
+
import OgmRecord from "../../lib/record";
|
|
4
|
+
import { fetchOrThrow, recordError } from "../../lib/errors";
|
|
4
5
|
// Only need to call this once, at the top level
|
|
5
6
|
setBasePath(getAssetPath(''));
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
// Serve icons from our self-hosted bootstrap-icons subset instead of the default Font Awesome library
|
|
8
|
+
registerIconLibrary('default', {
|
|
9
|
+
resolver: name => getBasePath(`assets/icons/${name}.svg`),
|
|
10
|
+
});
|
|
11
|
+
// Web Awesome's raw color palette is scoped to `:root`, which can only ever match the actual
|
|
12
|
+
// document root - never an element inside a shadow tree, so a component-scoped @import can't
|
|
13
|
+
// activate it. Loading it here, at the document level, lets it match `:root` for real, and lets
|
|
14
|
+
// its `.wa-light`/`.wa-dark` theme rules match Host element in each component because that element
|
|
15
|
+
// is part of the page light DOM and not the shadow DOM. Injecting it here means consumers
|
|
16
|
+
// don't have to remember to add it to their own page.
|
|
17
|
+
function loadWebAwesomeStylesheet() {
|
|
18
|
+
const id = 'ogm-viewer-webawesome-styles';
|
|
19
|
+
if (document.getElementById(id))
|
|
20
|
+
return;
|
|
21
|
+
const link = document.createElement('link');
|
|
22
|
+
link.id = id;
|
|
23
|
+
link.rel = 'stylesheet';
|
|
24
|
+
link.href = getBasePath('assets/webawesome/styles/webawesome.css');
|
|
25
|
+
document.head.appendChild(link);
|
|
26
|
+
}
|
|
27
|
+
loadWebAwesomeStylesheet();
|
|
28
|
+
// Import all required Web Awesome components
|
|
29
|
+
import "@awesome.me/webawesome/dist/components/button/button.js";
|
|
30
|
+
import "@awesome.me/webawesome/dist/components/callout/callout.js";
|
|
31
|
+
import "@awesome.me/webawesome/dist/components/icon/icon.js";
|
|
32
|
+
import "@awesome.me/webawesome/dist/components/scroller/scroller.js";
|
|
33
|
+
import "@awesome.me/webawesome/dist/components/slider/slider.js";
|
|
34
|
+
import "@awesome.me/webawesome/dist/components/spinner/spinner.js";
|
|
35
|
+
import "@awesome.me/webawesome/dist/components/tab-group/tab-group.js";
|
|
36
|
+
import "@awesome.me/webawesome/dist/components/tab-panel/tab-panel.js";
|
|
37
|
+
import "@awesome.me/webawesome/dist/components/tab/tab.js";
|
|
38
|
+
import "@awesome.me/webawesome/dist/components/tooltip/tooltip.js";
|
|
17
39
|
export class OgmViewer {
|
|
18
40
|
el;
|
|
19
41
|
recordUrl;
|
|
20
42
|
theme = this.getThemePreference();
|
|
21
43
|
record;
|
|
44
|
+
error;
|
|
22
45
|
previewOpacity = 100;
|
|
23
46
|
sidebarOpen = false;
|
|
24
47
|
loading = false;
|
|
48
|
+
loadingCount = 0;
|
|
25
49
|
sidebarPadding = 0;
|
|
26
50
|
// Prior to rendering, fetch the record if a URL is provided
|
|
27
51
|
async componentWillLoad() {
|
|
@@ -43,34 +67,44 @@ export class OgmViewer {
|
|
|
43
67
|
}
|
|
44
68
|
// Can be called externally to set the record directly
|
|
45
69
|
async loadRecord(record) {
|
|
70
|
+
this.error = undefined;
|
|
46
71
|
this.record = record;
|
|
47
72
|
}
|
|
48
73
|
// Listen for opacity changes from the sidebar and adjust the preview layer
|
|
49
74
|
adjustPreviewOpacity(event) {
|
|
50
75
|
this.previewOpacity = event.detail;
|
|
51
76
|
}
|
|
52
|
-
// Listen for
|
|
77
|
+
// Listen for a preview to report loading started
|
|
53
78
|
setLoadingStarted() {
|
|
79
|
+
this.loadingCount++;
|
|
54
80
|
this.loading = true;
|
|
55
81
|
}
|
|
56
|
-
//
|
|
82
|
+
// When all in-flight previews have loaded, clear loading state
|
|
57
83
|
setLoadingFinished() {
|
|
84
|
+
this.loadingCount = Math.max(0, this.loadingCount - 1);
|
|
85
|
+
this.loading = this.loadingCount > 0;
|
|
86
|
+
}
|
|
87
|
+
// When a new record loads, reset the loading count and loading state
|
|
88
|
+
resetLoading() {
|
|
89
|
+
this.loadingCount = 0;
|
|
58
90
|
this.loading = false;
|
|
59
91
|
}
|
|
60
|
-
// Fetch a record by URL and parse it into an OgmRecord instance
|
|
92
|
+
// Fetch a record by URL and parse it into an OgmRecord instance.
|
|
61
93
|
async fetchRecord(recordUrl) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
94
|
+
this.error = undefined;
|
|
95
|
+
try {
|
|
96
|
+
const response = await fetchOrThrow(recordUrl);
|
|
97
|
+
const data = await response.json();
|
|
98
|
+
return new OgmRecord(data);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error(`Error loading record ${recordUrl}:`, error);
|
|
102
|
+
this.error = recordError(error, recordUrl);
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
71
105
|
}
|
|
72
106
|
render() {
|
|
73
|
-
return (h(
|
|
107
|
+
return (h(Host, { key: '6fae950d74eac18eca8192c3ab22d27cde8f8215', class: `wa-${this.theme}` }, h("div", { key: 'ddaf990f2145b165c24ded5272ec3f0f11d32df1', class: "container" }, h("ogm-menubar", { key: '93de36998fdfe07aaea28ee1d32512d129402ae6', theme: this.theme, record: this.record, loading: this.loading }), h("div", { key: 'cafd7e0862a8c39008caee372da2e79b48df2aec', class: "main-container" }, h("ogm-sidebar", { key: '03b5f864d35a385de6941f3eac9b1da050422eb9', theme: this.theme, record: this.record, open: this.sidebarOpen }), this.error ? (h("ogm-alerts", { theme: this.theme, error: this.error })) : (h("ogm-previews", { theme: this.theme, record: this.record, "preview-opacity": this.previewOpacity, "sidebar-padding": this.sidebarPadding }))))));
|
|
74
108
|
}
|
|
75
109
|
static get is() { return "ogm-viewer"; }
|
|
76
110
|
static get encapsulation() { return "shadow"; }
|
|
@@ -130,8 +164,10 @@ export class OgmViewer {
|
|
|
130
164
|
static get states() {
|
|
131
165
|
return {
|
|
132
166
|
"record": {},
|
|
167
|
+
"error": {},
|
|
133
168
|
"previewOpacity": {},
|
|
134
|
-
"sidebarOpen": {}
|
|
169
|
+
"sidebarOpen": {},
|
|
170
|
+
"loading": {}
|
|
135
171
|
};
|
|
136
172
|
}
|
|
137
173
|
static get methods() {
|
|
@@ -150,10 +186,8 @@ export class OgmViewer {
|
|
|
150
186
|
"id": "global::Promise"
|
|
151
187
|
},
|
|
152
188
|
"OgmRecord": {
|
|
153
|
-
"location": "
|
|
154
|
-
"
|
|
155
|
-
"id": "src/lib/record.ts::OgmRecord",
|
|
156
|
-
"referenceLocation": "OgmRecord"
|
|
189
|
+
"location": "global",
|
|
190
|
+
"id": "global::OgmRecord"
|
|
157
191
|
}
|
|
158
192
|
},
|
|
159
193
|
"return": "Promise<void>"
|
|
@@ -170,6 +204,9 @@ export class OgmViewer {
|
|
|
170
204
|
return [{
|
|
171
205
|
"propName": "recordUrl",
|
|
172
206
|
"methodName": "updateRecord"
|
|
207
|
+
}, {
|
|
208
|
+
"propName": "record",
|
|
209
|
+
"methodName": "resetLoading"
|
|
173
210
|
}];
|
|
174
211
|
}
|
|
175
212
|
static get listeners() {
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// Supertype for errors thrown inside ogm-viewer. `message` is inherited from Error; redeclaring it
|
|
2
|
+
// here would emit an uninitialized class field that clobbers the value super() sets (under the
|
|
3
|
+
// es2022 define-fields semantics this project compiles with), leaving every subtype's message empty.
|
|
4
|
+
export class PreviewError extends Error {
|
|
5
|
+
title;
|
|
6
|
+
url;
|
|
7
|
+
}
|
|
8
|
+
// The OGM record URL responded with a non-OK HTTP status.
|
|
9
|
+
class RecordLoadError extends PreviewError {
|
|
10
|
+
title = "This record couldn't be loaded";
|
|
11
|
+
constructor(status, url) {
|
|
12
|
+
super(`The record URL responded with an error (HTTP ${status}). Check that the URL is correct and the record is publicly available.`);
|
|
13
|
+
this.url = url;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// The OGM record URL fetch failed due to a network error or CORS restriction.
|
|
17
|
+
class RecordNetworkError extends PreviewError {
|
|
18
|
+
title = "This record couldn't be reached";
|
|
19
|
+
constructor(url) {
|
|
20
|
+
super('The server may be unreachable, or it may be blocking cross-origin (CORS) requests from this page.');
|
|
21
|
+
this.url = url;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// The OGM record couldn't be parsed as JSON.
|
|
25
|
+
class RecordParseError extends PreviewError {
|
|
26
|
+
title = "This record couldn't be parsed";
|
|
27
|
+
constructor(url) {
|
|
28
|
+
super("The record URL didn't return valid JSON metadata. It may be pointing at an HTML page or a malformed file.");
|
|
29
|
+
this.url = url;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Something else went wrong reading the record.
|
|
33
|
+
class RecordReadError extends PreviewError {
|
|
34
|
+
title = "This record couldn't be read";
|
|
35
|
+
constructor(message, url) {
|
|
36
|
+
super(message);
|
|
37
|
+
this.url = url;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// The reference URL responded with a non-OK HTTP status.
|
|
41
|
+
class ReferenceLoadError extends PreviewError {
|
|
42
|
+
constructor(refType, status, url) {
|
|
43
|
+
super(`The reference URL responded with an error (HTTP ${status}). Check that the URL is correct and the reference is publicly available.`);
|
|
44
|
+
this.title = `The ${refType} preview couldn't be loaded`;
|
|
45
|
+
this.url = url;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// The reference URL fetch failed due to a network error or CORS restriction.
|
|
49
|
+
class ReferenceNetworkError extends PreviewError {
|
|
50
|
+
constructor(refType, url) {
|
|
51
|
+
super('The server may be unreachable, or it may be blocking cross-origin (CORS) requests from this page.');
|
|
52
|
+
this.title = `The ${refType} preview couldn't be reached`;
|
|
53
|
+
this.url = url;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Something else went wrong reading the reference.
|
|
57
|
+
class ReferenceReadError extends PreviewError {
|
|
58
|
+
constructor(refType, message, url) {
|
|
59
|
+
super(message);
|
|
60
|
+
this.title = `The ${refType} preview couldn't be read`;
|
|
61
|
+
this.url = url;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Used to re-raise HTTP responses from fetch() with a non-OK status as PreviewErrors
|
|
65
|
+
export class HttpError extends Error {
|
|
66
|
+
status;
|
|
67
|
+
statusText;
|
|
68
|
+
url;
|
|
69
|
+
constructor(url, status, statusText) {
|
|
70
|
+
super(`HTTP ${status} ${statusText} for ${url}`);
|
|
71
|
+
this.name = 'HttpError';
|
|
72
|
+
this.status = status;
|
|
73
|
+
this.statusText = statusText;
|
|
74
|
+
this.url = url;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Execute a fetch() and raise HttpError on non-OK status
|
|
78
|
+
export async function fetchOrThrow(url, init) {
|
|
79
|
+
const response = await fetch(url, init);
|
|
80
|
+
if (!response.ok)
|
|
81
|
+
throw new HttpError(url, response.status, response.statusText);
|
|
82
|
+
return response;
|
|
83
|
+
}
|
|
84
|
+
// Attempt to get a useful HTTP status code from any error. We only keep values
|
|
85
|
+
// over 400 because MapLibre uses code "0", which isn't a real HTTP status.
|
|
86
|
+
function statusOf(error) {
|
|
87
|
+
if (error instanceof HttpError)
|
|
88
|
+
return error.status;
|
|
89
|
+
const status = error?.status;
|
|
90
|
+
return typeof status === 'number' && status >= 400 ? status : undefined;
|
|
91
|
+
}
|
|
92
|
+
// A fetch() failure to reach the server at all, or a CORS block, rejects with a TypeError. MapLibre
|
|
93
|
+
// reports the same class of failure on its internal tile/data requests with a synthetic status of 0
|
|
94
|
+
// (not a real HTTP status). Treat both as a network error so the user sees the unreachable/CORS
|
|
95
|
+
// message rather than a generic read error or a nonsensical "HTTP 0".
|
|
96
|
+
function isNetworkError(error) {
|
|
97
|
+
if (error instanceof TypeError)
|
|
98
|
+
return true;
|
|
99
|
+
return error?.status === 0;
|
|
100
|
+
}
|
|
101
|
+
// Attempt get a useful message from any error.
|
|
102
|
+
function messageOf(error) {
|
|
103
|
+
if (error instanceof Error)
|
|
104
|
+
return error.message;
|
|
105
|
+
if (typeof error === 'string')
|
|
106
|
+
return error;
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
// Generate a PreviewError when something went wrong loading the record.
|
|
110
|
+
export function recordError(error, url) {
|
|
111
|
+
const status = statusOf(error);
|
|
112
|
+
const message = messageOf(error);
|
|
113
|
+
// The request failed to reach the server at all, or was blocked by CORS.
|
|
114
|
+
if (isNetworkError(error))
|
|
115
|
+
return new RecordNetworkError(url);
|
|
116
|
+
// If we have an HTTP status code, the server responded.
|
|
117
|
+
if (status !== undefined)
|
|
118
|
+
return new RecordLoadError(status, url);
|
|
119
|
+
// A SyntaxError here means we got a response but it wasn't valid JSON metadata.
|
|
120
|
+
if (error instanceof SyntaxError)
|
|
121
|
+
return new RecordParseError(url);
|
|
122
|
+
// Anything else (e.g. an unsupported metadata version thrown by OgmRecord's constructor).
|
|
123
|
+
return new RecordReadError(message ?? 'An unknown error occurred while reading this record.', url);
|
|
124
|
+
}
|
|
125
|
+
// Generate a PreviewError when something went wrong loading an individual reference.
|
|
126
|
+
export function referenceError(error, refType, url) {
|
|
127
|
+
const status = statusOf(error);
|
|
128
|
+
const message = messageOf(error);
|
|
129
|
+
// The request failed to reach the server at all, or was blocked by CORS.
|
|
130
|
+
if (isNetworkError(error))
|
|
131
|
+
return new ReferenceNetworkError(refType, url);
|
|
132
|
+
// If we have an HTTP status code, the server responded.
|
|
133
|
+
if (status !== undefined)
|
|
134
|
+
return new ReferenceLoadError(refType, status, url);
|
|
135
|
+
// Anything else.
|
|
136
|
+
return new ReferenceReadError(refType, message ?? 'An unknown error occurred while reading this reference.', url);
|
|
137
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { describe, it, expect, vi, afterEach } from "@stencil/vitest";
|
|
2
|
+
import { HttpError, PreviewError, fetchOrThrow, recordError, referenceError } from "./errors";
|
|
3
|
+
describe('errors', () => {
|
|
4
|
+
afterEach(() => vi.restoreAllMocks());
|
|
5
|
+
describe('HttpError', () => {
|
|
6
|
+
it('captures the status, statusText, and url', () => {
|
|
7
|
+
const error = new HttpError('http://example.com/x', 404, 'Not Found');
|
|
8
|
+
expect(error).toBeInstanceOf(Error);
|
|
9
|
+
expect(error.name).toBe('HttpError');
|
|
10
|
+
expect(error.status).toBe(404);
|
|
11
|
+
expect(error.statusText).toBe('Not Found');
|
|
12
|
+
expect(error.url).toBe('http://example.com/x');
|
|
13
|
+
expect(error.message).toContain('404');
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
describe('fetchOrThrow', () => {
|
|
17
|
+
it('returns the response when the status is ok', async () => {
|
|
18
|
+
const response = new Response('{}', { status: 200 });
|
|
19
|
+
vi.spyOn(global, 'fetch').mockResolvedValueOnce(response);
|
|
20
|
+
await expect(fetchOrThrow('http://example.com/ok')).resolves.toBe(response);
|
|
21
|
+
});
|
|
22
|
+
it('throws an HttpError when the status is not ok', async () => {
|
|
23
|
+
vi.spyOn(global, 'fetch').mockResolvedValueOnce(new Response('nope', { status: 500, statusText: 'Server Error' }));
|
|
24
|
+
await expect(fetchOrThrow('http://example.com/bad')).rejects.toMatchObject({ name: 'HttpError', status: 500, url: 'http://example.com/bad' });
|
|
25
|
+
});
|
|
26
|
+
it('propagates a network error (TypeError) unchanged', async () => {
|
|
27
|
+
const networkError = new TypeError('Failed to fetch');
|
|
28
|
+
vi.spyOn(global, 'fetch').mockRejectedValueOnce(networkError);
|
|
29
|
+
await expect(fetchOrThrow('http://example.com/cors')).rejects.toBe(networkError);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe('recordError', () => {
|
|
33
|
+
it('always returns a PreviewError (and therefore an Error), carrying a usable message', () => {
|
|
34
|
+
const error = recordError(new Error('boom'), 'http://example.com/r');
|
|
35
|
+
expect(error).toBeInstanceOf(PreviewError);
|
|
36
|
+
expect(error).toBeInstanceOf(Error);
|
|
37
|
+
// Guards the class-field pitfall where redeclaring `message` blanks the value super() sets.
|
|
38
|
+
expect(error.message).toBeTruthy();
|
|
39
|
+
});
|
|
40
|
+
it('classifies an HttpError as an HTTP load error and includes the status', () => {
|
|
41
|
+
const error = recordError(new HttpError('http://example.com/r', 403, 'Forbidden'), 'http://example.com/r');
|
|
42
|
+
expect(error.title).toBe("This record couldn't be loaded");
|
|
43
|
+
expect(error.message).toContain('403');
|
|
44
|
+
expect(error.url).toBe('http://example.com/r');
|
|
45
|
+
});
|
|
46
|
+
it('classifies a SyntaxError as a parse error', () => {
|
|
47
|
+
const error = recordError(new SyntaxError('Unexpected token < in JSON'), 'http://example.com/r');
|
|
48
|
+
expect(error.title).toBe("This record couldn't be parsed");
|
|
49
|
+
expect(error.message).toMatch(/JSON/);
|
|
50
|
+
});
|
|
51
|
+
it('classifies a fetch TypeError as a network/CORS error', () => {
|
|
52
|
+
const error = recordError(new TypeError('Failed to fetch'), 'http://example.com/r');
|
|
53
|
+
expect(error.title).toBe("This record couldn't be reached");
|
|
54
|
+
expect(error.message).toMatch(/CORS/);
|
|
55
|
+
});
|
|
56
|
+
it('falls back to a read error for other failures (e.g. an unsupported metadata version)', () => {
|
|
57
|
+
const error = recordError(new Error('Unsupported metadata version: GeoBlacklight'), 'http://example.com/r');
|
|
58
|
+
expect(error.title).toBe("This record couldn't be read");
|
|
59
|
+
expect(error.message).toContain('Unsupported metadata version');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe('referenceError', () => {
|
|
63
|
+
it('names the source in the title and keeps the url', () => {
|
|
64
|
+
const error = referenceError(new TypeError('Failed to fetch'), 'GeoJSON', 'http://example.com/data.json');
|
|
65
|
+
expect(error).toBeInstanceOf(PreviewError);
|
|
66
|
+
expect(error.title).toContain('GeoJSON');
|
|
67
|
+
expect(error.url).toBe('http://example.com/data.json');
|
|
68
|
+
});
|
|
69
|
+
it('classifies an HttpError as an HTTP load error', () => {
|
|
70
|
+
const error = referenceError(new HttpError('http://example.com/wms', 502, 'Bad Gateway'), 'WMS');
|
|
71
|
+
expect(error.title).toBe("The WMS preview couldn't be loaded");
|
|
72
|
+
expect(error.message).toContain('502');
|
|
73
|
+
});
|
|
74
|
+
it('reads a numeric status off a library error object (e.g. MapLibre AjaxError)', () => {
|
|
75
|
+
const error = referenceError({ status: 404, message: 'not found' }, 'XYZ tiles');
|
|
76
|
+
expect(error.title).toBe("The XYZ tiles preview couldn't be loaded");
|
|
77
|
+
expect(error.message).toContain('404');
|
|
78
|
+
});
|
|
79
|
+
it('classifies a fetch TypeError as a network/CORS error', () => {
|
|
80
|
+
const error = referenceError(new TypeError('Failed to fetch'), 'IIIF Image');
|
|
81
|
+
expect(error.title).toBe("The IIIF Image preview couldn't be reached");
|
|
82
|
+
expect(error.message).toMatch(/CORS/);
|
|
83
|
+
});
|
|
84
|
+
it('falls back to a read error for a non-HTTP, non-network failure', () => {
|
|
85
|
+
const error = referenceError(new Error('open-failed'), 'IIIF Image');
|
|
86
|
+
expect(error.title).toBe("The IIIF Image preview couldn't be read");
|
|
87
|
+
expect(error.message).toContain('open-failed');
|
|
88
|
+
});
|
|
89
|
+
it('treats a status-0 error (MapLibre CORS/network block) as a network error, not "HTTP 0"', () => {
|
|
90
|
+
const error = referenceError({ status: 0, message: 'Failed to fetch' }, 'Web Map Service (WMS)');
|
|
91
|
+
expect(error.title).toBe("The Web Map Service (WMS) preview couldn't be reached");
|
|
92
|
+
expect(error.message).toMatch(/CORS/);
|
|
93
|
+
expect(error.message).not.toContain('HTTP 0');
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -7,26 +7,33 @@ import Previewer from "./previewer";
|
|
|
7
7
|
// NOTE: can't be built currently due to a bug; see:
|
|
8
8
|
// https://github.com/OpenGeoMetadata/ogm-viewer/issues/100
|
|
9
9
|
export default class DeckCogPreviewer extends Previewer {
|
|
10
|
+
// Store reference to the map and styles
|
|
11
|
+
style;
|
|
10
12
|
map;
|
|
13
|
+
// Store reference to the deck.gl overlay and the layer ID for cleanup
|
|
11
14
|
deckOverlay;
|
|
12
15
|
layerId = undefined;
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
// Bounds so we don't recalculate them
|
|
17
|
+
bounds;
|
|
18
|
+
// Current opacity state
|
|
19
|
+
opacity;
|
|
20
|
+
// Initialize with opacity at the theme's opacity value
|
|
21
|
+
constructor(source, map, style) {
|
|
15
22
|
super(source);
|
|
16
23
|
this.map = map;
|
|
24
|
+
this.style = style;
|
|
25
|
+
this.opacity = this.style.opacity;
|
|
17
26
|
this.deckOverlay = this.getDeckOverlay();
|
|
18
27
|
}
|
|
19
28
|
async preview() {
|
|
20
29
|
if (!this.layerId) {
|
|
21
30
|
const layer = this.createLayer();
|
|
22
|
-
console.debug('Created COG preview layer', layer.id);
|
|
23
31
|
this.layerId = layer.id;
|
|
24
32
|
this.deckOverlay.setProps({ layers: [layer] });
|
|
25
33
|
}
|
|
26
34
|
}
|
|
27
35
|
async clearPreview() {
|
|
28
36
|
if (this.layerId) {
|
|
29
|
-
console.debug('Clearing COG preview layer', this.layerId);
|
|
30
37
|
this.deckOverlay.setProps({ layers: [] });
|
|
31
38
|
this.layerId = undefined;
|
|
32
39
|
}
|
|
@@ -37,9 +44,8 @@ export default class DeckCogPreviewer extends Previewer {
|
|
|
37
44
|
createLayer() {
|
|
38
45
|
return new COGLayer({
|
|
39
46
|
id: this.getSourceId(),
|
|
40
|
-
geotiff: this.source.
|
|
41
|
-
onGeoTIFFLoad: (
|
|
42
|
-
console.debug('COG loaded', data, options);
|
|
47
|
+
geotiff: this.source.getMapLibreSourceUrl(),
|
|
48
|
+
onGeoTIFFLoad: (_data, options) => {
|
|
43
49
|
const { west, south, east, north } = options.geographicBounds;
|
|
44
50
|
this.bounds = [
|
|
45
51
|
[west, south],
|
|
@@ -56,6 +62,7 @@ export default class DeckCogPreviewer extends Previewer {
|
|
|
56
62
|
}),
|
|
57
63
|
});
|
|
58
64
|
}
|
|
65
|
+
// We get bounds for free from geoTIFF metadata
|
|
59
66
|
async getBounds() {
|
|
60
67
|
return this.bounds;
|
|
61
68
|
}
|
|
@@ -64,7 +71,6 @@ export default class DeckCogPreviewer extends Previewer {
|
|
|
64
71
|
// No built-in way to query existing controls...
|
|
65
72
|
const overlay = this.map._controls.find(control => control instanceof DeckOverlay);
|
|
66
73
|
if (overlay) {
|
|
67
|
-
console.debug('Deck.gl overlay exists; skipping creation', overlay);
|
|
68
74
|
return overlay;
|
|
69
75
|
}
|
|
70
76
|
return this.createDeckOverlay();
|
|
@@ -73,7 +79,6 @@ export default class DeckCogPreviewer extends Previewer {
|
|
|
73
79
|
createDeckOverlay() {
|
|
74
80
|
const overlay = new DeckOverlay({ interleaved: true });
|
|
75
81
|
this.map.addControl(overlay);
|
|
76
|
-
console.debug('Deck.gl overlay created', overlay);
|
|
77
82
|
return overlay;
|
|
78
83
|
}
|
|
79
84
|
}
|
|
@@ -6,15 +6,15 @@ import RasterPreviewer from "./raster";
|
|
|
6
6
|
// See: https://github.com/geomatico/maplibre-cog-protocol
|
|
7
7
|
export default class CogPreviewer extends RasterPreviewer {
|
|
8
8
|
// Register the 'cog://' protocol handler with MapLibre when the previewer is created
|
|
9
|
-
constructor(source, map,
|
|
10
|
-
super(source, map,
|
|
9
|
+
constructor(source, map, style) {
|
|
10
|
+
super(source, map, style);
|
|
11
11
|
maplibregl.addProtocol('cog', cogProtocol);
|
|
12
12
|
}
|
|
13
13
|
// COG sources use 'url' instead of 'tiles' and have no scheme
|
|
14
14
|
async createSource() {
|
|
15
15
|
return {
|
|
16
16
|
type: 'raster',
|
|
17
|
-
url: await this.source.
|
|
17
|
+
url: await this.source.getMapLibreSourceUrl(),
|
|
18
18
|
tileSize: this.source.getTileSize(),
|
|
19
19
|
};
|
|
20
20
|
}
|
|
@@ -2,8 +2,9 @@ import VectorPreviewer from "./vector";
|
|
|
2
2
|
export default class GeoJSONPreviewer extends VectorPreviewer {
|
|
3
3
|
async createSource() {
|
|
4
4
|
return {
|
|
5
|
-
type: await this.source.
|
|
6
|
-
data: await this.source.
|
|
5
|
+
type: await this.source.getMapLibreSourceType(),
|
|
6
|
+
data: await this.source.getMapLibreSourceUrl(),
|
|
7
|
+
generateId: true,
|
|
7
8
|
};
|
|
8
9
|
}
|
|
9
10
|
}
|
|
@@ -1,42 +1,38 @@
|
|
|
1
1
|
import Previewer from "./previewer";
|
|
2
|
-
const defaultOptions = {
|
|
3
|
-
padding: 40,
|
|
4
|
-
opacity: 1,
|
|
5
|
-
};
|
|
6
2
|
export default class MapLibrePreviewer extends Previewer {
|
|
3
|
+
// Store reference to the map and styles
|
|
4
|
+
style;
|
|
7
5
|
map;
|
|
8
|
-
|
|
9
|
-
opacity;
|
|
6
|
+
// Stored state for added source and layers to allow for cleanup
|
|
10
7
|
sourceId = null;
|
|
11
8
|
layerIds = [];
|
|
12
|
-
|
|
9
|
+
// Current opacity state
|
|
10
|
+
opacity;
|
|
11
|
+
// Initialize with opacity at the theme's opacity value
|
|
12
|
+
constructor(source, map, style) {
|
|
13
13
|
super(source);
|
|
14
14
|
this.map = map;
|
|
15
|
-
this.
|
|
16
|
-
this.opacity = this.
|
|
15
|
+
this.style = style;
|
|
16
|
+
this.opacity = this.style.opacity;
|
|
17
17
|
}
|
|
18
18
|
// Add source and preview layers if they don't already exist
|
|
19
19
|
async preview() {
|
|
20
20
|
if (!this.sourceId) {
|
|
21
21
|
if (this.map.getSource(this.getSourceId())) {
|
|
22
|
-
console.debug(`MapLibre source ${this.getSourceId()} exists; skipping creation`);
|
|
23
22
|
return;
|
|
24
23
|
}
|
|
25
24
|
const source = await this.createSource();
|
|
26
25
|
this.map.addSource(this.getSourceId(), source);
|
|
27
26
|
this.sourceId = this.getSourceId();
|
|
28
|
-
console.debug('Added MapLibre source', this.getSourceId(), source);
|
|
29
27
|
}
|
|
30
28
|
if (this.layerIds.length == 0) {
|
|
31
29
|
const layers = await this.createLayers();
|
|
32
30
|
layers.forEach(layer => {
|
|
33
31
|
if (this.map.getLayer(layer.id)) {
|
|
34
|
-
console.debug(`MapLibre layer ${layer.id} exists; skipping creation`);
|
|
35
32
|
return;
|
|
36
33
|
}
|
|
37
34
|
this.map.addLayer(layer);
|
|
38
35
|
this.layerIds.push(layer.id);
|
|
39
|
-
console.debug('Added MapLibre layer', layer.id);
|
|
40
36
|
});
|
|
41
37
|
}
|
|
42
38
|
}
|
|
@@ -44,13 +40,11 @@ export default class MapLibrePreviewer extends Previewer {
|
|
|
44
40
|
async clearPreview() {
|
|
45
41
|
this.layerIds.forEach(layerId => {
|
|
46
42
|
if (this.map.getLayer(layerId)) {
|
|
47
|
-
console.debug('Removing MapLibre layer', layerId);
|
|
48
43
|
this.map.removeLayer(layerId);
|
|
49
44
|
}
|
|
50
45
|
});
|
|
51
46
|
this.layerIds = [];
|
|
52
47
|
if (this.sourceId && this.map.getSource(this.getSourceId())) {
|
|
53
|
-
console.debug('Removing MapLibre source', this.getSourceId());
|
|
54
48
|
this.map.removeSource(this.getSourceId());
|
|
55
49
|
this.sourceId = null;
|
|
56
50
|
}
|
|
@@ -3,7 +3,7 @@ export default class PMTilesVectorPreviewer extends VectorPreviewer {
|
|
|
3
3
|
async createSource() {
|
|
4
4
|
return {
|
|
5
5
|
type: 'vector',
|
|
6
|
-
url: this.source.
|
|
6
|
+
url: this.source.getMapLibreSourceUrl(),
|
|
7
7
|
encoding: await this.source.getVectorEncoding(),
|
|
8
8
|
};
|
|
9
9
|
}
|
|
@@ -14,6 +14,12 @@ export default class PMTilesVectorPreviewer extends VectorPreviewer {
|
|
|
14
14
|
'source-layer': layerId,
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
|
+
createPolygonOutlineLayer(layerId) {
|
|
18
|
+
return {
|
|
19
|
+
...super.createPolygonOutlineLayer(layerId),
|
|
20
|
+
'source-layer': layerId,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
17
23
|
createLineLayer(layerId) {
|
|
18
24
|
return {
|
|
19
25
|
...super.createLineLayer(layerId),
|
|
@@ -3,7 +3,7 @@ export default class RasterPreviewer extends MapLibrePreviewer {
|
|
|
3
3
|
async createSource() {
|
|
4
4
|
return {
|
|
5
5
|
type: 'raster',
|
|
6
|
-
tiles: [await this.source.
|
|
6
|
+
tiles: [await this.source.getMapLibreSourceUrl()],
|
|
7
7
|
scheme: this.source.getScheme(),
|
|
8
8
|
tileSize: this.source.getTileSize(),
|
|
9
9
|
};
|