@basemaps/lambda-tiler 6.39.0 → 6.41.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 (140) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/build/__tests__/config.data.d.ts.map +1 -1
  3. package/build/__tests__/config.data.js +142 -1
  4. package/build/__tests__/config.data.js.map +1 -1
  5. package/build/__tests__/wmts.capability.test.js +105 -79
  6. package/build/__tests__/wmts.capability.test.js.map +1 -1
  7. package/build/__tests__/xyz.util.d.ts.map +1 -1
  8. package/build/__tests__/xyz.util.js +6 -2
  9. package/build/__tests__/xyz.util.js.map +1 -1
  10. package/build/cli/render.tile.d.ts +2 -0
  11. package/build/cli/render.tile.d.ts.map +1 -0
  12. package/build/cli/render.tile.js +36 -0
  13. package/build/cli/render.tile.js.map +1 -0
  14. package/build/routes/__tests__/attribution.test.js +62 -2
  15. package/build/routes/__tests__/attribution.test.js.map +1 -1
  16. package/build/routes/__tests__/wmts.test.js +50 -8
  17. package/build/routes/__tests__/wmts.test.js.map +1 -1
  18. package/build/routes/attribution.d.ts +11 -0
  19. package/build/routes/attribution.d.ts.map +1 -1
  20. package/build/routes/attribution.js +32 -28
  21. package/build/routes/attribution.js.map +1 -1
  22. package/build/routes/tile.json.d.ts.map +1 -1
  23. package/build/routes/tile.json.js +2 -1
  24. package/build/routes/tile.json.js.map +1 -1
  25. package/build/routes/tile.style.json.d.ts.map +1 -1
  26. package/build/routes/tile.style.json.js +2 -1
  27. package/build/routes/tile.style.json.js.map +1 -1
  28. package/build/routes/tile.wmts.d.ts.map +1 -1
  29. package/build/routes/tile.wmts.js +12 -7
  30. package/build/routes/tile.wmts.js.map +1 -1
  31. package/build/routes/tile.xyz.raster.d.ts.map +1 -1
  32. package/build/routes/tile.xyz.raster.js +5 -1
  33. package/build/routes/tile.xyz.raster.js.map +1 -1
  34. package/build/util/__test__/filter.test.d.ts +2 -0
  35. package/build/util/__test__/filter.test.d.ts.map +1 -0
  36. package/build/util/__test__/filter.test.js +64 -0
  37. package/build/util/__test__/filter.test.js.map +1 -0
  38. package/build/util/config.loader.d.ts.map +1 -1
  39. package/build/util/config.loader.js +2 -3
  40. package/build/util/config.loader.js.map +1 -1
  41. package/build/util/filter.d.ts +15 -0
  42. package/build/util/filter.d.ts.map +1 -0
  43. package/build/util/filter.js +59 -0
  44. package/build/util/filter.js.map +1 -0
  45. package/build/util/validate.d.ts.map +1 -1
  46. package/build/util/validate.js +4 -3
  47. package/build/util/validate.js.map +1 -1
  48. package/build/wmts.capability.d.ts +61 -28
  49. package/build/wmts.capability.d.ts.map +1 -1
  50. package/build/wmts.capability.js +175 -99
  51. package/build/wmts.capability.js.map +1 -1
  52. package/dist/index.js +110 -82
  53. package/dist/node_modules/.package-lock.json +17 -17
  54. package/dist/node_modules/detect-libc/README.md +4 -1
  55. package/dist/node_modules/detect-libc/index.d.ts +3 -0
  56. package/dist/node_modules/detect-libc/lib/detect-libc.js +105 -4
  57. package/dist/node_modules/detect-libc/lib/filesystem.js +41 -0
  58. package/dist/node_modules/detect-libc/lib/process.js +3 -0
  59. package/dist/node_modules/detect-libc/package.json +7 -3
  60. package/dist/node_modules/minimist/.eslintrc +25 -50
  61. package/dist/node_modules/minimist/CHANGELOG.md +87 -1
  62. package/dist/node_modules/minimist/README.md +14 -10
  63. package/dist/node_modules/minimist/example/parse.js +2 -0
  64. package/dist/node_modules/minimist/index.js +256 -242
  65. package/dist/node_modules/minimist/package.json +73 -73
  66. package/dist/node_modules/minimist/test/all_bool.js +26 -24
  67. package/dist/node_modules/minimist/test/bool.js +146 -147
  68. package/dist/node_modules/minimist/test/dash.js +33 -21
  69. package/dist/node_modules/minimist/test/default_bool.js +26 -24
  70. package/dist/node_modules/minimist/test/dotted.js +13 -11
  71. package/dist/node_modules/minimist/test/kv_short.js +26 -10
  72. package/dist/node_modules/minimist/test/long.js +28 -26
  73. package/dist/node_modules/minimist/test/num.js +30 -28
  74. package/dist/node_modules/minimist/test/parse.js +169 -157
  75. package/dist/node_modules/minimist/test/parse_modified.js +7 -5
  76. package/dist/node_modules/minimist/test/proto.js +41 -37
  77. package/dist/node_modules/minimist/test/short.js +57 -55
  78. package/dist/node_modules/minimist/test/stop_early.js +10 -8
  79. package/dist/node_modules/minimist/test/unknown.js +83 -81
  80. package/dist/node_modules/minimist/test/whitespace.js +6 -4
  81. package/dist/node_modules/node-abi/.circleci/config.yml +2 -2
  82. package/dist/node_modules/node-abi/.github/CODEOWNERS +1 -0
  83. package/dist/node_modules/node-abi/.github/workflows/semantic.yml +26 -0
  84. package/dist/node_modules/node-abi/.github/workflows/update-abi.yml +5 -4
  85. package/dist/node_modules/node-abi/README.md +5 -3
  86. package/dist/node_modules/node-abi/abi_registry.json +32 -1
  87. package/dist/node_modules/node-abi/package.json +4 -4
  88. package/dist/node_modules/node-abi/scripts/update-abi-registry.js +2 -2
  89. package/dist/node_modules/readable-stream/README.md +1 -1
  90. package/dist/node_modules/readable-stream/lib/_stream_duplex.js +12 -25
  91. package/dist/node_modules/readable-stream/lib/_stream_passthrough.js +2 -4
  92. package/dist/node_modules/readable-stream/lib/_stream_readable.js +176 -273
  93. package/dist/node_modules/readable-stream/lib/_stream_transform.js +26 -37
  94. package/dist/node_modules/readable-stream/lib/_stream_writable.js +118 -174
  95. package/dist/node_modules/readable-stream/lib/internal/streams/async_iterator.js +10 -37
  96. package/dist/node_modules/readable-stream/lib/internal/streams/buffer_list.js +20 -47
  97. package/dist/node_modules/readable-stream/lib/internal/streams/destroy.js +8 -17
  98. package/dist/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +1 -19
  99. package/dist/node_modules/readable-stream/lib/internal/streams/from.js +12 -24
  100. package/dist/node_modules/readable-stream/lib/internal/streams/pipeline.js +5 -16
  101. package/dist/node_modules/readable-stream/lib/internal/streams/state.js +2 -7
  102. package/dist/node_modules/readable-stream/package.json +1 -1
  103. package/dist/node_modules/semver/README.md +70 -1
  104. package/dist/node_modules/semver/bin/semver.js +16 -2
  105. package/dist/node_modules/semver/classes/comparator.js +39 -34
  106. package/dist/node_modules/semver/classes/range.js +45 -28
  107. package/dist/node_modules/semver/classes/semver.js +32 -17
  108. package/dist/node_modules/semver/functions/coerce.js +1 -1
  109. package/dist/node_modules/semver/functions/diff.js +58 -16
  110. package/dist/node_modules/semver/functions/inc.js +3 -2
  111. package/dist/node_modules/semver/functions/parse.js +5 -22
  112. package/dist/node_modules/semver/index.js +1 -0
  113. package/dist/node_modules/semver/internal/constants.js +20 -2
  114. package/dist/node_modules/semver/internal/parse-options.js +14 -10
  115. package/dist/node_modules/semver/internal/re.js +34 -4
  116. package/dist/node_modules/semver/package.json +8 -7
  117. package/dist/node_modules/semver/ranges/intersects.js +1 -1
  118. package/dist/node_modules/semver/ranges/subset.js +6 -3
  119. package/dist/package-lock.json +18 -349
  120. package/dist/package.json +1 -2
  121. package/package.json +9 -10
  122. package/src/__tests__/config.data.ts +142 -1
  123. package/src/__tests__/wmts.capability.test.ts +117 -79
  124. package/src/__tests__/xyz.util.ts +6 -2
  125. package/src/cli/render.tile.ts +41 -0
  126. package/src/routes/__tests__/attribution.test.ts +64 -2
  127. package/src/routes/__tests__/wmts.test.ts +70 -9
  128. package/src/routes/attribution.ts +28 -28
  129. package/src/routes/tile.json.ts +2 -1
  130. package/src/routes/tile.style.json.ts +2 -1
  131. package/src/routes/tile.wmts.ts +13 -6
  132. package/src/routes/tile.xyz.raster.ts +4 -1
  133. package/src/util/__test__/filter.test.ts +80 -0
  134. package/src/util/config.loader.ts +1 -2
  135. package/src/util/filter.ts +60 -0
  136. package/src/util/validate.ts +4 -3
  137. package/src/wmts.capability.ts +216 -123
  138. package/tsconfig.tsbuildinfo +1 -1
  139. package/test-dump.js +0 -6
  140. package/test-imagery.js +0 -3
