import { spawn } from "child_process" import { Tiles } from "../src/Models/TileRange" export class PmTilesExtractGenerator { private readonly _targetDir: string private readonly _sourceFile: string private readonly _executeableLocation: string constructor( sourceFile: string, targetDir: string, executeableLocation: string = "/data/pmtiles" ) { this._sourceFile = sourceFile this._targetDir = targetDir this._executeableLocation = executeableLocation } startProcess(script: string, captureStdioChunks?: (string: string) => void): Promise { return new Promise((resolve, reject) => { const child = spawn(this._executeableLocation, script.split(" "), { stdio: captureStdioChunks === undefined ? "ignore" : ["pipe", "pipe", "pipe"], cwd: this._targetDir, }) if (captureStdioChunks !== undefined) { child.stdout.on("data", (data) => { captureStdioChunks(data) }) } /*child.stderr.on('data', data => { console.error(`stderr: ${data}`); });*/ child.on("close", (code) => { if (code === 0) resolve() else reject(new Error(`Process exited with code ${code}`)) }) child.on("error", reject) }) } getFilename(z: number, x: number, y: number) { return `${this._targetDir}/${z}/${x}/${y}.pmtiles` } async generateArchive(z: number, x: number, y: number, maxzoom?: number): Promise { const [[max_lat, min_lon], [min_lat, max_lon]] = Tiles.tile_bounds(z, x, y) let maxzoomflag = "" if (maxzoom !== undefined) { maxzoomflag = " --maxzoom=" + maxzoom } const outputFileName = this.getFilename(z, x, y) await this.startProcess( `extract ${ this._sourceFile } --download-threads=1 --minzoom=${z}${maxzoomflag} --bbox=${[ min_lon, min_lat + 0.0001, max_lon, max_lat, ].join(",")} ${outputFileName}` ) return outputFileName } }