importing graph into geopandas using networkx - networkx

Is it possible to create a node edge graph in geopandas or can we in anyway import networkx graph into geopandas. I want to create a directed graph in geopandas.

Related

Intersection of points and polygons using geopandas

I am using the Australian Bureau of Statistics data (ABS) to visualize meshblocks and boundaries of buffer data from a centre of location with certain radius.
I want to create the following plot:
intersection plot
So far, I am able to create a function which can give me a circle with certain radius depending on the initial coordinates (lon, lat) I have provided.
I have used the following function to plot the circle around the required location on the map:
import geopandas as gpd
import pandas as pd
import leaflet
from osgeo import gdal
import shapefile as shp
def func_radius_around_point(point_list,m_list,crs_from,crs_to):
points_df = pd.DataFrame(point_list).reset_index()
points_df = points_df.rename(columns={0:'geometry'})
points_gpd = gpd.GeoDataFrame(points_df,geometry='geometry',crs=crs_from)
for m in m_list:
buffered= points_gpd.to_crs(epsg=crs_to).buffer(m).to_crs(epsg=crs_from)
col_name = 'buffered_{m}'.format(m=m)
points_gpd[col_name] = buffered
return points_gpd
I have the data for mesh block and statistical area 1. All I want to create is the intersection of points and polygon. How do I create this intersection using geopandas?
With R, it seems so much easier using the simple features library. Is there a simple features package in geopandas that I have missed out on?

OSMnx finding the shortest path of a directed graph using networkx

In OSMnx the streets are directed in order to preserve one-way directionality and therefore, when I try to find the shortest path using Networkx I get NetworkXNoPath: No path to (osmid). How do I fix this issue? I need to find the shortest path in a network with one-way streets.
See code below:
import osmnx as ox
import networkx as nx
# define place
centreLat=40.771687
centreLon=-73.957233
# download osm data
G= ox.graph_from_point((centreLat,centreLon), distance=1000, network_type='drive',simplify = True)
# plot the graph
fig,ax = ox.plot_graph(G)
# Get origin x and y coordinates
orig_xy = 40.7647425, -73.9683181
# Get target x and y coordinates
target_xy =40.7804348, -73.9498809
# Find the node in the graph that is closest to the origin point (here, we want to get the node id)
orig_node = ox.get_nearest_node(G, orig_xy, method='euclidean')
# Find the node in the graph that is closest to the target point (here, we want to get the node id)
target_node = ox.get_nearest_node(G, target_xy, method='euclidean')
# Get shortest path
route = nx.shortest_path(G, source=orig_node, target=target_node, weight='length')
# Plot the shortest path
fig, ax = ox.plot_graph_route(G, route, origin_point=orig_xy, destination_point=target_xy)
This issue was fixed by creating the strongly connected components of the directed graph in order to make sure that every vertex is accessible from every other vertex.
G=ox.geo_utils.get_largest_component(G,strongly=True)

Extract constrained polygon using OSMnx

I'm playing around with OSMnx package in order to solve the following task:
- there is a point X on the map defined by latitude and longitude
- we need to detect a polygon that contains that point X and is constrained by the neighboring roads
- so basically the point X is inside the polygon and the neighboring roads will be borders of that polygon.
So far I've managed only to plot the visualization of the graph on the map and find the closest edge/node to point X.
In the attached image I've highlighted the area I want to extract in red.
As you are trying to find a polygon containing your point, you first need to generate polygons out of multilinestring geometry. As you did not provide your data I am downloading a sample from OSM using OSMnx.
import osmnx as ox
import geopandas as gpd
import shapely
point = (40.742623, -73.977857)
streets_graph = ox.graph_from_point(point, distance=500, network_type='drive')
streets_graph = ox.project_graph(streets_graph)
I have reprojected it as it is way more convenient than working with degrees, especially if you want to measure anything.
You then have to convert OSMnx graph to geopandas GeoDataFrame.
streets = ox.save_load.graph_to_gdfs(streets_graph, nodes=False, edges=True,
node_geometry=False, fill_edge_geometry=True)
To get some point I can work with, I'll just use the one in the centre of this geodataframe.
point = streets.unary_union.centroid
This is what it looks like.
Next you need to get polygons of your blocks defined by streets, using shapely.ops.polygonize as I suggested in the comment above and store them as GeoSeries.
polygons = shapely.ops.polygonize(streets.geometry)
polygons = gpd.GeoSeries(polygons)
The only thing you have to do next is to find which polygon contains your point.
target = polygons.loc[polygons.contains(point)]
Plotting it again:
ax = target.plot()
gpd.GeoSeries([point]).plot(ax=ax, color='r')
If you want to know which streets are forming the boundary of this polygon, just intersect it with the original network. I am filtering for MultiLineString to exclude streets which intersects the polygon only in one point.
target_streets = streets.loc[streets.intersection(target.iloc[0]).type == 'MultiLineString']
This is how the result of that looks like.
ax = target_streets2.plot()
gpd.GeoSeries([point]).plot(ax=ax, color='r')
Hope it helps.

Implement a directed Graph as an undirected graph using GraphX

I have following directed graph as given by the nodes and edges below.
Nodes
1,2,3,4,5
Edges
(1,2),(1,3),(1,4),(2,5),(3,4),(3,5),(4,5)
How do I convert this directed graph to undirected graph
Do I have to convert using built-in method. If there is build in method, what method is it?.
Or, do I have to add edges manually in the dataset such as (1,2) to (2,1).
You don't need to convert your graph to an undirected graph. You'll simply have to treat it as an undirected graph (by simply ignoring the edge directions).
For example, if you use collectNeighbors, you can make it act as an undirected graph by passing an EdgeDirection.Either as parameter.

matplotlib — are there actual PyPlot objects that interact with Basemap objects?

Looking at the Basemap docs, I can see how a Basemap object is instantiated and overlaid with content:
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np
map = Basemap(projection='ortho',lat_0=45,lon_0=-100,resolution='l')
map.drawcoastlines(linewidth=0.25)
...
The object is named map and various Basemap methods act on it. But I can't understand how, later in the same code, PyPlot (imported as plt) behaves. There seems to be no distinct PyPlot object, and the calls to the PyPlot module never mention map:
# make up some data on a regular lat/lon grid.
nlats = 73; nlons = 145; delta = 2.*np.pi/(nlons-1)
lats = (0.5*np.pi-delta*np.indices((nlats,nlons))[0,:,:])
lons = (delta*np.indices((nlats,nlons))[1,:,:])
wave = 0.75*(np.sin(2.*lats)**8*np.cos(4.*lons))
mean = 0.5*np.cos(2.*lats)*((np.sin(2.*lats))**2 + 2.)
# compute native map projection coordinates of lat/lon grid.
x, y = map(lons*180./np.pi, lats*180./np.pi)
# contour data over the map.
cs = map.contour(x,y,wave+mean,15,linewidths=1.5)
plt.title('contour lines over filled continent background')
plt.show()
How and where does PyPlot interact with the map object?
Also, in the third line of code from the bottom, why is variable cs being assigned, since it isn't actually used elsewhere in the code? I see no difference in the output with cs = removed.
pyplot is just an interface to various matplotlib modules. For example, plt.plot() finds the current Axes object (let's call it ax) and the uses the ax.plot() method to do the drawing.
In general, operating on the Axes, or in this case Basemap objects directly is the greatly preferred style.