@basemaps/lambda-tiler 7.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/build/__tests__/config.data.d.ts +0 -1
- package/build/__tests__/config.data.js +2 -6
- package/build/__tests__/config.data.js.map +1 -1
- package/build/__tests__/index.test.d.ts +0 -1
- package/build/__tests__/index.test.js +28 -27
- package/build/__tests__/index.test.js.map +1 -1
- package/build/__tests__/tile.style.json.test.d.ts +0 -1
- package/build/__tests__/tile.style.json.test.js +38 -37
- package/build/__tests__/tile.style.json.test.js.map +1 -1
- package/build/__tests__/wmts.capability.test.d.ts +0 -1
- package/build/__tests__/wmts.capability.test.js +111 -122
- package/build/__tests__/wmts.capability.test.js.map +1 -1
- package/build/__tests__/xyz.util.d.ts +0 -1
- package/build/cli/render.preview.d.ts +0 -1
- package/build/cli/render.preview.js +13 -9
- package/build/cli/render.preview.js.map +1 -1
- package/build/cli/render.tile.d.ts +0 -1
- package/build/cli/render.tile.js +25 -17
- package/build/cli/render.tile.js.map +1 -1
- package/build/index.d.ts +0 -1
- package/build/index.js +24 -20
- package/build/index.js.map +1 -1
- package/build/routes/__tests__/attribution.test.d.ts +0 -1
- package/build/routes/__tests__/attribution.test.js +38 -37
- package/build/routes/__tests__/attribution.test.js.map +1 -1
- package/build/routes/__tests__/fonts.test.d.ts +0 -1
- package/build/routes/__tests__/fonts.test.js +61 -63
- package/build/routes/__tests__/fonts.test.js.map +1 -1
- package/build/routes/__tests__/health.test.d.ts +0 -1
- package/build/routes/__tests__/health.test.js +16 -16
- package/build/routes/__tests__/health.test.js.map +1 -1
- package/build/routes/__tests__/imagery.test.d.ts +0 -1
- package/build/routes/__tests__/imagery.test.js +10 -9
- package/build/routes/__tests__/imagery.test.js.map +1 -1
- package/build/routes/__tests__/memory.fs.d.ts +2 -3
- package/build/routes/__tests__/preview.index.test.d.ts +0 -1
- package/build/routes/__tests__/preview.index.test.js +88 -42
- package/build/routes/__tests__/preview.index.test.js.map +1 -1
- package/build/routes/__tests__/sprites.test.d.ts +0 -1
- package/build/routes/__tests__/sprites.test.js +34 -34
- package/build/routes/__tests__/sprites.test.js.map +1 -1
- package/build/routes/__tests__/tile.json.test.d.ts +0 -1
- package/build/routes/__tests__/tile.json.test.js +45 -51
- package/build/routes/__tests__/tile.json.test.js.map +1 -1
- package/build/routes/__tests__/tile.style.json.test.d.ts +0 -1
- package/build/routes/__tests__/tile.style.json.test.js +49 -50
- package/build/routes/__tests__/tile.style.json.test.js.map +1 -1
- package/build/routes/__tests__/wmts.test.d.ts +0 -1
- package/build/routes/__tests__/wmts.test.js +27 -20
- package/build/routes/__tests__/wmts.test.js.map +1 -1
- package/build/routes/__tests__/xyz.test.d.ts +0 -1
- package/build/routes/__tests__/xyz.test.js +97 -49
- package/build/routes/__tests__/xyz.test.js.map +1 -1
- package/build/routes/attribution.d.ts +1 -1
- package/build/routes/attribution.js +4 -5
- package/build/routes/attribution.js.map +1 -1
- package/build/routes/config.d.ts +0 -1
- package/build/routes/config.js +1 -2
- package/build/routes/config.js.map +1 -1
- package/build/routes/fonts.d.ts +0 -1
- package/build/routes/fonts.js +2 -3
- package/build/routes/fonts.js.map +1 -1
- package/build/routes/health.d.ts +1 -2
- package/build/routes/health.js +5 -15
- package/build/routes/health.js.map +1 -1
- package/build/routes/imagery.d.ts +0 -1
- package/build/routes/imagery.js +1 -1
- package/build/routes/imagery.js.map +1 -1
- package/build/routes/ping.d.ts +0 -1
- package/build/routes/ping.js +1 -1
- package/build/routes/ping.js.map +1 -1
- package/build/routes/preview.d.ts +6 -5
- package/build/routes/preview.index.d.ts +0 -1
- package/build/routes/preview.index.js +6 -5
- package/build/routes/preview.index.js.map +1 -1
- package/build/routes/preview.js +35 -10
- package/build/routes/preview.js.map +1 -1
- package/build/routes/sprites.d.ts +0 -1
- package/build/routes/sprites.js +2 -4
- package/build/routes/sprites.js.map +1 -1
- package/build/routes/tile.json.d.ts +0 -1
- package/build/routes/tile.json.js +10 -5
- package/build/routes/tile.json.js.map +1 -1
- package/build/routes/tile.style.json.d.ts +1 -1
- package/build/routes/tile.style.json.js +79 -16
- package/build/routes/tile.style.json.js.map +1 -1
- package/build/routes/tile.wmts.d.ts +0 -1
- package/build/routes/tile.wmts.js +8 -9
- package/build/routes/tile.wmts.js.map +1 -1
- package/build/routes/tile.xyz.d.ts +0 -1
- package/build/routes/tile.xyz.js.map +1 -1
- package/build/routes/tile.xyz.raster.d.ts +7 -8
- package/build/routes/tile.xyz.raster.js +17 -13
- package/build/routes/tile.xyz.raster.js.map +1 -1
- package/build/routes/tile.xyz.vector.d.ts +0 -1
- package/build/routes/tile.xyz.vector.js +4 -3
- package/build/routes/tile.xyz.vector.js.map +1 -1
- package/build/routes/version.d.ts +0 -1
- package/build/routes/version.js +3 -4
- package/build/routes/version.js.map +1 -1
- package/build/util/__test__/config.loader.test.d.ts +0 -1
- package/build/util/__test__/config.loader.test.js +35 -34
- package/build/util/__test__/config.loader.test.js.map +1 -1
- package/build/util/__test__/filter.test.d.ts +0 -1
- package/build/util/__test__/filter.test.js +17 -16
- package/build/util/__test__/filter.test.js.map +1 -1
- package/build/util/__test__/validate.test.d.ts +0 -1
- package/build/util/__test__/validate.test.js +26 -43
- package/build/util/__test__/validate.test.js.map +1 -1
- package/build/util/assets.provider.d.ts +5 -5
- package/build/util/assets.provider.js +8 -8
- package/build/util/assets.provider.js.map +1 -1
- package/build/util/config.cache.d.ts +2 -2
- package/build/util/config.cache.js +14 -3
- package/build/util/config.cache.js.map +1 -1
- package/build/util/config.loader.d.ts +0 -1
- package/build/util/config.loader.js +11 -12
- package/build/util/config.loader.js.map +1 -1
- package/build/util/cotar.serve.d.ts +3 -3
- package/build/util/cotar.serve.js +2 -2
- package/build/util/cotar.serve.js.map +1 -1
- package/build/util/etag.d.ts +0 -1
- package/build/util/etag.js.map +1 -1
- package/build/util/filter.d.ts +0 -1
- package/build/util/filter.js +4 -5
- package/build/util/filter.js.map +1 -1
- package/build/util/response.d.ts +0 -1
- package/build/util/source.cache.d.ts +8 -9
- package/build/util/source.cache.js +27 -24
- package/build/util/source.cache.js.map +1 -1
- package/build/util/swapping.lru.d.ts +0 -1
- package/build/util/swapping.lru.js +48 -7
- package/build/util/swapping.lru.js.map +1 -1
- package/build/util/validate.d.ts +17 -5
- package/build/util/validate.js +51 -15
- package/build/util/validate.js.map +1 -1
- package/build/wmts.capability.d.ts +1 -2
- package/build/wmts.capability.js +81 -12
- package/build/wmts.capability.js.map +1 -1
- package/bundle.sh +2 -2
- package/package.json +16 -18
- package/scripts/create.deployment.package.mjs +4 -11
- package/src/__tests__/config.data.ts +2 -6
- package/src/__tests__/index.test.ts +29 -27
- package/src/__tests__/tile.style.json.test.ts +40 -37
- package/src/__tests__/wmts.capability.test.ts +139 -120
- package/src/cli/render.preview.ts +14 -9
- package/src/cli/render.tile.ts +27 -18
- package/src/index.ts +28 -23
- package/src/routes/__tests__/attribution.test.ts +40 -37
- package/src/routes/__tests__/fonts.test.ts +68 -64
- package/src/routes/__tests__/health.test.ts +18 -17
- package/src/routes/__tests__/imagery.test.ts +11 -9
- package/src/routes/__tests__/preview.index.test.ts +114 -40
- package/src/routes/__tests__/sprites.test.ts +39 -34
- package/src/routes/__tests__/tile.json.test.ts +41 -39
- package/src/routes/__tests__/tile.style.json.test.ts +49 -46
- package/src/routes/__tests__/wmts.test.ts +28 -20
- package/src/routes/__tests__/xyz.test.ts +134 -55
- package/src/routes/attribution.ts +2 -2
- package/src/routes/config.ts +1 -0
- package/src/routes/fonts.ts +3 -3
- package/src/routes/health.ts +7 -13
- package/src/routes/imagery.ts +2 -1
- package/src/routes/ping.ts +1 -1
- package/src/routes/preview.index.ts +9 -5
- package/src/routes/preview.ts +44 -15
- package/src/routes/sprites.ts +4 -5
- package/src/routes/tile.json.ts +9 -2
- package/src/routes/tile.style.json.ts +89 -13
- package/src/routes/tile.wmts.ts +4 -3
- package/src/routes/tile.xyz.raster.ts +26 -22
- package/src/routes/tile.xyz.ts +1 -0
- package/src/routes/tile.xyz.vector.ts +5 -3
- package/src/routes/version.ts +3 -3
- package/src/util/__test__/config.loader.test.ts +38 -34
- package/src/util/__test__/filter.test.ts +19 -16
- package/src/util/__test__/validate.test.ts +28 -43
- package/src/util/assets.provider.ts +10 -9
- package/src/util/config.cache.ts +4 -3
- package/src/util/config.loader.ts +13 -13
- package/src/util/cotar.serve.ts +3 -2
- package/src/util/source.cache.ts +15 -26
- package/src/util/validate.ts +61 -14
- package/src/wmts.capability.ts +3 -3
- package/tsconfig.json +1 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/build/__tests__/config.data.d.ts.map +0 -1
- package/build/__tests__/index.test.d.ts.map +0 -1
- package/build/__tests__/tile.style.json.test.d.ts.map +0 -1
- package/build/__tests__/wmts.capability.test.d.ts.map +0 -1
- package/build/__tests__/xyz.util.d.ts.map +0 -1
- package/build/cli/render.preview.d.ts.map +0 -1
- package/build/cli/render.tile.d.ts.map +0 -1
- package/build/index.d.ts.map +0 -1
- package/build/routes/__tests__/attribution.test.d.ts.map +0 -1
- package/build/routes/__tests__/fonts.test.d.ts.map +0 -1
- package/build/routes/__tests__/health.test.d.ts.map +0 -1
- package/build/routes/__tests__/imagery.test.d.ts.map +0 -1
- package/build/routes/__tests__/memory.fs.d.ts.map +0 -1
- package/build/routes/__tests__/preview.index.test.d.ts.map +0 -1
- package/build/routes/__tests__/sprites.test.d.ts.map +0 -1
- package/build/routes/__tests__/tile.json.test.d.ts.map +0 -1
- package/build/routes/__tests__/tile.style.json.test.d.ts.map +0 -1
- package/build/routes/__tests__/wmts.test.d.ts.map +0 -1
- package/build/routes/__tests__/xyz.test.d.ts.map +0 -1
- package/build/routes/attribution.d.ts.map +0 -1
- package/build/routes/config.d.ts.map +0 -1
- package/build/routes/fonts.d.ts.map +0 -1
- package/build/routes/health.d.ts.map +0 -1
- package/build/routes/imagery.d.ts.map +0 -1
- package/build/routes/ping.d.ts.map +0 -1
- package/build/routes/preview.d.ts.map +0 -1
- package/build/routes/preview.index.d.ts.map +0 -1
- package/build/routes/sprites.d.ts.map +0 -1
- package/build/routes/tile.json.d.ts.map +0 -1
- package/build/routes/tile.style.json.d.ts.map +0 -1
- package/build/routes/tile.wmts.d.ts.map +0 -1
- package/build/routes/tile.xyz.d.ts.map +0 -1
- package/build/routes/tile.xyz.raster.d.ts.map +0 -1
- package/build/routes/tile.xyz.vector.d.ts.map +0 -1
- package/build/routes/version.d.ts.map +0 -1
- package/build/util/__test__/config.loader.test.d.ts.map +0 -1
- package/build/util/__test__/filter.test.d.ts.map +0 -1
- package/build/util/__test__/validate.test.d.ts.map +0 -1
- package/build/util/assets.provider.d.ts.map +0 -1
- package/build/util/config.cache.d.ts.map +0 -1
- package/build/util/config.loader.d.ts.map +0 -1
- package/build/util/cotar.serve.d.ts.map +0 -1
- package/build/util/etag.d.ts.map +0 -1
- package/build/util/filter.d.ts.map +0 -1
- package/build/util/response.d.ts.map +0 -1
- package/build/util/source.cache.d.ts.map +0 -1
- package/build/util/source.tracer.d.ts +0 -18
- package/build/util/source.tracer.d.ts.map +0 -1
- package/build/util/source.tracer.js +0 -26
- package/build/util/source.tracer.js.map +0 -1
- package/build/util/swapping.lru.d.ts.map +0 -1
- package/build/util/validate.d.ts.map +0 -1
- package/build/wmts.capability.d.ts.map +0 -1
- package/src/util/source.tracer.ts +0 -38
package/src/routes/health.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
|
|
1
3
|
import { ConfigTileSetRaster } from '@basemaps/config';
|
|
2
|
-
import { GoogleTms,
|
|
4
|
+
import { GoogleTms, Nztm2000QuadTms } from '@basemaps/geo';
|
|
3
5
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
4
|
-
import * as fs from 'fs';
|
|
5
|
-
import * as path from 'path';
|
|
6
6
|
import PixelMatch from 'pixelmatch';
|
|
7
7
|
import Sharp from 'sharp';
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
import { ConfigLoader } from '../util/config.loader.js';
|
|
10
10
|
import { TileXyz } from '../util/validate.js';
|
|
11
11
|
import { TileXyzRaster } from './tile.xyz.raster.js';
|
|
@@ -15,8 +15,8 @@ interface TestTile extends TileXyz {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export const TestTiles: TestTile[] = [
|
|
18
|
-
{ tileSet: 'health', tileMatrix: GoogleTms, tileType:
|
|
19
|
-
{ tileSet: 'health', tileMatrix: Nztm2000QuadTms, tileType:
|
|
18
|
+
{ tileSet: 'health', tileMatrix: GoogleTms, tileType: 'png', tile: { x: 252, y: 156, z: 8 } },
|
|
19
|
+
{ tileSet: 'health', tileMatrix: Nztm2000QuadTms, tileType: 'png', tile: { x: 30, y: 33, z: 6 } },
|
|
20
20
|
];
|
|
21
21
|
const TileSize = 256;
|
|
22
22
|
|
|
@@ -26,13 +26,7 @@ export async function getTestBuffer(test: TestTile): Promise<Buffer> {
|
|
|
26
26
|
|
|
27
27
|
const expectedFile = `static/expected_tile_${test.tileMatrix.identifier}_${tile.x}_${tile.y}_z${tile.z}.${test.tileType}`;
|
|
28
28
|
// Initiate test img buffer if not defined
|
|
29
|
-
|
|
30
|
-
return await fs.promises.readFile(expectedFile);
|
|
31
|
-
} catch (e: any) {
|
|
32
|
-
if (e.code !== 'ENOENT') throw e;
|
|
33
|
-
const otherFile = path.join(path.dirname(url.fileURLToPath(import.meta.url)), '..', '..', expectedFile);
|
|
34
|
-
return await fs.promises.readFile(otherFile);
|
|
35
|
-
}
|
|
29
|
+
return await fs.promises.readFile(expectedFile);
|
|
36
30
|
}
|
|
37
31
|
|
|
38
32
|
export async function updateExpectedTile(test: TestTile, newTileData: Buffer, difference: Buffer): Promise<void> {
|
package/src/routes/imagery.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { fsa } from '@basemaps/shared';
|
|
|
2
2
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
3
3
|
import { promisify } from 'util';
|
|
4
4
|
import { gzip } from 'zlib';
|
|
5
|
+
|
|
5
6
|
import { ConfigLoader } from '../util/config.loader.js';
|
|
6
7
|
import { isGzip } from '../util/cotar.serve.js';
|
|
7
8
|
import { Etag } from '../util/etag.js';
|
|
@@ -38,7 +39,7 @@ export async function imageryGet(req: LambdaHttpRequest<ImageryGet>): Promise<La
|
|
|
38
39
|
const imagery = await config.Imagery.get(config.Imagery.id(req.params.imageryId));
|
|
39
40
|
if (imagery == null) return NotFound();
|
|
40
41
|
|
|
41
|
-
const targetPath = fsa.
|
|
42
|
+
const targetPath = new URL(requestedFile, fsa.toUrl(imagery.uri));
|
|
42
43
|
|
|
43
44
|
try {
|
|
44
45
|
const buf = await fsa.read(targetPath);
|
package/src/routes/ping.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { promisify } from 'node:util';
|
|
2
|
+
import { gunzip } from 'node:zlib';
|
|
3
|
+
|
|
1
4
|
import { GoogleTms, LocationUrl, LonLatZoom, TileMatrixSets } from '@basemaps/geo';
|
|
5
|
+
import { Env, fsa, getPreviewQuery } from '@basemaps/shared';
|
|
2
6
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
7
|
+
|
|
3
8
|
import { ConfigLoader } from '../util/config.loader.js';
|
|
4
|
-
import { Env, fsa } from '@basemaps/shared';
|
|
5
9
|
import { isGzip } from '../util/cotar.serve.js';
|
|
6
|
-
import { gunzip } from 'node:zlib';
|
|
7
|
-
import { promisify } from 'node:util';
|
|
8
10
|
import { Etag } from '../util/etag.js';
|
|
9
11
|
|
|
10
12
|
const gunzipP = promisify(gunzip);
|
|
@@ -43,8 +45,10 @@ export async function loadAndServeIndexHtml(
|
|
|
43
45
|
});
|
|
44
46
|
}
|
|
45
47
|
|
|
48
|
+
const staticUrl = fsa.toUrl(staticLocation);
|
|
49
|
+
|
|
46
50
|
try {
|
|
47
|
-
let indexHtml = await fsa.read(
|
|
51
|
+
let indexHtml = await fsa.read(new URL('index.html', staticUrl));
|
|
48
52
|
if (isGzip(indexHtml)) indexHtml = await gunzipP(indexHtml);
|
|
49
53
|
|
|
50
54
|
const res = new LambdaHttpResponse(200, 'ok');
|
|
@@ -100,7 +104,7 @@ export async function previewIndexGet(req: LambdaHttpRequest<PreviewIndexGet>):
|
|
|
100
104
|
const shortLocation = [short.zoom, short.lon, short.lat].join('/');
|
|
101
105
|
|
|
102
106
|
const cfg = ConfigLoader.extract(req);
|
|
103
|
-
const queryParams = cfg
|
|
107
|
+
const queryParams = getPreviewQuery({ config: cfg, pipeline: query.pipeline ?? tileSet.outputs?.[0]?.name });
|
|
104
108
|
|
|
105
109
|
// Include tile matrix name eg "[NZTM2000Quad]" in the title if its not WebMercatorQuad
|
|
106
110
|
const tileMatrixId = tileMatrix.identifier === GoogleTms.identifier ? '' : ` [${tileMatrix.identifier}]`;
|
package/src/routes/preview.ts
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import { ConfigTileSetRaster } from '@basemaps/config';
|
|
2
|
-
import { Bounds,
|
|
3
|
-
import { CompositionTiff, Tiler } from '@basemaps/tiler';
|
|
1
|
+
import { ConfigTileSetRaster, ConfigTileSetRasterOutput } from '@basemaps/config';
|
|
2
|
+
import { Bounds, LatLon, Projection, TileMatrixSet } from '@basemaps/geo';
|
|
3
|
+
import { CompositionTiff, TileMakerContext, Tiler } from '@basemaps/tiler';
|
|
4
4
|
import { SharpOverlay, TileMakerSharp } from '@basemaps/tiler-sharp';
|
|
5
5
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
6
|
+
import sharp from 'sharp';
|
|
7
|
+
|
|
6
8
|
import { ConfigLoader } from '../util/config.loader.js';
|
|
7
9
|
import { Etag } from '../util/etag.js';
|
|
8
10
|
import { NotModified } from '../util/response.js';
|
|
9
11
|
import { Validate } from '../util/validate.js';
|
|
10
|
-
import {
|
|
11
|
-
import sharp from 'sharp';
|
|
12
|
+
import { DefaultBackground, DefaultResizeKernel, isArchiveTiff, TileXyzRaster } from './tile.xyz.raster.js';
|
|
12
13
|
|
|
13
14
|
export interface PreviewGet {
|
|
14
15
|
Params: {
|
|
15
16
|
tileSet: string;
|
|
16
17
|
tileMatrix: string;
|
|
18
|
+
outputType?: string;
|
|
17
19
|
lat: string;
|
|
18
20
|
lon: string;
|
|
19
21
|
z: string;
|
|
@@ -23,7 +25,6 @@ export interface PreviewGet {
|
|
|
23
25
|
const PreviewSize = { width: 1200, height: 630 };
|
|
24
26
|
const TilerSharp = new TileMakerSharp(PreviewSize.width, PreviewSize.height);
|
|
25
27
|
|
|
26
|
-
const OutputFormat = ImageFormat.Webp;
|
|
27
28
|
/** Slightly grey color for the checker background */
|
|
28
29
|
const PreviewBackgroundFillColor = 0xef;
|
|
29
30
|
/** Make th e checkered background 30x30px */
|
|
@@ -33,6 +34,7 @@ const PreviewBackgroundSizePx = 30;
|
|
|
33
34
|
* Serve a preview of a imagery set
|
|
34
35
|
*
|
|
35
36
|
* /v1/preview/:tileSet/:tileMatrixSet/:z/:lon/:lat
|
|
37
|
+
* /v1/preview/:tileSet/:tileMatrixSet/:z/:lon/:lat/:outputType
|
|
36
38
|
*
|
|
37
39
|
* @example
|
|
38
40
|
* Raster Tile `/v1/preview/aerial/WebMercatorQuad/12/177.3998405/-39.0852555`
|
|
@@ -46,8 +48,6 @@ export async function tilePreviewGet(req: LambdaHttpRequest<PreviewGet>): Promis
|
|
|
46
48
|
req.set('projection', tileMatrix.projection.code);
|
|
47
49
|
|
|
48
50
|
// TODO we should detect the format based off the "Accept" header and maybe default back to webp
|
|
49
|
-
req.set('extension', OutputFormat);
|
|
50
|
-
|
|
51
51
|
const location = Validate.getLocation(req.params.lon, req.params.lat);
|
|
52
52
|
if (location == null) return new LambdaHttpResponse(404, 'Preview location not found');
|
|
53
53
|
req.set('location', location);
|
|
@@ -64,7 +64,23 @@ export async function tilePreviewGet(req: LambdaHttpRequest<PreviewGet>): Promis
|
|
|
64
64
|
// Only raster previews are supported
|
|
65
65
|
if (tileSet.type !== 'raster') return new LambdaHttpResponse(404, 'Preview invalid tile set type');
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
const pipeline = req.query.get('pipeline');
|
|
68
|
+
|
|
69
|
+
// Use the prefered output format from the pipeline if its defined
|
|
70
|
+
let defaultFormat = 'webp';
|
|
71
|
+
if (pipeline) {
|
|
72
|
+
const output = tileSet.outputs?.find((f) => f.name === pipeline);
|
|
73
|
+
defaultFormat = output?.format?.[0] ?? defaultFormat;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const outputFormat = req.params.outputType ?? defaultFormat;
|
|
77
|
+
|
|
78
|
+
const tileOutput = Validate.pipeline(tileSet, outputFormat, req.query.get('pipeline'));
|
|
79
|
+
if (tileOutput == null) return new LambdaHttpResponse(404, `Output format: ${outputFormat} not found`);
|
|
80
|
+
req.set('extension', outputFormat);
|
|
81
|
+
req.set('pipeline', tileOutput.name ?? 'rgba');
|
|
82
|
+
|
|
83
|
+
return renderPreview(req, { tileSet, tileMatrix, location, output: tileOutput, z });
|
|
68
84
|
}
|
|
69
85
|
|
|
70
86
|
interface PreviewRenderContext {
|
|
@@ -74,8 +90,8 @@ interface PreviewRenderContext {
|
|
|
74
90
|
tileMatrix: TileMatrixSet;
|
|
75
91
|
/** Center point of the preview */
|
|
76
92
|
location: LatLon;
|
|
77
|
-
/**
|
|
78
|
-
|
|
93
|
+
/** Image format to render the preview as */
|
|
94
|
+
output: ConfigTileSetRasterOutput;
|
|
79
95
|
/** Zom level to be use, must be a integer */
|
|
80
96
|
z: number;
|
|
81
97
|
}
|
|
@@ -133,10 +149,23 @@ export async function renderPreview(req: LambdaHttpRequest, ctx: PreviewRenderCo
|
|
|
133
149
|
compositions.push(...result);
|
|
134
150
|
}
|
|
135
151
|
|
|
152
|
+
const tileOutput = ctx.output;
|
|
153
|
+
const tileContext: TileMakerContext = {
|
|
154
|
+
layers: compositions,
|
|
155
|
+
pipeline: tileOutput.pipeline,
|
|
156
|
+
format: tileOutput.format?.[0] ?? 'webp', // default to the first output format if defined or webp
|
|
157
|
+
background: tileOutput.background ?? ctx.tileSet.background ?? DefaultBackground,
|
|
158
|
+
resizeKernel: tileOutput.resizeKernel ?? ctx.tileSet.resizeKernel ?? DefaultResizeKernel,
|
|
159
|
+
log: req.log,
|
|
160
|
+
};
|
|
161
|
+
|
|
136
162
|
// Load all the tiff tiles and resize/them into the correct locations
|
|
137
163
|
req.timer.start('compose:overlay');
|
|
138
164
|
const overlays = (await Promise.all(
|
|
139
|
-
compositions.map((comp) =>
|
|
165
|
+
compositions.map((comp) => {
|
|
166
|
+
if (tileContext.pipeline) return TilerSharp.composeTilePipeline(comp, tileContext);
|
|
167
|
+
return TilerSharp.composeTileTiff(comp, tileContext.resizeKernel);
|
|
168
|
+
}),
|
|
140
169
|
).then((items) => items.filter((f) => f != null))) as SharpOverlay[];
|
|
141
170
|
req.timer.end('compose:overlay');
|
|
142
171
|
|
|
@@ -145,7 +174,7 @@ export async function renderPreview(req: LambdaHttpRequest, ctx: PreviewRenderCo
|
|
|
145
174
|
img.composite(overlays);
|
|
146
175
|
|
|
147
176
|
req.timer.start('compose:compress');
|
|
148
|
-
const buf = await TilerSharp.toImage(
|
|
177
|
+
const buf = await TilerSharp.toImage(tileContext.format, img, tileContext.lossless);
|
|
149
178
|
req.timer.end('compose:compress');
|
|
150
179
|
|
|
151
180
|
req.set('layersUsed', overlays.length);
|
|
@@ -153,10 +182,10 @@ export async function renderPreview(req: LambdaHttpRequest, ctx: PreviewRenderCo
|
|
|
153
182
|
const response = new LambdaHttpResponse(200, 'ok');
|
|
154
183
|
response.header(HttpHeader.ETag, cacheKey);
|
|
155
184
|
response.header(HttpHeader.CacheControl, 'public, max-age=604800, stale-while-revalidate=86400');
|
|
156
|
-
response.buffer(buf, 'image/' +
|
|
185
|
+
response.buffer(buf, 'image/' + tileContext.format);
|
|
157
186
|
|
|
158
187
|
const shortLocation = [ctx.location.lon.toFixed(7), ctx.location.lat.toFixed(7)].join('_');
|
|
159
|
-
const suggestedFileName = `preview_${ctx.tileSet.name}_z${ctx.z}_${shortLocation}
|
|
188
|
+
const suggestedFileName = `preview_${ctx.tileSet.name}_z${ctx.z}_${shortLocation}-${ctx.output.name}.${tileContext.format}`;
|
|
160
189
|
response.header('Content-Disposition', `inline; filename=\"${suggestedFileName}\"`);
|
|
161
190
|
|
|
162
191
|
return response;
|
package/src/routes/sprites.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { fsa } from '@chunkd/fs';
|
|
2
|
-
import path from 'path';
|
|
3
1
|
import { LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
4
|
-
import
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
5
4
|
import { assetProvider } from '../util/assets.provider.js';
|
|
5
|
+
import { NotFound } from '../util/response.js';
|
|
6
6
|
|
|
7
7
|
interface SpriteGet {
|
|
8
8
|
Params: {
|
|
@@ -19,6 +19,5 @@ export async function spriteGet(req: LambdaHttpRequest<SpriteGet>): Promise<Lamb
|
|
|
19
19
|
const mimeType = Extensions.get(extension);
|
|
20
20
|
if (mimeType == null) return NotFound();
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
return assetProvider.serve(req, targetFile, mimeType);
|
|
22
|
+
return assetProvider.serve(req, `sprites/${req.params.spriteName}`, mimeType);
|
|
24
23
|
}
|
package/src/routes/tile.json.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConfigTileSet, TileSetType } from '@basemaps/config';
|
|
2
|
+
import { GoogleTms, OutputFormat, TileJson, TileMatrixSet } from '@basemaps/geo';
|
|
2
3
|
import { Env, toQueryString } from '@basemaps/shared';
|
|
3
4
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
5
|
+
|
|
4
6
|
import { ConfigLoader } from '../util/config.loader.js';
|
|
5
7
|
import { getFilters } from '../util/filter.js';
|
|
6
8
|
import { NotFound } from '../util/response.js';
|
|
@@ -13,6 +15,11 @@ export interface TileJsonGet {
|
|
|
13
15
|
};
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
function defaultOutputFormat(tileSet: ConfigTileSet): OutputFormat[] {
|
|
19
|
+
if (tileSet.type === TileSetType.Vector) return ['pbf'];
|
|
20
|
+
return ['webp'];
|
|
21
|
+
}
|
|
22
|
+
|
|
16
23
|
export async function tileJsonGet(req: LambdaHttpRequest<TileJsonGet>): Promise<LambdaHttpResponse> {
|
|
17
24
|
const tileMatrix = Validate.getTileMatrixSet(req.params.tileMatrix);
|
|
18
25
|
if (tileMatrix == null) return NotFound();
|
|
@@ -26,7 +33,7 @@ export async function tileJsonGet(req: LambdaHttpRequest<TileJsonGet>): Promise<
|
|
|
26
33
|
req.timer.end('tileset:load');
|
|
27
34
|
if (tileSet == null) return NotFound();
|
|
28
35
|
|
|
29
|
-
const format = Validate.getRequestedFormats(req) ??
|
|
36
|
+
const format: OutputFormat[] = Validate.getRequestedFormats(req) ?? defaultOutputFormat(tileSet);
|
|
30
37
|
|
|
31
38
|
const host = Env.get(Env.PublicUrlBase) ?? '';
|
|
32
39
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { ConfigTileSetRaster, Layer, Sources, StyleJson, TileSetType } from '@basemaps/config';
|
|
2
|
+
import { GoogleTms, TileMatrixSets } from '@basemaps/geo';
|
|
2
3
|
import { Env, toQueryString } from '@basemaps/shared';
|
|
3
|
-
import { fsa } from '@chunkd/fs';
|
|
4
4
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
5
5
|
import { URL } from 'url';
|
|
6
|
-
|
|
7
|
-
import { Validate } from '../util/validate.js';
|
|
8
|
-
import { Etag } from '../util/etag.js';
|
|
6
|
+
|
|
9
7
|
import { ConfigLoader } from '../util/config.loader.js';
|
|
10
|
-
import {
|
|
8
|
+
import { Etag } from '../util/etag.js';
|
|
11
9
|
import { getFilters } from '../util/filter.js';
|
|
10
|
+
import { NotFound, NotModified } from '../util/response.js';
|
|
11
|
+
import { Validate } from '../util/validate.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Convert relative URLS into a full hostname url
|
|
@@ -20,7 +20,7 @@ export function convertRelativeUrl(url?: string, apiKey?: string, config?: strin
|
|
|
20
20
|
if (url == null) return '';
|
|
21
21
|
const host = Env.get(Env.PublicUrlBase) ?? '';
|
|
22
22
|
if (!url.startsWith('/')) return url; // Not relative ignore
|
|
23
|
-
const fullUrl = new URL(
|
|
23
|
+
const fullUrl = new URL(url, host);
|
|
24
24
|
if (apiKey) fullUrl.searchParams.set('api', apiKey);
|
|
25
25
|
if (config) fullUrl.searchParams.set('config', config);
|
|
26
26
|
return fullUrl.toString().replace(/%7B/g, '{').replace(/%7D/g, '}');
|
|
@@ -70,16 +70,19 @@ export async function tileSetToStyle(
|
|
|
70
70
|
): Promise<LambdaHttpResponse> {
|
|
71
71
|
const tileMatrix = TileMatrixSets.find(req.query.get('tileMatrix') ?? GoogleTms.identifier);
|
|
72
72
|
if (tileMatrix == null) return new LambdaHttpResponse(400, 'Invalid tile matrix');
|
|
73
|
-
const [tileFormat] = Validate.getRequestedFormats(req) ?? [
|
|
73
|
+
const [tileFormat] = Validate.getRequestedFormats(req) ?? ['webp'];
|
|
74
74
|
if (tileFormat == null) return new LambdaHttpResponse(400, 'Invalid image format');
|
|
75
75
|
|
|
76
|
+
const pipeline = Validate.pipeline(tileSet, tileFormat, req.query.get('pipeline'));
|
|
77
|
+
const pipelineName = pipeline?.name === 'rgba' ? undefined : pipeline?.name;
|
|
78
|
+
|
|
76
79
|
const configLocation = ConfigLoader.extract(req);
|
|
77
|
-
const query = toQueryString({ config: configLocation, api: apiKey, ...getFilters(req) });
|
|
80
|
+
const query = toQueryString({ config: configLocation, api: apiKey, ...getFilters(req), pipeline: pipelineName });
|
|
81
|
+
|
|
82
|
+
const tileUrl =
|
|
83
|
+
(Env.get(Env.PublicUrlBase) ?? '') +
|
|
84
|
+
`/v1/tiles/${tileSet.name}/${tileMatrix.identifier}/{z}/{x}/{y}.${tileFormat}${query}`;
|
|
78
85
|
|
|
79
|
-
const tileUrl = fsa.join(
|
|
80
|
-
Env.get(Env.PublicUrlBase) ?? '',
|
|
81
|
-
`/v1/tiles/${tileSet.name}/${tileMatrix.identifier}/{z}/{x}/{y}.${tileFormat}${query}`,
|
|
82
|
-
);
|
|
83
86
|
const styleId = `basemaps-${tileSet.name}`;
|
|
84
87
|
const style = {
|
|
85
88
|
version: 8,
|
|
@@ -99,6 +102,78 @@ export async function tileSetToStyle(
|
|
|
99
102
|
return response;
|
|
100
103
|
}
|
|
101
104
|
|
|
105
|
+
export async function tileSetOutputToStyle(
|
|
106
|
+
req: LambdaHttpRequest<StyleGet>,
|
|
107
|
+
tileSet: ConfigTileSetRaster,
|
|
108
|
+
apiKey: string,
|
|
109
|
+
): Promise<LambdaHttpResponse> {
|
|
110
|
+
const tileMatrix = TileMatrixSets.find(req.query.get('tileMatrix') ?? GoogleTms.identifier);
|
|
111
|
+
if (tileMatrix == null) return new LambdaHttpResponse(400, 'Invalid tile matrix');
|
|
112
|
+
|
|
113
|
+
const configLocation = ConfigLoader.extract(req);
|
|
114
|
+
const query = toQueryString({ config: configLocation, api: apiKey, ...getFilters(req) });
|
|
115
|
+
|
|
116
|
+
const styleId = `basemaps-${tileSet.name}`;
|
|
117
|
+
const sources: Sources = {};
|
|
118
|
+
const layers: Layer[] = [];
|
|
119
|
+
|
|
120
|
+
if (tileSet.outputs) {
|
|
121
|
+
//for loop output.
|
|
122
|
+
for (const output of tileSet.outputs) {
|
|
123
|
+
const format = output.format?.[0] ?? 'webp';
|
|
124
|
+
const urlBase = Env.get(Env.PublicUrlBase) ?? '';
|
|
125
|
+
const tileUrl = `${urlBase}/v1/tiles/${tileSet.name}/${tileMatrix.identifier}/{z}/{x}/{y}.${format}${query}`;
|
|
126
|
+
|
|
127
|
+
if (output.name === 'terrain-rgb') {
|
|
128
|
+
// Add both raster source and dem raster source for terrain-rgb output
|
|
129
|
+
sources[`${styleId}-${output.name}`] = {
|
|
130
|
+
type: 'raster',
|
|
131
|
+
tiles: [tileUrl + `&pipeline=${output.name}`],
|
|
132
|
+
tileSize: 256,
|
|
133
|
+
};
|
|
134
|
+
sources[`${styleId}-${output.name}-dem`] = {
|
|
135
|
+
type: 'raster-dem',
|
|
136
|
+
tiles: [tileUrl + `&pipeline=${output.name}`],
|
|
137
|
+
tileSize: 256,
|
|
138
|
+
};
|
|
139
|
+
} else {
|
|
140
|
+
// Add raster source other outputs
|
|
141
|
+
sources[`${styleId}-${output.name}`] = {
|
|
142
|
+
type: 'raster',
|
|
143
|
+
tiles: [tileUrl + `&pipeline=${output.name}`],
|
|
144
|
+
tileSize: 256,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Add first raster source as default layer
|
|
151
|
+
for (const source of Object.keys(sources)) {
|
|
152
|
+
if (sources[source].type === 'raster') {
|
|
153
|
+
layers.push({
|
|
154
|
+
id: styleId,
|
|
155
|
+
type: 'raster',
|
|
156
|
+
source,
|
|
157
|
+
});
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const style = { version: 8, sources, layers };
|
|
163
|
+
|
|
164
|
+
const data = Buffer.from(JSON.stringify(style));
|
|
165
|
+
|
|
166
|
+
const cacheKey = Etag.key(data);
|
|
167
|
+
if (Etag.isNotModified(req, cacheKey)) return NotModified();
|
|
168
|
+
|
|
169
|
+
const response = new LambdaHttpResponse(200, 'ok');
|
|
170
|
+
response.header(HttpHeader.ETag, cacheKey);
|
|
171
|
+
response.header(HttpHeader.CacheControl, 'no-store');
|
|
172
|
+
response.buffer(data, 'application/json');
|
|
173
|
+
req.set('bytes', data.byteLength);
|
|
174
|
+
return response;
|
|
175
|
+
}
|
|
176
|
+
|
|
102
177
|
export async function styleJsonGet(req: LambdaHttpRequest<StyleGet>): Promise<LambdaHttpResponse> {
|
|
103
178
|
const apiKey = Validate.apiKey(req);
|
|
104
179
|
const styleName = req.params.styleName;
|
|
@@ -114,7 +189,8 @@ export async function styleJsonGet(req: LambdaHttpRequest<StyleGet>): Promise<La
|
|
|
114
189
|
const tileSet = await config.TileSet.get(config.TileSet.id(styleName));
|
|
115
190
|
if (tileSet == null) return NotFound();
|
|
116
191
|
if (tileSet.type !== TileSetType.Raster) return NotFound();
|
|
117
|
-
return
|
|
192
|
+
if (tileSet.outputs) return tileSetOutputToStyle(req, tileSet, apiKey);
|
|
193
|
+
else return tileSetToStyle(req, tileSet, apiKey);
|
|
118
194
|
}
|
|
119
195
|
|
|
120
196
|
// Prepare sources and add linz source
|
package/src/routes/tile.wmts.ts
CHANGED
|
@@ -3,12 +3,13 @@ import { GoogleTms, Nztm2000QuadTms, TileMatrixSet } from '@basemaps/geo';
|
|
|
3
3
|
import { Env } from '@basemaps/shared';
|
|
4
4
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
5
5
|
import { createHash } from 'crypto';
|
|
6
|
+
|
|
7
|
+
import { ConfigLoader } from '../util/config.loader.js';
|
|
8
|
+
import { Etag } from '../util/etag.js';
|
|
9
|
+
import { filterLayers, getFilters } from '../util/filter.js';
|
|
6
10
|
import { NotFound, NotModified } from '../util/response.js';
|
|
7
11
|
import { Validate } from '../util/validate.js';
|
|
8
12
|
import { WmtsCapabilities } from '../wmts.capability.js';
|
|
9
|
-
import { Etag } from '../util/etag.js';
|
|
10
|
-
import { ConfigLoader } from '../util/config.loader.js';
|
|
11
|
-
import { filterLayers, getFilters } from '../util/filter.js';
|
|
12
13
|
|
|
13
14
|
export interface WmtsCapabilitiesGet {
|
|
14
15
|
Params: {
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Bounds, Epsg, TileMatrixSet, TileMatrixSets
|
|
3
|
-
import { Env,
|
|
1
|
+
import { ConfigTileSetRaster, getAllImagery } from '@basemaps/config';
|
|
2
|
+
import { Bounds, Epsg, ImageFormat, TileMatrixSet, TileMatrixSets } from '@basemaps/geo';
|
|
3
|
+
import { Cotar, Env, stringToUrlFolder, Tiff } from '@basemaps/shared';
|
|
4
4
|
import { Tiler } from '@basemaps/tiler';
|
|
5
5
|
import { TileMakerSharp } from '@basemaps/tiler-sharp';
|
|
6
|
-
import { CogTiff } from '@cogeotiff/core';
|
|
7
|
-
import { Cotar } from '@cotar/core';
|
|
8
6
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
9
7
|
import pLimit from 'p-limit';
|
|
8
|
+
|
|
10
9
|
import { ConfigLoader } from '../util/config.loader.js';
|
|
11
10
|
import { Etag } from '../util/etag.js';
|
|
12
11
|
import { filterLayers } from '../util/filter.js';
|
|
13
12
|
import { NotFound, NotModified } from '../util/response.js';
|
|
14
13
|
import { CoSources } from '../util/source.cache.js';
|
|
15
|
-
import { TileXyz } from '../util/validate.js';
|
|
14
|
+
import { TileXyz, Validate } from '../util/validate.js';
|
|
16
15
|
|
|
17
16
|
const LoadingQueue = pLimit(Env.getNumber(Env.TiffConcurrency, 25));
|
|
18
17
|
|
|
@@ -22,13 +21,13 @@ export function getTiffName(name: string): string {
|
|
|
22
21
|
return `${name}.tiff`;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
export type CloudArchive =
|
|
24
|
+
export type CloudArchive = Tiff | Cotar;
|
|
26
25
|
|
|
27
26
|
/** Check to see if a cloud archive is a Tiff or a Cotar */
|
|
28
|
-
export function isArchiveTiff(x: CloudArchive): x is
|
|
29
|
-
if (x instanceof
|
|
30
|
-
if (x.source.
|
|
31
|
-
if (x.source.
|
|
27
|
+
export function isArchiveTiff(x: CloudArchive): x is Tiff {
|
|
28
|
+
if (x instanceof Tiff) return true;
|
|
29
|
+
if (x.source.url.pathname.endsWith('.tiff')) return true;
|
|
30
|
+
if (x.source.url.pathname.endsWith('.tif')) return true;
|
|
32
31
|
return false;
|
|
33
32
|
}
|
|
34
33
|
|
|
@@ -45,12 +44,12 @@ export const TileXyzRaster = {
|
|
|
45
44
|
bounds: Bounds,
|
|
46
45
|
zoom: number,
|
|
47
46
|
ignoreOverview = false,
|
|
48
|
-
): Promise<
|
|
47
|
+
): Promise<URL[]> {
|
|
49
48
|
const config = await ConfigLoader.load(req);
|
|
50
49
|
const imagery = await getAllImagery(config, tileSet.layers, [tileMatrix.projection]);
|
|
51
50
|
const filteredLayers = filterLayers(req, tileSet.layers);
|
|
52
51
|
|
|
53
|
-
const output:
|
|
52
|
+
const output: URL[] = [];
|
|
54
53
|
|
|
55
54
|
// All zoom level config is stored as Google zoom levels
|
|
56
55
|
const filterZoom = TileMatrixSet.convertZoomLevel(zoom, tileMatrix, TileMatrixSets.get(Epsg.Google));
|
|
@@ -69,6 +68,7 @@ export const TileXyzRaster = {
|
|
|
69
68
|
}
|
|
70
69
|
if (!bounds.intersects(Bounds.fromJson(img.bounds))) continue;
|
|
71
70
|
|
|
71
|
+
const imgUrl = stringToUrlFolder(img.uri);
|
|
72
72
|
for (const c of img.files) {
|
|
73
73
|
if (!bounds.intersects(Bounds.fromJson(c))) continue;
|
|
74
74
|
|
|
@@ -80,23 +80,23 @@ export const TileXyzRaster = {
|
|
|
80
80
|
img.overviews.minZoom <= filterZoom &&
|
|
81
81
|
ignoreOverview !== true
|
|
82
82
|
) {
|
|
83
|
-
output.push(
|
|
83
|
+
output.push(new URL(img.overviews.path, imgUrl));
|
|
84
84
|
break;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
const tiffPath =
|
|
87
|
+
const tiffPath = new URL(getTiffName(c.name), imgUrl);
|
|
88
88
|
output.push(tiffPath);
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
return output;
|
|
92
92
|
},
|
|
93
93
|
|
|
94
|
-
async loadAssets(req: LambdaHttpRequest, assets:
|
|
94
|
+
async loadAssets(req: LambdaHttpRequest, assets: URL[]): Promise<CloudArchive[]> {
|
|
95
95
|
const toLoad: Promise<CloudArchive | null>[] = [];
|
|
96
96
|
for (const assetPath of assets) {
|
|
97
97
|
toLoad.push(
|
|
98
98
|
LoadingQueue((): Promise<CloudArchive | null> => {
|
|
99
|
-
if (assetPath.endsWith('.tar.co')) {
|
|
99
|
+
if (assetPath.pathname.endsWith('.tar.co')) {
|
|
100
100
|
return CoSources.getCotar(assetPath).catch((error) => {
|
|
101
101
|
req.log.warn({ error, tiff: assetPath }, 'Load:Cotar:Failed');
|
|
102
102
|
return null;
|
|
@@ -113,13 +113,15 @@ export const TileXyzRaster = {
|
|
|
113
113
|
return (await Promise.all(toLoad)).filter((f) => f != null) as CloudArchive[];
|
|
114
114
|
},
|
|
115
115
|
|
|
116
|
-
async getAssetsForTile(req: LambdaHttpRequest, tileSet: ConfigTileSetRaster, xyz: TileXyz): Promise<
|
|
116
|
+
async getAssetsForTile(req: LambdaHttpRequest, tileSet: ConfigTileSetRaster, xyz: TileXyz): Promise<URL[]> {
|
|
117
117
|
const tileBounds = xyz.tileMatrix.tileToSourceBounds(xyz.tile);
|
|
118
118
|
return TileXyzRaster.getAssetsForBounds(req, tileSet, xyz.tileMatrix, tileBounds, xyz.tile.z);
|
|
119
119
|
},
|
|
120
120
|
|
|
121
121
|
async tile(req: LambdaHttpRequest, tileSet: ConfigTileSetRaster, xyz: TileXyz): Promise<LambdaHttpResponse> {
|
|
122
|
-
|
|
122
|
+
const tileOutput = Validate.pipeline(tileSet, xyz.tileType, xyz.pipeline);
|
|
123
|
+
if (tileOutput == null) return NotFound();
|
|
124
|
+
req.set('pipeline', tileOutput.name);
|
|
123
125
|
|
|
124
126
|
const assetPaths = await this.getAssetsForTile(req, tileSet, xyz);
|
|
125
127
|
const cacheKey = Etag.key(assetPaths);
|
|
@@ -132,10 +134,12 @@ export const TileXyzRaster = {
|
|
|
132
134
|
|
|
133
135
|
const res = await TileComposer.compose({
|
|
134
136
|
layers,
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
137
|
+
pipeline: tileOutput.pipeline,
|
|
138
|
+
format: xyz.tileType as ImageFormat,
|
|
139
|
+
background: tileOutput.background ?? tileSet.background ?? DefaultBackground,
|
|
140
|
+
resizeKernel: tileOutput.resizeKernel ?? tileSet.resizeKernel ?? DefaultResizeKernel,
|
|
138
141
|
metrics: req.timer,
|
|
142
|
+
log: req.log,
|
|
139
143
|
});
|
|
140
144
|
|
|
141
145
|
req.set('layersUsed', res.layers);
|
package/src/routes/tile.xyz.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { TileSetType } from '@basemaps/config';
|
|
2
2
|
import { LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
3
|
+
|
|
3
4
|
import { ConfigLoader } from '../util/config.loader.js';
|
|
4
5
|
import { NotFound } from '../util/response.js';
|
|
5
6
|
import { Validate } from '../util/validate.js';
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ConfigTileSetVector } from '@basemaps/config';
|
|
2
|
-
import { GoogleTms
|
|
2
|
+
import { GoogleTms } from '@basemaps/geo';
|
|
3
|
+
import { fsa } from '@basemaps/shared';
|
|
3
4
|
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
5
|
+
|
|
4
6
|
import { isGzip } from '../util/cotar.serve.js';
|
|
5
7
|
import { Etag } from '../util/etag.js';
|
|
6
8
|
import { NoContent, NotFound, NotModified } from '../util/response.js';
|
|
@@ -10,7 +12,7 @@ import { TileXyz } from '../util/validate.js';
|
|
|
10
12
|
export const tileXyzVector = {
|
|
11
13
|
/** Serve a MVT vector tile */
|
|
12
14
|
async tile(req: LambdaHttpRequest, tileSet: ConfigTileSetVector, xyz: TileXyz): Promise<LambdaHttpResponse> {
|
|
13
|
-
if (xyz.tileType !==
|
|
15
|
+
if (xyz.tileType !== 'pbf') return NotFound();
|
|
14
16
|
if (xyz.tileMatrix.identifier !== GoogleTms.identifier) return NotFound();
|
|
15
17
|
|
|
16
18
|
if (tileSet.layers.length > 1) return new LambdaHttpResponse(500, 'Too many layers in tileset');
|
|
@@ -28,7 +30,7 @@ export const tileXyzVector = {
|
|
|
28
30
|
if (Etag.isNotModified(req, cacheKey)) return NotModified();
|
|
29
31
|
|
|
30
32
|
req.timer.start('cotar:load');
|
|
31
|
-
const cotar = await CoSources.getCotar(layerId);
|
|
33
|
+
const cotar = await CoSources.getCotar(fsa.toUrl(layerId));
|
|
32
34
|
if (cotar == null) return new LambdaHttpResponse(500, 'Failed to load VectorTiles');
|
|
33
35
|
req.timer.end('cotar:load');
|
|
34
36
|
|
package/src/routes/version.ts
CHANGED
|
@@ -8,17 +8,17 @@ export async function versionGet(): Promise<LambdaHttpResponse> {
|
|
|
8
8
|
* last git version tag
|
|
9
9
|
* @example "v6.42.1"
|
|
10
10
|
*/
|
|
11
|
-
version: process.env
|
|
11
|
+
version: process.env['GIT_VERSION'] ?? 'dev',
|
|
12
12
|
/**
|
|
13
13
|
* Full git commit hash
|
|
14
14
|
* @example "e4231b1ee62c276c8657c56677ced02681dfe5d6"
|
|
15
15
|
*/
|
|
16
|
-
hash: process.env
|
|
16
|
+
hash: process.env['GIT_HASH'],
|
|
17
17
|
/**
|
|
18
18
|
* The exact build that this release was run from
|
|
19
19
|
* @example "1658821493-3"
|
|
20
20
|
*/
|
|
21
|
-
buildId: process.env
|
|
21
|
+
buildId: process.env['BUILD_ID'],
|
|
22
22
|
});
|
|
23
23
|
return response;
|
|
24
24
|
}
|