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 {