@basemaps/cli 6.8.0 → 6.12.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 +58 -0
- package/basemaps.js +2 -0
- package/build/cli/base.cli.d.ts +1 -1
- package/build/cli/base.cli.d.ts.map +1 -1
- package/build/cli/base.cli.js +22 -33
- package/build/cli/basemaps/action.invalidate.d.ts +1 -1
- package/build/cli/basemaps/action.invalidate.d.ts.map +1 -1
- package/build/cli/basemaps/action.invalidate.js +14 -18
- package/build/cli/basemaps/action.tileset.info.d.ts +1 -1
- package/build/cli/basemaps/action.tileset.info.d.ts.map +1 -1
- package/build/cli/basemaps/action.tileset.info.js +18 -23
- package/build/cli/basemaps/index.d.ts +2 -2
- package/build/cli/basemaps/index.d.ts.map +1 -1
- package/build/cli/basemaps/index.js +7 -16
- package/build/cli/basemaps/tileset.action.d.ts.map +1 -1
- package/build/cli/basemaps/tileset.action.js +4 -8
- package/build/cli/basemaps/tileset.util.d.ts +1 -1
- package/build/cli/basemaps/tileset.util.d.ts.map +1 -1
- package/build/cli/basemaps/tileset.util.js +20 -28
- package/build/cli/cli.table.d.ts.map +1 -1
- package/build/cli/cli.table.js +2 -7
- package/build/cli/cogify/__test__/action.batch.test.js +11 -14
- package/build/cli/cogify/__test__/semver.test.js +50 -53
- package/build/cli/cogify/action.batch.d.ts +2 -2
- package/build/cli/cogify/action.batch.d.ts.map +1 -1
- package/build/cli/cogify/action.batch.js +16 -22
- package/build/cli/cogify/action.cog.d.ts +1 -1
- package/build/cli/cogify/action.cog.d.ts.map +1 -1
- package/build/cli/cogify/action.cog.js +29 -33
- package/build/cli/cogify/action.job.d.ts.map +1 -1
- package/build/cli/cogify/action.job.js +21 -26
- package/build/cli/cogify/index.d.ts +2 -2
- package/build/cli/cogify/index.d.ts.map +1 -1
- package/build/cli/cogify/index.js +9 -13
- package/build/cli/cogify/semver.util.d.ts.map +1 -1
- package/build/cli/cogify/semver.util.js +2 -5
- package/build/cli/folder.js +6 -11
- package/build/cli/tag.action.js +1 -4
- package/build/cli/util.js +11 -16
- package/build/cog/__test__/builder.test.js +31 -35
- package/build/cog/__test__/cog.stac.job.test.js +59 -62
- package/build/cog/__test__/cog.test.js +26 -29
- package/build/cog/__test__/cog.vrt.test.js +90 -90
- package/build/cog/__test__/cutline.test.js +71 -71
- package/build/cog/__test__/source.tiff.testhelper.d.ts +1 -1
- package/build/cog/__test__/source.tiff.testhelper.d.ts.map +1 -1
- package/build/cog/__test__/source.tiff.testhelper.js +6 -9
- package/build/cog/builder.d.ts +3 -3
- package/build/cog/builder.d.ts.map +1 -1
- package/build/cog/builder.js +43 -48
- package/build/cog/cog.d.ts +2 -2
- package/build/cog/cog.d.ts.map +1 -1
- package/build/cog/cog.js +15 -19
- package/build/cog/cog.stac.job.d.ts +10 -10
- package/build/cog/cog.stac.job.d.ts.map +1 -1
- package/build/cog/cog.stac.job.js +48 -52
- package/build/cog/cog.vrt.d.ts +2 -2
- package/build/cog/cog.vrt.d.ts.map +1 -1
- package/build/cog/cog.vrt.js +16 -18
- package/build/cog/constants.js +2 -5
- package/build/cog/cutline.d.ts +21 -21
- package/build/cog/cutline.d.ts.map +1 -1
- package/build/cog/cutline.js +53 -58
- package/build/cog/job.factory.d.ts +2 -2
- package/build/cog/job.factory.d.ts.map +1 -1
- package/build/cog/job.factory.js +25 -41
- package/build/cog/stac.d.ts +1 -1
- package/build/cog/stac.d.ts.map +1 -1
- package/build/cog/stac.js +2 -5
- package/build/cog/types.d.ts +1 -1
- package/build/cog/types.d.ts.map +1 -1
- package/build/cog/types.js +1 -2
- package/build/gdal/__test__/gdal.progress.test.js +11 -14
- package/build/gdal/__test__/gdal.test.js +35 -38
- package/build/gdal/gdal.cog.d.ts +2 -2
- package/build/gdal/gdal.cog.d.ts.map +1 -1
- package/build/gdal/gdal.cog.js +14 -18
- package/build/gdal/gdal.command.d.ts +1 -1
- package/build/gdal/gdal.command.d.ts.map +1 -1
- package/build/gdal/gdal.command.js +4 -9
- package/build/gdal/gdal.config.d.ts.map +1 -1
- package/build/gdal/gdal.config.js +4 -7
- package/build/gdal/gdal.d.ts +1 -1
- package/build/gdal/gdal.d.ts.map +1 -1
- package/build/gdal/gdal.docker.d.ts +1 -1
- package/build/gdal/gdal.docker.d.ts.map +1 -1
- package/build/gdal/gdal.docker.js +8 -13
- package/build/gdal/gdal.js +7 -11
- package/build/gdal/gdal.local.d.ts +1 -1
- package/build/gdal/gdal.local.d.ts.map +1 -1
- package/build/gdal/gdal.local.js +2 -6
- package/build/gdal/gdal.progress.d.ts.map +1 -1
- package/build/gdal/gdal.progress.js +2 -6
- package/build/index.d.ts +5 -5
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4 -11
- package/{cogify → cogify.js} +1 -1
- package/package.json +15 -13
- package/basemaps +0 -2
package/build/cog/cog.vrt.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const gdal_1 = require("../gdal/gdal");
|
|
7
|
-
const cog_1 = require("./cog");
|
|
1
|
+
import { Epsg } from '@basemaps/geo';
|
|
2
|
+
import { fsa, isConfigS3Role, s3ToVsis3 } from '@basemaps/shared';
|
|
3
|
+
import { Gdal } from '../gdal/gdal.js';
|
|
4
|
+
import { onProgress } from './cog.js';
|
|
5
|
+
import { AwsCredentials } from '@chunkd/fs';
|
|
8
6
|
/**
|
|
9
7
|
* Build the VRT for the needed source imagery
|
|
10
8
|
*/
|
|
@@ -27,7 +25,7 @@ async function buildWarpVrt(job, sourceVrtPath, gdalCommand, cogVrtPath, tr, log
|
|
|
27
25
|
'-wo',
|
|
28
26
|
'NUM_THREADS=ALL_CPUS',
|
|
29
27
|
'-s_srs',
|
|
30
|
-
|
|
28
|
+
Epsg.get(job.source.epsg).toEpsgString(),
|
|
31
29
|
'-t_srs',
|
|
32
30
|
job.tileMatrix.projection.toEpsgString(),
|
|
33
31
|
'-tr',
|
|
@@ -49,7 +47,7 @@ async function buildWarpVrt(job, sourceVrtPath, gdalCommand, cogVrtPath, tr, log
|
|
|
49
47
|
logger.debug({ warpOpts: warpOpts.join(' ') }, 'gdalwarp');
|
|
50
48
|
await gdalCommand.run('gdalwarp', [...warpOpts, cogVrtPath, sourceVrtPath], logger);
|
|
51
49
|
}
|
|
52
|
-
|
|
50
|
+
export const CogVrt = {
|
|
53
51
|
/**
|
|
54
52
|
* Build a vrt file for a COG `name` that transforms the source imagery with a cutline
|
|
55
53
|
*
|
|
@@ -63,16 +61,16 @@ exports.CogVrt = {
|
|
|
63
61
|
*/
|
|
64
62
|
async buildVrt(tmpFolder, job, cutline, name, logger) {
|
|
65
63
|
logger.info({ name }, 'buildCogVrt');
|
|
66
|
-
const sourceFiles = cutline.filterSourcesForName(name, job).map(
|
|
64
|
+
const sourceFiles = cutline.filterSourcesForName(name, job).map(s3ToVsis3);
|
|
67
65
|
if (sourceFiles.length === 0) {
|
|
68
66
|
return null;
|
|
69
67
|
}
|
|
70
|
-
const sourceVrtPath =
|
|
71
|
-
const cogVrtPath =
|
|
68
|
+
const sourceVrtPath = fsa.join(tmpFolder, `source.vrt`);
|
|
69
|
+
const cogVrtPath = fsa.join(tmpFolder, `cog.vrt`);
|
|
72
70
|
let cutlineTarget = '';
|
|
73
71
|
if (cutline.clipPoly.length !== 0) {
|
|
74
|
-
cutlineTarget =
|
|
75
|
-
await
|
|
72
|
+
cutlineTarget = fsa.join(tmpFolder, 'cutline.geojson');
|
|
73
|
+
await fsa.writeJson(cutlineTarget, cutline.toGeoJson());
|
|
76
74
|
}
|
|
77
75
|
else {
|
|
78
76
|
job.output.cutline = undefined;
|
|
@@ -82,11 +80,11 @@ exports.CogVrt = {
|
|
|
82
80
|
outputTotal: sourceFiles.length,
|
|
83
81
|
cutlinePolygons: cutline.clipPoly.length,
|
|
84
82
|
}, 'Tiff count');
|
|
85
|
-
const gdalCommand =
|
|
83
|
+
const gdalCommand = Gdal.create();
|
|
86
84
|
const sourceLocation = job.source.location;
|
|
87
85
|
// If required assume role
|
|
88
|
-
if (
|
|
89
|
-
const credentials =
|
|
86
|
+
if (isConfigS3Role(sourceLocation)) {
|
|
87
|
+
const credentials = AwsCredentials.role(sourceLocation.roleArn, sourceLocation.externalId);
|
|
90
88
|
gdalCommand.setCredentials(credentials);
|
|
91
89
|
}
|
|
92
90
|
if (gdalCommand.mount != null) {
|
|
@@ -95,7 +93,7 @@ exports.CogVrt = {
|
|
|
95
93
|
gdalCommand.mount(file.name);
|
|
96
94
|
}
|
|
97
95
|
const tr = job.output.gsd.toString();
|
|
98
|
-
|
|
96
|
+
onProgress(gdalCommand, { target: `vrt.${job.tileMatrix.projection.code}` }, logger);
|
|
99
97
|
await buildPlainVrt(job, sourceFiles, sourceVrtPath, gdalCommand, logger);
|
|
100
98
|
await buildWarpVrt(job, cogVrtPath, gdalCommand, sourceVrtPath, tr, logger, cutlineTarget);
|
|
101
99
|
return cogVrtPath;
|
package/build/cog/constants.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CoveringFraction = exports.MaxImagePixelWidth = void 0;
|
|
4
1
|
/** Maximum desired image size */
|
|
5
|
-
|
|
2
|
+
export const MaxImagePixelWidth = 256000;
|
|
6
3
|
/** When a tile has at least this much covering merge it up to parent */
|
|
7
|
-
|
|
4
|
+
export const CoveringFraction = 0.25;
|
package/build/cog/cutline.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Bounds, NamedBounds, TileMatrixSet } from '@basemaps/geo';
|
|
2
2
|
import { MultiPolygon } from '@linzjs/geojson';
|
|
3
3
|
import { FeatureCollection } from 'geojson';
|
|
4
|
-
import { CogJob, FeatureCollectionWithCrs, SourceMetadata } from './types';
|
|
4
|
+
import { CogJob, FeatureCollectionWithCrs, SourceMetadata } from './types.js';
|
|
5
5
|
export declare function polyContainsBounds(poly: MultiPolygon, bounds: Bounds): boolean;
|
|
6
6
|
export declare class Cutline {
|
|
7
7
|
/** The polygon to clip source imagery to */
|
|
@@ -14,16 +14,16 @@ export declare class Cutline {
|
|
|
14
14
|
/** the polygon outlining a area covered by the source imagery and clip polygon */
|
|
15
15
|
srcPoly: MultiPolygon;
|
|
16
16
|
/**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
* Create a Cutline instance from a `GeoJSON FeatureCollection`.
|
|
18
|
+
|
|
19
|
+
* @param tileMatrix the tileMatrix the COGs will be created in.
|
|
20
|
+
|
|
21
|
+
* @param clipPoly the optional cutline. The source imagery outline used by default. This
|
|
22
|
+
* `FeatureCollection` is converted to one `MultiPolygon` with any holes removed and the
|
|
23
|
+
* coordinates transposed from `Wgs84` to the target projection (unless already in target projection).
|
|
24
|
+
|
|
25
|
+
* @param blend How much blending to consider when working out boundaries.
|
|
26
|
+
*/
|
|
27
27
|
constructor(tileMatrix: TileMatrixSet, clipPoly?: FeatureCollection, blend?: number, oneCogCovering?: boolean);
|
|
28
28
|
/**
|
|
29
29
|
* Load a geojson cutline from the file-system.
|
|
@@ -60,18 +60,18 @@ export declare class Cutline {
|
|
|
60
60
|
*/
|
|
61
61
|
private makeTiles;
|
|
62
62
|
/**
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
* Find the polygon covering of source imagery and a (optional) clip cutline. Truncates the
|
|
64
|
+
* cutline to match.
|
|
65
|
+
|
|
66
|
+
* @param sourceMetadata
|
|
67
|
+
*/
|
|
68
68
|
private findCovering;
|
|
69
69
|
/**
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
* Pad the bounds to take in to consideration blending and 100 pixels of adjacent image data
|
|
71
|
+
|
|
72
|
+
* @param bounds
|
|
73
|
+
* @param resZoom the imagery resolution target zoom level
|
|
74
|
+
*/
|
|
75
75
|
private padBounds;
|
|
76
76
|
}
|
|
77
77
|
//# sourceMappingURL=cutline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cutline.d.ts","sourceRoot":"","sources":["../../src/cog/cutline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAQ,WAAW,EAAQ,aAAa,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,
|
|
1
|
+
{"version":3,"file":"cutline.d.ts","sourceRoot":"","sources":["../../src/cog/cutline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAQ,WAAW,EAAQ,aAAa,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,EAIL,YAAY,EAIb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAgB9E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAK9E;AAqBD,qBAAa,OAAO;IAClB,4CAA4C;IAC5C,QAAQ,EAAE,YAAY,CAAC;IACvB,UAAU,EAAE,aAAa,CAAC;IAC1B,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,cAAc,EAAE,OAAO,CAAC;IACxB,kFAAkF;IAClF,OAAO,EAAE,YAAY,CAAM;IAE3B;;;;;;;;;;SAUK;gBACO,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,iBAAiB,EAAE,KAAK,SAAI,EAAE,cAAc,UAAQ;IAsBtG;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAI5D;;;;;;;OAOG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;IAqCzD;;;OAGG;IACH,gBAAgB,CAAC,cAAc,EAAE,cAAc,GAAG,WAAW,EAAE;IA0C/D;;OAEG;IACH,SAAS,CAAC,QAAQ,eAAgB,GAAG,wBAAwB;IAS7D;;;;;;;;OAQG;IACH,OAAO,CAAC,SAAS;IA0CjB;;;;;SAKK;IACL,OAAO,CAAC,YAAY;IAqCpB;;;;;SAKK;IACL,OAAO,CAAC,SAAS;CAQlB"}
|
package/build/cog/cutline.js
CHANGED
|
@@ -1,28 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const shared_1 = require("@basemaps/shared");
|
|
6
|
-
const geojson_1 = require("@linzjs/geojson");
|
|
7
|
-
const constants_1 = require("./constants");
|
|
1
|
+
import { Bounds, Epsg, TileMatrixSet } from '@basemaps/geo';
|
|
2
|
+
import { compareName, fsa, Projection } from '@basemaps/shared';
|
|
3
|
+
import { clipMultipolygon, featuresToMultiPolygon, intersection, toFeatureCollection, toFeatureMultiPolygon, union, } from '@linzjs/geojson';
|
|
4
|
+
import { CoveringFraction, MaxImagePixelWidth } from './constants.js';
|
|
8
5
|
/** Padding to always apply to image boundies */
|
|
9
6
|
const PixelPadding = 100;
|
|
10
7
|
/** fraction to scale source imagery to avoid degenerate edges */
|
|
11
8
|
const SourceSmoothScale = 1 + 1e-8;
|
|
12
9
|
function findGeoJsonProjection(geojson) {
|
|
13
10
|
var _a, _b, _c, _d;
|
|
14
|
-
return (_d =
|
|
11
|
+
return (_d = Epsg.parse((_c = (_b = (_a = geojson === null || geojson === void 0 ? void 0 : geojson.crs) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : '')) !== null && _d !== void 0 ? _d : Epsg.Wgs84;
|
|
15
12
|
}
|
|
16
13
|
function namedBounds(tms, tile) {
|
|
17
|
-
return { name:
|
|
14
|
+
return { name: TileMatrixSet.tileToName(tile), ...tms.tileToSourceBounds(tile).toJson() };
|
|
18
15
|
}
|
|
19
|
-
function polyContainsBounds(poly, bounds) {
|
|
20
|
-
const clipped =
|
|
16
|
+
export function polyContainsBounds(poly, bounds) {
|
|
17
|
+
const clipped = clipMultipolygon(poly, bounds.toBbox());
|
|
21
18
|
if (clipped.length !== 1 || clipped[0].length !== 1 || clipped[0][0].length !== 5)
|
|
22
19
|
return false;
|
|
23
|
-
return
|
|
20
|
+
return Bounds.fromMultiPolygon(clipped).containsBounds(bounds);
|
|
24
21
|
}
|
|
25
|
-
exports.polyContainsBounds = polyContainsBounds;
|
|
26
22
|
/**
|
|
27
23
|
* Filter out duplicate tiles
|
|
28
24
|
*/
|
|
@@ -41,18 +37,18 @@ function addNonDupes(list, addList) {
|
|
|
41
37
|
}
|
|
42
38
|
}
|
|
43
39
|
}
|
|
44
|
-
class Cutline {
|
|
40
|
+
export class Cutline {
|
|
45
41
|
/**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
42
|
+
* Create a Cutline instance from a `GeoJSON FeatureCollection`.
|
|
43
|
+
|
|
44
|
+
* @param tileMatrix the tileMatrix the COGs will be created in.
|
|
45
|
+
|
|
46
|
+
* @param clipPoly the optional cutline. The source imagery outline used by default. This
|
|
47
|
+
* `FeatureCollection` is converted to one `MultiPolygon` with any holes removed and the
|
|
48
|
+
* coordinates transposed from `Wgs84` to the target projection (unless already in target projection).
|
|
49
|
+
|
|
50
|
+
* @param blend How much blending to consider when working out boundaries.
|
|
51
|
+
*/
|
|
56
52
|
constructor(tileMatrix, clipPoly, blend = 0, oneCogCovering = false) {
|
|
57
53
|
/** the polygon outlining a area covered by the source imagery and clip polygon */
|
|
58
54
|
this.srcPoly = [];
|
|
@@ -65,12 +61,12 @@ class Cutline {
|
|
|
65
61
|
}
|
|
66
62
|
this.tileMatrix = tileMatrix;
|
|
67
63
|
const proj = findGeoJsonProjection(clipPoly);
|
|
68
|
-
const tmsProj =
|
|
64
|
+
const tmsProj = Projection.get(tileMatrix);
|
|
69
65
|
const needProj = proj !== tmsProj.epsg;
|
|
70
|
-
if (needProj && proj !==
|
|
66
|
+
if (needProj && proj !== Epsg.Wgs84)
|
|
71
67
|
throw new Error('Invalid geojson; CRS may not be set for cutline!');
|
|
72
68
|
const convert = needProj ? tmsProj.fromWgs84 : undefined;
|
|
73
|
-
this.clipPoly =
|
|
69
|
+
this.clipPoly = featuresToMultiPolygon(clipPoly.features, true, convert).coordinates;
|
|
74
70
|
}
|
|
75
71
|
/**
|
|
76
72
|
* Load a geojson cutline from the file-system.
|
|
@@ -78,7 +74,7 @@ class Cutline {
|
|
|
78
74
|
* @param path the path of the cutline to load. Can be `s3://` or local file path.
|
|
79
75
|
*/
|
|
80
76
|
static loadCutline(path) {
|
|
81
|
-
return
|
|
77
|
+
return fsa.readJson(path);
|
|
82
78
|
}
|
|
83
79
|
/**
|
|
84
80
|
* For the given tile `name`, filter `job.source.files` and cutline polygons that are within bounds plus
|
|
@@ -91,20 +87,20 @@ class Cutline {
|
|
|
91
87
|
filterSourcesForName(name, job) {
|
|
92
88
|
if (this.oneCogCovering)
|
|
93
89
|
return job.source.files.map(({ name }) => name);
|
|
94
|
-
const tile =
|
|
95
|
-
const sourceCode =
|
|
96
|
-
const targetCode =
|
|
90
|
+
const tile = TileMatrixSet.nameToTile(name);
|
|
91
|
+
const sourceCode = Projection.get(job.source.epsg);
|
|
92
|
+
const targetCode = Projection.get(this.tileMatrix);
|
|
97
93
|
const tileBounds = this.tileMatrix.tileToSourceBounds(tile);
|
|
98
94
|
const tilePadded = this.padBounds(tileBounds, job.targetZoom);
|
|
99
95
|
let tileBoundsInSrcProj = tilePadded;
|
|
100
96
|
if (sourceCode !== targetCode) {
|
|
101
97
|
// convert the padded quadKey to source projection ensuring fully enclosed
|
|
102
98
|
const poly = targetCode.projectMultipolygon([tileBoundsInSrcProj.toPolygon()], sourceCode);
|
|
103
|
-
tileBoundsInSrcProj =
|
|
99
|
+
tileBoundsInSrcProj = Bounds.fromMultiPolygon(poly);
|
|
104
100
|
}
|
|
105
101
|
const paddedBbox = tilePadded.toBbox();
|
|
106
102
|
if (this.clipPoly.length > 0) {
|
|
107
|
-
const poly =
|
|
103
|
+
const poly = clipMultipolygon(this.clipPoly, paddedBbox);
|
|
108
104
|
if (poly.length === 0) {
|
|
109
105
|
// this tile is not needed
|
|
110
106
|
this.clipPoly = [];
|
|
@@ -120,7 +116,7 @@ class Cutline {
|
|
|
120
116
|
}
|
|
121
117
|
}
|
|
122
118
|
return job.source.files
|
|
123
|
-
.filter((image) => tileBoundsInSrcProj.intersects(
|
|
119
|
+
.filter((image) => tileBoundsInSrcProj.intersects(Bounds.fromJson(image)))
|
|
124
120
|
.map(({ name }) => name);
|
|
125
121
|
}
|
|
126
122
|
/**
|
|
@@ -137,14 +133,14 @@ class Cutline {
|
|
|
137
133
|
// Look for the biggest tile size we are allowed to create.
|
|
138
134
|
let minZ = resZoom - 1;
|
|
139
135
|
while (minZ > 0 &&
|
|
140
|
-
|
|
136
|
+
Projection.getImagePixelWidth(this.tileMatrix, { x: 0, y: 0, z: minZ }, resZoom) < MaxImagePixelWidth) {
|
|
141
137
|
--minZ;
|
|
142
138
|
}
|
|
143
139
|
minZ = Math.max(1, minZ + 1);
|
|
144
140
|
let tiles = [];
|
|
145
141
|
for (const tile of this.tileMatrix.topLevelTiles()) {
|
|
146
142
|
// Don't make COGs with a tile.z < minZ.
|
|
147
|
-
tiles = tiles.concat(this.makeTiles(tile, this.srcPoly, minZ,
|
|
143
|
+
tiles = tiles.concat(this.makeTiles(tile, this.srcPoly, minZ, CoveringFraction).tiles);
|
|
148
144
|
}
|
|
149
145
|
if (tiles.length === 0) {
|
|
150
146
|
throw new Error('Source imagery does not overlap with project extent');
|
|
@@ -154,18 +150,18 @@ class Cutline {
|
|
|
154
150
|
return covering
|
|
155
151
|
.filter((curr) => {
|
|
156
152
|
for (const other of covering) {
|
|
157
|
-
if (other !== curr &&
|
|
153
|
+
if (other !== curr && Bounds.contains(other, curr))
|
|
158
154
|
return false;
|
|
159
155
|
}
|
|
160
156
|
return true;
|
|
161
157
|
})
|
|
162
|
-
.sort(
|
|
158
|
+
.sort(compareName);
|
|
163
159
|
}
|
|
164
160
|
/**
|
|
165
161
|
* Convert JobCutline to geojson FeatureCollection
|
|
166
162
|
*/
|
|
167
163
|
toGeoJson(clipPoly = this.clipPoly) {
|
|
168
|
-
const feature =
|
|
164
|
+
const feature = toFeatureCollection([toFeatureMultiPolygon(clipPoly)]);
|
|
169
165
|
feature.crs = {
|
|
170
166
|
type: 'name',
|
|
171
167
|
properties: { name: this.tileMatrix.projection.toUrn() },
|
|
@@ -183,7 +179,7 @@ class Cutline {
|
|
|
183
179
|
*/
|
|
184
180
|
makeTiles(tile, srcArea, minZ, coveringFraction) {
|
|
185
181
|
const clipBounds = this.tileMatrix.tileToSourceBounds(tile).toBbox();
|
|
186
|
-
srcArea =
|
|
182
|
+
srcArea = clipMultipolygon(srcArea, clipBounds);
|
|
187
183
|
if (srcArea.length === 0) {
|
|
188
184
|
return { tiles: [], fractionCovered: 0 };
|
|
189
185
|
}
|
|
@@ -210,32 +206,32 @@ class Cutline {
|
|
|
210
206
|
return ans;
|
|
211
207
|
}
|
|
212
208
|
/**
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
209
|
+
* Find the polygon covering of source imagery and a (optional) clip cutline. Truncates the
|
|
210
|
+
* cutline to match.
|
|
211
|
+
|
|
212
|
+
* @param sourceMetadata
|
|
213
|
+
*/
|
|
218
214
|
findCovering(sourceMetadata) {
|
|
219
215
|
var _a;
|
|
220
216
|
let srcPoly = [];
|
|
221
217
|
const { resZoom } = sourceMetadata;
|
|
222
218
|
// merge imagery bounds
|
|
223
219
|
for (const image of sourceMetadata.bounds) {
|
|
224
|
-
const poly = [
|
|
225
|
-
srcPoly =
|
|
220
|
+
const poly = [Bounds.fromJson(image).scaleFromCenter(SourceSmoothScale).toPolygon()];
|
|
221
|
+
srcPoly = union(srcPoly, poly);
|
|
226
222
|
}
|
|
227
223
|
// Convert polygon to target projection
|
|
228
|
-
const sourceProj =
|
|
229
|
-
const targetProj =
|
|
224
|
+
const sourceProj = Projection.get(sourceMetadata.projection);
|
|
225
|
+
const targetProj = Projection.get(this.tileMatrix);
|
|
230
226
|
if (sourceProj !== targetProj) {
|
|
231
227
|
srcPoly = sourceProj.projectMultipolygon(srcPoly, targetProj);
|
|
232
228
|
}
|
|
233
229
|
this.srcPoly = srcPoly;
|
|
234
230
|
if (this.clipPoly.length === 0)
|
|
235
231
|
return;
|
|
236
|
-
const srcBounds =
|
|
232
|
+
const srcBounds = Bounds.fromMultiPolygon(srcPoly);
|
|
237
233
|
const boundsPadded = this.padBounds(srcBounds, resZoom).toBbox();
|
|
238
|
-
const poly =
|
|
234
|
+
const poly = clipMultipolygon(this.clipPoly, boundsPadded);
|
|
239
235
|
if (poly.length === 0) {
|
|
240
236
|
throw new Error('No intersection between source imagery and cutline');
|
|
241
237
|
}
|
|
@@ -246,15 +242,15 @@ class Cutline {
|
|
|
246
242
|
else {
|
|
247
243
|
// set the cutline polygons to just the area of interest (minus degenerate edges)
|
|
248
244
|
this.clipPoly = poly;
|
|
249
|
-
this.srcPoly = (_a =
|
|
245
|
+
this.srcPoly = (_a = intersection(srcPoly, this.clipPoly)) !== null && _a !== void 0 ? _a : [];
|
|
250
246
|
}
|
|
251
247
|
}
|
|
252
248
|
/**
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
249
|
+
* Pad the bounds to take in to consideration blending and 100 pixels of adjacent image data
|
|
250
|
+
|
|
251
|
+
* @param bounds
|
|
252
|
+
* @param resZoom the imagery resolution target zoom level
|
|
253
|
+
*/
|
|
258
254
|
padBounds(bounds, resZoom) {
|
|
259
255
|
const px = this.tileMatrix.pixelScale(resZoom);
|
|
260
256
|
// Ensure cutline blend does not interferre with non-costal edges
|
|
@@ -263,4 +259,3 @@ class Cutline {
|
|
|
263
259
|
return bounds.scaleFromCenter(widthScale, heightScale);
|
|
264
260
|
}
|
|
265
261
|
}
|
|
266
|
-
exports.Cutline = Cutline;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { JobCreationContext } from './cog.stac.job';
|
|
2
|
-
import { CogJob } from './types';
|
|
1
|
+
import { JobCreationContext } from './cog.stac.job.js';
|
|
2
|
+
import { CogJob } from './types.js';
|
|
3
3
|
export declare const MaxConcurrencyDefault = 50;
|
|
4
4
|
export declare const CogJobFactory: {
|
|
5
5
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"job.factory.d.ts","sourceRoot":"","sources":["../../src/cog/job.factory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"job.factory.d.ts","sourceRoot":"","sources":["../../src/cog/job.factory.ts"],"names":[],"mappings":"AAOA,OAAO,EAAc,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAOxC,eAAO,MAAM,aAAa;IACxB;;OAEG;gBACe,kBAAkB,GAAG,QAAQ,MAAM,CAAC;CA6FvD,CAAC"}
|
package/build/cog/job.factory.js
CHANGED
|
@@ -1,61 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const __1 = require("..");
|
|
12
|
-
const action_batch_1 = require("../cli/cogify/action.batch");
|
|
13
|
-
const gdal_1 = require("../gdal/gdal");
|
|
14
|
-
const cog_stac_job_1 = require("./cog.stac.job");
|
|
15
|
-
const cutline_1 = require("./cutline");
|
|
16
|
-
exports.MaxConcurrencyDefault = 50;
|
|
1
|
+
import { Bounds } from '@basemaps/geo';
|
|
2
|
+
import { fsa, isConfigS3Role, isFileConfigPath, LogConfig } from '@basemaps/shared';
|
|
3
|
+
import { basename } from 'path';
|
|
4
|
+
import * as ulid from 'ulid';
|
|
5
|
+
import { CogBuilder } from '../index.js';
|
|
6
|
+
import { ActionBatchJob } from '../cli/cogify/action.batch.js';
|
|
7
|
+
import { Gdal } from '../gdal/gdal.js';
|
|
8
|
+
import { CogStacJob } from './cog.stac.job.js';
|
|
9
|
+
import { Cutline } from './cutline.js';
|
|
10
|
+
export const MaxConcurrencyDefault = 50;
|
|
17
11
|
function filterTiff(a) {
|
|
18
12
|
const lowerA = a.toLowerCase();
|
|
19
13
|
return lowerA.endsWith('.tiff') || lowerA.endsWith('.tif');
|
|
20
14
|
}
|
|
21
|
-
|
|
15
|
+
export const CogJobFactory = {
|
|
22
16
|
/**
|
|
23
17
|
* Create a COG Job and potentially submit it to AWS Batch for processing
|
|
24
18
|
*/
|
|
25
19
|
async create(ctx) {
|
|
26
20
|
var _a, _b, _c, _d, _e, _f;
|
|
27
21
|
const id = (_b = (_a = ctx.override) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : ulid.ulid();
|
|
28
|
-
const imageryName =
|
|
29
|
-
const logger =
|
|
30
|
-
const gdalVersion = await
|
|
22
|
+
const imageryName = basename(ctx.sourceLocation.path).replace(/\./g, '-'); // batch does not allow '.' in names
|
|
23
|
+
const logger = LogConfig.get().child({ id, imageryName });
|
|
24
|
+
const gdalVersion = await Gdal.version(logger);
|
|
31
25
|
logger.info({ version: gdalVersion }, 'GdalVersion');
|
|
32
26
|
const { sourceLocation } = ctx;
|
|
33
|
-
logger.info({ source: ctx.sourceLocation.path, sourceRole:
|
|
34
|
-
|
|
35
|
-
const tiffList =
|
|
27
|
+
logger.info({ source: ctx.sourceLocation.path, sourceRole: isConfigS3Role(sourceLocation) && sourceLocation.roleArn }, 'ListTiffs');
|
|
28
|
+
fsa.configure(sourceLocation);
|
|
29
|
+
const tiffList = isFileConfigPath(sourceLocation)
|
|
36
30
|
? sourceLocation.files
|
|
37
|
-
: (await
|
|
38
|
-
const tiffSource = tiffList.map((path) =>
|
|
39
|
-
|
|
40
|
-
if (shared_1.fsa.isS3Processor(fs)) {
|
|
41
|
-
const { bucket, key } = fs.parse(path);
|
|
42
|
-
if (key == null)
|
|
43
|
-
throw new Error(`Failed to read tiff from uri: "${path}"`);
|
|
44
|
-
// Use the same s3 credentials to access the files that were used to list them
|
|
45
|
-
return new source_aws_1.SourceAwsS3(bucket, key, fs.s3);
|
|
46
|
-
}
|
|
47
|
-
return new source_file_1.SourceFile(path);
|
|
48
|
-
});
|
|
49
|
-
const maxConcurrency = (_d = (_c = ctx.override) === null || _c === void 0 ? void 0 : _c.concurrency) !== null && _d !== void 0 ? _d : exports.MaxConcurrencyDefault;
|
|
31
|
+
: (await fsa.toArray(fsa.list(sourceLocation.path))).filter(filterTiff);
|
|
32
|
+
const tiffSource = tiffList.map((path) => fsa.source(path));
|
|
33
|
+
const maxConcurrency = (_d = (_c = ctx.override) === null || _c === void 0 ? void 0 : _c.concurrency) !== null && _d !== void 0 ? _d : MaxConcurrencyDefault;
|
|
50
34
|
logger.info({ source: sourceLocation.path, tiffCount: tiffList.length }, 'LoadingTiffs');
|
|
51
|
-
const cutline = new
|
|
52
|
-
const builder = new
|
|
35
|
+
const cutline = new Cutline(ctx.tileMatrix, ctx.cutline && (await Cutline.loadCutline(ctx.cutline.href)), (_e = ctx.cutline) === null || _e === void 0 ? void 0 : _e.blend, ctx.oneCogCovering);
|
|
36
|
+
const builder = new CogBuilder(ctx.tileMatrix, maxConcurrency, logger, (_f = ctx.override) === null || _f === void 0 ? void 0 : _f.projection);
|
|
53
37
|
const metadata = await builder.build(tiffSource, cutline);
|
|
54
38
|
if (cutline.clipPoly.length === 0) {
|
|
55
39
|
// no cutline needed for this imagery set
|
|
56
40
|
ctx.cutline = undefined;
|
|
57
41
|
}
|
|
58
|
-
const files = metadata.files.sort(
|
|
42
|
+
const files = metadata.files.sort(Bounds.compareArea);
|
|
59
43
|
if (files.length > 0) {
|
|
60
44
|
const bigArea = files[files.length - 1];
|
|
61
45
|
const smallArea = files[0];
|
|
@@ -84,7 +68,7 @@ exports.CogJobFactory = {
|
|
|
84
68
|
logger.info({ bandCount: metadata.bands }, 'Vrt:DetectedAlpha, Disabling -addalpha');
|
|
85
69
|
addAlpha = false;
|
|
86
70
|
}
|
|
87
|
-
const job = await
|
|
71
|
+
const job = await CogStacJob.create({
|
|
88
72
|
id,
|
|
89
73
|
imageryName,
|
|
90
74
|
metadata,
|
|
@@ -93,7 +77,7 @@ exports.CogJobFactory = {
|
|
|
93
77
|
cutlinePoly: cutline.clipPoly,
|
|
94
78
|
});
|
|
95
79
|
if (ctx.batch)
|
|
96
|
-
await
|
|
80
|
+
await ActionBatchJob.batchJob(job, true, undefined, logger);
|
|
97
81
|
logger.info({ tileMatrix: ctx.tileMatrix.identifier, job: job.getJobPath() }, 'Done');
|
|
98
82
|
return job;
|
|
99
83
|
},
|
package/build/cog/stac.d.ts
CHANGED
package/build/cog/stac.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stac.d.ts","sourceRoot":"","sources":["../../src/cog/stac.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"stac.d.ts","sourceRoot":"","sources":["../../src/cog/stac.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,YAAY;IAC3B,sBAAsB;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAEhB,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,QAAQ,EAAE,CAAC;IACxB,4EAA4E;IAC5E,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,aAAa,EAAE,gBAAgB,EAAE,CAAC;IAClC,gBAAgB,EAAE,YAAY,EAAE,CAAC;CAGlC;AAED,eAAO,MAAM,eAAe,UAA6B,CAAC;AAC1D,eAAO,MAAM,qBAAqB,UAAiB,CAAC;AAEpD,4DAA4D;AAC5D,oBAAY,OAAO,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;AAEnD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,QAAQ,CAAC;CACvB;AAED,oBAAY,WAAW,GAAG,QAAQ,CAAC,qBAAqB,CAAC,CAAC"}
|
package/build/cog/stac.js
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.CogStacItemExtensions = exports.CogStacKeywords = void 0;
|
|
4
|
-
exports.CogStacKeywords = ['Imagery', 'New Zealand'];
|
|
5
|
-
exports.CogStacItemExtensions = ['projection'];
|
|
1
|
+
export const CogStacKeywords = ['Imagery', 'New Zealand'];
|
|
2
|
+
export const CogStacItemExtensions = ['projection'];
|
package/build/cog/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BoundingBox, EpsgCode, NamedBounds, TileMatrixSet } from '@basemaps/geo';
|
|
2
2
|
import { FileConfig } from '@basemaps/shared';
|
|
3
|
-
import { GdalCogBuilderResampling } from '../gdal/gdal.config';
|
|
3
|
+
import { GdalCogBuilderResampling } from '../gdal/gdal.config.js';
|
|
4
4
|
export interface FeatureCollectionWithCrs extends GeoJSON.FeatureCollection {
|
|
5
5
|
crs: {
|
|
6
6
|
type: string;
|
package/build/cog/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cog/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cog/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE,MAAM,WAAW,wBAAyB,SAAQ,OAAO,CAAC,iBAAiB;IACzE,GAAG,EAAE;QACH,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE;YACV,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IAEZ,0BAA0B;IAC1B,QAAQ,EAAE,UAAU,CAAC;IAErB,0BAA0B;IAC1B,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,wBAAwB,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB,+EAA+E;IAC/E,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,mBAAoB,SAAQ,eAAe,EAAE,iBAAiB;IAC7E,iCAAiC;IACjC,MAAM,EAAE,WAAW,CAAC;IAEpB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,QAAQ,CAAC;IAEf,sBAAsB;IACtB,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAEF,0FAA0F;IAC1F,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,2BAA2B;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED,MAAM,WAAW,MAAO,SAAQ,UAAU;IACxC,UAAU,EAAE,aAAa,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IAEnB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,MAAM,EAAE,WAAW,EAAE,CAAC;IAEtB,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IAEnB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAEhB,6BAA6B;IAC7B,UAAU,EAAE,QAAQ,CAAC;IAErB,wBAAwB;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD,uCAAuC;IACvC,YAAY,EAAE,WAAW,CAAC;IAE1B,oDAAoD;IACpD,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB"}
|
package/build/cog/types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
ospec_1.default('should emit on progress', () => {
|
|
8
|
-
const prog = new gdal_progress_1.GdalProgressParser();
|
|
9
|
-
ospec_1.default(prog.progress).equals(0);
|
|
1
|
+
import o from 'ospec';
|
|
2
|
+
import { GdalProgressParser } from '../gdal.progress.js';
|
|
3
|
+
o.spec('GdalProgressParser', () => {
|
|
4
|
+
o('should emit on progress', () => {
|
|
5
|
+
const prog = new GdalProgressParser();
|
|
6
|
+
o(prog.progress).equals(0);
|
|
10
7
|
prog.data(Buffer.from('\n.'));
|
|
11
|
-
|
|
8
|
+
o(prog.progress.toFixed(2)).equals('3.23');
|
|
12
9
|
});
|
|
13
|
-
|
|
14
|
-
const prog = new
|
|
10
|
+
o('should take 31 dots to finish', () => {
|
|
11
|
+
const prog = new GdalProgressParser();
|
|
15
12
|
let processCount = 0;
|
|
16
13
|
prog.data(Buffer.from('\n'));
|
|
17
14
|
prog.on('progress', () => processCount++);
|
|
18
15
|
for (let i = 0; i < 31; i++) {
|
|
19
16
|
prog.data(Buffer.from('.'));
|
|
20
|
-
|
|
17
|
+
o(processCount).equals(i + 1);
|
|
21
18
|
}
|
|
22
|
-
|
|
19
|
+
o(prog.progress.toFixed(2)).equals('100.00');
|
|
23
20
|
});
|
|
24
21
|
});
|