@@ -24,16 +24,17 @@ o.spec('WmtsCapabilities', () => {
24
24
  o('should output the requested formats', () => {
25
25
  const wmts = new WmtsCapabilities({
26
26
  httpBase: 'https://basemaps.test',
27
- provider: Provider,
28
- tileMatrix: [GoogleTms],
29
- tileSet: TileSetAerial,
30
- imagery: allImagery,
31
27
  apiKey,
32
- formats: [ImageFormat.Avif],
33
- isIndividualLayers: false,
34
- }).toVNode();
28
+ });
29
+
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();
35
36
 
36
- const urls = tags(wmts, 'ResourceURL');
37
+ const urls = tags(wmtsCapability, 'ResourceURL');
37
38
  o(urls.length).equals(1);
38
39
  o(urls[0].attrs.format).equals('image/avif');
39
40
  o(urls[0].attrs.template).equals(
@@ -44,17 +45,18 @@ o.spec('WmtsCapabilities', () => {
44
45
  o('should include config location', () => {
45
46
  const wmts = new WmtsCapabilities({
46
47
  httpBase: 'https://basemaps.test',
47
- provider: Provider,
48
- tileMatrix: [GoogleTms],
49
- tileSet: TileSetAerial,
50
- imagery: allImagery,
51
48
  apiKey,
52
49
  config: 's3://linz-basemaps/config.json',
53
- formats: [ImageFormat.Avif],
54
- isIndividualLayers: false,
55
- }).toVNode();
50
+ });
56
51
 
57
- const urls = tags(wmts, 'ResourceURL');
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();
58
+
59
+ const urls = tags(wmtsCapability, 'ResourceURL');
58
60
  o(urls.length).equals(1);
59
61
  o(urls[0].attrs.format).equals('image/avif');
60
62
  o(urls[0].attrs.template).equals(
@@ -62,17 +64,20 @@ o.spec('WmtsCapabilities', () => {
62
64
  );
63
65
  });
64
66
 
65
- o('should be seting encoding to utf-8', () => {
66
- const xml = new WmtsCapabilities({
67
+ o('should be adding encoding to utf-8', () => {
68
+ const wmts = new WmtsCapabilities({
67
69
  httpBase: 'https://basemaps.test',
70
+ apiKey,
71
+ });
72
+
73
+ wmts.fromParams({
68
74
  provider: Provider,
69
75
  tileMatrix: [GoogleTms],
70
76
  tileSet: TileSetAerial,
71
77
  imagery: allImagery,
72
- apiKey,
73
78
  formats: [ImageFormat.Avif],
74
- isIndividualLayers: false,
75
- }).toXml();
79
+ });
80
+ const xml = wmts.toXml();
76
81
 
77
82
  o(xml.split('\n')[0]).deepEquals('<?xml version="1.0" encoding="utf-8"?>');
78
83
  });
@@ -82,24 +87,26 @@ o.spec('WmtsCapabilities', () => {
82
87
  tileSet.name = '🦄_🌈_2022_0-5m';
83
88
  tileSet.title = '🦄 🌈 Imagery (2022)';
84
89
  tileSet.description = '🦄 🌈 Description';
90
+
85
91
  const wmts = new WmtsCapabilities({
86
92
  httpBase: 'https://basemaps.test',
87
- provider: Provider,
88
- tileMatrix: [GoogleTms],
89
- tileSet,
90
- imagery: allImagery,
91
93
  apiKey,
92
- formats: [ImageFormat.Avif],
93
- isIndividualLayers: false,
94
- }).toVNode();
94
+ });
95
+
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();
95
102
 
96
- const urls = tags(wmts, 'ResourceURL');
103
+ const urls = tags(wmtsCapability, 'ResourceURL');
97
104
  o(urls.length).equals(1);
98
105
  o(urls[0].attrs.template).equals(
99
106
  'https://basemaps.test/v1/tiles/🦄-🌈-2022-0.5m/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.avif?api=secret1234',
100
107
  );
101
108
 
102
- const layer = tags(wmts, 'Layer')[0];
109
+ const layer = tags(wmtsCapability, 'Layer')[0];
103
110
 
104
111
  const title = layer.find('ows:Title')?.toString();
105
112
  o(title).equals('<ows:Title>🦄 🌈 Imagery (2022)</ows:Title>');
@@ -137,33 +144,36 @@ o.spec('WmtsCapabilities', () => {
137
144
 
138
145
  const wmts = new WmtsCapabilities({
139
146
  httpBase: 'https://basemaps.test',
140
- provider: Provider,
141
- tileMatrix: [GoogleTms],
142
- tileSet,
143
- imagery,
144
147
  apiKey,
145
- isIndividualLayers: true,
146
- }).toVNode();
148
+ });
147
149
 
148
- const layers = tags(wmts, 'Layer').map((c) => c.find('ows:Title')?.textContent);
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();
156
+
157
+ const layers = tags(wmtsCapability, 'Layer').map((c) => c.find('ows:Title')?.textContent);
149
158
 
150
159
  // The base layer "Aerial Imagery" should always be first then all sub layers after
151
160
  o(layers).deepEquals(['Aerial Imagery', 'aaaa', 'bbbb', 'Ōtorohanga 0.1m Urban Aerial Photos (2021)']);
152
161
  });
153
162
 
154
- o('should build capability xml for tileset and projection', () => {
163
+ o('should build capability xml for tileSet and projection', () => {
155
164
  const imagery = new Map();
156
165
  imagery.set(Imagery3857.id, Imagery3857);
166
+
157
167
  const wmts = new WmtsCapabilities({
158
168
  httpBase: 'https://basemaps.test',
159
- provider: Provider,
160
- tileMatrix: [GoogleTms],
161
- tileSet: TileSetAerial,
162
- imagery,
163
169
  apiKey,
164
- isIndividualLayers: false,
165
170
  });
166
171
 
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);
167
177
  const raw = wmts.toVNode();
168
178
  const serviceId = raw.find('ows:ServiceIdentification');
169
179
 
@@ -206,15 +216,17 @@ o.spec('WmtsCapabilities', () => {
206
216
  });
207
217
 
208
218
  o('should include output the correct TileMatrix', () => {
209
- const raw = new WmtsCapabilities({
219
+ const wmts = new WmtsCapabilities({
210
220
  httpBase: 'https://basemaps.test',
211
- provider: Provider,
212
- tileMatrix: [GoogleTms],
213
- tileSet: TileSetAerial,
214
- imagery: allImagery,
215
221
  apiKey,
216
- isIndividualLayers: false,
217
- }).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
+
218
230
  const layer = raw.find('Contents', 'Layer');
219
231
 
220
232
  o(layer?.find('TileMatrixSetLink', 'TileMatrixSet')?.textContent).equals('WebMercatorQuad');
@@ -249,19 +261,25 @@ o.spec('WmtsCapabilities', () => {
249
261
  compareMatrix(tileMatrices[10], '10', 1024, 545978.773465544);
250
262
  });
251
263
 
252
- o('should output individual imagery sets', () => {
264
+ o('should output individual imagery adds', () => {
253
265
  const imagery = new Map<string, ConfigImagery>();
254
266
  imagery.set(Imagery3857.id, Imagery3857);
255
267
  imagery.set(Imagery2193.id, Imagery2193);
256
- const raw = new WmtsCapabilities({
268
+
269
+ const wmts = new WmtsCapabilities({
257
270
  httpBase: 'https://basemaps.test',
271
+ });
272
+
273
+ wmts.fromParams({
258
274
  provider: Provider,
259
275
  tileMatrix: [GoogleTms],
260
276
  tileSet: TileSetAerial,
261
- imagery: imagery,
277
+ imagery,
278
+ layers: TileSetAerial.layers,
262
279
  formats: [ImageFormat.Png],
263
- isIndividualLayers: true,
264
- }).toVNode();
280
+ });
281
+
282
+ const raw = wmts.toVNode();
265
283
 
266
284
  const tms = raw?.find('TileMatrixSet', 'ows:Identifier');
267
285
 
@@ -292,16 +310,20 @@ o.spec('WmtsCapabilities', () => {
292
310
  const imagery = new Map<string, ConfigImagery>();
293
311
  imagery.set(Imagery3857.id, Imagery3857);
294
312
  imagery.set(Imagery2193.id, Imagery2193);
295
- const raw = new WmtsCapabilities({
313
+
314
+ const wmts = new WmtsCapabilities({
296
315
  httpBase: 'https://basemaps.test',
316
+ });
317
+
318
+ wmts.fromParams({
297
319
  provider: Provider,
298
320
  tileMatrix: [GoogleTms, Nztm2000QuadTms],
299
321
  tileSet: TileSetAerial,
300
322
  imagery: imagery,
301
323
  formats: [ImageFormat.Png],
302
- isIndividualLayers: false,
303
- }).toVNode();
324
+ });
304
325
 
326
+ const raw = wmts.toVNode();
305
327
  const layers = tags(raw, 'Layer');
306
328
  o(layers.length).equals(1);
307
329
  const layer = layers[0];
@@ -328,11 +350,11 @@ o.spec('WmtsCapabilities', () => {
328
350
  );
329
351
  o(layer.find('ows:Identifier')?.textContent).equals('aerial');
330
352
 
331
- const sets = tags(layer, 'TileMatrixSet');
353
+ const adds = tags(layer, 'TileMatrixSet');
332
354
 
333
- o(sets.length).equals(2);
334
- o(sets[0].toString()).equals('<TileMatrixSet>WebMercatorQuad</TileMatrixSet>');
335
- 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>');
336
358
 
337
359
  const boundingBoxes = tags(layer, 'ows:BoundingBox');
338
360
  o(boundingBoxes.length).equals(2);
@@ -354,37 +376,45 @@ o.spec('WmtsCapabilities', () => {
354
376
 
355
377
  o('should only output imagery if exists', () => {
356
378
  const imagery = new Map<string, ConfigImagery>();
357
- const raw = new WmtsCapabilities({
379
+ const wmtsA = new WmtsCapabilities({
358
380
  httpBase: 'https://basemaps.test',
381
+ });
382
+
383
+ wmtsA.fromParams({
359
384
  provider: Provider,
360
385
  tileMatrix: [Nztm2000QuadTms],
361
386
  tileSet: TileSetAerial,
362
387
  imagery: imagery,
363
388
  formats: [ImageFormat.Png],
364
- isIndividualLayers: true,
365
- }).toVNode();
389
+ layers: TileSetAerial.layers,
390
+ });
366
391
 
367
- const layers = tags(raw, 'Layer');
392
+ const rawA = wmtsA.toVNode();
393
+
394
+ const layers = tags(rawA, 'Layer');
368
395
  o(layers.length).equals(1);
369
396
 
370
397
  imagery.set(Imagery3857.id, Imagery3857);
371
- const rawB = new WmtsCapabilities({
398
+ const wmtsB = new WmtsCapabilities({
372
399
  httpBase: 'https://basemaps.test',
400
+ });
401
+ wmtsB.fromParams({
373
402
  provider: Provider,
374
403
  tileMatrix: [Nztm2000QuadTms],
375
404
  tileSet: TileSetAerial,
376
405
  imagery: imagery,
377
406
  formats: [ImageFormat.Png],
378
- isIndividualLayers: true,
379
- }).toVNode();
407
+ layers: TileSetAerial.layers,
408
+ });
380
409
 
410
+ const rawB = wmtsB.toVNode();
381
411
  const layersB = tags(rawB, 'Layer');
382
412
  o(layersB.length).equals(1);
383
413
  });
384
414
 
385
415
  o('should cover the entire WebMercatorBounds', () => {
386
416
  const halfSize = GoogleTms.extent.width / 2;
387
- // 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
388
418
  // so the entire bounding box should be tile z0 x0 y0 or the full extent
389
419
  const imagery = new Map();
390
420
  const imageTopLeft = { ...Imagery3857, id: 'im_top_left', name: 'top_left' };
@@ -397,19 +427,23 @@ o.spec('WmtsCapabilities', () => {
397
427
 
398
428
  const tileSet = { ...TileSetAerial };
399
429
  tileSet.layers = [
400
- { 3857: imageTopLeft.id, name: 'a_top_left' },
401
- { 3857: imageBottomRight.id, name: 'b_bottom_right' },
430
+ { 3857: imageTopLeft.id, name: 'a_top_left', title: 'A Top Left' },
431
+ { 3857: imageBottomRight.id, name: 'b_bottom_right', title: 'B Bottom Right' },
402
432
  ];
403
433
 
404
- const raw = new WmtsCapabilities({
434
+ const wmts = new WmtsCapabilities({
405
435
  httpBase: 'https://basemaps.test',
436
+ });
437
+ wmts.fromParams({
406
438
  provider: Provider,
407
439
  tileMatrix: [GoogleTms],
408
440
  tileSet,
409
441
  imagery,
410
442
  formats: [ImageFormat.Png],
411
- isIndividualLayers: true,
412
- }).toVNode();
443
+ layers: tileSet.layers,
444
+ });
445
+
446
+ const raw = wmts.toVNode();
413
447
 
414
448
  const boundingBox = tags(raw, 'ows:WGS84BoundingBox').map((c) =>
415
449
  c
@@ -438,17 +472,21 @@ o.spec('WmtsCapabilities', () => {
438
472
  imagery.set(imageBottomRight.id, imageBottomRight);
439
473
 
440
474
  const tileSet = { ...TileSetAerial };
441
- tileSet.layers = [{ 3857: imageBottomRight.id, name: 'b_bottom_right' }];
475
+ tileSet.layers = [{ 3857: imageBottomRight.id, name: 'b_bottom_right', title: 'B Bottom Right' }];
442
476
 
443
- const raw = new WmtsCapabilities({
477
+ const wmts = new WmtsCapabilities({
444
478
  httpBase: 'https://basemaps.test',
479
+ });
480
+ wmts.fromParams({
445
481
  provider: Provider,
446
482
  tileMatrix: [GoogleTms],
447
483
  tileSet,
448
484
  imagery,
449
485
  formats: [ImageFormat.Png],
450
- isIndividualLayers: true,
451
- }).toVNode();
486
+ layers: tileSet.layers,
487
+ });
488
+
489
+ const raw = wmts.toVNode();
452
490
 
453
491
  const boundingBox = tags(raw, 'ows:WGS84BoundingBox').map((c) =>
454
492
  roundNumbersInString(c.toString(), 4)
@@ -3,6 +3,8 @@ import { LambdaAlbRequest, LambdaHttpRequest, LambdaUrlRequest } from '@linzjs/l
3
3
  import { Context } from 'aws-lambda';
4
4
 
5
5
  export function mockRequest(path: string, method = 'get', headers: Record<string, string> = {}): LambdaHttpRequest {
6
+ const log = LogConfig.get();
7
+ log.level = 'silent';
6
8
  return new LambdaAlbRequest(
7
9
  {
8
10
  requestContext: null as any,
@@ -13,7 +15,7 @@ export function mockRequest(path: string, method = 'get', headers: Record<string
13
15
  isBase64Encoded: false,
14
16
  },
15
17
  {} as Context,
16
- LogConfig.get(),
18
+ log,
17
19
  );
18
20
  }
19
21
 
@@ -23,6 +25,8 @@ export function mockUrlRequest(
23
25
  headers: Record<string, unknown> = {},
24
26
  method?: string,
25
27
  ): LambdaHttpRequest {
28
+ const log = LogConfig.get();
29
+ log.level = 'silent';
26
30
  return new LambdaUrlRequest(
27
31
  {
28
32
  requestContext: { http: { method: method ? method.toUpperCase() : 'GET' } },
@@ -32,7 +36,7 @@ export function mockUrlRequest(
32
36
  isBase64Encoded: false,
33
37
  } as any,
34
38
  {} as Context,
35
- LogConfig.get(),
39
+ log,
36
40
  );
37
41
  }
38
42
 
@@ -0,0 +1,41 @@
1
+ import { ConfigProviderMemory } from '@basemaps/config';
2
+ import { initConfigFromUrls } from '@basemaps/config/build/json/tiff.config.js';
3
+ import { GoogleTms, ImageFormat } from '@basemaps/geo';
4
+ import { LogConfig, setDefaultConfig } from '@basemaps/shared';
5
+ import { fsa } from '@chunkd/fs';
6
+ import { LambdaHttpRequest, LambdaUrlRequest, UrlEvent } from '@linzjs/lambda';
7
+ import { Context } from 'aws-lambda';
8
+ import { TileXyzRaster } from '../routes/tile.xyz.raster.js';
9
+ import { pathToFileURL } from 'url';
10
+
11
+ const target = pathToFileURL(`/home/blacha/tmp/basemaps/white-lines/nz-0.5m/`);
12
+ const tile = { z: 10, x: 1013, y: 633 };
13
+ const tileMatrix = GoogleTms;
14
+ const imageFormat = ImageFormat.Webp;
15
+
16
+ async function main(): Promise<void> {
17
+ const log = LogConfig.get();
18
+ const provider = new ConfigProviderMemory();
19
+ setDefaultConfig(provider);
20
+ const { tileSet, imagery } = await initConfigFromUrls(provider, [target]);
21
+
22
+ if (tileSet.layers.length === 0) throw new Error('No imagery found in path: ' + target);
23
+ log.info({ tileSet: tileSet.name, layers: tileSet.layers.length }, 'TileSet:Loaded');
24
+ for (const im of imagery) {
25
+ log.info({ url: im.uri, title: im.title, tileMatrix: im.tileMatrix, files: im.files.length }, 'Imagery:Loaded');
26
+ }
27
+ const request = new LambdaUrlRequest({ headers: {} } as UrlEvent, {} as Context, log) as LambdaHttpRequest;
28
+
29
+ tileSet.background = { r: 255, g: 255, b: 255, alpha: 1 };
30
+ const res = await TileXyzRaster.tile(request, tileSet, {
31
+ tile,
32
+ tileMatrix,
33
+ tileSet: tileSet.id,
34
+ tileType: imageFormat,
35
+ });
36
+
37
+ await fsa.write(`./${tile.z}_${tile.x}_${tile.y}.${imageFormat}`, Buffer.from(res.body, 'base64'));
38
+ log.info({ path: `./${tile.z}_${tile.x}_${tile.y}.${imageFormat}` }, 'Tile:Write');
39
+ }
40
+
41
+ main();
@@ -1,7 +1,8 @@
1
1
  import { Attribution } from '@basemaps/attribution';
2
2
  import { ConfigProviderMemory } from '@basemaps/config';
3
- import { Nztm2000QuadTms } from '@basemaps/geo';
3
+ import { GoogleTms, Nztm2000QuadTms, Projection } from '@basemaps/geo';
4
4
  import { LogConfig } from '@basemaps/shared';
5
+ import { BBox } from '@linzjs/geojson';
5
6
  import { HttpHeader } from '@linzjs/lambda';
6
7
  import o from 'ospec';
7
8
  import sinon from 'sinon';
@@ -9,6 +10,7 @@ import { handler } from '../../index.js';
9
10
  import { ConfigLoader } from '../../util/config.loader.js';
10
11
  import { FakeData, Imagery2193, Imagery3857, Provider, TileSetAerial } from '../../__tests__/config.data.js';
11
12
  import { mockUrlRequest } from '../../__tests__/xyz.util.js';
13
+ import { createCoordinates } from '../attribution.js';
12
14
 
13
15
  // const ExpectedJson = {
14
16
  // id: 'aerial_WebMercatorQuad',
@@ -332,7 +334,7 @@ o.spec('/v1/attribution', () => {
332
334
  });
333
335
 
334
336
  o.spec('ImageryRules', () => {
335
- const fakeLayer = { [2193]: Imagery2193.id, name: 'image', minZoom: 9, maxZoom: 16 };
337
+ const fakeLayer = { [2193]: Imagery2193.id, name: 'image', minZoom: 9, maxZoom: 16, title: 'Image' };
336
338
  const ts = FakeData.tileSetRaster('fake');
337
339
 
338
340
  o.beforeEach(() => {
@@ -387,4 +389,64 @@ o.spec('/v1/attribution', () => {
387
389
  o(output.collections[0].summaries['linz:zoom']).deepEquals({ min: 0, max: Nztm2000QuadTms.maxZoom });
388
390
  });
389
391
  });
392
+
393
+ o('should create valid coordinates', async () => {
394
+ //bbox: BBox, files: NamedBounds[], proj: Projection
395
+ const bbox = [174.79248047, -38.21228805, 175.25939941, -37.99616268] as BBox;
396
+ const proj = Projection.get(GoogleTms);
397
+ const coordinates = createCoordinates(bbox, Imagery3857.files, proj);
398
+ console.log(JSON.stringify(coordinates));
399
+ o(coordinates).deepEquals([
400
+ [
401
+ [
402
+ [174.79247149, -38.09998972],
403
+ [174.81446211, -38.09998972],
404
+ [174.81446211, -38.09134368],
405
+ [174.82544844, -38.09134368],
406
+ [174.82544844, -38.08485848],
407
+ [174.82819502, -38.08485848],
408
+ [174.82819502, -38.08269662],
409
+ [174.83643476, -38.08269662],
410
+ [174.83643476, -38.06539942],
411
+ [174.85840742, -38.06539942],
412
+ [174.85840742, -37.9961556],
413
+ [174.81446211, -37.9961556],
414
+ [174.81446211, -37.9961556],
415
+ [174.79247149, -37.9961556],
416
+ [174.79247149, -38.01348331],
417
+ [174.80345781, -38.01348331],
418
+ [174.80345781, -38.02213855],
419
+ [174.81444414, -38.02213855],
420
+ [174.81444414, -38.04808399],
421
+ [174.79247149, -38.04808399],
422
+ [174.79247149, -38.09998972],
423
+ ],
424
+ ],
425
+ [
426
+ [
427
+ [175.16600664, -38.20366238],
428
+ [175.1879793, -38.20366238],
429
+ [175.1879793, -38.21229511],
430
+ [175.20996992, -38.21229511],
431
+ [175.20996992, -38.20797887],
432
+ [175.21546308, -38.20797887],
433
+ [175.21546308, -38.20366238],
434
+ [175.25391523, -38.20366238],
435
+ [175.25391523, -38.18207606],
436
+ [175.2594084, -38.18207606],
437
+ [175.2594084, -38.17342562],
438
+ [175.25391523, -38.17342562],
439
+ [175.25391523, -38.13454951],
440
+ [175.20995195, -38.13454951],
441
+ [175.20995195, -38.16046922],
442
+ [175.19896563, -38.16046922],
443
+ [175.19896563, -38.16694771],
444
+ [175.19621904, -38.16694771],
445
+ [175.19621904, -38.16910707],
446
+ [175.16600664, -38.16910707],
447
+ [175.16600664, -38.20366238],
448
+ ],
449
+ ],
450
+ ]);
451
+ });
390
452
  });
@@ -9,18 +9,11 @@ import { Api, mockUrlRequest } from '../../__tests__/xyz.util.js';
9
9
  o.spec('WMTSRouting', () => {
10
10
  const sandbox = createSandbox();
11
11
  const config = new ConfigProviderMemory();
12
+ const imagery = new Map();
12
13
 
13
- o.before(() => {
14
+ o.beforeEach(() => {
14
15
  sandbox.stub(ConfigLoader, 'load').resolves(config);
15
- });
16
16
 
17
- o.afterEach(() => {
18
- config.objects.clear();
19
- sandbox.restore();
20
- });
21
-
22
- o('should default to the aerial layer', async () => {
23
- const imagery = new Map();
24
17
  imagery.set(Imagery3857.id, Imagery3857);
25
18
  imagery.set(Imagery2193.id, Imagery2193);
26
19
 
@@ -28,7 +21,14 @@ o.spec('WMTSRouting', () => {
28
21
  config.put(Imagery2193);
29
22
  config.put(Imagery3857);
30
23
  config.put(Provider);
24
+ });
31
25
 
26
+ o.afterEach(() => {
27
+ config.objects.clear();
28
+ sandbox.restore();
29
+ });
30
+
31
+ o('should default to the aerial layer', async () => {
32
32
  const req = mockUrlRequest(
33
33
  '/v1/tiles/WMTSCapabilities.xml',
34
34
  `format=png&api=${Api.key}&config=s3://linz-basemaps/config.json`,
@@ -53,4 +53,65 @@ o.spec('WMTSRouting', () => {
53
53
  '<ResourceURL format="image/png" resourceType="tile" template="https://tiles.test/v1/tiles/ōtorohanga-urban-2021-0.1m/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png?api=d01f7w7rnhdzg0p7fyrc9v9ard1&amp;config=Q5pC4UjWdtFLU1CYtLcRSmB49RekgDgMa5EGJnB2M" />',
54
54
  ]);
55
55
  });
56
+
57
+ o('should filter out date[after] by year', async () => {
58
+ const req = mockUrlRequest(
59
+ '/v1/tiles/WMTSCapabilities.xml',
60
+ `format=png&api=${Api.key}&config=s3://linz-basemaps/config.json&date[after]=2022`,
61
+ );
62
+ const res = await handler.router.handle(req);
63
+
64
+ o(res.status).equals(200);
65
+ const lines = Buffer.from(res.body, 'base64').toString().split('\n');
66
+ const titles = lines.filter((f) => f.startsWith(' <ows:Title>')).map((f) => f.trim());
67
+
68
+ o(titles).deepEquals([
69
+ '<ows:Title>Aerial Imagery</ows:Title>',
70
+ '<ows:Title>Google Maps Compatible for the World</ows:Title>',
71
+ '<ows:Title>LINZ NZTM2000 Map Tile Grid V2</ows:Title>',
72
+ ]);
73
+ });
74
+
75
+ o('should filter out date[before] by year', async () => {
76
+ const req = mockUrlRequest(
77
+ '/v1/tiles/WMTSCapabilities.xml',
78
+ `format=png&api=${Api.key}&config=s3://linz-basemaps/config.json&date[before]=2020`,
79
+ );
80
+ const res = await handler.router.handle(req);
81
+
82
+ o(res.status).equals(200);
83
+ const lines = Buffer.from(res.body, 'base64').toString().split('\n');
84
+ const titles = lines.filter((f) => f.startsWith(' <ows:Title>')).map((f) => f.trim());
85
+
86
+ o(titles).deepEquals([
87
+ '<ows:Title>Aerial Imagery</ows:Title>',
88
+ '<ows:Title>Google Maps Compatible for the World</ows:Title>',
89
+ '<ows:Title>LINZ NZTM2000 Map Tile Grid V2</ows:Title>',
90
+ ]);
91
+ });
92
+
93
+ o('should filter inclusive date[before] by year', async () => {
94
+ const req = mockUrlRequest(
95
+ '/v1/tiles/WMTSCapabilities.xml',
96
+ `format=png&api=${Api.key}&config=s3://linz-basemaps/config.json&date[before]=2021`,
97
+ );
98
+ const res = await handler.router.handle(req);
99
+
100
+ o(res.status).equals(200);
101
+ const lines = Buffer.from(res.body, 'base64').toString().split('\n');
102
+ const titles = lines.filter((f) => f.startsWith(' <ows:Title>')).map((f) => f.trim());
103
+
104
+ o(titles).deepEquals([
105
+ '<ows:Title>Aerial Imagery</ows:Title>',
106
+ '<ows:Title>Ōtorohanga 0.1m Urban Aerial Photos (2021)</ows:Title>',
107
+ '<ows:Title>Google Maps Compatible for the World</ows:Title>',
108
+ '<ows:Title>LINZ NZTM2000 Map Tile Grid V2</ows:Title>',
109
+ ]);
110
+
111
+ const resourceURLs = lines.filter((f) => f.includes('<ResourceURL')).map((f) => f.trim());
112
+ o(resourceURLs).deepEquals([
113
+ '<ResourceURL format="image/png" resourceType="tile" template="https://tiles.test/v1/tiles/aerial/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png?api=d01f7w7rnhdzg0p7fyrc9v9ard1&amp;config=Q5pC4UjWdtFLU1CYtLcRSmB49RekgDgMa5EGJnB2M&amp;date%5Bbefore%5D=2021" />',
114
+ '<ResourceURL format="image/png" resourceType="tile" template="https://tiles.test/v1/tiles/ōtorohanga-urban-2021-0.1m/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png?api=d01f7w7rnhdzg0p7fyrc9v9ard1&amp;config=Q5pC4UjWdtFLU1CYtLcRSmB49RekgDgMa5EGJnB2M" />',
115
+ ]);
116
+ });
56
117
  });