From d721141ad62a1929d58928efff309b31c74e8389 Mon Sep 17 00:00:00 2001 From: Wentao Kuang Date: Thu, 12 Dec 2024 16:16:13 +1300 Subject: [PATCH] Move the background to create cover and stac item. --- .../src/cogify/cli/__test__/cli.cover.test.ts | 3 +-- packages/cogify/src/cogify/cli/cli.cog.ts | 23 ++----------------- packages/cogify/src/cogify/cli/cli.cover.ts | 20 +++++++++++++++- packages/cogify/src/tile.cover.ts | 6 +++++ 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/packages/cogify/src/cogify/cli/__test__/cli.cover.test.ts b/packages/cogify/src/cogify/cli/__test__/cli.cover.test.ts index 85941baa37..ad5115f1a9 100644 --- a/packages/cogify/src/cogify/cli/__test__/cli.cover.test.ts +++ b/packages/cogify/src/cogify/cli/__test__/cli.cover.test.ts @@ -23,13 +23,13 @@ describe('cli.cover', () => { target: new URL('memory://target/'), preset: 'webp', tileMatrix: 'WebMercatorQuad', - cutline: undefined, cutlineBlend: 20, baseZoomOffset: undefined, verbose: false, extraVerbose: false, requireStacCollection: false, + background: undefined, }; it('should generate a covering', async () => { @@ -50,7 +50,6 @@ describe('cli.cover', () => { paths: [new URL('memory://source/')], target: new URL('memory://target/'), preset: 'webp', - requireStacCollection: true, tileMatrix: 'WebMercatorQuad', }).catch((e) => String(e)); diff --git a/packages/cogify/src/cogify/cli/cli.cog.ts b/packages/cogify/src/cogify/cli/cli.cog.ts index bfe6f9fbe0..44018a1136 100644 --- a/packages/cogify/src/cogify/cli/cli.cog.ts +++ b/packages/cogify/src/cogify/cli/cli.cog.ts @@ -3,7 +3,7 @@ import { Projection, ProjectionLoader, TileId, TileMatrixSet, TileMatrixSets } f import { fsa, LogType, stringToUrlFolder, Tiff } from '@basemaps/shared'; import { CliId, CliInfo } from '@basemaps/shared/build/cli/info.js'; import { Metrics } from '@linzjs/metrics'; -import { command, flag, number, option, optional, restPositionals, string } from 'cmd-ts'; +import { command, flag, number, option, optional, restPositionals } from 'cmd-ts'; import { mkdir, rm } from 'fs/promises'; import { tmpdir } from 'os'; import pLimit from 'p-limit'; @@ -18,22 +18,12 @@ import { getLogger, logArguments } from '../../log.js'; import { gdalBuildCog, gdalBuildVrt, gdalBuildVrtWarp, gdalCreate } from '../gdal.command.js'; import { GdalRunner } from '../gdal.runner.js'; import { Url, UrlArrayJsonFile } from '../parsers.js'; -import { Background, CogifyCreationOptions, CogifyStacItem, getCutline, getSources } from '../stac.js'; +import { CogifyCreationOptions, CogifyStacItem, getCutline, getSources } from '../stac.js'; function extractSourceFiles(item: CogifyStacItem, baseUrl: URL): URL[] { return item.links.filter((link) => link.rel === 'linz_basemaps:source').map((link) => new URL(link.href, baseUrl)); } -function parseBackgroud(background: string): Background { - const parts = background.split(',').map((f) => { - const value = parseInt(f); - if (value < 0 || value > 255) throw new Error('Invalid rgba number'); - return value; - }); - if (parts.length !== 4) throw new Error('Invalid background format'); - return { r: parts[0], g: parts[1], b: parts[2], alpha: parts[3] }; -} - const Collections = new Map>(); export interface CogItem { @@ -82,11 +72,6 @@ export const BasemapsCogifyCreateCommand = command({ defaultValue: () => 4, defaultValueIsSerializable: true, }), - background: option({ - type: optional(string), - long: 'background', - description: 'Background rbga color to fill empty space in the COG' + 'Format: "r,g,b,a" eg "255,0,0,0.5"', - }), docker: flag({ long: 'docker', description: 'Run GDAL inside docker container' }), fromFile: option({ type: optional(UrlArrayJsonFile), @@ -102,7 +87,6 @@ export const BasemapsCogifyCreateCommand = command({ const logger = getLogger(this, args); if (args.docker) process.env['GDAL_DOCKER'] = '1'; - const background = args.background ? parseBackgroud(args.background) : undefined; const paths = args.fromFile != null ? args.path.concat(args.fromFile) : args.path; const toCreate = await Promise.all(paths.map(async (p) => loadItem(p, logger))); @@ -173,9 +157,6 @@ export const BasemapsCogifyCreateCommand = command({ const options = item.properties['linz_basemaps:options']; const tileId = TileId.fromTile(options.tile); - // Forces background if defined. - if (background) options.background = background; - // Location to where the tiff should be stored const tiffPath = new URL(tileId + '.tiff', url); const itemStacPath = new URL(tileId + '.json', url); diff --git a/packages/cogify/src/cogify/cli/cli.cover.ts b/packages/cogify/src/cogify/cli/cli.cover.ts index 3cbd33c9af..c27d9d4b77 100644 --- a/packages/cogify/src/cogify/cli/cli.cover.ts +++ b/packages/cogify/src/cogify/cli/cli.cover.ts @@ -12,7 +12,7 @@ import { getLogger, logArguments } from '../../log.js'; import { Presets } from '../../preset.js'; import { createTileCover, TileCoverContext } from '../../tile.cover.js'; import { Url, UrlFolder } from '../parsers.js'; -import { createFileStats } from '../stac.js'; +import { Background, createFileStats } from '../stac.js'; const SupportedTileMatrix = [GoogleTms, Nztm2000QuadTms]; @@ -23,6 +23,17 @@ export function gsdToMeter(gsd: number): number { return parseFloat(gsd.toFixed(3)); } +// parse background color from string "r,g,b,a" +function parseBackgroud(background: string): Background { + const parts = background.split(',').map((f) => { + const value = parseInt(f); + if (value < 0 || value > 255) throw new Error('Invalid rgba number'); + return value; + }); + if (parts.length !== 4) throw new Error('Invalid background format'); + return { r: parts[0], g: parts[1], b: parts[2], alpha: parts[3] }; +} + export const BasemapsCogifyCoverCommand = command({ name: 'cogify-cover', version: CliInfo.version, @@ -62,6 +73,11 @@ export const BasemapsCogifyCoverCommand = command({ defaultValue: () => false, defaultValueIsSerializable: true, }), + background: option({ + type: optional(string), + long: 'background', + description: 'Background rbga color to fill empty space in the COG' + 'Format: "r,g,b,a" eg "255,0,0,0.5"', + }), }, async handler(args) { const metrics = new Metrics(); @@ -69,6 +85,7 @@ export const BasemapsCogifyCoverCommand = command({ const mem = new ConfigProviderMemory(); metrics.start('imagery:load'); + const background = args.background ? parseBackgroud(args.background) : undefined; const cfg = await initConfigFromUrls(mem, args.paths); const imageryLoadTime = metrics.end('imagery:load'); if (cfg.imagery.length === 0) throw new Error('No imagery found'); @@ -95,6 +112,7 @@ export const BasemapsCogifyCoverCommand = command({ metrics, cutline, preset: args.preset, + background, targetZoomOffset: args.baseZoomOffset, }; diff --git a/packages/cogify/src/tile.cover.ts b/packages/cogify/src/tile.cover.ts index e7cc125250..9d42f2209a 100644 --- a/packages/cogify/src/tile.cover.ts +++ b/packages/cogify/src/tile.cover.ts @@ -8,6 +8,7 @@ import { GeoJSONPolygon } from 'stac-ts/src/types/geojson.js'; import { createCovering } from './cogify/covering.js'; import { + Background, CogifyLinkCutline, CogifyLinkSource, CogifyStacCollection, @@ -32,6 +33,8 @@ export interface TileCoverContext { logger?: LogType; /** GDAL configuration preset */ preset: string; + /** Optional configuration for adding background for the target cog */ + background?: Background; /** * Override the base zoom to store the output COGS as */ @@ -180,6 +183,9 @@ export async function createTileCover(ctx: TileCoverContext): Promise