ogm-viewer 0.1.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/app-globals-V2Kpy_OQ.js +8 -0
  3. package/dist/cjs/app-globals-V2Kpy_OQ.js.map +1 -0
  4. package/dist/cjs/index-DQQaalxf.js +1421 -0
  5. package/dist/cjs/index-DQQaalxf.js.map +1 -0
  6. package/dist/cjs/index.cjs.js +5 -0
  7. package/dist/cjs/index.cjs.js.map +1 -0
  8. package/dist/cjs/loader.cjs.js +16 -0
  9. package/dist/cjs/loader.cjs.js.map +1 -0
  10. package/dist/cjs/ogm-menubar.ogm-metadata.ogm-sidebar.ogm-viewer.entry.cjs.js.map +1 -0
  11. package/dist/cjs/ogm-menubar_4.cjs.entry.js +3573 -0
  12. package/dist/cjs/ogm-menubar_4.cjs.entry.js.map +1 -0
  13. package/dist/cjs/ogm-viewer.cjs.js +28 -0
  14. package/dist/cjs/ogm-viewer.cjs.js.map +1 -0
  15. package/dist/collection/assets/icons/braces.svg +3 -0
  16. package/dist/collection/assets/icons/c-circle.svg +3 -0
  17. package/dist/collection/assets/icons/info-circle-fill.svg +3 -0
  18. package/dist/collection/assets/icons/link-45deg.svg +4 -0
  19. package/dist/collection/assets/icons/list.svg +3 -0
  20. package/dist/collection/collection-manifest.json +15 -0
  21. package/dist/collection/components/ogm-menubar/ogm-menubar.css +26 -0
  22. package/dist/collection/components/ogm-menubar/ogm-menubar.js +70 -0
  23. package/dist/collection/components/ogm-menubar/ogm-menubar.js.map +1 -0
  24. package/dist/collection/components/ogm-metadata/ogm-metadata.css +505 -0
  25. package/dist/collection/components/ogm-metadata/ogm-metadata.js +136 -0
  26. package/dist/collection/components/ogm-metadata/ogm-metadata.js.map +1 -0
  27. package/dist/collection/components/ogm-sidebar/ogm-sidebar.css +538 -0
  28. package/dist/collection/components/ogm-sidebar/ogm-sidebar.js +92 -0
  29. package/dist/collection/components/ogm-sidebar/ogm-sidebar.js.map +1 -0
  30. package/dist/collection/components/ogm-viewer/ogm-viewer.css +516 -0
  31. package/dist/collection/components/ogm-viewer/ogm-viewer.js +155 -0
  32. package/dist/collection/components/ogm-viewer/ogm-viewer.js.map +1 -0
  33. package/dist/collection/index.js +2 -0
  34. package/dist/collection/index.js.map +1 -0
  35. package/dist/collection/utils/record.js +186 -0
  36. package/dist/collection/utils/record.js.map +1 -0
  37. package/dist/collection/utils/references.js +80 -0
  38. package/dist/collection/utils/references.js.map +1 -0
  39. package/dist/collection/utils/sources.js +121 -0
  40. package/dist/collection/utils/sources.js.map +1 -0
  41. package/dist/collection/utils/utils.js +15 -0
  42. package/dist/collection/utils/utils.js.map +1 -0
  43. package/dist/esm/app-globals-DQuL1Twl.js +6 -0
  44. package/dist/esm/app-globals-DQuL1Twl.js.map +1 -0
  45. package/dist/esm/index-ChIbGKue.js +1411 -0
  46. package/dist/esm/index-ChIbGKue.js.map +1 -0
  47. package/dist/esm/index.js +4 -0
  48. package/dist/esm/index.js.map +1 -0
  49. package/dist/esm/loader.js +14 -0
  50. package/dist/esm/loader.js.map +1 -0
  51. package/dist/esm/ogm-menubar.ogm-metadata.ogm-sidebar.ogm-viewer.entry.js.map +1 -0
  52. package/dist/esm/ogm-menubar_4.entry.js +3568 -0
  53. package/dist/esm/ogm-menubar_4.entry.js.map +1 -0
  54. package/dist/esm/ogm-viewer.js +24 -0
  55. package/dist/esm/ogm-viewer.js.map +1 -0
  56. package/dist/index.cjs.js +1 -0
  57. package/dist/index.js +1 -0
  58. package/dist/ogm-viewer/index.esm.js +2 -0
  59. package/dist/ogm-viewer/index.esm.js.map +1 -0
  60. package/dist/ogm-viewer/loader.esm.js.map +1 -0
  61. package/dist/ogm-viewer/ogm-menubar.ogm-metadata.ogm-sidebar.ogm-viewer.entry.esm.js.map +1 -0
  62. package/dist/ogm-viewer/ogm-viewer.esm.js +2 -0
  63. package/dist/ogm-viewer/ogm-viewer.esm.js.map +1 -0
  64. package/dist/ogm-viewer/p-601c9fec.entry.js +769 -0
  65. package/dist/ogm-viewer/p-601c9fec.entry.js.map +1 -0
  66. package/dist/ogm-viewer/p-ChIbGKue.js +3 -0
  67. package/dist/ogm-viewer/p-ChIbGKue.js.map +1 -0
  68. package/dist/ogm-viewer/p-DQuL1Twl.js +2 -0
  69. package/dist/ogm-viewer/p-DQuL1Twl.js.map +1 -0
  70. package/dist/types/components/ogm-menubar/ogm-menubar.d.ts +7 -0
  71. package/dist/types/components/ogm-metadata/ogm-metadata.d.ts +17 -0
  72. package/dist/types/components/ogm-sidebar/ogm-sidebar.d.ts +16 -0
  73. package/dist/types/components/ogm-viewer/ogm-viewer.d.ts +19 -0
  74. package/dist/types/components.d.ts +122 -0
  75. package/dist/types/index.d.ts +10 -0
  76. package/dist/types/stencil-public-runtime.d.ts +1702 -0
  77. package/dist/types/utils/record.d.ts +153 -0
  78. package/dist/types/utils/references.d.ts +47 -0
  79. package/dist/types/utils/sources.d.ts +3 -0
  80. package/dist/types/utils/utils.d.ts +1 -0
  81. package/loader/cdn.js +1 -0
  82. package/loader/index.cjs.js +1 -0
  83. package/loader/index.d.ts +24 -0
  84. package/loader/index.es2017.js +1 -0
  85. package/loader/index.js +2 -0
  86. package/package.json +54 -0
  87. package/readme.md +4 -0
