Load a Graph from .osm file using Osmnx/Python - python

I want to load a graph from XML, i.e. .osm file, using Osmnx Python library.
The .osm file contains roads not connected each other, for example only highway=primary and highway=primary_link of a country's region.
I use the parameter retain_all to avoid discarding all the roads, since
retain_all: if True, return the entire graph even if it is not connected. otherwise, retain only the largest weakly connected component.
I use this instruction:
graph = ox.graph_from_xml('temp.osm', retain_all=True)
But I get the following error
AttributeError: 'float' object has no attribute 'deg2rad'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "D:\code.py", line 37, in <module>
graph = ox.graph_from_xml('temp.osm', retain_all=True)
File "D:\Python\lib\site-packages\osmnx\graph.py", line 518, in graph_from_xml
G = _create_graph(response_jsons, bidirectional=bidirectional, retain_all=retain_all)
File "D:\Python\lib\site-packages\osmnx\graph.py", line 587, in _create_graph
G = distance.add_edge_lengths(G)
File "D:\Python\lib\site-packages\osmnx\distance.py", line 154, in add_edge_lengths
dists = great_circle_vec(c[:, 0], c[:, 1], c[:, 2], c[:, 3]).round(precision)
File "D:\Python\lib\site-packages\osmnx\distance.py", line 60, in great_circle_vec
y1 = np.deg2rad(lat1)
TypeError: loop of ufunc does not support argument 0 of type float which has no callable deg2rad method
If I remove retain_all parameter, of course, the error does not occurr but the graph will contain only one primary road.
How can I keep all the roads even if not connected in the map?

I forgot to post my solution. I solved using another Python library, called Pyrosm:
osm = OSM('temp.pbf')
nodes, edges = osm.get_network(nodes=True, network_type='driving')
graph = osm.to_graph(nodes, edges, graph_type='networkx', retain_all=True)

Related

What is the type of the below argument in Pyx?

The official documentation describes that layers can be used to set the occlusion of rendered elements
canvas.layer(name, above=None, below=None)
This method creates or gets a layer with name name.
A layer is a canvas itself and can be used to combine drawing operations for ordering purposes, i.e., what is above and below each
other. The layer name name is a dotted string, where dots are used to
form a hierarchy of layer groups. When inserting a layer, it is put on
top of its layer group except when another layer instance of this
group is specified by means of the parameters above or below.
Well I tried the following:
c = canvas.canvas().layer("top")
t = canvas.canvas().layer("bot", below="top")
t = canvas.canvas().layer("bot", below=c)
t = canvas.canvas().layer("bot", below=0)
They all return with some error. For example the string version:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/pyx/canvas.py", line 296, in layer
group, layer = name.split(".", 1)
ValueError: not enough values to unpack (expected 2, got 1)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "EdgeRefining/refine_edges.py", line 174, in <module>
t = canvas.canvas().layer("bot", below="top")
File "/usr/lib/python3/dist-packages/pyx/canvas.py", line 312, in layer
self.items.insert(self.items.index(self.layers[below]), self.layers[name])
KeyError: 'top'
Has anyone used this functionality?
Layers are canvas instances within a canvas. Here is an example:
from pyx import *
c = canvas.canvas()
l1 = c.layer('l1')
l2 = c.layer('l2')
l1.fill(path.circle(0, 0, 2), [color.rgb.red])
l2.fill(path.circle(3, 0, 2), [color.rgb.green])
c.writePDFfile()
Now you can add below='l1' when creating the layer l2 and the red circle will be placed above the green circle. The problem in your code was, that you created new canvas instances all the time, however, multiple layers are to be used within the same canvas.

OSMNX KeyError: 'x' when trying to get_nearest_nodes()

