def parse_osm(self, fname, target, dname="area", get_area=False, override_area=False): tree = ElementTree.parse(fname) root = tree.getroot() relations = root.getiterator("relation") ways = root.getiterator("way") nodes = root.getiterator("node") print "scanning", len(relations), "relations" nbAdmin = 0 for r in relations: # scan each relation isAdmin = False inCountry = False name = "" pop = 0 ref = 0 admin_level = 0 country = "" try: id = long(r.get("id")) except: id = -1 print "* error retrieving attribute 'id' for admin relation" for tag in r.getiterator( "tag"): # for one relation, scan each tags k = tag.get("k") if k == 'admin_level': nbAdmin = nbAdmin + 1 try: v = int(tag.get("v")) isAdmin = ((target <> 0) and (v == target)) or ( (target == 0) and (v == 4 or v == 6 or v == 8)) admin_level = v except: print "* error relation #%d : retrieving 'place'" % id if k == 'name': name = tag.get("v") if k == 'population': try: pop = int(tag.get("v")) except: pop = -1 if k == 'ref' or k == 'ref:INSEE': try: ref = int(tag.get("v")) inCountry = True except: ref = -1 if isAdmin and inCountry: t0 = time.time() print "> %s (%d), admin=%d" % (name, ref, v) # create the object to store data if admin_level == 4: # region o = OSMRegion(id) self.regions.append(o) if admin_level == 6: # departement o = OSMDepartement(id) self.departements.append(o) if admin_level == 8: # communes o = OSMCommune(id) self.communes.append(o) o.name = name o.population = pop o.ref = ref o.level = admin_level # get the admin_centre node or compute the barycentre + store nodes (if get_area==True) waysID = [] nodesID = [] if get_area: nodearea = [] wayarea = [] is_node = -1 for m in r.getiterator("member"): ref = long(m.get("ref")) type = m.get("type") role = m.get("role") if type == "node" and ( role == "admin_centre" or role == "admin_center"): # has an admin_centre is_node = ref if type == "way": waysID.append(ref) if get_area: wayarea.append(pyOSM.Way(ref)) if is_node > 0: # store the admin_centre o.node.osm_id = is_node try: o.node.name = "not found" for n in nodes: ref = long(n.get("id")) if ref == is_node: ll = float(n.get("lat")) lo = float(n.get("lon")) o.node.location = (ll, lo) try: for tag in n.getiterator("tag"): k = tag.get("k") if k == "name": o.node.name = tag.get("v") except: o.node.name = "admin_centre has no name" break except: o.node.location = (0.0, 0.0) print "admin_centre %d for %s has no location" % ( is_node, o.name) if is_node < 0 or get_area: # compute a barycentre and store nodes if len(waysID) > 0: for w in ways: wr = long(w.get("id")) if get_area: wo = pyOSM.is_in(wayarea, wr) else: wo = None if wr in waysID: for n in w.getiterator("nd"): nr = long(n.get("ref")) nodesID.append(nr) if wo: nodearea.append((wr, nr)) wo.add_node(pyOSM.Node(nr)) if len(nodesID): nb_nodes = 0 lat, lon = (0.0, 0.0) for n in nodes: ref = long(n.get("id")) if ref in nodesID: nb_nodes = nb_nodes + 1 ll = float(n.get("lat")) lo = float(n.get("lon")) if ll and lo: lat = lat + ll lon = lon + lo if get_area: for wr, nr in nodearea: if nr == ref: wo = pyOSM.is_in(wayarea, wr) if wo: no = wo.get_node(ref) if ll == 0.0 or lo == 0.0: print "bad location for node %d in way %d" % ( wr, nr) no.location = (ll, lo) else: print "wo %d not found for node %d" % ( wr, nr) if nb_nodes > 0: lat = lat / nb_nodes lon = lon / nb_nodes if get_area: o.area.add_sorted_ways(wayarea) noloc = [] for n in o.area.nodes: ll, lo = n.location if ll == 0.0 or lo == 0.0: noloc.append(n.osm_id) print "\t%d node missing" % len(noloc) if len(noloc) > 0: print "\t", noloc o.area.osm_id = o.osm_id o.area.name = o.name filename = os.path.join( dname, "fr%d_%d_%s.xml" % (o.level, o.ref, o.name)) ensure_dir(filename) if not os.path.exists(filename) or override_area: o.area.save(filename) o.node.osm_id = is_node if is_node < 0: o.node.name = "barycenter" o.node.location = (lat, lon) t0 = time.time() - t0 o.show(False) print "\t>%.1f seconds" % t0 return nbAdmin
def get_area(relations, ways, nodes, name): """ get_area extract from relations, ways and nodes list an admin boundary (level=8 for city) build a way (osm data structure) for this boundary """ id = -1 area = pyOSM.Area() # scan relations to find the right boundary=administrative (admin_level=8 + name) for r in relations: is_zone = False is_subzone = False is_name = False for tag in r.getiterator("tag"): k = tag.get("k") if k == zone_tag: if tag.get("v") == zone_value: is_zone = True if k == zone_subtag: if tag.get("v") == zone_subvalue: is_subzone = True if k == "name": if tag.get("v") == name: is_name = True # we match the correct relation : handle it if is_zone and is_subzone and is_name: id = long(r.get("id")) if _debug_: print "\tfound relation:", id, "build way(s) and node(s)" waylist = [] nodelist = [] # extract members to build in memory the way list and node(s) corresponding (with location) for m in r.getiterator("member"): if m.get("type") == "way": ref = long(m.get("ref")) w = pyOSM.Way(ref) waylist.append(w) if len(waylist) > 0: # scan way list and pre-build nodes print "\t\textract", len(waylist), "way(s)" for w in ways: wid = long(w.get("id")) wo = pyOSM.is_in(waylist, wid) if wo != None: for t in w.getiterator("tag"): name = t.get("name") if name != None: wo.name = name nb = 0 for n in w.getiterator("nd"): nid = long(n.get("ref")) nodelist.append((wid, nid)) n0 = pyOSM.Node(nid) wo.add_node(n0) nb = nb + 1 if len( nodelist ) > 0: # complete node informations for way list by scanning all the nodes and extract location print "\t\textract", len(nodelist), "node(s)" for node in nodes: ref = long(node.get("id")) for i in nodelist: if i[1] == ref: wo = pyOSM.is_in(waylist, i[0]) if wo: n = wo.get_node(ref) if n != None: ll = float(node.get("lat")) lo = float(node.get("lon")) n.location = (ll, lo) if len(waylist) > 0: # ordered the way in the logical order to describe the polygon (the last node of a way is the first of the next) print "\t\tordering", len(waylist), "ways" area.add_sorted_ways(waylist) return area
def parse_osm(self,fname,dname="area",get_area=False,override_area=False): tree=ElementTree.parse(fname) root=tree.getroot() relations=root.getiterator("relation") ways=root.getiterator("way") nodes=root.getiterator("node") print "scanning",len(relations),"relations" nbAdmin=0 o=None relationsID=[] for r in relations: # scan each relation name="" pop=0 admin_level=0 try: id=long(r.get("id")) if id==france_id: for tag in r.getiterator("tag"): # for one relation, scan each tags k=tag.get("k") if k=='admin_level': nbAdmin=nbAdmin+1 try: v=int(tag.get("v")) admin_level=v except: print "* error relation #%d : retrieving 'place'" %id if k=='name': name=tag.get("v") if k=='population': try: pop=int(tag.get("v")) except: pop=-1 print "France found:",id,name o=OSMCountry(id) self.pays.append(o) o.name=name o.population=pop o.level=admin_level is_node=-1 for m in r.getiterator("member"): ref=long(m.get("ref")) type=m.get("type") role=m.get("role") if type=="node" and (role=="capital" or role=="admin_centre" or role=="admin_center"): # has an admin_centre is_node=ref if type=="relation": relationsID.append(ref) if is_node>0: # store the admin_centre o.node.osm_id=is_node try: o.node.name="not found" for n in nodes: ref=long(n.get("id")) if ref==is_node: ll=float(n.get("lat")) lo=float(n.get("lon")) o.node.location=(ll,lo) try: for tag in n.getiterator("tag"): k=tag.get("k") if k=="name": o.node.name=tag.get("v") except: o.node.name="admin_centre has no name" break except: o.node.location=(0.0,0.0) print "admin_centre %d for %s has no location" % (is_node,o.name) except: id=-1 print "* error retrieving attribute 'id' for admin relation" print sys.exc_info() if o!=None: # if we found the mother relation, then proceed on sister relation waysID=[] nodesID=[] nodearea=[] wayarea=[] is_node=-1 print "scanning %d relations" % len(relations) for r in relations: # scan each relation for sister relations name="" try: id=long(r.get("id")) except: id=-1 print "* error retrieving attribute 'id' for admin relation" if id in relationsID: #it's a sister relation, handle for tag in r.getiterator("tag"): # for one relation, scan each tags k=tag.get("k") if k=='admin_level': nbAdmin=nbAdmin+1 if k=='name': name=tag.get("v") for m in r.getiterator("member"): ref=long(m.get("ref")) type=m.get("type") role=m.get("role") if type=="way": waysID.append(ref) wayarea.append(pyOSM.Way(ref)) print "Scanning %d way(s)" % len(waysID) if len(waysID)>0: for w in ways: wr=long(w.get("id")) wo=pyOSM.is_in(wayarea,wr) if wr in waysID: for n in w.getiterator("nd"): nr=long(n.get("ref")) nodesID.append(nr) if wo: nodearea.append((wr,nr)) wo.add_node(pyOSM.Node(nr)) print "Retrieving %d node(s)" % len(nodesID) if len(nodesID): nb_nodes=0 lat,lon=(0.0,0.0) for n in nodes: ref=long(n.get("id")) if ref in nodesID: nb_nodes=nb_nodes+1 ll=float(n.get("lat")) lo=float(n.get("lon")) if ll and lo: lat=lat+ll lon=lon+lo for wr,nr in nodearea: if nr==ref: wo=pyOSM.is_in(wayarea,wr) if wo: no=wo.get_node(ref) if ll==0.0 or lo==0.0: print "bad location for node %d in way %d" % (wr,nr) no.location=(ll,lo) else: print "wo %d not found for node %d" % (wr,nr) if nb_nodes>0: lat=lat/nb_nodes lon=lon/nb_nodes # sort ways o.area.add_sorted_ways(wayarea) noloc=[] for n in o.area.nodes: ll,lo=n.location if ll==0.0 or lo==0.0: noloc.append(n.osm_id) if len(noloc)>0: print "\t%d node without location" % len(noloc) print "\t",noloc o.area.osm_id=o.osm_id o.area.name=o.name filename=os.path.join(dname,"fr%d_%s.xml" % (o.level,o.name)) ensure_dir(filename) o.area.save(filename) o.node.osm_id=is_node if is_node<0: o.node.name="barycenter" o.node.location=(lat,lon) o.show(False) return nbAdmin
def parse_osm(self,fname,target,dname="area",get_area=False,override_area=False): tree=ElementTree.parse(fname) root=tree.getroot() relations=root.getiterator("relation") ways=root.getiterator("way") nodes=root.getiterator("node") print "scanning",len(relations),"relations" nbAdmin=0 for r in relations: # scan each relation isAdmin=False inCountry=False name="" pop=0 ref=0 admin_level=0 country="" try: id=long(r.get("id")) except: id=-1 print "* error retrieving attribute 'id' for admin relation" for tag in r.getiterator("tag"): # for one relation, scan each tags k=tag.get("k") if k=='admin_level': nbAdmin=nbAdmin+1 try: v=int(tag.get("v")) isAdmin=((target<>0) and (v==target)) or ((target==0)and(v==4 or v==6 or v==8)) admin_level=v except: print "* error relation #%d : retrieving 'place'" %id if k=='name': name=tag.get("v") if k=='population': try: pop=int(tag.get("v")) except: pop=-1 if k=='ref' or k=='ref:INSEE': try: ref=int(tag.get("v")) inCountry=True except: ref=-1 if isAdmin and inCountry: t0=time.time() print "> %s (%d), admin=%d" % (name,ref,v) # create the object to store data if admin_level==4: # region o=OSMRegion(id) self.regions.append(o) if admin_level==6: # departement o=OSMDepartement(id) self.departements.append(o) if admin_level==8: # communes o=OSMCommune(id) self.communes.append(o) o.name=name o.population=pop o.ref=ref o.level=admin_level # get the admin_centre node or compute the barycentre + store nodes (if get_area==True) waysID=[] nodesID=[] if get_area: nodearea=[] wayarea=[] is_node=-1 for m in r.getiterator("member"): ref=long(m.get("ref")) type=m.get("type") role=m.get("role") if type=="node" and (role=="admin_centre" or role=="admin_center"): # has an admin_centre is_node=ref if type=="way": waysID.append(ref) if get_area: wayarea.append(pyOSM.Way(ref)) if is_node>0: # store the admin_centre o.node.osm_id=is_node try: o.node.name="not found" for n in nodes: ref=long(n.get("id")) if ref==is_node: ll=float(n.get("lat")) lo=float(n.get("lon")) o.node.location=(ll,lo) try: for tag in n.getiterator("tag"): k=tag.get("k") if k=="name": o.node.name=tag.get("v") except: o.node.name="admin_centre has no name" break except: o.node.location=(0.0,0.0) print "admin_centre %d for %s has no location" % (is_node,o.name) if is_node<0 or get_area: # compute a barycentre and store nodes if len(waysID)>0: for w in ways: wr=long(w.get("id")) if get_area: wo=pyOSM.is_in(wayarea,wr) else: wo=None if wr in waysID: for n in w.getiterator("nd"): nr=long(n.get("ref")) nodesID.append(nr) if wo: nodearea.append((wr,nr)) wo.add_node(pyOSM.Node(nr)) if len(nodesID): nb_nodes=0 lat,lon=(0.0,0.0) for n in nodes: ref=long(n.get("id")) if ref in nodesID: nb_nodes=nb_nodes+1 ll=float(n.get("lat")) lo=float(n.get("lon")) if ll and lo: lat=lat+ll lon=lon+lo if get_area: for wr,nr in nodearea: if nr==ref: wo=pyOSM.is_in(wayarea,wr) if wo: no=wo.get_node(ref) if ll==0.0 or lo==0.0: print "bad location for node %d in way %d" % (wr,nr) no.location=(ll,lo) else: print "wo %d not found for node %d" % (wr,nr) if nb_nodes>0: lat=lat/nb_nodes lon=lon/nb_nodes if get_area: o.area.add_sorted_ways(wayarea) noloc=[] for n in o.area.nodes: ll,lo=n.location if ll==0.0 or lo==0.0: noloc.append(n.osm_id) print "\t%d node missing" % len(noloc) if len(noloc)>0: print "\t",noloc o.area.osm_id=o.osm_id o.area.name=o.name filename=os.path.join(dname,"fr%d_%d_%s.xml" % (o.level,o.ref,o.name)) ensure_dir(filename) if not os.path.exists(filename) or override_area: o.area.save(filename) o.node.osm_id=is_node if is_node<0: o.node.name="barycenter" o.node.location=(lat,lon) t0=time.time()-t0 o.show(False) print "\t>%.1f seconds" % t0 return nbAdmin
def get_area(relations,ways,nodes,name): """ get_area extract from relations, ways and nodes list an admin boundary (level=8 for city) build a way (osm data structure) for this boundary """ id=-1 area=pyOSM.Area() # scan relations to find the right boundary=administrative (admin_level=8 + name) for r in relations: is_zone=False is_subzone=False is_name=False for tag in r.getiterator("tag"): k=tag.get("k") if k==zone_tag: if tag.get("v")==zone_value: is_zone=True if k==zone_subtag: if tag.get("v")==zone_subvalue: is_subzone=True if k=="name": if tag.get("v")==name: is_name=True # we match the correct relation : handle it if is_zone and is_subzone and is_name: id=long(r.get("id")) if _debug_: print "\tfound relation:",id,"build way(s) and node(s)" waylist=[] nodelist=[] # extract members to build in memory the way list and node(s) corresponding (with location) for m in r.getiterator("member"): if m.get("type")=="way": ref=long(m.get("ref")) w=pyOSM.Way(ref) waylist.append(w) if len(waylist)>0: # scan way list and pre-build nodes print "\t\textract",len(waylist),"way(s)" for w in ways: wid=long(w.get("id")) wo=pyOSM.is_in(waylist,wid) if wo!=None: for t in w.getiterator("tag"): name=t.get("name") if name!=None: wo.name=name nb=0 for n in w.getiterator("nd"): nid=long(n.get("ref")) nodelist.append((wid,nid)) n0=pyOSM.Node(nid) wo.add_node(n0) nb=nb+1 if len(nodelist)>0: # complete node informations for way list by scanning all the nodes and extract location print "\t\textract",len(nodelist),"node(s)" for node in nodes: ref=long(node.get("id")) for i in nodelist: if i[1]==ref: wo=pyOSM.is_in(waylist,i[0]) if wo: n=wo.get_node(ref) if n!=None: ll=float(node.get("lat")) lo=float(node.get("lon")) n.location=(ll,lo) if len(waylist)>0: # ordered the way in the logical order to describe the polygon (the last node of a way is the first of the next) print "\t\tordering",len(waylist),"ways" area.add_sorted_ways(waylist) return area