/
imagery.ts
61 lines (51 loc) · 2.21 KB
/
imagery.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { fsa } from '@basemaps/shared';
import { HttpHeader, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
import { promisify } from 'util';
import { gzip } from 'zlib';
import { ConfigLoader } from '../util/config.loader.js';
import { isGzip } from '../util/cotar.serve.js';
import { Etag } from '../util/etag.js';
import { NotFound, NotModified } from '../util/response.js';
const gzipP = promisify(gzip);
export function isAllowedFile(f: string): boolean {
if (f == null) return false;
if (f.endsWith('.geojson')) return true;
if (f.endsWith('.json')) return true;
return false;
}
interface ImageryGet {
Params: { imageryId: string; fileName: string };
}
/**
* Get metadata around the imagery such as the source bounding box or the bounding box of the COGS
*
* @example
* - /v1/imagery/:imageryId/source.geojson - Source boudning boxes
* - /v1/imagery/:imageryId/covering.geojson - Output tile bounding boxes
* - /v1/imagery/:imageryId/cutline.geojson - Cutline used ont he imagery set
* - /v1/imagery/:imageryId/collection.json - STAC Collection
* - /v1/imagery/:imageryId/15-32659-21603.json - STAC Item
*/
export async function imageryGet(req: LambdaHttpRequest<ImageryGet>): Promise<LambdaHttpResponse> {
const requestedFile = req.params.fileName;
if (!isAllowedFile(requestedFile)) return NotFound();
const config = await ConfigLoader.load(req);
const imagery = await config.Imagery.get(config.Imagery.id(req.params.imageryId));
if (imagery == null) return NotFound();
const targetPath = new URL(requestedFile, fsa.toUrl(imagery.uri));
try {
const buf = await fsa.read(targetPath);
const cacheKey = Etag.key(buf);
if (Etag.isNotModified(req, cacheKey)) return NotModified();
const response = new LambdaHttpResponse(200, 'ok');
response.header(HttpHeader.ETag, cacheKey);
response.header(HttpHeader.ContentEncoding, 'gzip');
response.header(HttpHeader.CacheControl, 'public, max-age=604800, stale-while-revalidate=86400');
response.buffer(isGzip(buf) ? buf : await gzipP(buf), 'application/json');
req.set('bytes', buf.byteLength);
return response;
} catch (e) {
req.log.warn({ targetPath }, 'ImageryMetadata:Failed');
return NotFound();
}
}