Skip to content

Commit 4d223b6

Browse files
authored
feat(lambda-tiler): Refactoring the wmts Capablity to builder interface. (#2686)
* Refactoring the wmts capablity to builder interface. * Update the buildWmtsCapabilities to toVNode * Move all the vnode logic into toVnode * Some improvements to the refactoring. * Add missing api key docs
1 parent ac1e02d commit 4d223b6

File tree

4 files changed

+333
-195
lines changed

4 files changed

+333
-195
lines changed

packages/cli/src/cli/overview/overview.wmts.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ export function createOverviewWmtsCapabilities(
1717
title,
1818
};
1919
const wmts = new WmtsCapabilities({
20-
tileSet,
21-
tileMatrix: [tileMatrix],
22-
formats: [ImageFormat.Webp],
2320
httpBase: '',
24-
imagery: new Map(),
2521
});
2622

23+
wmts.addFormats(ImageFormat.Webp);
24+
wmts.addTileMatrix(tileMatrix);
25+
wmts.addTileSet(tileSet);
26+
2727
wmts.maxZoom = maxZoom;
2828

2929
const nodes = wmts.toVNode();

packages/lambda-tiler/src/__tests__/wmts.capability.test.ts

Lines changed: 110 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,17 @@ o.spec('WmtsCapabilities', () => {
2424
o('should output the requested formats', () => {
2525
const wmts = new WmtsCapabilities({
2626
httpBase: 'https://basemaps.test',
27-
provider: Provider,
28-
tileMatrix: [GoogleTms],
29-
tileSet: TileSetAerial,
30-
imagery: allImagery,
3127
apiKey,
32-
formats: [ImageFormat.Avif],
33-
}).toVNode();
28+
});
3429

35-
const urls = tags(wmts, 'ResourceURL');
30+
wmts.addTileMatrix(GoogleTms);
31+
for (const im of allImagery.values()) wmts.addImagery(im);
32+
wmts.addFormats(ImageFormat.Avif);
33+
wmts.addProvider(Provider);
34+
wmts.addTileSet(TileSetAerial);
35+
const wmtsCapability = wmts.toVNode();
36+
37+
const urls = tags(wmtsCapability, 'ResourceURL');
3638
o(urls.length).equals(1);
3739
o(urls[0].attrs.format).equals('image/avif');
3840
o(urls[0].attrs.template).equals(
@@ -43,33 +45,39 @@ o.spec('WmtsCapabilities', () => {
4345
o('should include config location', () => {
4446
const wmts = new WmtsCapabilities({
4547
httpBase: 'https://basemaps.test',
46-
provider: Provider,
47-
tileMatrix: [GoogleTms],
48-
tileSet: TileSetAerial,
49-
imagery: allImagery,
5048
apiKey,
5149
config: 's3://linz-basemaps/config.json',
52-
formats: [ImageFormat.Avif],
53-
}).toVNode();
50+
});
51+
52+
wmts.addTileMatrix(GoogleTms);
53+
for (const im of allImagery.values()) wmts.addImagery(im);
54+
wmts.addFormats(ImageFormat.Avif);
55+
wmts.addProvider(Provider);
56+
wmts.addTileSet(TileSetAerial);
57+
const wmtsCapability = wmts.toVNode();
5458

55-
const urls = tags(wmts, 'ResourceURL');
59+
const urls = tags(wmtsCapability, 'ResourceURL');
5660
o(urls.length).equals(1);
5761
o(urls[0].attrs.format).equals('image/avif');
5862
o(urls[0].attrs.template).equals(
5963
'https://basemaps.test/v1/tiles/aerial/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.avif?api=secret1234&config=s3%3A%2F%2Flinz-basemaps%2Fconfig.json',
6064
);
6165
});
6266

63-
o('should be seting encoding to utf-8', () => {
64-
const xml = new WmtsCapabilities({
67+
o('should be adding encoding to utf-8', () => {
68+
const wmts = new WmtsCapabilities({
6569
httpBase: 'https://basemaps.test',
70+
apiKey,
71+
});
72+
73+
wmts.fromParams({
6674
provider: Provider,
6775
tileMatrix: [GoogleTms],
6876
tileSet: TileSetAerial,
6977
imagery: allImagery,
70-
apiKey,
7178
formats: [ImageFormat.Avif],
72-
}).toXml();
79+
});
80+
const xml = wmts.toXml();
7381

7482
o(xml.split('\n')[0]).deepEquals('<?xml version="1.0" encoding="utf-8"?>');
7583
});
@@ -79,23 +87,26 @@ o.spec('WmtsCapabilities', () => {
7987
tileSet.name = '🦄_🌈_2022_0-5m';
8088
tileSet.title = '🦄 🌈 Imagery (2022)';
8189
tileSet.description = '🦄 🌈 Description';
90+
8291
const wmts = new WmtsCapabilities({
8392
httpBase: 'https://basemaps.test',
84-
provider: Provider,
85-
tileMatrix: [GoogleTms],
86-
tileSet,
87-
imagery: allImagery,
8893
apiKey,
89-
formats: [ImageFormat.Avif],
90-
}).toVNode();
94+
});
9195

92-
const urls = tags(wmts, 'ResourceURL');
96+
wmts.addTileMatrix(GoogleTms);
97+
for (const im of allImagery.values()) wmts.addImagery(im);
98+
wmts.addFormats(ImageFormat.Avif);
99+
wmts.addProvider(Provider);
100+
wmts.addTileSet(tileSet);
101+
const wmtsCapability = wmts.toVNode();
102+
103+
const urls = tags(wmtsCapability, 'ResourceURL');
93104
o(urls.length).equals(1);
94105
o(urls[0].attrs.template).equals(
95106
'https://basemaps.test/v1/tiles/🦄-🌈-2022-0.5m/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.avif?api=secret1234',
96107
);
97108

98-
const layer = tags(wmts, 'Layer')[0];
109+
const layer = tags(wmtsCapability, 'Layer')[0];
99110

100111
const title = layer.find('ows:Title')?.toString();
101112
o(title).equals('<ows:Title>🦄 🌈 Imagery (2022)</ows:Title>');
@@ -133,32 +144,36 @@ o.spec('WmtsCapabilities', () => {
133144

134145
const wmts = new WmtsCapabilities({
135146
httpBase: 'https://basemaps.test',
136-
provider: Provider,
137-
tileMatrix: [GoogleTms],
138-
tileSet,
139-
imagery,
140147
apiKey,
141-
layers: tileSet.layers,
142-
}).toVNode();
148+
});
149+
150+
wmts.addTileMatrix(GoogleTms);
151+
for (const im of imagery.values()) wmts.addImagery(im);
152+
wmts.addProvider(Provider);
153+
wmts.addTileSet(tileSet);
154+
wmts.addLayers(tileSet.layers);
155+
const wmtsCapability = wmts.toVNode();
143156

144-
const layers = tags(wmts, 'Layer').map((c) => c.find('ows:Title')?.textContent);
157+
const layers = tags(wmtsCapability, 'Layer').map((c) => c.find('ows:Title')?.textContent);
145158

146159
// The base layer "Aerial Imagery" should always be first then all sub layers after
147160
o(layers).deepEquals(['Aerial Imagery', 'aaaa', 'bbbb', 'Ōtorohanga 0.1m Urban Aerial Photos (2021)']);
148161
});
149162

150-
o('should build capability xml for tileset and projection', () => {
163+
o('should build capability xml for tileSet and projection', () => {
151164
const imagery = new Map();
152165
imagery.set(Imagery3857.id, Imagery3857);
166+
153167
const wmts = new WmtsCapabilities({
154168
httpBase: 'https://basemaps.test',
155-
provider: Provider,
156-
tileMatrix: [GoogleTms],
157-
tileSet: TileSetAerial,
158-
imagery,
159169
apiKey,
160170
});
161171

172+
wmts.addTileMatrix(GoogleTms);
173+
for (const im of imagery.values()) wmts.addImagery(im);
174+
wmts.addProvider(Provider);
175+
wmts.addTileSet(TileSetAerial);
176+
wmts.addLayers(TileSetAerial.layers);
162177
const raw = wmts.toVNode();
163178
const serviceId = raw.find('ows:ServiceIdentification');
164179

@@ -201,14 +216,17 @@ o.spec('WmtsCapabilities', () => {
201216
});
202217

203218
o('should include output the correct TileMatrix', () => {
204-
const raw = new WmtsCapabilities({
219+
const wmts = new WmtsCapabilities({
205220
httpBase: 'https://basemaps.test',
206-
provider: Provider,
207-
tileMatrix: [GoogleTms],
208-
tileSet: TileSetAerial,
209-
imagery: allImagery,
210221
apiKey,
211-
}).toVNode();
222+
});
223+
224+
wmts.addTileMatrix(GoogleTms);
225+
for (const im of allImagery.values()) wmts.addImagery(im);
226+
wmts.addProvider(Provider);
227+
wmts.addTileSet(TileSetAerial);
228+
const raw = wmts.toVNode();
229+
212230
const layer = raw.find('Contents', 'Layer');
213231

214232
o(layer?.find('TileMatrixSetLink', 'TileMatrixSet')?.textContent).equals('WebMercatorQuad');
@@ -243,19 +261,25 @@ o.spec('WmtsCapabilities', () => {
243261
compareMatrix(tileMatrices[10], '10', 1024, 545978.773465544);
244262
});
245263

246-
o('should output individual imagery sets', () => {
264+
o('should output individual imagery adds', () => {
247265
const imagery = new Map<string, ConfigImagery>();
248266
imagery.set(Imagery3857.id, Imagery3857);
249267
imagery.set(Imagery2193.id, Imagery2193);
250-
const raw = new WmtsCapabilities({
268+
269+
const wmts = new WmtsCapabilities({
251270
httpBase: 'https://basemaps.test',
271+
});
272+
273+
wmts.fromParams({
252274
provider: Provider,
253275
tileMatrix: [GoogleTms],
254276
tileSet: TileSetAerial,
255-
imagery: imagery,
256-
formats: [ImageFormat.Png],
277+
imagery,
257278
layers: TileSetAerial.layers,
258-
}).toVNode();
279+
formats: [ImageFormat.Png],
280+
});
281+
282+
const raw = wmts.toVNode();
259283

260284
const tms = raw?.find('TileMatrixSet', 'ows:Identifier');
261285

@@ -286,15 +310,20 @@ o.spec('WmtsCapabilities', () => {
286310
const imagery = new Map<string, ConfigImagery>();
287311
imagery.set(Imagery3857.id, Imagery3857);
288312
imagery.set(Imagery2193.id, Imagery2193);
289-
const raw = new WmtsCapabilities({
313+
314+
const wmts = new WmtsCapabilities({
290315
httpBase: 'https://basemaps.test',
316+
});
317+
318+
wmts.fromParams({
291319
provider: Provider,
292320
tileMatrix: [GoogleTms, Nztm2000QuadTms],
293321
tileSet: TileSetAerial,
294322
imagery: imagery,
295323
formats: [ImageFormat.Png],
296-
}).toVNode();
324+
});
297325

326+
const raw = wmts.toVNode();
298327
const layers = tags(raw, 'Layer');
299328
o(layers.length).equals(1);
300329
const layer = layers[0];
@@ -321,11 +350,11 @@ o.spec('WmtsCapabilities', () => {
321350
);
322351
o(layer.find('ows:Identifier')?.textContent).equals('aerial');
323352

324-
const sets = tags(layer, 'TileMatrixSet');
353+
const adds = tags(layer, 'TileMatrixSet');
325354

326-
o(sets.length).equals(2);
327-
o(sets[0].toString()).equals('<TileMatrixSet>WebMercatorQuad</TileMatrixSet>');
328-
o(sets[1].toString()).equals('<TileMatrixSet>NZTM2000Quad</TileMatrixSet>');
355+
o(adds.length).equals(2);
356+
o(adds[0].toString()).equals('<TileMatrixSet>WebMercatorQuad</TileMatrixSet>');
357+
o(adds[1].toString()).equals('<TileMatrixSet>NZTM2000Quad</TileMatrixSet>');
329358

330359
const boundingBoxes = tags(layer, 'ows:BoundingBox');
331360
o(boundingBoxes.length).equals(2);
@@ -347,37 +376,45 @@ o.spec('WmtsCapabilities', () => {
347376

348377
o('should only output imagery if exists', () => {
349378
const imagery = new Map<string, ConfigImagery>();
350-
const raw = new WmtsCapabilities({
379+
const wmtsA = new WmtsCapabilities({
351380
httpBase: 'https://basemaps.test',
381+
});
382+
383+
wmtsA.fromParams({
352384
provider: Provider,
353385
tileMatrix: [Nztm2000QuadTms],
354386
tileSet: TileSetAerial,
355387
imagery: imagery,
356388
formats: [ImageFormat.Png],
357389
layers: TileSetAerial.layers,
358-
}).toVNode();
390+
});
359391

360-
const layers = tags(raw, 'Layer');
392+
const rawA = wmtsA.toVNode();
393+
394+
const layers = tags(rawA, 'Layer');
361395
o(layers.length).equals(1);
362396

363397
imagery.set(Imagery3857.id, Imagery3857);
364-
const rawB = new WmtsCapabilities({
398+
const wmtsB = new WmtsCapabilities({
365399
httpBase: 'https://basemaps.test',
400+
});
401+
wmtsB.fromParams({
366402
provider: Provider,
367403
tileMatrix: [Nztm2000QuadTms],
368404
tileSet: TileSetAerial,
369405
imagery: imagery,
370406
formats: [ImageFormat.Png],
371407
layers: TileSetAerial.layers,
372-
}).toVNode();
408+
});
373409

410+
const rawB = wmtsB.toVNode();
374411
const layersB = tags(rawB, 'Layer');
375412
o(layersB.length).equals(1);
376413
});
377414

378415
o('should cover the entire WebMercatorBounds', () => {
379416
const halfSize = GoogleTms.extent.width / 2;
380-
// Create two fake imagery sets one covers tile z1 x0 y0 another covers tile z1 x1 y1
417+
// Create two fake imagery adds one covers tile z1 x0 y0 another covers tile z1 x1 y1
381418
// so the entire bounding box should be tile z0 x0 y0 or the full extent
382419
const imagery = new Map();
383420
const imageTopLeft = { ...Imagery3857, id: 'im_top_left', name: 'top_left' };
@@ -394,15 +431,19 @@ o.spec('WmtsCapabilities', () => {
394431
{ 3857: imageBottomRight.id, name: 'b_bottom_right', title: 'B Bottom Right' },
395432
];
396433

397-
const raw = new WmtsCapabilities({
434+
const wmts = new WmtsCapabilities({
398435
httpBase: 'https://basemaps.test',
436+
});
437+
wmts.fromParams({
399438
provider: Provider,
400439
tileMatrix: [GoogleTms],
401440
tileSet,
402441
imagery,
403442
formats: [ImageFormat.Png],
404443
layers: tileSet.layers,
405-
}).toVNode();
444+
});
445+
446+
const raw = wmts.toVNode();
406447

407448
const boundingBox = tags(raw, 'ows:WGS84BoundingBox').map((c) =>
408449
c
@@ -433,15 +474,19 @@ o.spec('WmtsCapabilities', () => {
433474
const tileSet = { ...TileSetAerial };
434475
tileSet.layers = [{ 3857: imageBottomRight.id, name: 'b_bottom_right', title: 'B Bottom Right' }];
435476

436-
const raw = new WmtsCapabilities({
477+
const wmts = new WmtsCapabilities({
437478
httpBase: 'https://basemaps.test',
479+
});
480+
wmts.fromParams({
438481
provider: Provider,
439482
tileMatrix: [GoogleTms],
440483
tileSet,
441484
imagery,
442485
formats: [ImageFormat.Png],
443486
layers: tileSet.layers,
444-
}).toVNode();
487+
});
488+
489+
const raw = wmts.toVNode();
445490

446491
const boundingBox = tags(raw, 'ows:WGS84BoundingBox').map((c) =>
447492
roundNumbersInString(c.toString(), 4)

packages/lambda-tiler/src/routes/tile.wmts.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,23 @@ export async function wmtsCapabilitiesGet(req: LambdaHttpRequest<WmtsCapabilitie
5555
);
5656
req.timer.end('imagery:load');
5757

58-
const xml = new WmtsCapabilities({
58+
const wmts = new WmtsCapabilities({
5959
httpBase: host,
60+
apiKey,
61+
config: ConfigLoader.extract(req),
62+
filters: getFilters(req),
63+
});
64+
65+
wmts.fromParams({
6066
provider: provider ?? undefined,
6167
tileSet,
6268
tileMatrix,
6369
imagery,
64-
apiKey,
65-
config: ConfigLoader.extract(req),
66-
formats: Validate.getRequestedFormats(req),
67-
layers: req.params.tileMatrix == null ? filterLayers(req, tileSet.layers) : null,
68-
filters: getFilters(req),
69-
}).toXml();
70+
formats: Validate.getRequestedFormats(req) ?? [],
71+
layers: req.params.tileMatrix == null ? filterLayers(req, tileSet.layers) : undefined,
72+
});
73+
74+
const xml = wmts.toXml();
7075
if (xml == null) return NotFound();
7176

7277
const data = Buffer.from(xml);

0 commit comments

Comments
 (0)