Calculating Walk Scores with Python

Introduction

Walkability Measures

Datasets

#Downloading Pedestrian Network Data 
import zipfile
import io
from pyproj import Proj, CRS, transform
url = ‘https://ckan0.cf.opendata.inter.prod-toronto.ca/download_resource/3ce9a0a9-c66d-4324-820a-ce44dabb2b46'
local_path = ‘./tmp’
print(‘Downloading zipped shapefile…’)
r = requests.get(url)
z = zipfile.ZipFile(io.BytesIO(r.content))
print(“Done”)
z.extractall(path=local_path) # extract to tmp folder
filenames = [y for y in sorted(z.namelist()) for ending in [‘dbf’, ‘prj’, ‘shp’, ‘shx’] if y.endswith(ending)]
print(filenames)
pednet= gpd.read_file(r’./tmp/pednet.shp’)
#reprojecting epsg 4386 (wgs84) to epsg 2019 (mtm nad 27)
crs = CRS(“EPSG:2019”)
pednet = gpd.GeoDataFrame(pednet, crs=crs, geometry=’geometry’)
pednet.head(5)
Pedestrian Network Data
# Downloading Address Points 
import zipfile
import io
from pyproj import Proj, CRS, transform
url = ‘https://ckan0.cf.opendata.inter.prod-toronto.ca/download_resource/d918eb68-e077-4bb1-872b-59ebe265d016'
local_path = ‘./tmp’
print(‘Downloading zipped shapefile…’)
r = requests.get(url)
z = zipfile.ZipFile(io.BytesIO(r.content))
print(“Done”)
z.extractall(path=local_path) # extract to tmp folder
filenames = [y for y in sorted(z.namelist()) for ending in [‘dbf’, ‘prj’, ‘shp’, ‘shx’] if y.endswith(ending)]
print(filenames)
address_points= gpd.read_file(r’./tmp/ADDRESS_POINT_WGS84.shp’)
#reprojecting epsg 4386 (wgs84) to epsg 2019 (mtm nad 27)
crs = CRS(“EPSG:2019”)
address_points = gpd.GeoDataFrame(address_points, crs=crs, geometry=’geometry’)
address_points.head(5)
Address Points Data
# download building data
import zipfile
import io
from pyproj import Proj, CRS, transform
url = 'https://ckan0.cf.opendata.inter.prod-toronto.ca/download_resource/a5da8e3e-bb05-42f1-9f5e-646cb95d9690'
local_path = './tmp'
print('Downloading zipped shapefile...')
r = requests.get(url)
z = zipfile.ZipFile(io.BytesIO(r.content))
print("Done")
z.extractall(path=local_path) # extract to tmp folder
filenames = [y for y in sorted(z.namelist()) for ending in ['dbf', 'prj', 'shp', 'shx'] if y.endswith(ending)]
print(filenames)
building= gpd.read_file(r'./tmp/3DMassing_2019_WGS84.shp')
#reprojecting epsg 4386 (wgs84) to epsg 2019 (mtm nad 27)
crs = CRS("EPSG:2019")
building = gpd.GeoDataFrame(building, crs=crs, geometry='geometry')
building.head(5)
Downloading Building Data

Amenities

Amenities and Column Names
# load data from pg database total 24 layers
con = psycopg2.connect(database=”walk", user=”postgres”, password=’****',
host=”17**.***",port=”5432")
#service layers
foodconv = gpd.read_postgis(‘SELECT * FROM staging.food_convenience_store’,con,crs={‘init’: ‘epsg:2019’})
fast_food = gpd.read_postgis(‘SELECT * FROM staging.food_fastfood’,con,crs={‘init’: ‘epsg:2019’})
supermarket = gpd.read_postgis(‘SELECT * FROM staging.food_supermarket’,con,crs={‘init’: ‘epsg:2019’})
hospital = gpd.read_postgis(‘SELECT * FROM staging.health_hospital’,con,crs={‘init’: ‘epsg:2019’})
sxhclinic = gpd.read_postgis(‘SELECT * FROM staging.health_sexual_health_clinic’,con,crs={‘init’: ‘epsg:2019’})
wkclinic = gpd.read_postgis(‘SELECT * FROM staging.health_walkin’,con,crs={‘init’: ‘epsg:2019’})
arena = gpd.read_postgis(‘SELECT * FROM staging.publicservice_arena’,con,crs={‘init’: ‘epsg:2019’})
daycare = gpd.read_postgis(‘SELECT * FROM staging.publicservice_day_care_centre’,con,crs={‘init’: ‘epsg:2019’})
dropin = gpd.read_postgis(‘SELECT * FROM staging.publicservice_dropin’,con,crs={‘init’: ‘epsg:2019’})
ems = gpd.read_postgis(‘SELECT * FROM staging.publicservice_ems’,con,crs={‘init’: ‘epsg:2019’})
famcentre = gpd.read_postgis(‘SELECT * FROM staging.publicservice_family_resource_centre’,con,crs={‘init’: ‘epsg:2019’})
fire = gpd.read_postgis(‘SELECT * FROM staging.publicservice_fire_facility’,con,crs={‘init’: ‘epsg:2019’})
library = gpd.read_postgis(‘SELECT * FROM staging.publicservice_library’,con,crs={‘init’: ‘epsg:2019’})
police = gpd.read_postgis(‘SELECT * FROM staging.publicservice_police_facility’,con,crs={‘init’: ‘epsg:2019’})
recreation = gpd.read_postgis(‘SELECT * FROM staging.publicservice_recreation’,con,crs={‘init’: ‘epsg:2019’})
school = gpd.read_postgis(‘SELECT * FROM staging.publicservice_school’,con,crs={‘init’: ‘epsg:2019’})
thingstodo = gpd.read_postgis(‘SELECT * FROM staging.publicservice_thingstodo’,con,crs={‘init’: ‘epsg:2019’})
voteloc = gpd.read_postgis(‘SELECT * FROM staging.publicservice_voting_location’,con,crs={‘init’: ‘epsg:2019’})
bike_parking = gpd.read_postgis(‘SELECT * FROM staging.transit_bicycle_parking_on_street’,con,crs={‘init’: ‘epsg:2019’})
bike_station = gpd.read_postgis(‘SELECT * FROM staging.transit_bicycle_station_indoor’,con,crs={‘init’: ‘epsg:2019’})
ttc_station = gpd.read_postgis(‘SELECT * FROM staging.transit_ttc_station’,con,crs={‘init’: ‘epsg:2019’})
ttc_accessible = gpd.read_postgis(‘SELECT * FROM staging.transit_ttc_station_accessible’,con,crs={‘init’: ‘epsg:2019’})
ttc_stop = gpd.read_postgis(‘SELECT * FROM staging.transit_ttc_stop’,con,crs={‘init’: ‘epsg:2019’})
ts = gpd.read_postgis(‘SELECT * FROM staging.tscw’,con,crs={‘init’: ‘epsg:2019’})

