forked from MapComplete/MapComplete
90 lines
3.1 KiB
TypeScript
90 lines
3.1 KiB
TypeScript
import Script from "./Script"
|
|
import { Tiles } from "../src/Models/TileRange"
|
|
import { OfflineBasemapManager } from "../src/service-worker/OfflineBasemapManager"
|
|
|
|
import { spawn } from "child_process"
|
|
|
|
|
|
class GeneratePmTilesExtracts extends Script {
|
|
|
|
private targetDir: string
|
|
|
|
constructor() {
|
|
super("Generates many pmtiles-archive from planet-latest.pmtiles. Must be started from the directory where planet-latest.pmtiles resides, archives will be created next to it")
|
|
}
|
|
|
|
startProcess(script: string): Promise<void> {
|
|
return new Promise((resolve, reject) => {
|
|
const child = spawn("./pmtiles", [script],
|
|
{ stdio: "inherit", cwd: this.targetDir })
|
|
|
|
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 planet-latest.pmtiles --download-threads=1 --minzoom=${z}${maxzoomflag} --bbox=${[min_lon, min_lat + 0.0001, max_lon, max_lat].join(",")} ${z}-${x}-${y}.pmtiles`)
|
|
}
|
|
|
|
private* generateField(z: number, maxzoom?: number): Generator<Promise<void>> {
|
|
const boundary = 2 << z
|
|
for (let x = 0; x < boundary; x++) {
|
|
for (let y = 0; y < boundary; y++) {
|
|
yield this.generateArchive(z, x, y, maxzoom)
|
|
}
|
|
}
|
|
}
|
|
|
|
private* generateAll(): Generator<Promise<void>> {
|
|
const zoomlevels: Record<number, number> = OfflineBasemapManager.zoomelevels
|
|
for (const key in zoomlevels) {
|
|
const minzoom: number = Number(key)
|
|
const maxzoom: number | undefined = zoomlevels[key]
|
|
for (const promise of this.generateField(minzoom, maxzoom)) {
|
|
yield promise
|
|
}
|
|
}
|
|
}
|
|
|
|
createBatch<T>(generator: Generator<T>, length: number): T[] {
|
|
const batch = []
|
|
do {
|
|
const next = generator.next()
|
|
if (next.done) {
|
|
return batch
|
|
}
|
|
batch.push(next.value)
|
|
} while (batch.length < length)
|
|
return batch
|
|
}
|
|
|
|
async main(args: string[]): Promise<void> {
|
|
this.targetDir = args[0]
|
|
if (!this.targetDir) {
|
|
console.log("Please specify a target directory")
|
|
return
|
|
}
|
|
console.log("Target dir is:", this.targetDir)
|
|
const numberOfThreads = 1
|
|
const generator = this.generateAll()
|
|
let batch: Promise<void>[] = []
|
|
do {
|
|
batch = this.createBatch(generator, numberOfThreads)
|
|
await Promise.all(batch)
|
|
console.log("Completed", numberOfThreads, "processes")
|
|
} while (batch.length > 0)
|
|
}
|
|
|
|
}
|
|
|
|
new GeneratePmTilesExtracts().run()
|