ogm-viewer 0.5.0 → 0.6.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/{lerc-Df0hDWkS.js → lerc-XQuzL9p2.js} +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{ogm-alerts.ogm-attributes.ogm-image.ogm-map.ogm-menubar.ogm-metadata.ogm-preview.ogm-previews.ogm-settings.ogm-sidebar.ogm-viewer-DMEfXquS.js → ogm-alerts.ogm-attributes.ogm-image.ogm-map.ogm-menubar.ogm-metadata.ogm-preview.ogm-previews.ogm-settings.ogm-sidebar.ogm-viewer-B4jkHqvr.js} +11313 -10658
- package/dist/cjs/ogm-alerts_11.cjs.entry.js +1 -1
- package/dist/cjs/ogm-viewer.cjs.js +1 -1
- package/dist/collection/components/ogm-image/ogm-image.js +14 -14
- package/dist/collection/components/ogm-map/ogm-map.js +144 -52
- package/dist/collection/components/ogm-menubar/ogm-menubar.js +23 -2
- package/dist/collection/components/ogm-menubar/ogm-menubar.test.js +34 -0
- package/dist/collection/components/ogm-preview/ogm-preview.js +13 -13
- package/dist/collection/components/ogm-preview/ogm-preview.test.js +5 -5
- package/dist/collection/components/ogm-previews/ogm-previews.js +30 -28
- package/dist/collection/components/ogm-previews/ogm-previews.test.js +3 -3
- package/dist/collection/components/ogm-viewer/ogm-viewer.css +6 -2
- package/dist/collection/components/ogm-viewer/ogm-viewer.js +29 -18
- package/dist/collection/lib/geometry.js +35 -1
- package/dist/collection/lib/geometry.test.js +90 -1
- package/dist/collection/lib/previewers/cog-deck.js +4 -4
- package/dist/collection/lib/previewers/cog.js +11 -11
- package/dist/collection/lib/previewers/geojson.js +10 -7
- package/dist/collection/lib/previewers/map.js +51 -0
- package/dist/collection/lib/previewers/openindexmap.js +2 -2
- package/dist/collection/lib/previewers/pmtiles-raster.js +9 -9
- package/dist/collection/lib/previewers/pmtiles-vector.js +12 -51
- package/dist/collection/lib/previewers/previewer.js +4 -3
- package/dist/collection/lib/previewers/raster.js +15 -11
- package/dist/collection/lib/previewers/tiled-vector.js +47 -0
- package/dist/collection/lib/previewers/tilejson-raster.js +27 -0
- package/dist/collection/lib/previewers/tilejson-vector.js +18 -0
- package/dist/collection/lib/previewers/tilejson.test.js +140 -0
- package/dist/collection/lib/previewers/vector.js +7 -4
- package/dist/collection/lib/previewers/wms.js +86 -6
- package/dist/collection/lib/previewers/wms.test.js +133 -0
- package/dist/collection/lib/previewers/wmts.js +31 -0
- package/dist/collection/lib/previewers/wmts.test.js +108 -0
- package/dist/collection/lib/{sources → resources}/cog.js +2 -2
- package/dist/collection/lib/{sources → resources}/geojson.js +3 -3
- package/dist/collection/lib/{sources → resources}/iiif-manifest.js +2 -2
- package/dist/collection/lib/{sources → resources}/iiif-manifest.test.js +3 -3
- package/dist/collection/lib/{sources → resources}/iiif.js +2 -2
- package/dist/collection/lib/{sources/maplibre.js → resources/map.js} +2 -2
- package/dist/collection/lib/{sources → resources}/openindexmap.js +2 -2
- package/dist/collection/lib/{sources → resources}/pmtiles.js +2 -2
- package/dist/collection/lib/{sources → resources}/raster.js +2 -2
- package/dist/collection/lib/{sources/source.js → resources/resource.js} +3 -3
- package/dist/collection/lib/{sources → resources}/tilejson.js +21 -4
- package/dist/collection/lib/{sources → resources}/tms.js +2 -2
- package/dist/collection/lib/{sources → resources}/vector.js +2 -2
- package/dist/collection/lib/{sources → resources}/wms.js +46 -6
- package/dist/collection/lib/resources/wms.test.js +63 -0
- package/dist/collection/lib/resources/wmts.js +317 -0
- package/dist/collection/lib/resources/wmts.test.js +235 -0
- package/dist/collection/lib/{sources → resources}/xyz.js +2 -2
- package/dist/esm/{lerc-CB_Jcu33.js → lerc-BxCv6y50.js} +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{ogm-alerts.ogm-attributes.ogm-image.ogm-map.ogm-menubar.ogm-metadata.ogm-preview.ogm-previews.ogm-settings.ogm-sidebar.ogm-viewer-Dlc6USWB.js → ogm-alerts.ogm-attributes.ogm-image.ogm-map.ogm-menubar.ogm-metadata.ogm-preview.ogm-previews.ogm-settings.ogm-sidebar.ogm-viewer-DtEO48bS.js} +11313 -10658
- package/dist/esm/ogm-alerts_11.entry.js +1 -1
- package/dist/esm/ogm-viewer.js +1 -1
- package/dist/ogm-viewer/ogm-viewer.esm.js +1 -1
- package/dist/ogm-viewer/p-7EhN80oi.js +2822 -0
- package/dist/ogm-viewer/{p-DqRDI3AC.js → p-BO_nFj5K.js} +1 -1
- package/dist/ogm-viewer/{p-7936ccc9.entry.js → p-c9af56a3.entry.js} +1 -1
- package/dist/types/components/ogm-image/ogm-image.d.ts +2 -2
- package/dist/types/components/ogm-map/ogm-map.d.ts +13 -9
- package/dist/types/components/ogm-menubar/ogm-menubar.d.ts +2 -1
- package/dist/types/components/ogm-preview/ogm-preview.d.ts +2 -2
- package/dist/types/components/ogm-previews/ogm-previews.d.ts +2 -2
- package/dist/types/components/ogm-viewer/ogm-viewer.d.ts +1 -0
- package/dist/types/components.d.ts +24 -6
- package/dist/types/lib/geometry.d.ts +5 -1
- package/dist/types/lib/previewers/cog-deck.d.ts +3 -3
- package/dist/types/lib/previewers/cog.d.ts +6 -6
- package/dist/types/lib/previewers/geojson.d.ts +7 -4
- package/dist/types/lib/previewers/{maplibre.d.ts → map.d.ts} +10 -7
- package/dist/types/lib/previewers/openindexmap.d.ts +2 -2
- package/dist/types/lib/previewers/pmtiles-raster.d.ts +2 -3
- package/dist/types/lib/previewers/pmtiles-vector.d.ts +4 -11
- package/dist/types/lib/previewers/previewer.d.ts +3 -3
- package/dist/types/lib/previewers/raster.d.ts +10 -7
- package/dist/types/lib/previewers/tiled-vector.d.ts +11 -0
- package/dist/types/lib/previewers/tilejson-raster.d.ts +8 -0
- package/dist/types/lib/previewers/tilejson-vector.d.ts +6 -0
- package/dist/types/lib/previewers/vector.d.ts +9 -5
- package/dist/types/lib/previewers/wms.d.ts +17 -5
- package/dist/types/lib/previewers/wms.test.d.ts +1 -0
- package/dist/types/lib/previewers/wmts.d.ts +11 -0
- package/dist/types/lib/previewers/wmts.test.d.ts +1 -0
- package/dist/types/lib/{sources → resources}/cog.d.ts +2 -2
- package/dist/types/lib/{sources → resources}/geojson.d.ts +2 -2
- package/dist/types/lib/{sources → resources}/iiif-manifest.d.ts +2 -2
- package/dist/types/lib/resources/iiif-manifest.test.d.ts +1 -0
- package/dist/types/lib/resources/iiif.d.ts +5 -0
- package/dist/types/lib/{sources/maplibre.d.ts → resources/map.d.ts} +2 -2
- package/dist/types/lib/resources/openindexmap.d.ts +5 -0
- package/dist/types/lib/{sources → resources}/pmtiles.d.ts +2 -2
- package/dist/types/lib/{sources → resources}/raster.d.ts +2 -2
- package/dist/types/lib/{sources/source.d.ts → resources/resource.d.ts} +1 -1
- package/dist/types/lib/{sources → resources}/tilejson.d.ts +5 -2
- package/dist/types/lib/resources/tms.d.ts +5 -0
- package/dist/types/lib/{sources → resources}/vector.d.ts +2 -2
- package/dist/types/lib/{sources → resources}/wms.d.ts +15 -5
- package/dist/types/lib/resources/wms.test.d.ts +1 -0
- package/dist/types/lib/resources/wmts.d.ts +59 -0
- package/dist/types/lib/resources/wmts.test.d.ts +1 -0
- package/dist/types/lib/resources/xyz.d.ts +5 -0
- package/package.json +1 -1
- package/readme.md +1 -0
- package/dist/collection/lib/previewers/maplibre.js +0 -56
- package/dist/ogm-viewer/p-CWtUrqsM.js +0 -2822
- package/dist/types/lib/sources/iiif.d.ts +0 -5
- package/dist/types/lib/sources/openindexmap.d.ts +0 -5
- package/dist/types/lib/sources/tms.d.ts +0 -5
- package/dist/types/lib/sources/xyz.d.ts +0 -5
- /package/dist/types/lib/{sources/iiif-manifest.test.d.ts → previewers/tilejson.test.d.ts} +0 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/** @vitest-environment happy-dom */
|
|
2
|
+
import { describe, it, expect } from "@stencil/vitest";
|
|
3
|
+
import { LngLatBounds } from "maplibre-gl";
|
|
4
|
+
import WmtsResource from "./wmts";
|
|
5
|
+
const ENDPOINT = 'https://example.org/wmts/1.0.0/WMTSCapabilities.xml';
|
|
6
|
+
// Reads a hand-built capabilities document instead of fetching one
|
|
7
|
+
class TestWmtsResource extends WmtsResource {
|
|
8
|
+
xml;
|
|
9
|
+
constructor(id, url, options, xml, bounds) {
|
|
10
|
+
super(id, url, options, bounds);
|
|
11
|
+
this.xml = xml;
|
|
12
|
+
}
|
|
13
|
+
async getMetadata() {
|
|
14
|
+
return new DOMParser().parseFromString(this.xml, 'application/xml');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// One zoom of the XYZ grid: 2^z square tiles hung from the northwest corner of the world
|
|
18
|
+
const mercatorLevel = (zoom, { prefix = '', tileSize = 256 } = {}) => `
|
|
19
|
+
<TileMatrix>
|
|
20
|
+
<ows:Identifier>${prefix}${zoom}</ows:Identifier>
|
|
21
|
+
<TopLeftCorner>-20037508.34278925 20037508.34278925</TopLeftCorner>
|
|
22
|
+
<TileWidth>${tileSize}</TileWidth>
|
|
23
|
+
<TileHeight>${tileSize}</TileHeight>
|
|
24
|
+
<MatrixWidth>${2 ** zoom}</MatrixWidth>
|
|
25
|
+
<MatrixHeight>${2 ** zoom}</MatrixHeight>
|
|
26
|
+
</TileMatrix>`;
|
|
27
|
+
// Tiles per side at each zoom of NASA GIBS' geographic "500m" grid, which halves down from
|
|
28
|
+
// 160x80 tiles of 2.25 degrees and rounds up - so it is neither square nor a quadtree
|
|
29
|
+
const GEOGRAPHIC_LEVELS = [
|
|
30
|
+
[2, 1],
|
|
31
|
+
[3, 2],
|
|
32
|
+
[5, 3],
|
|
33
|
+
[10, 5],
|
|
34
|
+
];
|
|
35
|
+
const geographicLevel = (zoom) => `
|
|
36
|
+
<TileMatrix>
|
|
37
|
+
<ows:Identifier>${zoom}</ows:Identifier>
|
|
38
|
+
<TopLeftCorner>-180 90</TopLeftCorner>
|
|
39
|
+
<TileWidth>512</TileWidth>
|
|
40
|
+
<TileHeight>512</TileHeight>
|
|
41
|
+
<MatrixWidth>${GEOGRAPHIC_LEVELS[zoom][0]}</MatrixWidth>
|
|
42
|
+
<MatrixHeight>${GEOGRAPHIC_LEVELS[zoom][1]}</MatrixHeight>
|
|
43
|
+
</TileMatrix>`;
|
|
44
|
+
const tileMatrixSet = (id, crs, levels) => `
|
|
45
|
+
<TileMatrixSet>
|
|
46
|
+
<ows:Identifier>${id}</ows:Identifier>
|
|
47
|
+
<ows:SupportedCRS>${crs}</ows:SupportedCRS>
|
|
48
|
+
${levels}
|
|
49
|
+
</TileMatrixSet>`;
|
|
50
|
+
const ZOOMS = [0, 1, 2, 3];
|
|
51
|
+
const MERCATOR_SET = tileMatrixSet('GoogleMapsCompatible_Level3', 'urn:ogc:def:crs:EPSG:6.18:3:3857', ZOOMS.map(zoom => mercatorLevel(zoom)).join(''));
|
|
52
|
+
const GEOGRAPHIC_SET = tileMatrixSet('500m', 'urn:ogc:def:crs:OGC:1.3:CRS84', ZOOMS.map(geographicLevel).join(''));
|
|
53
|
+
// GeoServer and friends qualify the level with the grid it belongs to
|
|
54
|
+
const QUALIFIED_SET = tileMatrixSet('EPSG:900913', 'EPSG:900913', ZOOMS.map(zoom => mercatorLevel(zoom, { prefix: 'EPSG:900913:' })).join(''));
|
|
55
|
+
// Web Mercator, but with a level that doesn't hold the 2^z by 2^z tiles that zoom has
|
|
56
|
+
const RAGGED_SET = tileMatrixSet('ragged', 'EPSG:3857', `${mercatorLevel(0)}
|
|
57
|
+
<TileMatrix>
|
|
58
|
+
<ows:Identifier>1</ows:Identifier>
|
|
59
|
+
<TopLeftCorner>-20037508.34278925 20037508.34278925</TopLeftCorner>
|
|
60
|
+
<TileWidth>256</TileWidth>
|
|
61
|
+
<TileHeight>256</TileHeight>
|
|
62
|
+
<MatrixWidth>3</MatrixWidth>
|
|
63
|
+
<MatrixHeight>2</MatrixHeight>
|
|
64
|
+
</TileMatrix>`);
|
|
65
|
+
const TIME_DIMENSION = `
|
|
66
|
+
<Dimension>
|
|
67
|
+
<ows:Identifier>Time</ows:Identifier>
|
|
68
|
+
<UOM>ISO8601</UOM>
|
|
69
|
+
<Default>2016-01-01</Default>
|
|
70
|
+
</Dimension>`;
|
|
71
|
+
const TILE_TEMPLATE = 'https://tiles.example.org/lights/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png';
|
|
72
|
+
const boundingBox = (west, south, east, north) => `
|
|
73
|
+
<ows:WGS84BoundingBox crs="urn:ogc:def:crs:OGC:2:84">
|
|
74
|
+
<ows:LowerCorner>${west} ${south}</ows:LowerCorner>
|
|
75
|
+
<ows:UpperCorner>${east} ${north}</ows:UpperCorner>
|
|
76
|
+
</ows:WGS84BoundingBox>`;
|
|
77
|
+
const layer = ({ id = 'lights', links, templates = [TILE_TEMPLATE], dimension = '', extraUrls = '', bbox = '' }) => `
|
|
78
|
+
<Layer>
|
|
79
|
+
<ows:Title>Night Lights</ows:Title>
|
|
80
|
+
${bbox}
|
|
81
|
+
<ows:Identifier>${id}</ows:Identifier>
|
|
82
|
+
<Style isDefault="true"><ows:Identifier>default</ows:Identifier></Style>
|
|
83
|
+
${dimension}
|
|
84
|
+
${links.map(link => `<TileMatrixSetLink><TileMatrixSet>${link}</TileMatrixSet></TileMatrixSetLink>`).join('')}
|
|
85
|
+
${templates.map(template => `<ResourceURL resourceType="tile" format="image/png" template="${template}"/>`).join('')}
|
|
86
|
+
${extraUrls}
|
|
87
|
+
</Layer>`;
|
|
88
|
+
const capabilities = (...contents) => `<?xml version="1.0" encoding="UTF-8"?>
|
|
89
|
+
<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" version="1.0.0">
|
|
90
|
+
<Contents>${contents.join('')}</Contents>
|
|
91
|
+
</Capabilities>`;
|
|
92
|
+
const resourceFor = (xml, layerIds = ['lights'], url = ENDPOINT, bounds) => new TestWmtsResource('night-lights', url, { layerIds }, xml, bounds);
|
|
93
|
+
describe('WmtsResource#getLayers', () => {
|
|
94
|
+
it('rewrites a Web Mercator layer as XYZ tile URLs', async () => {
|
|
95
|
+
const resource = resourceFor(capabilities(layer({ links: ['GoogleMapsCompatible_Level3'] }), MERCATOR_SET));
|
|
96
|
+
const [drawn] = await resource.getLayers();
|
|
97
|
+
expect(drawn.id).toEqual('lights');
|
|
98
|
+
expect(drawn.title).toEqual('Night Lights');
|
|
99
|
+
expect(drawn.tileUrls).toEqual(['https://tiles.example.org/lights/default/GoogleMapsCompatible_Level3/{z}/{y}/{x}.png']);
|
|
100
|
+
});
|
|
101
|
+
it('takes the tile size and zoom range from the tile matrix set', async () => {
|
|
102
|
+
const bigTiles = tileMatrixSet('big', 'EPSG:3857', [2, 3].map(zoom => mercatorLevel(zoom, { tileSize: 512 })).join(''));
|
|
103
|
+
const resource = resourceFor(capabilities(layer({ links: ['big'] }), bigTiles));
|
|
104
|
+
const [drawn] = await resource.getLayers();
|
|
105
|
+
// Both differ from what MapLibre would assume on its own, which is 512px tiles over zooms 0-22
|
|
106
|
+
expect(drawn.tileSize).toEqual(512);
|
|
107
|
+
expect(drawn.minzoom).toEqual(2);
|
|
108
|
+
expect(drawn.maxzoom).toEqual(3);
|
|
109
|
+
});
|
|
110
|
+
it('substitutes the default value of each dimension', async () => {
|
|
111
|
+
const template = 'https://tiles.example.org/lights/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png';
|
|
112
|
+
const resource = resourceFor(capabilities(layer({ links: ['GoogleMapsCompatible_Level3'], templates: [template], dimension: TIME_DIMENSION }), MERCATOR_SET));
|
|
113
|
+
const [drawn] = await resource.getLayers();
|
|
114
|
+
expect(drawn.tileUrls).toEqual(['https://tiles.example.org/lights/default/2016-01-01/GoogleMapsCompatible_Level3/{z}/{y}/{x}.png']);
|
|
115
|
+
});
|
|
116
|
+
it('ignores resource URLs that serve something other than tiles', async () => {
|
|
117
|
+
const extraUrls = '<ResourceURL resourceType="Domains" format="text/xml" template="https://tiles.example.org/lights/domains/{TileMatrixSet}/all.xml"/>';
|
|
118
|
+
const resource = resourceFor(capabilities(layer({ links: ['GoogleMapsCompatible_Level3'], extraUrls }), MERCATOR_SET));
|
|
119
|
+
const [drawn] = await resource.getLayers();
|
|
120
|
+
expect(drawn.tileUrls).toHaveLength(1);
|
|
121
|
+
});
|
|
122
|
+
it('keeps the prefix on tile matrix identifiers that are qualified by their grid', async () => {
|
|
123
|
+
const resource = resourceFor(capabilities(layer({ links: ['EPSG:900913'] }), QUALIFIED_SET));
|
|
124
|
+
const [drawn] = await resource.getLayers();
|
|
125
|
+
expect(drawn.tileUrls).toEqual(['https://tiles.example.org/lights/default/EPSG:900913/EPSG:900913:{z}/{y}/{x}.png']);
|
|
126
|
+
});
|
|
127
|
+
it('passes over a grid it cannot draw for one it can, whatever the order', async () => {
|
|
128
|
+
const resource = resourceFor(capabilities(layer({ links: ['500m', 'GoogleMapsCompatible_Level3'] }), GEOGRAPHIC_SET, MERCATOR_SET));
|
|
129
|
+
const [drawn] = await resource.getLayers();
|
|
130
|
+
expect(drawn.tileUrls).toEqual(['https://tiles.example.org/lights/default/GoogleMapsCompatible_Level3/{z}/{y}/{x}.png']);
|
|
131
|
+
});
|
|
132
|
+
it('refuses a layer published only in a geographic grid, naming the grid and its CRS', async () => {
|
|
133
|
+
const resource = resourceFor(capabilities(layer({ links: ['500m'] }), GEOGRAPHIC_SET));
|
|
134
|
+
// Tile indices in a geographic grid address different ground than MapLibre's XYZ ones,
|
|
135
|
+
// so drawing it would put imagery in the wrong place or fall off the end of a row
|
|
136
|
+
await expect(resource.getLayers()).rejects.toThrow('500m (urn:ogc:def:crs:OGC:1.3:CRS84)');
|
|
137
|
+
await expect(resource.getLayers()).rejects.toThrow(/Web Mercator/);
|
|
138
|
+
});
|
|
139
|
+
it('refuses a Web Mercator grid whose levels are not the XYZ ones', async () => {
|
|
140
|
+
const resource = resourceFor(capabilities(layer({ links: ['ragged'] }), RAGGED_SET));
|
|
141
|
+
await expect(resource.getLayers()).rejects.toThrow('ragged (EPSG:3857)');
|
|
142
|
+
});
|
|
143
|
+
it('refuses a layer the service does not publish', async () => {
|
|
144
|
+
const resource = resourceFor(capabilities(layer({ links: ['GoogleMapsCompatible_Level3'] }), MERCATOR_SET), ['moonlight']);
|
|
145
|
+
await expect(resource.getLayers()).rejects.toThrow('moonlight');
|
|
146
|
+
});
|
|
147
|
+
it('returns only the requested layer when the service lists many', async () => {
|
|
148
|
+
const others = [1, 2, 3].map(index => layer({ id: `other-${index}`, links: ['GoogleMapsCompatible_Level3'] })).join('');
|
|
149
|
+
const resource = resourceFor(capabilities(others, layer({ links: ['GoogleMapsCompatible_Level3'] }), MERCATOR_SET));
|
|
150
|
+
const drawn = await resource.getLayers();
|
|
151
|
+
expect(drawn.map(each => each.id)).toEqual(['lights']);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
// Deep enough to hold the zoom a city-sized layer starts at
|
|
155
|
+
const DEEP_SET = tileMatrixSet('GoogleMapsCompatible', 'EPSG:3857', Array.from({ length: 20 }, (_, zoom) => mercatorLevel(zoom)).join(''));
|
|
156
|
+
// Vienna, as its orthophoto service states it, and as the Aardvark record does
|
|
157
|
+
const VIENNA = boundingBox(16.17, 48.1, 16.58, 48.33);
|
|
158
|
+
// Built the way bboxToBounds builds it from a record's ENVELOPE, since that is what arrives here
|
|
159
|
+
const VIENNA_RECORD = new LngLatBounds([16.133423, 48.106056], [16.626434, 48.3348]);
|
|
160
|
+
const boundedLayers = (bbox, grid = DEEP_SET, id = 'GoogleMapsCompatible', bounds) => resourceFor(capabilities(layer({ links: [id], bbox }), grid), ['lights'], ENDPOINT, bounds).getLayers();
|
|
161
|
+
describe('WmtsResource#getLayers extent', () => {
|
|
162
|
+
it('carries the published bounding box through in MapLibre order', async () => {
|
|
163
|
+
const [drawn] = await boundedLayers(VIENNA);
|
|
164
|
+
expect(drawn.bounds).toEqual([16.17, 48.1, 16.58, 48.33]);
|
|
165
|
+
});
|
|
166
|
+
it('starts a city-sized layer at the zoom where it first fills a tile', async () => {
|
|
167
|
+
// Below this every tile is mostly outside the layer, and a service that draws the empty
|
|
168
|
+
// part rather than answering 404 paints it over the map
|
|
169
|
+
const [drawn] = await boundedLayers(VIENNA);
|
|
170
|
+
expect(drawn.minzoom).toEqual(10);
|
|
171
|
+
expect(drawn.maxzoom).toEqual(19);
|
|
172
|
+
});
|
|
173
|
+
it('leaves a layer that covers the world at the first zoom of its grid', async () => {
|
|
174
|
+
const [drawn] = await boundedLayers(boundingBox(-180, -90, 180, 90));
|
|
175
|
+
expect(drawn.minzoom).toEqual(0);
|
|
176
|
+
});
|
|
177
|
+
it('measures a bounding box that crosses the antimeridian the short way round', async () => {
|
|
178
|
+
// Two degrees of longitude at the date line, not the 358 that subtracting the corners gives
|
|
179
|
+
const [drawn] = await boundedLayers(boundingBox(179, -0.1, -179, 0.1));
|
|
180
|
+
expect(drawn.minzoom).toEqual(8);
|
|
181
|
+
});
|
|
182
|
+
it('never starts a layer past the end of its grid', async () => {
|
|
183
|
+
const [drawn] = await boundedLayers(boundingBox(16.4, 48.2, 16.4, 48.2), MERCATOR_SET, 'GoogleMapsCompatible_Level3');
|
|
184
|
+
expect(drawn.minzoom).toEqual(3);
|
|
185
|
+
expect(drawn.maxzoom).toEqual(3);
|
|
186
|
+
});
|
|
187
|
+
it('falls back to the extent on the record when the service publishes none', async () => {
|
|
188
|
+
const [drawn] = await boundedLayers('', DEEP_SET, 'GoogleMapsCompatible', VIENNA_RECORD);
|
|
189
|
+
expect(drawn.bounds).toEqual([16.133423, 48.106056, 16.626434, 48.3348]);
|
|
190
|
+
expect(drawn.minzoom).toEqual(10);
|
|
191
|
+
});
|
|
192
|
+
it('prefers the extent the service publishes to the one on the record', async () => {
|
|
193
|
+
// The record states one extent for everything it references; the service states one per layer
|
|
194
|
+
const [drawn] = await boundedLayers(VIENNA, DEEP_SET, 'GoogleMapsCompatible', [-180, -85, 180, 85]);
|
|
195
|
+
expect(drawn.bounds).toEqual([16.17, 48.1, 16.58, 48.33]);
|
|
196
|
+
expect(drawn.minzoom).toEqual(10);
|
|
197
|
+
});
|
|
198
|
+
it('leaves the extent unset when neither the service nor the record gives one', async () => {
|
|
199
|
+
const [drawn] = await boundedLayers('');
|
|
200
|
+
expect(drawn.bounds).toBeUndefined();
|
|
201
|
+
expect(drawn.minzoom).toEqual(0);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
// Vienna's service, in miniature: tiles sharded over several hosts, only one of which is the
|
|
205
|
+
// host that answered the capabilities request, and every one of them advertised over http
|
|
206
|
+
const SHARDED_TEMPLATES = ['maps1', 'maps2', 'maps'].map(host => `http://${host}.example.org/lb2016/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg`);
|
|
207
|
+
const shardedLayers = (url, templates = SHARDED_TEMPLATES) => resourceFor(capabilities(layer({ links: ['GoogleMapsCompatible_Level3'], templates }), MERCATOR_SET), ['lights'], url).getLayers();
|
|
208
|
+
describe('WmtsResource#getLayers tile hosts', () => {
|
|
209
|
+
it('keeps only the host that served the capabilities document', async () => {
|
|
210
|
+
// MapLibre assigns each tile to a host by coordinate and never retries elsewhere, so a
|
|
211
|
+
// hostname that no longer resolves costs us that share of the tiles for good
|
|
212
|
+
const [drawn] = await shardedLayers('https://maps.example.org/wmts/1.0.0/WMTSCapabilities.xml');
|
|
213
|
+
expect(drawn.tileUrls).toEqual(['https://maps.example.org/lb2016/default/GoogleMapsCompatible_Level3/{z}/{y}/{x}.jpeg']);
|
|
214
|
+
});
|
|
215
|
+
it('reaches that host over https when that is how the capabilities came back', async () => {
|
|
216
|
+
// A document served over https can still advertise http tiles, which the browser blocks
|
|
217
|
+
// as mixed content
|
|
218
|
+
const [drawn] = await shardedLayers('https://maps.example.org/wmts/1.0.0/WMTSCapabilities.xml');
|
|
219
|
+
expect(drawn.tileUrls[0].startsWith('https://')).toBe(true);
|
|
220
|
+
});
|
|
221
|
+
it('leaves every host in place when none of them served the capabilities', async () => {
|
|
222
|
+
const [drawn] = await shardedLayers('https://www.example.org/wmts/1.0.0/WMTSCapabilities.xml');
|
|
223
|
+
expect(drawn.tileUrls).toHaveLength(3);
|
|
224
|
+
expect(drawn.tileUrls[0]).toContain('http://maps1.example.org/');
|
|
225
|
+
});
|
|
226
|
+
it('never downgrades a tile host that already speaks https', async () => {
|
|
227
|
+
const templates = ['https://maps.example.org/lb2016/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg'];
|
|
228
|
+
const [drawn] = await shardedLayers('http://maps.example.org/wmts/1.0.0/WMTSCapabilities.xml', templates);
|
|
229
|
+
expect(drawn.tileUrls[0].startsWith('https://')).toBe(true);
|
|
230
|
+
});
|
|
231
|
+
it('leaves a service whose tiles live on a host of their own alone', async () => {
|
|
232
|
+
const [drawn] = await resourceFor(capabilities(layer({ links: ['GoogleMapsCompatible_Level3'] }), MERCATOR_SET)).getLayers();
|
|
233
|
+
expect(drawn.tileUrls).toEqual(['https://tiles.example.org/lights/default/GoogleMapsCompatible_Level3/{z}/{y}/{x}.png']);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as inflate_1 } from './pako.esm-KbdoS3Oq.js';
|
|
2
|
-
import { g as getDefaultExportFromCjs, L as LercAddCompression, a as LercParameters } from './ogm-alerts.ogm-attributes.ogm-image.ogm-map.ogm-menubar.ogm-metadata.ogm-preview.ogm-previews.ogm-settings.ogm-sidebar.ogm-viewer-
|
|
2
|
+
import { g as getDefaultExportFromCjs, L as LercAddCompression, a as LercParameters } from './ogm-alerts.ogm-attributes.ogm-image.ogm-map.ogm-menubar.ogm-metadata.ogm-preview.ogm-previews.ogm-settings.ogm-sidebar.ogm-viewer-DtEO48bS.js';
|
|
3
3
|
import { B as BaseDecoder } from './basedecoder-BK531nfi.js';
|
|
4
4
|
import './index-DTLAlWKQ.js';
|
|
5
5
|
|
package/dist/esm/loader.js
CHANGED
|
@@ -5,7 +5,7 @@ import { g as globalScripts } from './app-globals-DQuL1Twl.js';
|
|
|
5
5
|
const defineCustomElements = async (win, options) => {
|
|
6
6
|
if (typeof window === 'undefined') return undefined;
|
|
7
7
|
await globalScripts();
|
|
8
|
-
return bootstrapLazy([["ogm-alerts_11",[[513,"ogm-viewer",{"recordUrl":[1,"record-url"],"theme":[1],"record":[32],"error":[32],"previewOpacity":[32],"sidebarOpen":[32],"loading":[32],"loadRecord":[64]},[[0,"sidebarToggled","toggleSidebar"],[0,"opacityChange","adjustPreviewOpacity"],[0,"mapLoading","setLoadingStarted"],[0,"imageLoading","setLoadingStarted"],[0,"mapIdle","setLoadingFinished"],[0,"imageLoaded","setLoadingFinished"]],{"recordUrl":[{"updateRecord":0}],"record":[{"resetLoading":0}]}],[513,"ogm-previews",{"theme":[1],"record":[16],"previewOpacity":[2,"preview-opacity"],"sidebarPadding":[2,"sidebar-padding"],"
|
|
8
|
+
return bootstrapLazy([["ogm-alerts_11",[[513,"ogm-viewer",{"recordUrl":[1,"record-url"],"theme":[1],"hideTitle":[4,"hide-title"],"record":[32],"error":[32],"previewOpacity":[32],"sidebarOpen":[32],"loading":[32],"loadRecord":[64]},[[0,"sidebarToggled","toggleSidebar"],[0,"opacityChange","adjustPreviewOpacity"],[0,"mapLoading","setLoadingStarted"],[0,"imageLoading","setLoadingStarted"],[0,"mapIdle","setLoadingFinished"],[0,"imageLoaded","setLoadingFinished"]],{"recordUrl":[{"updateRecord":0}],"record":[{"resetLoading":0}]}],[513,"ogm-previews",{"theme":[1],"record":[16],"previewOpacity":[2,"preview-opacity"],"sidebarPadding":[2,"sidebar-padding"],"resources":[32]},null,{"record":[{"getSources":0}]}],[513,"ogm-sidebar",{"record":[16],"theme":[1],"open":[4]}],[513,"ogm-menubar",{"record":[16],"theme":[1],"loading":[4],"hideTitle":[4,"hide-title"]}],[513,"ogm-preview",{"theme":[1],"previewResource":[16],"previewOpacity":[2,"preview-opacity"],"sidebarPadding":[2,"sidebar-padding"],"error":[32]},[[0,"previewError","handlePreviewError"]],{"previewResource":[{"resetError":0}]}],[513,"ogm-metadata",{"record":[16],"theme":[1],"fieldNames":[16],"filteredRecord":[32]}],[513,"ogm-settings",{"record":[16]},[[0,"input","handleOpacityChange"]]],[513,"ogm-map",{"previewResource":[16],"theme":[1],"padding":[2],"easeMapTo":[64]},[[16,"featureSelected","handleFeatureSelected"]],{"previewResource":[{"loadResource":0}],"theme":[{"onThemeChange":0}],"padding":[{"onPaddingChange":0}]}],[513,"ogm-alerts",{"theme":[1],"error":[16]}],[513,"ogm-image",{"previewResource":[16],"theme":[1],"padding":[2]},null,{"previewResource":[{"onSourceChange":0}],"padding":[{"onPaddingChange":0}]}],[513,"ogm-attributes",{"features":[16],"currentIndex":[32]},null,{"features":[{"onFeaturesChange":0}],"currentIndex":[{"onCurrentIndexChange":0}]}]]]], options);
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export { defineCustomElements };
|