Walk Scores

Walk Scores
#load calculated walk times and spatially joined census, pedestrain, and building data.
password = open(‘password.txt’,’r’).readline()
username = ‘postgres’
walkability_engine = create_engine(‘postgresql://%s:%s@*ip**:5432/walkability’ %(username,password))
buildings_sumfin = gpd.read_postgis(“select * from results.buildings_summary_walktimes_fin”, walkability_engine, ‘geom’)
census_sumfin = gpd.read_postgis(“select * from results.census_summary_walktimes_fin”, walkability_engine, ‘geom’)
pednet_sumfin = gpd.read_postgis(“select * from results.pednet_summary_walktimes_fin”, walkability_engine, ‘geom’)
buildings = gpd.read_postgis(“select * from staging.buildings327”, walkability_engine, ‘geom’)
# keep walk times columns
buildingws = buildings[['m_fc_0','m_fc_1','m_ff_0','m_ff_1','m_sm_0','m_sm_1','m_hp_0','m_hp_1','m_sxhc_0','m_sxhc_1','m_wc_0','m_wc_1','m_sc_0','m_sc_1','m_ar_0','m_ar_1','m_dc_0','m_dc_1','m_di_0','m_di_1','m_ems_0','m_ems_1','m_frc_0','m_frc_1','m_fr_0','m_fr_1','m_lb_0','m_lb_1','m_plc_0','m_plc_1','m_rec_0','m_rec_1','m_thing_0','m_thing_1','m_vtl_0','m_vtl_1','m_bp_0','m_bp_1','m_bs_0','m_bs_1','m_ttcstop_0','m_ttcstop_1','m_ttcst_0','m_ttcst_1','m_ttcacc_0','m_ttcacc_1','m_ts_0','m_ts_1']]
buildingws["m_lb_0"].describe()
The closest POI Walk Times Description to Library (m_lb_0 Column)
import hiscore
#generate a scoring function by calling hiscore.create with this reference set
reference_set = {(0): 100, (5): 90, (10): 80, (15): 70, (20): 60, (25): 50, (30): 40, (40): 30, (50): 20, (60): 10, (70): 0}
score_function = hiscore.create(reference_set, [-1], minval=0, maxval=100)
list(zip(reference_set.keys(), np.round(score_function.calculate(reference_set.keys()))))
Score Reference Set
# Creating walk score columns 
for col in buildingws.columns:
st = col.replace(‘m’, ‘ws’)
buildingws[st]= buildingws[col]
buildingws.head(2)
buildingws[‘ws_fc_0’] = buildingws.apply(lambda row: np.round(score_function.calculate(row.ws_fc_0)) , axis=1)
Walk scores of ws_fc_0 column
#calculate walk scores in a loop. This method is slower than the previous one
for col in buildingws.columns:
st = col.replace(‘m’, ‘ws’)
buildingws[st]= np.round(score_function.calculate(buildingws[col]))
Walk Score Calculation
x = buldingws.plot(figsize=(15, 15), column=’ws0_avg’, scheme=’quantiles’, legend=True,markersize = 1)
ttc_stop.plot(ax=ax, color=’red’, markersize =1, alpha=0.99, categorical =True,legend=True)
plt.title(‘Walk Scores based on Average Walk Minutes’)
Walk Scores based on Average Walk Minutes

Result

Walk Scores by Census Tracts
Walk Scores by Building Locations

Conclusion

Walkability WebApp

Senior Geospatial Specialist in Toronto

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store