Skip to content

Instantly share code, notes, and snippets.

@zdila
Created September 14, 2016 19:48
Show Gist options
  • Save zdila/9ea6c4d1d246394ac8aa6d6b00d8b93a to your computer and use it in GitHub Desktop.
Save zdila/9ea6c4d1d246394ac8aa6d6b00d8b93a to your computer and use it in GitHub Desktop.
guidepost to hiking relation adder
// overpass query:
/*
[out:xml][timeout:250];
(
relation[route="hiking"][colour="yellow"]["operator"="KST"];
);
(._;>;);
out meta;
*/
'use strict';
const xmldom = require('xmldom');
const DOMParser = xmldom.DOMParser;
const XMLSerializer = xmldom.XMLSerializer;
const fs = require('fs');
const doc = new DOMParser().parseFromString(fs.readFileSync('./yellow.osm', 'utf8'));
// wayID => way
// nodeID => node
const wayMap = {};
const nodeMap = {};
const nodes = doc.getElementsByTagName('node');
for (let i = 0; i < nodes.length; i++) {
const node = nodes.item(i);
node.isKst = isKst(node);
nodeMap[node.getAttribute('id')] = node;
}
const ways = doc.getElementsByTagName('way');
for (let i = 0; i < ways.length; i++) {
const way = ways.item(i);
const nds = way.getElementsByTagName('nd');
const nodes = [];
for (let j = 0; j < nds.length; j++) {
const nd = nds.item(j);
nodes.push(nodeMap[nd.getAttribute('ref')]);
}
wayMap[way.getAttribute('id')] = { way: way, nodes: nodes };
}
const relations = doc.getElementsByTagName('relation');
for (let i = 0; i < relations.length; i++) {
const relation = relations.item(i);
if (!isKst(relation)) {
continue;
}
const members = relation.getElementsByTagName('member');
const nnn = {};
for (let j = 0; j < members.length; j++) {
const member = members.item(j);
if (member.getAttribute('type') === 'node') {
nnn[member.getAttribute('ref')] = true;
}
}
const nodeIds = {};
for (let j = 0; j < members.length; j++) {
const member = members.item(j);
if (member.getAttribute('type') === 'way') {
wayMap[member.getAttribute('ref')].nodes.filter(node => node.isKst).map(node => node.getAttribute('id')).filter(id => !(id in nnn)).forEach(id => {
nodeIds[id] = true;
})
}
}
Object.keys(nodeIds).forEach(nodeId => {
const newMember = doc.createElement('member');
newMember.setAttribute('type', 'node');
newMember.setAttribute('role', '');
newMember.setAttribute('ref', nodeId);
relation.appendChild(newMember);
relation.setAttribute('action', 'modify');
});
}
function isKst(node) {
const tags = node.getElementsByTagName('tag');
let kst = false;
let hiking = false;
let guidepost = false;
for (let i = 0; i < tags.length; i++) {
const tag = tags.item(i);
const key = tag.getAttribute('k');
const value = tag.getAttribute('v');
if (key === 'hiking' && value === 'yes') {
hiking = true;
} else if (key === 'operator' && value === 'KST') {
kst = true;
} else if (key === 'information' && value === 'guidepost') {
guidepost = true;
}
if (node.nodeName === 'node' && hiking && kst && guidepost || node.nodeName === 'relation' && kst) {
return true;
}
}
return false;
}
console.log(new XMLSerializer().serializeToString(doc));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment