@basemaps/lambda-tiler 6.24.0 → 6.25.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 +35 -0
- package/build/__test__/tile.cache.key.test.js +2 -3
- package/build/__test__/tile.import.test.d.ts +2 -0
- package/build/__test__/tile.import.test.d.ts.map +1 -0
- package/build/__test__/tile.import.test.js +115 -0
- package/build/__test__/tile.set.cache.test.js +9 -0
- package/build/__test__/tile.style.json.test.js +47 -1
- package/build/__test__/xyz.test.js +55 -28
- package/build/__test__/xyz.util.d.ts +4 -0
- package/build/__test__/xyz.util.d.ts.map +1 -1
- package/build/__test__/xyz.util.js +8 -1
- package/build/cli/dump.js +2 -3
- package/build/import/imagery.find.d.ts +17 -0
- package/build/import/imagery.find.d.ts.map +1 -0
- package/build/import/imagery.find.js +38 -0
- package/build/import/make.cog.d.ts +5 -0
- package/build/import/make.cog.d.ts.map +1 -0
- package/build/import/make.cog.js +21 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -0
- package/build/routes/__test__/attribution.test.js +4 -0
- package/build/routes/__test__/health.test.js +1 -2
- package/build/routes/attribution.d.ts.map +1 -1
- package/build/routes/attribution.js +1 -0
- package/build/routes/health.d.ts.map +1 -1
- package/build/routes/health.js +3 -4
- package/build/routes/import.d.ts +9 -0
- package/build/routes/import.d.ts.map +1 -0
- package/build/routes/import.js +61 -0
- package/build/routes/tile.json.d.ts +0 -7
- package/build/routes/tile.json.d.ts.map +1 -1
- package/build/routes/tile.json.js +26 -18
- package/build/routes/tile.style.json.d.ts +8 -0
- package/build/routes/tile.style.json.d.ts.map +1 -1
- package/build/routes/tile.style.json.js +26 -20
- package/build/tile.set.cache.d.ts.map +1 -1
- package/build/tile.set.cache.js +7 -3
- package/build/tile.set.raster.d.ts +4 -2
- package/build/tile.set.raster.d.ts.map +1 -1
- package/build/tile.set.raster.js +9 -5
- package/build/tile.set.vector.d.ts +4 -1
- package/build/tile.set.vector.d.ts.map +1 -1
- package/build/tile.set.vector.js +9 -1
- package/build/wmts.capability.d.ts +4 -0
- package/build/wmts.capability.d.ts.map +1 -1
- package/build/wmts.capability.js +1 -1
- package/package.json +9 -8
- package/src/__test__/tile.cache.key.test.ts +3 -3
- package/src/__test__/tile.import.test.ts +140 -0
- package/src/__test__/tile.set.cache.test.ts +11 -0
- package/src/__test__/tile.style.json.test.ts +56 -1
- package/src/__test__/xyz.test.ts +59 -28
- package/src/__test__/xyz.util.ts +10 -2
- package/src/cli/dump.ts +2 -3
- package/src/import/imagery.find.ts +60 -0
- package/src/import/make.cog.ts +29 -0
- package/src/index.ts +2 -0
- package/src/routes/__test__/attribution.test.ts +4 -0
- package/src/routes/__test__/health.test.ts +1 -3
- package/src/routes/attribution.ts +1 -0
- package/src/routes/health.ts +3 -4
- package/src/routes/import.ts +66 -0
- package/src/routes/tile.json.ts +26 -27
- package/src/routes/tile.style.json.ts +25 -21
- package/src/tile.set.cache.ts +6 -2
- package/src/tile.set.raster.ts +9 -6
- package/src/tile.set.vector.ts +11 -2
- package/src/wmts.capability.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,41 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [6.25.0](https://github.com/linz/basemaps/compare/v6.24.2...v6.25.0) (2022-05-11)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **config:** serve tilejson 3.0.0 and allow raster imagery ([#2173](https://github.com/linz/basemaps/issues/2173)) ([29f5313](https://github.com/linz/basemaps/commit/29f53131e917fa0b3ce6f280e8f9e09f4fe6e957))
|
|
12
|
+
* **lambda-tiler:** Import api for import imagery jobs. ([#2170](https://github.com/linz/basemaps/issues/2170)) ([76b6175](https://github.com/linz/basemaps/commit/76b6175930db2a04f24437c7a05e7a70f160f7cd))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## [6.24.2](https://github.com/linz/basemaps/compare/v6.24.1...v6.24.2) (2022-04-20)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* **lambda-tiler:** expose the name of the imagery set in attribution ([#2153](https://github.com/linz/basemaps/issues/2153)) ([65d22cb](https://github.com/linz/basemaps/commit/65d22cbbf805d704b0179581ac6b66e755d2ef8f))
|
|
24
|
+
* **lambda-tiler:** missing tilesets should 404 not 500 ([#2149](https://github.com/linz/basemaps/issues/2149)) ([a3420bc](https://github.com/linz/basemaps/commit/a3420bcc956a7fc16e2b3867100bd5943fa13e73))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## [6.24.1](https://github.com/linz/basemaps/compare/v6.24.0...v6.24.1) (2022-04-07)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Bug Fixes
|
|
34
|
+
|
|
35
|
+
* **lambda-tiler:** do not destroy database config when serving style.json ([#2146](https://github.com/linz/basemaps/issues/2146)) ([a625efd](https://github.com/linz/basemaps/commit/a625efd9a5f94522c50925e764c95ddeb57de427))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
6
41
|
# [6.24.0](https://github.com/linz/basemaps/compare/v6.23.0...v6.24.0) (2022-04-05)
|
|
7
42
|
|
|
8
43
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { GoogleTms, Nztm2000Tms } from '@basemaps/geo';
|
|
1
|
+
import { GoogleTms, Nztm2000Tms, ImageFormat } from '@basemaps/geo';
|
|
2
2
|
import { TileType } from '@basemaps/shared';
|
|
3
3
|
import { TestTiff } from '@basemaps/test';
|
|
4
|
-
import { ImageFormat } from '@basemaps/tiler';
|
|
5
4
|
import o from 'ospec';
|
|
6
5
|
import { TileEtag } from '../routes/tile.etag.js';
|
|
7
6
|
o.spec('TileCacheKey', () => {
|
|
@@ -12,7 +11,7 @@ o.spec('TileCacheKey', () => {
|
|
|
12
11
|
z: 0,
|
|
13
12
|
tileMatrix: GoogleTms,
|
|
14
13
|
name: 'foo',
|
|
15
|
-
ext: ImageFormat.
|
|
14
|
+
ext: ImageFormat.Png,
|
|
16
15
|
type: TileType.Tile,
|
|
17
16
|
};
|
|
18
17
|
o.afterEach(() => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tile.import.test.d.ts","sourceRoot":"","sources":["../../src/__test__/tile.import.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { Nztm2000Tms } from '@basemaps/geo';
|
|
2
|
+
import { Config, Env, fsa, LogConfig } from '@basemaps/shared';
|
|
3
|
+
import o from 'ospec';
|
|
4
|
+
import { createHash } from 'crypto';
|
|
5
|
+
import sinon from 'sinon';
|
|
6
|
+
import { LambdaAlbRequest } from '@linzjs/lambda';
|
|
7
|
+
import { Import } from '../routes/import.js';
|
|
8
|
+
import { CogJobFactory } from '@basemaps/cli';
|
|
9
|
+
o.spec('Import', () => {
|
|
10
|
+
const sandbox = sinon.createSandbox();
|
|
11
|
+
const outputBucket = 'testOutputBucket';
|
|
12
|
+
const configBucket = 'testConfigBucket';
|
|
13
|
+
const origConfigBucket = process.env[Env.AwsRoleConfigBucket];
|
|
14
|
+
const origOutputBucket = process.env[Env.ImportImageryBucket];
|
|
15
|
+
o.beforeEach(() => {
|
|
16
|
+
process.env[Env.AwsRoleConfigBucket] = configBucket;
|
|
17
|
+
process.env[Env.ImportImageryBucket] = outputBucket;
|
|
18
|
+
});
|
|
19
|
+
o.afterEach(() => {
|
|
20
|
+
process.env[Env.AwsRoleConfigBucket] = origConfigBucket;
|
|
21
|
+
process.env[Env.ImportImageryBucket] = origOutputBucket;
|
|
22
|
+
sandbox.restore();
|
|
23
|
+
});
|
|
24
|
+
const tileMatrix = Nztm2000Tms;
|
|
25
|
+
const bucket = 'testSourceBucket';
|
|
26
|
+
const path = `s3://${bucket}/imagery/`;
|
|
27
|
+
const role = {
|
|
28
|
+
bucket,
|
|
29
|
+
accountId: '123456',
|
|
30
|
+
roleArn: 'arn:aws:iam::123456:role/read-role',
|
|
31
|
+
};
|
|
32
|
+
const files = [`${path}/1.tiff`, `${path}/2.tiff`];
|
|
33
|
+
async function* listFiles() {
|
|
34
|
+
for (const key in files)
|
|
35
|
+
yield files[key];
|
|
36
|
+
}
|
|
37
|
+
const ctx = {
|
|
38
|
+
override: {
|
|
39
|
+
projection: tileMatrix.projection,
|
|
40
|
+
resampling: {
|
|
41
|
+
warp: 'bilinear',
|
|
42
|
+
overview: 'lanczos',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
outputLocation: { type: 's3', path: `s3://${outputBucket}` },
|
|
46
|
+
sourceLocation: { type: 's3', path: path, ...role, files: files },
|
|
47
|
+
batch: true,
|
|
48
|
+
tileMatrix,
|
|
49
|
+
oneCogCovering: false,
|
|
50
|
+
};
|
|
51
|
+
const id = createHash('sha256').update(JSON.stringify(ctx)).digest('base64');
|
|
52
|
+
const jobId = Config.ProcessingJob.id(id);
|
|
53
|
+
function getRequest(path, projection) {
|
|
54
|
+
return new LambdaAlbRequest({
|
|
55
|
+
requestContext: null,
|
|
56
|
+
httpMethod: 'get',
|
|
57
|
+
path: '/v1/tiles/import',
|
|
58
|
+
body: null,
|
|
59
|
+
isBase64Encoded: false,
|
|
60
|
+
queryStringParameters: { path: path, p: projection },
|
|
61
|
+
}, {}, LogConfig.get());
|
|
62
|
+
}
|
|
63
|
+
o('should return projection not found', async () => {
|
|
64
|
+
// Given ... wrong projection
|
|
65
|
+
const req = getRequest(path, '0000');
|
|
66
|
+
// When ... Then ...
|
|
67
|
+
const res = await Import(req);
|
|
68
|
+
o(res.body).equals('{"status":404,"message":"Target projection Not found"}');
|
|
69
|
+
});
|
|
70
|
+
o('should return Invalid s3 location', async () => {
|
|
71
|
+
// Given... wrong s3 path
|
|
72
|
+
const req = getRequest('s3::testbucket/', '2193');
|
|
73
|
+
// When ...Then ...
|
|
74
|
+
const res = await Import(req);
|
|
75
|
+
o(res.body).equals('{"status":500,"message":"Invalid s3 path"}');
|
|
76
|
+
});
|
|
77
|
+
o('should return Unable to access bucket', async () => {
|
|
78
|
+
// Given... different bucket have no access role
|
|
79
|
+
sandbox.stub(fsa, 'readJson').resolves({ buckets: [role] });
|
|
80
|
+
const req = getRequest(`s3://wrong-bucket/imagery/`, '2193');
|
|
81
|
+
// When ...Then ...
|
|
82
|
+
const res = await Import(req);
|
|
83
|
+
o(res.body).equals('{"status":500,"message":"Unable to Access the bucket"}');
|
|
84
|
+
});
|
|
85
|
+
o('should return Imagery not found', async () => {
|
|
86
|
+
// Given... none imagery find from bucket
|
|
87
|
+
sandbox.stub(fsa, 'readJson').resolves({ buckets: [role] });
|
|
88
|
+
sandbox.stub(fsa, 'list').callsFake(async function* () {
|
|
89
|
+
yield `${path}1.json`;
|
|
90
|
+
});
|
|
91
|
+
const req = getRequest(path, '2193');
|
|
92
|
+
// When ...Then ...
|
|
93
|
+
const res = await Import(req);
|
|
94
|
+
o(res.body).equals('{"status":404,"message":"Imagery Not Found"}');
|
|
95
|
+
});
|
|
96
|
+
o('should return 200 with existing import', async () => {
|
|
97
|
+
var _a;
|
|
98
|
+
// Given... different bucket have no access role
|
|
99
|
+
sandbox.stub(fsa, 'readJson').resolves({ buckets: [role] });
|
|
100
|
+
sandbox.stub(fsa, 'list').callsFake(listFiles);
|
|
101
|
+
sandbox.stub(CogJobFactory, 'create').resolves(undefined);
|
|
102
|
+
const jobConfig = {
|
|
103
|
+
id: jobId,
|
|
104
|
+
name: path,
|
|
105
|
+
status: 'complete',
|
|
106
|
+
};
|
|
107
|
+
sandbox.stub(Config.ProcessingJob, 'get').resolves(jobConfig);
|
|
108
|
+
const req = getRequest(path, '2193');
|
|
109
|
+
// When ...Then ...
|
|
110
|
+
const res = await Import(req);
|
|
111
|
+
o(res.status).equals(200);
|
|
112
|
+
const body = Buffer.from((_a = res.body) !== null && _a !== void 0 ? _a : '', 'base64').toString();
|
|
113
|
+
o(JSON.parse(body)).deepEquals(jobConfig);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -66,6 +66,15 @@ o.spec('TileSetCache', () => {
|
|
|
66
66
|
throw new Error('null subTileSetB');
|
|
67
67
|
o(subTileSetB.title).equals('parent Tasman rural 2018-19 0.3m');
|
|
68
68
|
});
|
|
69
|
+
o('should not throw if child does not exist', async () => {
|
|
70
|
+
TileSets.add(new TileSetRaster('aerial@head', GoogleTms));
|
|
71
|
+
const parentTileSet = await TileSets.get('aerial@head', GoogleTms);
|
|
72
|
+
if (parentTileSet == null || parentTileSet.type === TileSetType.Vector)
|
|
73
|
+
throw new Error('null parentTileSet');
|
|
74
|
+
parentTileSet.imagery = imgMap;
|
|
75
|
+
const subTileSet = await TileSets.get('aerial@head:fake', GoogleTms);
|
|
76
|
+
o(subTileSet).equals(null);
|
|
77
|
+
});
|
|
69
78
|
});
|
|
70
79
|
o.spec('loadTileSets', () => {
|
|
71
80
|
o('load all', async () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Env } from '@basemaps/shared';
|
|
2
2
|
import o from 'ospec';
|
|
3
|
-
import { convertRelativeUrl } from '../routes/tile.style.json.js';
|
|
3
|
+
import { convertRelativeUrl, convertStyleJson } from '../routes/tile.style.json.js';
|
|
4
4
|
o.spec('TileStyleJson', () => {
|
|
5
5
|
const host = 'https://tiles.test';
|
|
6
6
|
let originalHost;
|
|
@@ -30,4 +30,50 @@ o.spec('TileStyleJson', () => {
|
|
|
30
30
|
o('should not convert full urls', () => {
|
|
31
31
|
o(convertRelativeUrl('https://foo.com/foo?bar=baz', 'abc')).equals('https://foo.com/foo?bar=baz');
|
|
32
32
|
});
|
|
33
|
+
const baseStyleJson = {
|
|
34
|
+
version: 8,
|
|
35
|
+
id: 'style.id',
|
|
36
|
+
name: 'style.name',
|
|
37
|
+
sources: {
|
|
38
|
+
vector: { type: 'vector', url: '/v1/tiles/topographic/EPSG:3857/tile.json' },
|
|
39
|
+
raster: { type: 'raster', tiles: ['/v1/tiles/aerial/EPSG:3857/{z}/{x}/{y}.webp'] },
|
|
40
|
+
},
|
|
41
|
+
layers: [],
|
|
42
|
+
metadata: {},
|
|
43
|
+
glyphs: '/v1/glyphs',
|
|
44
|
+
sprite: '/v1/sprites',
|
|
45
|
+
};
|
|
46
|
+
o('should not destroy the original configuration', () => {
|
|
47
|
+
const apiKey = 'abc123';
|
|
48
|
+
const converted = convertStyleJson(baseStyleJson, apiKey);
|
|
49
|
+
o(converted.sources.vector).deepEquals({
|
|
50
|
+
type: 'vector',
|
|
51
|
+
url: 'https://tiles.test/v1/tiles/topographic/EPSG:3857/tile.json?api=abc123',
|
|
52
|
+
});
|
|
53
|
+
o(converted.sources.raster).deepEquals({
|
|
54
|
+
type: 'raster',
|
|
55
|
+
tiles: ['https://tiles.test/v1/tiles/aerial/EPSG:3857/{z}/{x}/{y}.webp?api=abc123'],
|
|
56
|
+
});
|
|
57
|
+
o(JSON.stringify(baseStyleJson).includes(apiKey)).equals(false);
|
|
58
|
+
const convertedB = convertStyleJson(baseStyleJson, '0x1234');
|
|
59
|
+
o(convertedB.sources.vector).deepEquals({
|
|
60
|
+
type: 'vector',
|
|
61
|
+
url: 'https://tiles.test/v1/tiles/topographic/EPSG:3857/tile.json?api=0x1234',
|
|
62
|
+
});
|
|
63
|
+
o(convertedB.sources.raster).deepEquals({
|
|
64
|
+
type: 'raster',
|
|
65
|
+
tiles: ['https://tiles.test/v1/tiles/aerial/EPSG:3857/{z}/{x}/{y}.webp?api=0x1234'],
|
|
66
|
+
});
|
|
67
|
+
o(JSON.stringify(baseStyleJson).includes('0x1234')).equals(false);
|
|
68
|
+
o(JSON.stringify(baseStyleJson).includes(apiKey)).equals(false);
|
|
69
|
+
o(JSON.stringify(baseStyleJson).includes('?api=')).equals(false);
|
|
70
|
+
});
|
|
71
|
+
o('should convert relative glyphs and sprites', () => {
|
|
72
|
+
const apiKey = '0x9f9f';
|
|
73
|
+
const converted = convertStyleJson(baseStyleJson, apiKey);
|
|
74
|
+
o(converted.sprite).equals('https://tiles.test/v1/sprites');
|
|
75
|
+
o(converted.glyphs).equals('https://tiles.test/v1/glyphs');
|
|
76
|
+
o(JSON.stringify(baseStyleJson).includes(apiKey)).equals(false);
|
|
77
|
+
o(JSON.stringify(baseStyleJson).includes('?api=')).equals(false);
|
|
78
|
+
});
|
|
33
79
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TileMatrixSets } from '@basemaps/geo';
|
|
1
|
+
import { GoogleTms, Nztm2000QuadTms, TileMatrixSets } from '@basemaps/geo';
|
|
2
2
|
import { Config, Env, LogConfig, VNodeParser } from '@basemaps/shared';
|
|
3
3
|
import { round } from '@basemaps/test/build/rounding.js';
|
|
4
4
|
import o from 'ospec';
|
|
@@ -7,7 +7,7 @@ import { handleRequest } from '../index.js';
|
|
|
7
7
|
import { TileEtag } from '../routes/tile.etag.js';
|
|
8
8
|
import { TileSets } from '../tile.set.cache.js';
|
|
9
9
|
import { TileComposer } from '../tile.set.raster.js';
|
|
10
|
-
import { FakeTileSet, mockRequest, Provider } from './xyz.util.js';
|
|
10
|
+
import { FakeTileSet, FakeTileSetVector, mockRequest, Provider } from './xyz.util.js';
|
|
11
11
|
const sandbox = sinon.createSandbox();
|
|
12
12
|
const TileSetNames = ['aerial', 'aerial@head', 'aerial@beta', '01E7PJFR9AMQFJ05X9G7FQ3XMW'];
|
|
13
13
|
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
@@ -42,6 +42,7 @@ o.spec('LambdaXyz', () => {
|
|
|
42
42
|
tileSet.initTiffs = async () => [];
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
+
TileSets.add(new FakeTileSetVector('topographic', GoogleTms));
|
|
45
46
|
Config.Provider.get = async () => Provider;
|
|
46
47
|
});
|
|
47
48
|
o.afterEach(() => {
|
|
@@ -152,44 +153,70 @@ o.spec('LambdaXyz', () => {
|
|
|
152
153
|
});
|
|
153
154
|
});
|
|
154
155
|
o.spec('tileJson', () => {
|
|
155
|
-
o('should
|
|
156
|
-
|
|
157
|
-
const key = 'BBfQpNXA3Q90jlFrLSOZhxbvfOh7OpN1OEE+BylpbHw=';
|
|
158
|
-
const request = mockRequest('/v1/tiles/tile.json', 'get', { 'if-none-match': key, ...apiKeyHeader });
|
|
156
|
+
o('should 404 if invalid url is given', async () => {
|
|
157
|
+
const request = mockRequest('/v1/tiles/tile.json', 'get', apiKeyHeader);
|
|
159
158
|
const res = await handleRequest(request);
|
|
160
|
-
|
|
161
|
-
o(res.header('eTaG')).equals(key); // this line is useful for discovering the new etag
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
o(res.status).equals(304);
|
|
165
|
-
o(rasterMock.calls.length).equals(0);
|
|
166
|
-
o(request.logContext['cache']).deepEquals({ key, match: key, hit: true });
|
|
159
|
+
o(res.status).equals(404);
|
|
167
160
|
});
|
|
168
|
-
o('should
|
|
161
|
+
o('should serve tile json for tile_set', async () => {
|
|
169
162
|
var _a;
|
|
170
|
-
const
|
|
171
|
-
const request = mockRequest('/v1/tiles/tile.json', 'get', { 'if-none-match': key, ...apiKeyHeader });
|
|
163
|
+
const request = mockRequest('/v1/tiles/aerial/NZTM2000Quad/tile.json', 'get', apiKeyHeader);
|
|
172
164
|
const res = await handleRequest(request);
|
|
173
165
|
o(res.status).equals(200);
|
|
174
|
-
o(res.header('
|
|
175
|
-
const
|
|
176
|
-
o(
|
|
177
|
-
|
|
166
|
+
o(res.header('cache-control')).equals('no-store');
|
|
167
|
+
const body = Buffer.from((_a = res.body) !== null && _a !== void 0 ? _a : '', 'base64').toString();
|
|
168
|
+
o(JSON.parse(body)).deepEquals({
|
|
169
|
+
tiles: [`https://tiles.test/v1/tiles/aerial/NZTM2000Quad/{z}/{x}/{y}.webp?api=${apiKey}`],
|
|
170
|
+
vector_layers: [],
|
|
171
|
+
tilejson: '3.0.0',
|
|
172
|
+
});
|
|
178
173
|
});
|
|
179
|
-
o('should serve
|
|
174
|
+
o('should serve vector tiles', async () => {
|
|
180
175
|
var _a;
|
|
181
|
-
const request = mockRequest('/v1/tiles/topographic/
|
|
176
|
+
const request = mockRequest('/v1/tiles/topographic/WebMercatorQuad/tile.json', 'get', apiKeyHeader);
|
|
182
177
|
const res = await handleRequest(request);
|
|
183
178
|
o(res.status).equals(200);
|
|
184
|
-
o(res.header('content-type')).equals('application/json');
|
|
185
|
-
o(res.header('cache-control')).equals('max-age=120');
|
|
186
179
|
const body = Buffer.from((_a = res.body) !== null && _a !== void 0 ? _a : '', 'base64').toString();
|
|
187
180
|
o(JSON.parse(body)).deepEquals({
|
|
188
|
-
tiles: [`https://tiles.test/v1/tiles/topographic/
|
|
189
|
-
|
|
181
|
+
tiles: [`https://tiles.test/v1/tiles/topographic/EPSG:3857/{z}/{x}/{y}.pbf?api=${apiKey}`],
|
|
182
|
+
vector_layers: [],
|
|
183
|
+
tilejson: '3.0.0',
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
o('should serve vector tiles with min/max zoom', async () => {
|
|
187
|
+
var _a;
|
|
188
|
+
const fakeTileSet = new FakeTileSetVector('fake-vector', GoogleTms);
|
|
189
|
+
fakeTileSet.tileSet.maxZoom = 15;
|
|
190
|
+
fakeTileSet.tileSet.minZoom = 3;
|
|
191
|
+
TileSets.add(fakeTileSet);
|
|
192
|
+
const request = mockRequest('/v1/tiles/fake-vector/WebMercatorQuad/tile.json', 'get', apiKeyHeader);
|
|
193
|
+
const res = await handleRequest(request);
|
|
194
|
+
o(res.status).equals(200);
|
|
195
|
+
const body = Buffer.from((_a = res.body) !== null && _a !== void 0 ? _a : '', 'base64').toString();
|
|
196
|
+
o(JSON.parse(body)).deepEquals({
|
|
197
|
+
tiles: [`https://tiles.test/v1/tiles/fake-vector/EPSG:3857/{z}/{x}/{y}.pbf?api=${apiKey}`],
|
|
198
|
+
vector_layers: [],
|
|
190
199
|
maxzoom: 15,
|
|
191
|
-
|
|
192
|
-
tilejson: '
|
|
200
|
+
minzoom: 3,
|
|
201
|
+
tilejson: '3.0.0',
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
o('should serve convert zoom to tile matrix', async () => {
|
|
205
|
+
var _a;
|
|
206
|
+
const fakeTileSet = new FakeTileSetVector('fake-vector', Nztm2000QuadTms);
|
|
207
|
+
fakeTileSet.tileSet.maxZoom = 15;
|
|
208
|
+
fakeTileSet.tileSet.minZoom = 1;
|
|
209
|
+
TileSets.add(fakeTileSet);
|
|
210
|
+
const request = mockRequest('/v1/tiles/fake-vector/NZTM2000Quad/tile.json', 'get', apiKeyHeader);
|
|
211
|
+
const res = await handleRequest(request);
|
|
212
|
+
o(res.status).equals(200);
|
|
213
|
+
const body = Buffer.from((_a = res.body) !== null && _a !== void 0 ? _a : '', 'base64').toString();
|
|
214
|
+
o(JSON.parse(body)).deepEquals({
|
|
215
|
+
tiles: [`https://tiles.test/v1/tiles/fake-vector/NZTM2000Quad/{z}/{x}/{y}.pbf?api=${apiKey}`],
|
|
216
|
+
vector_layers: [],
|
|
217
|
+
maxzoom: 13,
|
|
218
|
+
minzoom: 0,
|
|
219
|
+
tilejson: '3.0.0',
|
|
193
220
|
});
|
|
194
221
|
});
|
|
195
222
|
});
|
|
@@ -2,9 +2,13 @@ import { ConfigProvider } from '@basemaps/config';
|
|
|
2
2
|
import { TileMatrixSet } from '@basemaps/geo';
|
|
3
3
|
import { LambdaHttpRequest } from '@linzjs/lambda';
|
|
4
4
|
import { TileSetRaster } from '../tile.set.raster.js';
|
|
5
|
+
import { TileSetVector } from '../tile.set.vector.js';
|
|
5
6
|
export declare function mockRequest(path: string, method?: string, headers?: Record<string, string>): LambdaHttpRequest;
|
|
6
7
|
export declare class FakeTileSet extends TileSetRaster {
|
|
7
8
|
constructor(name: string, tileMatrix: TileMatrixSet, title?: string, description?: string);
|
|
8
9
|
}
|
|
10
|
+
export declare class FakeTileSetVector extends TileSetVector {
|
|
11
|
+
constructor(name: string, tileMatrix: TileMatrixSet);
|
|
12
|
+
}
|
|
9
13
|
export declare const Provider: ConfigProvider;
|
|
10
14
|
//# sourceMappingURL=xyz.util.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xyz.util.d.ts","sourceRoot":"","sources":["../../src/__test__/xyz.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"xyz.util.d.ts","sourceRoot":"","sources":["../../src/__test__/xyz.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EAAoB,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAQ,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,iBAAiB,CAajH;AAED,qBAAa,WAAY,SAAQ,aAAa;gBAChC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,KAAK,SAAkB,EAAE,WAAW,SAAwB;CAIlH;AAED,qBAAa,iBAAkB,SAAQ,aAAa;gBACtC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa;CAIpD;AAED,eAAO,MAAM,QAAQ,EAAE,cA4BtB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { LambdaAlbRequest } from '@linzjs/lambda';
|
|
2
1
|
import { LogConfig } from '@basemaps/shared';
|
|
2
|
+
import { LambdaAlbRequest } from '@linzjs/lambda';
|
|
3
3
|
import { TileSetRaster } from '../tile.set.raster.js';
|
|
4
|
+
import { TileSetVector } from '../tile.set.vector.js';
|
|
4
5
|
export function mockRequest(path, method = 'get', headers = {}) {
|
|
5
6
|
return new LambdaAlbRequest({
|
|
6
7
|
requestContext: null,
|
|
@@ -17,6 +18,12 @@ export class FakeTileSet extends TileSetRaster {
|
|
|
17
18
|
this.tileSet = { title, description };
|
|
18
19
|
}
|
|
19
20
|
}
|
|
21
|
+
export class FakeTileSetVector extends TileSetVector {
|
|
22
|
+
constructor(name, tileMatrix) {
|
|
23
|
+
super(name, tileMatrix);
|
|
24
|
+
this.tileSet = {};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
20
27
|
export const Provider = {
|
|
21
28
|
createdAt: Date.now(),
|
|
22
29
|
name: 'main',
|
package/build/cli/dump.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Nztm2000Tms } from '@basemaps/geo';
|
|
1
|
+
import { Nztm2000Tms, ImageFormat } from '@basemaps/geo';
|
|
2
2
|
import { LogConfig } from '@basemaps/shared';
|
|
3
|
-
import { ImageFormat } from '@basemaps/tiler';
|
|
4
3
|
import { LambdaAlbRequest } from '@linzjs/lambda';
|
|
5
4
|
import { promises as fs } from 'fs';
|
|
6
5
|
import { tileXyz } from '../routes/tile.xyz.js';
|
|
@@ -9,7 +8,7 @@ import { TileSetLocal } from './tile.set.local.js';
|
|
|
9
8
|
const xyz = { x: 0, y: 0, z: 0 };
|
|
10
9
|
const tileMatrix = Nztm2000Tms;
|
|
11
10
|
const tileSetName = 'aerial';
|
|
12
|
-
const ext = ImageFormat.
|
|
11
|
+
const ext = ImageFormat.Png;
|
|
13
12
|
/** Load a tileset form a file path otherwise default to the hard coded one from AWS */
|
|
14
13
|
async function getTileSet(filePath) {
|
|
15
14
|
if (filePath != null) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface RoleConfig {
|
|
2
|
+
bucket: string;
|
|
3
|
+
accountId: string;
|
|
4
|
+
roleArn: string;
|
|
5
|
+
externalId?: string;
|
|
6
|
+
roleSessionDuration?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class RoleRegister {
|
|
9
|
+
/** Get all imagery source aws roles */
|
|
10
|
+
static _loadRoles(): Promise<RoleConfig[]>;
|
|
11
|
+
static _loadRolesPromise: Promise<RoleConfig[]> | undefined;
|
|
12
|
+
static loadRoles(): Promise<RoleConfig[]>;
|
|
13
|
+
static findRole(path: string): Promise<RoleConfig | undefined>;
|
|
14
|
+
}
|
|
15
|
+
/** Search for the imagery across all of our buckets */
|
|
16
|
+
export declare function findImagery(path: string): Promise<string[]>;
|
|
17
|
+
//# sourceMappingURL=imagery.find.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imagery.find.d.ts","sourceRoot":"","sources":["../../src/import/imagery.find.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAWD,qBAAa,YAAY;IACvB,uCAAuC;WAC1B,UAAU,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAgBhD,MAAM,CAAC,iBAAiB,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,GAAG,SAAS,CAAC;IAC5D,MAAM,CAAC,SAAS,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;WAK5B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;CAIrE;AAED,uDAAuD;AACvD,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOjE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { AwsCredentials } from '@chunkd/source-aws-v2';
|
|
2
|
+
import { fsa } from '@chunkd/fs';
|
|
3
|
+
import { Env } from '@basemaps/shared';
|
|
4
|
+
export class RoleRegister {
|
|
5
|
+
/** Get all imagery source aws roles */
|
|
6
|
+
static async _loadRoles() {
|
|
7
|
+
const configBucket = Env.get(Env.AwsRoleConfigBucket);
|
|
8
|
+
if (configBucket == null)
|
|
9
|
+
return [];
|
|
10
|
+
const configPath = `s3://${configBucket}/config.json`;
|
|
11
|
+
const config = await fsa.readJson(configPath);
|
|
12
|
+
const roles = [];
|
|
13
|
+
for (const role of config.buckets) {
|
|
14
|
+
fsa.register('s3://' + role.bucket, AwsCredentials.fsFromRole(role.roleArn, role.externalId, role.roleSessionDuration));
|
|
15
|
+
roles.push(role);
|
|
16
|
+
}
|
|
17
|
+
return roles;
|
|
18
|
+
}
|
|
19
|
+
static loadRoles() {
|
|
20
|
+
if (RoleRegister._loadRolesPromise == null)
|
|
21
|
+
RoleRegister._loadRolesPromise = this._loadRoles();
|
|
22
|
+
return RoleRegister._loadRolesPromise;
|
|
23
|
+
}
|
|
24
|
+
static async findRole(path) {
|
|
25
|
+
const roles = await this.loadRoles();
|
|
26
|
+
return roles.find((f) => path.startsWith(`s3://${f.bucket}`));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Search for the imagery across all of our buckets */
|
|
30
|
+
export async function findImagery(path) {
|
|
31
|
+
const files = [];
|
|
32
|
+
for await (const key of fsa.list(path)) {
|
|
33
|
+
const searchKey = key.toLowerCase();
|
|
34
|
+
if (searchKey.endsWith('.tif') || searchKey.endsWith('.tiff'))
|
|
35
|
+
files.push(key);
|
|
36
|
+
}
|
|
37
|
+
return files;
|
|
38
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { JobCreationContext } from '@basemaps/cli/build/cog/cog.stac.job';
|
|
2
|
+
import { TileMatrixSet } from '@basemaps/geo';
|
|
3
|
+
import { RoleConfig } from './imagery.find.js';
|
|
4
|
+
export declare function getJobCreationContext(path: string, tileMatrix: TileMatrixSet, role: RoleConfig, files: string[]): Promise<JobCreationContext>;
|
|
5
|
+
//# sourceMappingURL=make.cog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"make.cog.d.ts","sourceRoot":"","sources":["../../src/import/make.cog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,aAAa,EACzB,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,kBAAkB,CAAC,CAkB7B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Env } from '@basemaps/shared';
|
|
2
|
+
export async function getJobCreationContext(path, tileMatrix, role, files) {
|
|
3
|
+
const bucket = Env.get(Env.ImportImageryBucket);
|
|
4
|
+
if (bucket == null)
|
|
5
|
+
throw new Error('Output AWS s3 bucket Not Found.');
|
|
6
|
+
const ctx = {
|
|
7
|
+
override: {
|
|
8
|
+
projection: tileMatrix.projection,
|
|
9
|
+
resampling: {
|
|
10
|
+
warp: 'bilinear',
|
|
11
|
+
overview: 'lanczos',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
outputLocation: { type: 's3', path: `s3://${bucket}` },
|
|
15
|
+
sourceLocation: { type: 's3', path, ...role, files: files },
|
|
16
|
+
batch: true,
|
|
17
|
+
tileMatrix,
|
|
18
|
+
oneCogCovering: false,
|
|
19
|
+
};
|
|
20
|
+
return ctx;
|
|
21
|
+
}
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAM,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAM,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAuB3E,wBAAsB,aAAa,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA2BvF;AAED,eAAO,MAAM,OAAO,2LAA0C,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { createHash } from 'crypto';
|
|
|
8
8
|
import { Imagery } from './routes/imagery.js';
|
|
9
9
|
import { Esri } from './routes/esri/rest.js';
|
|
10
10
|
import { St } from './source.tracer.js';
|
|
11
|
+
import { Import } from './routes/import.js';
|
|
11
12
|
const app = new Router();
|
|
12
13
|
app.get('ping', Ping);
|
|
13
14
|
app.get('health', Health);
|
|
@@ -15,6 +16,7 @@ app.get('version', Version);
|
|
|
15
16
|
app.get('tiles', Tiles);
|
|
16
17
|
app.get('imagery', Imagery);
|
|
17
18
|
app.get('esri', Esri);
|
|
19
|
+
app.get('import', Import);
|
|
18
20
|
let slowTimer = null;
|
|
19
21
|
export async function handleRequest(req) {
|
|
20
22
|
// Reset the request tracing
|
|
@@ -43,6 +43,7 @@ const ExpectedJson = {
|
|
|
43
43
|
],
|
|
44
44
|
},
|
|
45
45
|
properties: {
|
|
46
|
+
title: 'Hastings-district urban 2011-13 0.1m',
|
|
46
47
|
datetime: null,
|
|
47
48
|
start_datetime: '2011-01-01T00:00:00Z',
|
|
48
49
|
end_datetime: '2014-01-01T00:00:00Z',
|
|
@@ -71,6 +72,7 @@ const ExpectedJson = {
|
|
|
71
72
|
],
|
|
72
73
|
},
|
|
73
74
|
properties: {
|
|
75
|
+
title: 'Hastings-district urban 2013-14 0.1m',
|
|
74
76
|
datetime: null,
|
|
75
77
|
start_datetime: '2013-01-01T00:00:00Z',
|
|
76
78
|
end_datetime: '2015-01-01T00:00:00Z',
|
|
@@ -99,6 +101,7 @@ const ExpectedJson = {
|
|
|
99
101
|
],
|
|
100
102
|
},
|
|
101
103
|
properties: {
|
|
104
|
+
title: 'Hastings-district urban 2015-17 0.1m',
|
|
102
105
|
datetime: null,
|
|
103
106
|
start_datetime: '2015-01-01T00:00:00Z',
|
|
104
107
|
end_datetime: '2018-01-01T00:00:00Z',
|
|
@@ -127,6 +130,7 @@ const ExpectedJson = {
|
|
|
127
130
|
],
|
|
128
131
|
},
|
|
129
132
|
properties: {
|
|
133
|
+
title: 'Hastings-district urban 2017-18 0.1m',
|
|
130
134
|
datetime: null,
|
|
131
135
|
start_datetime: '2017-01-01T00:00:00Z',
|
|
132
136
|
end_datetime: '2019-01-01T00:00:00Z',
|
|
@@ -14,6 +14,7 @@ const ctx = new LambdaAlbRequest({
|
|
|
14
14
|
isBase64Encoded: false,
|
|
15
15
|
}, {}, LogConfig.get());
|
|
16
16
|
o.spec('health', async () => {
|
|
17
|
+
o.specTimeout(1000);
|
|
17
18
|
const sandbox = sinon.createSandbox();
|
|
18
19
|
const tileSet = new TileSetRaster('health', GoogleTms);
|
|
19
20
|
o.beforeEach(() => {
|
|
@@ -42,7 +43,6 @@ o.spec('health', async () => {
|
|
|
42
43
|
});
|
|
43
44
|
// Prepare mock test tile response based on the static test tiles
|
|
44
45
|
o('Should give a 200 response', async () => {
|
|
45
|
-
o.timeout(500);
|
|
46
46
|
// Given ... a series good get tile response
|
|
47
47
|
const callback = sandbox.stub(tileSet, 'tile');
|
|
48
48
|
callback.onCall(0).resolves(Response1);
|
|
@@ -54,7 +54,6 @@ o.spec('health', async () => {
|
|
|
54
54
|
o(res.statusDescription).equals('ok');
|
|
55
55
|
});
|
|
56
56
|
o('Should return mis-match tile response', async () => {
|
|
57
|
-
o.timeout(500);
|
|
58
57
|
// Given ... a bad get tile response for second get tile
|
|
59
58
|
const callback = sandbox.stub(tileSet, 'tile');
|
|
60
59
|
callback.onCall(0).resolves(Response1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attribution.d.ts","sourceRoot":"","sources":["../../src/routes/attribution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAe,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EACL,qBAAqB,EAOrB,cAAc,EACd,UAAU,EAEX,MAAM,eAAe,CAAC;AAYvB,OAAO,EAAc,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAInF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AA2DtD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EACvC,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,UAAU,GACjB,qBAAqB,CAqBvB;
|
|
1
|
+
{"version":3,"file":"attribution.d.ts","sourceRoot":"","sources":["../../src/routes/attribution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAe,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EACL,qBAAqB,EAOrB,cAAc,EACd,UAAU,EAEX,MAAM,eAAe,CAAC;AAYvB,OAAO,EAAc,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAInF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AA2DtD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EACvC,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,UAAU,GACjB,qBAAqB,CAqBvB;AAkFD;;GAEG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAkCrF"}
|
|
@@ -133,6 +133,7 @@ async function tileSetAttribution(tileSet) {
|
|
|
133
133
|
coordinates: createCoordinates(bbox, im.files, proj),
|
|
134
134
|
},
|
|
135
135
|
properties: {
|
|
136
|
+
title: titleizeImageryName(im.name),
|
|
136
137
|
datetime: null,
|
|
137
138
|
start_datetime: interval[0][0],
|
|
138
139
|
end_datetime: interval[0][1],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAY,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAY,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAc,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAQnF,UAAU,QAAS,SAAQ,WAAW;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,SAAS,EAAE,QAAQ,EAG/B,CAAC;AAGF,wBAAsB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAYnE;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO/G;AAED;;;;;;GAMG;AACH,wBAAsB,MAAM,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgChF"}
|