Scripts: create server script for pmtiles

This commit is contained in:
Pieter Vander Vennet 2025-09-26 01:53:34 +02:00
parent 1527627cd0
commit 676bb8a250
6 changed files with 175 additions and 60 deletions

View file

@ -1,15 +1,15 @@
import Script from "./Script"
import { Tiles } from "../src/Models/TileRange"
import { spawn } from "child_process"
import { existsSync, mkdirSync, writeFileSync } from "fs"
import { Utils } from "../src/Utils"
import { OfflineBasemapManager } from "../src/Logic/OfflineBasemapManager"
import { PmTilesExtractGenerator } from "./pmTilesExtractGenerator"
class GeneratePmTilesExtracts extends Script {
private targetDir: string
private sourceFile: string
private skipped: number = 0
private extractsGenerator: PmTilesExtractGenerator
constructor() {
super(
"Generates many pmtiles-archive from planet-latest.pmtiles. Expects the `pmtiles`-executable to be at `/data/pmtiles`." +
@ -18,56 +18,14 @@ class GeneratePmTilesExtracts extends Script {
)
}
startProcess(script: string, captureStdioChunks?: (string: string) => void): Promise<void> {
return new Promise((resolve, reject) => {
const child = spawn("/data/pmtiles", 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)
})
}
private generateArchive(z: number, x: number, y: number, maxzoom?: number): Promise<void> {
const [[max_lat, min_lon], [min_lat, max_lon]] = Tiles.tile_bounds(z, x, y)
let maxzoomflag = ""
if (maxzoom !== undefined) {
maxzoomflag = " --maxzoom=" + maxzoom
}
return this.startProcess(
`extract ${this.sourceFile} --download-threads=1 --minzoom=${z}${maxzoomflag} --bbox=${[
min_lon,
min_lat + 0.0001,
max_lon,
max_lat,
].join(",")} ${this.getFilename(z, x, y)}`
)
}
private *generateColumnIfNeeded(
public *generateColumnIfNeeded(
z: number,
x: number,
boundary: number,
maxzoom?: number
): Generator<Promise<void>> {
const lastFileForColumn = this.getFilename(z, x, boundary - 1)
if (existsSync(this.targetDir + "/" + lastFileForColumn)) {
): Generator<Promise<any>> {
const lastFileForColumn = this.extractsGenerator.getFilename(z, x, boundary - 1)
if (existsSync(lastFileForColumn)) {
// Skip this column, already exists
console.log("Skipping column ", x, "at zoom", z)
this.skipped += boundary
@ -79,12 +37,12 @@ class GeneratePmTilesExtracts extends Script {
"at zoom",
z,
"as",
this.targetDir + "/" + lastFileForColumn,
lastFileForColumn,
"does not exist"
)
for (let y = 0; y < boundary; y++) {
yield this.generateArchive(z, x, y, maxzoom)
yield this.extractsGenerator.generateArchive(z, x, y, maxzoom)
}
}
@ -100,9 +58,7 @@ class GeneratePmTilesExtracts extends Script {
}
}
private getFilename(z: number, x: number, y: number) {
return `${z}/${x}/${y}.pmtiles`
}
private *generateAll(): Generator<Promise<void>> {
const zoomlevels: Record<number, number> = OfflineBasemapManager.zoomelevels
@ -132,11 +88,13 @@ class GeneratePmTilesExtracts extends Script {
async main(args: string[]): Promise<void> {
this.targetDir = args[0]
this.sourceFile = this.targetDir+"/planet-latest.pmtiles"
const sourceFile = this.targetDir+"/planet-latest.pmtiles"
if (!this.targetDir) {
console.log("Please specify a target directory. Did you forget '--' in vite-node?")
return
}
this.extractsGenerator = new PmTilesExtractGenerator(sourceFile, this.targetDir)
let estimate = 0
for (const key in OfflineBasemapManager.zoomelevels) {
const z: number = Number(key)