From 53ebd3b3e9652fccf05a6c3fb5e91fabcb02720d Mon Sep 17 00:00:00 2001 From: acalcutt Date: Wed, 22 Oct 2025 14:29:27 -0400 Subject: [PATCH 1/3] add smoothing options --- package-lock.json | 15 +++---- package.json | 2 +- src/generate-contour-tile-pyramid.ts | 45 ++++++++++++++++--- src/index.ts | 67 +++++++++++++++++++++------- src/mlcontour-adapter.ts | 4 +- 5 files changed, 100 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac82f74..1b417f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,14 +6,14 @@ "packages": { "": { "name": "contour-generator", - "version": "2.0.6", + "version": "2.0.7", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { + "@acalcutt/maplibre-contour": "^0.1.5", "@mapbox/mbtiles": "^0.12.1", "@mapbox/tilebelt": "^2.0.2", "commander": "^12.1.0", - "maplibre-contour": "^0.1.0", "patch-package": "8.0.0", "pmtiles": "^4.1.0", "semver": "^7.7.2", @@ -35,6 +35,11 @@ "typescript-eslint": "^8.19.1" } }, + "node_modules/@acalcutt/maplibre-contour": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@acalcutt/maplibre-contour/-/maplibre-contour-0.1.5.tgz", + "integrity": "sha512-i02+nD4uk3R6XMyHbIl9fcruDZUadPzOdZrC75hUHnnFwAGPOwi2B9xj6yu97VvJ5izAHczXWGqi07fLw+/HsA==" + }, "node_modules/@emnapi/runtime": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", @@ -3625,12 +3630,6 @@ "node": ">= 10" } }, - "node_modules/maplibre-contour": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/maplibre-contour/-/maplibre-contour-0.1.0.tgz", - "integrity": "sha512-H8muT7JWYE4oLbFv7L2RSbIM1NOu5JxjA9P/TQqhODDnRChE8ENoDkQIWOKgfcKNU77ypLk2ggGoh4/pt4UPLA==", - "license": "BSD-3-Clause" - }, "node_modules/matcher": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", diff --git a/package.json b/package.json index 0c20df9..aaac450 100644 --- a/package.json +++ b/package.json @@ -38,10 +38,10 @@ }, "homepage": "https://github.com/acalcutt/contour-generator#readme", "dependencies": { + "@acalcutt/maplibre-contour": "0.1.5", "@mapbox/mbtiles": "^0.12.1", "@mapbox/tilebelt": "^2.0.2", "commander": "^12.1.0", - "maplibre-contour": "^0.1.0", "patch-package": "8.0.0", "pmtiles": "^4.1.0", "semver": "^7.7.2", diff --git a/src/generate-contour-tile-pyramid.ts b/src/generate-contour-tile-pyramid.ts index 3cdd7f8..3c413df 100644 --- a/src/generate-contour-tile-pyramid.ts +++ b/src/generate-contour-tile-pyramid.ts @@ -2,7 +2,7 @@ import { Command } from "commander"; import { writeFileSync, mkdir, existsSync } from "fs"; -import mlcontour from "maplibre-contour"; +import mlcontour from "@acalcutt/maplibre-contour"; import { extractZXYFromUrlTrim, GetImageData, @@ -23,7 +23,7 @@ import { import { getChildren } from "@mapbox/tilebelt"; import path from "path"; -import type { Encoding } from "../node_modules/maplibre-contour/dist/types.d.ts"; +import type { Encoding } from "../node_modules/@acalcutt/maplibre-contour/dist/types.d.ts"; import { type PMTiles } from "pmtiles"; type Tile = [number, number, number]; @@ -85,6 +85,32 @@ program "The image format for generated blank tiles ('png', 'webp', or 'jpeg'). This is used as a fallback if the source format cannot be determined.", "png", // Default format for blank tiles ) + // --- Smoothing Options --- + .option( + "--smooth ", + "Apply smoothing to contour lines: 'none', 'linear', 'chaikin', 'catmull-rom', or 'bezier'.", + (value) => { + const validValues = [ + "none", + "linear", + "chaikin", + "catmull-rom", + "bezier", + ]; + if (!validValues.includes(value)) { + throw new Error( + `Invalid value for --smooth, must be one of: ${validValues.join(", ")}`, + ); + } + return value; + }, + "none", // default value + ) + .option( + "--smoothIterations ", + "Number of times to apply smoothing algorithm (default 1, higher = smoother but more processing).", + "1", // default value as a string + ) // ADD THE VERBOSE OPTION HERE .option("-v, --verbose", "Enable verbose output.") .parse(process.argv); @@ -103,6 +129,8 @@ const { outputDir, blankTileSize, blankTileFormat, + smooth, + smoothIterations, verbose, // Capture the verbose option } = options; @@ -114,6 +142,7 @@ const numsourceMaxZoom = Number(sourceMaxZoom); const numIncrement = Number(increment); const numoutputMaxZoom = Number(outputMaxZoom); const numblankTileSize = Number(blankTileSize); +const numSmoothIterations = Number(smoothIterations); const validBlankTileFormats = ["png", "webp", "jpeg"]; if (!validBlankTileFormats.includes(blankTileFormat)) { @@ -239,7 +268,9 @@ const pmtilesFetcher: TileFetcher = async ( formatForBlank as any, ); return { - data: new Blob([blankTileBuffer], { type: sourceMimeType }), + data: new Blob([new Uint8Array(blankTileBuffer)], { + type: sourceMimeType, + }), mimeType: sourceMimeType, expires: undefined, cacheControl: undefined, @@ -297,7 +328,7 @@ const mbtilesFetcher: TileFetcher = async ( ); const blobType = `image/${sourceFormat}`; return { - data: new Blob([blankTileBuffer], { type: blobType }), + data: new Blob([new Uint8Array(blankTileBuffer)], { type: blobType }), mimeType: blobType, expires: undefined, cacheControl: undefined, @@ -309,7 +340,7 @@ const mbtilesFetcher: TileFetcher = async ( blobType = tileData.contentType; } return { - data: new Blob([tileData.data], { type: blobType }), + data: new Blob([new Uint8Array(tileData.data)], { type: blobType }), mimeType: blobType, expires: undefined, cacheControl: undefined, @@ -333,7 +364,7 @@ const mbtilesFetcher: TileFetcher = async ( ); const blobType = `image/${sourceFormat}`; return { - data: new Blob([blankTileBuffer], { type: blobType }), + data: new Blob([new Uint8Array(blankTileBuffer)], { type: blobType }), mimeType: blobType, expires: undefined, cacheControl: undefined, @@ -393,6 +424,8 @@ const demManagerOptions = { decodeImage: GetImageData, demUrlPattern: demUrlPattern, // Pass the determined pattern getTile: currentFetcher, // Pass the appropriate fetcher function + smooth: smooth as "none" | "linear" | "chaikin" | "catmull-rom" | "bezier", + smoothIterations: numSmoothIterations, }; const manager = demUrlPattern diff --git a/src/index.ts b/src/index.ts index ed845c4..c155a8c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,6 +23,8 @@ type BaseOptions = { blankTileNoDataValue: number; blankTileSize: number; blankTileFormat: string; + smooth: "none" | "linear" | "chaikin" | "catmull-rom" | "bezier"; + smoothIterations: number; }; type PyramidOptions = BaseOptions & { @@ -56,6 +58,18 @@ function validateEncoding( } } +// Helper function to validate smooth +function validateSmooth( + smooth: string, +): asserts smooth is BaseOptions["smooth"] { + const validValues = ["none", "linear", "chaikin", "catmull-rom", "bezier"]; + if (!validValues.includes(smooth)) { + throw new Error( + `Invalid value for --smooth, must be one of: ${validValues.join(", ")}`, + ); + } +} + /** * Function to create metadata.json */ @@ -110,6 +124,7 @@ async function processTile(options: PyramidOptions): Promise { } validateEncoding(options.encoding); + validateSmooth(options.smooth); return new Promise((resolve, reject) => { // Path to the generate-contour-tile-pyramid.js script in the same directory @@ -147,6 +162,10 @@ async function processTile(options: PyramidOptions): Promise { options.blankTileSize.toString(), "--blankTileFormat", options.blankTileFormat, + "--smooth", + options.smooth, + "--smoothIterations", + options.smoothIterations.toString(), ]; // Pass the verbose flag down to the child process ONLY if the orchestrator is verbose @@ -168,19 +187,9 @@ async function processTile(options: PyramidOptions): Promise { workerProcess.stdout.on("data", (data) => { stdoutBuffer += data.toString(); // Process captured output if orchestrator is verbose. - // We trust the child process to handle its own verbose output; this capture - // is mainly for potential error logging or if the child isn't verbose. if (options.verbose) { const lines = stdoutBuffer.split("\n"); stdoutBuffer = lines.pop() || ""; // Keep the last (potentially partial) line - // Log with orchestrator's prefix, but only if it's not already verbose output from child - // This is still tricky. The robust solution is to NOT log here and let the child's verbose logs appear. - // However, for debugging purposes, logging captured data is useful. - // The duplicate "Starting..." and "Finished..." are from the orchestrator's own handlers. - // We should avoid double-logging the CHILD's output. - // - // For now, let's keep the logging here, but be aware it might duplicate child's --verbose output. - // The FIX for the "Starting..." and "Finished..." duplication is in the orchestrator handlers themselves. lines.forEach((line) => console.log(processPrefix + line.trim())); } }); @@ -419,13 +428,11 @@ async function main(): Promise { | ParsedOptionConfig; const commonOptionConfigs: OptionConfig[] = [ - // required options { type: "required", flags: "--demUrl ", description: "The URL of the DEM source.", }, - // standard options (string/boolean only) { type: "standard", flags: "--encoding ", @@ -452,7 +459,6 @@ async function main(): Promise { description: "Enable verbose output", defaultValue: false, }, - // parsed options (numbers that need parsing) { type: "parsed", flags: "--sourceMaxZoom ", @@ -496,6 +502,21 @@ async function main(): Promise { parser: Number, defaultValue: 512, }, + { + type: "standard", + flags: "--smooth ", + description: + "Apply smoothing to contour lines: 'none', 'linear', 'chaikin', 'catmull-rom', or 'bezier'.", + defaultValue: "none", + }, + { + type: "parsed", + flags: "--smoothIterations ", + description: + "Number of times to apply smoothing algorithm (default 1, higher = smoother but more processing).", + parser: Number, + defaultValue: 1, + }, ]; // --- Pyramid Command --- @@ -578,8 +599,22 @@ async function main(): Promise { config.defaultValue, ); } else { - // This is a StandardOptionConfig - string/boolean only - command.option(config.flags, config.description, config.defaultValue); + // This handles StandardOptionConfig (string/boolean only) + if (config.flags.startsWith("--smooth")) { + // Custom parser for smooth option + command.option( + config.flags, + config.description, + (value) => { + validateSmooth(value); + return value; + }, + config.defaultValue, + ); + } else { + // Standard string/boolean options + command.option(config.flags, config.description, config.defaultValue); + } } } }; @@ -591,7 +626,7 @@ async function main(): Promise { // --- Set up action handlers (after options are defined) --- pyramidCmd.action(async (options: PyramidOptions) => { - await runPyramid(options); + await runPyramid(options as Required); }); zoomCmd.action(async (options: ZoomOptions) => { diff --git a/src/mlcontour-adapter.ts b/src/mlcontour-adapter.ts index 2fc47d3..550632d 100644 --- a/src/mlcontour-adapter.ts +++ b/src/mlcontour-adapter.ts @@ -1,10 +1,10 @@ import sharp from "sharp"; -import mlcontour from "maplibre-contour"; +import mlcontour from "@acalcutt/maplibre-contour"; import type { DemTile, Encoding, GlobalContourTileOptions, -} from "../node_modules/maplibre-contour/dist/types.d.ts"; +} from "../node_modules/@acalcutt/maplibre-contour/dist/types.d.ts"; // Constants for Encoding const TERRARIUM_MULT = 256; From f1eba955ea1ec4df8a2e79b5a08ff1d6ca35773c Mon Sep 17 00:00:00 2001 From: acalcutt Date: Wed, 22 Oct 2025 16:56:31 -0400 Subject: [PATCH 2/3] remove patch package, no longer needed @acalcutt/maplibre-contour includes these, and they have been merged into main --- package-lock.json | 473 +-------------------------- package.json | 4 - patches/maplibre-contour+0.1.0.patch | 58 ---- 3 files changed, 11 insertions(+), 524 deletions(-) delete mode 100644 patches/maplibre-contour+0.1.0.patch diff --git a/package-lock.json b/package-lock.json index 1b417f8..55550d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,14 +7,12 @@ "": { "name": "contour-generator", "version": "2.0.7", - "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { - "@acalcutt/maplibre-contour": "^0.1.5", + "@acalcutt/maplibre-contour": "0.1.5", "@mapbox/mbtiles": "^0.12.1", "@mapbox/tilebelt": "^2.0.2", "commander": "^12.1.0", - "patch-package": "8.0.0", "pmtiles": "^4.1.0", "semver": "^7.7.2", "sharp": "^0.33.5", @@ -27,7 +25,6 @@ "@types/node": "^22.10.2", "eslint": "^9.17.0", "eslint-config-prettier": "^9.1.0", - "patch-package": "^8.0.0", "prettier": "^3.4.2", "rimraf": "^6.0.1", "shellcheck": "^3.0.0", @@ -1477,13 +1474,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true, - "license": "BSD-2-Clause" - }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -1640,16 +1630,6 @@ "dev": true, "license": "Python-2.0" }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1824,56 +1804,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1909,22 +1839,6 @@ "node": ">=10" } }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -2227,21 +2141,6 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -2327,19 +2226,6 @@ "node": ">= 0.4" } }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -2746,16 +2632,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "micromatch": "^4.0.2" - } - }, "node_modules/flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", @@ -2810,22 +2686,6 @@ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -2842,8 +2702,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "devOptional": true, - "license": "ISC" + "license": "ISC", + "optional": true }, "node_modules/fsevents": { "version": "2.3.3", @@ -2858,16 +2718,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/gauge": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", @@ -2889,45 +2739,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/get-stream": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", @@ -2963,8 +2774,8 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", - "devOptional": true, "license": "ISC", + "optional": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2996,8 +2807,8 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "devOptional": true, "license": "MIT", + "optional": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3007,8 +2818,8 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "devOptional": true, "license": "ISC", + "optional": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -3107,19 +2918,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -3127,19 +2925,6 @@ "license": "ISC", "optional": true }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/http-cache-semantics": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", @@ -3275,8 +3060,8 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "devOptional": true, "license": "ISC", + "optional": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -3308,22 +3093,6 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3386,19 +3155,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -3453,68 +3209,18 @@ "dev": true, "license": "MIT" }, - "node_modules/json-stable-stringify": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz", - "integrity": "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "isarray": "^2.0.5", - "jsonify": "^0.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/json-stable-stringify/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "license": "MIT" - }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, - "node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", - "dev": true, - "license": "Public Domain", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -3524,16 +3230,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.11" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -3642,16 +3338,6 @@ "node": ">=10" } }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3970,23 +3656,6 @@ "wrappy": "1" } }, - "node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -4004,16 +3673,6 @@ "node": ">= 0.8.0" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4080,51 +3739,6 @@ "node": ">=6" } }, - "node_modules/patch-package": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", - "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^4.1.2", - "ci-info": "^3.7.0", - "cross-spawn": "^7.0.3", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", - "json-stable-stringify": "^1.0.2", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.6", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^7.5.3", - "slash": "^2.0.0", - "tmp": "^0.0.33", - "yaml": "^2.2.2" - }, - "bin": { - "patch-package": "index.js" - }, - "engines": { - "node": ">=14", - "npm": ">5" - } - }, - "node_modules/patch-package/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4138,8 +3752,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "devOptional": true, "license": "MIT", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -4641,24 +4255,6 @@ "license": "ISC", "optional": true }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/sharp": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", @@ -4795,16 +4391,6 @@ "is-arrayish": "^0.3.1" } }, - "node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -5012,10 +4598,9 @@ } }, "node_modules/tar-fs": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", - "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", - "license": "MIT", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -5103,19 +4688,6 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", @@ -5278,16 +4850,6 @@ "imurmurhash": "^0.1.4" } }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -5461,19 +5023,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "license": "ISC" }, - "node_modules/yaml": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", - "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", - "dev": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - } - }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", diff --git a/package.json b/package.json index aaac450..8e48a6a 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,8 @@ }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "patch": "patch-package", "build": "rimraf dist && tsc", "prepare": "npm run build", - "postinstall": "npm run patch", "format": "prettier --write \"**/*.{ts,js,json}\"", "lint": "eslint \"**/*.{ts,js}\"", "check": "npm run format && npm run lint" @@ -42,7 +40,6 @@ "@mapbox/mbtiles": "^0.12.1", "@mapbox/tilebelt": "^2.0.2", "commander": "^12.1.0", - "patch-package": "8.0.0", "pmtiles": "^4.1.0", "semver": "^7.7.2", "sharp": "^0.33.5", @@ -52,7 +49,6 @@ "@types/node": "^22.10.2", "eslint": "^9.17.0", "eslint-config-prettier": "^9.1.0", - "patch-package": "^8.0.0", "prettier": "^3.4.2", "rimraf": "^6.0.1", "shellcheck": "^3.0.0", diff --git a/patches/maplibre-contour+0.1.0.patch b/patches/maplibre-contour+0.1.0.patch deleted file mode 100644 index 5aac513..0000000 --- a/patches/maplibre-contour+0.1.0.patch +++ /dev/null @@ -1,58 +0,0 @@ -diff --git a/node_modules/maplibre-contour/package.json b/node_modules/maplibre-contour/package.json -index 1234567..abcdefg 100644 ---- a/node_modules/maplibre-contour/package.json -+++ b/node_modules/maplibre-contour/package.json -@@ -7,6 +7,7 @@ - "module": "dist/index.mjs", - "types": "dist/index.d.ts", - "exports": { -+ "default": "./dist/index.mjs", - "module": "./dist/index.mjs", - "require": "./dist/index.cjs", - "types": "./dist/index.d.ts", -diff --git a/node_modules/maplibre-contour/dist/index.mjs b/node_modules/maplibre-contour/dist/index.mjs -index 2345678..bcdefgh 100644 ---- a/node_modules/maplibre-contour/dist/index.mjs -+++ b/node_modules/maplibre-contour/dist/index.mjs -@@ -2077,7 +2077,7 @@ class LocalDemManager { - }, - }); - mark === null || mark === void 0 ? void 0 : mark(); -- return { arrayBuffer: result.buffer }; -+ return { arrayBuffer: result.slice().buffer }; - }), parentAbortController); - } - } -diff --git a/node_modules/maplibre-contour/dist/index.mjs b/node_modules/maplibre-contour/dist/index.mjs -index 2345678..bcdefgh 100644 ---- a/node_modules/maplibre-contour/dist/index.mjs -+++ b/node_modules/maplibre-contour/dist/index.mjs -@@ -1724,9 +1724,8 @@ function encodeVectorTile(tile) { - function writeLayer(layer, pbf) { - if (!pbf) - throw new Error("pbf undefined"); -- pbf.writeVarintField(15, 2); -- pbf.writeStringField(1, layer.id || ""); -- pbf.writeVarintField(5, layer.extent || 4096); -+ pbf.writeStringField(1, layer.id || ""); // name (required, field 1) -+ // Write all features (field 2) - const context = { - keys: [], - values: [], -@@ -1737,12 +1736,16 @@ function writeLayer(layer, pbf) { - context.feature = feature; - pbf.writeMessage(2, writeFeature, context); - } -+ // Write all keys (field 3) - for (const key of context.keys) { - pbf.writeStringField(3, key); - } -+ // Write all values (field 4) - for (const value of context.values) { - pbf.writeMessage(4, writeValue, value); - } -+ pbf.writeVarintField(5, layer.extent || 4096); // extent (field 5) -+ pbf.writeVarintField(15, 2); // version (field 15, LAST) - } - function writeFeature(context, pbf) { - const feature = context.feature; From d64a02dbcb5d5c327a64c27dae04cc6f263537ae Mon Sep 17 00:00:00 2001 From: acalcutt Date: Wed, 22 Oct 2025 17:15:53 -0400 Subject: [PATCH 3/3] change validation --- CHANGELOG.md | 3 ++ src/index.ts | 111 +++++++++++++++++++++------------------------------ 2 files changed, 48 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ce5318..3f3dc7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,5 @@ +## 2.1.0 +*add smoothing options 'smooth' and 'smoothIterations' + ## 2.0.7 * Test Release \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index c155a8c..344415b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,31 +45,6 @@ type BboxOptions = BaseOptions & { outputMinZoom: number; }; -/** - * Helper function to validate encoding - */ -function validateEncoding( - encoding: string, -): asserts encoding is "mapbox" | "terrarium" { - if (encoding !== "mapbox" && encoding !== "terrarium") { - throw new Error( - `Encoding must be either "mapbox" or "terrarium", got ${encoding}`, - ); - } -} - -// Helper function to validate smooth -function validateSmooth( - smooth: string, -): asserts smooth is BaseOptions["smooth"] { - const validValues = ["none", "linear", "chaikin", "catmull-rom", "bezier"]; - if (!validValues.includes(smooth)) { - throw new Error( - `Invalid value for --smooth, must be one of: ${validValues.join(", ")}`, - ); - } -} - /** * Function to create metadata.json */ @@ -123,9 +98,6 @@ async function processTile(options: PyramidOptions): Promise { ); } - validateEncoding(options.encoding); - validateSmooth(options.smooth); - return new Promise((resolve, reject) => { // Path to the generate-contour-tile-pyramid.js script in the same directory const scriptPath = path.join(__dirname, "generate-contour-tile-pyramid.js"); @@ -168,28 +140,26 @@ async function processTile(options: PyramidOptions): Promise { options.smoothIterations.toString(), ]; - // Pass the verbose flag down to the child process ONLY if the orchestrator is verbose if (options.verbose) { commandArgs.push("--verbose"); // Pass the verbose flag to the child } const workerProcess = spawn("node", commandArgs, { stdio: ["ignore", "pipe", "pipe"], // Capture stdout and stderr - shell: true, // Use false for better security and performance + shell: true, }); const processPrefix = `[Tile ${options.z}-${options.x}-${options.y}] `; - // Buffering for verbose output to prevent flooding the console and consuming excessive memory + // Buffering for verbose output let stdoutBuffer = ""; let stderrBuffer = ""; workerProcess.stdout.on("data", (data) => { stdoutBuffer += data.toString(); - // Process captured output if orchestrator is verbose. if (options.verbose) { const lines = stdoutBuffer.split("\n"); - stdoutBuffer = lines.pop() || ""; // Keep the last (potentially partial) line + stdoutBuffer = lines.pop() || ""; lines.forEach((line) => console.log(processPrefix + line.trim())); } }); @@ -204,7 +174,6 @@ async function processTile(options: PyramidOptions): Promise { }); workerProcess.on("close", (code) => { - // Flush any remaining buffered data if verbose, primarily for error reporting if (options.verbose) { if (stdoutBuffer) console.log(processPrefix + stdoutBuffer.trim()); if (stderrBuffer) console.error(processPrefix + stderrBuffer.trim()); @@ -212,11 +181,10 @@ async function processTile(options: PyramidOptions): Promise { if (code === 0) { if (options.verbose) { - console.log(processPrefix + "Finished successfully."); // Orchestrator's own status message + console.log(processPrefix + "Finished successfully."); } resolve(); } else { - // Reject with a more informative error, including stderr content reject( new Error( `${processPrefix}Exited with code ${code}. Captured stderr: "${stderrBuffer.trim()}"`, @@ -236,9 +204,6 @@ async function processTile(options: PyramidOptions): Promise { /** * Manages a pool of worker processes to execute tasks concurrently, * ensuring no more than `maxProcesses` are running at any time. - * @param coordinates - Array of [z, x, y] tuples representing tiles to process. - * @param options - Base options to pass to each tile processing job. - * @param maxProcesses - The maximum number of parallel processes to run. */ async function processTilesInParallel( coordinates: Array<[number, number, number]>, @@ -261,13 +226,11 @@ async function processTilesInParallel( return new Promise((resolve, reject) => { const scheduleNextTile = () => { - // If all tasks are assigned and all active workers have finished, we are done. if (currentIndex >= totalTiles && activeWorkers.length === 0) { console.log(`[Main] All ${totalTiles} tiles processed.`); return resolve(); } - // While we have tasks left and the number of active workers is below the limit while (currentIndex < totalTiles && activeWorkers.length < maxProcesses) { const [z, x, y] = coordinates[currentIndex]; const tileOptions: PyramidOptions = { @@ -285,7 +248,6 @@ async function processTilesInParallel( ); } - // Create a promise for this tile's processing const tilePromise = processTile(tileOptions) .then(() => { completedCount++; @@ -300,15 +262,13 @@ async function processTilesInParallel( `[Main] Error processing tile ${z}-${x}-${y}:`, error, ); - reject(error); // Reject the main promise if any tile fails + reject(error); }) .finally(() => { - // Remove this worker from the active pool const index = activeWorkers.indexOf(tilePromise); if (index > -1) { activeWorkers.splice(index, 1); } - // Try to schedule the next available tile scheduleNextTile(); }); @@ -316,7 +276,6 @@ async function processTilesInParallel( } }; - // Start the initial batch of workers scheduleNextTile(); }); } @@ -422,22 +381,41 @@ async function main(): Promise { defaultValue: number; }; + type CustomParserOptionConfig = { + type: "custom-parser"; + flags: string; + description: string; + parser: (value: string) => string; + defaultValue: string; + }; + type OptionConfig = | RequiredOptionConfig | StandardOptionConfig - | ParsedOptionConfig; + | ParsedOptionConfig + | CustomParserOptionConfig; const commonOptionConfigs: OptionConfig[] = [ + // required options { type: "required", flags: "--demUrl ", description: "The URL of the DEM source.", }, + // standard options (string/boolean only) { - type: "standard", + type: "custom-parser", flags: "--encoding ", description: 'The encoding of the source DEM (e.g., "terrarium", "mapbox").', + parser: (value: string) => { + if (value !== "mapbox" && value !== "terrarium") { + throw new Error( + `Encoding must be either "mapbox" or "terrarium", got ${value}`, + ); + } + return value; + }, defaultValue: "mapbox", }, { @@ -459,6 +437,7 @@ async function main(): Promise { description: "Enable verbose output", defaultValue: false, }, + // parsed options (numbers that need parsing) { type: "parsed", flags: "--sourceMaxZoom ", @@ -503,10 +482,25 @@ async function main(): Promise { defaultValue: 512, }, { - type: "standard", + type: "custom-parser", flags: "--smooth ", description: "Apply smoothing to contour lines: 'none', 'linear', 'chaikin', 'catmull-rom', or 'bezier'.", + parser: (value: string) => { + const validValues = [ + "none", + "linear", + "chaikin", + "catmull-rom", + "bezier", + ]; + if (!validValues.includes(value)) { + throw new Error( + `Invalid value for --smooth, must be one of: ${validValues.join(", ")}`, + ); + } + return value; + }, defaultValue: "none", }, { @@ -590,8 +584,7 @@ async function main(): Promise { for (const config of configs) { if (config.type === "required") { command.requiredOption(config.flags, config.description); - } else if (config.type === "parsed") { - // This is a ParsedOptionConfig - needs parser + } else if (config.type === "parsed" || config.type === "custom-parser") { command.option( config.flags, config.description, @@ -600,21 +593,7 @@ async function main(): Promise { ); } else { // This handles StandardOptionConfig (string/boolean only) - if (config.flags.startsWith("--smooth")) { - // Custom parser for smooth option - command.option( - config.flags, - config.description, - (value) => { - validateSmooth(value); - return value; - }, - config.defaultValue, - ); - } else { - // Standard string/boolean options - command.option(config.flags, config.description, config.defaultValue); - } + command.option(config.flags, config.description, config.defaultValue); } } };