@basemaps/lambda-tiler 7.11.0 → 7.13.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 +28 -0
- package/build/index.js +9 -4
- package/build/index.js.map +1 -1
- package/build/routes/__tests__/link.test.d.ts +1 -0
- package/build/routes/__tests__/link.test.js +82 -0
- package/build/routes/__tests__/link.test.js.map +1 -0
- package/build/routes/__tests__/tile.style.json.attribution.test.d.ts +1 -0
- package/build/routes/__tests__/tile.style.json.attribution.test.js +172 -0
- package/build/routes/__tests__/tile.style.json.attribution.test.js.map +1 -0
- package/build/routes/__tests__/tile.style.json.test.js +3 -1
- package/build/routes/__tests__/tile.style.json.test.js.map +1 -1
- package/build/routes/attribution.d.ts +19 -1
- package/build/routes/attribution.js +38 -3
- package/build/routes/attribution.js.map +1 -1
- package/build/routes/link.d.ts +17 -0
- package/build/routes/link.js +42 -0
- package/build/routes/link.js.map +1 -0
- package/build/routes/tile.style.json.d.ts +6 -2
- package/build/routes/tile.style.json.js +13 -5
- package/build/routes/tile.style.json.js.map +1 -1
- package/build/util/__test__/nztm.style.test.js +16 -7
- package/build/util/__test__/nztm.style.test.js.map +1 -1
- package/build/util/nztm.style.js +0 -3
- package/build/util/nztm.style.js.map +1 -1
- package/dist/index.js +86535 -0
- package/dist/node_modules/.package-lock.json +179 -0
- package/dist/node_modules/@img/sharp-libvips-linux-arm64/README.md +47 -0
- package/dist/node_modules/@img/sharp-libvips-linux-arm64/lib/glib-2.0/include/glibconfig.h +219 -0
- package/dist/node_modules/@img/sharp-libvips-linux-arm64/lib/index.js +1 -0
- package/dist/node_modules/@img/sharp-libvips-linux-arm64/lib/libvips-cpp.so.42 +0 -0
- package/dist/node_modules/@img/sharp-libvips-linux-arm64/package.json +45 -0
- package/dist/node_modules/@img/sharp-libvips-linux-arm64/versions.json +31 -0
- package/dist/node_modules/@img/sharp-linux-arm64/LICENSE +191 -0
- package/dist/node_modules/@img/sharp-linux-arm64/README.md +18 -0
- package/dist/node_modules/@img/sharp-linux-arm64/lib/sharp-linux-arm64.node +0 -0
- package/dist/node_modules/@img/sharp-linux-arm64/package.json +47 -0
- package/dist/node_modules/color/LICENSE +21 -0
- package/dist/node_modules/color/README.md +123 -0
- package/dist/node_modules/color/index.js +496 -0
- package/dist/node_modules/color/package.json +47 -0
- package/dist/node_modules/color-convert/CHANGELOG.md +54 -0
- package/dist/node_modules/color-convert/LICENSE +21 -0
- package/dist/node_modules/color-convert/README.md +68 -0
- package/dist/node_modules/color-convert/conversions.js +839 -0
- package/dist/node_modules/color-convert/index.js +81 -0
- package/dist/node_modules/color-convert/package.json +48 -0
- package/dist/node_modules/color-convert/route.js +97 -0
- package/dist/node_modules/color-name/LICENSE +8 -0
- package/dist/node_modules/color-name/README.md +11 -0
- package/dist/node_modules/color-name/index.js +152 -0
- package/dist/node_modules/color-name/package.json +28 -0
- package/dist/node_modules/color-string/LICENSE +21 -0
- package/dist/node_modules/color-string/README.md +62 -0
- package/dist/node_modules/color-string/index.js +242 -0
- package/dist/node_modules/color-string/package.json +39 -0
- package/dist/node_modules/detect-libc/LICENSE +201 -0
- package/dist/node_modules/detect-libc/README.md +163 -0
- package/dist/node_modules/detect-libc/index.d.ts +14 -0
- package/dist/node_modules/detect-libc/lib/detect-libc.js +267 -0
- package/dist/node_modules/detect-libc/lib/filesystem.js +41 -0
- package/dist/node_modules/detect-libc/lib/process.js +24 -0
- package/dist/node_modules/detect-libc/package.json +40 -0
- package/dist/node_modules/is-arrayish/LICENSE +21 -0
- package/dist/node_modules/is-arrayish/README.md +16 -0
- package/dist/node_modules/is-arrayish/index.js +9 -0
- package/dist/node_modules/is-arrayish/package.json +45 -0
- package/dist/node_modules/is-arrayish/yarn-error.log +1443 -0
- package/dist/node_modules/lerc/CHANGELOG.md +69 -0
- package/dist/node_modules/lerc/LercDecode.d.ts +61 -0
- package/dist/node_modules/lerc/LercDecode.es.d.ts +61 -0
- package/dist/node_modules/lerc/LercDecode.es.js +434 -0
- package/dist/node_modules/lerc/LercDecode.es.min.js +17 -0
- package/dist/node_modules/lerc/LercDecode.js +448 -0
- package/dist/node_modules/lerc/LercDecode.min.js +17 -0
- package/dist/node_modules/lerc/README.md +123 -0
- package/dist/node_modules/lerc/lerc-wasm.wasm +0 -0
- package/dist/node_modules/lerc/package.json +30 -0
- package/dist/node_modules/semver/LICENSE +15 -0
- package/dist/node_modules/semver/README.md +654 -0
- package/dist/node_modules/semver/bin/semver.js +188 -0
- package/dist/node_modules/semver/classes/comparator.js +141 -0
- package/dist/node_modules/semver/classes/index.js +5 -0
- package/dist/node_modules/semver/classes/range.js +554 -0
- package/dist/node_modules/semver/classes/semver.js +302 -0
- package/dist/node_modules/semver/functions/clean.js +6 -0
- package/dist/node_modules/semver/functions/cmp.js +52 -0
- package/dist/node_modules/semver/functions/coerce.js +60 -0
- package/dist/node_modules/semver/functions/compare-build.js +7 -0
- package/dist/node_modules/semver/functions/compare-loose.js +3 -0
- package/dist/node_modules/semver/functions/compare.js +5 -0
- package/dist/node_modules/semver/functions/diff.js +65 -0
- package/dist/node_modules/semver/functions/eq.js +3 -0
- package/dist/node_modules/semver/functions/gt.js +3 -0
- package/dist/node_modules/semver/functions/gte.js +3 -0
- package/dist/node_modules/semver/functions/inc.js +19 -0
- package/dist/node_modules/semver/functions/lt.js +3 -0
- package/dist/node_modules/semver/functions/lte.js +3 -0
- package/dist/node_modules/semver/functions/major.js +3 -0
- package/dist/node_modules/semver/functions/minor.js +3 -0
- package/dist/node_modules/semver/functions/neq.js +3 -0
- package/dist/node_modules/semver/functions/parse.js +16 -0
- package/dist/node_modules/semver/functions/patch.js +3 -0
- package/dist/node_modules/semver/functions/prerelease.js +6 -0
- package/dist/node_modules/semver/functions/rcompare.js +3 -0
- package/dist/node_modules/semver/functions/rsort.js +3 -0
- package/dist/node_modules/semver/functions/satisfies.js +10 -0
- package/dist/node_modules/semver/functions/sort.js +3 -0
- package/dist/node_modules/semver/functions/valid.js +6 -0
- package/dist/node_modules/semver/index.js +89 -0
- package/dist/node_modules/semver/internal/constants.js +35 -0
- package/dist/node_modules/semver/internal/debug.js +9 -0
- package/dist/node_modules/semver/internal/identifiers.js +23 -0
- package/dist/node_modules/semver/internal/lrucache.js +40 -0
- package/dist/node_modules/semver/internal/parse-options.js +15 -0
- package/dist/node_modules/semver/internal/re.js +217 -0
- package/dist/node_modules/semver/package.json +77 -0
- package/dist/node_modules/semver/preload.js +2 -0
- package/dist/node_modules/semver/range.bnf +16 -0
- package/dist/node_modules/semver/ranges/gtr.js +4 -0
- package/dist/node_modules/semver/ranges/intersects.js +7 -0
- package/dist/node_modules/semver/ranges/ltr.js +4 -0
- package/dist/node_modules/semver/ranges/max-satisfying.js +25 -0
- package/dist/node_modules/semver/ranges/min-satisfying.js +24 -0
- package/dist/node_modules/semver/ranges/min-version.js +61 -0
- package/dist/node_modules/semver/ranges/outside.js +80 -0
- package/dist/node_modules/semver/ranges/simplify.js +47 -0
- package/dist/node_modules/semver/ranges/subset.js +247 -0
- package/dist/node_modules/semver/ranges/to-comparators.js +8 -0
- package/dist/node_modules/semver/ranges/valid.js +11 -0
- package/dist/node_modules/sharp/LICENSE +191 -0
- package/dist/node_modules/sharp/README.md +118 -0
- package/dist/node_modules/sharp/install/check.js +36 -0
- package/dist/node_modules/sharp/lib/channel.js +174 -0
- package/dist/node_modules/sharp/lib/colour.js +182 -0
- package/dist/node_modules/sharp/lib/composite.js +210 -0
- package/dist/node_modules/sharp/lib/constructor.js +444 -0
- package/dist/node_modules/sharp/lib/index.d.ts +1717 -0
- package/dist/node_modules/sharp/lib/index.js +16 -0
- package/dist/node_modules/sharp/lib/input.js +657 -0
- package/dist/node_modules/sharp/lib/is.js +169 -0
- package/dist/node_modules/sharp/lib/libvips.js +171 -0
- package/dist/node_modules/sharp/lib/operation.js +919 -0
- package/dist/node_modules/sharp/lib/output.js +1561 -0
- package/dist/node_modules/sharp/lib/resize.js +582 -0
- package/dist/node_modules/sharp/lib/sharp.js +86 -0
- package/dist/node_modules/sharp/lib/utility.js +287 -0
- package/dist/node_modules/sharp/package.json +219 -0
- package/dist/node_modules/sharp/src/binding.gyp +277 -0
- package/dist/node_modules/sharp/src/common.cc +1090 -0
- package/dist/node_modules/sharp/src/common.h +393 -0
- package/dist/node_modules/sharp/src/metadata.cc +287 -0
- package/dist/node_modules/sharp/src/metadata.h +82 -0
- package/dist/node_modules/sharp/src/operations.cc +471 -0
- package/dist/node_modules/sharp/src/operations.h +125 -0
- package/dist/node_modules/sharp/src/pipeline.cc +1724 -0
- package/dist/node_modules/sharp/src/pipeline.h +385 -0
- package/dist/node_modules/sharp/src/sharp.cc +40 -0
- package/dist/node_modules/sharp/src/stats.cc +183 -0
- package/dist/node_modules/sharp/src/stats.h +59 -0
- package/dist/node_modules/sharp/src/utilities.cc +269 -0
- package/dist/node_modules/sharp/src/utilities.h +19 -0
- package/dist/node_modules/simple-swizzle/LICENSE +21 -0
- package/dist/node_modules/simple-swizzle/README.md +39 -0
- package/dist/node_modules/simple-swizzle/index.js +29 -0
- package/dist/node_modules/simple-swizzle/package.json +36 -0
- package/dist/package-lock.json +610 -0
- package/dist/package.json +40 -0
- package/dist/static/expected_tile_2193_153_255_z7.png +0 -0
- package/dist/static/expected_tile_NZTM2000Quad_30_33_z6.png +0 -0
- package/dist/static/expected_tile_WebMercatorQuad_252_156_z8.png +0 -0
- package/package.json +9 -9
- package/src/index.ts +10 -4
- package/src/routes/__tests__/link.test.ts +114 -0
- package/src/routes/__tests__/tile.style.json.attribution.test.ts +224 -0
- package/src/routes/__tests__/tile.style.json.test.ts +3 -2
- package/src/routes/attribution.ts +50 -5
- package/src/routes/link.ts +55 -0
- package/src/routes/tile.style.json.ts +16 -5
- package/src/util/__test__/nztm.style.test.ts +18 -8
- package/src/util/nztm.style.ts +0 -3
- package/tsconfig.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basemaps/lambda-tiler",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.13.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/linz/basemaps.git",
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
"types": "./build/index.d.ts",
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@basemaps/config": "^7.
|
|
26
|
-
"@basemaps/config-loader": "^7.
|
|
27
|
-
"@basemaps/geo": "^7.
|
|
28
|
-
"@basemaps/shared": "^7.
|
|
29
|
-
"@basemaps/tiler": "^7.
|
|
30
|
-
"@basemaps/tiler-sharp": "^7.
|
|
25
|
+
"@basemaps/config": "^7.12.0",
|
|
26
|
+
"@basemaps/config-loader": "^7.12.0",
|
|
27
|
+
"@basemaps/geo": "^7.12.0",
|
|
28
|
+
"@basemaps/shared": "^7.12.0",
|
|
29
|
+
"@basemaps/tiler": "^7.12.0",
|
|
30
|
+
"@basemaps/tiler-sharp": "^7.12.0",
|
|
31
31
|
"@linzjs/geojson": "^7.10.0",
|
|
32
32
|
"@linzjs/lambda": "^4.0.0",
|
|
33
33
|
"@mapbox/vector-tile": "^2.0.3",
|
|
@@ -50,11 +50,11 @@
|
|
|
50
50
|
"bundle": "./bundle.sh"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@basemaps/attribution": "^7.
|
|
53
|
+
"@basemaps/attribution": "^7.12.0",
|
|
54
54
|
"@chunkd/fs": "^11.2.0",
|
|
55
55
|
"@types/aws-lambda": "^8.10.75",
|
|
56
56
|
"@types/pixelmatch": "^5.0.0",
|
|
57
57
|
"pretty-json-log": "^1.0.0"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "9c1d78fe9e4cccb6309b761f17dc249681ce1769"
|
|
60
60
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FsaCache, FsaLog, LogConfig } from '@basemaps/shared';
|
|
1
|
+
import { FsaCache, FsaLog, LogConfig, LogStorage } from '@basemaps/shared';
|
|
2
2
|
import { LambdaHttpRequest, LambdaHttpResponse, lf } from '@linzjs/lambda';
|
|
3
3
|
|
|
4
4
|
import { tileAttributionGet } from './routes/attribution.js';
|
|
@@ -6,6 +6,7 @@ import { configImageryGet, configTileSetGet } from './routes/config.js';
|
|
|
6
6
|
import { fontGet, fontList } from './routes/fonts.js';
|
|
7
7
|
import { healthGet } from './routes/health.js';
|
|
8
8
|
import { imageryGet } from './routes/imagery.js';
|
|
9
|
+
import { linkGet } from './routes/link.js';
|
|
9
10
|
import { pingGet } from './routes/ping.js';
|
|
10
11
|
import { previewIndexGet } from './routes/preview.index.js';
|
|
11
12
|
import { tilePreviewGet } from './routes/preview.js';
|
|
@@ -33,13 +34,14 @@ function randomTrace(req: LambdaHttpRequest): void {
|
|
|
33
34
|
const rand = Math.random();
|
|
34
35
|
// 1% trace
|
|
35
36
|
if (rand < 0.01) req.log.level = 'trace';
|
|
36
|
-
//
|
|
37
|
-
else if (rand < 0.
|
|
37
|
+
// 25% debug
|
|
38
|
+
else if (rand < 0.25) req.log.level = 'debug';
|
|
38
39
|
// everything else info
|
|
39
40
|
else req.log.level = 'info';
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
handler.router.hook('request', (req) => {
|
|
44
|
+
LogStorage.enterWith({ log: req.log });
|
|
43
45
|
FsaLog.reset();
|
|
44
46
|
|
|
45
47
|
randomTrace(req);
|
|
@@ -48,7 +50,8 @@ handler.router.hook('request', (req) => {
|
|
|
48
50
|
});
|
|
49
51
|
|
|
50
52
|
handler.router.hook('response', (req, res) => {
|
|
51
|
-
req.set('
|
|
53
|
+
req.set('fetchCount', FsaLog.count);
|
|
54
|
+
req.set('fetches', FsaLog.requests);
|
|
52
55
|
req.set('cacheSize', FsaCache.size);
|
|
53
56
|
// Force access-control-allow-origin to everything
|
|
54
57
|
res.header('access-control-allow-origin', '*');
|
|
@@ -102,6 +105,9 @@ handler.router.get('/v1/preview/:tileSet/:tileMatrix/:z/:lon/:lat/:outputType',
|
|
|
102
105
|
handler.router.get('/v1/@:location', previewIndexGet);
|
|
103
106
|
handler.router.get('/@:location', previewIndexGet);
|
|
104
107
|
|
|
108
|
+
// Link
|
|
109
|
+
handler.router.get('/v1/link/:tileSet', linkGet);
|
|
110
|
+
|
|
105
111
|
// Attribution
|
|
106
112
|
handler.router.get('/v1/tiles/:tileSet/:tileMatrix/attribution.json', tileAttributionGet);
|
|
107
113
|
handler.router.get('/v1/attribution/:tileSet/:tileMatrix/summary.json', tileAttributionGet);
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { strictEqual } from 'node:assert';
|
|
2
|
+
import { afterEach, describe, it } from 'node:test';
|
|
3
|
+
|
|
4
|
+
import { ConfigProviderMemory } from '@basemaps/config';
|
|
5
|
+
import { Epsg } from '@basemaps/geo';
|
|
6
|
+
|
|
7
|
+
import { FakeData, Imagery3857 } from '../../__tests__/config.data.js';
|
|
8
|
+
import { mockRequest } from '../../__tests__/xyz.util.js';
|
|
9
|
+
import { handler } from '../../index.js';
|
|
10
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
11
|
+
|
|
12
|
+
describe('/v1/link/:tileSet', () => {
|
|
13
|
+
const FakeTileSetName = 'tileset';
|
|
14
|
+
const config = new ConfigProviderMemory();
|
|
15
|
+
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
config.objects.clear();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 3xx status responses
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// tileset found, is raster type, has one layer, has '3857' entry, imagery found > 302 response
|
|
25
|
+
it('success: redirect to pre-zoomed imagery', async (t) => {
|
|
26
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
27
|
+
|
|
28
|
+
config.put(FakeData.tileSetRaster(FakeTileSetName));
|
|
29
|
+
config.put(Imagery3857);
|
|
30
|
+
|
|
31
|
+
const req = mockRequest(`/v1/link/${FakeTileSetName}`);
|
|
32
|
+
const res = await handler.router.handle(req);
|
|
33
|
+
|
|
34
|
+
strictEqual(res.status, 302);
|
|
35
|
+
strictEqual(res.statusDescription, 'Redirect to pre-zoomed imagery');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 4xx status responses
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
// tileset not found > 404 response
|
|
43
|
+
it('failure: tileset not found', async (t) => {
|
|
44
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
45
|
+
|
|
46
|
+
const req = mockRequest(`/v1/link/${FakeTileSetName}`);
|
|
47
|
+
const res = await handler.router.handle(req);
|
|
48
|
+
|
|
49
|
+
strictEqual(res.status, 404);
|
|
50
|
+
strictEqual(res.statusDescription, 'Tileset not found');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// tileset found, not raster type > 400 response
|
|
54
|
+
it('failure: tileset must be raster type', async (t) => {
|
|
55
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
56
|
+
|
|
57
|
+
config.put(FakeData.tileSetVector(FakeTileSetName));
|
|
58
|
+
|
|
59
|
+
const req = mockRequest(`/v1/link/${FakeTileSetName}`);
|
|
60
|
+
const res = await handler.router.handle(req);
|
|
61
|
+
|
|
62
|
+
strictEqual(res.status, 400);
|
|
63
|
+
strictEqual(res.statusDescription, 'Tileset must be raster type');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// tileset found, is raster type, has more than one layer > 400 response
|
|
67
|
+
it('failure: too many layers', async (t) => {
|
|
68
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
69
|
+
|
|
70
|
+
const tileSet = FakeData.tileSetRaster(FakeTileSetName);
|
|
71
|
+
|
|
72
|
+
// add another layer
|
|
73
|
+
tileSet.layers.push(tileSet.layers[0]);
|
|
74
|
+
|
|
75
|
+
config.put(tileSet);
|
|
76
|
+
|
|
77
|
+
const req = mockRequest(`/v1/link/${FakeTileSetName}`);
|
|
78
|
+
const res = await handler.router.handle(req);
|
|
79
|
+
|
|
80
|
+
strictEqual(res.status, 400);
|
|
81
|
+
strictEqual(res.statusDescription, 'Too many layers');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// tileset found, is raster type, has one layer, no '3857' entry > 400 response
|
|
85
|
+
it("failure: no imagery for '3857' projection", async (t) => {
|
|
86
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
87
|
+
|
|
88
|
+
const tileSet = FakeData.tileSetRaster(FakeTileSetName);
|
|
89
|
+
|
|
90
|
+
// delete '3857' entry
|
|
91
|
+
delete tileSet.layers[0][Epsg.Google.code];
|
|
92
|
+
|
|
93
|
+
config.put(tileSet);
|
|
94
|
+
|
|
95
|
+
const req = mockRequest(`/v1/link/${FakeTileSetName}`);
|
|
96
|
+
const res = await handler.router.handle(req);
|
|
97
|
+
|
|
98
|
+
strictEqual(res.status, 400);
|
|
99
|
+
strictEqual(res.statusDescription, "No imagery for '3857' projection");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// tileset found, is raster type, has one layer, has '3857' entry, imagery not found > 400 response
|
|
103
|
+
it('failure: imagery not found', async (t) => {
|
|
104
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
105
|
+
|
|
106
|
+
config.put(FakeData.tileSetRaster(FakeTileSetName));
|
|
107
|
+
|
|
108
|
+
const req = mockRequest(`/v1/link/${FakeTileSetName}`);
|
|
109
|
+
const res = await handler.router.handle(req);
|
|
110
|
+
|
|
111
|
+
strictEqual(res.status, 400);
|
|
112
|
+
strictEqual(res.statusDescription, 'Imagery not found');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import assert, { strictEqual } from 'node:assert';
|
|
2
|
+
import { afterEach, before, describe, it } from 'node:test';
|
|
3
|
+
|
|
4
|
+
import { copyright, createLicensorAttribution } from '@basemaps/attribution/build/utils.js';
|
|
5
|
+
import { ConfigProviderMemory, StyleJson } from '@basemaps/config';
|
|
6
|
+
import { StacProvider } from '@basemaps/geo';
|
|
7
|
+
import { Env } from '@basemaps/shared';
|
|
8
|
+
|
|
9
|
+
import { FakeData, Imagery3857 } from '../../__tests__/config.data.js';
|
|
10
|
+
import { Api, mockRequest } from '../../__tests__/xyz.util.js';
|
|
11
|
+
import { handler } from '../../index.js';
|
|
12
|
+
import { ConfigLoader } from '../../util/config.loader.js';
|
|
13
|
+
|
|
14
|
+
const defaultAttribution = `${copyright} LINZ`;
|
|
15
|
+
|
|
16
|
+
describe('/v1/styles', () => {
|
|
17
|
+
const host = 'https://tiles.test';
|
|
18
|
+
const config = new ConfigProviderMemory();
|
|
19
|
+
|
|
20
|
+
const FakeTileSetName = 'tileset';
|
|
21
|
+
const FakeLicensor1: StacProvider = {
|
|
22
|
+
name: 'L1',
|
|
23
|
+
roles: ['licensor'],
|
|
24
|
+
};
|
|
25
|
+
const FakeLicensor2: StacProvider = {
|
|
26
|
+
name: 'L2',
|
|
27
|
+
roles: ['licensor'],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
before(() => {
|
|
31
|
+
process.env[Env.PublicUrlBase] = host;
|
|
32
|
+
});
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
config.objects.clear();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// tileset exists, imagery not found
|
|
38
|
+
it('default: imagery not found', async (t) => {
|
|
39
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
40
|
+
|
|
41
|
+
// insert
|
|
42
|
+
config.put(FakeData.tileSetRaster(FakeTileSetName));
|
|
43
|
+
|
|
44
|
+
// request
|
|
45
|
+
const req = mockRequest(`/v1/styles/${FakeTileSetName}.json`, 'get', Api.header);
|
|
46
|
+
const res = await handler.router.handle(req);
|
|
47
|
+
strictEqual(res.status, 200);
|
|
48
|
+
|
|
49
|
+
// extract
|
|
50
|
+
const body = Buffer.from(res.body, 'base64').toString();
|
|
51
|
+
const json = JSON.parse(body) as StyleJson;
|
|
52
|
+
|
|
53
|
+
const source = Object.values(json.sources)[0];
|
|
54
|
+
assert(source != null);
|
|
55
|
+
assert(source.attribution != null);
|
|
56
|
+
|
|
57
|
+
// verify
|
|
58
|
+
strictEqual(source.attribution, defaultAttribution);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// tileset exists, imagery found, more than one layer
|
|
62
|
+
it('default: too many layers', async (t) => {
|
|
63
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
64
|
+
|
|
65
|
+
// insert
|
|
66
|
+
const tileset = FakeData.tileSetRaster(FakeTileSetName);
|
|
67
|
+
assert(tileset.layers[0] != null);
|
|
68
|
+
|
|
69
|
+
tileset.layers.push(tileset.layers[0]);
|
|
70
|
+
assert(tileset.layers.length > 1);
|
|
71
|
+
|
|
72
|
+
config.put(tileset);
|
|
73
|
+
config.put(Imagery3857);
|
|
74
|
+
|
|
75
|
+
// request
|
|
76
|
+
const req = mockRequest(`/v1/styles/${FakeTileSetName}.json`, 'get', Api.header);
|
|
77
|
+
const res = await handler.router.handle(req);
|
|
78
|
+
strictEqual(res.status, 200);
|
|
79
|
+
|
|
80
|
+
// extract
|
|
81
|
+
const body = Buffer.from(res.body, 'base64').toString();
|
|
82
|
+
const json = JSON.parse(body) as StyleJson;
|
|
83
|
+
|
|
84
|
+
const source = Object.values(json.sources)[0];
|
|
85
|
+
assert(source != null);
|
|
86
|
+
assert(source.attribution != null);
|
|
87
|
+
|
|
88
|
+
// verify
|
|
89
|
+
strictEqual(source.attribution, defaultAttribution);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// tileset exists, imagery found, one layer, no providers
|
|
93
|
+
it('default: no providers', async (t) => {
|
|
94
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
95
|
+
|
|
96
|
+
// insert
|
|
97
|
+
const tileset = FakeData.tileSetRaster(FakeTileSetName);
|
|
98
|
+
assert(tileset.layers[0] != null);
|
|
99
|
+
assert(tileset.layers.length === 1);
|
|
100
|
+
|
|
101
|
+
const imagery = Imagery3857;
|
|
102
|
+
assert(imagery.providers == null);
|
|
103
|
+
|
|
104
|
+
config.put(tileset);
|
|
105
|
+
config.put(imagery);
|
|
106
|
+
|
|
107
|
+
// request
|
|
108
|
+
const req = mockRequest(`/v1/styles/${FakeTileSetName}.json`, 'get', Api.header);
|
|
109
|
+
const res = await handler.router.handle(req);
|
|
110
|
+
strictEqual(res.status, 200);
|
|
111
|
+
|
|
112
|
+
// extract
|
|
113
|
+
const body = Buffer.from(res.body, 'base64').toString();
|
|
114
|
+
const json = JSON.parse(body) as StyleJson;
|
|
115
|
+
|
|
116
|
+
const source = Object.values(json.sources)[0];
|
|
117
|
+
assert(source != null);
|
|
118
|
+
assert(source.attribution != null);
|
|
119
|
+
|
|
120
|
+
// verify
|
|
121
|
+
strictEqual(source.attribution, defaultAttribution);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// tileset exists, imagery found, one layer, has providers, no licensors
|
|
125
|
+
it('default: no licensors', async (t) => {
|
|
126
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
127
|
+
|
|
128
|
+
// insert
|
|
129
|
+
const tileset = FakeData.tileSetRaster(FakeTileSetName);
|
|
130
|
+
assert(tileset.layers[0] != null);
|
|
131
|
+
assert(tileset.layers.length === 1);
|
|
132
|
+
|
|
133
|
+
const imagery = Imagery3857;
|
|
134
|
+
imagery.providers = [];
|
|
135
|
+
assert(imagery.providers != null);
|
|
136
|
+
|
|
137
|
+
config.put(tileset);
|
|
138
|
+
config.put(imagery);
|
|
139
|
+
|
|
140
|
+
// request
|
|
141
|
+
const req = mockRequest(`/v1/styles/${FakeTileSetName}.json`, 'get', Api.header);
|
|
142
|
+
const res = await handler.router.handle(req);
|
|
143
|
+
strictEqual(res.status, 200);
|
|
144
|
+
|
|
145
|
+
// extract
|
|
146
|
+
const body = Buffer.from(res.body, 'base64').toString();
|
|
147
|
+
const json = JSON.parse(body) as StyleJson;
|
|
148
|
+
|
|
149
|
+
const source = Object.values(json.sources)[0];
|
|
150
|
+
assert(source != null);
|
|
151
|
+
assert(source.attribution != null);
|
|
152
|
+
|
|
153
|
+
// verify
|
|
154
|
+
strictEqual(source.attribution, defaultAttribution);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// tileset exists, imagery found, one layer, has providers, one licensor
|
|
158
|
+
it('custom: one licensor', async (t) => {
|
|
159
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
160
|
+
|
|
161
|
+
// insert
|
|
162
|
+
const tileset = FakeData.tileSetRaster(FakeTileSetName);
|
|
163
|
+
assert(tileset.layers[0] != null);
|
|
164
|
+
assert(tileset.layers.length === 1);
|
|
165
|
+
|
|
166
|
+
const imagery = Imagery3857;
|
|
167
|
+
imagery.providers = [FakeLicensor1];
|
|
168
|
+
assert(imagery.providers != null);
|
|
169
|
+
|
|
170
|
+
config.put(tileset);
|
|
171
|
+
config.put(imagery);
|
|
172
|
+
|
|
173
|
+
// request
|
|
174
|
+
const req = mockRequest(`/v1/styles/${FakeTileSetName}.json`, 'get', Api.header);
|
|
175
|
+
const res = await handler.router.handle(req);
|
|
176
|
+
strictEqual(res.status, 200);
|
|
177
|
+
|
|
178
|
+
// extract
|
|
179
|
+
const body = Buffer.from(res.body, 'base64').toString();
|
|
180
|
+
const json = JSON.parse(body) as StyleJson;
|
|
181
|
+
|
|
182
|
+
const source = Object.values(json.sources)[0];
|
|
183
|
+
assert(source != null);
|
|
184
|
+
assert(source.attribution != null);
|
|
185
|
+
|
|
186
|
+
// verify
|
|
187
|
+
strictEqual(source.attribution, `${copyright} ${FakeLicensor1.name}`);
|
|
188
|
+
strictEqual(source.attribution, createLicensorAttribution([FakeLicensor1]));
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// tileset exists, imagery found, one layer, has providers, two licensors
|
|
192
|
+
it('custom: two licensors', async (t) => {
|
|
193
|
+
t.mock.method(ConfigLoader, 'getDefaultConfig', () => Promise.resolve(config));
|
|
194
|
+
|
|
195
|
+
// insert
|
|
196
|
+
const tileset = FakeData.tileSetRaster(FakeTileSetName);
|
|
197
|
+
assert(tileset.layers[0] != null);
|
|
198
|
+
assert(tileset.layers.length === 1);
|
|
199
|
+
|
|
200
|
+
const imagery = Imagery3857;
|
|
201
|
+
imagery.providers = [FakeLicensor1, FakeLicensor2];
|
|
202
|
+
assert(imagery.providers != null);
|
|
203
|
+
|
|
204
|
+
config.put(tileset);
|
|
205
|
+
config.put(imagery);
|
|
206
|
+
|
|
207
|
+
// request
|
|
208
|
+
const req = mockRequest(`/v1/styles/${FakeTileSetName}.json`, 'get', Api.header);
|
|
209
|
+
const res = await handler.router.handle(req);
|
|
210
|
+
strictEqual(res.status, 200);
|
|
211
|
+
|
|
212
|
+
// extract
|
|
213
|
+
const body = Buffer.from(res.body, 'base64').toString();
|
|
214
|
+
const json = JSON.parse(body) as StyleJson;
|
|
215
|
+
|
|
216
|
+
const source = Object.values(json.sources)[0];
|
|
217
|
+
assert(source != null);
|
|
218
|
+
assert(source.attribution != null);
|
|
219
|
+
|
|
220
|
+
// verify
|
|
221
|
+
strictEqual(source.attribution, `${copyright} ${FakeLicensor1.name}, ${FakeLicensor2.name}`);
|
|
222
|
+
strictEqual(source.attribution, createLicensorAttribution([FakeLicensor1, FakeLicensor2]));
|
|
223
|
+
});
|
|
224
|
+
});
|
|
@@ -2,7 +2,8 @@ import assert from 'node:assert';
|
|
|
2
2
|
import { afterEach, before, beforeEach, describe, it } from 'node:test';
|
|
3
3
|
|
|
4
4
|
import { ConfigProviderMemory, SourceRaster, StyleJson } from '@basemaps/config';
|
|
5
|
-
import { Terrain } from '@basemaps/config/
|
|
5
|
+
import { DefaultExaggeration, Terrain } from '@basemaps/config/build/config/vector.style.js';
|
|
6
|
+
import { Nztm2000QuadTms } from '@basemaps/geo';
|
|
6
7
|
import { Env } from '@basemaps/shared';
|
|
7
8
|
import { createSandbox } from 'sinon';
|
|
8
9
|
|
|
@@ -441,7 +442,7 @@ describe('/v1/styles', () => {
|
|
|
441
442
|
},
|
|
442
443
|
],
|
|
443
444
|
terrain: {
|
|
444
|
-
exaggeration:
|
|
445
|
+
exaggeration: DefaultExaggeration[Nztm2000QuadTms.identifier],
|
|
445
446
|
},
|
|
446
447
|
},
|
|
447
448
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createLicensorAttribution } from '@basemaps/attribution/build/utils.js';
|
|
2
|
+
import { BasemapsConfigProvider, ConfigProvider, ConfigTileSet, getAllImagery, TileSetType } from '@basemaps/config';
|
|
2
3
|
import {
|
|
3
4
|
AttributionCollection,
|
|
4
5
|
AttributionItem,
|
|
5
6
|
AttributionStac,
|
|
6
7
|
Bounds,
|
|
8
|
+
Epsg,
|
|
7
9
|
GoogleTms,
|
|
8
10
|
NamedBounds,
|
|
9
11
|
Projection,
|
|
@@ -93,10 +95,11 @@ async function tileSetAttribution(
|
|
|
93
95
|
|
|
94
96
|
const config = await ConfigLoader.load(req);
|
|
95
97
|
const imagery = await getAllImagery(config, tileSet.layers, [tileMatrix.projection]);
|
|
96
|
-
|
|
97
98
|
const host = await config.Provider.get(config.Provider.id('linz'));
|
|
98
99
|
|
|
99
|
-
for (
|
|
100
|
+
for (let i = 0; i < tileSet.layers.length; i++) {
|
|
101
|
+
const layer = tileSet.layers[i];
|
|
102
|
+
|
|
100
103
|
const imgId = layer[proj.epsg.code];
|
|
101
104
|
if (imgId == null) continue;
|
|
102
105
|
|
|
@@ -138,11 +141,12 @@ async function tileSetAttribution(
|
|
|
138
141
|
|
|
139
142
|
const zoomMin = TileMatrixSet.convertZoomLevel(layer.minZoom ? layer.minZoom : 0, GoogleTms, tileMatrix, true);
|
|
140
143
|
const zoomMax = TileMatrixSet.convertZoomLevel(layer.maxZoom ? layer.maxZoom : 32, GoogleTms, tileMatrix, true);
|
|
144
|
+
|
|
141
145
|
cols.push({
|
|
142
146
|
stac_version: Stac.Version,
|
|
143
147
|
license: Stac.License,
|
|
144
148
|
id: im.id,
|
|
145
|
-
providers: getHost(host),
|
|
149
|
+
providers: im.providers ?? getHost(host),
|
|
146
150
|
title,
|
|
147
151
|
description: 'No description',
|
|
148
152
|
extent,
|
|
@@ -150,10 +154,11 @@ async function tileSetAttribution(
|
|
|
150
154
|
summaries: {
|
|
151
155
|
'linz:category': im.category,
|
|
152
156
|
'linz:zoom': { min: zoomMin, max: zoomMax },
|
|
153
|
-
'linz:priority': [1000 +
|
|
157
|
+
'linz:priority': [1000 + i],
|
|
154
158
|
},
|
|
155
159
|
});
|
|
156
160
|
}
|
|
161
|
+
|
|
157
162
|
return {
|
|
158
163
|
id: tileSet.id,
|
|
159
164
|
type: 'FeatureCollection',
|
|
@@ -205,3 +210,43 @@ export async function tileAttributionGet(req: LambdaHttpRequest<TileAttributionG
|
|
|
205
210
|
response.json(attributions);
|
|
206
211
|
return response;
|
|
207
212
|
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Construct a licensor attribution for a given tileSet.
|
|
216
|
+
*
|
|
217
|
+
* @param provider The BasemapsConfigProvider object.
|
|
218
|
+
* @param tileSet The tileset from which to build the attribution.
|
|
219
|
+
* @param projection The projection to consider.
|
|
220
|
+
*
|
|
221
|
+
* @returns A default attribution, if the tileset has more than one layer or no such imagery for the given projection exists.
|
|
222
|
+
* Otherwise, a copyright string comprising the names of the tileset's licensors.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* "CC BY 4.0 LINZ"
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* "CC BY 4.0 Nelson City Council, Tasman District Council, Waka Kotahi"
|
|
229
|
+
*/
|
|
230
|
+
export async function createTileSetAttribution(
|
|
231
|
+
provider: BasemapsConfigProvider,
|
|
232
|
+
tileSet: ConfigTileSet,
|
|
233
|
+
projection: Epsg,
|
|
234
|
+
): Promise<string> {
|
|
235
|
+
// ensure the tileset has exactly one layer
|
|
236
|
+
if (tileSet.layers.length > 1 || tileSet.layers[0] == null) {
|
|
237
|
+
return createLicensorAttribution();
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// ensure imagery exist for the given projection
|
|
241
|
+
const imgId = tileSet.layers[0][projection.code];
|
|
242
|
+
if (imgId == null) return '';
|
|
243
|
+
|
|
244
|
+
// attempt to load the imagery
|
|
245
|
+
const imagery = await provider.Imagery.get(imgId);
|
|
246
|
+
if (imagery?.providers == null) {
|
|
247
|
+
return createLicensorAttribution();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// return a licensor attribution string
|
|
251
|
+
return createLicensorAttribution(imagery.providers);
|
|
252
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { TileSetType } from '@basemaps/config';
|
|
2
|
+
import { Epsg } from '@basemaps/geo';
|
|
3
|
+
import { getPreviewUrl } from '@basemaps/shared';
|
|
4
|
+
import { LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
5
|
+
|
|
6
|
+
import { ConfigLoader } from '../util/config.loader.js';
|
|
7
|
+
|
|
8
|
+
export interface LinkGet {
|
|
9
|
+
Params: {
|
|
10
|
+
tileSet: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Redirect the client to a Basemaps URL that is already zoomed to the extent of the tileset's imagery.
|
|
16
|
+
*
|
|
17
|
+
* /v1/link/:tileSet
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* '/v1/link/ashburton-2023-0.1m'
|
|
21
|
+
*
|
|
22
|
+
* @returns on success, 302 redirect response. on failure, 4xx status code response.
|
|
23
|
+
*/
|
|
24
|
+
export async function linkGet(req: LambdaHttpRequest<LinkGet>): Promise<LambdaHttpResponse> {
|
|
25
|
+
const config = await ConfigLoader.load(req);
|
|
26
|
+
|
|
27
|
+
// get tileset
|
|
28
|
+
|
|
29
|
+
req.timer.start('tileset:load');
|
|
30
|
+
const tileSet = await config.TileSet.get(req.params.tileSet);
|
|
31
|
+
req.timer.end('tileset:load');
|
|
32
|
+
|
|
33
|
+
if (tileSet == null) return new LambdaHttpResponse(404, 'Tileset not found');
|
|
34
|
+
|
|
35
|
+
if (tileSet.type !== TileSetType.Raster) return new LambdaHttpResponse(400, 'Tileset must be raster type');
|
|
36
|
+
|
|
37
|
+
// TODO: add support for 'aerial' and 'elevation' multi-layer tilesets
|
|
38
|
+
if (tileSet.layers.length !== 1) return new LambdaHttpResponse(400, 'Too many layers');
|
|
39
|
+
|
|
40
|
+
// get imagery
|
|
41
|
+
|
|
42
|
+
const imageryId = tileSet.layers[0][Epsg.Google.code];
|
|
43
|
+
if (imageryId === undefined) return new LambdaHttpResponse(400, "No imagery for '3857' projection");
|
|
44
|
+
|
|
45
|
+
const imagery = await config.Imagery.get(imageryId);
|
|
46
|
+
if (imagery == null) return new LambdaHttpResponse(400, 'Imagery not found');
|
|
47
|
+
|
|
48
|
+
// do redirect
|
|
49
|
+
|
|
50
|
+
const url = getPreviewUrl({ imagery });
|
|
51
|
+
|
|
52
|
+
return new LambdaHttpResponse(302, 'Redirect to pre-zoomed imagery', {
|
|
53
|
+
location: `/${url.slug}?i=${url.name}`,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
@@ -19,6 +19,7 @@ import { Etag } from '../util/etag.js';
|
|
|
19
19
|
import { convertStyleToNztmStyle } from '../util/nztm.style.js';
|
|
20
20
|
import { NotFound, NotModified } from '../util/response.js';
|
|
21
21
|
import { Validate } from '../util/validate.js';
|
|
22
|
+
import { createTileSetAttribution } from './attribution.js';
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Convert relative URL into a full hostname URL, converting {tileMatrix} into the provided tileMatrix
|
|
@@ -89,7 +90,7 @@ export interface StyleConfig {
|
|
|
89
90
|
/**
|
|
90
91
|
* Turn on the terrain setting in the style json
|
|
91
92
|
*/
|
|
92
|
-
function setStyleTerrain(style: StyleJson, terrain: string, tileMatrix: TileMatrixSet): void {
|
|
93
|
+
export function setStyleTerrain(style: StyleJson, terrain: string, tileMatrix: TileMatrixSet): void {
|
|
93
94
|
const source = Object.keys(style.sources).find((s) => s === terrain);
|
|
94
95
|
if (source == null) throw new LambdaHttpResponse(400, `Terrain: ${terrain} does not exists in the style source.`);
|
|
95
96
|
style.terrain = {
|
|
@@ -153,12 +154,13 @@ async function ensureTerrain(
|
|
|
153
154
|
* Generate a StyleJSON from a tileset
|
|
154
155
|
* @returns
|
|
155
156
|
*/
|
|
156
|
-
export function tileSetToStyle(
|
|
157
|
+
export async function tileSetToStyle(
|
|
157
158
|
req: LambdaHttpRequest<StyleGet>,
|
|
159
|
+
config: BasemapsConfigProvider,
|
|
158
160
|
tileSet: ConfigTileSetRaster,
|
|
159
161
|
tileMatrix: TileMatrixSet,
|
|
160
162
|
apiKey: string,
|
|
161
|
-
): StyleJson {
|
|
163
|
+
): Promise<StyleJson> {
|
|
162
164
|
// If the style has outputs defined it has a different process for generating the stylejson
|
|
163
165
|
if (tileSet.outputs) return tileSetOutputToStyle(req, tileSet, tileMatrix, apiKey);
|
|
164
166
|
|
|
@@ -175,12 +177,21 @@ export function tileSetToStyle(
|
|
|
175
177
|
(Env.get(Env.PublicUrlBase) ?? '') +
|
|
176
178
|
`/v1/tiles/${tileSet.name}/${tileMatrix.identifier}/{z}/{x}/{y}.${tileFormat}${query}`;
|
|
177
179
|
|
|
180
|
+
const attribution = await createTileSetAttribution(config, tileSet, tileMatrix.projection);
|
|
181
|
+
|
|
178
182
|
const styleId = `basemaps-${tileSet.name}`;
|
|
179
183
|
return {
|
|
180
184
|
id: ConfigId.prefix(ConfigPrefix.Style, tileSet.name),
|
|
181
185
|
name: tileSet.name,
|
|
182
186
|
version: 8,
|
|
183
|
-
sources: {
|
|
187
|
+
sources: {
|
|
188
|
+
[styleId]: {
|
|
189
|
+
type: 'raster',
|
|
190
|
+
tiles: [tileUrl],
|
|
191
|
+
tileSize: 256,
|
|
192
|
+
attribution,
|
|
193
|
+
},
|
|
194
|
+
},
|
|
184
195
|
layers: [{ id: styleId, type: 'raster', source: styleId }],
|
|
185
196
|
};
|
|
186
197
|
}
|
|
@@ -248,7 +259,7 @@ async function generateStyleFromTileSet(
|
|
|
248
259
|
throw new LambdaHttpResponse(400, 'Only raster tile sets can generate style JSON');
|
|
249
260
|
}
|
|
250
261
|
if (tileSet.outputs) return tileSetOutputToStyle(req, tileSet, tileMatrix, apiKey);
|
|
251
|
-
|
|
262
|
+
return tileSetToStyle(req, config, tileSet, tileMatrix, apiKey);
|
|
252
263
|
}
|
|
253
264
|
|
|
254
265
|
export interface StyleGet {
|