Skip to content

Instantly share code, notes, and snippets.

@rohitsuratekar
Created July 16, 2018 15:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rohitsuratekar/1bd089668168b2343446cf27c91954a3 to your computer and use it in GitHub Desktop.
Save rohitsuratekar/1bd089668168b2343446cf27c91954a3 to your computer and use it in GitHub Desktop.
"""
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