예제 #1
0
 def __init__(self, config):
     self.config = config
     self.filter = None
     if config.polygon_id:
         try:
             self.filter = PolygonErrorFilter(config.polygon_id)
         except Exception as e:
             print(e)
             pass
     self.geom_type_renderer = {
         "node": self.node,
         "way": self.way,
         "relation": self.relation,
         "position": self.position
     }
예제 #2
0
 def __init__(self, config):
     self.config = config
     self.filter = None
     if config.polygon_id:
         try:
             self.filter = PolygonErrorFilter(config.polygon_id)
         except Exception as e:
             print(e)
             pass
     self.geom_type_renderer = {"node": self.node, "way": self.way, "relation": self.relation, "position": self.position}
예제 #3
0
class ErrorFile:
    def __init__(self, config):
        self.config = config
        self.filter = None
        if config.polygon_id:
            try:
                self.filter = PolygonErrorFilter(config.polygon_id)
            except Exception as e:
                print(e)
                pass
        self.geom_type_renderer = {
            "node": self.node,
            "way": self.way,
            "relation": self.relation,
            "position": self.position
        }

    def begin(self):
        if self.config.dst.endswith(".bz2"):
            output = bz2.BZ2File(self.config.dst, "w")
        else:
            output = open(self.config.dst, "w")
        self.outxml = OsmSax.OsmSaxWriter(output, "UTF-8")
        self.outxml.startDocument()
        self.outxml.startElement("analysers", {})

    def end(self):
        self.outxml.endElement("analysers")
        self.outxml.endDocument()
        del self.outxml

    def analyser(self, timestamp, change=False):
        self.mode = "analyserChange" if change else "analyser"
        attrs = {}
        attrs["timestamp"] = timestamp.strftime("%Y-%m-%dT%H:%M:%SZ")
        if hasattr(self.config, "version"):
            attrs["version"] = self.config.version
        self.outxml.startElement(self.mode, attrs)

    def analyser_end(self):
        self.outxml.endElement(self.mode)

    def classs(self, id, item, level, tag, langs):
        options = {"id": str(id), "item": str(item)}
        if level:
            options["level"] = str(level)
        if tag:
            options["tag"] = ",".join(tag)
        self.outxml.startElement("class", options)
        for lang in sorted(langs.keys()):
            self.outxml.Element("classtext", {
                "lang": lang,
                "title": langs[lang]
            })
        self.outxml.endElement("class")

    def error(self, classs, subclass, text, res, fixType, fix, geom):
        if self.filter and not self.filter.apply(classs, subclass, geom):
            return

        if subclass != None:
            self.outxml.startElement(
                "error", {
                    "class": str(classs),
                    "subclass": str(int(subclass) % 2147483647)
                })
        else:
            self.outxml.startElement("error", {"class": str(classs)})
        for type in geom:
            for g in geom[type]:
                self.geom_type_renderer[type](g)
        if text:
            for lang in text:
                self.outxml.Element("text", {
                    "lang": lang,
                    "value": text[lang]
                })
        if fix:
            fix = self.fixdiff(fix)
            fix = self.filterfix(res, fixType, fix, geom)
            self.dumpxmlfix(res, fixType, fix)
        self.outxml.endElement("error")

    def node(self, args):
        self.outxml.NodeCreate(args)

    def way(self, args):
        self.outxml.WayCreate(args)

    def relation(self, args):
        self.outxml.RelationCreate(args)

    def position(self, args):
        self.outxml.Element("location", {
            "lat": str(args["lat"]),
            "lon": str(args["lon"])
        })

    def delete(self, t, id):
        self.outxml.Element("delete", {"type": t, "id": str(id)})

    def node_delete(self, id):
        self.delete("node", id)

    def way_delete(self, id):
        self.delete("way", id)

    def relation_delete(self, id):
        self.delete("relation", id)

    FixTable = {'~': 'modify', '+': 'create', '-': 'delete'}

    def fixdiff(self, fixes):
        """
        Normalise fix in e
        Normal form is [[{'+':{'k1':'v1', 'k2', 'v2'}, '-':{'k3':'v3'}, '~':{'k4','v4'}}, {...}]]
        Array of alternative ways to fix -> Array of fix for objects part of error -> Dict for diff actions -> Dict for tags
        """
        if not isinstance(fixes, list):
            fixes = [[fixes]]
        elif not isinstance(fixes[0], list):
            # Default one level array is different way of fix
            fixes = map(lambda x: [x], fixes)
        return map(
            lambda fix: map(
                lambda f: None
                if f == None else (f if '~' in f or '-' in f or '+' in f else {
                    '~': f
                }), fix), fixes)

    def filterfix(self, res, fixesType, fixes, geom):
        ret_fixes = []
        for fix in fixes:
            i = 0
            for f in fix:
                if f != None and i < len(fixesType):
                    osm_obj = next(
                        (x for x in geom[fixesType[i]] if x['id'] == res[i]),
                        None)
                    if osm_obj:
                        fix_tags = f['+'].keys() if '+' in f else []
                        if len(
                                set(osm_obj['tag'].keys()).intersection(
                                    fix_tags)) > 0:
                            # Fix try to override existing tag in object, drop the fix
                            i = 0
                            break
                i += 1
            if i > 0:
                ret_fixes.append(fix)
        return ret_fixes

    def dumpxmlfix(self, res, fixesType, fixes):
        self.outxml.startElement("fixes", {})
        for fix in fixes:
            self.outxml.startElement("fix", {})
            i = 0
            for f in fix:
                if f != None and i < len(fixesType):
                    type = fixesType[i]
                    if type:
                        self.outxml.startElement(type, {'id': str(res[i])})
                        for opp, tags in f.items():
                            for k in tags:
                                if opp in '~+':
                                    self.outxml.Element(
                                        'tag', {
                                            'action': self.FixTable[opp],
                                            'k': k,
                                            'v': tags[k]
                                        })
                                else:
                                    self.outxml.Element(
                                        'tag', {
                                            'action': self.FixTable[opp],
                                            'k': k
                                        })
                        self.outxml.endElement(type)
                i += 1
            self.outxml.endElement('fix')
        self.outxml.endElement('fixes')
예제 #4
0
class ErrorFile:

    def __init__(self, config):
        self.config = config
        self.filter = None
        if config.polygon_id:
            try:
                self.filter = PolygonErrorFilter(config.polygon_id)
            except Exception as e:
                print(e)
                pass
        self.geom_type_renderer = {"node": self.node, "way": self.way, "relation": self.relation, "position": self.position}

    def begin(self):
        if self.config.dst.endswith(".bz2"):
            output = bz2.BZ2File(self.config.dst, "w")
        else:
            output = open(self.config.dst, "w")
        self.outxml = OsmSax.OsmSaxWriter(output, "UTF-8")
        self.outxml.startDocument()
        self.outxml.startElement("analysers", {"timestamp":time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())})

    def end(self):
        self.outxml.endElement("analysers")
        self.outxml.endDocument()
        del self.outxml

    def analyser(self, change=False):
        self.mode = "analyserChange" if change else "analyser"
        attrs = {}
        attrs["timestamp"] = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
        if hasattr(self.config, "version"):
            attrs["version"] = self.config.version
        self.outxml.startElement(self.mode, attrs)

    def analyser_end(self):
        self.outxml.endElement(self.mode)

    def classs(self, id, item, level, tag, langs):
        options = {"id":str(id), "item": str(item)}
        if level:
            options["level"] = str(level)
        if tag:
            options["tag"] = ",".join(tag)
        self.outxml.startElement("class", options)
        for lang in sorted(langs.keys()):
            self.outxml.Element("classtext", {"lang":lang, "title":langs[lang]})
        self.outxml.endElement("class")

    def error(self, classs, subclass, text, res, fixType, fix, geom):
        if self.filter and not self.filter.apply(classs, subclass, geom):
            return

        if subclass != None:
            self.outxml.startElement("error", {"class":str(classs), "subclass":str(int(subclass) % 2147483647)})
        else:
            self.outxml.startElement("error", {"class":str(classs)})
        for type in geom:
            for g in geom[type]:
                self.geom_type_renderer[type](g)
        if text:
            for lang in text:
                self.outxml.Element("text", {"lang":lang, "value":text[lang]})
        if fix:
            fix = self.fixdiff(fix)
            fix = self.filterfix(res, fixType, fix, geom)
            self.dumpxmlfix(res, fixType, fix)
        self.outxml.endElement("error")

    def node(self, args):
        self.outxml.NodeCreate(args)

    def way(self, args):
        self.outxml.WayCreate(args)

    def relation(self, args):
        self.outxml.RelationCreate(args)

    def position(self, args):
        self.outxml.Element("location", {"lat":str(args["lat"]), "lon":str(args["lon"])})

    def delete(self, t, id):
        self.outxml.Element("delete", {"type": t, "id": str(id)})

    def node_delete(self, id):
        self.delete("node", id)

    def way_delete(self, id):
        self.delete("way", id)

    def relation_delete(self, id):
        self.delete("relation", id)

    FixTable = {'~':'modify', '+':'create', '-':'delete'}

    def fixdiff(self, fixes):
        """
        Normalise fix in e
        Normal form is [[{'+':{'k1':'v1', 'k2', 'v2'}, '-':{'k3':'v3'}, '~':{'k4','v4'}}, {...}]]
        Array of alternative ways to fix -> Array of fix for objects part of error -> Dict for diff actions -> Dict for tags
        """
        if not isinstance(fixes, list):
            fixes = [[fixes]]
        elif not isinstance(fixes[0], list):
            # Default one level array is different way of fix
            fixes = map(lambda x: [x], fixes)
        return map(lambda fix:
            map(lambda f:
                None if f == None else (f if '~' in f or '-' in f or '+' in f else {'~': f}),
                fix),
            fixes)

    def filterfix(self, res, fixesType, fixes, geom):
        ret_fixes = []
        for fix in fixes:
            i = 0
            for f in fix:
                if f != None and i < len(fixesType):
                    osm_obj = next((x for x in geom[fixesType[i]] if x['id'] == res[i]), None)
                    if osm_obj:
                        fix_tags = f['+'].keys() if '+' in f else []
                        if len(set(osm_obj['tag'].keys()).intersection(fix_tags)) > 0:
                            # Fix try to override existing tag in object, drop the fix
                            i = 0
                            break
                i += 1
            if i > 0:
                ret_fixes.append(fix)
        return ret_fixes

    def dumpxmlfix(self, res, fixesType, fixes):
        self.outxml.startElement("fixes", {})
        for fix in fixes:
            self.outxml.startElement("fix", {})
            i = 0
            for f in fix:
                if f != None and i < len(fixesType):
                    type = fixesType[i]
                    if type:
                        self.outxml.startElement(type, {'id': str(res[i])})
                        for opp, tags in f.items():
                            for k in tags:
                                if opp in '~+':
                                    self.outxml.Element('tag', {'action': self.FixTable[opp], 'k': k, 'v': tags[k]})
                                else:
                                    self.outxml.Element('tag', {'action': self.FixTable[opp], 'k': k})
                        self.outxml.endElement(type)
                i += 1
            self.outxml.endElement('fix')
        self.outxml.endElement('fixes')