forked from MapComplete/MapComplete
Slice script now clips to tile box if flag is set
This commit is contained in:
parent
b88bb5b6d0
commit
8cf3b88172
2 changed files with 163 additions and 133 deletions
|
@ -783,4 +783,14 @@ export class GeoOperations {
|
|||
): boolean {
|
||||
return booleanWithin(feature, possiblyEncloingFeature)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a union between two features
|
||||
*/
|
||||
static union = turf.union
|
||||
|
||||
/**
|
||||
* Create an intersection between two features
|
||||
*/
|
||||
static intersect = turf.intersect
|
||||
}
|
||||
|
|
|
@ -4,13 +4,21 @@ import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSou
|
|||
import * as readline from "readline"
|
||||
import ScriptUtils from "./ScriptUtils"
|
||||
import { Utils } from "../Utils"
|
||||
import Script from "./Script"
|
||||
import { BBox } from "../Logic/BBox"
|
||||
import { GeoOperations } from "../Logic/GeoOperations"
|
||||
|
||||
/**
|
||||
* This script slices a big newline-delimeted geojson file into tiled geojson
|
||||
* It was used to convert the CRAB-data into geojson tiles
|
||||
*/
|
||||
|
||||
async function readFeaturesFromLineDelimitedJsonFile(inputFile: string): Promise<any[]> {
|
||||
class Slice extends Script {
|
||||
constructor() {
|
||||
super("Break data into tiles")
|
||||
}
|
||||
|
||||
async readFeaturesFromLineDelimitedJsonFile(inputFile: string): Promise<any[]> {
|
||||
const fileStream = fs.createReadStream(inputFile)
|
||||
|
||||
const rl = readline.createInterface({
|
||||
|
@ -36,7 +44,7 @@ async function readFeaturesFromLineDelimitedJsonFile(inputFile: string): Promise
|
|||
return allFeatures
|
||||
}
|
||||
|
||||
async function readGeojsonLineByLine(inputFile: string): Promise<any[]> {
|
||||
async readGeojsonLineByLine(inputFile: string): Promise<any[]> {
|
||||
const fileStream = fs.createReadStream(inputFile)
|
||||
|
||||
const rl = readline.createInterface({
|
||||
|
@ -74,25 +82,28 @@ async function readGeojsonLineByLine(inputFile: string): Promise<any[]> {
|
|||
return allFeatures
|
||||
}
|
||||
|
||||
async function readFeaturesFromGeoJson(inputFile: string): Promise<any[]> {
|
||||
async readFeaturesFromGeoJson(inputFile: string): Promise<any[]> {
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(inputFile, { encoding: "utf-8" })).features
|
||||
} catch (e) {
|
||||
// We retry, but with a line-by-line approach
|
||||
return await readGeojsonLineByLine(inputFile)
|
||||
return await this.readGeojsonLineByLine(inputFile)
|
||||
}
|
||||
}
|
||||
|
||||
async function main(args: string[]) {
|
||||
async main(args: string[]) {
|
||||
console.log("GeoJSON slicer")
|
||||
if (args.length < 3) {
|
||||
console.log("USAGE: <input-file.geojson> <target-zoom-level> <output-directory>")
|
||||
console.log(
|
||||
"USAGE: <input-file.geojson> <target-zoom-level> <output-directory> [--clip]"
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
const inputFile = args[0]
|
||||
const zoomlevel = Number(args[1])
|
||||
const outputDirectory = args[2]
|
||||
const doSlice = args[3] === "--clip"
|
||||
|
||||
if (!fs.existsSync(outputDirectory)) {
|
||||
fs.mkdirSync(outputDirectory)
|
||||
|
@ -103,10 +114,10 @@ async function main(args: string[]) {
|
|||
let allFeatures: any[]
|
||||
if (inputFile.endsWith(".geojson")) {
|
||||
console.log("Detected geojson")
|
||||
allFeatures = await readFeaturesFromGeoJson(inputFile)
|
||||
allFeatures = await this.readFeaturesFromGeoJson(inputFile)
|
||||
} else {
|
||||
console.log("Loading as newline-delimited features")
|
||||
allFeatures = await readFeaturesFromLineDelimitedJsonFile(inputFile)
|
||||
allFeatures = await this.readFeaturesFromLineDelimitedJsonFile(inputFile)
|
||||
}
|
||||
allFeatures = Utils.NoNull(allFeatures)
|
||||
|
||||
|
@ -129,7 +140,19 @@ async function main(args: string[]) {
|
|||
maxFeatureCount: Number.MAX_VALUE,
|
||||
registerTile: (tile) => {
|
||||
const path = `${outputDirectory}/tile_${tile.z}_${tile.x}_${tile.y}.geojson`
|
||||
const features = tile.features.data.map((ff) => ff.feature)
|
||||
const box = BBox.fromTile(tile.z, tile.x, tile.y)
|
||||
let features = tile.features.data.map((ff) => ff.feature)
|
||||
if (doSlice) {
|
||||
features = Utils.NoNull(
|
||||
features.map((f) => {
|
||||
const intersection = GeoOperations.intersect(f, box.asGeoJson({}))
|
||||
if (intersection) {
|
||||
intersection.properties = f.properties
|
||||
}
|
||||
return intersection
|
||||
})
|
||||
)
|
||||
}
|
||||
features.forEach((f) => {
|
||||
delete f.bbox
|
||||
})
|
||||
|
@ -154,9 +177,6 @@ async function main(args: string[]) {
|
|||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let args = [...process.argv]
|
||||
args.splice(0, 2)
|
||||
main(args).then((_) => {
|
||||
console.log("All done!")
|
||||
})
|
||||
new Slice().run()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue