Skip to content

Instantly share code, notes, and snippets.

@zdila
Created November 20, 2022 10:46
Show Gist options
  • Save zdila/eb6a1e294021c911e6e33d60225c097d to your computer and use it in GitHub Desktop.
Save zdila/eb6a1e294021c911e6e33d60225c097d to your computer and use it in GitHub Desktop.
mirecnet-false-fords-cleanup
/*
Overpass QL for the input file (mirecnet-false-fords.osm):
```
[out:xml][timeout:600][bbox:{{bbox}}];
(
way[highway]->.w1;
way[waterway]->.w2;
node[!"ford"](w.w1)(w.w2)(user:"Mirecnet");
);
out meta;
```
*/
const fs = require("fs");
const xml2js = require("xml2js");
let data;
xml2js.parseString(
fs.readFileSync("mirecnet-false-fords.osm"),
(err, result) => {
data = result;
}
);
const candidateNodes = new Map();
for (const node of data.osm.node) {
// only nodes with tags
if (!node.tag && node.$.user === "Mirecnet") {
candidateNodes.set(node.$.id, node);
}
}
const nodeInWaterwayRefs = new Map();
const nodeInHighwayRefs = new Map();
const ignoreRefs = new Set(); // skip nodes of multiple highways or waterways
for (const way of data.osm.way) {
const tags = tagsToMap(way);
for (const ref1 of ensureArray(way.nd)) {
const ref = ref1.$.ref;
if (!candidateNodes.has(ref)) {
continue;
}
if (tags.highway) {
if (nodeInHighwayRefs.has(ref)) {
ignoreRefs.add(ref);
}
nodeInHighwayRefs.set(ref, way);
}
if (tags.waterway) {
if (nodeInWaterwayRefs.has(ref)) {
ignoreRefs.add(ref);
}
nodeInWaterwayRefs.set(ref, way);
}
}
}
let nextRef = 0;
for (const [nr, waterway] of nodeInWaterwayRefs.entries()) {
if (ignoreRefs.has(nr)) {
continue;
}
const highway = nodeInHighwayRefs.get(nr);
if (!highway) {
continue;
}
for (let i = 0; i < waterway.nd.length; i++) {
const ref = waterway.nd[i].$.ref;
if (ref !== nr) {
continue;
}
waterway.$.action = "modify";
nextRef--;
waterway.nd[i].$.ref = nextRef;
const newNode = structuredClone(candidateNodes.get(nr));
newNode.$.id = nextRef;
delete newNode.$.timestamp;
delete newNode.$.uid;
delete newNode.$.user;
delete newNode.$.changeset;
newNode.$.lat = Number(newNode.$.lat) + 0.000001;
newNode.$.lon = Number(newNode.$.lon) + 0.0000015;
data.osm.node.push(newNode);
break;
}
}
const builder = new xml2js.Builder();
console.log(builder.buildObject(data));
function tagsToMap(a) {
const tags = {};
for (const tag of ensureArray(a.tag)) {
tags[tag.$.k] = tag.$.v;
}
return tags;
}
function ensureArray(a) {
return !a ? [] : Array.isArray(a) ? a : [a];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment