@basemaps/cli-raster 8.9.0 → 8.11.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/build/cogify/cli/__test__/cli.cover.test.js +13 -0
- package/build/cogify/cli/__test__/cli.cover.test.js.map +1 -1
- package/build/cogify/cli/__test__/cli.topo.test.js +1 -0
- package/build/cogify/cli/__test__/cli.topo.test.js.map +1 -1
- package/build/cogify/cli/cli.charts.d.ts +0 -2
- package/build/cogify/cli/cli.charts.js +86 -44
- package/build/cogify/cli/cli.charts.js.map +1 -1
- package/build/cogify/cli/cli.cog.js +6 -5
- package/build/cogify/cli/cli.cog.js.map +1 -1
- package/build/cogify/cli/cli.cover.d.ts +4 -2
- package/build/cogify/cli/cli.cover.js +24 -3
- package/build/cogify/cli/cli.cover.js.map +1 -1
- package/build/cogify/cli/cli.topo.d.ts +6 -1
- package/build/cogify/cli/cli.topo.js +10 -2
- package/build/cogify/cli/cli.topo.js.map +1 -1
- package/build/cogify/cli.d.ts +6 -4
- package/build/cogify/covering/tile.cover.d.ts +6 -1
- package/build/cogify/covering/tile.cover.js +24 -8
- package/build/cogify/covering/tile.cover.js.map +1 -1
- package/build/cogify/gdal/gdal.command.d.ts +1 -1
- package/build/cogify/gdal/gdal.command.js +26 -10
- package/build/cogify/gdal/gdal.command.js.map +1 -1
- package/build/cogify/gdal/gdal.runner.js +1 -1
- package/build/cogify/gdal/gdal.runner.js.map +1 -1
- package/build/cogify/stac.d.ts +32 -18
- package/build/cogify/stac.js.map +1 -1
- package/build/cogify/topo/extract.js +4 -4
- package/build/cogify/topo/extract.js.map +1 -1
- package/build/preset.d.ts +67 -6
- package/build/preset.js +41 -0
- package/build/preset.js.map +1 -1
- package/dist/index.cjs +443 -113
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -4554,7 +4554,7 @@ var require_oneOf = __commonJS({
|
|
|
4554
4554
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4555
4555
|
exports.oneOf = void 0;
|
|
4556
4556
|
var util_1 = require("util");
|
|
4557
|
-
function
|
|
4557
|
+
function oneOf3(literals) {
|
|
4558
4558
|
const examples = literals.map((x) => (0, util_1.inspect)(x)).join(", ");
|
|
4559
4559
|
return {
|
|
4560
4560
|
async from(str) {
|
|
@@ -4567,7 +4567,7 @@ var require_oneOf = __commonJS({
|
|
|
4567
4567
|
description: `One of ${examples}`
|
|
4568
4568
|
};
|
|
4569
4569
|
}
|
|
4570
|
-
exports.oneOf =
|
|
4570
|
+
exports.oneOf = oneOf3;
|
|
4571
4571
|
}
|
|
4572
4572
|
});
|
|
4573
4573
|
|
|
@@ -75271,9 +75271,9 @@ var ulid2 = __toESM(require_index_umd(), 1);
|
|
|
75271
75271
|
var CliInfo = {
|
|
75272
75272
|
// Detect unlinked packages looks for this string since its a package name, slightly work around it
|
|
75273
75273
|
package: "@basemaps/cli",
|
|
75274
|
-
version: "v8.
|
|
75275
|
-
hash: "
|
|
75276
|
-
buildId: "
|
|
75274
|
+
version: "v8.13.0",
|
|
75275
|
+
hash: "5a1984ab0e9b3939aab0db451d2f5e7aee1919af",
|
|
75276
|
+
buildId: "18264739226-1"
|
|
75277
75277
|
};
|
|
75278
75278
|
var CliDate = (/* @__PURE__ */ new Date()).toISOString();
|
|
75279
75279
|
var CliId = ulid2.ulid();
|
|
@@ -79554,6 +79554,12 @@ var DefaultColorRampOutput = {
|
|
|
79554
79554
|
// Taken from 0 of DefaultColorRamp
|
|
79555
79555
|
background: { r: 172, g: 204, b: 226, alpha: 1 }
|
|
79556
79556
|
};
|
|
79557
|
+
var DefaultBandExpandOutput = {
|
|
79558
|
+
title: "Gray",
|
|
79559
|
+
name: "expand",
|
|
79560
|
+
pipeline: [{ type: "color-ramp" }],
|
|
79561
|
+
background: { r: 255, g: 255, b: 255, alpha: 1 }
|
|
79562
|
+
};
|
|
79557
79563
|
|
|
79558
79564
|
// ../config/build/config/tile.set.pipeline.js
|
|
79559
79565
|
var ConfigImageFormatParser = z.union([
|
|
@@ -79563,15 +79569,39 @@ var ConfigImageFormatParser = z.union([
|
|
|
79563
79569
|
z.literal("avif")
|
|
79564
79570
|
]);
|
|
79565
79571
|
var ConfigResizeKernelParser = z.union([z.literal("nearest"), z.literal("lanczos3"), z.literal("lanczos2")]);
|
|
79566
|
-
var
|
|
79567
|
-
|
|
79568
|
-
|
|
79569
|
-
|
|
79570
|
-
|
|
79571
|
-
|
|
79572
|
-
|
|
79573
|
-
|
|
79572
|
+
var ColorParser = z.object({
|
|
79573
|
+
r: z.number(),
|
|
79574
|
+
g: z.number(),
|
|
79575
|
+
b: z.number(),
|
|
79576
|
+
alpha: z.number()
|
|
79577
|
+
});
|
|
79578
|
+
var PipelineTerrainRgbParser = z.object({ type: z.literal("terrain-rgb") });
|
|
79579
|
+
var PipelineColorRampParser = z.object({ type: z.literal("color-ramp") });
|
|
79580
|
+
var PipelineNdviParser = z.object({
|
|
79581
|
+
type: z.literal("ndvi"),
|
|
79582
|
+
nir: z.number(),
|
|
79583
|
+
r: z.number(),
|
|
79584
|
+
alpha: z.number(),
|
|
79585
|
+
scale: z.object({
|
|
79586
|
+
nir: z.number(),
|
|
79587
|
+
r: z.number(),
|
|
79588
|
+
alpha: z.number()
|
|
79589
|
+
}).optional()
|
|
79574
79590
|
});
|
|
79591
|
+
var PipelineExtractParser = z.object({
|
|
79592
|
+
type: z.literal("extract"),
|
|
79593
|
+
r: z.number(),
|
|
79594
|
+
g: z.number(),
|
|
79595
|
+
b: z.number(),
|
|
79596
|
+
alpha: z.number(),
|
|
79597
|
+
scale: ColorParser.optional()
|
|
79598
|
+
});
|
|
79599
|
+
var ConfigTileSetPipelineParser = z.discriminatedUnion("type", [
|
|
79600
|
+
PipelineExtractParser,
|
|
79601
|
+
PipelineTerrainRgbParser,
|
|
79602
|
+
PipelineColorRampParser,
|
|
79603
|
+
PipelineNdviParser
|
|
79604
|
+
]);
|
|
79575
79605
|
var ConfigRgbaParser = z.object({ r: z.number(), g: z.number(), b: z.number(), alpha: z.number() });
|
|
79576
79606
|
var ConfigTileSetOutputParser = z.object({
|
|
79577
79607
|
/**
|
|
@@ -79620,6 +79650,20 @@ var ConfigTileSetOutputParser = z.object({
|
|
|
79620
79650
|
// ../config/build/memory/memory.config.js
|
|
79621
79651
|
var import_ulid2 = __toESM(require_index_umd(), 1);
|
|
79622
79652
|
|
|
79653
|
+
// ../config/build/config/migration/imagery.js
|
|
79654
|
+
function migrateConfigImagery(img) {
|
|
79655
|
+
if (img.v === 2)
|
|
79656
|
+
return img;
|
|
79657
|
+
return {
|
|
79658
|
+
...img,
|
|
79659
|
+
v: 2,
|
|
79660
|
+
title: img.title ?? img.name,
|
|
79661
|
+
bands: (img.bands ?? []).map((m) => {
|
|
79662
|
+
return { type: m };
|
|
79663
|
+
})
|
|
79664
|
+
};
|
|
79665
|
+
}
|
|
79666
|
+
|
|
79623
79667
|
// ../config/build/name.convertor.js
|
|
79624
79668
|
function fixChunkGsd(chunk) {
|
|
79625
79669
|
if (!chunk.endsWith("m"))
|
|
@@ -79666,6 +79710,98 @@ function standardizeLayerName(name) {
|
|
|
79666
79710
|
return output.join("-");
|
|
79667
79711
|
}
|
|
79668
79712
|
|
|
79713
|
+
// ../config/build/memory/imagery.outputs.js
|
|
79714
|
+
function addDefaultOutputPipelines(ts, img) {
|
|
79715
|
+
if (ts.outputs != null)
|
|
79716
|
+
return ts.outputs;
|
|
79717
|
+
if (img.bands == null || img.bands.length === 0)
|
|
79718
|
+
return void 0;
|
|
79719
|
+
if (img.bands.length === 1) {
|
|
79720
|
+
if (img.bands[0].color === "gray")
|
|
79721
|
+
return [DefaultBandExpandOutput];
|
|
79722
|
+
return [DefaultTerrainRgbOutput, DefaultColorRampOutput];
|
|
79723
|
+
}
|
|
79724
|
+
const colors = { red: -1, green: -1, blue: -1, nir: -1, alpha: -1 };
|
|
79725
|
+
for (let i = 0; i < img.bands.length; i++) {
|
|
79726
|
+
const band = img.bands[i];
|
|
79727
|
+
if (band.color)
|
|
79728
|
+
colors[band.color] = i;
|
|
79729
|
+
}
|
|
79730
|
+
if (img.bands.length === 3 && colors.red >= 0 && colors.green >= 0 && colors.blue >= 0)
|
|
79731
|
+
return;
|
|
79732
|
+
if (img.bands.length === 4 && colors.red >= 0 && colors.green >= 0 && colors.blue >= 0 && colors.alpha >= 0)
|
|
79733
|
+
return;
|
|
79734
|
+
const pipelines = [];
|
|
79735
|
+
if (colors.red >= 0 && colors.green >= 0 && colors.blue >= 0) {
|
|
79736
|
+
const rgbExtract = {
|
|
79737
|
+
type: "extract",
|
|
79738
|
+
r: colors.red,
|
|
79739
|
+
g: colors.green,
|
|
79740
|
+
b: colors.blue,
|
|
79741
|
+
alpha: colors.alpha
|
|
79742
|
+
};
|
|
79743
|
+
const pipeline2 = { name: "rgb", title: "RGBA", pipeline: [rgbExtract] };
|
|
79744
|
+
rgbExtract.scale = getBandScales(img.bands, rgbExtract);
|
|
79745
|
+
pipelines.push(pipeline2);
|
|
79746
|
+
}
|
|
79747
|
+
if (colors.nir >= 0 && colors.red >= 0) {
|
|
79748
|
+
const ndviArgs = { type: "ndvi", r: colors.red, nir: colors.nir, alpha: colors.alpha };
|
|
79749
|
+
const scale = {
|
|
79750
|
+
r: getScale(img.bands[colors.red], "red"),
|
|
79751
|
+
nir: getScale(img.bands[colors.nir], "nir"),
|
|
79752
|
+
alpha: getAlphaScale(img.bands[colors.alpha])
|
|
79753
|
+
};
|
|
79754
|
+
if (scale.r && scale.nir && scale.alpha)
|
|
79755
|
+
ndviArgs.scale = scale;
|
|
79756
|
+
pipelines.push({
|
|
79757
|
+
name: "ndvi",
|
|
79758
|
+
title: "NDVI",
|
|
79759
|
+
pipeline: [ndviArgs]
|
|
79760
|
+
});
|
|
79761
|
+
}
|
|
79762
|
+
if (colors.red >= 0 && colors.green >= 0 && colors.nir >= 0) {
|
|
79763
|
+
const falseColorExtract = {
|
|
79764
|
+
type: "extract",
|
|
79765
|
+
r: colors.nir,
|
|
79766
|
+
g: colors.red,
|
|
79767
|
+
b: colors.green,
|
|
79768
|
+
alpha: colors.alpha
|
|
79769
|
+
};
|
|
79770
|
+
const pipeline2 = { name: "false-color", title: "FalseColor", pipeline: [falseColorExtract] };
|
|
79771
|
+
falseColorExtract.scale = getBandScales(img.bands, falseColorExtract);
|
|
79772
|
+
pipelines.push(pipeline2);
|
|
79773
|
+
}
|
|
79774
|
+
if (pipelines.length > 0)
|
|
79775
|
+
return pipelines;
|
|
79776
|
+
return void 0;
|
|
79777
|
+
}
|
|
79778
|
+
function getBandScales(bands, pipe) {
|
|
79779
|
+
const scale = {
|
|
79780
|
+
r: getScale(bands[pipe.r], "red"),
|
|
79781
|
+
g: getScale(bands[pipe.g], "green"),
|
|
79782
|
+
b: getScale(bands[pipe.b], "blue"),
|
|
79783
|
+
alpha: getAlphaScale(bands[pipe.alpha])
|
|
79784
|
+
};
|
|
79785
|
+
if (scale.r && scale.g && scale.b && scale.alpha)
|
|
79786
|
+
return scale;
|
|
79787
|
+
return void 0;
|
|
79788
|
+
}
|
|
79789
|
+
function getScale(band, color) {
|
|
79790
|
+
if (band.type === "uint8")
|
|
79791
|
+
return void 0;
|
|
79792
|
+
if (band.stats == null)
|
|
79793
|
+
return void 0;
|
|
79794
|
+
const stdDevs = color === "nir" ? 3 : 3;
|
|
79795
|
+
return Math.round(band.stats.mean + stdDevs * band.stats.stddev);
|
|
79796
|
+
}
|
|
79797
|
+
function getAlphaScale(band) {
|
|
79798
|
+
if (band.type === "uint8")
|
|
79799
|
+
return void 0;
|
|
79800
|
+
if (band.stats == null)
|
|
79801
|
+
return void 0;
|
|
79802
|
+
return Math.round(band.stats.max);
|
|
79803
|
+
}
|
|
79804
|
+
|
|
79669
79805
|
// ../config/build/memory/memory.config.js
|
|
79670
79806
|
function isConfigImagery(i) {
|
|
79671
79807
|
return ConfigId.getPrefix(i.id) === ConfigPrefix.Imagery;
|
|
@@ -79769,14 +79905,14 @@ var ConfigProviderMemory = class _ConfigProviderMemory extends BasemapsConfigPro
|
|
|
79769
79905
|
}
|
|
79770
79906
|
toJson() {
|
|
79771
79907
|
const cfg = {
|
|
79908
|
+
v: 2,
|
|
79772
79909
|
id: "",
|
|
79773
79910
|
hash: "",
|
|
79774
79911
|
assets: this.assets,
|
|
79775
79912
|
imagery: [],
|
|
79776
79913
|
style: [],
|
|
79777
79914
|
provider: [],
|
|
79778
|
-
tileSet: []
|
|
79779
|
-
duplicateImagery: this.duplicateImagery
|
|
79915
|
+
tileSet: []
|
|
79780
79916
|
};
|
|
79781
79917
|
for (const val2 of this.objects.values()) {
|
|
79782
79918
|
const prefix = val2.id.slice(0, val2.id.indexOf("_"));
|
|
@@ -79867,9 +80003,9 @@ var ConfigProviderMemory = class _ConfigProviderMemory extends BasemapsConfigPro
|
|
|
79867
80003
|
};
|
|
79868
80004
|
removeUndefined(existing);
|
|
79869
80005
|
this.put(existing);
|
|
79870
|
-
|
|
79871
|
-
|
|
79872
|
-
|
|
80006
|
+
const outputs = addDefaultOutputPipelines(existing, i);
|
|
80007
|
+
if (outputs != null)
|
|
80008
|
+
existing.outputs = outputs;
|
|
79873
80009
|
}
|
|
79874
80010
|
const existingImageryId = existing.layers[0][i.projection];
|
|
79875
80011
|
if (existingImageryId) {
|
|
@@ -79895,9 +80031,9 @@ var ConfigProviderMemory = class _ConfigProviderMemory extends BasemapsConfigPro
|
|
|
79895
80031
|
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
|
79896
80032
|
updatedAt: Date.now()
|
|
79897
80033
|
};
|
|
79898
|
-
|
|
79899
|
-
|
|
79900
|
-
|
|
80034
|
+
const outputs = addDefaultOutputPipelines(ts, i);
|
|
80035
|
+
if (outputs != null)
|
|
80036
|
+
ts.outputs = outputs;
|
|
79901
80037
|
return ts;
|
|
79902
80038
|
}
|
|
79903
80039
|
/** Load a bundled configuration creating virtual tilesets for all imagery */
|
|
@@ -79912,8 +80048,10 @@ var ConfigProviderMemory = class _ConfigProviderMemory extends BasemapsConfigPro
|
|
|
79912
80048
|
mem.put(st);
|
|
79913
80049
|
for (const pv of cfg.provider)
|
|
79914
80050
|
mem.put(pv);
|
|
79915
|
-
for (const img of cfg.imagery)
|
|
79916
|
-
|
|
80051
|
+
for (const img of cfg.imagery) {
|
|
80052
|
+
const parsed = migrateConfigImagery(img);
|
|
80053
|
+
mem.put(parsed);
|
|
80054
|
+
}
|
|
79917
80055
|
const updatedAt = (0, import_ulid2.decodeTime)(ConfigId.unprefix(ConfigPrefix.ConfigBundle, cfg.id));
|
|
79918
80056
|
for (const obj of mem.objects.values())
|
|
79919
80057
|
obj.updatedAt = updatedAt;
|
|
@@ -81925,11 +82063,11 @@ var Bounds = class _Bounds {
|
|
|
81925
82063
|
|
|
81926
82064
|
// ../geo/build/epsg.js
|
|
81927
82065
|
var EpsgCode;
|
|
81928
|
-
(function(
|
|
81929
|
-
|
|
81930
|
-
|
|
81931
|
-
|
|
81932
|
-
|
|
82066
|
+
(function(EpsgCode3) {
|
|
82067
|
+
EpsgCode3[EpsgCode3["Google"] = 3857] = "Google";
|
|
82068
|
+
EpsgCode3[EpsgCode3["Wgs84"] = 4326] = "Wgs84";
|
|
82069
|
+
EpsgCode3[EpsgCode3["Nztm2000"] = 2193] = "Nztm2000";
|
|
82070
|
+
EpsgCode3[EpsgCode3["Citm2000"] = 3793] = "Citm2000";
|
|
81933
82071
|
})(EpsgCode || (EpsgCode = {}));
|
|
81934
82072
|
var EpsgText = {
|
|
81935
82073
|
google: EpsgCode.Google,
|
|
@@ -86720,17 +86858,59 @@ var lzw = {
|
|
|
86720
86858
|
overviewResampling: "bilinear"
|
|
86721
86859
|
}
|
|
86722
86860
|
};
|
|
86861
|
+
var zstd_17 = {
|
|
86862
|
+
name: "zstd_17",
|
|
86863
|
+
options: {
|
|
86864
|
+
blockSize: 512,
|
|
86865
|
+
compression: "zstd",
|
|
86866
|
+
predictor: 2,
|
|
86867
|
+
level: 17,
|
|
86868
|
+
warpResampling: "bilinear",
|
|
86869
|
+
overviewResampling: "lanczos"
|
|
86870
|
+
}
|
|
86871
|
+
};
|
|
86723
86872
|
var Presets = {
|
|
86724
86873
|
[webP.name]: webP,
|
|
86725
86874
|
[webP80.name]: webP80,
|
|
86726
86875
|
[lerc1mm.name]: lerc1mm,
|
|
86727
86876
|
[lerc10mm.name]: lerc10mm,
|
|
86728
|
-
[lzw.name]: lzw
|
|
86877
|
+
[lzw.name]: lzw,
|
|
86878
|
+
[zstd_17.name]: zstd_17
|
|
86879
|
+
};
|
|
86880
|
+
var BandPresets = {
|
|
86881
|
+
/**
|
|
86882
|
+
* 4 band image, generally [uint8,uint8,uint8,uint8]
|
|
86883
|
+
* - Red,Green,Blue,Alpha
|
|
86884
|
+
*/
|
|
86885
|
+
rgba: ["red", "green", "blue", "alpha"],
|
|
86886
|
+
/**
|
|
86887
|
+
* 4 Band image, generally [uint8/16,uint8/16,uint8/16,uint8/16]
|
|
86888
|
+
* - Red,Green,Blue,Near Infrared
|
|
86889
|
+
*/
|
|
86890
|
+
rgbi: ["red", "green", "blue", "nir", "alpha"],
|
|
86891
|
+
rgbna: ["red", "green", "blue", "nir", "alpha"],
|
|
86892
|
+
/**
|
|
86893
|
+
* One band image, generally [float32]
|
|
86894
|
+
*/
|
|
86895
|
+
elevation: ["undefined"],
|
|
86896
|
+
/** One band image, generally 0-255 greyscale */
|
|
86897
|
+
hillshade: ["gray"]
|
|
86898
|
+
};
|
|
86899
|
+
var allPresets = Object.keys(BandPresets);
|
|
86900
|
+
var AllowedPresets = {
|
|
86901
|
+
// Webp is only suitable for RGB(A) images
|
|
86902
|
+
[webP.name]: ["rgba"],
|
|
86903
|
+
[webP80.name]: ["rgba"],
|
|
86904
|
+
[lerc1mm.name]: allPresets,
|
|
86905
|
+
[lerc10mm.name]: allPresets,
|
|
86906
|
+
[lzw.name]: allPresets,
|
|
86907
|
+
[zstd_17.name]: allPresets
|
|
86729
86908
|
};
|
|
86730
86909
|
|
|
86731
86910
|
// src/cogify/gdal/gdal.command.ts
|
|
86732
86911
|
var isPowerOfTwo = (x) => (x & x - 1) === 0;
|
|
86733
|
-
var
|
|
86912
|
+
var PixelTrimTop = 1;
|
|
86913
|
+
var PixelTrimRight = 4;
|
|
86734
86914
|
function gdalBuildVrt(targetVrt, source, addalpha) {
|
|
86735
86915
|
if (source.length === 0)
|
|
86736
86916
|
throw new Error("No source files given for :" + targetVrt.href);
|
|
@@ -86751,8 +86931,6 @@ function gdalBuildVrtWarp(targetVrt, sourceVrt, sourceProjection, cutline, opt)
|
|
|
86751
86931
|
args: [
|
|
86752
86932
|
["-of", "vrt"],
|
|
86753
86933
|
// Output as a VRT
|
|
86754
|
-
// ['-co', 'compress=lzw'],
|
|
86755
|
-
// ['-co', 'bigtiff=yes'],
|
|
86756
86934
|
"-multi",
|
|
86757
86935
|
// Mutithread IO
|
|
86758
86936
|
["-wo", "NUM_THREADS=ALL_CPUS"],
|
|
@@ -86769,6 +86947,24 @@ function gdalBuildVrtWarp(targetVrt, sourceVrt, sourceProjection, cutline, opt)
|
|
|
86769
86947
|
].filter((f) => f != null).flat().map(String)
|
|
86770
86948
|
};
|
|
86771
86949
|
}
|
|
86950
|
+
function getCompressionArgs(cfg) {
|
|
86951
|
+
if (cfg.compression === "lerc") {
|
|
86952
|
+
return [
|
|
86953
|
+
["-co", `MAX_Z_ERROR=${cfg.maxZError}`],
|
|
86954
|
+
["-co", `MAX_Z_ERROR_OVERVIEW=${cfg.maxZErrorOverview}`]
|
|
86955
|
+
];
|
|
86956
|
+
}
|
|
86957
|
+
if (cfg.compression === "zstd") {
|
|
86958
|
+
return [cfg.predictor ? ["-co", `PREDICTOR=${cfg.predictor}`] : [], ["-co", `LEVEL=${cfg.level}`]];
|
|
86959
|
+
}
|
|
86960
|
+
if (cfg.compression === "webp" || cfg.compression === "jpeg") {
|
|
86961
|
+
return [["-co", `QUALITY=${cfg.quality}`]];
|
|
86962
|
+
}
|
|
86963
|
+
if (cfg.compression === "lzw") {
|
|
86964
|
+
return [cfg.predictor ? ["-co", `PREDICTOR=${cfg.predictor}`] : []];
|
|
86965
|
+
}
|
|
86966
|
+
throw new Error("Unknown compression preset:" + String(cfg["compression"]));
|
|
86967
|
+
}
|
|
86772
86968
|
function gdalBuildCog(targetTiff, sourceVrt, opt) {
|
|
86773
86969
|
const cfg = { ...Presets[opt.preset], ...opt };
|
|
86774
86970
|
const tileMatrix = TileMatrixSets.find(cfg.tileMatrix);
|
|
@@ -86789,8 +86985,6 @@ function gdalBuildCog(targetTiff, sourceVrt, opt) {
|
|
|
86789
86985
|
["-of", "COG"],
|
|
86790
86986
|
["-co", "NUM_THREADS=ALL_CPUS"],
|
|
86791
86987
|
// Use all CPUS
|
|
86792
|
-
["--config", "GDAL_NUM_THREADS", "all_cpus"],
|
|
86793
|
-
// Also required to NUM_THREADS till gdal 3.7.x
|
|
86794
86988
|
["-co", "BIGTIFF=IF_NEEDED"],
|
|
86795
86989
|
// BigTiff is somewhat slower and most (All?) of the COGS should be well below 4GB
|
|
86796
86990
|
["-co", "ADD_ALPHA=YES"],
|
|
@@ -86800,16 +86994,15 @@ function gdalBuildCog(targetTiff, sourceVrt, opt) {
|
|
|
86800
86994
|
*/
|
|
86801
86995
|
["-co", "OVERVIEWS=IGNORE_EXISTING"],
|
|
86802
86996
|
["-co", `BLOCKSIZE=${cfg.blockSize}`],
|
|
86803
|
-
// ['-co', 'RESAMPLING=cubic'],
|
|
86804
86997
|
["-co", `WARP_RESAMPLING=${cfg.warpResampling}`],
|
|
86805
86998
|
["-co", `OVERVIEW_RESAMPLING=${cfg.overviewResampling}`],
|
|
86806
86999
|
["-co", `COMPRESS=${cfg.compression}`],
|
|
86807
|
-
cfg
|
|
86808
|
-
cfg.
|
|
86809
|
-
cfg.maxZErrorOverview ? ["-co", `MAX_Z_ERROR_OVERVIEW=${cfg.maxZErrorOverview}`] : void 0,
|
|
87000
|
+
...getCompressionArgs(cfg),
|
|
87001
|
+
cfg.presetBands ? ["-colorinterp", cfg.presetBands.join(",")] : void 0,
|
|
86810
87002
|
["-co", "SPARSE_OK=YES"],
|
|
86811
87003
|
["-co", `TARGET_SRS=${tileMatrix.projection.toEpsgString()}`],
|
|
86812
87004
|
["-co", `EXTENT=${tileExtent.join(",")},`],
|
|
87005
|
+
["-stats"],
|
|
86813
87006
|
["-tr", targetResolution, targetResolution],
|
|
86814
87007
|
urlToString(sourceVrt),
|
|
86815
87008
|
urlToString(targetTiff)
|
|
@@ -86854,7 +87047,7 @@ function gdalBuildTopoRasterCommands(targetTiff, sourceVrt, opt, width, height)
|
|
|
86854
87047
|
// Force stats (re)computation
|
|
86855
87048
|
["-of", "COG"],
|
|
86856
87049
|
// Output format
|
|
86857
|
-
["-srcwin",
|
|
87050
|
+
["-srcwin", 0, PixelTrimTop, width - PixelTrimRight, height - PixelTrimTop],
|
|
86858
87051
|
["-a_srs", `EPSG:${opt.sourceEpsg}`],
|
|
86859
87052
|
// https://gdal.org/en/latest/drivers/raster/cog.html#creation-options
|
|
86860
87053
|
["-co", "BIGTIFF=NO"],
|
|
@@ -86886,7 +87079,9 @@ function gdalBuildChartsCommand(target, source, cutline, tileMatrix) {
|
|
|
86886
87079
|
"-multi",
|
|
86887
87080
|
["-wo", "NUM_THREADS=ALL_CPUS"],
|
|
86888
87081
|
["-t_srs", tileMatrix.projection.toEpsgString()],
|
|
86889
|
-
"-
|
|
87082
|
+
["-b", "1", "-b", "2", "-b", "3"],
|
|
87083
|
+
// Drop dummy band 4 if it exists
|
|
87084
|
+
["-dstalpha"],
|
|
86890
87085
|
["-cutline", urlToString(cutline)],
|
|
86891
87086
|
["-crop_to_cutline"],
|
|
86892
87087
|
["-co", "BIGTIFF=NO"],
|
|
@@ -86903,7 +87098,7 @@ var import_events = require("events");
|
|
|
86903
87098
|
var import_path = require("path");
|
|
86904
87099
|
function getDockerContainer() {
|
|
86905
87100
|
const containerPath = process.env["GDAL_DOCKER_CONTAINER"] ?? "ghcr.io/osgeo/gdal";
|
|
86906
|
-
const tag = process.env["GDAL_DOCKER_CONTAINER_TAG"] ?? "ubuntu-small-3.
|
|
87101
|
+
const tag = process.env["GDAL_DOCKER_CONTAINER_TAG"] ?? "ubuntu-small-3.11.3";
|
|
86907
87102
|
return `${containerPath}:${tag}`;
|
|
86908
87103
|
}
|
|
86909
87104
|
function toDockerArgs(cmd) {
|
|
@@ -87095,13 +87290,6 @@ var ChartsCreationCommand = (0, import_cmd_ts2.command)({
|
|
|
87095
87290
|
long: "target",
|
|
87096
87291
|
description: "Target location for the output files"
|
|
87097
87292
|
}),
|
|
87098
|
-
tileMatrix: (0, import_cmd_ts2.option)({
|
|
87099
|
-
type: (0, import_cmd_ts2.oneOf)([Nztm2000QuadTms.identifier, GoogleTms.identifier]),
|
|
87100
|
-
long: "tile-matrix",
|
|
87101
|
-
description: `Output TileMatrix to use. Either: ${Nztm2000QuadTms.identifier}, or ${GoogleTms.identifier}.`,
|
|
87102
|
-
defaultValue: () => GoogleTms.identifier,
|
|
87103
|
-
defaultValueIsSerializable: true
|
|
87104
|
-
}),
|
|
87105
87293
|
cutline: (0, import_cmd_ts2.option)({
|
|
87106
87294
|
type: UrlFolder,
|
|
87107
87295
|
long: "cutline",
|
|
@@ -87129,9 +87317,6 @@ var ChartsCreationCommand = (0, import_cmd_ts2.command)({
|
|
|
87129
87317
|
const logger = getLogger(this, args, "cli-raster");
|
|
87130
87318
|
logger.info("Charts:Start");
|
|
87131
87319
|
const files = args.source ? await Fsa.toArray(Fsa.list(args.source)) : args.paths;
|
|
87132
|
-
const tileMatrix = TileMatrixSets.find(args.tileMatrix);
|
|
87133
|
-
if (tileMatrix == null)
|
|
87134
|
-
throw new Error(`Tile matrix ${args.tileMatrix} is not supported`);
|
|
87135
87320
|
await (0, import_promises.mkdir)(tmpFolder, { recursive: true });
|
|
87136
87321
|
const outputs = /* @__PURE__ */ new Set();
|
|
87137
87322
|
const toProcess = files.map(
|
|
@@ -87150,39 +87335,15 @@ var ChartsCreationCommand = (0, import_cmd_ts2.command)({
|
|
|
87150
87335
|
}
|
|
87151
87336
|
const sourceTiff = await downloadCharts(file, filename, logger);
|
|
87152
87337
|
const cutline = await downloadCutlines(new import_url2.URL(args.cutline.href), chartCode, logger);
|
|
87153
|
-
logger.info({ file: file.href,
|
|
87338
|
+
logger.info({ file: file.href, chartCode }, "Charts:Processing");
|
|
87154
87339
|
const tiff = await new Tiff(Fsa.source(file)).init();
|
|
87155
87340
|
const backUpUrl = new import_url2.URL(filename, args.backup);
|
|
87156
87341
|
const metadata = await fetchMetadata(tiff, backUpUrl, logger);
|
|
87157
|
-
const bufferedCutline = await prepareCutline(
|
|
87158
|
-
|
|
87159
|
-
chartCode,
|
|
87160
|
-
tileMatrix,
|
|
87161
|
-
metadata.gsd,
|
|
87162
|
-
args.bufferPixels,
|
|
87163
|
-
logger
|
|
87164
|
-
);
|
|
87165
|
-
const { item, collection } = await createStacFiles(
|
|
87166
|
-
chartCode,
|
|
87167
|
-
tileMatrix,
|
|
87168
|
-
metadata,
|
|
87169
|
-
cutline,
|
|
87170
|
-
bufferedCutline,
|
|
87171
|
-
logger
|
|
87172
|
-
);
|
|
87173
|
-
logger.info({ file: file.href, chartCode, tileMatrix: tileMatrix.identifier }, "Charts:GdalBuildCharts");
|
|
87174
|
-
const cogFile = new import_url2.URL(`${chartCode}-${tileMatrix.identifier}.tif`, tmpFolder);
|
|
87175
|
-
await new GdalRunner(gdalBuildChartsCommand(cogFile, sourceTiff, bufferedCutline, tileMatrix)).run(logger);
|
|
87176
|
-
const targetPath = new import_url2.URL(`${tileMatrix.projection.code}/${chartCode}/`, args.target);
|
|
87177
|
-
logger.info({ file: file.href, target: targetPath.href }, "Charts:Uploading");
|
|
87342
|
+
const bufferedCutline = await prepareCutline(cutline, chartCode, metadata.gsd, args.bufferPixels, logger);
|
|
87343
|
+
const targetPath = new import_url2.URL(`${GoogleTms.projection.code}/${CliId}/${chartCode}/`, args.target);
|
|
87178
87344
|
if (targetPath.protocol === "file:")
|
|
87179
87345
|
await (0, import_promises.mkdir)(targetPath, { recursive: true });
|
|
87180
|
-
|
|
87181
|
-
await Fsa.write(targetTiff, Fsa.readStream(cogFile));
|
|
87182
|
-
const targetItem = new import_url2.URL(`${chartCode}.json`, targetPath);
|
|
87183
|
-
await Fsa.write(targetItem, JSON.stringify(item, null, 2));
|
|
87184
|
-
const targetCollection = new import_url2.URL("collection.json", targetPath);
|
|
87185
|
-
await Fsa.write(targetCollection, JSON.stringify(collection, null, 2));
|
|
87346
|
+
await createCogs(sourceTiff, cutline, chartCode, bufferedCutline, metadata, targetPath, logger);
|
|
87186
87347
|
outputs.add(urlToString(targetPath));
|
|
87187
87348
|
await tiff.source.close?.();
|
|
87188
87349
|
})
|
|
@@ -87215,17 +87376,17 @@ async function downloadCutlines(cutline, chartCode, logger) {
|
|
|
87215
87376
|
}
|
|
87216
87377
|
return new import_url2.URL(`${chartCode}.shp`, tmpFolder);
|
|
87217
87378
|
}
|
|
87218
|
-
async function prepareCutline(cutline, chartCode,
|
|
87379
|
+
async function prepareCutline(cutline, chartCode, gsd, bufferPixels, logger) {
|
|
87219
87380
|
logger.info({ cutline: cutline.href, chartCode }, "Charts:WrapCutline");
|
|
87220
87381
|
const wrappedCutline = new import_url2.URL(`${chartCode}-wrapped.shp`, tmpFolder);
|
|
87221
87382
|
await new GdalRunner(wrapCutline(wrappedCutline, cutline)).run(logger);
|
|
87222
|
-
logger.info({ cutline: cutline.href, chartCode, tileMatrix:
|
|
87223
|
-
const reprojectedCutline = new import_url2.URL(`${chartCode}-${
|
|
87224
|
-
await new GdalRunner(reprojectCutline(reprojectedCutline, wrappedCutline,
|
|
87383
|
+
logger.info({ cutline: cutline.href, chartCode, tileMatrix: GoogleTms.identifier }, "Charts:ReprojectCutline");
|
|
87384
|
+
const reprojectedCutline = new import_url2.URL(`${chartCode}-${GoogleTms.identifier}.shp`, tmpFolder);
|
|
87385
|
+
await new GdalRunner(reprojectCutline(reprojectedCutline, wrappedCutline, GoogleTms)).run(logger);
|
|
87225
87386
|
logger.info({ cutline: cutline.href, chartCode, gsd, bufferPixels }, "Charts:BufferCutline");
|
|
87226
87387
|
const bufferedCutline = new import_url2.URL(`${chartCode}-buffered.geojson`, tmpFolder);
|
|
87227
87388
|
await new GdalRunner(
|
|
87228
|
-
bufferCutline(bufferedCutline, reprojectedCutline, `${chartCode}-${
|
|
87389
|
+
bufferCutline(bufferedCutline, reprojectedCutline, `${chartCode}-${GoogleTms.identifier}`, gsd, bufferPixels)
|
|
87229
87390
|
).run(logger);
|
|
87230
87391
|
return bufferedCutline;
|
|
87231
87392
|
}
|
|
@@ -87276,9 +87437,9 @@ function geojsonToBbox(geojson) {
|
|
|
87276
87437
|
throw new Error("No union found in GeoJSON features");
|
|
87277
87438
|
return union2.toBbox();
|
|
87278
87439
|
}
|
|
87279
|
-
async function
|
|
87440
|
+
async function createStacItem(chartCode, metadata, sourceCutline, cutline, logger) {
|
|
87441
|
+
const geojson = await Fsa.readJson(cutline);
|
|
87280
87442
|
logger.info({ chartCode }, "Charts:CreateStacItem");
|
|
87281
|
-
const geojson = await Fsa.readJson(bufferedCutline);
|
|
87282
87443
|
const item = {
|
|
87283
87444
|
id: `${CliId}/${chartCode}`,
|
|
87284
87445
|
type: "Feature",
|
|
@@ -87305,9 +87466,9 @@ async function createStacFiles(chartCode, tileMatrix, metadata, sourceCutline, b
|
|
|
87305
87466
|
],
|
|
87306
87467
|
properties: {
|
|
87307
87468
|
datetime: CliDate,
|
|
87308
|
-
"proj:epsg":
|
|
87469
|
+
"proj:epsg": GoogleTms.projection.code,
|
|
87309
87470
|
"linz_basemaps:options": {
|
|
87310
|
-
tileMatrix:
|
|
87471
|
+
tileMatrix: GoogleTms.identifier,
|
|
87311
87472
|
sourceEpsg: metadata.epsg
|
|
87312
87473
|
},
|
|
87313
87474
|
"linz_basemaps:generated": {
|
|
@@ -87319,6 +87480,9 @@ async function createStacFiles(chartCode, tileMatrix, metadata, sourceCutline, b
|
|
|
87319
87480
|
},
|
|
87320
87481
|
assets: {}
|
|
87321
87482
|
};
|
|
87483
|
+
return item;
|
|
87484
|
+
}
|
|
87485
|
+
function CreateStacCollection(chartCode, items, logger) {
|
|
87322
87486
|
logger.info({ chartCode }, "Charts:CreateStacCollection");
|
|
87323
87487
|
const collection = {
|
|
87324
87488
|
id: CliId,
|
|
@@ -87327,21 +87491,73 @@ async function createStacFiles(chartCode, tileMatrix, metadata, sourceCutline, b
|
|
|
87327
87491
|
stac_extensions: [],
|
|
87328
87492
|
license: "CC-BY-4.0",
|
|
87329
87493
|
title: `New Zealand Charts Mapsheets - ${chartCode}`,
|
|
87330
|
-
description: `New Zealand Charts Mapsheets - ${chartCode} - ${
|
|
87494
|
+
description: `New Zealand Charts Mapsheets - ${chartCode} - ${GoogleTms.identifier}`,
|
|
87331
87495
|
extent: {
|
|
87332
|
-
spatial: { bbox:
|
|
87496
|
+
spatial: { bbox: items.map((i) => i.bbox) },
|
|
87333
87497
|
temporal: { interval: [[CliDate, null]] }
|
|
87334
87498
|
},
|
|
87335
87499
|
links: [
|
|
87336
87500
|
{ rel: "self", href: "./collection.json", type: "application/json" },
|
|
87337
|
-
{
|
|
87501
|
+
...items.map((item) => ({
|
|
87338
87502
|
href: `./${item.id}.json`,
|
|
87339
87503
|
rel: "item",
|
|
87340
87504
|
type: "application/json"
|
|
87341
|
-
}
|
|
87505
|
+
}))
|
|
87342
87506
|
]
|
|
87343
87507
|
};
|
|
87344
|
-
|
|
87508
|
+
for (const item of items) {
|
|
87509
|
+
collection.extent.spatial.bbox.push(item.bbox);
|
|
87510
|
+
}
|
|
87511
|
+
return collection;
|
|
87512
|
+
}
|
|
87513
|
+
async function createCogs(sourceTiff, sourceCutline, chartCode, bufferedCutline, metadata, targetPath, logger) {
|
|
87514
|
+
const geojson = await Fsa.readJson(bufferedCutline);
|
|
87515
|
+
let index = 0;
|
|
87516
|
+
const items = [];
|
|
87517
|
+
for (const feature of geojson.features) {
|
|
87518
|
+
if (feature.geometry.type === "Polygon") {
|
|
87519
|
+
const splitCutline = {
|
|
87520
|
+
type: "FeatureCollection",
|
|
87521
|
+
crs: { type: "name", properties: { name: "urn:ogc:def:crs:EPSG::3857" } },
|
|
87522
|
+
features: [feature]
|
|
87523
|
+
};
|
|
87524
|
+
const cutlineFile = new import_url2.URL(`cutline-${index}.geojson`, tmpFolder);
|
|
87525
|
+
await Fsa.write(cutlineFile, JSON.stringify(splitCutline));
|
|
87526
|
+
const item = await createStacItem(`${chartCode}-${index}`, metadata, sourceCutline, cutlineFile, logger);
|
|
87527
|
+
await Fsa.write(new import_url2.URL(`${chartCode}-${index}.json`, targetPath), JSON.stringify(item, null, 2));
|
|
87528
|
+
items.push(item);
|
|
87529
|
+
const cog = new import_url2.URL(`${chartCode}-${index}.tif`, tmpFolder);
|
|
87530
|
+
await new GdalRunner(gdalBuildChartsCommand(cog, sourceTiff, cutlineFile, GoogleTms)).run(logger);
|
|
87531
|
+
await Fsa.write(new import_url2.URL(`${chartCode}-${index}.tif`, targetPath), Fsa.readStream(cog));
|
|
87532
|
+
index++;
|
|
87533
|
+
} else if (feature.geometry.type === "MultiPolygon") {
|
|
87534
|
+
for (const coords of feature.geometry.coordinates) {
|
|
87535
|
+
const splitCutline = {
|
|
87536
|
+
type: "FeatureCollection",
|
|
87537
|
+
crs: { type: "name", properties: { name: "urn:ogc:def:crs:EPSG::3857" } },
|
|
87538
|
+
features: [
|
|
87539
|
+
{
|
|
87540
|
+
type: "Feature",
|
|
87541
|
+
geometry: { type: "Polygon", coordinates: coords }
|
|
87542
|
+
}
|
|
87543
|
+
]
|
|
87544
|
+
};
|
|
87545
|
+
const cutlineFile = new import_url2.URL(`cutline-${index}.geojson`, tmpFolder);
|
|
87546
|
+
await Fsa.write(cutlineFile, JSON.stringify(splitCutline));
|
|
87547
|
+
const item = await createStacItem(`${chartCode}-${index}`, metadata, sourceCutline, cutlineFile, logger);
|
|
87548
|
+
await Fsa.write(new import_url2.URL(`${chartCode}-${index}.json`, targetPath), JSON.stringify(item, null, 2));
|
|
87549
|
+
items.push(item);
|
|
87550
|
+
const cog = new import_url2.URL(`${chartCode}-${index}.tif`, tmpFolder);
|
|
87551
|
+
await new GdalRunner(gdalBuildChartsCommand(cog, sourceTiff, cutlineFile, GoogleTms)).run(logger);
|
|
87552
|
+
await Fsa.write(new import_url2.URL(`${chartCode}-${index}.tif`, targetPath), Fsa.readStream(cog));
|
|
87553
|
+
index++;
|
|
87554
|
+
}
|
|
87555
|
+
} else {
|
|
87556
|
+
throw new Error("GeoJSON must contain Polygon or MultiPolygon geometries");
|
|
87557
|
+
}
|
|
87558
|
+
}
|
|
87559
|
+
const collection = CreateStacCollection(chartCode, items, logger);
|
|
87560
|
+
await Fsa.write(new import_url2.URL("collection.json", targetPath), JSON.stringify(collection, null, 2));
|
|
87345
87561
|
}
|
|
87346
87562
|
|
|
87347
87563
|
// ../config-loader/build/json/json.config.js
|
|
@@ -87511,8 +87727,15 @@ function ensureBandsSimilar(tiff, existingBands, newBands) {
|
|
|
87511
87727
|
const bB = newBands[i];
|
|
87512
87728
|
if (bA == null || bB == null)
|
|
87513
87729
|
continue;
|
|
87514
|
-
if (bA !== bB) {
|
|
87515
|
-
throw new Error(`Band:${i} datatype mismatch: ${tiff.source.url.href} ${bA} vs ${bB}`);
|
|
87730
|
+
if (bA.type !== bB.type) {
|
|
87731
|
+
throw new Error(`Band:${i} datatype mismatch: ${tiff.source.url.href} ${bA.type} vs ${bB.type}`);
|
|
87732
|
+
}
|
|
87733
|
+
if (bA.stats == null && bB.stats) {
|
|
87734
|
+
bA.stats = bB.stats;
|
|
87735
|
+
} else if (bA.stats && bB.stats) {
|
|
87736
|
+
bA.stats.min = Math.min(bA.stats.min, bB.stats.min);
|
|
87737
|
+
bA.stats.max = Math.max(bA.stats.max, bB.stats.max);
|
|
87738
|
+
bA.stats.mean = (bA.stats.mean + bB.stats.mean) / 2;
|
|
87516
87739
|
}
|
|
87517
87740
|
}
|
|
87518
87741
|
if (existingBands.length >= newBands.length)
|
|
@@ -87533,12 +87756,13 @@ async function computeTiffSummary(target, tiffs) {
|
|
|
87533
87756
|
else if (res.projection !== epsg) {
|
|
87534
87757
|
throw new Error(`ESPG projection mismatch on imagery ${res.projection} vs ${epsg} source: ${tiff.source.url.href}`);
|
|
87535
87758
|
}
|
|
87536
|
-
const [dataType, bitsPerSample, noData] = await Promise.all([
|
|
87759
|
+
const [dataType, bitsPerSample, noData, gdalMetadata] = await Promise.all([
|
|
87537
87760
|
/** firstImage.fetch(TiffTag.Photometric), **/
|
|
87538
87761
|
// TODO enable RGB detection
|
|
87539
87762
|
firstImage.fetch(TiffTag.SampleFormat),
|
|
87540
87763
|
firstImage.fetch(TiffTag.BitsPerSample),
|
|
87541
|
-
firstImage.fetch(TiffTag.GdalNoData)
|
|
87764
|
+
firstImage.fetch(TiffTag.GdalNoData),
|
|
87765
|
+
firstImage.fetch(TiffTag.GdalMetadata)
|
|
87542
87766
|
]);
|
|
87543
87767
|
if (bitsPerSample == null) {
|
|
87544
87768
|
throw new Error(`Failed to extract band information from : ${tiff.source.url.href}`);
|
|
@@ -87550,8 +87774,9 @@ async function computeTiffSummary(target, tiffs) {
|
|
|
87550
87774
|
for (let i = 0; i < bitsPerSample.length; i++) {
|
|
87551
87775
|
const type = getDataType(dataType ? dataType[i] : SampleFormat.Uint);
|
|
87552
87776
|
const bits = bitsPerSample[i];
|
|
87553
|
-
imageBands.push(`${type}${bits}`);
|
|
87777
|
+
imageBands.push({ type: `${type}${bits}` });
|
|
87554
87778
|
}
|
|
87779
|
+
parseGdalMetadata(gdalMetadata, imageBands);
|
|
87555
87780
|
res.bands = ensureBandsSimilar(tiff, res.bands, imageBands);
|
|
87556
87781
|
const imageNoData = noData ? Number(noData) : null;
|
|
87557
87782
|
if (res.noData != null && imageNoData !== res.noData) {
|
|
@@ -87596,6 +87821,62 @@ async function computeTiffSummary(target, tiffs) {
|
|
|
87596
87821
|
throw new Error(`Failed to extract imagery from: ${target.href}`);
|
|
87597
87822
|
return res;
|
|
87598
87823
|
}
|
|
87824
|
+
var MetadataSetter = {
|
|
87825
|
+
COLORINTERP: (val2, meta) => meta.color = val2.toLowerCase(),
|
|
87826
|
+
STATISTICS_MEAN: (val2, meta) => {
|
|
87827
|
+
meta.stats = meta.stats ?? { min: NaN, mean: NaN, max: NaN, stddev: NaN };
|
|
87828
|
+
meta.stats.mean = Number(val2);
|
|
87829
|
+
},
|
|
87830
|
+
STATISTICS_MAXIMUM: (val2, meta) => {
|
|
87831
|
+
meta.stats = meta.stats ?? { min: NaN, mean: NaN, max: NaN, stddev: NaN };
|
|
87832
|
+
meta.stats.max = Number(val2);
|
|
87833
|
+
},
|
|
87834
|
+
STATISTICS_MINIMUM: (val2, meta) => {
|
|
87835
|
+
meta.stats = meta.stats ?? { min: NaN, mean: NaN, max: NaN, stddev: NaN };
|
|
87836
|
+
meta.stats.min = Number(val2);
|
|
87837
|
+
},
|
|
87838
|
+
// Ignored
|
|
87839
|
+
STATISTICS_STDDEV: (val2, meta) => {
|
|
87840
|
+
meta.stats = meta.stats ?? { min: NaN, mean: NaN, max: NaN, stddev: NaN };
|
|
87841
|
+
meta.stats.stddev = Number(val2);
|
|
87842
|
+
},
|
|
87843
|
+
STATISTICS_VALIDPERCENT: () => {
|
|
87844
|
+
}
|
|
87845
|
+
};
|
|
87846
|
+
function parseGdalMetadata(dat, bands, log) {
|
|
87847
|
+
if (dat == null)
|
|
87848
|
+
return;
|
|
87849
|
+
const items = dat.split("\n").map((f) => f.trim()).filter((f) => f.startsWith("<Item"));
|
|
87850
|
+
for (const item of items) {
|
|
87851
|
+
const name = item.match(/name="([A-Z_]+)"/);
|
|
87852
|
+
if (name == null)
|
|
87853
|
+
continue;
|
|
87854
|
+
const sample = item.match(/sample="([0-9]+)"/);
|
|
87855
|
+
if (sample == null)
|
|
87856
|
+
continue;
|
|
87857
|
+
const value = item.match(/>(.*)<\/Item>/);
|
|
87858
|
+
if (value == null)
|
|
87859
|
+
continue;
|
|
87860
|
+
const sampleId = Number(sample[1]);
|
|
87861
|
+
if (isNaN(sampleId))
|
|
87862
|
+
continue;
|
|
87863
|
+
if (bands[sampleId] == null) {
|
|
87864
|
+
log?.warn({ sampleId }, "GdalMetadataParser:InvalidBand");
|
|
87865
|
+
return;
|
|
87866
|
+
}
|
|
87867
|
+
MetadataSetter[name[1]]?.(value[1], bands[sampleId]);
|
|
87868
|
+
if (MetadataSetter[name[1]] == null) {
|
|
87869
|
+
log?.debug({ gdalConfigName: name[1] }, "GdalMetadataParser:UnknownKey:" + name[1]);
|
|
87870
|
+
}
|
|
87871
|
+
}
|
|
87872
|
+
for (const band of bands) {
|
|
87873
|
+
if (band.stats == null)
|
|
87874
|
+
continue;
|
|
87875
|
+
if (isNaN(band.stats?.max) || isNaN(band.stats.min) || isNaN(band.stats.mean)) {
|
|
87876
|
+
delete band.stats;
|
|
87877
|
+
}
|
|
87878
|
+
}
|
|
87879
|
+
}
|
|
87599
87880
|
function toRelative(base, other) {
|
|
87600
87881
|
if (!other.href.startsWith(base.href))
|
|
87601
87882
|
throw new Error("Paths are not relative");
|
|
@@ -87682,6 +87963,7 @@ async function initImageryFromTiffUrl(target, Q3, configCache, log) {
|
|
|
87682
87963
|
const title = stac?.title ?? imageryName;
|
|
87683
87964
|
const tileMatrix = params.projection === EpsgCode.Nztm2000 ? Nztm2000QuadTms : TileMatrixSets.tryGet(params.projection);
|
|
87684
87965
|
const imagery = {
|
|
87966
|
+
v: 2,
|
|
87685
87967
|
id: `im_${sha256base58(target.href)}`,
|
|
87686
87968
|
name: imageryName,
|
|
87687
87969
|
title,
|
|
@@ -87717,7 +87999,8 @@ async function initConfigFromUrls(provider, targets, concurrency = 25, configCac
|
|
|
87717
87999
|
title: "Basemaps",
|
|
87718
88000
|
category: "Basemaps",
|
|
87719
88001
|
type: TileSetType.Raster,
|
|
87720
|
-
layers: []
|
|
88002
|
+
layers: [],
|
|
88003
|
+
outputs: []
|
|
87721
88004
|
};
|
|
87722
88005
|
const elevationTileSet = {
|
|
87723
88006
|
id: "ts_elevation",
|
|
@@ -87763,7 +88046,7 @@ function isRgbOrRgba(img) {
|
|
|
87763
88046
|
if (img.bands.length > 4)
|
|
87764
88047
|
return false;
|
|
87765
88048
|
for (const b of img.bands) {
|
|
87766
|
-
if (b !== "uint8")
|
|
88049
|
+
if (b.type !== "uint8")
|
|
87767
88050
|
return false;
|
|
87768
88051
|
}
|
|
87769
88052
|
return true;
|
|
@@ -88618,7 +88901,11 @@ async function createCog(ctx) {
|
|
|
88618
88901
|
if (tileMatrix == null)
|
|
88619
88902
|
throw new Error("Failed to find tile matrix: " + options.tileMatrix);
|
|
88620
88903
|
logger?.debug({ tileId }, "Cog:Create:VrtSource");
|
|
88621
|
-
|
|
88904
|
+
let addAlpha = false;
|
|
88905
|
+
if (options.presetBands?.includes("alpha") && options.presetBands.length > options.sourceBands.length) {
|
|
88906
|
+
addAlpha = true;
|
|
88907
|
+
}
|
|
88908
|
+
const vrtSourceCommand = gdalBuildVrt(new URL(`${tileId}-source.vrt`, ctx.tempFolder), ctx.sourceFiles, addAlpha);
|
|
88622
88909
|
await new GdalRunner(vrtSourceCommand).run(logger);
|
|
88623
88910
|
logger?.debug({ tileId }, "Cog:Create:VrtWarp");
|
|
88624
88911
|
const cutlineProperties = { url: null, blend: ctx.cutline.blend };
|
|
@@ -88648,10 +88935,11 @@ async function createCog(ctx) {
|
|
|
88648
88935
|
}
|
|
88649
88936
|
const gdalCreateCommand = gdalCreate(new URL(`${tileId}-bg.tiff`, ctx.tempFolder), options.background, options);
|
|
88650
88937
|
await new GdalRunner(gdalCreateCommand).run(logger);
|
|
88651
|
-
const vrtMergeCommand = gdalBuildVrt(
|
|
88652
|
-
|
|
88653
|
-
vrtWarpCommand.output
|
|
88654
|
-
|
|
88938
|
+
const vrtMergeCommand = gdalBuildVrt(
|
|
88939
|
+
new URL(`${tileId}-merged.vrt`, ctx.tempFolder),
|
|
88940
|
+
[gdalCreateCommand.output, vrtWarpCommand.output],
|
|
88941
|
+
false
|
|
88942
|
+
);
|
|
88655
88943
|
await new GdalRunner(vrtMergeCommand).run(logger);
|
|
88656
88944
|
const cogCreateCommand = gdalBuildCog(new URL(`${tileId}.tiff`, ctx.tempFolder), vrtMergeCommand.output, options);
|
|
88657
88945
|
await new GdalRunner(cogCreateCommand).run(logger);
|
|
@@ -88841,10 +89129,16 @@ function getTargetBaseZoom(tileMatrix, resolution, targetZoomOffset) {
|
|
|
88841
89129
|
return Projection.getTiffResZoom(tileMatrix, resolution);
|
|
88842
89130
|
return Projection.getTiffResZoom(tileMatrix, resolution) + targetZoomOffset;
|
|
88843
89131
|
}
|
|
89132
|
+
var TargetZoomOffset = {
|
|
89133
|
+
zstd_17: 6,
|
|
89134
|
+
lzw: 6
|
|
89135
|
+
};
|
|
88844
89136
|
async function createTileCover(ctx) {
|
|
88845
89137
|
await ProjectionLoader.load(ctx.imagery.projection);
|
|
89138
|
+
await ProjectionLoader.load(EpsgCode.Wgs84);
|
|
88846
89139
|
const targetBaseZoom = getTargetBaseZoom(ctx.tileMatrix, ctx.imagery.gsd, ctx.targetZoomOffset);
|
|
88847
|
-
const
|
|
89140
|
+
const targetZoomOffset = TargetZoomOffset[ctx.preset] ?? 7;
|
|
89141
|
+
const optimalCoveringZoom = Math.max(1, targetBaseZoom - targetZoomOffset);
|
|
88848
89142
|
ctx.logger?.debug({ targetBaseZoom, cogOverZoom: optimalCoveringZoom }, "Imagery:ZoomLevel");
|
|
88849
89143
|
const sourceBounds = projectPolygon(
|
|
88850
89144
|
polygonFromBounds(ctx.imagery.files),
|
|
@@ -88881,8 +89175,10 @@ async function createTileCover(ctx) {
|
|
|
88881
89175
|
for (const tile of covering) {
|
|
88882
89176
|
const bounds = ctx.tileMatrix.tileToSourceBounds(tile);
|
|
88883
89177
|
const scaledBounds = bounds.scaleFromCenter(1.05);
|
|
88884
|
-
const
|
|
88885
|
-
|
|
89178
|
+
const projection = Projection.get(ctx.tileMatrix);
|
|
89179
|
+
const wsg84Bounds = multiPolygonToWgs84([scaledBounds.toPolygon()], projection.toWgs84, true);
|
|
89180
|
+
const tileBounds = Projection.get(EpsgCode.Wgs84).projectMultipolygon(
|
|
89181
|
+
wsg84Bounds,
|
|
88886
89182
|
Projection.get(ctx.imagery.projection)
|
|
88887
89183
|
);
|
|
88888
89184
|
const source = imageryBounds.filter((f) => intersection(tileBounds, f.polygon).length > 0);
|
|
@@ -88909,9 +89205,11 @@ async function createTileCover(ctx) {
|
|
|
88909
89205
|
"linz_basemaps:options": {
|
|
88910
89206
|
preset: ctx.preset,
|
|
88911
89207
|
...Presets[ctx.preset].options,
|
|
89208
|
+
presetBands: ctx.presetBands,
|
|
88912
89209
|
tile,
|
|
88913
89210
|
tileMatrix: ctx.tileMatrix.identifier,
|
|
88914
89211
|
sourceEpsg: ctx.imagery.projection,
|
|
89212
|
+
sourceBands: ctx.imagery.bands,
|
|
88915
89213
|
zoomLevel: targetBaseZoom
|
|
88916
89214
|
},
|
|
88917
89215
|
"linz_basemaps:generated": {
|
|
@@ -89027,6 +89325,11 @@ var BasemapsCogifyCoverCommand = (0, import_cmd_ts4.command)({
|
|
|
89027
89325
|
defaultValue: () => "webp",
|
|
89028
89326
|
defaultValueIsSerializable: true
|
|
89029
89327
|
}),
|
|
89328
|
+
presetBand: (0, import_cmd_ts4.option)({
|
|
89329
|
+
type: (0, import_cmd_ts4.optional)((0, import_cmd_ts4.oneOf)(Object.keys(BandPresets))),
|
|
89330
|
+
long: "preset-bands",
|
|
89331
|
+
description: "Tell GDAL what the bands in the source image represent see `-colorinterp` in GDAL"
|
|
89332
|
+
}),
|
|
89030
89333
|
tileMatrix: (0, import_cmd_ts4.option)({
|
|
89031
89334
|
type: import_cmd_ts4.string,
|
|
89032
89335
|
long: "tile-matrix",
|
|
@@ -89052,6 +89355,9 @@ var BasemapsCogifyCoverCommand = (0, import_cmd_ts4.command)({
|
|
|
89052
89355
|
async handler(args) {
|
|
89053
89356
|
const metrics = new Metrics();
|
|
89054
89357
|
const logger = getLogger(this, args, "cli-raster");
|
|
89358
|
+
if (args.presetBand != null && !AllowedPresets[args.preset].includes(args.presetBand)) {
|
|
89359
|
+
throw new Error(`Preset ${args.preset} does not support band option ${args.presetBand}`);
|
|
89360
|
+
}
|
|
89055
89361
|
const mem = new ConfigProviderMemory();
|
|
89056
89362
|
metrics.start("imagery:load");
|
|
89057
89363
|
const cfg = await initConfigFromUrls(mem, args.paths);
|
|
@@ -89060,6 +89366,21 @@ var BasemapsCogifyCoverCommand = (0, import_cmd_ts4.command)({
|
|
|
89060
89366
|
throw new Error("No imagery found");
|
|
89061
89367
|
const im = cfg.imagery[0];
|
|
89062
89368
|
logger.info({ files: im.files.length, title: im.title, duration: imageryLoadTime }, "Imagery:Loaded");
|
|
89369
|
+
if (args.presetBand != null && im.bands != null) {
|
|
89370
|
+
const bandList = BandPresets[args.presetBand];
|
|
89371
|
+
if (bandList && im.bands.length !== bandList.length) {
|
|
89372
|
+
if (bandList.includes("alpha") && im.bands.length === bandList.length - 1) {
|
|
89373
|
+
logger.warn(
|
|
89374
|
+
{ title: im.title, bands: im.bands.length, expectedBands: bandList.length },
|
|
89375
|
+
`Imagery:Bands:MissingAlpha - Adding alpha to source`
|
|
89376
|
+
);
|
|
89377
|
+
} else {
|
|
89378
|
+
throw new Error(
|
|
89379
|
+
`Imagery has ${im.bands.length} bands, preset ${args.presetBand} requires ${bandList.join(", ")}`
|
|
89380
|
+
);
|
|
89381
|
+
}
|
|
89382
|
+
}
|
|
89383
|
+
}
|
|
89063
89384
|
if (im.collection == null && args.requireStacCollection) {
|
|
89064
89385
|
throw new Error(`No collection.json found with imagery: ${im.url.href}`);
|
|
89065
89386
|
}
|
|
@@ -89081,6 +89402,7 @@ var BasemapsCogifyCoverCommand = (0, import_cmd_ts4.command)({
|
|
|
89081
89402
|
metrics,
|
|
89082
89403
|
cutline,
|
|
89083
89404
|
preset: args.preset,
|
|
89405
|
+
presetBands: BandPresets[args.presetBand] ?? void 0,
|
|
89084
89406
|
background: args.background,
|
|
89085
89407
|
targetZoomOffset: args.baseZoomOffset
|
|
89086
89408
|
};
|
|
@@ -89169,12 +89491,12 @@ function extractBoundsFromTiff(tiff, logger) {
|
|
|
89169
89491
|
}
|
|
89170
89492
|
var GeotagToEpsgCode = {
|
|
89171
89493
|
// global
|
|
89172
|
-
"Universal Transverse Mercator Zone":
|
|
89494
|
+
"Universal Transverse Mercator Zone": EpsgCode.Wgs84,
|
|
89173
89495
|
// antarctic
|
|
89174
89496
|
"McMurdo Sound Lambert Conformal 2000": 5479,
|
|
89175
89497
|
// new zealand
|
|
89176
|
-
"
|
|
89177
|
-
"
|
|
89498
|
+
"New Zealand Transverse Mercator 2000": EpsgCode.Nztm2000,
|
|
89499
|
+
"Chatham Islands Transverse Mercator 2000": EpsgCode.Citm2000,
|
|
89178
89500
|
// new zealand offshore islands
|
|
89179
89501
|
"Auckland Islands Transverse Mercator": 3788,
|
|
89180
89502
|
"Campbell Island Transverse Mercator": 3789,
|
|
@@ -89484,6 +89806,7 @@ async function writeStacFiles(target, items, collection, logger) {
|
|
|
89484
89806
|
|
|
89485
89807
|
// src/cogify/cli/cli.topo.ts
|
|
89486
89808
|
var Q2 = pLimit(10);
|
|
89809
|
+
var Format = ["gridded", "gridless"];
|
|
89487
89810
|
var MapSeries = ["topo25", "topo50", "topo250"];
|
|
89488
89811
|
var MapSeriesTitle = {
|
|
89489
89812
|
topo25: "Raster Topographic Maps 25k",
|
|
@@ -89509,7 +89832,12 @@ var TopoStacCreationCommand = (0, import_cmd_ts5.command)({
|
|
|
89509
89832
|
mapSeries: (0, import_cmd_ts5.option)({
|
|
89510
89833
|
type: (0, import_cmd_ts5.oneOf)(MapSeries),
|
|
89511
89834
|
long: "map-series",
|
|
89512
|
-
description: `Map series
|
|
89835
|
+
description: `Map series scale. Either ${MapSeries.join(", ")}`
|
|
89836
|
+
}),
|
|
89837
|
+
format: (0, import_cmd_ts5.option)({
|
|
89838
|
+
type: (0, import_cmd_ts5.oneOf)(Format),
|
|
89839
|
+
long: "format",
|
|
89840
|
+
description: `Map sheet format. Either ${Format.join(", ")}`
|
|
89513
89841
|
}),
|
|
89514
89842
|
latestOnly: (0, import_cmd_ts5.flag)({
|
|
89515
89843
|
type: import_cmd_ts5.boolean,
|
|
@@ -89533,6 +89861,7 @@ var TopoStacCreationCommand = (0, import_cmd_ts5.command)({
|
|
|
89533
89861
|
const startTime = performance.now();
|
|
89534
89862
|
logger.info("TopoCogify:Start");
|
|
89535
89863
|
const mapSeries = args.mapSeries;
|
|
89864
|
+
const format = args.format;
|
|
89536
89865
|
const title = args.title ?? MapSeriesTitle[mapSeries];
|
|
89537
89866
|
const ctx = {
|
|
89538
89867
|
latestOnly: args.latestOnly,
|
|
@@ -89540,6 +89869,7 @@ var TopoStacCreationCommand = (0, import_cmd_ts5.command)({
|
|
|
89540
89869
|
target: args.target,
|
|
89541
89870
|
title,
|
|
89542
89871
|
mapSeries,
|
|
89872
|
+
format,
|
|
89543
89873
|
output: args.output,
|
|
89544
89874
|
logger
|
|
89545
89875
|
};
|
|
@@ -89583,7 +89913,7 @@ async function loadTiffsToCreateStacs(ctx) {
|
|
|
89583
89913
|
const epsgDirectoryPaths = [];
|
|
89584
89914
|
const stacItemPaths = [];
|
|
89585
89915
|
const mapSeries = ctx.mapSeries;
|
|
89586
|
-
const resolution =
|
|
89916
|
+
const resolution = `${ctx.format}_600dpi`;
|
|
89587
89917
|
for (const [epsg, tiffItems] of allTiffItems.entries()) {
|
|
89588
89918
|
logger?.info({ epsg }, "CreateStacFiles:Start");
|
|
89589
89919
|
const latestTiffItems = extractLatestTiffItemsByMapCode(tiffItems);
|