@basemaps/cli-raster 8.0.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.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/build/bin.d.ts +1 -0
  4. package/build/bin.js +16 -0
  5. package/build/bin.js.map +1 -0
  6. package/build/cogify/__test__/covering.test.d.ts +1 -0
  7. package/build/cogify/__test__/covering.test.js +64 -0
  8. package/build/cogify/__test__/covering.test.js.map +1 -0
  9. package/build/cogify/__test__/extract.test.d.ts +1 -0
  10. package/build/cogify/__test__/extract.test.js +34 -0
  11. package/build/cogify/__test__/extract.test.js.map +1 -0
  12. package/build/cogify/cli/__test__/cli.cover.test.d.ts +1 -0
  13. package/build/cogify/cli/__test__/cli.cover.test.js +48 -0
  14. package/build/cogify/cli/__test__/cli.cover.test.js.map +1 -0
  15. package/build/cogify/cli/__test__/cli.topo.test.d.ts +1 -0
  16. package/build/cogify/cli/__test__/cli.topo.test.js +53 -0
  17. package/build/cogify/cli/__test__/cli.topo.test.js.map +1 -0
  18. package/build/cogify/cli/cli.cog.d.ts +55 -0
  19. package/build/cogify/cli/cli.cog.js +353 -0
  20. package/build/cogify/cli/cli.cog.js.map +1 -0
  21. package/build/cogify/cli/cli.cover.d.ts +30 -0
  22. package/build/cogify/cli/cli.cover.js +157 -0
  23. package/build/cogify/cli/cli.cover.js.map +1 -0
  24. package/build/cogify/cli/cli.topo.d.ts +50 -0
  25. package/build/cogify/cli/cli.topo.js +169 -0
  26. package/build/cogify/cli/cli.topo.js.map +1 -0
  27. package/build/cogify/cli/cli.validate.d.ts +15 -0
  28. package/build/cogify/cli/cli.validate.js +30 -0
  29. package/build/cogify/cli/cli.validate.js.map +1 -0
  30. package/build/cogify/cli.d.ts +121 -0
  31. package/build/cogify/cli.js +15 -0
  32. package/build/cogify/cli.js.map +1 -0
  33. package/build/cogify/covering/covering.d.ts +28 -0
  34. package/build/cogify/covering/covering.js +126 -0
  35. package/build/cogify/covering/covering.js.map +1 -0
  36. package/build/cogify/covering/cutline.d.ts +29 -0
  37. package/build/cogify/covering/cutline.js +109 -0
  38. package/build/cogify/covering/cutline.js.map +1 -0
  39. package/build/cogify/covering/tile.cover.d.ts +38 -0
  40. package/build/cogify/covering/tile.cover.js +198 -0
  41. package/build/cogify/covering/tile.cover.js.map +1 -0
  42. package/build/cogify/gdal/gdal.command.d.ts +27 -0
  43. package/build/cogify/gdal/gdal.command.js +175 -0
  44. package/build/cogify/gdal/gdal.command.js.map +1 -0
  45. package/build/cogify/gdal/gdal.runner.d.ts +42 -0
  46. package/build/cogify/gdal/gdal.runner.js +194 -0
  47. package/build/cogify/gdal/gdal.runner.js.map +1 -0
  48. package/build/cogify/stac.d.ts +138 -0
  49. package/build/cogify/stac.js +25 -0
  50. package/build/cogify/stac.js.map +1 -0
  51. package/build/cogify/topo/extract.d.ts +82 -0
  52. package/build/cogify/topo/extract.js +195 -0
  53. package/build/cogify/topo/extract.js.map +1 -0
  54. package/build/cogify/topo/slug.d.ts +10 -0
  55. package/build/cogify/topo/slug.js +18 -0
  56. package/build/cogify/topo/slug.js.map +1 -0
  57. package/build/cogify/topo/stac.creation.d.ts +47 -0
  58. package/build/cogify/topo/stac.creation.js +171 -0
  59. package/build/cogify/topo/stac.creation.js.map +1 -0
  60. package/build/download.d.ts +57 -0
  61. package/build/download.js +144 -0
  62. package/build/download.js.map +1 -0
  63. package/build/hash.stream.d.ts +20 -0
  64. package/build/hash.stream.js +62 -0
  65. package/build/hash.stream.js.map +1 -0
  66. package/build/index.d.ts +1 -0
  67. package/build/index.js +2 -0
  68. package/build/index.js.map +1 -0
  69. package/build/preset.d.ts +15 -0
  70. package/build/preset.js +66 -0
  71. package/build/preset.js.map +1 -0
  72. package/dist/index.cjs +85880 -0
  73. package/package.json +61 -0
