Advertisement
Guest User

Untitled

a guest
Dec 4th, 2022
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. Overpass QL for the input file (waterway-rels.osm):
  3.  
  4. ```
  5. [out:xml][timeout:90];
  6. {{geocodeArea:slovakia}}->.searchArea;
  7. (
  8.   relation["type"="waterway"](area.searchArea);
  9. );
  10. (._;>;);
  11. out meta;
  12. ```
  13. */
  14.  
  15. const fs = require("fs");
  16. const xml2js = require("xml2js");
  17.  
  18. let data;
  19.  
  20. xml2js.parseString(fs.readFileSync("waterway-rels.osm"), (err, result) => {
  21.   data = result;
  22. });
  23.  
  24. const wayMap = new Map();
  25.  
  26. for (const way of data.osm.way) {
  27.   wayMap.set(way.$.id, way);
  28. }
  29.  
  30. rel: for (const relation of data.osm.relation) {
  31.   const tags = tagsToMap(relation);
  32.  
  33.   const members = ensureArray(relation.member);
  34.  
  35.   const ways = members
  36.     .filter((member) => member.$.type === "way")
  37.     .map((member) => wayMap.get(member.$.ref));
  38.  
  39.   let modifyRel = false;
  40.  
  41.   for (const way of ways) {
  42.     let conflict = false;
  43.  
  44.     for (const tag of ensureArray(way.tag)) {
  45.       const key = tag.$.k;
  46.       const value = tag.$.v;
  47.  
  48.       if (
  49.         key.startsWith("name:") ||
  50.         key.endsWith("_name") ||
  51.         key === "wikipedia" ||
  52.         key === "wikidata" ||
  53.         key === "ref" ||
  54.         key === "destination"
  55.       ) {
  56.         if (!tags[key]) {
  57.           tags[key] = value;
  58.  
  59.           modifyRel = true;
  60.         } else if (tags[key] !== value) {
  61.           console.error(
  62.             `Conflict! "${key}"="${tags[key]}" vs "${value}" r${relation.$.id} w${way.$.id}`
  63.           );
  64.  
  65.           conflict = true;
  66.         }
  67.       }
  68.     }
  69.  
  70.     if (conflict) {
  71.       continue rel;
  72.     }
  73.   }
  74.  
  75.   for (let i = 0; i < ways.length; i++) {
  76.     const way = ways[i];
  77.  
  78.     const tagArray = ensureArray(way.tag);
  79.  
  80.     for (let j = tagArray.length - 1; j >= 0; j--) {
  81.       const tag = tagArray[j];
  82.       const key = tag.$.k;
  83.       const value = tag.$.v;
  84.  
  85.       if (
  86.         key.startsWith("name:") ||
  87.         key.endsWith("_name") ||
  88.         key === "wikipedia" ||
  89.         key === "wikidata" ||
  90.         key === "ref" ||
  91.         key === "destination"
  92.       ) {
  93.         way.$.action = "modify";
  94.  
  95.         tagArray.splice(j, 1);
  96.       }
  97.     }
  98.   }
  99.  
  100.   if (modifyRel) {
  101.     relation.$.action = "modify";
  102.  
  103.     relation.tag = Object.entries(tags).map(([k, v]) => ({
  104.       $: {
  105.         k,
  106.         v,
  107.       },
  108.     }));
  109.   }
  110. }
  111.  
  112. const builder = new xml2js.Builder();
  113.  
  114. console.log(builder.buildObject(data));
  115.  
  116. function tagsToMap(a) {
  117.   const tags = {};
  118.  
  119.   for (const tag of ensureArray(a.tag)) {
  120.     tags[tag.$.k] = tag.$.v;
  121.   }
  122.  
  123.   return tags;
  124. }
  125.  
  126. function ensureArray(a) {
  127.   return !a ? [] : Array.isArray(a) ? a : [a];
  128. }
  129.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement