Exemplo n.º 1
0
    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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
	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
Exemplo n.º 4
0
	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
Exemplo n.º 5
0
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