def iter_osm_change_file(f, parse_timestamps=True): action = None obj = None for event, elem in etree.iterparse(f, events=('start', 'end')): if event == 'start': if elem.tag == 'node': obj = model.Node( int(elem.attrib['id']), int(elem.attrib['version']), int(elem.attrib['changeset']), elem.attrib.get('user'), maybeInt(elem.attrib.get('uid')), maybeBool(elem.attrib.get('visible')), isoToDatetime(elem.attrib.get('timestamp')) if parse_timestamps else elem.attrib.get('timestamp'), maybeFloat(elem.attrib.get('lat')), maybeFloat(elem.attrib.get('lon')), []) elif elem.tag == 'way': obj = model.Way( int(elem.attrib['id']), int(elem.attrib['version']), int(elem.attrib['changeset']), elem.attrib.get('user'), maybeInt(elem.attrib.get('uid')), maybeBool(elem.attrib.get('visible')), isoToDatetime(elem.attrib.get('timestamp')) if parse_timestamps else elem.attrib.get('timestamp'), [], []) elif elem.tag == 'tag': obj.tags.append(model.Tag(elem.attrib['k'], elem.attrib['v'])) elif elem.tag == 'nd': obj.nds.append(int(elem.attrib['ref'])) elif elem.tag == 'relation': obj = model.Relation( int(elem.attrib['id']), int(elem.attrib['version']), int(elem.attrib['changeset']), elem.attrib.get('user'), maybeInt(elem.attrib.get('uid')), maybeBool(elem.attrib.get('visible')), isoToDatetime(elem.attrib.get('timestamp')) if parse_timestamps else elem.attrib.get('timestamp'), [], []) elif elem.tag == 'member': obj.members.append( model.Member(elem.attrib['type'], int(elem.attrib['ref']), elem.attrib['role'])) elif elem.tag in ('create', 'modify', 'delete'): action = elem.tag elif event == 'end': if elem.tag == 'node': yield (action, obj) obj = None elif elem.tag == 'way': yield (action, obj) obj = None elif elem.tag == 'relation': yield (action, obj) obj = None elif elem.tag in ('create', 'modify', 'delete'): action = None elem.clear() while elem.getprevious() is not None: del elem.getparent()[0]
def iter_osm_file(f, parse_timestamps=True): """Parse a file-like containing OSM XML and yield one OSM primitive at a time to the caller.""" obj = None for event, elem in etree.iterparse(f, events=('start', 'end')): if event == 'start': if elem.tag == 'node': obj = model.Node( int(elem.attrib['id']), maybeInt(elem.get('version')), maybeInt(elem.get('changeset')), elem.attrib.get('user'), maybeInt(elem.attrib.get('uid')), maybeBool(elem.attrib.get('visible')), isoToDatetime(elem.attrib.get('timestamp')) if parse_timestamps else elem.attrib.get('timestamp'), maybeFloat(elem.get('lat')), maybeFloat(elem.get('lon')), []) elif elem.tag == 'way': obj = model.Way( int(elem.attrib['id']), maybeInt(elem.get('version')), maybeInt(elem.get('changeset')), elem.attrib.get('user'), maybeInt(elem.attrib.get('uid')), maybeBool(elem.attrib.get('visible')), isoToDatetime(elem.attrib.get('timestamp')) if parse_timestamps else elem.attrib.get('timestamp'), [], []) elif elem.tag == 'tag': obj.tags.append(model.Tag(elem.attrib['k'], elem.attrib['v'])) elif elem.tag == 'nd': obj.nds.append(int(elem.attrib['ref'])) elif elem.tag == 'relation': obj = model.Relation( int(elem.attrib['id']), maybeInt(elem.get('version')), maybeInt(elem.get('changeset')), elem.attrib.get('user'), maybeInt(elem.attrib.get('uid')), maybeBool(elem.attrib.get('visible')), isoToDatetime(elem.attrib.get('timestamp')) if parse_timestamps else elem.attrib.get('timestamp'), [], []) elif elem.tag == 'member': obj.members.append( model.Member(elem.attrib['type'], int(elem.attrib['ref']), elem.attrib['role'])) elif elem.tag == 'changeset': obj = model.Changeset( int(elem.attrib['id']), isoToDatetime(elem.attrib.get('created_at')) if parse_timestamps else elem.attrib.get('created_at'), isoToDatetime(elem.attrib.get('closed_at')) if parse_timestamps else elem.attrib.get('closed_at'), maybeBool(elem.attrib['open']), maybeFloat(elem.get('min_lat')), maybeFloat(elem.get('max_lat')), maybeFloat(elem.get('min_lon')), maybeFloat(elem.get('max_lon')), elem.attrib.get('user'), maybeInt(elem.attrib.get('uid')), []) elif event == 'end': if elem.tag == 'node': yield obj obj = None elif elem.tag == 'way': yield obj obj = None elif elem.tag == 'relation': yield obj obj = None elif elem.tag == 'changeset': yield obj obj = None elem.clear() while elem.getprevious() is not None: del elem.getparent()[0]