diff options
Diffstat (limited to 'upload/osmpatch.py')
-rwxr-xr-x | upload/osmpatch.py | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/upload/osmpatch.py b/upload/osmpatch.py new file mode 100755 index 0000000..a516c22 --- /dev/null +++ b/upload/osmpatch.py @@ -0,0 +1,144 @@ +#! /usr/bin/python +# vim: fileencoding=utf-8 encoding=utf-8 et sw=4 + +# Copyright (C) 2009 Jacek Konieczny <jajcus@jajcus.net> +# Copyright (C) 2009 Andrzej Zaborowski <balrogg@gmail.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +""" +Patches .osm files with .diff.xml files resulting from an upload of +an .osc file, for use when uploading a .osc file produced by osm2change.py +Note this removes deleted elements from the .osm file. +""" + +__version__ = "$Revision: 21 $" + +import os +import subprocess +import sys +import traceback +import codecs +import locale + +import xml.etree.cElementTree as ElementTree + +import locale, codecs +locale.setlocale(locale.LC_ALL, "en_US.UTF-8") +encoding = locale.getlocale()[1] +sys.stdout = codecs.getwriter(encoding)(sys.stdout, errors = "replace") +sys.stderr = codecs.getwriter(encoding)(sys.stderr, errors = "replace") + +if len(sys.argv) < 2 or sys.argv[1] == "--help": + print >>sys.stderr, u"Synopsis:" + print >>sys.stderr, u" %s <file.diff.xml> [osm-files-to-patch...]" + sys.exit(1) + +dd = [ {}, {}, {} ] +ddv = [ {}, {}, {} ] + +# TODO: use ElementTree +# TODO: take multiple diff arguments +diff = open(sys.argv[1], "r") +sys.stdout.write("Parsing diff\n") +for line in diff: + oldpos = line.find("old_id=\"") + newpos = line.find("new_id=\"") + newvpos = line.find("new_version=\"") + if oldpos < 0: + continue + if line.find("node") >= 0: + idx = 0 + elif line.find("way") >= 0: + idx = 1 + elif line.find("relation") >= 0: + idx = 2 + else: + continue + + old = line[oldpos + 8:] + old = old[:old.find("\"")] + if newpos >= 0 and newvpos >= 0: + new = line[newpos + 8:] + newv = line[newvpos + 13:] + new = new[:new.find("\"")] + newv = newv[:newv.find("\"")] + else: + new = 0 + newv = 0 + dd[idx][old] = new + ddv[idx][old] = newv + +for filename in sys.argv[2:]: + sys.stdout.write("Parsing " + filename + "\n") + + if not os.path.exists(filename): + print >>sys.stderr, u"File %r doesn't exist!" % (filename,) + sys.exit(1) + if filename.endswith(".osm"): + filename_base = filename[:-4] + else: + filename_base = filename + + tree = ElementTree.parse(filename) + root = tree.getroot() + if root.tag != "osm" or root.attrib.get("version") != "0.6": + print >>sys.stderr, u"File %s is not a v0.6 osm file!" % (filename,) + sys.exit(1) + + output_attr = {"version": "0.6", "generator": root.attrib.get("generator")} + output_root = ElementTree.Element("osm", output_attr) + output_tree = ElementTree.ElementTree(output_root) + + for element in root: + copy = 1 + + if "id" in element.attrib: + old = element.attrib["id"] + idx = [ "node", "way", "relation" ].index(element.tag) + if old in dd[idx]: + if dd[idx][old] and ddv[idx][old]: + element.attrib["id"] = dd[idx][old] + element.attrib["version"] = ddv[idx][old] + else: + copy = 0 + + if "action" in element.attrib: + action = element.attrib.pop("action") + + if action in [ "delete" ]: + if copy: + print "Bad delete on id " + old + elif action in [ "create", "modify" ]: + if not copy: + print "Bad create/modify on id " + old + else: + print "Bad action on id " + old + + for member in element: + if member.tag in [ "nd", "member" ]: + idx = 0; + if member.tag == "member": + idx = [ "node", "way", "relation" ].index( + member.attrib["type"]) + + ref = member.attrib["ref"] + if ref in dd[idx]: + member.attrib["ref"] = dd[idx][ref] + + if copy: + output_root.append(element) + + output_tree.write(filename_base + ".osm.diffed", "utf-8") |