import { appendFileSync, existsSync, readFileSync, writeFileSync } from "fs" import { GeoOperations } from "../../Logic/GeoOperations" import ScriptUtils from "../ScriptUtils" import { Utils } from "../../Utils" async function main(args: string[]) { ScriptUtils.fixUtils() const pointCandidates = JSON.parse(readFileSync(args[0], "utf8")) const postcodes = JSON.parse(readFileSync(args[1], "utf8")) const output = args[2] ?? "centralCoordinates.csv" const perPostCode = new Map() const alreadyLoaded = new Set() if (existsSync(output)) { const lines = readFileSync(output, { encoding: "utf8" }).split("\n") lines.shift() lines.forEach((line) => { const postalCode = Number(line.split(",")[0]) alreadyLoaded.add(postalCode) }) } else { writeFileSync(output, "postal_code,lon,lat\n", { encoding: "utf8" }) } for (const boundary of postcodes.features) { const postcode = boundary.properties.nouveau_PO if (alreadyLoaded.has(Number(postcode))) { console.log("Skipping ", postcode, "as already loaded") continue } if (perPostCode.has(postcode)) { perPostCode.get(postcode).push(boundary) } else { perPostCode.set(postcode, [boundary]) } } for (const postcode of Array.from(perPostCode.keys())) { const boundaries = perPostCode.get(postcode) const candidates = [] for (const boundary of boundaries) { for (const candidate of pointCandidates.features) { if (!GeoOperations.inside(candidate, boundary)) { // console.log(JSON.stringify(candidate)) continue } candidates.push(candidate.geometry.coordinates) } } if (candidates.length === 0) { console.log( "Postcode ", postcode, "has", candidates.length, "candidates, using centerpoint instead" ) candidates.push( ...boundaries.map((boundary) => GeoOperations.centerpointCoordinates(boundary)) ) } const url = "https://staging.anyways.eu/routing-api/v1/routes?access_token=postal_code_script&turn_by_turn=false&format=geojson&language=en" const depPoints: [number, number][] = Utils.NoNull( await Promise.all( candidates.map(async (candidate) => { try { const result = await Utils.downloadJson( url + "&loc=" + candidate.join("%2C") + "&loc=3.22000%2C51.21577&profile=car.short" ) const depPoint = result.features.filter( (f) => f.geometry.type === "LineString" )[0].geometry.coordinates[0] return <[number, number]>[depPoint[0], depPoint[1]] // Drop elevation } catch (e) { console.error("No result or could not calculate a route") } }) ) ) const centers = boundaries.map((b) => GeoOperations.centerpointCoordinates(b)) const center = GeoOperations.centerpointCoordinates({ type: "Feature", geometry: { type: "LineString", coordinates: centers, }, }) depPoints.sort( (c0, c1) => GeoOperations.distanceBetween(c0, center) - GeoOperations.distanceBetween(c1, center) ) console.log( "Sorted departure point candidates for ", postcode, " are ", JSON.stringify(depPoints) ) appendFileSync(output, [postcode, ...depPoints[0]].join(", ") + "\n", { encoding: "utf8" }) } } let args = [...process.argv] args.splice(0, 2) main(args).then((_) => console.log("Done!"))