I currently have a process where I
Download Open Street data using ox.geocode_to_gdf()
Get the Geopackage edges and nodes using and use gpd.overlay() to edit the edges and nodes based on another map
Convert edited edges back to OSMNX as a graph using ox.graph_from_gdfs()
At this stage, I have a graph (sample here)
where I would like to use to estimate the shortest path among some points. I have the Easting and Northing of these points and I am trying to get he nearest nodes to these cooridnates using
nodes_flood = ox.distance.get_nearest_nodes(g_post_200_Cur_centre, Easting, Northing)
so that I can run nx.shortest_path() with the graph and destination nodes. But I get an error message
File "<ipython-input-74-ed9774662a83>", line 1, in <module>
nodes_flood = ox.distance.get_nearest_nodes(g_post_200_Cur_centre, Easting, Northing)
File "/Users/opt/anaconda3/envs/Kinshasa/lib/python3.7/site-packages/osmnx/distance.py", line 256, in get_nearest_nodes
nn = [get_nearest_node(G, (y, x), method="haversine") for x, y in zip(X, Y)]
File "/Users/opt/anaconda3/envs/Kinshasa/lib/python3.7/site-packages/osmnx/distance.py", line 256, in <listcomp>
nn = [get_nearest_node(G, (y, x), method="haversine") for x, y in zip(X, Y)]
File "/Users/opt/anaconda3/envs/Kinshasa/lib/python3.7/site-packages/osmnx/distance.py", line 138, in get_nearest_node
df = pd.DataFrame(coords, columns=["node", "x", "y"]).set_index("node")
File "/Users/opt/anaconda3/envs/Kinshasa/lib/python3.7/site-packages/pandas/core/frame.py", line 563, in __init__
data = list(data)
File "/Users/opt/anaconda3/envs/Kinshasa/lib/python3.7/site-packages/osmnx/distance.py", line 137, in <genexpr>
coords = ((n, d["x"], d["y"]) for n, d in G.nodes(data=True))
KeyError: 'x'
Not sure what is causing this. I have OSMNX v1.0.
I fixed the error by passing the method argument to the get_nearest_nodes(). If you chose the 'kdtree' as the method, you will not have the error.
nodes_flood = ox.distance.get_nearest_nodes(g_post_200_Cur_centre, Easting, Northing, method='kdtree')
However, I still don't know the reason for the error if I was not passing the method name.

build KDtree: non-sensical error during query

I'm trying to assess an interpolation scheme, so I'm looking to compare the input points (red) to the resultant grid (blue). I've built two K-D trees looking to find the nearest blue dot to each red dot (with some radius). My limited understanding suggests that the query_ball_tree would provide the results I'm looking for once my trees are built.
gridTree = spatial.cKDTree(data=np.c_[np.array(xx.flatten()), np.array(yy.flatten())])
obsTree = spatial.cKDTree(data=np.c_[np.array(bathy['x']), np.array(bathy['y'])])
dist, idx = obsTree.query_ball_tree(gridTree, 2) # find points in grid that match obs
which produces the below error.
Traceback (most recent call last):
File "/home/repos/pyObjectiveMapping/operation_FRF_duneLidarDEM_bathy_interp.py", line 211, in <module>
dist, idx = obsTree.query_ball_tree(gridTree, 2)
ValueError: too many values to unpack (expected 2)
if I try to remove the "extra" argument:
dist, idx = obsTree.query_ball_tree(gridTree)
I get the below error (as expected, because it needs both)
Traceback (most recent call last):
File "/home/spike/anaconda3/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3331, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-5-022d5ab7a46f>", line 4, in <module>
dist, idx = obsTree.query_ball_tree(gridTree)
File "ckdtree.pyx", line 1001, in scipy.spatial.ckdtree.cKDTree.query_ball_tree
TypeError: query_ball_tree() takes at least 2 positional arguments (1 given)
so the error is not representing the problem effectively. I've checked and removed all masked data before entering it into the trees. I've tried removing the reds that were outside of the blue domain, that didn't help (didn't think it should matter, but wanted to check anyway). I've tried different radii values and had similar results.

Export graph to graphml with node positions using NetworkX

