@basemaps/lambda-tiler 6.29.0 → 6.30.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/CHANGELOG.md +25 -0
- package/build/__tests__/config.data.d.ts +6 -0
- package/build/__tests__/config.data.d.ts.map +1 -0
- package/build/__tests__/config.data.js +81 -0
- package/build/__tests__/config.data.js.map +1 -0
- package/build/__tests__/index.test.js +4 -3
- package/build/__tests__/index.test.js.map +1 -0
- package/build/__tests__/route.test.js +1 -0
- package/build/__tests__/route.test.js.map +1 -0
- package/build/__tests__/tiff.cache.test.js +1 -0
- package/build/__tests__/tiff.cache.test.js.map +1 -0
- package/build/__tests__/tile.cache.key.test.js +1 -0
- package/build/__tests__/tile.cache.key.test.js.map +1 -0
- package/build/__tests__/tile.set.cache.test.js +2 -53
- package/build/__tests__/tile.set.cache.test.js.map +1 -0
- package/build/__tests__/tile.set.test.js +1 -0
- package/build/__tests__/tile.set.test.js.map +1 -0
- package/build/__tests__/tile.style.json.test.js +1 -0
- package/build/__tests__/tile.style.json.test.js.map +1 -0
- package/build/__tests__/wmts.capability.test.d.ts +1 -1
- package/build/__tests__/wmts.capability.test.d.ts.map +1 -1
- package/build/__tests__/wmts.capability.test.js +207 -128
- package/build/__tests__/wmts.capability.test.js.map +1 -0
- package/build/__tests__/xyz.test.js +6 -37
- package/build/__tests__/xyz.test.js.map +1 -0
- package/build/__tests__/xyz.util.d.ts +0 -2
- package/build/__tests__/xyz.util.d.ts.map +1 -1
- package/build/__tests__/xyz.util.js +7 -29
- package/build/__tests__/xyz.util.js.map +1 -0
- package/build/api.key.js +1 -0
- package/build/api.key.js.map +1 -0
- package/build/cli/dump.js +1 -0
- package/build/cli/dump.js.map +1 -0
- package/build/cli/tile.set.local.js +1 -0
- package/build/cli/tile.set.local.js.map +1 -0
- package/build/cotar.cache.d.ts +25 -0
- package/build/cotar.cache.d.ts.map +1 -0
- package/build/cotar.cache.js +50 -0
- package/build/cotar.cache.js.map +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +31 -35
- package/build/index.js.map +1 -0
- package/build/router.js +1 -0
- package/build/router.js.map +1 -0
- package/build/routes/__tests__/attribution.test.js +5 -3
- package/build/routes/__tests__/attribution.test.js.map +1 -0
- package/build/routes/__tests__/fonts.test.js +9 -1
- package/build/routes/__tests__/fonts.test.js.map +1 -0
- package/build/routes/__tests__/health.test.js +1 -0
- package/build/routes/__tests__/health.test.js.map +1 -0
- package/build/routes/__tests__/imagery.test.js +1 -0
- package/build/routes/__tests__/imagery.test.js.map +1 -0
- package/build/routes/__tests__/memory.fs.js +1 -0
- package/build/routes/__tests__/memory.fs.js.map +1 -0
- package/build/routes/__tests__/sprites.test.js +1 -0
- package/build/routes/__tests__/sprites.test.js.map +1 -0
- package/build/routes/__tests__/wmts.test.js +59 -10
- package/build/routes/__tests__/wmts.test.js.map +1 -0
- package/build/routes/api.d.ts +0 -1
- package/build/routes/api.d.ts.map +1 -1
- package/build/routes/api.js +1 -3
- package/build/routes/api.js.map +1 -0
- package/build/routes/attribution.js +1 -0
- package/build/routes/attribution.js.map +1 -0
- package/build/routes/esri/rest.js +1 -0
- package/build/routes/esri/rest.js.map +1 -0
- package/build/routes/fonts.d.ts.map +1 -1
- package/build/routes/fonts.js +9 -1
- package/build/routes/fonts.js.map +1 -0
- package/build/routes/health.js +1 -0
- package/build/routes/health.js.map +1 -0
- package/build/routes/imagery.d.ts +8 -1
- package/build/routes/imagery.d.ts.map +1 -1
- package/build/routes/imagery.js +6 -7
- package/build/routes/imagery.js.map +1 -0
- package/build/routes/response.js +1 -0
- package/build/routes/response.js.map +1 -0
- package/build/routes/sprites.d.ts.map +1 -1
- package/build/routes/sprites.js +8 -14
- package/build/routes/sprites.js.map +1 -0
- package/build/routes/tile.etag.js +1 -0
- package/build/routes/tile.etag.js.map +1 -0
- package/build/routes/tile.js +1 -0
- package/build/routes/tile.js.map +1 -0
- package/build/routes/tile.json.d.ts.map +1 -1
- package/build/routes/tile.json.js +2 -2
- package/build/routes/tile.json.js.map +1 -0
- package/build/routes/tile.style.json.js +1 -0
- package/build/routes/tile.style.json.js.map +1 -0
- package/build/routes/tile.wmts.d.ts.map +1 -1
- package/build/routes/tile.wmts.js +19 -23
- package/build/routes/tile.wmts.js.map +1 -0
- package/build/routes/tile.xyz.js +1 -0
- package/build/routes/tile.xyz.js.map +1 -0
- package/build/source.tracer.js +1 -0
- package/build/source.tracer.js.map +1 -0
- package/build/tiff.cache.js +1 -0
- package/build/tiff.cache.js.map +1 -0
- package/build/tile.set.cache.d.ts +0 -1
- package/build/tile.set.cache.d.ts.map +1 -1
- package/build/tile.set.cache.js +1 -29
- package/build/tile.set.cache.js.map +1 -0
- package/build/tile.set.js +1 -0
- package/build/tile.set.js.map +1 -0
- package/build/tile.set.raster.d.ts.map +1 -1
- package/build/tile.set.raster.js +6 -3
- package/build/tile.set.raster.js.map +1 -0
- package/build/tile.set.vector.d.ts +0 -7
- package/build/tile.set.vector.d.ts.map +1 -1
- package/build/tile.set.vector.js +3 -20
- package/build/tile.set.vector.js.map +1 -0
- package/build/validate.js +1 -0
- package/build/validate.js.map +1 -0
- package/build/wmts.capability.d.ts +26 -12
- package/build/wmts.capability.d.ts.map +1 -1
- package/build/wmts.capability.js +136 -51
- package/build/wmts.capability.js.map +1 -0
- package/dist/index.js +86 -72
- package/dist/node_modules/.package-lock.json +1 -1
- package/dist/package-lock.json +2 -2
- package/dist/package.json +1 -1
- package/package.json +7 -7
- package/src/__tests__/config.data.ts +82 -0
- package/src/__tests__/index.test.ts +3 -3
- package/src/__tests__/tile.set.cache.test.ts +1 -67
- package/src/__tests__/wmts.capability.test.ts +224 -154
- package/src/__tests__/xyz.test.ts +5 -49
- package/src/__tests__/xyz.util.ts +6 -31
- package/src/cotar.cache.ts +54 -0
- package/src/index.ts +30 -33
- package/src/routes/__tests__/attribution.test.ts +4 -4
- package/src/routes/__tests__/fonts.test.ts +10 -1
- package/src/routes/__tests__/wmts.test.ts +75 -15
- package/src/routes/api.ts +0 -4
- package/src/routes/fonts.ts +9 -1
- package/src/routes/imagery.ts +9 -7
- package/src/routes/sprites.ts +7 -15
- package/src/routes/tile.json.ts +1 -2
- package/src/routes/tile.wmts.ts +20 -22
- package/src/tile.set.cache.ts +1 -28
- package/src/tile.set.raster.ts +4 -2
- package/src/tile.set.vector.ts +3 -21
- package/src/wmts.capability.ts +143 -58
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ConfigImagery } from '@basemaps/config';
|
|
2
|
+
import { GoogleTms, ImageFormat, Nztm2000QuadTms } from '@basemaps/geo';
|
|
3
|
+
import { V, VNodeElement } from '@basemaps/shared';
|
|
3
4
|
import { roundNumbersInString } from '@basemaps/test/build/rounding.js';
|
|
4
|
-
import { createHash } from 'crypto';
|
|
5
5
|
import o from 'ospec';
|
|
6
6
|
import { WmtsCapabilities } from '../wmts.capability.js';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
import 'source-map-support/register.js';
|
|
7
|
+
import { Imagery2193, Imagery3857, Provider, TileSetAerial } from './config.data.js';
|
|
10
8
|
|
|
11
9
|
function tags(node: VNodeElement | null | undefined, tag: string): VNodeElement[] {
|
|
12
10
|
if (node == null) return [];
|
|
@@ -18,16 +16,21 @@ function listTag(node: VNodeElement | null | undefined, tag: string): string[] {
|
|
|
18
16
|
|
|
19
17
|
o.spec('WmtsCapabilities', () => {
|
|
20
18
|
const apiKey = 'secret1234';
|
|
21
|
-
|
|
22
|
-
const
|
|
19
|
+
|
|
20
|
+
const allImagery = new Map();
|
|
21
|
+
allImagery.set(Imagery2193.id, Imagery2193);
|
|
22
|
+
allImagery.set(Imagery3857.id, Imagery3857);
|
|
23
23
|
|
|
24
24
|
o('should output the requested formats', () => {
|
|
25
25
|
const wmts = new WmtsCapabilities({
|
|
26
26
|
httpBase: 'https://basemaps.test',
|
|
27
27
|
provider: Provider,
|
|
28
|
-
|
|
28
|
+
tileMatrix: [GoogleTms],
|
|
29
|
+
tileSet: TileSetAerial,
|
|
30
|
+
imagery: allImagery,
|
|
29
31
|
apiKey,
|
|
30
32
|
formats: [ImageFormat.Avif],
|
|
33
|
+
isIndividualLayers: false,
|
|
31
34
|
}).toVNode();
|
|
32
35
|
|
|
33
36
|
const urls = tags(wmts, 'ResourceURL');
|
|
@@ -38,12 +41,106 @@ o.spec('WmtsCapabilities', () => {
|
|
|
38
41
|
);
|
|
39
42
|
});
|
|
40
43
|
|
|
44
|
+
o('should be seting encoding to utf-8', () => {
|
|
45
|
+
const xml = new WmtsCapabilities({
|
|
46
|
+
httpBase: 'https://basemaps.test',
|
|
47
|
+
provider: Provider,
|
|
48
|
+
tileMatrix: [GoogleTms],
|
|
49
|
+
tileSet: TileSetAerial,
|
|
50
|
+
imagery: allImagery,
|
|
51
|
+
apiKey,
|
|
52
|
+
formats: [ImageFormat.Avif],
|
|
53
|
+
isIndividualLayers: false,
|
|
54
|
+
}).toXml();
|
|
55
|
+
|
|
56
|
+
o(xml.split('\n')[0]).deepEquals('<?xml version="1.0" encoding="utf-8"?>');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
o('should support unicorns and rainbows', () => {
|
|
60
|
+
const tileSet = { ...TileSetAerial };
|
|
61
|
+
tileSet.name = '🦄_🌈_2022_0-5m';
|
|
62
|
+
tileSet.title = '🦄 🌈 Imagery (2022)';
|
|
63
|
+
tileSet.description = '🦄 🌈 Description';
|
|
64
|
+
const wmts = new WmtsCapabilities({
|
|
65
|
+
httpBase: 'https://basemaps.test',
|
|
66
|
+
provider: Provider,
|
|
67
|
+
tileMatrix: [GoogleTms],
|
|
68
|
+
tileSet,
|
|
69
|
+
imagery: allImagery,
|
|
70
|
+
apiKey,
|
|
71
|
+
formats: [ImageFormat.Avif],
|
|
72
|
+
isIndividualLayers: false,
|
|
73
|
+
}).toVNode();
|
|
74
|
+
|
|
75
|
+
const urls = tags(wmts, 'ResourceURL');
|
|
76
|
+
o(urls.length).equals(1);
|
|
77
|
+
o(urls[0].attrs.template).equals(
|
|
78
|
+
'https://basemaps.test/v1/tiles/🦄-🌈-2022-0.5m/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.avif?api=secret1234',
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const layer = tags(wmts, 'Layer')[0];
|
|
82
|
+
|
|
83
|
+
const title = layer.find('ows:Title')?.toString();
|
|
84
|
+
o(title).equals('<ows:Title>🦄 🌈 Imagery (2022)</ows:Title>');
|
|
85
|
+
|
|
86
|
+
const abstract = layer.find('ows:Abstract')?.toString();
|
|
87
|
+
o(abstract).equals('<ows:Abstract>🦄 🌈 Description</ows:Abstract>');
|
|
88
|
+
|
|
89
|
+
const identifier = layer.find('ows:Identifier')?.toString();
|
|
90
|
+
o(identifier).equals('<ows:Identifier>🦄-🌈-2022-0.5m</ows:Identifier>');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
o('should sort the sub imagery layers', () => {
|
|
94
|
+
const imageryA = { ...Imagery3857 };
|
|
95
|
+
imageryA.id = 'im_a';
|
|
96
|
+
imageryA.name = 'aaaa';
|
|
97
|
+
imageryA.title = 'aaaa';
|
|
98
|
+
|
|
99
|
+
const imageryB = { ...Imagery3857 };
|
|
100
|
+
imageryB.id = 'im_b';
|
|
101
|
+
imageryB.name = 'bbbb';
|
|
102
|
+
imageryB.title = 'bbbb';
|
|
103
|
+
|
|
104
|
+
const imagery = new Map();
|
|
105
|
+
imagery.set(Imagery3857.id, Imagery3857);
|
|
106
|
+
imagery.set(imageryB.id, imageryB);
|
|
107
|
+
imagery.set(imageryA.id, imageryA);
|
|
108
|
+
const tileSet = {
|
|
109
|
+
...TileSetAerial,
|
|
110
|
+
layers: [
|
|
111
|
+
...TileSetAerial.layers,
|
|
112
|
+
{ [3857]: imageryB.id, title: imageryB.title, name: imageryB.name },
|
|
113
|
+
{ [3857]: imageryA.id, title: imageryA.title, name: imageryA.name },
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const wmts = new WmtsCapabilities({
|
|
118
|
+
httpBase: 'https://basemaps.test',
|
|
119
|
+
provider: Provider,
|
|
120
|
+
tileMatrix: [GoogleTms],
|
|
121
|
+
tileSet,
|
|
122
|
+
imagery,
|
|
123
|
+
apiKey,
|
|
124
|
+
isIndividualLayers: true,
|
|
125
|
+
}).toVNode();
|
|
126
|
+
|
|
127
|
+
const layers = tags(wmts, 'Layer').map((c) => c.find('ows:Title')?.textContent);
|
|
128
|
+
|
|
129
|
+
// The base layer "Aerial Imagery" should always be first then all sub layers after
|
|
130
|
+
o(layers).deepEquals(['Aerial Imagery', 'aaaa', 'bbbb', 'Ōtorohanga 0.1m Urban Aerial Photos (2021)']);
|
|
131
|
+
});
|
|
132
|
+
|
|
41
133
|
o('should build capability xml for tileset and projection', () => {
|
|
134
|
+
const imagery = new Map();
|
|
135
|
+
imagery.set(Imagery3857.id, Imagery3857);
|
|
42
136
|
const wmts = new WmtsCapabilities({
|
|
43
137
|
httpBase: 'https://basemaps.test',
|
|
44
138
|
provider: Provider,
|
|
45
|
-
|
|
139
|
+
tileMatrix: [GoogleTms],
|
|
140
|
+
tileSet: TileSetAerial,
|
|
141
|
+
imagery,
|
|
46
142
|
apiKey,
|
|
143
|
+
isIndividualLayers: false,
|
|
47
144
|
});
|
|
48
145
|
|
|
49
146
|
const raw = wmts.toVNode();
|
|
@@ -53,10 +150,10 @@ o.spec('WmtsCapabilities', () => {
|
|
|
53
150
|
o(serviceId?.find('ows:Title')?.textContent).equals('the title');
|
|
54
151
|
|
|
55
152
|
o(raw.find('TileMatrixSetLink')?.toString()).deepEquals(
|
|
56
|
-
V('TileMatrixSetLink', [V('TileMatrixSet', '
|
|
153
|
+
V('TileMatrixSetLink', [V('TileMatrixSet', 'WebMercatorQuad')]).toString(),
|
|
57
154
|
);
|
|
58
155
|
|
|
59
|
-
const layer = raw
|
|
156
|
+
const layer = raw.find('Contents', 'Layer');
|
|
60
157
|
|
|
61
158
|
o(listTag(layer, 'Format')).deepEquals([
|
|
62
159
|
V('Format', 'image/jpeg').toString(),
|
|
@@ -64,41 +161,47 @@ o.spec('WmtsCapabilities', () => {
|
|
|
64
161
|
V('Format', 'image/png').toString(),
|
|
65
162
|
]);
|
|
66
163
|
|
|
67
|
-
o(listTag(layer, 'ows:BoundingBox')).deepEquals([
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
164
|
+
o(listTag(layer, 'ows:BoundingBox').map((s) => roundNumbersInString(s, 4))).deepEquals([
|
|
165
|
+
'<ows:BoundingBox crs="urn:ogc:def:crs:EPSG::3857">\n' +
|
|
166
|
+
' <ows:LowerCorner>19457809.9203 -4609458.5537</ows:LowerCorner>\n' +
|
|
167
|
+
' <ows:UpperCorner>19509787.0995 -4578883.7424</ows:UpperCorner>\n' +
|
|
168
|
+
'</ows:BoundingBox>',
|
|
72
169
|
]);
|
|
73
170
|
|
|
74
171
|
o(listTag(layer, 'ows:WGS84BoundingBox').map((s) => roundNumbersInString(s, 4))).deepEquals([
|
|
75
172
|
'<ows:WGS84BoundingBox crs="urn:ogc:def:crs:OGC:2:84">\n' +
|
|
76
|
-
' <ows:LowerCorner
|
|
77
|
-
' <ows:UpperCorner>
|
|
173
|
+
' <ows:LowerCorner>174.7925 -38.2123</ows:LowerCorner>\n' +
|
|
174
|
+
' <ows:UpperCorner>175.2594 -37.9962</ows:UpperCorner>\n' +
|
|
78
175
|
'</ows:WGS84BoundingBox>',
|
|
79
176
|
]);
|
|
80
177
|
|
|
81
|
-
o(layer?.find('ows:Abstract')?.textContent).equals('aerial:description');
|
|
82
|
-
o(layer?.find('ows:Title')?.textContent).equals('aerial:title');
|
|
83
178
|
o(layer?.find('ows:Identifier')?.textContent).equals('aerial');
|
|
179
|
+
o(layer?.find('ows:Title')?.textContent).equals('Aerial Imagery');
|
|
180
|
+
o(layer?.find('ows:Abstract')?.textContent).equals('aerial__description');
|
|
84
181
|
|
|
85
182
|
o(layer?.find('Style')?.toString()).equals(
|
|
86
183
|
V('Style', { isDefault: 'true' }, [V('ows:Title', 'Default Style'), V('ows:Identifier', 'default')]).toString(),
|
|
87
184
|
);
|
|
185
|
+
});
|
|
88
186
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
187
|
+
o('should include output the correct TileMatrix', () => {
|
|
188
|
+
const raw = new WmtsCapabilities({
|
|
189
|
+
httpBase: 'https://basemaps.test',
|
|
190
|
+
provider: Provider,
|
|
191
|
+
tileMatrix: [GoogleTms],
|
|
192
|
+
tileSet: TileSetAerial,
|
|
193
|
+
imagery: allImagery,
|
|
194
|
+
apiKey,
|
|
195
|
+
isIndividualLayers: false,
|
|
196
|
+
}).toVNode();
|
|
197
|
+
const layer = raw.find('Contents', 'Layer');
|
|
95
198
|
|
|
96
|
-
o(layer?.find('TileMatrixSetLink', 'TileMatrixSet')?.textContent).equals('
|
|
199
|
+
o(layer?.find('TileMatrixSetLink', 'TileMatrixSet')?.textContent).equals('WebMercatorQuad');
|
|
97
200
|
|
|
98
201
|
const matrix = tags(raw, 'TileMatrixSet')[1];
|
|
99
202
|
const matrixId = raw?.find('Contents', 'TileMatrixSet', 'ows:Identifier') ?? null;
|
|
100
203
|
o(matrix.find('ows:Identifier')).equals(matrixId);
|
|
101
|
-
o(matrixId?.textContent).equals('
|
|
204
|
+
o(matrixId?.textContent).equals('WebMercatorQuad');
|
|
102
205
|
|
|
103
206
|
o(matrix.find('ows:SupportedCRS')?.textContent).deepEquals('urn:ogc:def:crs:EPSG::3857');
|
|
104
207
|
o(matrix.find('WellKnownScaleSet')?.textContent).deepEquals(
|
|
@@ -123,46 +226,62 @@ o.spec('WmtsCapabilities', () => {
|
|
|
123
226
|
|
|
124
227
|
compareMatrix(tileMatrices[0], '0', 1, 559082264.028717);
|
|
125
228
|
compareMatrix(tileMatrices[10], '10', 1024, 545978.773465544);
|
|
126
|
-
|
|
127
|
-
const xml = new WmtsCapabilities({
|
|
128
|
-
httpBase: 'https://basemaps.test',
|
|
129
|
-
provider: Provider,
|
|
130
|
-
layers: [tileSet],
|
|
131
|
-
apiKey,
|
|
132
|
-
}).toXml();
|
|
133
|
-
|
|
134
|
-
o(xml).deepEquals('<?xml version="1.0"?>\n' + raw?.toString());
|
|
135
|
-
|
|
136
|
-
o(createHash('sha256').update(Buffer.from(xml)).digest('base64')).equals(
|
|
137
|
-
'beknYyMt8v74vK4p84AS3c1OnBSJ+ZE0kan+mMVQS1A=',
|
|
138
|
-
);
|
|
139
229
|
});
|
|
140
230
|
|
|
141
|
-
o('should
|
|
231
|
+
o('should output individual imagery sets', () => {
|
|
232
|
+
const imagery = new Map<string, ConfigImagery>();
|
|
233
|
+
imagery.set(Imagery3857.id, Imagery3857);
|
|
234
|
+
imagery.set(Imagery2193.id, Imagery2193);
|
|
142
235
|
const raw = new WmtsCapabilities({
|
|
143
236
|
httpBase: 'https://basemaps.test',
|
|
144
237
|
provider: Provider,
|
|
145
|
-
|
|
238
|
+
tileMatrix: [GoogleTms],
|
|
239
|
+
tileSet: TileSetAerial,
|
|
240
|
+
imagery: imagery,
|
|
241
|
+
formats: [ImageFormat.Png],
|
|
242
|
+
isIndividualLayers: true,
|
|
146
243
|
}).toVNode();
|
|
147
244
|
|
|
148
245
|
const tms = raw?.find('TileMatrixSet', 'ows:Identifier');
|
|
149
246
|
|
|
150
|
-
o(tms?.textContent).equals('
|
|
247
|
+
o(tms?.textContent).equals('WebMercatorQuad');
|
|
151
248
|
|
|
152
249
|
const urls = Array.from(raw ? raw.tags('ResourceURL') : []);
|
|
153
|
-
o(urls.length).equals(
|
|
154
|
-
o(urls[
|
|
250
|
+
o(urls.length).equals(2);
|
|
251
|
+
o(urls[0].toString()).deepEquals(
|
|
155
252
|
'<ResourceURL format="image/png" resourceType="tile" ' +
|
|
156
|
-
'template="https://basemaps.test/v1/tiles/
|
|
253
|
+
'template="https://basemaps.test/v1/tiles/aerial/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png" />',
|
|
157
254
|
);
|
|
255
|
+
o(urls[1].toString()).deepEquals(
|
|
256
|
+
'<ResourceURL format="image/png" resourceType="tile" ' +
|
|
257
|
+
'template="https://basemaps.test/v1/tiles/ōtorohanga-urban-2021-0.1m/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png" />',
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
const layers = [...raw.tags('Layer')];
|
|
261
|
+
|
|
262
|
+
o(layers.length).equals(2);
|
|
263
|
+
o(layers[0].find('ows:Title')?.textContent).equals('Aerial Imagery');
|
|
264
|
+
|
|
265
|
+
o(layers[1].find('ows:Title')?.textContent).equals('Ōtorohanga 0.1m Urban Aerial Photos (2021)');
|
|
266
|
+
o(layers[1].find('ows:Identifier')?.textContent).equals('ōtorohanga-urban-2021-0.1m');
|
|
267
|
+
o(layers[1].find('ows:Keywords', 'ows:Keyword')?.textContent).equals('Urban Aerial Photos');
|
|
158
268
|
});
|
|
159
269
|
|
|
160
270
|
o('should support multiple projections', () => {
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
271
|
+
const imagery = new Map<string, ConfigImagery>();
|
|
272
|
+
imagery.set(Imagery3857.id, Imagery3857);
|
|
273
|
+
imagery.set(Imagery2193.id, Imagery2193);
|
|
274
|
+
const raw = new WmtsCapabilities({
|
|
275
|
+
httpBase: 'https://basemaps.test',
|
|
276
|
+
provider: Provider,
|
|
277
|
+
tileMatrix: [GoogleTms, Nztm2000QuadTms],
|
|
278
|
+
tileSet: TileSetAerial,
|
|
279
|
+
imagery: imagery,
|
|
280
|
+
formats: [ImageFormat.Png],
|
|
281
|
+
isIndividualLayers: false,
|
|
282
|
+
}).toVNode();
|
|
164
283
|
|
|
165
|
-
const layers = tags(
|
|
284
|
+
const layers = tags(raw, 'Layer');
|
|
166
285
|
o(layers.length).equals(1);
|
|
167
286
|
const layer = layers[0];
|
|
168
287
|
|
|
@@ -171,126 +290,77 @@ o.spec('WmtsCapabilities', () => {
|
|
|
171
290
|
'ows:Title',
|
|
172
291
|
'ows:Abstract',
|
|
173
292
|
'ows:Identifier',
|
|
293
|
+
'ows:Keywords',
|
|
174
294
|
'ows:BoundingBox',
|
|
175
295
|
'ows:BoundingBox',
|
|
176
296
|
'ows:WGS84BoundingBox',
|
|
177
297
|
'Style',
|
|
178
298
|
'Format',
|
|
179
|
-
'Format',
|
|
180
|
-
'Format',
|
|
181
299
|
'TileMatrixSetLink',
|
|
182
300
|
'TileMatrixSetLink',
|
|
183
301
|
'ResourceURL',
|
|
184
|
-
'ResourceURL',
|
|
185
|
-
'ResourceURL',
|
|
186
302
|
]);
|
|
187
303
|
|
|
304
|
+
o(layer.find('ows:Title')?.textContent).equals('Aerial Imagery');
|
|
305
|
+
o(layer.find('ows:Keywords')?.toString()).equals(
|
|
306
|
+
'<ows:Keywords>\n <ows:Keyword>Basemap</ows:Keyword>\n</ows:Keywords>',
|
|
307
|
+
);
|
|
308
|
+
o(layer.find('ows:Identifier')?.textContent).equals('aerial');
|
|
309
|
+
|
|
188
310
|
const sets = tags(layer, 'TileMatrixSet');
|
|
189
311
|
|
|
190
312
|
o(sets.length).equals(2);
|
|
191
|
-
o(sets[0].toString()).equals('<TileMatrixSet>
|
|
192
|
-
o(sets[1].toString()).equals('<TileMatrixSet>
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
o(
|
|
196
|
-
|
|
197
|
-
o(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
o(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
new FakeTileSet(TileSetName.aerial, Nztm2000Tms, 'aerial-title'),
|
|
207
|
-
new FakeTileSet('01E7PJFR9AMQFJ05X9G7FQ3XMW', Nztm2000Tms, 'imagery-title'),
|
|
208
|
-
];
|
|
209
|
-
const nodes = new WmtsCapabilities({ httpBase: 'basemaps.test', provider: Provider, layers: ts }).toVNode();
|
|
210
|
-
const layers = tags(nodes, 'Layer');
|
|
211
|
-
o(layers.length).equals(2);
|
|
212
|
-
|
|
213
|
-
o(layers[0].find('ows:Title')?.textContent).equals('aerial-title');
|
|
214
|
-
o(layers[0].find('TileMatrixSet')?.textContent).equals('EPSG:2193');
|
|
313
|
+
o(sets[0].toString()).equals('<TileMatrixSet>WebMercatorQuad</TileMatrixSet>');
|
|
314
|
+
o(sets[1].toString()).equals('<TileMatrixSet>NZTM2000Quad</TileMatrixSet>');
|
|
315
|
+
|
|
316
|
+
const boundingBoxes = tags(layer, 'ows:BoundingBox');
|
|
317
|
+
o(boundingBoxes.length).equals(2);
|
|
318
|
+
o(boundingBoxes[0].attrs.crs).equals('urn:ogc:def:crs:EPSG::3857');
|
|
319
|
+
o(boundingBoxes[0].children.map((c) => roundNumbersInString(c.textContent, 4))).deepEquals([
|
|
320
|
+
'19457809.9203 -4609458.5537',
|
|
321
|
+
'19509787.0995 -4578883.7424',
|
|
322
|
+
]);
|
|
323
|
+
o(boundingBoxes[1].attrs.crs).equals('urn:ogc:def:crs:EPSG::2193');
|
|
324
|
+
o(boundingBoxes[1].children.map((c) => roundNumbersInString(c.textContent, 4))).deepEquals([
|
|
325
|
+
'5766358.9964 1757351.3045',
|
|
326
|
+
'5793264.8304 1798321.5516',
|
|
327
|
+
]);
|
|
215
328
|
|
|
216
|
-
|
|
217
|
-
o(
|
|
329
|
+
const wgs84 = layer.find('ows:WGS84BoundingBox');
|
|
330
|
+
o(wgs84?.attrs.crs).equals('urn:ogc:def:crs:OGC:2:84');
|
|
331
|
+
o(wgs84?.children.map((c) => roundNumbersInString(c.textContent, 4))).deepEquals([
|
|
332
|
+
'174.7925 -38.2123',
|
|
333
|
+
'175.2594 -37.9962',
|
|
334
|
+
]);
|
|
218
335
|
});
|
|
219
336
|
|
|
220
|
-
o('should
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
),
|
|
232
|
-
];
|
|
233
|
-
const nodes = new WmtsCapabilities({ httpBase: 'basemaps.test', provider: Provider, layers: ts }).toVNode();
|
|
234
|
-
const layers = tags(nodes, 'Layer');
|
|
235
|
-
|
|
236
|
-
o(layers.length).equals(2);
|
|
237
|
-
|
|
238
|
-
const boundingBoxes = tags(layers[0], 'ows:BoundingBox');
|
|
239
|
-
o(boundingBoxes.length).equals(1);
|
|
337
|
+
o('should only output imagery if exists', () => {
|
|
338
|
+
const imagery = new Map<string, ConfigImagery>();
|
|
339
|
+
const raw = new WmtsCapabilities({
|
|
340
|
+
httpBase: 'https://basemaps.test',
|
|
341
|
+
provider: Provider,
|
|
342
|
+
tileMatrix: [Nztm2000QuadTms],
|
|
343
|
+
tileSet: TileSetAerial,
|
|
344
|
+
imagery: imagery,
|
|
345
|
+
formats: [ImageFormat.Png],
|
|
346
|
+
isIndividualLayers: true,
|
|
347
|
+
}).toVNode();
|
|
240
348
|
|
|
241
|
-
const
|
|
242
|
-
o(
|
|
243
|
-
const secondTitle = layers[1].children[0].textContent;
|
|
244
|
-
o(secondTitle).equals('west-coast_rural_2016-17_0-3m');
|
|
245
|
-
});
|
|
349
|
+
const layers = tags(raw, 'Layer');
|
|
350
|
+
o(layers.length).equals(1);
|
|
246
351
|
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const nodes = new WmtsCapabilities({ httpBase: 'basemaps.test', provider: Provider, layers: ts }).toVNode();
|
|
258
|
-
|
|
259
|
-
const allMatrixes = tags(nodes, 'TileMatrixSet');
|
|
260
|
-
|
|
261
|
-
o(allMatrixes[0].children[0].textContent).equals('EPSG:2193');
|
|
262
|
-
o(allMatrixes[1].children[0].textContent).equals('EPSG:2193');
|
|
263
|
-
o(allMatrixes[2].children[0].textContent).equals('EPSG:3857');
|
|
264
|
-
o(allMatrixes[3].children[0].textContent).equals('NZTM2000Quad');
|
|
265
|
-
|
|
266
|
-
o(allMatrixes[4].find('ows:Identifier')?.textContent).equals('EPSG:2193');
|
|
267
|
-
o(allMatrixes[5].find('ows:Identifier')?.textContent).equals('EPSG:3857');
|
|
268
|
-
o(allMatrixes[6].find('ows:Identifier')?.textContent).equals('NZTM2000Quad');
|
|
269
|
-
o(allMatrixes.length).equals(7);
|
|
270
|
-
|
|
271
|
-
const layers = tags(nodes, 'Layer');
|
|
272
|
-
o(layers.length).equals(3);
|
|
273
|
-
|
|
274
|
-
o(layers[0].find('ows:Title')?.textContent).equals(TileSetName.aerial);
|
|
275
|
-
o(layers[0].find('TileMatrixSet')?.textContent).equals('EPSG:2193');
|
|
276
|
-
|
|
277
|
-
o(layers[1].find('ows:Identifier')?.textContent).equals('01F75X9G7FQ3XMWPJFR9AMQFJ0');
|
|
278
|
-
o(layers[1].find('TileMatrixSet')?.textContent).equals('EPSG:2193');
|
|
279
|
-
o(layers[1].find('ows:BoundingBox')?.toString()).equals(
|
|
280
|
-
'<ows:BoundingBox crs="urn:ogc:def:crs:EPSG::2193">\n' +
|
|
281
|
-
' <ows:LowerCorner>2 1</ows:LowerCorner>\n' +
|
|
282
|
-
' <ows:UpperCorner>4 3</ows:UpperCorner>\n' +
|
|
283
|
-
'</ows:BoundingBox>',
|
|
284
|
-
);
|
|
352
|
+
imagery.set(Imagery3857.id, Imagery3857);
|
|
353
|
+
const rawB = new WmtsCapabilities({
|
|
354
|
+
httpBase: 'https://basemaps.test',
|
|
355
|
+
provider: Provider,
|
|
356
|
+
tileMatrix: [Nztm2000QuadTms],
|
|
357
|
+
tileSet: TileSetAerial,
|
|
358
|
+
imagery: imagery,
|
|
359
|
+
formats: [ImageFormat.Png],
|
|
360
|
+
isIndividualLayers: true,
|
|
361
|
+
}).toVNode();
|
|
285
362
|
|
|
286
|
-
|
|
287
|
-
o(
|
|
288
|
-
o(layers[2].find('TileMatrixSet')?.textContent).equals('EPSG:3857');
|
|
289
|
-
o(layers[2].find('ows:BoundingBox')?.toString()).equals(
|
|
290
|
-
'<ows:BoundingBox crs="urn:ogc:def:crs:EPSG::3857">\n' +
|
|
291
|
-
' <ows:LowerCorner>-20037508.3427892 -20037508.3427892</ows:LowerCorner>\n' +
|
|
292
|
-
' <ows:UpperCorner>20037508.3427892 20037508.3427892</ows:UpperCorner>\n' +
|
|
293
|
-
'</ows:BoundingBox>',
|
|
294
|
-
);
|
|
363
|
+
const layersB = tags(rawB, 'Layer');
|
|
364
|
+
o(layersB.length).equals(1);
|
|
295
365
|
});
|
|
296
366
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConfigProvider, StyleJson } from '@basemaps/config';
|
|
2
2
|
import { GoogleTms, Nztm2000QuadTms, TileMatrixSets } from '@basemaps/geo';
|
|
3
|
-
import { Config, Env, LogConfig
|
|
3
|
+
import { Config, Env, LogConfig } from '@basemaps/shared';
|
|
4
4
|
import { round } from '@basemaps/test/build/rounding.js';
|
|
5
5
|
import o from 'ospec';
|
|
6
6
|
import sinon from 'sinon';
|
|
@@ -8,7 +8,8 @@ import { handleRequest } from '../index.js';
|
|
|
8
8
|
import { TileEtag } from '../routes/tile.etag.js';
|
|
9
9
|
import { TileSets } from '../tile.set.cache.js';
|
|
10
10
|
import { TileComposer } from '../tile.set.raster.js';
|
|
11
|
-
import {
|
|
11
|
+
import { Provider } from './config.data.js';
|
|
12
|
+
import { FakeTileSet, FakeTileSetVector, mockRequest } from './xyz.util.js';
|
|
12
13
|
|
|
13
14
|
const sandbox = sinon.createSandbox();
|
|
14
15
|
|
|
@@ -142,51 +143,6 @@ o.spec('LambdaXyz', () => {
|
|
|
142
143
|
}
|
|
143
144
|
});
|
|
144
145
|
|
|
145
|
-
o.spec('WMTSCapabilities', () => {
|
|
146
|
-
o('should 304 if a xml is not modified', async () => {
|
|
147
|
-
delete process.env[Env.PublicUrlBase];
|
|
148
|
-
o.timeout(1000);
|
|
149
|
-
const key = 'NuirTK8fozzCJV1iG1FznmdHhKvk6WaWuDhhEA1d40c=';
|
|
150
|
-
const request = mockRequest('/v1/tiles/WMTSCapabilities.xml', 'get', {
|
|
151
|
-
'if-none-match': key,
|
|
152
|
-
...apiKeyHeader,
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
const res = await handleRequest(request);
|
|
156
|
-
|
|
157
|
-
if (res.status === 200) {
|
|
158
|
-
o(res.header('eTaG')).equals(key); // this line is useful for discovering the new etag
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
o(res.status).equals(304);
|
|
163
|
-
o(rasterMock.calls.length).equals(0);
|
|
164
|
-
|
|
165
|
-
o(request.logContext['cache']).deepEquals({ key, match: key, hit: true });
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
o('should serve WMTSCapabilities for tile_set', async () => {
|
|
169
|
-
const request = mockRequest('/v1/tiles/aerial@beta/WMTSCapabilities.xml', 'get', apiKeyHeader);
|
|
170
|
-
|
|
171
|
-
const res = await handleRequest(request);
|
|
172
|
-
o(res.status).equals(200);
|
|
173
|
-
o(res.header('content-type')).equals('text/xml');
|
|
174
|
-
o(res.header('cache-control')).equals('max-age=0');
|
|
175
|
-
|
|
176
|
-
const body = Buffer.from(res.body ?? '', 'base64').toString();
|
|
177
|
-
o(body.slice(0, 100)).equals(
|
|
178
|
-
'<?xml version="1.0"?>\n' + '<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.op',
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
const vdom = await VNodeParser.parse(body);
|
|
182
|
-
const url = vdom.tags('ResourceURL').next().value;
|
|
183
|
-
o(url?.toString()).equals(
|
|
184
|
-
'<ResourceURL format="image/jpeg" resourceType="tile" ' +
|
|
185
|
-
`template="https://tiles.test/v1/tiles/aerial@beta/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.jpeg?api=${apiKey}" />`,
|
|
186
|
-
);
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
|
|
190
146
|
o.spec('tileJson', () => {
|
|
191
147
|
o('should 404 if invalid url is given', async () => {
|
|
192
148
|
const request = mockRequest('/v1/tiles/tile.json', 'get', apiKeyHeader);
|
|
@@ -217,7 +173,7 @@ o.spec('LambdaXyz', () => {
|
|
|
217
173
|
|
|
218
174
|
const body = Buffer.from(res.body ?? '', 'base64').toString();
|
|
219
175
|
o(JSON.parse(body)).deepEquals({
|
|
220
|
-
tiles: [`https://tiles.test/v1/tiles/topographic/
|
|
176
|
+
tiles: [`https://tiles.test/v1/tiles/topographic/WebMercatorQuad/{z}/{x}/{y}.pbf?api=${apiKey}`],
|
|
221
177
|
tilejson: '3.0.0',
|
|
222
178
|
});
|
|
223
179
|
});
|
|
@@ -234,7 +190,7 @@ o.spec('LambdaXyz', () => {
|
|
|
234
190
|
|
|
235
191
|
const body = Buffer.from(res.body ?? '', 'base64').toString();
|
|
236
192
|
o(JSON.parse(body)).deepEquals({
|
|
237
|
-
tiles: [`https://tiles.test/v1/tiles/fake-vector/
|
|
193
|
+
tiles: [`https://tiles.test/v1/tiles/fake-vector/WebMercatorQuad/{z}/{x}/{y}.pbf?api=${apiKey}`],
|
|
238
194
|
maxzoom: 15,
|
|
239
195
|
minzoom: 3,
|
|
240
196
|
tilejson: '3.0.0',
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ConfigProvider } from '@basemaps/config';
|
|
2
1
|
import { TileMatrixSet } from '@basemaps/geo';
|
|
3
2
|
import { LogConfig } from '@basemaps/shared';
|
|
4
3
|
import { LambdaAlbRequest, LambdaHttpRequest } from '@linzjs/lambda';
|
|
@@ -24,7 +23,12 @@ export function mockRequest(path: string, method = 'get', headers: Record<string
|
|
|
24
23
|
export class FakeTileSet extends TileSetRaster {
|
|
25
24
|
constructor(name: string, tileMatrix: TileMatrixSet, title = `${name}:title`, description = `${name}:description`) {
|
|
26
25
|
super(name, tileMatrix);
|
|
27
|
-
this.tileSet = {
|
|
26
|
+
this.tileSet = {
|
|
27
|
+
name,
|
|
28
|
+
title,
|
|
29
|
+
description,
|
|
30
|
+
layers: [{ name: `imagery_${name}`, [tileMatrix.projection.code]: `im_${title}` }],
|
|
31
|
+
} as any;
|
|
28
32
|
}
|
|
29
33
|
}
|
|
30
34
|
|
|
@@ -34,32 +38,3 @@ export class FakeTileSetVector extends TileSetVector {
|
|
|
34
38
|
this.tileSet = {} as any;
|
|
35
39
|
}
|
|
36
40
|
}
|
|
37
|
-
|
|
38
|
-
export const Provider: ConfigProvider = {
|
|
39
|
-
name: 'main',
|
|
40
|
-
id: 'pv_main_production',
|
|
41
|
-
updatedAt: Date.now(),
|
|
42
|
-
version: 1,
|
|
43
|
-
serviceIdentification: {
|
|
44
|
-
accessConstraints: 'the accessConstraints',
|
|
45
|
-
description: 'the description',
|
|
46
|
-
fees: 'the fees',
|
|
47
|
-
title: 'the title',
|
|
48
|
-
},
|
|
49
|
-
serviceProvider: {
|
|
50
|
-
contact: {
|
|
51
|
-
address: {
|
|
52
|
-
city: 'the city',
|
|
53
|
-
country: 'the country',
|
|
54
|
-
deliveryPoint: 'the deliveryPoint',
|
|
55
|
-
email: 'email address',
|
|
56
|
-
postalCode: 'the postalCode',
|
|
57
|
-
},
|
|
58
|
-
individualName: 'the contact name',
|
|
59
|
-
phone: 'the phone',
|
|
60
|
-
position: 'the position',
|
|
61
|
-
},
|
|
62
|
-
name: 'the name',
|
|
63
|
-
site: 'https://example.provider.com',
|
|
64
|
-
},
|
|
65
|
-
};
|