Created
July 16, 2018 15:08
-
-
Save rohitsuratekar/1bd089668168b2343446cf27c91954a3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Rohit Suratekar | |
July 2018 | |
Simple script to analyze Maps | |
""" | |
import os | |
import geopandas as gpd | |
import matplotlib.pylab as plt | |
import networkx as nx | |
import numpy as np | |
import pandas as pd | |
from descartes import PolygonPatch | |
from shapely.geometry import Point, LineString, Polygon | |
city = "Bangalore, India" # To analyse shapes | |
network_type = 'walk' # Can change to 'drive' for driving routes | |
origin_point = (13.071167, 77.580247) # Origin Point | |
distance_around_point = 4500 # In meter | |
travel_speed = 5 # walking speed in km/hour | |
# Use Cache to avoid repeating network requests. | |
ox.config(log_console=True, use_cache=True) | |
trip_times = [10, 20, 30, 60] # in minutes | |
iso_colors = ox.get_colors(n=len(trip_times), cmap='OrRd', start=0.3, | |
return_hex=True) | |
def get_graph(): | |
try: | |
return ox.graph_from_place(city, network_type=network_type) | |
except TypeError: | |
return ox.graph_from_address(city, distance=30000, | |
network_type=network_type) | |
def plot_direction(): | |
basic_stats = ox.basic_stats(get_graph()) | |
print(basic_stats) | |
G = ox.add_edge_bearings(get_graph()) | |
bearings = pd.Series( | |
[data['bearing'] for u, v, k, data in G.edges(keys=True, data=True)]) | |
n = 30 | |
count, division = np.histogram(bearings, | |
bins=[ang * 360 / n for ang in | |
range(0, n + 1)]) | |
division = division[0:-1] | |
width = 2 * np.pi / n | |
ax = plt.subplot(111, projection='polar') | |
ax.set_theta_zero_location('N') | |
ax.set_theta_direction('clockwise') | |
ax.set_yticklabels([]) | |
bars = ax.bar(division * np.pi / 180 - width * 0.5, count, width=width, | |
bottom=0.0) | |
ax.set_title('%s network edge bearings' % city, y=1.1) | |
plt.show() | |
def make_iso_polys(my_map, center_node, edge_buff=25, node_buff=50, | |
infill=False): | |
""" | |
This function is modified from | |
http://kuanbutts.com/2017/12/16/osmnx-isochrones/ | |
:param my_map: Map | |
:param center_node: From where you want to calculate distance | |
:param edge_buff: Edge Buffer (No idea what this is) | |
:param node_buff: Node Buffer(No idea what this is) | |
:param infill: (No idea what this is) | |
""" | |
isochrone_polys = [] | |
for trip_time in sorted(trip_times, reverse=True): | |
subgraph = nx.ego_graph(my_map, center_node, radius=trip_time, | |
distance='time') | |
node_points = [Point((data['x'], data['y'])) for node, data in | |
subgraph.nodes(data=True)] | |
nodes_gdf = gpd.GeoDataFrame({'id': subgraph.nodes()}, | |
geometry=node_points) | |
nodes_gdf = nodes_gdf.set_index('id') | |
edge_lines = [] | |
for n_fr, n_to in subgraph.edges(): | |
f = nodes_gdf.loc[n_fr].geometry | |
t = nodes_gdf.loc[n_to].geometry | |
edge_lines.append(LineString([f, t])) | |
n = nodes_gdf.buffer(node_buff).geometry | |
e = gpd.GeoSeries(edge_lines).buffer(edge_buff).geometry | |
all_gs = list(n) + list(e) | |
new_iso = gpd.GeoSeries(all_gs).unary_union | |
# try to fill in surrounded areas so shapes will appear solid and | |
# blocks without white space inside them | |
if infill: | |
new_iso = Polygon(new_iso.exterior) | |
isochrone_polys.append(new_iso) | |
return isochrone_polys | |
def go_distance(): | |
""" | |
Calculate distance travel based on parameter values declared at the top | |
of this file | |
:return: | |
""" | |
my_map = ox.graph_from_point(origin_point, distance_around_point, | |
network_type=network_type) | |
orig_node = ox.get_nearest_node(my_map, origin_point) | |
my_map = ox.project_graph(my_map) | |
meters_per_minute = travel_speed * 1000 / 60 # km per hour to m per minute | |
for u, v, k, data in my_map.edges(data=True, keys=True): | |
data['time'] = data['length'] / meters_per_minute | |
isochrone_polys = make_iso_polys(my_map, orig_node, edge_buff=25, | |
node_buff=0, | |
infill=True) | |
nc = ["b" if node == orig_node else 'none' for node in my_map.nodes()] | |
ns = [60 if node == orig_node else 0 for node in my_map.nodes()] | |
fig, ax = ox.plot_graph(my_map, fig_height=8, node_color=nc, node_size=ns, | |
show=False, close=False, edge_color='k', | |
edge_alpha=0.2) | |
for polygon, fc in zip(isochrone_polys, iso_colors): | |
patch = PolygonPatch(polygon, fc=fc, ec='none', alpha=0.6, zorder=-1) | |
ax.add_patch(patch) | |
plt.savefig('map.png', dpi=300, bbox_inches='tight', format="png") | |
plt.show() | |
if __name__ == "__main__": | |
go_distance() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment