Beispiel #1
0
    def __parse_relations(self, pblock, data):
        for e in data:
            members = []
            mid = 0
            for role_id, mtype, mid_delta in zip(e.roles_sid, e.types,
                                                 e.memids):
                mid += mid_delta
                members.append(
                    RelationMember(
                        pblock.stringtable.s[role_id].decode('utf-8'),
                        (Node, Way, Relation)[mtype], mid))

            yield Relation(id=e.id,
                           version=e.info.version,
                           changeset=int(e.info.changeset),
                           timestamp=int(e.info.timestamp),
                           uid=e.info.uid,
                           tags=self.__parse_tags(e, pblock),
                           members=tuple(members))
Beispiel #2
0
    def parse(self, fp):
        context = iterparse(fp, events=('start', 'end'))

        # common
        _type = None
        _id = None
        _version = None
        _changeset = None
        _timestamp = None
        _uid = None
        _tags = None
        # node only
        _lon = None
        _lat = None
        # way only
        _nodes = None
        # relation only
        _members = None

        for event, elem in context:

            if event == 'start':
                attrs = elem.attrib
                if elem.tag in ('node', 'way', 'relation'):
                    _id = long(attrs['id'])
                    _version = int(attrs['version'])

                    try:  # GeoFabrik's (May 2018) public snapshots strip the changeset attribute out of their data
                        _changeset = int(attrs['changeset'])
                    except:
                        _changeset = 0

                    # TODO: improve timestamp parsing - dateutil too slow
                    _tstxt = attrs['timestamp']
                    _timestamp = int(
                        (datetime(year=int(_tstxt[0:4]),
                                  month=int(_tstxt[5:7]),
                                  day=int(_tstxt[8:10]),
                                  hour=int(_tstxt[11:13]),
                                  minute=int(_tstxt[14:16]),
                                  second=int(_tstxt[17:19]),
                                  tzinfo=None) -
                         datetime(year=1970, month=1, day=1,
                                  tzinfo=None)).total_seconds())

                    try:  #An object can miss an uid (when anonymous edits were possible)
                        _uid = int(attrs['uid'])
                    except:
                        uid = 0

                    _tags = {}

                    if elem.tag == 'node':
                        _type = Node
                        _lon = float(attrs['lon'])
                        _lat = float(attrs['lat'])
                    elif elem.tag == 'way':
                        _type = Way
                        _nodes = []
                    elif elem.tag == 'relation':
                        _type = Relation
                        _members = []

                elif elem.tag == 'tag':
                    _tags[unicode(attrs['k'])] = unicode(attrs['v'])

                elif elem.tag == 'nd':
                    _nodes.append(long(attrs['ref']))

                elif elem.tag == 'member':
                    _members.append(
                        RelationMember(unicode(attrs['role']), {
                            'node': Node,
                            'way': Way,
                            'relation': Relation
                        }[attrs['type']], long(attrs['ref'])))

            elif event == 'end':
                if elem.tag in ('node', 'way', 'relation'):
                    args = [_id, _version, _changeset, _timestamp, _uid, _tags]

                    if elem.tag == 'node':
                        args.extend((_lon, _lat))

                    elif elem.tag == 'way':
                        args.append(tuple(_nodes))

                    elif elem.tag == 'relation':
                        args.append(tuple(_members))

                    elem.clear()

                    yield _type(*args)
Beispiel #3
0
    def parse(self, fp):
        d = json.load(fp)
        de = d["elements"]

        # common
        _type = None
        _id = None
        _version = None
        _changeset = None
        _timestamp = None
        _uid = None
        _tags = None
        # node only
        _lon = None
        _lat = None
        # way only
        _nodes = None
        # relation only
        _members = None

        for elem in de:
            tag = elem["type"]
            attrs = elem

            if tag in ('node', 'way', 'relation'):
                _id = long(attrs['id'])
                try:
                    _version = int(attrs['version'])
                except:
                    _version = 0

                try:
                    _changeset = int(attrs['changeset'])
                except:
                    _changeset = 0

                # TODO: improve timestamp parsing - dateutil too slow
                try:
                    _tstxt = attrs['timestamp']
                    _timestamp = int(
                        (datetime(year=int(_tstxt[0:4]),
                                  month=int(_tstxt[5:7]),
                                  day=int(_tstxt[8:10]),
                                  hour=int(_tstxt[11:13]),
                                  minute=int(_tstxt[14:16]),
                                  second=int(_tstxt[17:19]),
                                  tzinfo=None) -
                         datetime(year=1970, month=1, day=1,
                                  tzinfo=None)).total_seconds())
                except:
                    _timestamp = 0

                try:  # An object can miss an uid (when anonymous edits were possible)
                    _uid = int(attrs['uid'])
                except:
                    uid = 0

                _tags = {}

                if tag == 'node':
                    _type = Node
                    _lon = float(attrs['lon'])
                    _lat = float(attrs['lat'])
                elif tag == 'way':
                    _type = Way
                    _nodes = []
                elif tag == 'relation':
                    _type = Relation
                    _members = []

            if "tags" in elem:
                _tags = elem["tags"]

            if "nodes" in elem:
                _nodes = [long(x) for x in elem["nodes"]]

            if 'members' in elem:
                for m in elem["members"]:
                    _members.append(
                        RelationMember(unicode(m['role']), {
                            'node': Node,
                            'way': Way,
                            'relation': Relation
                        }[m['type']], long(m['ref'])))

            args = [_id, _version, _changeset, _timestamp, _uid, _tags]

            if tag == 'node':
                args.extend((_lon, _lat))

            elif tag == 'way':
                args.append(tuple(_nodes))

            elif tag == 'relation':
                args.append(tuple(_members))

            yield _type(*args)