154 lines
4.2 KiB
TypeScript
154 lines
4.2 KiB
TypeScript
import * as fs from "fs"
|
|
import { existsSync, writeFileSync } from "fs"
|
|
import * as readline from "readline"
|
|
import ScriptUtils from "../ScriptUtils"
|
|
|
|
/**
|
|
* Converts an open-address CSV file into a big geojson file
|
|
*/
|
|
|
|
async function main(args: string[]) {
|
|
const inputFile = args[0]
|
|
const outputFile = args[1]
|
|
const fileStream = fs.createReadStream(inputFile)
|
|
const perPostalCode = args[2] == "--per-postal-code"
|
|
const rl = readline.createInterface({
|
|
input: fileStream,
|
|
crlfDelay: Infinity,
|
|
})
|
|
// Note: we use the crlfDelay option to recognize all instances of CR LF
|
|
// ('\r\n') in input.txt as a single line break.
|
|
|
|
const fields = [
|
|
"EPSG:31370_x",
|
|
"EPSG:31370_y",
|
|
"EPSG:4326_lat",
|
|
"EPSG:4326_lon",
|
|
"address_id",
|
|
"box_number",
|
|
"house_number",
|
|
"municipality_id",
|
|
"municipality_name_de",
|
|
"municipality_name_fr",
|
|
"municipality_name_nl",
|
|
"postcode",
|
|
"postname_fr",
|
|
"postname_nl",
|
|
"street_id",
|
|
"streetname_de",
|
|
"streetname_fr",
|
|
"streetname_nl",
|
|
"region_code",
|
|
"status",
|
|
]
|
|
|
|
let i = 0
|
|
let failed = 0
|
|
|
|
let createdFiles: string[] = []
|
|
if (!perPostalCode) {
|
|
fs.writeFileSync(outputFile, "")
|
|
}
|
|
// @ts-ignore
|
|
for await (const line of rl) {
|
|
i++
|
|
if (i % 10000 == 0) {
|
|
ScriptUtils.erasableLog(
|
|
"Converted ",
|
|
i,
|
|
"features (of which ",
|
|
failed,
|
|
"features don't have a coordinate)"
|
|
)
|
|
}
|
|
const data = line.split(",")
|
|
const parsed: any = {}
|
|
for (let i = 0; i < fields.length; i++) {
|
|
const field = fields[i]
|
|
parsed[field] = data[i]
|
|
}
|
|
const lat = Number(parsed["EPSG:4326_lat"])
|
|
const lon = Number(parsed["EPSG:4326_lon"])
|
|
|
|
if (parsed["EPSG:31370_x"] === "0.0") {
|
|
failed++
|
|
continue
|
|
}
|
|
|
|
delete parsed["EPSG:4326_lat"]
|
|
delete parsed["EPSG:4326_lon"]
|
|
delete parsed["EPSG:31370_x"]
|
|
delete parsed["EPSG:31370_y"]
|
|
delete parsed["EPSG:4326_lat"]
|
|
delete parsed["EPSG:4326_lat"]
|
|
|
|
let targetFile = outputFile
|
|
if (perPostalCode) {
|
|
if (parsed["postcode"] === "") {
|
|
continue
|
|
}
|
|
if (isNaN(Number(parsed["postcode"]))) {
|
|
continue
|
|
}
|
|
targetFile = outputFile + "-" + parsed["postcode"] + ".geojson"
|
|
let isFirst = false
|
|
if (!existsSync(targetFile)) {
|
|
writeFileSync(targetFile, '{ "type":"FeatureCollection", "features":[')
|
|
createdFiles.push(targetFile)
|
|
isFirst = true
|
|
}
|
|
|
|
if (!isFirst) {
|
|
fs.appendFileSync(targetFile, ",\n")
|
|
}
|
|
|
|
fs.appendFileSync(
|
|
targetFile,
|
|
JSON.stringify({
|
|
type: "Feature",
|
|
properties: parsed,
|
|
geometry: {
|
|
type: "Point",
|
|
coordinates: [lon, lat],
|
|
},
|
|
})
|
|
)
|
|
} else {
|
|
fs.appendFileSync(
|
|
outputFile,
|
|
JSON.stringify({
|
|
type: "Feature",
|
|
properties: parsed,
|
|
geometry: {
|
|
type: "Point",
|
|
coordinates: [lon, lat],
|
|
},
|
|
}) + "\n"
|
|
)
|
|
}
|
|
}
|
|
|
|
console.log("Closing files...")
|
|
createdFiles.sort()
|
|
for (const createdFile of createdFiles) {
|
|
ScriptUtils.erasableLog("Closing ", createdFile, "and creating convex hull")
|
|
fs.appendFileSync(createdFile, "]}")
|
|
}
|
|
|
|
console.log(
|
|
"Done! Converted ",
|
|
i,
|
|
"features (of which ",
|
|
failed,
|
|
"features don't have a coordinate)"
|
|
)
|
|
}
|
|
|
|
let args = [...process.argv]
|
|
args.splice(0, 2)
|
|
|
|
if (args.length == 0) {
|
|
console.log("USAGE: input-csv-file output.newline-delimited-geojson.json [--per-postal-code]")
|
|
} else {
|
|
main(args).catch((e) => console.error(e))
|
|
}
|