@@ -0,0 +1,109 @@
1
+ import { Epsg, EpsgCode, Projection } from '@basemaps/geo';
2
+ import { fsa } from '@basemaps/shared';
3
+ import { Area, featuresToMultiPolygon, intersection, toFeatureCollection, toFeatureMultiPolygon, } from '@linzjs/geojson';
4
+ export async function loadCutline(path) {
5
+ const buf = await fsa.read(path);
6
+ if (path.pathname.endsWith('.geojson') || path.pathname.endsWith('.json')) {
7
+ const data = JSON.parse(buf.toString());
8
+ const projection = Epsg.parseCode(data.crs?.properties?.name ?? '') ?? EpsgCode.Wgs84;
9
+ const polygon = featuresToMultiPolygon(data.features, true).coordinates;
10
+ return { polygon, projection };
11
+ }
12
+ throw new Error('Unknown cutline type: ' + path.href);
13
+ }
14
+ export class CutlineOptimizer {
15
+ constructor(path, cutline, blend, tileMatrix) {
16
+ Object.defineProperty(this, "path", {
17
+ enumerable: true,
18
+ configurable: true,
19
+ writable: true,
20
+ value: void 0
21
+ });
22
+ Object.defineProperty(this, "cutline", {
23
+ enumerable: true,
24
+ configurable: true,
25
+ writable: true,
26
+ value: void 0
27
+ });
28
+ Object.defineProperty(this, "blend", {
29
+ enumerable: true,
30
+ configurable: true,
31
+ writable: true,
32
+ value: void 0
33
+ });
34
+ Object.defineProperty(this, "tileMatrix", {
35
+ enumerable: true,
36
+ configurable: true,
37
+ writable: true,
38
+ value: void 0
39
+ });
40
+ this.path = path;
41
+ this.cutline = cutline;
42
+ this.blend = blend;
43
+ this.tileMatrix = tileMatrix;
44
+ }
45
+ /** Cut a polygon to the cutline */
46
+ cut(poly) {
47
+ if (this.cutline == null)
48
+ return poly;
49
+ // TODO buffer the cutline by this.blend so blended tiles will be included
50
+ // although it is somewhat wasteful to make a cog just for a blended cut
51
+ return intersection(poly, this.cutline);
52
+ }
53
+ /** Optimize a cutline for a tile, if it doesn't intersect then ignore the cutline */
54
+ optimize(tile) {
55
+ if (this.cutline == null)
56
+ return null;
57
+ const tileBounds = this.tileMatrix.tileToSourceBounds(tile);
58
+ const tileScale = this.tileMatrix.pixelScale(tile.z);
59
+ // Expand the tile bounds to ensure optimized bounds are not clipping and blended.
60
+ const scaleAmount = (tileBounds.width + tileScale * (CutlineOptimizer.TilePixelPadding + this.blend) * 2) / tileBounds.width;
61
+ const scaledBounds = tileBounds.scaleFromCenter(scaleAmount);
62
+ const optimized = intersection(this.cutline, scaledBounds.toPolygon());
63
+ // Check how much of a change was the optimized cutline
64
+ const optimizedArea = Area.multiPolygon(optimized);
65
+ const scaledArea = scaledBounds.width * scaledBounds.height;
66
+ const areaPercent = 1 - optimizedArea / scaledArea;
67
+ // if area is bigger than 0.0001% then assume the cutline was applied
68
+ if (areaPercent < 1e-4)
69
+ return null;
70
+ const feature = toFeatureCollection([toFeatureMultiPolygon(optimized)]);
71
+ feature.crs = { type: 'name', properties: { name: this.tileMatrix.projection.toUrn() } };
72
+ return feature;
73
+ }
74
+ /**
75
+ * Convert cutline to geojson FeatureCollection
76
+ *
77
+ * @returns GeoJSON FeatureCollection if cutline exists, null otherwise
78
+ */
79
+ toGeoJson() {
80
+ if (this.cutline == null)
81
+ return null;
82
+ const feature = toFeatureCollection([toFeatureMultiPolygon(this.cutline)]);
83
+ feature.crs = { type: 'name', properties: { name: this.tileMatrix.projection.toUrn() } };
84
+ return feature;
85
+ }
86
+ static async load(path, blend, tileMatrix) {
87
+ if (path == null)
88
+ return new CutlineOptimizer(null, null, blend, tileMatrix);
89
+ const cut = await loadCutline(path);
90
+ if (cut.projection === tileMatrix.projection.code)
91
+ return new CutlineOptimizer(path, cut.polygon, blend, tileMatrix);
92
+ const projected = Projection.get(cut.projection).projectMultipolygon(cut.polygon, Projection.get(tileMatrix.projection));
93
+ return new CutlineOptimizer(path, projected, blend, tileMatrix);
94
+ }
95
+ /** Create a cutline optimizer from a STAC cutline link */
96
+ static async loadFromLink(l, tileMatrix) {
97
+ if (l == null)
98
+ return new CutlineOptimizer(null, null, 0, tileMatrix);
99
+ return this.load(new URL(l.href), l.blend, tileMatrix);
100
+ }
101
+ }
102
+ /** Pad tiles by 200m when optimizing cutlines so blending will not be affected */
103
+ Object.defineProperty(CutlineOptimizer, "TilePixelPadding", {
104
+ enumerable: true,
105
+ configurable: true,
106
+ writable: true,
107
+ value: 200
108
+ });
109
+ //# sourceMappingURL=cutline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cutline.js","sourceRoot":"","sources":["../../../src/cogify/covering/cutline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { Rgba } from '@basemaps/config';
2
+ import { ConfigImageryTiff } from '@basemaps/config-loader';
3
+ import { TileMatrixSet } from '@basemaps/geo';
4
+ import { LogType } from '@basemaps/shared';
5
+ import { Metrics } from '@linzjs/metrics';
6
+ import { CogifyStacCollection, CogifyStacItem } from '../stac.js';
7
+ import { CutlineOptimizer } from './cutline.js';
8
+ export interface TileCoverContext {
9
+ /** Unique id for the covering */
10
+ id: string;
11
+ /** List of imagery to cover */
12
+ imagery: ConfigImageryTiff;
13
+ /** Cutline to apply */
14
+ cutline: CutlineOptimizer;
15
+ /** Output tile matrix */
16
+ tileMatrix: TileMatrixSet;
17
+ /** Optional metrics provider to track how long actions take */
18
+ metrics?: Metrics;
19
+ /** Optional logger to trace covering creation */
20
+ logger?: LogType;
21
+ /** GDAL configuration preset */
22
+ preset: string;
23
+ /** Optional color with which to replace all transparent COG pixels */
24
+ background?: Rgba;
25
+ /**
26
+ * Override the base zoom to store the output COGS as
27
+ */
28
+ targetZoomOffset?: number;
29
+ }
30
+ export interface TileCoverResult {
31
+ /** Stac collection for the imagery */
32
+ collection: CogifyStacCollection;
33
+ /** tiles to create */
34
+ items: CogifyStacItem[];
35
+ /** GeoJSON features of all the source imagery */
36
+ source: GeoJSON.FeatureCollection;
37
+ }
38
+ export declare function createTileCover(ctx: TileCoverContext): Promise<TileCoverResult>;
@@ -0,0 +1,198 @@
1
+ import { Bounds, Projection, ProjectionLoader, TileId } from '@basemaps/geo';
2
+ import { fsa, urlToString } from '@basemaps/shared';
3
+ import { CliDate, CliInfo } from '@basemaps/shared/build/cli/info.js';
4
+ import { intersection, toFeatureCollection, union } from '@linzjs/geojson';
5
+ import { Presets } from '../../preset.js';
6
+ import { createFileStats } from '../stac.js';
7
+ import { createCovering } from './covering.js';
8
+ function getDateTime(ctx) {
9
+ const interval = ctx.imagery.collection?.extent?.temporal?.interval?.[0];
10
+ if (interval)
11
+ return { start: interval[0], end: interval[1] };
12
+ // TODO should we guess datetime
13
+ return { start: null, end: null };
14
+ }
15
+ /**
16
+ * Find a zoom level in the target tile matrix that is at least as good as resolution as `resolution`
17
+ *
18
+ * for some imagery sets this can mean a large difference in the source to target for example 1M resolution source imagery
19
+ * is resampled to 0.59m (z18) rather than the closer 1.19m (z17) `targetZoomOffset` can adjust the resolution
20
+ * to a nearer value using `-1` will convert a 1M target from 0.59m (z18) to 1.19m (z17)
21
+ *
22
+ * This can greatly reduce the size of output tiles
23
+ *
24
+ * @param tileMatrix target tile tile matrix to use
25
+ * @param resolution target resolution
26
+ * @param targetZoomOffset override the target base zoom, for instance -1 turns a z18 into z17
27
+ * @returns
28
+ */
29
+ function getTargetBaseZoom(tileMatrix, resolution, targetZoomOffset) {
30
+ if (targetZoomOffset == null)
31
+ return Projection.getTiffResZoom(tileMatrix, resolution);
32
+ return Projection.getTiffResZoom(tileMatrix, resolution) + targetZoomOffset;
33
+ }
34
+ export async function createTileCover(ctx) {
35
+ // Ensure we have the projection loaded for the source imagery
36
+ await ProjectionLoader.load(ctx.imagery.projection);
37
+ // Find the zoom level that is at least as good as the source imagery
38
+ const targetBaseZoom = getTargetBaseZoom(ctx.tileMatrix, ctx.imagery.gsd, ctx.targetZoomOffset);
39
+ // The base zoom is 256x256 pixels at its resolution, we are trying to find a image that is <32k pixels wide/high
40
+ // zooming out 7 levels converts a 256x256 image into 32k x 32k image
41
+ // 256 * 2 ** 7 = 32,768 - 256x256 tile
42
+ // 512 * 2 ** 6 = 32,768 - 512x512 tile
43
+ const optimalCoveringZoom = Math.max(1, targetBaseZoom - 7); // z12 from z19
44
+ ctx.logger?.debug({ targetBaseZoom, cogOverZoom: optimalCoveringZoom }, 'Imagery:ZoomLevel');
45
+ const sourceBounds = projectPolygon(polygonFromBounds(ctx.imagery.files), ctx.imagery.projection, ctx.tileMatrix.projection.code);
46
+ ctx.logger?.debug('Cutline:Apply');
47
+ ctx.metrics?.start('cutline:apply');
48
+ const dateTime = getDateTime(ctx);
49
+ // Convert the source imagery to a geojson
50
+ const sourceGeoJson = ctx.imagery.files.map((file) => {
51
+ return Projection.get(ctx.imagery.projection).boundsToGeoJsonFeature(file, { url: file.name });
52
+ });
53
+ ctx.logger?.info({ zoom: optimalCoveringZoom }, 'Imagery:Covering:Start');
54
+ // Cover the source imagery in tiles
55
+ ctx.metrics?.start('covering:create');
56
+ const covering = createCovering({
57
+ tileMatrix: ctx.tileMatrix,
58
+ source: sourceBounds,
59
+ targetZoom: optimalCoveringZoom,
60
+ baseZoom: targetBaseZoom,
61
+ cutline: ctx.cutline,
62
+ metrics: ctx.metrics,
63
+ logger: ctx.logger,
64
+ });
65
+ ctx.metrics?.end('covering:create');
66
+ if (covering.length === 0)
67
+ throw new Error('Unable to create tile covering, no tiles created.');
68
+ ctx.logger?.info({ tiles: covering.length, zoom: optimalCoveringZoom }, 'Imagery:Covering:Created');
69
+ const imageryBounds = ctx.imagery.files.map((f) => {
70
+ const polygon = Bounds.fromJson(f).toPolygon();
71
+ return { ...f, polygon };
72
+ });
73
+ ctx.metrics?.start('covering:polygon');
74
+ const items = [];
75
+ for (const tile of covering) {
76
+ const bounds = ctx.tileMatrix.tileToSourceBounds(tile);
77
+ // Scale the tile bounds slightly to ensure we get all relevant imagery
78
+ const scaledBounds = bounds.scaleFromCenter(1.05);
79
+ const tileBounds = Projection.get(ctx.tileMatrix).projectMultipolygon([scaledBounds.toPolygon()], Projection.get(ctx.imagery.projection));
80
+ const source = imageryBounds.filter((f) => intersection(tileBounds, f.polygon).length > 0);
81
+ const feature = Projection.get(ctx.tileMatrix).boundsToGeoJsonFeature(bounds);
82
+ const tileId = TileId.fromTile(tile);
83
+ const item = {
84
+ id: `${ctx.id}/${tileId}`,
85
+ type: 'Feature',
86
+ collection: ctx.id,
87
+ stac_version: '1.0.0',
88
+ stac_extensions: [],
89
+ geometry: feature.geometry,
90
+ bbox: Projection.get(ctx.tileMatrix).boundsToWgs84BoundingBox(bounds),
91
+ links: [
92
+ { href: `./${tileId}.json`, rel: 'self' },
93
+ { href: './collection.json', rel: 'collection' },
94
+ { href: './collection.json', rel: 'parent' },
95
+ ],
96
+ properties: {
97
+ datetime: dateTime.start ? null : CliDate,
98
+ start_datetime: dateTime.start ?? undefined,
99
+ end_datetime: dateTime.end ?? undefined,
100
+ 'proj:epsg': ctx.tileMatrix.projection.code,
101
+ 'linz_basemaps:options': {
102
+ preset: ctx.preset,
103
+ ...Presets[ctx.preset].options,
104
+ tile,
105
+ tileMatrix: ctx.tileMatrix.identifier,
106
+ sourceEpsg: ctx.imagery.projection,
107
+ zoomLevel: targetBaseZoom,
108
+ },
109
+ 'linz_basemaps:generated': {
110
+ package: CliInfo.package,
111
+ hash: CliInfo.hash,
112
+ version: CliInfo.version,
113
+ datetime: CliDate,
114
+ },
115
+ },
116
+ assets: {},
117
+ };
118
+ // Add the background color if it exists
119
+ if (ctx.background)
120
+ item.properties['linz_basemaps:options'].background = ctx.background;
121
+ // Add the source imagery as a STAC Link
122
+ for (const src of source) {
123
+ const srcLink = {
124
+ href: new URL(src.name, ctx.imagery.url).href,
125
+ rel: 'linz_basemaps:source',
126
+ type: 'image/tiff; application=geotiff;',
127
+ 'linz_basemaps:source_height': src.height,
128
+ 'linz_basemaps:source_width': src.width,
129
+ };
130
+ item.links.push(srcLink);
131
+ }
132
+ // Add the cutline as a STAC Link if it exists
133
+ if (ctx.cutline.path) {
134
+ const cutLink = {
135
+ href: urlToString(ctx.cutline.path),
136
+ rel: 'linz_basemaps:cutline',
137
+ blend: ctx.cutline.blend,
138
+ };
139
+ item.links.push(cutLink);
140
+ }
141
+ items.push(item);
142
+ }
143
+ ctx.metrics?.end('covering:polygon');
144
+ const collection = {
145
+ id: ctx.id,
146
+ type: 'Collection',
147
+ stac_version: '1.0.0',
148
+ stac_extensions: [],
149
+ license: ctx.imagery.collection?.license ?? 'CC-BY-4.0',
150
+ title: ctx.imagery.title,
151
+ description: ctx.imagery.collection?.description ?? 'Missing source STAC',
152
+ providers: ctx.imagery.collection?.providers,
153
+ extent: {
154
+ spatial: { bbox: [Projection.get(ctx.imagery.projection).boundsToWgs84BoundingBox(ctx.imagery.bounds)] },
155
+ // Default the temporal time today if no times were found as it is required for STAC
156
+ temporal: { interval: dateTime.start ? [[dateTime.start, dateTime.end]] : [[CliDate, null]] },
157
+ },
158
+ links: items.map((item) => {
159
+ const tile = item.properties['linz_basemaps:options'].tile;
160
+ if (tile == null)
161
+ throw new Error('Tile missing from item');
162
+ const tileId = TileId.fromTile(tile);
163
+ return { href: `./${tileId}.json`, rel: 'item', type: 'application/json' };
164
+ }),
165
+ };
166
+ // Add a self link to the links
167
+ collection.links.unshift({ rel: 'self', href: './collection.json', type: 'application/json' });
168
+ // Include a link back to the source collection
169
+ if (ctx.imagery.collection) {
170
+ const target = new URL('collection.json', ctx.imagery.url);
171
+ const stac = await fsa.read(target);
172
+ collection.links.push({
173
+ rel: 'linz_basemaps:source_collection',
174
+ href: target.href,
175
+ type: 'application/json',
176
+ ...createFileStats(stac),
177
+ });
178
+ }
179
+ return { collection, items, source: toFeatureCollection(sourceGeoJson) };
180
+ }
181
+ /** Convert a list of bounding boxes into a multipolygon */
182
+ function polygonFromBounds(bounds, scale = 1 + 1e-8) {
183
+ const srcPoly = [];
184
+ // merge imagery bounds
185
+ for (const image of bounds) {
186
+ srcPoly.push(Bounds.fromJson(image).scaleFromCenter(scale).toPolygon());
187
+ }
188
+ return union(srcPoly);
189
+ }
190
+ /** project a polygon from the source projection to a target projection */
191
+ function projectPolygon(p, sourceProjection, targetProjection) {
192
+ if (sourceProjection === targetProjection)
193
+ return p;
194
+ const sourceProj = Projection.get(sourceProjection);
195
+ const targetProj = Projection.get(targetProjection);
196
+ return sourceProj.projectMultipolygon(p, targetProj);
197
+ }
198
+ //# sourceMappingURL=tile.cover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tile.cover.js","sourceRoot":"","sources":["../../../src/cogify/covering/tile.cover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { Rgba } from '@basemaps/config';
2
+ import { EpsgCode } from '@basemaps/geo';
3
+ import { CogifyCreationOptions } from '../stac.js';
4
+ import { GdalCommand } from './gdal.runner.js';
5
+ export declare function gdalBuildVrt(targetVrt: URL, source: URL[], addalpha?: boolean): GdalCommand;
6
+ export declare function gdalBuildVrtWarp(targetVrt: URL, sourceVrt: URL, sourceProjection: EpsgCode, cutline: {
7
+ url: URL | null;
8
+ blend: number;
9
+ }, opt: CogifyCreationOptions): GdalCommand;
10
+ export declare function gdalBuildCog(targetTiff: URL, sourceVrt: URL, opt: CogifyCreationOptions): GdalCommand;
11
+ /**
12
+ * Creates an empty tiff where all pixel values are set to the given color.
13
+ * Used to force a background so that there are no empty pixels in the final COG.
14
+ *
15
+ * @param targetTiff the file path and name for the created tiff
16
+ * @param color the color to set all pixel values
17
+ * @param opt a CogifyCreationOptions object
18
+ *
19
+ * @returns a 'gdal_create' GdalCommand object
20
+ */
21
+ export declare function gdalCreate(targetTiff: URL, color: Rgba, opt: CogifyCreationOptions): GdalCommand;
22
+ /**
23
+ * Build a topographic mapsheet cog
24
+ *
25
+ * This is specific configuration to LINZ's topo50 and 250 mapsheets
26
+ */
27
+ export declare function gdalBuildTopoRasterCommands(targetTiff: URL, sourceVrt: URL, opt: CogifyCreationOptions, width: number, height: number): GdalCommand;
@@ -0,0 +1,175 @@
1
+ import { Epsg, TileMatrixSets } from '@basemaps/geo';
2
+ import { urlToString } from '@basemaps/shared';
3
+ import { Presets } from '../../preset.js';
4
+ const isPowerOfTwo = (x) => (x & (x - 1)) === 0;
5
+ /**
6
+ * Topographic mapsheets are rendered generally at 1:600 dpi,
7
+ *
8
+ * A topo50 mapsheet 1:600dpi does not perfectly align to full pixels and approximatly 1.7 pixels
9
+ * of empty space is rendered at the edge of every mapsheet.
10
+ *
11
+ */
12
+ const DefaultTrimPixelRight = 1.7; // 1.7 pixels to trim from the right side of the topo raster imagery
13
+ export function gdalBuildVrt(targetVrt, source, addalpha) {
14
+ if (source.length === 0)
15
+ throw new Error('No source files given for :' + targetVrt.href);
16
+ return {
17
+ output: targetVrt,
18
+ command: 'gdalbuildvrt',
19
+ args: [addalpha ? ['-addalpha'] : undefined, urlToString(targetVrt), ...source.map(urlToString)]
20
+ .filter((f) => f != null)
21
+ .flat()
22
+ .map(String),
23
+ };
24
+ }
25
+ export function gdalBuildVrtWarp(targetVrt, sourceVrt, sourceProjection, cutline, opt) {
26
+ const tileMatrix = TileMatrixSets.find(opt.tileMatrix);
27
+ if (tileMatrix == null)
28
+ throw new Error('Unable to find tileMatrix: ' + opt.tileMatrix);
29
+ const targetResolution = tileMatrix.pixelScale(opt.zoomLevel);
30
+ return {
31
+ output: targetVrt,
32
+ command: 'gdalwarp',
33
+ args: [
34
+ ['-of', 'vrt'], // Output as a VRT
35
+ // ['-co', 'compress=lzw'],
36
+ // ['-co', 'bigtiff=yes'],
37
+ '-multi', // Mutithread IO
38
+ ['-wo', 'NUM_THREADS=ALL_CPUS'], // Multithread the warp
39
+ ['-s_srs', Epsg.get(sourceProjection).toEpsgString()], // Source EPSG
40
+ ['-t_srs', tileMatrix.projection.toEpsgString()], // Target EPSG
41
+ ['-tr', targetResolution, targetResolution],
42
+ opt.warpResampling ? ['-r', opt.warpResampling] : undefined,
43
+ cutline.url ? ['-cutline', urlToString(cutline.url), '-cblend', cutline.blend] : undefined,
44
+ urlToString(sourceVrt),
45
+ urlToString(targetVrt),
46
+ ]
47
+ .filter((f) => f != null)
48
+ .flat()
49
+ .map(String),
50
+ };
51
+ }
52
+ export function gdalBuildCog(targetTiff, sourceVrt, opt) {
53
+ const cfg = { ...Presets[opt.preset], ...opt };
54
+ const tileMatrix = TileMatrixSets.find(cfg.tileMatrix);
55
+ if (tileMatrix == null)
56
+ throw new Error('Unable to find tileMatrix: ' + cfg.tileMatrix);
57
+ const bounds = tileMatrix.tileToSourceBounds(cfg.tile);
58
+ const tileExtent = [
59
+ Math.min(bounds.x, bounds.right),
60
+ Math.min(bounds.y, bounds.bottom),
61
+ Math.max(bounds.x, bounds.right),
62
+ Math.max(bounds.y, bounds.bottom),
63
+ ];
64
+ const targetResolution = tileMatrix.pixelScale(cfg.zoomLevel);
65
+ return {
66
+ command: 'gdal_translate',
67
+ output: targetTiff,
68
+ args: [
69
+ ['-of', 'COG'],
70
+ ['-co', 'NUM_THREADS=ALL_CPUS'], // Use all CPUS
71
+ ['--config', 'GDAL_NUM_THREADS', 'all_cpus'], // Also required to NUM_THREADS till gdal 3.7.x
72
+ ['-co', 'BIGTIFF=IF_NEEDED'], // BigTiff is somewhat slower and most (All?) of the COGS should be well below 4GB
73
+ ['-co', 'ADD_ALPHA=YES'],
74
+ /**
75
+ * GDAL will recompress existing overviews if they exist which will compound
76
+ * any lossly compression on the overview, so compute new overviews instead
77
+ */
78
+ ['-co', 'OVERVIEWS=IGNORE_EXISTING'],
79
+ ['-co', `BLOCKSIZE=${cfg.blockSize}`],
80
+ // ['-co', 'RESAMPLING=cubic'],
81
+ ['-co', `WARP_RESAMPLING=${cfg.warpResampling}`],
82
+ ['-co', `OVERVIEW_RESAMPLING=${cfg.overviewResampling}`],
83
+ ['-co', `COMPRESS=${cfg.compression}`],
84
+ cfg.quality ? ['-co', `QUALITY=${cfg.quality}`] : undefined,
85
+ cfg.maxZError ? ['-co', `MAX_Z_ERROR=${cfg.maxZError}`] : undefined,
86
+ cfg.maxZErrorOverview ? ['-co', `MAX_Z_ERROR_OVERVIEW=${cfg.maxZErrorOverview}`] : undefined,
87
+ ['-co', 'SPARSE_OK=YES'],
88
+ ['-co', `TARGET_SRS=${tileMatrix.projection.toEpsgString()}`],
89
+ ['-co', `EXTENT=${tileExtent.join(',')},`],
90
+ ['-tr', targetResolution, targetResolution],
91
+ urlToString(sourceVrt),
92
+ urlToString(targetTiff),
93
+ ]
94
+ .filter((f) => f != null)
95
+ .flat()
96
+ .map(String),
97
+ };
98
+ }
99
+ /**
100
+ * Creates an empty tiff where all pixel values are set to the given color.
101
+ * Used to force a background so that there are no empty pixels in the final COG.
102
+ *
103
+ * @param targetTiff the file path and name for the created tiff
104
+ * @param color the color to set all pixel values
105
+ * @param opt a CogifyCreationOptions object
106
+ *
107
+ * @returns a 'gdal_create' GdalCommand object
108
+ */
109
+ export function gdalCreate(targetTiff, color, opt) {
110
+ const cfg = { ...Presets[opt.preset], ...opt };
111
+ const tileMatrix = TileMatrixSets.find(cfg.tileMatrix);
112
+ if (tileMatrix == null)
113
+ throw new Error('Unable to find tileMatrix: ' + cfg.tileMatrix);
114
+ const bounds = tileMatrix.tileToSourceBounds(cfg.tile);
115
+ const pixelScale = tileMatrix.pixelScale(cfg.zoomLevel);
116
+ const size = Math.round(bounds.width / pixelScale);
117
+ // if the value of 'size' is not a power of 2
118
+ if (!isPowerOfTwo(size))
119
+ throw new Error('Size did not compute to a power of 2');
120
+ return {
121
+ command: 'gdal_create',
122
+ output: targetTiff,
123
+ args: [
124
+ ['-of', 'GTiff'],
125
+ ['-outsize', size, size], // set the size to match that of the final COG
126
+ ['-bands', '4'],
127
+ ['-burn', `${color.r} ${color.g} ${color.b} ${color.alpha}`], // set all pixel values to the given color
128
+ ['-a_srs', tileMatrix.projection.toEpsgString()],
129
+ ['-a_ullr', bounds.x, bounds.bottom, bounds.right, bounds.y],
130
+ ['-co', 'COMPRESS=LZW'],
131
+ urlToString(targetTiff),
132
+ ]
133
+ .filter((f) => f != null)
134
+ .flat()
135
+ .map(String),
136
+ };
137
+ }
138
+ /**
139
+ * Build a topographic mapsheet cog
140
+ *
141
+ * This is specific configuration to LINZ's topo50 and 250 mapsheets
142
+ */
143
+ export function gdalBuildTopoRasterCommands(targetTiff, sourceVrt, opt, width, height) {
144
+ const command = {
145
+ command: 'gdal_translate',
146
+ output: targetTiff,
147
+ args: [
148
+ ['-q'], // Supress non-error output
149
+ ['-stats'], // Force stats (re)computation
150
+ ['-of', 'COG'], // Output format
151
+ ['-srcwin', '0', '0', `${width - DefaultTrimPixelRight}`, `${height}`],
152
+ ['-a_srs', `EPSG:${opt.sourceEpsg}`],
153
+ // https://gdal.org/en/latest/drivers/raster/cog.html#creation-options
154
+ ['-co', 'BIGTIFF=NO'],
155
+ ['-co', 'BLOCKSIZE=512'],
156
+ ['-co', 'COMPRESS=WEBP'],
157
+ ['-co', 'NUM_THREADS=ALL_CPUS'], // Use all CPUS
158
+ ['-co', 'OVERVIEW_COMPRESS=WEBP'],
159
+ ['-co', 'OVERVIEWS=IGNORE_EXISTING'],
160
+ ['-co', 'OVERVIEW_QUALITY=90'],
161
+ ['-co', 'OVERVIEW_RESAMPLING=LANCZOS'],
162
+ ['-co', 'QUALITY=100'],
163
+ ['-co', 'SPARSE_OK=TRUE'], // Allow for sparse writes
164
+ // https://gdal.org/en/latest/drivers/raster/cog.html#reprojection-related-creation-options
165
+ ['-co', 'ADD_ALPHA=YES'],
166
+ urlToString(sourceVrt),
167
+ urlToString(targetTiff),
168
+ ]
169
+ .filter((f) => f != null)
170
+ .flat()
171
+ .map(String),
172
+ };
173
+ return command;
174
+ }
175
+ //# sourceMappingURL=gdal.command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gdal.command.js","sourceRoot":"","sources":["../../../src/cogify/gdal/gdal.command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { LogType } from '@basemaps/shared';
2
+ import { EventEmitter } from 'events';
3
+ export interface GdalCommand {
4
+ /** Output file location */
5
+ output: URL;
6
+ /** GDAL command to use */
7
+ command: 'gdal_create' | 'gdalwarp' | 'gdalbuildvrt' | 'gdal_translate';
8
+ /** GDAL arguments to use */
9
+ args: string[];
10
+ }
11
+ export declare class GdalRunner {
12
+ parser: GdalProgressParser;
13
+ startTime: number;
14
+ cmd: GdalCommand;
15
+ constructor(cmd: GdalCommand);
16
+ /**
17
+ * Run a GDAL command
18
+ *
19
+ * @param logger logger to use
20
+ */
21
+ run(logger?: LogType): Promise<{
22
+ stdout: string;
23
+ stderr: string;
24
+ duration: number;
25
+ }>;
26
+ }
27
+ /**
28
+ * Emit a "progress" event every time a "." is recorded in the output
29
+ */
30
+ export declare class GdalProgressParser extends EventEmitter<{
31
+ progress: [number];
32
+ }> {
33
+ waitNewLine: boolean;
34
+ dotCount: number;
35
+ byteCount: number;
36
+ lastEmit: number;
37
+ debounceMs: number;
38
+ /** Reset the progress counter */
39
+ reset(): void;
40
+ get progress(): number;
41
+ data(data: Buffer): void;
42
+ }