From bd3357e5c6dee34a6e458a2ac956643468f8fb2c Mon Sep 17 00:00:00 2001 From: Wentao Kuang Date: Fri, 6 Dec 2024 09:54:43 +1300 Subject: [PATCH] feat(config): Add resizeKernel into the config tileset then disable fastShrinkOnLoad. BM-1146 (#3377) ### Motivation As raster Topo map got edge effects on low zoom levels usually below zoom 6, like following. ![image](https://github.com/user-attachments/assets/44a0e388-a00b-4d70-bfda-62414930dab8) We have tests that with output resize kernel of `mitchell` and disable the fastShrinkOnLoad for lower scales levels will fix this problem. ![image](https://github.com/user-attachments/assets/dcf1af02-16b8-4738-81b7-dc4c5ef255ab) ### Modifications - Add the resiseKernel setting in the config bundle, so that we can bundle it into server. - disable `fastShrinkOnLoad` for the `resize.scale`less than 0.125. - Not fix yet: The virtual tileset for `topo-raster-50k` and `topo-raster-250k` won't fix as we can't propagate the resize kernel from combined tileset -> imagery config -> virtual tileset. Unless we add optional resizeKernal property for imagery config. ### Verification Local test. ![image](https://github.com/user-attachments/assets/4a15d740-46c7-4592-a238-35864b701b77) --- packages/config-loader/src/json/json.config.ts | 1 + packages/config-loader/src/json/parse.tile.set.ts | 5 ++++- packages/config/src/config/tile.set.ts | 2 +- packages/tiler-sharp/src/index.ts | 7 ++++++- packages/tiler/src/raster.ts | 2 +- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/config-loader/src/json/json.config.ts b/packages/config-loader/src/json/json.config.ts index bd4eb7111..c328583b9 100644 --- a/packages/config-loader/src/json/json.config.ts +++ b/packages/config-loader/src/json/json.config.ts @@ -247,6 +247,7 @@ export class ConfigJson { if (tileSet.type === TileSetType.Raster) { if (ts.outputs) tileSet.outputs = ts.outputs; if (ts.background) tileSet.background = ts.background; + if (ts.resizeKernel) tileSet.resizeKernel = ts.resizeKernel; } if (ts.format) { diff --git a/packages/config-loader/src/json/parse.tile.set.ts b/packages/config-loader/src/json/parse.tile.set.ts index 040c08e99..2a641df6d 100644 --- a/packages/config-loader/src/json/parse.tile.set.ts +++ b/packages/config-loader/src/json/parse.tile.set.ts @@ -1,4 +1,4 @@ -import { ConfigTileSetOutputParser, parseRgba, TileSetType } from '@basemaps/config'; +import { ConfigTileSetOutputParser, parseRgba, TileResizeKernel, TileSetType } from '@basemaps/config'; import { z } from 'zod'; export function validateColor(str: string): boolean { @@ -57,6 +57,8 @@ const zLayerConfig = z }, ); +const TileResizeKernel = z.enum(['nearest', 'mitchell', 'lanczos3', 'lanczos2']); + export const zTileSetConfig = z.object({ type: z.nativeEnum(TileSetType), id: z.string(), @@ -68,6 +70,7 @@ export const zTileSetConfig = z.object({ minZoom: zZoom.optional(), maxZoom: zZoom.optional(), format: z.string().optional(), + resizeKernel: z.object({ in: TileResizeKernel, out: TileResizeKernel }).optional(), outputs: z.array(ConfigTileSetOutputParser).optional(), }); diff --git a/packages/config/src/config/tile.set.ts b/packages/config/src/config/tile.set.ts index 07aa1e505..0642f62f3 100644 --- a/packages/config/src/config/tile.set.ts +++ b/packages/config/src/config/tile.set.ts @@ -31,7 +31,7 @@ export interface ConfigLayer extends Partial> { maxZoom?: number; } -export type TileResizeKernel = 'nearest' | 'lanczos3' | 'lanczos2'; +export type TileResizeKernel = 'nearest' | 'mitchell' | 'lanczos3' | 'lanczos2'; export interface ConfigTileSetBase extends ConfigBase { /** Human friendly display name for the tileset */ diff --git a/packages/tiler-sharp/src/index.ts b/packages/tiler-sharp/src/index.ts index 6ae79bcf1..ca98880af 100644 --- a/packages/tiler-sharp/src/index.ts +++ b/packages/tiler-sharp/src/index.ts @@ -144,7 +144,12 @@ export class TileMakerSharp implements TileMaker { if (resize) { const resizeOptions = { fit: Sharp.fit.cover, kernel: resize.scaleX > 1 ? resizeKernel.in : resizeKernel.out }; - sharp.resize(resize.width, resize.height, resizeOptions); + if (resize.scale <= 0.1251) { + // If the scale is less than 0.125, we need to disable fastShrinkOnLoad to prevent edge artifacts for topo raster map + sharp.resize(resize.width, resize.height, { ...resizeOptions, fastShrinkOnLoad: false }); + } else { + sharp.resize(resize.width, resize.height, resizeOptions); + } } if (crop) sharp.extract({ top: crop.y, left: crop.x, width: crop.width, height: crop.height }); diff --git a/packages/tiler/src/raster.ts b/packages/tiler/src/raster.ts index 7278549b7..4ad658628 100644 --- a/packages/tiler/src/raster.ts +++ b/packages/tiler/src/raster.ts @@ -7,7 +7,7 @@ export interface TileMaker { compose(ctx: TileMakerContext): Promise<{ buffer: Buffer; metrics: Metrics }>; } -export type ResizeKernelType = 'nearest' | 'lanczos3' | 'lanczos2'; +export type ResizeKernelType = 'nearest' | 'mitchell' | 'lanczos3' | 'lanczos2'; export type TileMakerResizeKernel = { in: ResizeKernelType; out: ResizeKernelType }; export interface TileMakerContext {