@@ -0,0 +1,155 @@
1
+ import { h } from "@stencil/core";
2
+ import maplibregl from "maplibre-gl";
3
+ import { cogProtocol } from "@geomatico/maplibre-cog-protocol";
4
+ import { OgmRecord } from "../../utils/record";
5
+ import { setAssetBasePath } from "../../utils/utils";
6
+ import { getPreviewLayer } from "../../utils/sources";
7
+ // Only need to call this once, at the top level
8
+ setAssetBasePath();
9
+ // Add support for COG protocol
10
+ maplibregl.addProtocol('cog', cogProtocol);
11
+ export class OgmViewer {
12
+ el;
13
+ recordUrl;
14
+ sidebarOpen = false;
15
+ record;
16
+ recordLoaded;
17
+ map;
18
+ previewId;
19
+ async componentWillLoad() {
20
+ if (this.recordUrl)
21
+ return await this.updateRecord();
22
+ }
23
+ componentDidLoad() {
24
+ this.map = new maplibregl.Map({
25
+ container: this.el.shadowRoot.getElementById('map'),
26
+ style: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
27
+ center: [0, 0],
28
+ zoom: 1,
29
+ });
30
+ this.map.addControl(new maplibregl.NavigationControl());
31
+ this.map.addControl(new maplibregl.FullscreenControl());
32
+ this.map.addControl(new maplibregl.GlobeControl());
33
+ this.map.once('load', this.addPreview.bind(this));
34
+ }
35
+ // Sidebar emits this event when menu button is clicked
36
+ _toggleSidebar() {
37
+ this.sidebarOpen = !this.sidebarOpen;
38
+ }
39
+ async updateRecord() {
40
+ if (this.recordUrl)
41
+ this.record = await this.fetchRecord(this.recordUrl);
42
+ }
43
+ addPreview() {
44
+ if (!this.record || !this.map)
45
+ return;
46
+ const bounds = this.record.getBounds();
47
+ this.clearPreview();
48
+ const previewLayer = getPreviewLayer(this.record);
49
+ if (previewLayer) {
50
+ this.previewId = previewLayer.id;
51
+ this.map.addLayer(previewLayer);
52
+ }
53
+ this.map.fitBounds(bounds, { padding: 20 });
54
+ }
55
+ // Remove the preview layer and source from the map
56
+ clearPreview() {
57
+ if (!this.previewId)
58
+ return;
59
+ this.map.removeLayer(this.previewId);
60
+ this.map.removeSource(this.previewId);
61
+ }
62
+ async fetchRecord(recordUrl) {
63
+ const response = await fetch(recordUrl);
64
+ const data = await response.json();
65
+ return new OgmRecord(data);
66
+ }
67
+ render() {
68
+ return (h("div", { key: 'd1e307410345fb77cf53a0c767e58452d59cba34', class: "container" }, h("ogm-menubar", { key: 'e8973b341791fe85598c3e6a581288222900979b', record: this.record }), h("div", { key: '03e7fdc35eb390b5b2773324269e08bb533cd6df', class: "map-container" }, h("ogm-sidebar", { key: 'b6cc82534cc1319a8ee6ef78c7b15261ebad3433', record: this.record, open: this.sidebarOpen }), h("div", { key: 'e90fcfebb4ef332266b35fbe6c9ad5a2fb845f4e', id: "map" }))));
69
+ }
70
+ static get is() { return "ogm-viewer"; }
71
+ static get encapsulation() { return "shadow"; }
72
+ static get originalStyleUrls() {
73
+ return {
74
+ "$": ["ogm-viewer.css"]
75
+ };
76
+ }
77
+ static get styleUrls() {
78
+ return {
79
+ "$": ["ogm-viewer.css"]
80
+ };
81
+ }
82
+ static get properties() {
83
+ return {
84
+ "recordUrl": {
85
+ "type": "string",
86
+ "attribute": "record-url",
87
+ "mutable": false,
88
+ "complexType": {
89
+ "original": "string",
90
+ "resolved": "string",
91
+ "references": {}
92
+ },
93
+ "required": false,
94
+ "optional": false,
95
+ "docs": {
96
+ "tags": [],
97
+ "text": ""
98
+ },
99
+ "getter": false,
100
+ "setter": false,
101
+ "reflect": false
102
+ }
103
+ };
104
+ }
105
+ static get states() {
106
+ return {
107
+ "sidebarOpen": {},
108
+ "record": {}
109
+ };
110
+ }
111
+ static get events() {
112
+ return [{
113
+ "method": "recordLoaded",
114
+ "name": "recordLoaded",
115
+ "bubbles": true,
116
+ "cancelable": true,
117
+ "composed": true,
118
+ "docs": {
119
+ "tags": [],
120
+ "text": ""
121
+ },
122
+ "complexType": {
123
+ "original": "OgmRecord",
124
+ "resolved": "OgmRecord",
125
+ "references": {
126
+ "OgmRecord": {
127
+ "location": "import",
128
+ "path": "../../utils/record",
129
+ "id": "src/utils/record.ts::OgmRecord"
130
+ }
131
+ }
132
+ }
133
+ }];
134
+ }
135
+ static get elementRef() { return "el"; }
136
+ static get watchers() {
137
+ return [{
138
+ "propName": "recordUrl",
139
+ "methodName": "updateRecord"
140
+ }, {
141
+ "propName": "record",
142
+ "methodName": "addPreview"
143
+ }];
144
+ }
145
+ static get listeners() {
146
+ return [{
147
+ "name": "sidebarToggled",
148
+ "method": "_toggleSidebar",
149
+ "target": undefined,
150
+ "capture": false,
151
+ "passive": false
152
+ }];
153
+ }
154
+ }
155
+ //# sourceMappingURL=ogm-viewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ogm-viewer.js","sourceRoot":"","sources":["../../../src/components/ogm-viewer/ogm-viewer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Element, Prop, Watch, State, Event, Listen, EventEmitter, h } from '@stencil/core';\nimport maplibregl from 'maplibre-gl';\nimport { cogProtocol } from '@geomatico/maplibre-cog-protocol';\n\nimport { OgmRecord } from '../../utils/record';\nimport { setAssetBasePath } from '../../utils/utils';\nimport { getPreviewLayer } from '../../utils/sources';\n\n// Only need to call this once, at the top level\nsetAssetBasePath();\n\n// Add support for COG protocol\nmaplibregl.addProtocol('cog', cogProtocol);\n\n@Component({\n tag: 'ogm-viewer',\n styleUrl: 'ogm-viewer.css',\n shadow: true,\n})\nexport class OgmViewer {\n @Element() el: HTMLElement;\n @Prop() recordUrl: string;\n @State() sidebarOpen: boolean = false;\n @State() record: OgmRecord;\n @Event() recordLoaded: EventEmitter<OgmRecord>;\n\n private map: maplibregl.Map;\n private previewId: string;\n\n async componentWillLoad() {\n if (this.recordUrl) return await this.updateRecord();\n }\n\n componentDidLoad() {\n this.map = new maplibregl.Map({\n container: this.el.shadowRoot.getElementById('map'),\n style: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',\n center: [0, 0],\n zoom: 1,\n });\n\n this.map.addControl(new maplibregl.NavigationControl());\n this.map.addControl(new maplibregl.FullscreenControl());\n this.map.addControl(new maplibregl.GlobeControl());\n\n this.map.once('load', this.addPreview.bind(this));\n }\n\n // Sidebar emits this event when menu button is clicked\n @Listen('sidebarToggled')\n _toggleSidebar() {\n this.sidebarOpen = !this.sidebarOpen;\n }\n\n @Watch('recordUrl')\n private async updateRecord() {\n if (this.recordUrl) this.record = await this.fetchRecord(this.recordUrl);\n }\n\n @Watch('record')\n addPreview() {\n if (!this.record || !this.map) return;\n\n const bounds = this.record.getBounds();\n\n this.clearPreview();\n\n const previewLayer = getPreviewLayer(this.record);\n if (previewLayer) {\n this.previewId = previewLayer.id;\n this.map.addLayer(previewLayer);\n }\n\n this.map.fitBounds(bounds, { padding: 20 });\n }\n\n // Remove the preview layer and source from the map\n clearPreview() {\n if (!this.previewId) return;\n this.map.removeLayer(this.previewId);\n this.map.removeSource(this.previewId);\n }\n\n async fetchRecord(recordUrl: string): Promise<OgmRecord> {\n const response = await fetch(recordUrl);\n const data = await response.json();\n return new OgmRecord(data);\n }\n\n render() {\n return (\n <div class=\"container\">\n <ogm-menubar record={this.record}></ogm-menubar>\n <div class=\"map-container\">\n <ogm-sidebar record={this.record} open={this.sidebarOpen}></ogm-sidebar>\n <div id=\"map\"></div>\n </div>\n </div>\n );\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG","sourcesContent":["/**\n * @fileoverview entry point for your component library\n *\n * This is the entry point for your component library. Use this file to export utilities,\n * constants or data structure that accompany your components.\n *\n * DO NOT use this file to export your components. Instead, use the recommended approaches\n * to consume components of this package as outlined in the `README.md`.\n */\n\nexport type * from './components.d.ts';\n"]}
@@ -0,0 +1,186 @@
1
+ import { LngLatBounds } from "maplibre-gl";
2
+ import { References } from "./references";
3
+ // Regular expression to match ENVELOPE syntax in bbox strings
4
+ export const ENVELOPE_REGEX = /^ENVELOPE\((?<west>[^,]+),(?<east>[^,]+),(?<north>[^,]+),(?<south>[^,]+)\)$/;
5
+ /**
6
+ * These are used to map the keys in the record to more user-friendly names.
7
+ */
8
+ export const OGM_FIELD_NAMES = {
9
+ id: 'ID',
10
+ title: 'Title',
11
+ description: 'Description',
12
+ resourceType: 'Resource Type',
13
+ resourceClass: 'Resource Class',
14
+ accessRights: 'Access Rights',
15
+ references: 'References',
16
+ identifier: 'Identifier',
17
+ wxsIdentifier: 'WxS Identifier',
18
+ alternativeTitles: 'Alternative Title',
19
+ language: 'Language',
20
+ displayNotes: 'Display Notes',
21
+ creators: 'Creator',
22
+ publishers: 'Publisher',
23
+ provider: 'Provider',
24
+ themes: 'Theme',
25
+ keywords: 'Keywords',
26
+ temporal: 'Temporal Coverage',
27
+ issued: 'Date Issued',
28
+ indexYear: 'Index Year',
29
+ dateRange: 'Date Range',
30
+ spatial: 'Spatial Coverage',
31
+ geometry: 'Geometry',
32
+ bbox: 'Bounding Box',
33
+ centroid: 'Centroid',
34
+ relations: 'Relation',
35
+ memberOf: 'Member Of',
36
+ isPartOf: 'Is Part Of',
37
+ source: 'Source',
38
+ isVersionOf: 'Is Version Of',
39
+ replaces: 'Replaces',
40
+ isReplacedBy: 'Is Replaced By',
41
+ rights: 'Rights',
42
+ rightsHolder: 'Rights Holder',
43
+ license: 'License',
44
+ fileSize: 'File Size',
45
+ mdModified: 'Modified',
46
+ suppressed: 'Suppressed',
47
+ georeferenced: 'Georeferenced',
48
+ subjects: 'Subject',
49
+ mdVersion: 'Metadata Version',
50
+ format: 'Format',
51
+ };
52
+ /**
53
+ * Class for representing an OGM Aardvark record parsed from JSON data.
54
+ */
55
+ export class OgmRecord {
56
+ // Original JSON data
57
+ json;
58
+ // Required
59
+ id;
60
+ title;
61
+ resourceClass;
62
+ accessRights;
63
+ mdVersion = 'Aardvark';
64
+ // Optional
65
+ references;
66
+ identifier;
67
+ wxsIdentifier;
68
+ alternativeTitles;
69
+ description;
70
+ language;
71
+ displayNotes;
72
+ creators;
73
+ publishers;
74
+ provider;
75
+ resourceType;
76
+ themes;
77
+ keywords;
78
+ temporal;
79
+ issued;
80
+ indexYear;
81
+ dateRange;
82
+ spatial;
83
+ geometry;
84
+ bbox;
85
+ centroid;
86
+ relations;
87
+ memberOf;
88
+ isPartOf;
89
+ source;
90
+ isVersionOf;
91
+ replaces;
92
+ isReplacedBy;
93
+ rights;
94
+ rightsHolder;
95
+ license;
96
+ fileSize;
97
+ mdModified;
98
+ suppressed;
99
+ georeferenced;
100
+ subjects;
101
+ format;
102
+ constructor(data) {
103
+ if (data.gbl_mdVersion_s !== 'Aardvark') {
104
+ throw new Error('Unsupported metadata version: ' + data.gbl_mdVersion_s);
105
+ }
106
+ // Copy fields with friendlier names
107
+ this.id = data.id;
108
+ this.title = data.dct_title_s;
109
+ this.wxsIdentifier = data.gbl_wxsIdentifier_s;
110
+ this.subjects = data.dct_subject_sm;
111
+ this.resourceClass = data.gbl_resourceClass_sm;
112
+ this.rights = data.dct_rights_sm;
113
+ this.rightsHolder = data.dct_rightsHolder_sm;
114
+ this.license = data.dct_license_sm;
115
+ this.accessRights = data.dct_accessRights_s;
116
+ this.identifier = data.dct_identifier_sm;
117
+ this.wxsIdentifier = data.gbl_wxsIdentifier_s;
118
+ this.alternativeTitles = data.dct_alternative_sm;
119
+ this.description = data.dct_description_sm;
120
+ this.language = data.dct_language_sm;
121
+ this.displayNotes = data.gbl_displayNote_sm;
122
+ this.creators = data.dct_creator_sm;
123
+ this.publishers = data.dct_publisher_sm;
124
+ this.provider = data.schema_provider_s;
125
+ this.resourceType = data.gbl_resourceType_sm;
126
+ this.themes = data.dcat_theme_sm;
127
+ this.keywords = data.dcat_keyword_sm;
128
+ this.temporal = data.dct_temporal_sm;
129
+ this.issued = data.dct_issued_s;
130
+ this.indexYear = data.gbl_indexYear_im;
131
+ this.dateRange = data.gbl_dateRange_drsim;
132
+ this.spatial = data.dct_spatial_sm;
133
+ this.geometry = data.locn_geometry;
134
+ this.bbox = data.dcat_bbox;
135
+ this.centroid = data.dcat_centroid;
136
+ this.format = data.dct_format_s;
137
+ this.fileSize = data.gbl_fileSize_s;
138
+ // Parse references from JSON string
139
+ this.references = new References(data.dct_references_s || '{}');
140
+ // Save original JSON data
141
+ this.json = data;
142
+ }
143
+ // String used for attribution of map layers. Uses, in order of preference:
144
+ // - publishers(s)
145
+ // - creator(s)
146
+ // - provider
147
+ get attribution() {
148
+ if (this.publishers && this.publishers.length > 0)
149
+ return this.publishers.join(', ');
150
+ if (this.creators && this.creators.length > 0)
151
+ return this.creators.join(', ');
152
+ if (this.provider)
153
+ return this.provider;
154
+ }
155
+ // List of download links with URL and label
156
+ get downloadLinks() {
157
+ return this.references.downloadLinks.map(link => {
158
+ // If no label for download, use the format, falling back to 'Object'
159
+ // If file size is available, append it to the label
160
+ if (!link.label)
161
+ link.label = this.format || 'Object';
162
+ if (this.fileSize)
163
+ link.label += ` (${this.fileSize})`;
164
+ return link;
165
+ });
166
+ }
167
+ // Convert ENVELOPE syntax to LngLatBounds
168
+ getBounds() {
169
+ // Nothing to do if no bbox in record
170
+ if (!this.bbox)
171
+ return null;
172
+ // Try to parse bbox in ENVELOPE syntax
173
+ const coords = this.bbox.match(ENVELOPE_REGEX);
174
+ if (!coords)
175
+ return null;
176
+ if (coords.length !== 5)
177
+ return null;
178
+ // Convert to numbers and create LngLatBounds
179
+ const west = parseFloat(coords.groups.west);
180
+ const east = parseFloat(coords.groups.east);
181
+ const north = parseFloat(coords.groups.north);
182
+ const south = parseFloat(coords.groups.south);
183
+ return new LngLatBounds([west, south, east, north]);
184
+ }
185
+ }
186
+ //# sourceMappingURL=record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.js","sourceRoot":"","sources":["../../src/utils/record.ts"],"names":[],"mappings":"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","sourcesContent":["import { LngLatBounds } from 'maplibre-gl';\n\nimport { References } from './references';\n\n// Regular expression to match ENVELOPE syntax in bbox strings\nexport const ENVELOPE_REGEX = /^ENVELOPE\\((?<west>[^,]+),(?<east>[^,]+),(?<north>[^,]+),(?<south>[^,]+)\\)$/;\n\n/**\n * Schema for GeoBlacklight. See https://opengeometadata.github.io/aardvark/aardvarkMetadata.html for more details.\n */\nexport interface GeoBlacklightSchemaAardvark {\n dct_title_s: string;\n dct_alternative_sm?: string[];\n dct_description_sm?: string[];\n dct_language_sm?: string[];\n gbl_displayNote_sm?: string[];\n dct_creator_sm?: string[];\n dct_publisher_sm?: string[];\n schema_provider_s?: string;\n gbl_resourceClass_sm: ('Datasets' | 'Maps' | 'Imagery' | 'Collections' | 'Websites' | 'Web services' | 'Other')[];\n gbl_resourceType_sm?: string[];\n dct_subject_sm?: string[];\n dcat_theme_sm?: string[];\n dcat_keyword_sm?: string[];\n dct_temporal_sm?: string[];\n dct_issued_s?: string;\n gbl_indexYear_im?: number[];\n gbl_dateRange_drsim?: string[];\n dct_spatial_sm?: string[];\n locn_geometry?: string;\n dcat_bbox?: string;\n dcat_centroid?: string;\n dct_relation_sm?: string[];\n pcdm_memberOf_sm?: string[];\n dct_isPartOf_sm?: string[];\n dct_source_sm?: string[];\n dct_isVersionOf_sm?: string[];\n dct_replaces_sm?: string[];\n dct_isReplacedBy_sm?: string[];\n dct_rights_sm?: string[];\n dct_rightsHolder_sm?: string[];\n dct_license_sm?: string[];\n dct_accessRights_s: string;\n dct_format_s?: string;\n gbl_fileSize_s?: string;\n gbl_wxsIdentifier_s?: string;\n dct_references_s?: string;\n id: string;\n dct_identifier_sm?: string[];\n gbl_mdModified_dt?: string;\n gbl_mdVersion_s: 'Aardvark';\n gbl_suppressed_b?: boolean;\n gbl_georeferenced_b?: boolean;\n [k: string]: unknown;\n}\n\n/**\n * These are used to map the keys in the record to more user-friendly names.\n */\nexport const OGM_FIELD_NAMES = {\n id: 'ID',\n title: 'Title',\n description: 'Description',\n resourceType: 'Resource Type',\n resourceClass: 'Resource Class',\n accessRights: 'Access Rights',\n references: 'References',\n identifier: 'Identifier',\n wxsIdentifier: 'WxS Identifier',\n alternativeTitles: 'Alternative Title',\n language: 'Language',\n displayNotes: 'Display Notes',\n creators: 'Creator',\n publishers: 'Publisher',\n provider: 'Provider',\n themes: 'Theme',\n keywords: 'Keywords',\n temporal: 'Temporal Coverage',\n issued: 'Date Issued',\n indexYear: 'Index Year',\n dateRange: 'Date Range',\n spatial: 'Spatial Coverage',\n geometry: 'Geometry',\n bbox: 'Bounding Box',\n centroid: 'Centroid',\n relations: 'Relation',\n memberOf: 'Member Of',\n isPartOf: 'Is Part Of',\n source: 'Source',\n isVersionOf: 'Is Version Of',\n replaces: 'Replaces',\n isReplacedBy: 'Is Replaced By',\n rights: 'Rights',\n rightsHolder: 'Rights Holder',\n license: 'License',\n fileSize: 'File Size',\n mdModified: 'Modified',\n suppressed: 'Suppressed',\n georeferenced: 'Georeferenced',\n subjects: 'Subject',\n mdVersion: 'Metadata Version',\n format: 'Format',\n};\n\n/**\n * Class for representing an OGM Aardvark record parsed from JSON data.\n */\nexport class OgmRecord {\n // Original JSON data\n json: GeoBlacklightSchemaAardvark;\n\n // Required\n id: string;\n title: string;\n resourceClass: string[];\n accessRights: string;\n mdVersion = 'Aardvark';\n\n // Optional\n references: References;\n identifier?: string[];\n wxsIdentifier?: string;\n alternativeTitles?: string[];\n description?: string[];\n language?: string[];\n displayNotes?: string[];\n creators?: string[];\n publishers?: string[];\n provider?: string;\n resourceType?: string[];\n themes?: string[];\n keywords?: string[];\n temporal?: string[];\n issued?: string;\n indexYear?: number[];\n dateRange?: string[];\n spatial?: string[];\n geometry?: string;\n bbox?: string;\n centroid?: string;\n relations?: string[];\n memberOf?: string[];\n isPartOf?: string[];\n source?: string[];\n isVersionOf?: string[];\n replaces?: string[];\n isReplacedBy?: string[];\n rights?: string[];\n rightsHolder?: string[];\n license?: string[];\n fileSize?: string;\n mdModified?: string;\n suppressed?: boolean;\n georeferenced?: boolean;\n subjects?: string[];\n format?: string;\n\n constructor(data: GeoBlacklightSchemaAardvark) {\n if (data.gbl_mdVersion_s !== 'Aardvark') {\n throw new Error('Unsupported metadata version: ' + data.gbl_mdVersion_s);\n }\n\n // Copy fields with friendlier names\n this.id = data.id;\n this.title = data.dct_title_s;\n this.wxsIdentifier = data.gbl_wxsIdentifier_s;\n this.subjects = data.dct_subject_sm;\n this.resourceClass = data.gbl_resourceClass_sm;\n this.rights = data.dct_rights_sm;\n this.rightsHolder = data.dct_rightsHolder_sm;\n this.license = data.dct_license_sm;\n this.accessRights = data.dct_accessRights_s;\n this.identifier = data.dct_identifier_sm;\n this.wxsIdentifier = data.gbl_wxsIdentifier_s;\n this.alternativeTitles = data.dct_alternative_sm;\n this.description = data.dct_description_sm;\n this.language = data.dct_language_sm;\n this.displayNotes = data.gbl_displayNote_sm;\n this.creators = data.dct_creator_sm;\n this.publishers = data.dct_publisher_sm;\n this.provider = data.schema_provider_s;\n this.resourceType = data.gbl_resourceType_sm;\n this.themes = data.dcat_theme_sm;\n this.keywords = data.dcat_keyword_sm;\n this.temporal = data.dct_temporal_sm;\n this.issued = data.dct_issued_s;\n this.indexYear = data.gbl_indexYear_im;\n this.dateRange = data.gbl_dateRange_drsim;\n this.spatial = data.dct_spatial_sm;\n this.geometry = data.locn_geometry;\n this.bbox = data.dcat_bbox;\n this.centroid = data.dcat_centroid;\n this.format = data.dct_format_s;\n this.fileSize = data.gbl_fileSize_s;\n\n // Parse references from JSON string\n this.references = new References(data.dct_references_s || '{}');\n\n // Save original JSON data\n this.json = data;\n }\n\n // String used for attribution of map layers. Uses, in order of preference:\n // - publishers(s)\n // - creator(s)\n // - provider\n get attribution() {\n if (this.publishers && this.publishers.length > 0) return this.publishers.join(', ');\n if (this.creators && this.creators.length > 0) return this.creators.join(', ');\n if (this.provider) return this.provider;\n }\n\n // List of download links with URL and label\n get downloadLinks() {\n return this.references.downloadLinks.map(link => {\n // If no label for download, use the format, falling back to 'Object'\n // If file size is available, append it to the label\n if (!link.label) link.label = this.format || 'Object';\n if (this.fileSize) link.label += ` (${this.fileSize})`;\n return link;\n });\n }\n\n // Convert ENVELOPE syntax to LngLatBounds\n getBounds() {\n // Nothing to do if no bbox in record\n if (!this.bbox) return null;\n\n // Try to parse bbox in ENVELOPE syntax\n const coords = this.bbox.match(ENVELOPE_REGEX);\n if (!coords) return null;\n if (coords.length !== 5) return null;\n\n // Convert to numbers and create LngLatBounds\n const west = parseFloat(coords.groups.west);\n const east = parseFloat(coords.groups.east);\n const north = parseFloat(coords.groups.north);\n const south = parseFloat(coords.groups.south);\n return new LngLatBounds([west, south, east, north]);\n }\n}\n"]}
@@ -0,0 +1,80 @@
1
+ // Map reference URI keys to user-friendly names
2
+ export const REFERENCE_URIS = {
3
+ 'https://github.com/cogeotiff/cog-spec': 'COG',
4
+ 'http://lccn.loc.gov/sh85035852': 'Data dictionary',
5
+ 'http://schema.org/downloadUrl': 'Download URL',
6
+ 'http://geojson.org/geojson-spec.html': 'GeoJSON',
7
+ 'http://schema.org/url': 'Layer description',
8
+ 'http://iiif.io/api/image': 'IIIF image',
9
+ 'http://iiif.io/api/presentation#manifest': 'IIIF manifest',
10
+ 'http://www.opengis.net/cat/csw/csdgm': 'FGDC metadata',
11
+ 'http://www.w3.org/1999/xhtml': 'HTML metadata',
12
+ 'http://www.isotc211.org/schemas/2005/gmd/': 'ISO 19139 metadata',
13
+ 'http://www.loc.gov/mods/v3': 'MODS metadata',
14
+ 'https://oembed.com': 'OEmbed',
15
+ 'https://openindexmaps.org': 'Index map',
16
+ 'https://github.com/protomaps/PMTiles': 'PMTiles',
17
+ 'https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification': 'TMS',
18
+ 'https://github.com/mapbox/tilejson-spec': 'TileJSON',
19
+ 'http://www.opengis.net/def/serviceType/ogc/wcs': 'WCS',
20
+ 'http://www.opengis.net/def/serviceType/ogc/wms': 'WMS',
21
+ 'http://www.opengis.net/def/serviceType/ogc/wfs': 'WFS',
22
+ 'http://www.opengis.net/def/serviceType/ogc/wmts': 'WMTS',
23
+ 'https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames': 'XYZ tiles',
24
+ };
25
+ // References that are links to metadata
26
+ const METADATA_REFERENCE_URIS = [
27
+ 'http://schema.org/url',
28
+ 'http://www.opengis.net/cat/csw/csdgm',
29
+ 'http://www.w3.org/1999/xhtml',
30
+ 'http://www.isotc211.org/schemas/2005/gmd/',
31
+ 'http://www.loc.gov/mods/v3',
32
+ 'http://lccn.loc.gov/sh85035852',
33
+ ];
34
+ // Class that encapsulates references functionality
35
+ export class References {
36
+ // Underlying object to hold references
37
+ references;
38
+ // Create a new instance with the JSON string from a record
39
+ constructor(dct_references_s) {
40
+ try {
41
+ this.references = JSON.parse(dct_references_s);
42
+ }
43
+ catch (error) {
44
+ console.error('Failed to parse references:', error);
45
+ this.references = {};
46
+ }
47
+ }
48
+ // The WMS URL, if any
49
+ get wms() {
50
+ return this.references['http://www.opengis.net/def/serviceType/ogc/wms'];
51
+ }
52
+ // The cloud-optimized GeoTIFF URL, if any
53
+ get cog() {
54
+ return this.references['https://github.com/cogeotiff/cog-spec'];
55
+ }
56
+ // The TMS URL, if any
57
+ get tms() {
58
+ return this.references['https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification'];
59
+ }
60
+ // The XYZ tiles URL, if any
61
+ get xyz() {
62
+ return this.references['https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames'];
63
+ }
64
+ // List of download links with URL and label
65
+ get downloadLinks() {
66
+ const fieldContents = this.references['http://schema.org/downloadUrl'];
67
+ if (!fieldContents)
68
+ return [];
69
+ if (Array.isArray(fieldContents))
70
+ return fieldContents;
71
+ return [{ url: fieldContents, label: null }];
72
+ }
73
+ // List of metadata links with URL and label
74
+ get metadataLinks() {
75
+ return Object.entries(this.references)
76
+ .filter(([uri]) => METADATA_REFERENCE_URIS.includes(uri))
77
+ .map(([uri, url]) => ({ url, label: REFERENCE_URIS[uri] }));
78
+ }
79
+ }
80
+ //# sourceMappingURL=references.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"references.js","sourceRoot":"","sources":["../../src/utils/references.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,uCAAuC,EAAE,KAAK;IAC9C,gCAAgC,EAAE,iBAAiB;IACnD,+BAA+B,EAAE,cAAc;IAC/C,sCAAsC,EAAE,SAAS;IACjD,uBAAuB,EAAE,mBAAmB;IAC5C,0BAA0B,EAAE,YAAY;IACxC,0CAA0C,EAAE,eAAe;IAC3D,sCAAsC,EAAE,eAAe;IACvD,8BAA8B,EAAE,eAAe;IAC/C,2CAA2C,EAAE,oBAAoB;IACjE,4BAA4B,EAAE,eAAe;IAC7C,oBAAoB,EAAE,QAAQ;IAC9B,2BAA2B,EAAE,WAAW;IACxC,sCAAsC,EAAE,SAAS;IACjD,4DAA4D,EAAE,KAAK;IACnE,yCAAyC,EAAE,UAAU;IACrD,gDAAgD,EAAE,KAAK;IACvD,gDAAgD,EAAE,KAAK;IACvD,gDAAgD,EAAE,KAAK;IACvD,iDAAiD,EAAE,MAAM;IACzD,0DAA0D,EAAE,WAAW;CAC/D,CAAC;AAMX,wCAAwC;AACxC,MAAM,uBAAuB,GAAG;IAC9B,uBAAuB;IACvB,sCAAsC;IACtC,8BAA8B;IAC9B,2CAA2C;IAC3C,4BAA4B;IAC5B,gCAAgC;CACjC,CAAC;AAUF,mDAAmD;AACnD,MAAM,OAAO,UAAU;IACrB,uCAAuC;IAC/B,UAAU,CAAmB;IAErC,2DAA2D;IAC3D,YAAY,gBAAwB;QAClC,IAAI,CAAC;YACH,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACpD,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,UAAU,CAAC,gDAAgD,CAAC,CAAC;IAC3E,CAAC;IAED,0CAA0C;IAC1C,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,UAAU,CAAC,uCAAuC,CAAC,CAAC;IAClE,CAAC;IAED,sBAAsB;IACtB,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,UAAU,CAAC,4DAA4D,CAAC,CAAC;IACvF,CAAC;IAED,4BAA4B;IAC5B,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,UAAU,CAAC,0DAA0D,CAAC,CAAC;IACrF,CAAC;IAED,4CAA4C;IAC5C,IAAI,aAAa;QACf,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,+BAA+B,CAAC,CAAC;QACvE,IAAI,CAAC,aAAa;YAAE,OAAO,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;YAAE,OAAO,aAAa,CAAC;QACvD,OAAO,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,4CAA4C;IAC5C,IAAI,aAAa;QACf,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;aACnC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;aACxD,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAyB,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACxF,CAAC;CACF","sourcesContent":["// Map reference URI keys to user-friendly names\nexport const REFERENCE_URIS = {\n 'https://github.com/cogeotiff/cog-spec': 'COG',\n 'http://lccn.loc.gov/sh85035852': 'Data dictionary',\n 'http://schema.org/downloadUrl': 'Download URL',\n 'http://geojson.org/geojson-spec.html': 'GeoJSON',\n 'http://schema.org/url': 'Layer description',\n 'http://iiif.io/api/image': 'IIIF image',\n 'http://iiif.io/api/presentation#manifest': 'IIIF manifest',\n 'http://www.opengis.net/cat/csw/csdgm': 'FGDC metadata',\n 'http://www.w3.org/1999/xhtml': 'HTML metadata',\n 'http://www.isotc211.org/schemas/2005/gmd/': 'ISO 19139 metadata',\n 'http://www.loc.gov/mods/v3': 'MODS metadata',\n 'https://oembed.com': 'OEmbed',\n 'https://openindexmaps.org': 'Index map',\n 'https://github.com/protomaps/PMTiles': 'PMTiles',\n 'https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification': 'TMS',\n 'https://github.com/mapbox/tilejson-spec': 'TileJSON',\n 'http://www.opengis.net/def/serviceType/ogc/wcs': 'WCS',\n 'http://www.opengis.net/def/serviceType/ogc/wms': 'WMS',\n 'http://www.opengis.net/def/serviceType/ogc/wfs': 'WFS',\n 'http://www.opengis.net/def/serviceType/ogc/wmts': 'WMTS',\n 'https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames': 'XYZ tiles',\n} as const;\n\n// Specific types for URI values and their friendly names\nexport type ReferenceURI = keyof typeof REFERENCE_URIS;\nexport type ReferenceName = (typeof REFERENCE_URIS)[ReferenceURI];\n\n// References that are links to metadata\nconst METADATA_REFERENCE_URIS = [\n 'http://schema.org/url',\n 'http://www.opengis.net/cat/csw/csdgm',\n 'http://www.w3.org/1999/xhtml',\n 'http://www.isotc211.org/schemas/2005/gmd/',\n 'http://www.loc.gov/mods/v3',\n 'http://lccn.loc.gov/sh85035852',\n];\n\n// Special handling for download URLs, can be a single string or an array of objects\nexport type LabelledLinks = { url: string; label: string }[];\ntype NonDownloadReferenceURI = Exclude<ReferenceURI, 'http://schema.org/downloadUrl'>;\ntype DownloadReference = { 'http://schema.org/downloadUrl': string | LabelledLinks };\n\n// Type for the complete references record, all keys are optional\nexport type ReferencesRecord = Partial<{ [key in NonDownloadReferenceURI]: string } & DownloadReference>;\n\n// Class that encapsulates references functionality\nexport class References {\n // Underlying object to hold references\n private references: ReferencesRecord;\n\n // Create a new instance with the JSON string from a record\n constructor(dct_references_s: string) {\n try {\n this.references = JSON.parse(dct_references_s);\n } catch (error) {\n console.error('Failed to parse references:', error);\n this.references = {};\n }\n }\n\n // The WMS URL, if any\n get wms() {\n return this.references['http://www.opengis.net/def/serviceType/ogc/wms'];\n }\n\n // The cloud-optimized GeoTIFF URL, if any\n get cog() {\n return this.references['https://github.com/cogeotiff/cog-spec'];\n }\n\n // The TMS URL, if any\n get tms() {\n return this.references['https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification'];\n }\n\n // The XYZ tiles URL, if any\n get xyz() {\n return this.references['https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames'];\n }\n\n // List of download links with URL and label\n get downloadLinks(): LabelledLinks {\n const fieldContents = this.references['http://schema.org/downloadUrl'];\n if (!fieldContents) return [];\n if (Array.isArray(fieldContents)) return fieldContents;\n return [{ url: fieldContents, label: null }];\n }\n\n // List of metadata links with URL and label\n get metadataLinks(): LabelledLinks {\n return Object.entries(this.references)\n .filter(([uri]) => METADATA_REFERENCE_URIS.includes(uri))\n .map(([uri, url]: [ReferenceURI, string]) => ({ url, label: REFERENCE_URIS[uri] }));\n }\n}\n"]}
@@ -0,0 +1,121 @@
1
+ // Given a record, generate a preview layer with embedded source for the map
2
+ export const getPreviewLayer = (record) => {
3
+ // If nothing we can render from references, warn and bail out
4
+ const bestSource = getRecordSource(record);
5
+ if (!bestSource) {
6
+ console.warn(`No suitable preview source found for record ${record.id}`);
7
+ return;
8
+ }
9
+ // Generate a mapLibre layer object with embedded source
10
+ const { id, source } = bestSource;
11
+ const type = getLayerType(record, source);
12
+ return { id, type, source }; // The ID always matches the record & source ID
13
+ };
14
+ // Map source types to layer types using information from the record
15
+ const getLayerType = (_record, source) => {
16
+ // For now, we only support raster layers
17
+ if (source.type === 'raster')
18
+ return 'raster';
19
+ else
20
+ throw new Error(`Unsupported source type: ${source.type}`);
21
+ };
22
+ // Given a record, choose the best source used to preview it on the map
23
+ const getRecordSource = (record) => {
24
+ return [
25
+ // Methods that create new sources are added here in order of preference
26
+ // The first one that returns a valid source will be used
27
+ recordCOGSource(record),
28
+ recordWMSSource(record),
29
+ recordTMSSource(record),
30
+ recordXYZSource(record),
31
+ ].find(Boolean);
32
+ };
33
+ const recordXYZSource = (record) => {
34
+ // If no XYZ reference, nothing to do
35
+ const xyzUrl = record.references.xyz;
36
+ if (!xyzUrl)
37
+ return null;
38
+ return {
39
+ id: record.id,
40
+ source: {
41
+ type: 'raster',
42
+ tiles: [xyzUrl],
43
+ scheme: 'xyz',
44
+ tileSize: 256,
45
+ attribution: record.attribution,
46
+ },
47
+ };
48
+ };
49
+ // Given a record, create a MapLibre TMS source, if possible
50
+ const recordTMSSource = (record) => {
51
+ // If no TMS reference, nothing to do
52
+ const tmsUrl = record.references.tms;
53
+ if (!tmsUrl)
54
+ return null;
55
+ return {
56
+ id: record.id,
57
+ source: {
58
+ type: 'raster',
59
+ tiles: [tmsUrl],
60
+ scheme: 'tms',
61
+ tileSize: 256,
62
+ attribution: record.attribution,
63
+ },
64
+ };
65
+ };
66
+ // Given a record, create a MapLibre COG source, if possible
67
+ const recordCOGSource = (record) => {
68
+ // If no COG reference, nothing to do
69
+ const cogUrl = record.references.cog;
70
+ if (!cogUrl)
71
+ return null;
72
+ // Add the cog:// protocol that will tell MapLibre to use the plugin
73
+ const url = `cog://${cogUrl}`;
74
+ return {
75
+ id: record.id,
76
+ source: {
77
+ type: 'raster',
78
+ url,
79
+ tileSize: 256,
80
+ attribution: record.attribution,
81
+ },
82
+ };
83
+ };
84
+ // Given a record, create a MapLibre WMS source, if possible
85
+ const recordWMSSource = (record) => {
86
+ // If no WMS reference or no WXS layer identifier, nothing we can do
87
+ const wmsUrl = record.references.wms;
88
+ if (!wmsUrl)
89
+ return null;
90
+ const layerIds = [record.wxsIdentifier];
91
+ if (!layerIds[0])
92
+ return null;
93
+ // Generate the source spec with a unique ID based on the record
94
+ const source = createWMSSource({ wmsUrl, layerIds, attribution: record.attribution });
95
+ const id = record.id;
96
+ return { id, source };
97
+ };
98
+ // Create a MapLibre raster source specification object for a WMS layer
99
+ // Default is 256px transparent PNG tiles in EPSG:3857 projection
100
+ const createWMSSource = ({ wmsUrl, layerIds, bbox = '{bbox-epsg-3857}', srs = 'EPSG:3857', tileSize = 256, format = 'image/png', transparent = true, attribution = '', }) => {
101
+ const tilesUrl = new URL(wmsUrl);
102
+ // Construct the WMS URL with required parameters
103
+ tilesUrl.searchParams.set('service', 'WMS');
104
+ tilesUrl.searchParams.set('request', 'GetMap');
105
+ tilesUrl.searchParams.set('layers', layerIds.join(','));
106
+ tilesUrl.searchParams.set('width', String(tileSize));
107
+ tilesUrl.searchParams.set('height', String(tileSize));
108
+ tilesUrl.searchParams.set('transparent', String(transparent));
109
+ tilesUrl.searchParams.set('srs', srs);
110
+ tilesUrl.searchParams.set('format', format);
111
+ // This param can't be encoded because MapLibre needs to template it
112
+ let tilesUrlString = tilesUrl.toString();
113
+ tilesUrlString += `&bbox=${bbox}`;
114
+ return {
115
+ type: 'raster',
116
+ tiles: [tilesUrlString],
117
+ tileSize,
118
+ attribution,
119
+ };
120
+ };
121
+ //# sourceMappingURL=sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/utils/sources.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SourceSpecification, AddLayerObject } from 'maplibre-gl';\nimport type { OgmRecord } from './record';\n\ntype AddSourceObject = { id: string; source: SourceSpecification };\ntype LayerType = Exclude<AddLayerObject['type'], 'custom'>;\n\n// Given a record, generate a preview layer with embedded source for the map\nexport const getPreviewLayer = (record: OgmRecord): AddLayerObject => {\n // If nothing we can render from references, warn and bail out\n const bestSource = getRecordSource(record);\n if (!bestSource) {\n console.warn(`No suitable preview source found for record ${record.id}`);\n return;\n }\n\n // Generate a mapLibre layer object with embedded source\n const { id, source } = bestSource;\n const type = getLayerType(record, source);\n return { id, type, source }; // The ID always matches the record & source ID\n};\n\n// Map source types to layer types using information from the record\nconst getLayerType = (_record: OgmRecord, source: SourceSpecification): LayerType => {\n // For now, we only support raster layers\n if (source.type === 'raster') return 'raster';\n else throw new Error(`Unsupported source type: ${source.type}`);\n};\n\n// Given a record, choose the best source used to preview it on the map\nconst getRecordSource = (record: OgmRecord): AddSourceObject => {\n return [\n // Methods that create new sources are added here in order of preference\n // The first one that returns a valid source will be used\n recordCOGSource(record),\n recordWMSSource(record),\n recordTMSSource(record),\n recordXYZSource(record),\n ].find(Boolean);\n};\n\nconst recordXYZSource = (record: OgmRecord): AddSourceObject => {\n // If no XYZ reference, nothing to do\n const xyzUrl = record.references.xyz;\n if (!xyzUrl) return null;\n\n return {\n id: record.id,\n source: {\n type: 'raster',\n tiles: [xyzUrl],\n scheme: 'xyz',\n tileSize: 256,\n attribution: record.attribution,\n },\n };\n};\n\n// Given a record, create a MapLibre TMS source, if possible\nconst recordTMSSource = (record: OgmRecord): AddSourceObject => {\n // If no TMS reference, nothing to do\n const tmsUrl = record.references.tms;\n if (!tmsUrl) return null;\n\n return {\n id: record.id,\n source: {\n type: 'raster',\n tiles: [tmsUrl],\n scheme: 'tms',\n tileSize: 256,\n attribution: record.attribution,\n },\n };\n};\n\n// Given a record, create a MapLibre COG source, if possible\nconst recordCOGSource = (record: OgmRecord): AddSourceObject => {\n // If no COG reference, nothing to do\n const cogUrl = record.references.cog;\n if (!cogUrl) return null;\n\n // Add the cog:// protocol that will tell MapLibre to use the plugin\n const url = `cog://${cogUrl}`;\n\n return {\n id: record.id,\n source: {\n type: 'raster',\n url,\n tileSize: 256,\n attribution: record.attribution,\n },\n };\n};\n\n// Given a record, create a MapLibre WMS source, if possible\nconst recordWMSSource = (record: OgmRecord): AddSourceObject => {\n // If no WMS reference or no WXS layer identifier, nothing we can do\n const wmsUrl = record.references.wms;\n if (!wmsUrl) return null;\n const layerIds = [record.wxsIdentifier];\n if (!layerIds[0]) return null;\n\n // Generate the source spec with a unique ID based on the record\n const source = createWMSSource({ wmsUrl, layerIds, attribution: record.attribution });\n const id = record.id;\n return { id, source };\n};\n\n// Create a MapLibre raster source specification object for a WMS layer\n// Default is 256px transparent PNG tiles in EPSG:3857 projection\nconst createWMSSource = ({\n wmsUrl,\n layerIds,\n bbox = '{bbox-epsg-3857}',\n srs = 'EPSG:3857',\n tileSize = 256,\n format = 'image/png',\n transparent = true,\n attribution = '',\n}): SourceSpecification => {\n const tilesUrl = new URL(wmsUrl);\n\n // Construct the WMS URL with required parameters\n tilesUrl.searchParams.set('service', 'WMS');\n tilesUrl.searchParams.set('request', 'GetMap');\n tilesUrl.searchParams.set('layers', layerIds.join(','));\n tilesUrl.searchParams.set('width', String(tileSize));\n tilesUrl.searchParams.set('height', String(tileSize));\n tilesUrl.searchParams.set('transparent', String(transparent));\n tilesUrl.searchParams.set('srs', srs);\n tilesUrl.searchParams.set('format', format);\n\n // This param can't be encoded because MapLibre needs to template it\n let tilesUrlString = tilesUrl.toString();\n tilesUrlString += `&bbox=${bbox}`;\n\n return {\n type: 'raster',\n tiles: [tilesUrlString],\n tileSize,\n attribution,\n };\n};\n"]}
@@ -0,0 +1,15 @@
1
+ import { setBasePath } from "@shoelace-style/shoelace/dist/utilities/base-path.js";
2
+ import { getAssetPath } from "@stencil/core";
3
+ // Utility to set the base path for assets so that e.g. icon images are loaded
4
+ export const setAssetBasePath = () => {
5
+ // Points to the top-level package directory, corresponding to src/ in this repo
6
+ // In local dev, it will be an empty string instead
7
+ const packageRoot = getAssetPath('').split('/').filter(Boolean).slice(0, -1).join('/');
8
+ // Set the asset path for icon images – src/ will become dist/collection/
9
+ // If in local dev, just set it to the root, since Stencil handles serving assets
10
+ if (packageRoot)
11
+ setBasePath(`${packageRoot}/collection`);
12
+ else
13
+ setBasePath('');
14
+ };
15
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sDAAsD,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE;IACnC,gFAAgF;IAChF,mDAAmD;IACnD,MAAM,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEvF,yEAAyE;IACzE,iFAAiF;IACjF,IAAI,WAAW;QAAE,WAAW,CAAC,GAAG,WAAW,aAAa,CAAC,CAAC;;QACrD,WAAW,CAAC,EAAE,CAAC,CAAC;AACvB,CAAC,CAAC","sourcesContent":["import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';\nimport { getAssetPath } from '@stencil/core';\n\n// Utility to set the base path for assets so that e.g. icon images are loaded\nexport const setAssetBasePath = () => {\n // Points to the top-level package directory, corresponding to src/ in this repo\n // In local dev, it will be an empty string instead\n const packageRoot = getAssetPath('').split('/').filter(Boolean).slice(0, -1).join('/');\n\n // Set the asset path for icon images – src/ will become dist/collection/\n // If in local dev, just set it to the root, since Stencil handles serving assets\n if (packageRoot) setBasePath(`${packageRoot}/collection`);\n else setBasePath('');\n};\n"]}