I'm using NetworkX 1.9.1.
I have a graph that I need to organize with positions and I then export to graphml format.
I've tried code in this question. It does not work, here is my example
import networkx as nx
import matplotlib.pyplot as plt
G = nx.read_graphml("colored.graphml")
pos=nx.spring_layout(G) # an example of quick positioning
nx.set_node_attributes(G, 'pos', pos)
nx.write_graphml(G, "g.graphml")
nx.draw_networkx(G, pos)
plt.savefig("g.pdf")
Here are the errors I get, the problem is how positions are saved (graphml does not accept arrays).
C:\Anaconda\python.exe C:/Users/sturaroa/Documents/PycharmProjects/node_labeling_test.py
Traceback (most recent call last):
File "C:/Users/sturaroa/Documents/PycharmProjects/node_labeling_test.py", line 11, in <module>
nx.write_graphml(G, "g.graphml")
File "<string>", line 2, in write_graphml
File "C:\Anaconda\lib\site-packages\networkx\utils\decorators.py", line 220, in _open_file
result = func(*new_args, **kwargs)
File "C:\Anaconda\lib\site-packages\networkx\readwrite\graphml.py", line 82, in write_graphml
writer.add_graph_element(G)
File "C:\Anaconda\lib\site-packages\networkx\readwrite\graphml.py", line 350, in add_graph_element
self.add_nodes(G,graph_element)
File "C:\Anaconda\lib\site-packages\networkx\readwrite\graphml.py", line 307, in add_nodes
self.add_attributes("node", node_element, data, default)
File "C:\Anaconda\lib\site-packages\networkx\readwrite\graphml.py", line 300, in add_attributes
scope=scope, default=default_value)
File "C:\Anaconda\lib\site-packages\networkx\readwrite\graphml.py", line 288, in add_data
'%s as data values.'%element_type)
networkx.exception.NetworkXError: GraphML writer does not support <type 'numpy.ndarray'> as data values.
I'm under the impression that I would be better off defining positions as 2 separate node attributes, x and y, and save them separately, defining a key for each of them in the graphml format, like this.
However, I'm not that familiar with Python, and would like your opinion before I make a mess iterating back and forth.
Thanks.
You are right, GraphML want's simpler attributes (no numpy arrays or lists).
You can set the x and y positions of the nodes as attributes like this
G = nx.path_graph(4)
pos = nx.spring_layout(G)
for node,(x,y) in pos.items():
G.node[node]['x'] = float(x)
G.node[node]['y'] = float(y)
nx.write_graphml(G, "g.graphml")

ZeroDivisionError when using scipy.interpolate.griddata

I'm getting a ZeroDivisionError from the following code:
#stacking the array into a complex array allows np.unique to choose
#truely unique points. We also keep a handle on the unique indices
#to allow us to index `self` in the same order.
unique_points,index = np.unique(xdata[mask]+1j*ydata[mask],
return_index=True)
#Now we break it into the data structure we need.
points = np.column_stack((unique_points.real,unique_points.imag))
xx1,xx2 = self.meta['rcm_xx1'],self.meta['rcm_xx2']
yy1 = self.meta['rcm_yy2']
gx = np.arange(xx1,xx2+dx,dx)
gy = np.arange(-yy1,yy1+dy,dy)
GX,GY = np.meshgrid(gx,gy)
xi = np.column_stack((GX.ravel(),GY.ravel()))
gdata = griddata(points,self[mask][index],xi,method='linear',
fill_value=np.nan)
Here, xdata,ydata and self are all 2D numpy.ndarrays (or subclasses thereof) with the same shape and dtype=np.float32. mask is a 2d ndarray with the same shape and dtype=bool. Here's a link for those wanting to peruse the scipy.interpolate.griddata documentation.
Originally, xdata and ydata are derived from a non-uniform cylindrical grid that has a 4 point stencil -- I thought that the error might be coming from the fact that the same point was defined multiple times, so I made the set of input points unique as suggested in this question. Unfortunately, that hasn't seemed to help. The full traceback is:
Traceback (most recent call last):
File "/xxxxxxx/rcm.py", line 428, in <module>
x[...,1].to_pz0()
File "/xxxxxxx/rcm.py", line 285, in to_pz0
fill_value=fill_value)
File "/usr/local/lib/python2.7/site-packages/scipy/interpolate/ndgriddata.py", line 183, in griddata
ip = LinearNDInterpolator(points, values, fill_value=fill_value)
File "interpnd.pyx", line 192, in scipy.interpolate.interpnd.LinearNDInterpolator.__init__ (scipy/interpolate/interpnd.c:2935)
File "qhull.pyx", line 996, in scipy.spatial.qhull.Delaunay.__init__ (scipy/spatial/qhull.c:6607)
File "qhull.pyx", line 183, in scipy.spatial.qhull._construct_delaunay (scipy/spatial/qhull.c:1919)
ZeroDivisionError: float division
For what it's worth, the code "works" (No exception) if I use the "nearest" method.

Categories