Geospatial Data Science in Python
  • Syllabus
  • Schedule
    • Section 401
    • Section 402
  • Content
  • Assignments
    • Overview
    • Section 401
    • Section 402
  • Resources
  • GitHub
  • Canvas
  • Ed Discussion

Week 5A
Geospatial Data: Street Networks

  • Monday, October 2, 2023
  • Section 401
# The usual imports
import altair as alt
import geopandas as gpd
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
# Show all columns in dataframes
pd.options.display.max_columns = 999
# Hide warnings due to issue in shapely package 
# See: https://github.com/shapely/shapely/issues/1345
np.seterr(invalid="ignore");

Today: Urban street networks and OpenStreetMap (OSM)

  • Two tools that make working with OSM data very easy
  • What kind of questions can we answer?
    • Street orientations
    • Mapping event points to streets: car crashes
    • Mapping amenities
    • Network-constrained distances: accessibility

OSM: what is it?

  • Collaborative mapping
  • A free editable map of the World
  • Sort of like Wikipedia for maps

Great source of data: street networks and a wealth of amenity information

https://www.openstreetmap.org

Working with OSM data

  • Raw data is very messy
  • Two relatively new, amazing Python packages greatly simply the process
  • Related, but complementary features
    • OSMnx: downloading and manipulating streets as networks
    • Pandana: networks focused on accessibility of amenities

Related: interactive web maps in Python

Part 1: OSMnx

Relatively new package (just a few years old), but quickly becoming the go to package for working with street networks and OpenStreetMap data in Python.

Several key features:

  • Downloading political boundaries for cities, states, countries, etc

  • Downloading street networks

  • Analyzing networks: routing, visualization, statistics

    • GitHub
    • Introductory Blog Post
    • Jupyter Notebook Examples (Binder)
    • Documentation
import osmnx as ox

1.1. Getting boundary shapefiles from OSM

Key function: geocode_to_gdf() (docs)

We can get the boundary for anything identified as a “place” by OSM.

Important: Be careful to pass the right place name that OSM needs

philly = ox.geocode_to_gdf("Philadelphia, PA")

philly.head()
geometry bbox_north bbox_south bbox_east bbox_west place_id osm_type osm_id lat lon class type place_rank importance addresstype name display_name
0 POLYGON ((-75.28030 39.97500, -75.28022 39.974... 40.137959 39.867005 -74.955831 -75.280298 14128726 relation 188022 39.952724 -75.163526 boundary administrative 16 0.713797 city Philadelphia Philadelphia, Pennsylvania, United States
philly.crs
<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich

We can plot it just like any other GeoDataFrame

# Project it to Web Mercator first and plot
ax = philly.to_crs(epsg=3857).plot(facecolor="none", edgecolor="black")
ax.set_axis_off()

1.2 Projecting with OSMnx

Key function: project_gdf() (docs)

Automatically projects to the Universal Transverse Mercator (UTM) CRS for the UTM zone that the centroid of the polygon lies in

A good, general projection that works for most latitudes except very northern locations.

ax = ox.project_gdf(philly).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

Some more examples:

# Some examples
place1 = ox.geocode_to_gdf("Manhattan, New York City, New York, USA")
place2 = ox.geocode_to_gdf("Miami-Dade County, Florida")
place3 = ox.geocode_to_gdf("Florida, USA")
place4 = ox.geocode_to_gdf("Spain")
# Manhattan
ax = ox.project_gdf(place1).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

# Miami-Dade County
ax = ox.project_gdf(place2).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

# Florida
ax = ox.project_gdf(place3).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

# Spain
ax = ox.project_gdf(place4).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

1.3 Downloading OSM features

Key functions: features_from_*

  • features_from_place() (docs)
    • Download features within an OSM place boundary
  • features_from_address() (docs)
    • Download features within a certain distance of an address
  • features_from_bbox() (docs)
    • Download features within a N, S, E, W bounding box
  • features_from_point() (docs)
    • Download features within a certain distance of a specified point
  • features_from_polygon() (docs)
    • Download features within a polygon object
About OSM features

Important reference: https://wiki.openstreetmap.org/wiki/Map_Features

  • OSM uses a tagging system to categorize different map features
  • The main feature categories are available on the OSM Wikipedia
    • Examples: ‘amenity’, ‘building’, ‘landuse’, ‘highway’
  • There are specific sub-categories for each feature type too:
    • Amenity examples: ‘bar’, ‘college’, ‘library’

In the language of OSM, the “key” is the main feature category (e.g., amenity) and the “value” is the sub-category type (e.g., “bar”)

osmnx mirrors the key/value syntax of OSM. Use a dict to specify the features you want:

# Get all amenities in Philadelphia
amenities = ox.features_from_place("Philadelphia, PA", tags={"amenity": True})
len(amenities)
10647
amenities.head()
geometry amenity created_by cuisine name brand brand:wikidata brand:wikipedia operator operator:wikidata operator:wikipedia short_name addr:city addr:housenumber addr:postcode addr:state addr:street contact:website official_name opening_hours phone takeaway source wheelchair healthcare internet_access url contact:phone description email website wikidata internet_access:ssid brewery alt_name ele gnis:county_id gnis:created gnis:feature_id gnis:state_id religion historic:amenity old_name denomination building comment operator:type school wikipedia gnis:edited check_date craft microbrewery restaurant contact:facebook name:en social_facility operator:short emergency healthcare:speciality bicycle_parking capacity covered barrier atm attraction gnis:county_name gnis:import_uuid gnis:reviewed internet_access:fee addr:county addr:country outdoor_seating artist_name artwork_subject artwork_type image start_date statue subject:wikidata tourism reservation website:menu air_conditioning shop training toilets:wheelchair addr:housename bottle parking designation not:brand:wikidata dispensing drive_through screen delivery diet:vegan payment:cash payment:coins indoor_seating smoking architect contact:instagram collection_times ref male female fee diet:vegetarian fax bar source:pkey fixme access changing_table toilets name:zh addr:full entrance level name:he fuel:biodiesel fuel:biogas fuel:cng fuel:diesel fuel:e10 fuel:e85 fuel:electricity sport wifi collection_times:signed ref:signed drive_in check_date:collection_times food toilets:access payment:bitcoin diet:halal disused:amenity branch self_service diet:meat note leisure drink:club-mate car_wash compressed_air toilets:disposal unisex contact:twitter currency:XBT diet:pescetarian lgbtq payment:credit_cards payment:debit_cards park_ride supervised check_date:opening_hours opening_hours:signed landuse flickr contact:email facebook instagram service_times twitter youtube source:cuisine social_facility:for disused:shop toilets:position maxheight wheelchair:description wheelchair:description:en layer service:bicycle:chain_tool service:bicycle:pump currency:USD drink:coca-cola drink:coke drink:cola drink:cola_zero drink:soda drink:water vending opening_hours:kitchen bicycle_rental network network:wikidata network:wikipedia amenity_1 recycling:computers recycling:tv_monitor recycling_type ferry public_transport toilets:unisex kitchen_hours animal addr:unit was:amenity was:cuisine was:delivery was:drive_through was:name was:outdoor_seating was:takeaway direction backrest service:bicycle:repair payment:cards name:es diet:kosher theatre:genre service:bicycle:tools beds payment:visa cash_in currency:BCH currency:LTC office date display faces studio name:ca bench lit shelter_type addr:city:ar name:ar colour material fountain addr:block_number seats brand:type indoor parcel_locker:type parcel_mail_in parcel_pickup historic type payment:american_express payment:discover_card payment:mastercard dog recycling:beverage_cartons recycling:cans recycling:glass_bottles recycling:paper recycling:plastic recycling:plastic_bottles recycling:plastic_packaging portable toilets:handwashing opening_hours:drive_through internet_access:description name:vi payment:cheque min_age bus tram waste payment:cash_app payment:venmo seating street_vendor theatre:type smoothness surface brand:en brand:zh location drinking_water height fridge wikimedia_commons opening_hours:covid19 diet:healthy abandoned:amenity memorial payment:lightning payment:lightning_contactless payment:onchain country payment:contactless delivery:partner internet_access:password post_box:type description:en inscription check_date:currency:XBT public_bookcase:type urgent_care diet:gluten_free community_centre:for community_centre animal_shelter name:etymology name:etymology:wikidata mobile nodes building:levels capacity:disabled building:floor ref:nrhp vehicle natural water building:use ship:type roof:shape automated brand:website building:material source:name roof:levels roof:material access:conditional rite heritage heritage:operator architect:wikidata building:levels:underground heritage:website nrhp:criteria nrhp:inscription_date building:colour area check_date:compressed_air gnis:fcode nonsquare name:ja name:zn roof:orientation happy_hours building:part elevation historic:name grades maxstay monastery:type library theme owner loc_name drink bin police school:type old_name1 old_name2 fuel:octane_95 fuel:gasoline fuel:octane_87 healthcare:counselling orientation parking:orientation protection_title source_ref parking_space ways healthcare:for
element_type osmid
node 109811385 POINT (-75.19487 40.05846) bench NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
274215467 POINT (-75.19492 39.95935) fast_food Potlatch 0.9c pizza Powelton Pizza NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
274216093 POINT (-75.19125 39.95764) atm NaN NaN Citibank Citibank Q857063 en:Citibank Citibank Q857063 en:Citibank Citi NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
274217596 POINT (-75.19229 39.95301) cafe NaN coffee_shop Starbucks Starbucks Q37158 en:Starbucks NaN NaN NaN NaN Philadelphia 3401 19104 PA Walnut Street https://www.starbucks.com/store-locator/store/... Starbucks Coffee Mo-Fr 05:30-24:00; Sa,Su 06:00-24:00 215-387-1914 yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
313440966 POINT (-75.16694 39.96394) car_sharing Potlatch 0.10f NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN local_knowledge NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# Get all bars in philadelphia
bars = ox.features_from_place("Philadelphia, PA", tags={"amenity": "bar"})
len(bars)
165
bars.head()
addr:city addr:housenumber addr:postcode addr:state addr:street amenity brewery craft gnis:county_id microbrewery name operator restaurant website wikidata wikipedia geometry contact:phone contact:website description opening_hours outdoor_seating check_date contact:facebook phone air_conditioning smoking toilets:wheelchair wheelchair indoor_seating designation addr:housename source wifi leisure sport cuisine diet:vegan diet:vegetarian food internet_access brand brand:wikidata wheelchair:description fixme name:en name:es addr:unit check_date:opening_hours email min_age alt_name level height opening_hours:signed nodes atm building building:levels nonsquare heritage
element_type osmid
node 357303425 Philadelphia 500 19123 PA Spring Garden Street bar yes brewery 101 yes Yards Brewing Company Yards Brewing Company yes https://yardsbrewing.com/ Q16903914 en:Yards Brewing Company POINT (-75.14712 39.96067) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
655425272 NaN NaN NaN NaN NaN bar NaN NaN NaN NaN Drinkers West NaN NaN NaN NaN NaN POINT (-75.20020 39.95521) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1033935437 NaN 2101 NaN NaN Chestnut Street bar NaN NaN NaN NaN Mix Bar & Grill NaN NaN NaN NaN NaN POINT (-75.17552 39.95242) +1 215-568-3355 https://mixbarandgrillphilly.com/location/mix-... The bar is open until whenever the rush ends. Mo-We,Su 11:00-22:00; Th-Sa 11:00-23:00 yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1167079387 NaN 401 NaN NaN South Street bar NaN NaN NaN NaN MilkBoy South Street NaN NaN NaN NaN NaN POINT (-75.14925 39.94170) +1 215-925-6455 https://www.milkboy.tv/southstreet NaN Mo-Tu,Su 11:00-24:00; We-Sa 11:00-25:00 NaN 2023-04-12 https://www.facebook.com/milkboysouthstreet NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1204761128 NaN NaN NaN NaN NaN bar NaN NaN NaN NaN Vikings High School Club NaN NaN NaN NaN NaN POINT (-75.16363 39.92685) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# Get bar, pub, and restaurant features in Philadelphia
food_and_drink = ox.features_from_place(
    "Philadelphia, PA", tags={"amenity": ["pub", "bar", "restaurant"]}
)
len(food_and_drink)
1075
food_and_drink.head()
amenity created_by name source wheelchair geometry addr:city addr:housenumber addr:postcode addr:state addr:street brewery opening_hours craft gnis:county_id microbrewery operator restaurant website wikidata wikipedia cuisine outdoor_seating brand brand:wikidata check_date contact:facebook contact:website email phone reservation website:menu description designation not:brand:wikidata contact:phone contact:instagram internet_access diet:vegan diet:vegetarian fax air_conditioning smoking bar takeaway addr:housename toilets:wheelchair addr:country alt_name short_name name:zh level indoor_seating sport wifi delivery drive_in payment:cash food payment:bitcoin diet:halal disused:amenity brand:wikipedia official_name diet:meat capacity note leisure contact:twitter currency:XBT fixme diet:pescetarian lgbtq payment:credit_cards payment:debit_cards branch source:cuisine wheelchair:description facebook opening_hours:kitchen ref amenity_1 kitchen_hours name:en name:es addr:unit check_date:opening_hours name:ca internet_access:fee toilets payment:american_express payment:discover_card payment:mastercard payment:visa start_date internet_access:description internet_access:ssid min_age diet:healthy drive_through country delivery:partner toilets:access height payment:contactless opening_hours:signed diet:gluten_free nodes building historic payment:cards ship:type atm building:levels area image roof:levels name:ja name:zn happy_hours nonsquare theme heritage layer
element_type osmid
node 333786044 restaurant Potlatch 0.10f Sam's Morning Glory knowledge limited POINT (-75.15893 39.94086) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
343293806 pub NaN Prohibition Taproom survey NaN POINT (-75.15946 39.96073) Philadelphia 501 19123 PA North 13th Street yes Mo-Su 11:00-02:00 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
357303425 bar NaN Yards Brewing Company NaN NaN POINT (-75.14712 39.96067) Philadelphia 500 19123 PA Spring Garden Street yes NaN brewery 101 yes Yards Brewing Company yes https://yardsbrewing.com/ Q16903914 en:Yards Brewing Company NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
566683522 restaurant NaN Spring Garden Pizza & Restaurant NaN NaN POINT (-75.15755 39.96205) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN pizza NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
596230881 restaurant NaN NaN NaN NaN POINT (-75.18682 40.05492) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# Get bus stop features
bus_stops = ox.features_from_place("Philadelphia, PA", tags={"highway": "bus_stop"})
len(bus_stops)
290
bus_stops.head()
bench bus covered highway name network network:wikidata operator public_transport shelter geometry network:wikipedia ref tactile_paving wheelchair route_ref local_ref designation source bin lit departures_board internet_access addr:street route_ref_1 description note operator:wikidata brand brand:wikidata railway tram trolleybus network:short not:network:wikidata
element_type osmid
node 361011456 yes yes yes bus_stop 13th St & Market St SEPTA Q2037863 SEPTA platform yes POINT (-75.16166 39.95223) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
750281693 NaN yes NaN bus_stop NaN NaN NaN NaN platform NaN POINT (-75.07732 40.01797) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
768271130 NaN yes NaN bus_stop Wissahickon Transportation Center SEPTA Q2037863 SEPTA platform yes POINT (-75.20726 40.01487) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1015342921 NaN yes NaN bus_stop NaN NaN NaN NaN platform NaN POINT (-75.18187 39.96640) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1015342926 NaN yes NaN bus_stop NaN NaN NaN NaN platform NaN POINT (-75.18024 39.96670) NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# Get commercial and retail landuse features
landuse = ox.features_from_place(
    "Philadelphia, PA", tags={"landuse": ["commercial", "retail"]}
)
len(landuse)
349

Let’s plot the land use features:

fig, ax = plt.subplots(figsize=(10, 6))

ax = landuse.plot(ax=ax)
ax.set_axis_off()

1.4 Downloading street networks

Key functions: graph_from_*

  • graph_from_place() (docs)
    • Download street network within an OSM place boundary
  • graph_from_address() (docs)
    • Download street network within a certain distance of an address
  • graph_from_bbox() (docs)
    • Download street network within a N, S, E, W bounding box
  • graph_from_point() (docs)
    • Download street network within a certain distance of a specified point
  • graph_from_polygon() (docs)
    • Download street network within a polygon object

Street network around an address

Get streets within 500 meters of the center of Center City

G = ox.graph_from_address("Center City, Philadelphia, PA", dist=500)

Project and plot it:

G_projected = ox.project_graph(G)
ox.plot_graph(G_projected);

Remove the nodes:

ox.plot_graph(G_projected, node_size=0);

Let’s zoom out to 2,000 meters. This will take a little longer.

G = ox.graph_from_address("Center City, Philadelphia, PA", dist=2000)
G_projected = ox.project_graph(G)
ox.plot_graph(G_projected, node_size=0);

Getting different network types

  • drive - get drivable public streets (but not service roads)
  • drive_service - get drivable streets, including service roads
  • walk - get all streets and paths that pedestrians can use (this network type ignores one-way directionality)
  • bike - get all streets and paths that cyclists can use
  • all - download all non-private OSM streets and paths
  • all_private - download all OSM streets and paths, including private-access ones (default)
# the "drive" network
G = ox.graph_from_address("Center City, Philadelphia, PA", network_type="drive")
ox.plot_graph(G);

# the "walk" network
G = ox.graph_from_address("Center City, Philadelphia, PA", network_type="walk")
ox.plot_graph(ox.project_graph(G));

Street network within a place boundary

Use graph_from_place() to get the streets within a specific OSM place.

Caution

A couple of things to watch out for: 1. The place query has to be resolved by OSM. 2. If the place is a big city, you might be downloading a lot of data!

Let’s check out the street network for Berkeley, CA:

berkeley = ox.graph_from_place("Berkeley, California, USA")
ox.plot_graph(ox.project_graph(berkeley), node_size=0);

Streets within a specific polygon

Example: Let’s download all streets within Center City. We will use the “Central” planning district as a proxy for this area. The city’s planning districts are available on Open Data Philly.

planning_districts = gpd.read_file(
    "https://opendata.arcgis.com/datasets/0960ea0f38f44146bb562f2b212075aa_0.geojson"
)
len(planning_districts)
18
planning_districts.head()
OBJECTID_1 OBJECTID DIST_NAME ABBREV Shape__Area Shape__Length PlanningDist DaytimePop geometry
0 1 14 River Wards RW 2.107270e+08 66931.595020 NaN NaN POLYGON ((-75.09798 40.00496, -75.09687 40.005...
1 2 3 North Delaware NDEL 2.700915e+08 89213.074378 NaN NaN POLYGON ((-74.98159 40.05363, -74.98139 40.053...
2 3 0 Lower Far Northeast LFNE 3.068529e+08 92703.285159 NaN NaN POLYGON ((-74.96443 40.11728, -74.96434 40.117...
3 4 9 Central CTR 1.782880e+08 71405.143450 NaN NaN POLYGON ((-75.14791 39.96733, -75.14715 39.967...
4 5 10 University Southwest USW 1.296468e+08 65267.676141 NaN NaN POLYGON ((-75.18742 39.96338, -75.18644 39.963...

Trim to the central district:

central_district = planning_districts.query("DIST_NAME == 'Central'")

And plot it:

ax = ox.project_gdf(central_district).plot(fc="lightblue", ec="gray")
ax.set_axis_off()

central_district
OBJECTID_1 OBJECTID DIST_NAME ABBREV Shape__Area Shape__Length PlanningDist DaytimePop geometry
3 4 9 Central CTR 1.782880e+08 71405.14345 NaN NaN POLYGON ((-75.14791 39.96733, -75.14715 39.967...

Squeeze it so we can get the geometry polygon:

center_city_outline = central_district.squeeze().geometry

center_city_outline

Now, let’s use ox.graph_from_polygon() to extract streets within this polygon.

# Get the graph
G_cc = ox.graph_from_polygon(center_city_outline, network_type="drive")
# Viola!
ox.plot_graph(ox.project_graph(G_cc), node_size=0);

1.5 Converting from a graph to a GeoDataFrame

Key function: ox.graph_to_gdfs() (docs)

You can get a GeoDataFrame for both the nodes (points) and edges (lines)

type(G_cc)
networkx.classes.multidigraph.MultiDiGraph
# only get the edges
cc_edges = ox.graph_to_gdfs(G_cc, edges=True, nodes=False)
# we have lots of data associated with each edge!
cc_edges.head()
osmid oneway name highway reversed length geometry maxspeed lanes bridge ref tunnel width service access junction
u v key
109727439 109911666 0 132508434 True Bainbridge Street residential False 44.137 LINESTRING (-75.17104 39.94345, -75.17053 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109727448 109727439 0 12109011 True South Colorado Street residential False 109.484 LINESTRING (-75.17125 39.94248, -75.17120 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
110034229 0 12159387 True Fitzwater Street residential False 91.353 LINESTRING (-75.17125 39.94248, -75.17137 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109727507 110024052 0 193364514 True Carpenter Street residential False 53.208 LINESTRING (-75.17196 39.93973, -75.17134 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109728761 110274344 0 672312336 True Brown Street residential False 58.270 LINESTRING (-75.17317 39.96951, -75.17250 39.9... 25 mph NaN NaN NaN NaN NaN NaN NaN NaN
# plot it like any old GeoDataFrame
ax = cc_edges.to_crs(epsg=3857).plot(color="gray")

# add the neighborhood boundaries
boundary = gpd.GeoSeries([center_city_outline], crs="EPSG:4326")
boundary.to_crs(epsg=3857).plot(
    ax=ax, facecolor="none", edgecolor="red", linewidth=3, zorder=2
)

ax.set_axis_off()

Don’t forget: We can use the .explore() function to get an interactive web map via Folium:

cc_edges.explore(tiles='cartodb positron')
Make this Notebook Trusted to load map: File -> Trust Notebook

1.6 What can we do with the graph?

  • Network-based statistics
  • Routing
  • Street orientations
  • Visualizing crashes

And much more: see the OSMnx repository of Jupyter notebook examples

Street orientations

A great blog post on street orientations across different US and global cities.

One of my favorite examples of data viz, using matplotlib for radial histograms of street orientations…

The code for these histograms is available in the osmnx examples repository.

Network statistics

We can use the ox.basic_stats() to get some basic network statistics

ox.basic_stats(G_cc)
{'n': 2026,
 'm': 3902,
 'k_avg': 3.8519249753208293,
 'edge_length_total': 349745.43700000027,
 'edge_length_avg': 89.63235187083554,
 'streets_per_node_avg': 3.428923988153998,
 'streets_per_node_counts': {0: 0, 1: 55, 2: 9, 3: 996, 4: 948, 5: 14, 6: 4},
 'streets_per_node_proportions': {0: 0.0,
  1: 0.027147087857847977,
  2: 0.004442250740375123,
  3: 0.491609081934847,
  4: 0.46791707798617965,
  5: 0.006910167818361303,
  6: 0.0019743336623889436},
 'intersection_count': 1971,
 'street_length_total': 306400.7959999999,
 'street_segment_count': 3384,
 'street_length_avg': 90.54397044917255,
 'circuity_avg': 1.0172703832466288,
 'self_loop_proportion': 0.0008865248226950354}

Finding the shortest route

Let’s calculate the shortest route between the Art Museum and the Liberty Bell.

We’ll need to download all amenities in Philadelphia of type “tourism”.

  • The ox.features_from_place() can download OSM features with a specific tag
  • You can consult the OSM pages (the Art Museum and Liberty Bell) for each feature for additional info
  • Both features are categorized as “tourism” in the OSM data — use the “tags” keyword to select this category
philly_tourism = ox.features_from_place("Philadelphia, PA", tags={"tourism": True})
len(philly_tourism)
593
philly_tourism.head()
ref geometry ele gnis:county_id gnis:created gnis:feature_id gnis:state_id name tourism brand brand:wikidata brand:wikipedia operator artwork_type historic source wikidata information artist_name material website addr:state gnis:county_name gnis:reviewed gnis:import_uuid fee opening_hours amenity artwork_subject image start_date statue subject:wikidata colour wheelchair wikipedia addr:city name:de designation description museum operator:type alt_name barrier heritage heritage:operator heritage:website nrhp:criteria nrhp:inscription_date nrhp:nhl protection_title ref:nrhp source_ref artist:wikidata height name:fr addr:housenumber addr:postcode addr:street memorial year_of_construction name:ru layer phone check_date contact:email name:en board_type toilets:wheelchair inscription subject:wikipedia level natural attraction note display end_date comment historic:amenity garden:type leisure postal_code official_name internet_access short_name parking guest_house inscription:url gender bicycle hiking covered drinking_water openfire addr:unit mimics source:url direction email departures_board map_size map_type direction_north direction_southeast direction_west direction_east direction_south direction_northeast direction_northwest direction_southwest nodes building building:material name:hi building:levels roof:shape highway incline step_count building:wikidata building:wikipedia check_date:opening_hours old_name smoking building:colour air_conditioning fax rooms stars roof:colour addr:country contact:fax contact:phone ship:type addr:housename bar disused:amenity roof:material internet_access:fee abandoned:amenity fixme internet_access:ssid fee:conditional shop roof:levels name:zh artist:website bridge foot horse lit sac_scale surface trail_visibility width bridge:structure man_made disused:website boundary operator:short operator:wikidata ownership protected building:part area subject contact:facebook ways type place
element_type osmid
node 357371322 NaN POINT (-75.19580 39.96970) 17 101 08/23/2007 2347097 42 Bird Lake Picnic Area picnic_site NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
360500844 NaN POINT (-75.19582 39.95352) NaN NaN NaN NaN NaN Hilton Inn at Penn hotel Hilton Q598884 en:Hilton Hotels & Resorts Hilton NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
360515304 NaN POINT (-75.14860 39.94771) NaN NaN NaN NaN NaN Robert Morris artwork NaN NaN NaN NaN statue memorial survey NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
360542779 NaN POINT (-75.18932 39.95540) NaN NaN NaN NaN NaN Mario the Magnificent artwork NaN NaN NaN NaN statue NaN NaN Q98563440 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
360777728 NaN POINT (-75.19021 39.95230) NaN NaN NaN NaN NaN Pennsylvania Historical Marker: ENIAC, first a... information NaN NaN NaN NaN NaN NaN NaN NaN board NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
# How to find the name of the POI: search for keywords
philly_tourism.loc[philly_tourism['name'].str.contains("Art", na=False)]
ref geometry ele gnis:county_id gnis:created gnis:feature_id gnis:state_id name tourism brand brand:wikidata brand:wikipedia operator artwork_type historic source wikidata information artist_name material website addr:state gnis:county_name gnis:reviewed gnis:import_uuid fee opening_hours amenity artwork_subject image start_date statue subject:wikidata colour wheelchair wikipedia addr:city name:de designation description museum operator:type alt_name barrier heritage heritage:operator heritage:website nrhp:criteria nrhp:inscription_date nrhp:nhl protection_title ref:nrhp source_ref artist:wikidata height name:fr addr:housenumber addr:postcode addr:street memorial year_of_construction name:ru layer phone check_date contact:email name:en board_type toilets:wheelchair inscription subject:wikipedia level natural attraction note display end_date comment historic:amenity garden:type leisure postal_code official_name internet_access short_name parking guest_house inscription:url gender bicycle hiking covered drinking_water openfire addr:unit mimics source:url direction email departures_board map_size map_type direction_north direction_southeast direction_west direction_east direction_south direction_northeast direction_northwest direction_southwest nodes building building:material name:hi building:levels roof:shape highway incline step_count building:wikidata building:wikipedia check_date:opening_hours old_name smoking building:colour air_conditioning fax rooms stars roof:colour addr:country contact:fax contact:phone ship:type addr:housename bar disused:amenity roof:material internet_access:fee abandoned:amenity fixme internet_access:ssid fee:conditional shop roof:levels name:zh artist:website bridge foot horse lit sac_scale surface trail_visibility width bridge:structure man_made disused:website boundary operator:short operator:wikidata ownership protected building:part area subject contact:facebook ways type place
element_type osmid
node 367974278 NaN POINT (-75.15240 40.03748) 61 NaN NaN 2349240 NaN La Salle University Art Museum museum NaN NaN NaN NaN NaN NaN USGS Geonames Q16893816 NaN NaN NaN https://artcollection.lasalle.edu/ PA Philadelphia no NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4064343335 NaN POINT (-75.22113 40.02427) NaN NaN NaN NaN NaN Soft Illusions Fine Art Gallery gallery NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN http://www.softillusions.net/ PA NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN Philadelphia NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 4226 19127 Main Street NaN NaN NaN NaN +1 215-840-0832 2023-08-08 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5368454121 NaN POINT (-75.19477 39.95406) NaN NaN NaN NaN NaN Institute of Contemporary Art museum NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN https://icaphila.org/ PA NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN yes NaN Philadelphia NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 118 19104 South 36th Street NaN NaN NaN NaN NaN NaN NaN NaN NaN yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5718906477 NaN POINT (-75.13058 39.99573) NaN NaN NaN NaN NaN Art Making Machine Studios gallery NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN PA NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN Philadelphia NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 3000 19133 North Hope Street NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6639391809 NaN POINT (-75.16088 39.96383) NaN NaN NaN NaN NaN Philadelphia Museum of Jewish Art museum NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN https://rodephshalom.org/community/philadelphi... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6680708848 NaN POINT (-75.16833 39.94733) NaN NaN NaN NaN NaN Romanian Folk Art Museum museum NaN NaN NaN NaN NaN NaN NaN Q113484178 NaN NaN NaN http://www.romanianculture.us/ PA NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN Philadelphia NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1606 19103 Spruce Street NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
way 28533972 NaN POLYGON ((-75.18116 39.96467, -75.18138 39.964... 32 NaN NaN NaN NaN Philadelphia Museum of Art museum NaN NaN NaN NaN NaN NaN NaN Q510324 NaN NaN NaN https://www.philamuseum.org/ PA NaN NaN NaN NaN Su,Mo,Th,Sa 10:00-17:00; Fr 10:00-20:45 NaN NaN NaN NaN NaN NaN NaN yes en:Philadelphia Museum of Art Philadelphia NaN NaN NaN art NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2600 19130 Benjamin Franklin Parkway NaN NaN NaN NaN +1-215-763-8100 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN [313440467, 313440468, 313440469, 313440470, 3... yes NaN फिलाडेल्फिया कला संग्रहालय NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
333931830 NaN POLYGON ((-75.16410 39.95543, -75.16416 39.955... 13 NaN NaN 1196718 NaN Pennsylvania Academy of the Fine Arts museum NaN NaN NaN NaN NaN building NaN Q1952033 NaN NaN NaN https://www.pafa.org/ PA NaN NaN NaN NaN Tu-Fr 10:00-17:00; Sa-Su 11:00-17:00 NaN NaN NaN NaN NaN NaN NaN NaN en:Pennsylvania Academy of the Fine Arts Philadelphia NaN NaN NaN art NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 71000731 NaN NaN NaN NaN 118 19102 North Broad Street NaN NaN NaN NaN +1-215-972-7600 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN [3409804705, 3409804706, 3453181052, 340980470... yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN US NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
988345364 NaN POLYGON ((-75.21926 40.08320, -75.21931 40.083... 84 NaN NaN NaN NaN Woodmere Art Museum museum NaN NaN NaN NaN NaN NaN esri/Philadelphia_PA_Buildings_OSM Q2424929 NaN NaN NaN https://woodmereartmuseum.org/ PA NaN NaN NaN yes We-Su 10:00-17:00; Sa 10:00-18:00 NaN NaN NaN NaN NaN NaN NaN yes NaN Philadelphia NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 20.72 NaN 9201 19118 Germantown Avenue NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN [10968493549, 9135569442, 9135569424, 91355694... yes NaN NaN NaN NaN NaN NaN NaN NaN NaN 2023-06-10 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
art_museum = philly_tourism.query("name == 'Philadelphia Museum of Art'").squeeze()

art_museum.geometry

liberty_bell = philly_tourism.query("name == 'Liberty Bell'").squeeze()

liberty_bell.geometry

Now, extract the lat and lng coordinates

For the Art Museum geometry, we can use the .geometry.centroid attribute to calculate the centroid of the building footprint.

liberty_bell_x = liberty_bell.geometry.x
liberty_bell_y = liberty_bell.geometry.y
art_museum_x = art_museum.geometry.centroid.x
art_museum_y = art_museum.geometry.centroid.y

Find the nearest nodes on our OSMnx graph, using the ox.nearest_nodes() function

ox.nearest_nodes?
Signature: ox.nearest_nodes(G, X, Y, return_dist=False)
Docstring:
Find the nearest node to a point or to each of several points.
If `X` and `Y` are single coordinate values, this will return the nearest
node to that point. If `X` and `Y` are lists of coordinate values, this
will return the nearest node to each point.
If the graph is projected, this uses a k-d tree for euclidean nearest
neighbor search, which requires that scipy is installed as an optional
dependency. If it is unprojected, this uses a ball tree for haversine
nearest neighbor search, which requires that scikit-learn is installed as
an optional dependency.
Parameters
----------
G : networkx.MultiDiGraph
    graph in which to find nearest nodes
X : float or list
    points' x (longitude) coordinates, in same CRS/units as graph and
    containing no nulls
Y : float or list
    points' y (latitude) coordinates, in same CRS/units as graph and
    containing no nulls
return_dist : bool
    optionally also return distance between points and nearest nodes
Returns
-------
nn or (nn, dist) : int/list or tuple
    nearest node IDs or optionally a tuple where `dist` contains distances
    between the points and their nearest nodes
File:      ~/mambaforge/envs/musa-550-fall-2023/lib/python3.10/site-packages/osmnx/distance.py
Type:      function
# Get the origin node
orig_node = ox.nearest_nodes(G_cc, liberty_bell_x, liberty_bell_y) 

# Get the destination node
dest_node = ox.nearest_nodes(G_cc, art_museum_x, art_museum_y)

Now, we can use ox.shortest_path() function to find the shortest path between these graph nodes.

Note

We need to specify weight=‘length’ to find the shortest path by minimizing distance traveled (otherwise it treats each edge as weight=1).

# get the shortest path --> just a list of node IDs
route1 = ox.shortest_path(G_cc, orig_node, dest_node, weight="length")

route1
[3408446156,
 110217312,
 109814427,
 5372039288,
 109814445,
 8588123388,
 109814449,
 5358069713,
 5372059864,
 2644235371,
 5534891499,
 110540235,
 109750941,
 110402209,
 110402230,
 534960802,
 110391250,
 637791907,
 637791980,
 110329803,
 110329806,
 775897224,
 3414249481,
 110329822,
 110353061,
 11162290432,
 110054089,
 775897147,
 110329848,
 110329851,
 110125895,
 534969088,
 109745905,
 109740423,
 110330569,
 550175455,
 550175399]

Use ox.plot_graph_route() to plot a graph and highlight a specific route

ox.plot_graph_route(G_cc, route1, node_size=0);

How about an interactive version?

osmnx has a helper function ox.utils_graph.route_to_gdf() to convert a route to a GeoDataFrame of edges.

ox.utils_graph.route_to_gdf(G_cc, route1, weight="length").explore(
    tiles="cartodb positron",
    color="red",
)
Make this Notebook Trusted to load map: File -> Trust Notebook

Finding the shortest travel time

The add_edge_speeds function add edge speeds (km per hour) to graph as new speed_kph edge attributes.

The function will add free-flow travel speeds for all edges based on the average maxspeed value of edges, per highway type. This process can definitely be imprecise, but in the case that you happen to have more precise speed data, you can supply your own data instead of relying on OSM data.

# impute speed on all edges missing data
G_cc = ox.add_edge_speeds(G_cc)

# calculate travel time (seconds) for all edges
G_cc = ox.add_edge_travel_times(G_cc)
# Get the graph edges
edges = ox.graph_to_gdfs(G_cc, nodes=False)
edges.head()
osmid oneway name highway reversed length speed_kph travel_time geometry maxspeed lanes bridge ref tunnel width service access junction
u v key
109727439 109911666 0 132508434 True Bainbridge Street residential False 44.137 37.0 4.3 LINESTRING (-75.17104 39.94345, -75.17053 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109727448 109727439 0 12109011 True South Colorado Street residential False 109.484 37.0 10.7 LINESTRING (-75.17125 39.94248, -75.17120 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
110034229 0 12159387 True Fitzwater Street residential False 91.353 37.0 8.9 LINESTRING (-75.17125 39.94248, -75.17137 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109727507 110024052 0 193364514 True Carpenter Street residential False 53.208 37.0 5.2 LINESTRING (-75.17196 39.93973, -75.17134 39.9... NaN NaN NaN NaN NaN NaN NaN NaN NaN
109728761 110274344 0 672312336 True Brown Street residential False 58.270 40.2 5.2 LINESTRING (-75.17317 39.96951, -75.17250 39.9... 25 mph NaN NaN NaN NaN NaN NaN NaN NaN
# Groupby highway type and get the mean values
edges["highway"] = edges["highway"].astype(str)
edges.groupby("highway")[["length", "speed_kph", "travel_time"]].mean()
length speed_kph travel_time
highway
['secondary', 'primary'] 676.801000 43.300000 56.300000
['tertiary', 'motorway_link'] 151.615000 42.100000 13.000000
living_street 52.877143 47.200000 4.028571
motorway 451.723346 83.038462 19.323077
motorway_link 295.568174 47.200000 22.550000
primary 103.286915 44.870944 8.251816
primary_link 56.531789 40.200000 5.063158
residential 81.302576 37.001304 7.920488
secondary 93.164418 43.312000 7.877818
secondary_link 65.884000 47.200000 5.000000
tertiary 80.093234 42.094659 6.867507
tertiary_link 37.969000 47.200000 2.850000
trunk 72.969538 54.507692 4.800000
trunk_link 176.703500 47.200000 13.500000
unclassified 126.344395 32.200000 14.128947
# calculate two routes by minimizing travel time
route2 = ox.shortest_path(G_cc, orig_node, dest_node, weight="travel_time")
# plot the routes
fig, ax = ox.plot_graph_routes(
    G_cc,
    routes=[route1, route2],
    route_colors=["r", "y"],
    route_linewidth=6,
    node_size=0,
)

Let’s plot both in an interactive map:

m = ox.utils_graph.route_to_gdf(G_cc, route1, weight="length").explore(
    tiles="cartodb dark matter",
    color="red",
)

m = ox.utils_graph.route_to_gdf(G_cc, route2, weight="length").explore(
    tiles="cartodb dark matter",
    color="yellow",
    m=m
)

m
Make this Notebook Trusted to load map: File -> Trust Notebook

Let’s compare to the two routes:

Distances:

meters_to_miles = 0.0006213712

# compare the two routes
route1_length = (
    ox.utils_graph.route_to_gdf(G_cc, route1, weight="length")["length"].sum()
    * meters_to_miles
)

route2_length = (
    ox.utils_graph.route_to_gdf(G_cc, route2, weight="length")["length"].sum()
    * meters_to_miles
)

Travel times:

seconds_to_mins = 1.0 / 60

route1_time = (
    ox.utils_graph.route_to_gdf(G_cc, route1, weight="travel_time")["travel_time"].sum()
    * seconds_to_mins
)
route2_time = (
    ox.utils_graph.route_to_gdf(G_cc, route2, weight="travel_time")["travel_time"].sum()
    * seconds_to_mins
)

Summarize:

print(f"Route 1 is {route1_length:.2f} miles and takes {route1_time:.2f} minutes.")
print(f"Route 2 is {route2_length:.2f} miles and takes {route2_time:.2f} minutes.")
Route 1 is 2.19 miles and takes 5.04 minutes.
Route 2 is 2.46 miles and takes 4.46 minutes.

Part 2: Pandana

“Pandas Network Analysis - dataframes of network queries, quickly”

A complementary set of OSM-related features: - Downloading OSM-based networks - Extracting amenity data (so-called “Points of Interest”) - Calculating network-constrained distances

  • GitHub
  • Jupyter Notebook Examples
  • Documentation
import pandana as pnda
from pandana.loaders import osm

Step 1: Get amenity data

Key function: osm.node_query()

  • This will extract amenities within a given bounding box.
  • Similar to the ox.features_from_bbox() function in OSMnx, but we slightly different syntax.
osm.node_query?
Signature: osm.node_query(lat_min, lng_min, lat_max, lng_max, tags=None)
Docstring:
Search for OSM nodes within a bounding box that match given tags.
Parameters
----------
lat_min, lng_min, lat_max, lng_max : float
tags : str or list of str, optional
    Node tags that will be used to filter the search.
    See http://wiki.openstreetmap.org/wiki/Overpass_API/Language_Guide
    for information about OSM Overpass queries
    and http://wiki.openstreetmap.org/wiki/Map_Features
    for a list of tags.
Returns
-------
nodes : pandas.DataFrame
    Will have 'lat' and 'lon' columns, plus other columns for the
    tags associated with the node (these will vary based on the query).
    Index will be the OSM node IDs.
File:      ~/mambaforge/envs/musa-550-fall-2023/lib/python3.10/site-packages/pandana/loaders/osm.py
Type:      function

Get the bounding box:

boundary = center_city_outline.bounds
boundary
(-75.193582452986, 39.9286257450627, -75.1259307965391, 39.9738724134056)
[lng_min, lat_min, lng_max, lat_max] = boundary
# query OSM
poi_df = osm.node_query(lat_min, lng_min, lat_max, lng_max)

# remove missing data
poi_df = poi_df.dropna(subset=["amenity"])
poi_df.head()
lat lon railway light_rail name network operator public_transport wheelchair highway traffic_signals old_ref ref noref traffic_signals:direction direction traffic_calming crossing crossing:markings tactile_paving stop noexit crossing:barrier barrier crossing:island disused:railway crossing_ref supervised railway:signal:direction ele gnis:feature_id place wikidata wikipedia alt_name gnis:Class gnis:County gnis:County_num gnis:ST_alpha gnis:ST_num import_uuid is_in name:en name:zh amenity brand brand:wikidata brand:wikipedia operator:wikidata operator:wikipedia short_name addr:city addr:housenumber addr:postcode addr:state addr:street contact:website cuisine official_name opening_hours phone takeaway shop website ferry building addr:housename healthcare internet_access internet_access:ssid brewery description gnis:county_id gnis:created gnis:state_id historic:amenity note old_name craft microbrewery restaurant leisure sport man_made tower:type gnis:edited operator:short operator:type check_date emergency healthcare:speciality railway:position train artwork_type historic tourism atm information artist_name material attraction office bench bus covered network:wikidata shelter memorial gnis:county_name gnis:import_uuid gnis:reviewed comment historic:tourism aeroway gnis:feature_type addr:country platforms station subway kerb junction iata railway:ref railway:switch:local_operated railway:signal:position addr:unit internet_access:fee crossing:light start_date subject:wikidata artwork_subject image statue tram contact:facebook email reservation website:menu colour parking designation not:brand:wikidata entrance denomination religion screen delivery diet:vegan outdoor_seating payment:cash payment:coins air_conditioning contact:phone indoor_seating smoking architect disused:amenity contact:instagram network:wikipedia collection_times male female dispensing name:de drive_through diet:vegetarian fax bar service:bicycle:pump service:bicycle:repair service:bicycle:retail toilets:wheelchair route_ref capacity source:pkey power access level museum name:he fuel:biodiesel fuel:biogas fuel:cng fuel:diesel fuel:e10 fuel:e85 fuel:electricity collection_times:signed ref:signed check_date:collection_times clothes addr:full branch name:ja operator:en fair_trade organic disused:shop fixme artist:wikidata inscription:url name:ga contact:email payment:bitcoin source:name phone:mnemonic disused:brand disused:brand:wikidata disused:brand:wikipedia disused:dispensing disused:drive_through disused:healthcare disused:opening_hours diet:pescetarian lgbtq payment:credit_cards payment:debit_cards drink:club-mate fare_zone toilets toilets:access building:levels is_in:state_code population farm_boxes compost addr:place social_facility check_date:opening_hours source:cuisine social_facility:for demolished:amenity demolished:opening_hours demolished:phone demolished:social_facility maxheight access:delivery wheelchair:description wheelchair:description:en beauty elevation fee park_ride layer height name:es service:bicycle:chain_tool natural name:fr name:signed bin lit departures_board denotation facebook currency:USD drink:coca-cola drink:coke drink:cola drink:cola_zero drink:soda drink:water vending opening_hours:kitchen bicycle_rental disused:leisure year_of_construction name:ru toilets:unisex toilets:disposal unisex kitchen_hours currency:XBT animal owner button_operated traffic_signals:sound traffic_signals:vibration source:lgbtq service:bicycle:rental service:bicycle:second_hand bicycle horse motor_vehicle bottle surface lamp_type theatre:genre service:bicycle:tools bicycle_parking ref:retrofitness leaf_cycle leaf_type capital loc_name name:ar name:azb name:be name:bn name:ca name:cs name:el name:fa name:grc name:hi name:it name:kn name:ko name:lv name:moh name:oc name:ono name:pa name:pl name:pt name:sr name:ta name:te name:tr name:uk name:ur name:zh-Hans name:zh-Hant population:date source:name:oc source:population payment:cheque advertising payment:american_express payment:mastercard payment:visa backrest fire_hydrant:position fire_hydrant:type club playground date display faces studio seamark:type amenity_1 payment:venmo self_service payment:cards payment:contactless payment:notes fountain camera:direction camera:mount camera:type surveillance surveillance:type manhole drink:beer recycling_type addr:block_number seats brand:type end_date subject:wikipedia type authority marker_date historic:name parcel_locker:type parcel_mail_in consulate country diplomatic target dog recycling:beverage_cartons recycling:cans recycling:glass_bottles recycling:paper recycling:plastic recycling:plastic_bottles recycling:plastic_packaging postal_code changing_table portable seasonal toilets:handwashing toilets:position locked payment:discover_card flag:name flag:type flag:wikidata subject flag:colour foot communication:mobile_phone school dance:style dance:teaching waste landuse military_service generator:method generator:output:electricity generator:source generator:type payment:cash_app seating street_vendor books gender inscription hiking support twitter door smoothness contact:flickr contact:mastodon contact:twitter indoor name:etymology:wikidata payment:paypal min_age was:amenity Business network:short mimics source:url disused opening_hours:signed location water_source drinking_water fridge wikimedia_commons ramp:wheelchair food generator:output:hot_water not:network:wikidata bridge:support opening_hours:url payment:lightning payment:lightning_contactless payment:onchain fishing couplings government self_checkout flickr disused:payment:cash disused:payment:contactless disused:payment:credit_cards disused:payment:debit_cards disused:phone disused:ref delivery:partner internet_access:password surveillance:zone post_box:type fire_mains fire_sprinkler bonnet:colour lamp_mount openplaques:id description:en military memorial:website ref:hmdb post_office service:bicycle:sales service:bicycle:service diet:gluten_free addr:door community_centre:for community_centre cycleway name:etymology collector bollard
id
274216093 39.957640 -75.191254 NaN NaN Citibank NaN Citibank NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN atm Citibank Q857063 en:Citibank Q857063 en:Citibank Citi NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
274217596 39.953015 -75.192289 NaN NaN Starbucks NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN cafe Starbucks Q37158 en:Starbucks NaN NaN NaN Philadelphia 3401 19104 PA Walnut Street https://www.starbucks.com/store-locator/store/... coffee_shop Starbucks Coffee Mo-Fr 05:30-24:00; Sa,Su 06:00-24:00 215-387-1914 yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
313440966 39.963935 -75.166939 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN car_sharing NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
313440968 39.963978 -75.170407 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN car_sharing NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
326519551 39.944261 -75.132616 NaN NaN Camden RiverLink Ferry Landing NaN NaN station NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ferry_terminal NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN https://www.delawareriverwaterfront.com/places... yes NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
len(poi_df)
2383
poi_df[["lat", "lon", "amenity"]].head(10)
lat lon amenity
id
274216093 39.957640 -75.191254 atm
274217596 39.953015 -75.192289 cafe
313440966 39.963935 -75.166939 car_sharing
313440968 39.963978 -75.170407 car_sharing
326519551 39.944261 -75.132616 ferry_terminal
333786044 39.940858 -75.158928 restaurant
333786095 39.941924 -75.157357 cafe
333786448 39.942642 -75.157958 bank
333786774 39.943102 -75.160030 pharmacy
343293716 39.960440 -75.159770 cafe

Explore the amenities in this region

For the full list of amenities, see the OSM Wikipedia

chart = (
    alt.Chart(poi_df)
    .mark_bar()
    .encode(y=alt.Y("amenity", sort="-x"), x="count()", tooltip=["amenity", "count()"])
)

chart
/Users/nhand/mambaforge/envs/musa-550-fall-2023/lib/python3.10/site-packages/altair/utils/schemapi.py:353: DeprecationWarning: jsonschema.RefResolver is deprecated as of v4.18.0, in favor of the https://github.com/python-jsonschema/referencing library, which provides more compliant referencing behavior as well as more flexible APIs for customization. A future release will remove RefResolver. Please file a feature request (on referencing) if you are missing an API for the kind of customization you need.
  resolver = jsonschema.RefResolver.from_schema(root or schema)
/Users/nhand/mambaforge/envs/musa-550-fall-2023/lib/python3.10/site-packages/altair/utils/schemapi.py:118: DeprecationWarning: jsonschema.RefResolver is deprecated as of v4.18.0, in favor of the https://github.com/python-jsonschema/referencing library, which provides more compliant referencing behavior as well as more flexible APIs for customization. A future release will remove RefResolver. Please file a feature request (on referencing) if you are missing an API for the kind of customization you need.
  resolver = jsonschema.RefResolver.from_schema(rootschema)

Step 2: Create a Pandana network

  • Key function: pdna_network_from_bbox()
  • It takes a bounding box and returns the OSM network within that region.
  • Multiple network types: ‘walk’ and ‘drive’
net = osm.pdna_network_from_bbox(
    lat_min, lng_min, lat_max, lng_max, network_type="walk"
)
Requesting network data within bounding box from Overpass API in 1 request(s)
Posting to http://www.overpass-api.de/api/interpreter with timeout=180, "{'data': '[out:json][timeout:180];(way["highway"]["highway"!~"motor|proposed|construction|abandoned|platform|raceway"]["foot"!~"no"]["pedestrians"!~"no"](39.92862575,-75.19358245,39.97387241,-75.12593080);>;);out;'}"
Downloaded 7,224.1KB from www.overpass-api.de in 1.11 seconds
Downloaded OSM network data within bounding box from Overpass API in 1 request(s) and 1.18 seconds
Returning OSM data with 38,122 nodes and 11,966 ways...
Edge node pairs completed. Took 3.55 seconds
Returning processed graph with 17,676 nodes and 26,530 edges...
Completed OSM data download and Pandana node and edge table creation in 5.01 seconds
Generating contraction hierarchies with 10 threads.
Setting CH node vector of size 17676
Setting CH edge vector of size 26750
Range graph removed 994 edges of 53500
. 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100%

Step 3: Tell the network the location of amenities

Key function: network.set_pois()

  • Today, we’ll explore these four amenities: “restaurant”, “bar”, “school”, “car_sharing”
  • IMPORTANT: if you want to explore other amenities, you’ll need to run the code below for your amenities of interest
# sensible defaults
max_distance = 2000  # in meters
num_pois = 10  # only need the 10 nearest POI to each point in the network


AMENITIES = ["restaurant", "bar", "school", "car_sharing"]
for amenity in AMENITIES:
    
    # get the subset of amenities for this type
    pois_subset = poi_df[poi_df["amenity"] == amenity]

    # set the POI, using the longitude and latitude of POI
    net.set_pois(
        amenity, max_distance, num_pois, pois_subset["lon"], pois_subset["lat"]
    )
# keyword arguments to pass for the matplotlib figure
bbox_aspect_ratio = (lat_max - lat_min) / (lng_max - lng_min)
fig_kwargs = {"facecolor": "w", "figsize": (10, 10 * bbox_aspect_ratio)}

# keyword arguments to pass for scatter plots
plot_kwargs = {"s": 20, "alpha": 0.9, "cmap": "viridis_r", "edgecolor": "none"}

Step 4: Plot the walking distance to the nearest POI

For every point on the network, find the nth nearest POI, calculate the distance, and color that point according to the distance.

  1. Use network.nearest_poi() to get distances from nodes to nearest POIs
  2. Merge coordinates of network nodes with distances to nearest POIs
  3. Plot the node coordinates, colored by distance to nth nearest POI

4.1 Use network.nearest_poi() to get distances from nodes to nearest POIs

amenity = "bar"
access = net.nearest_pois(distance=2000, category=amenity, num_pois=num_pois)
access.tail(n=50)
1 2 3 4 5 6 7 8 9 10
id
11224592622 505.604004 1148.965942 1176.387939 1216.400024 1387.113037 1401.880981 1401.880981 1456.896973 1534.586060 1555.621948
11224592624 647.953003 1427.760010 1455.182007 1505.411011 1676.124023 1690.891968 1690.891968 1695.935059 1745.907959 1823.597046
11224592628 640.257996 1420.064941 1447.487061 1497.715942 1668.428955 1683.197021 1683.197021 1688.239990 1738.213013 1815.901978
11224592629 603.883972 1408.291992 1435.713989 1485.942993 1656.656006 1671.423950 1671.423950 1679.582031 1726.439941 1804.129028
11224592630 609.986023 1310.845947 1338.267944 1388.496948 1559.209961 1573.978027 1573.978027 1582.135986 1628.994019 1706.682983
11224592632 405.128998 1251.527954 1278.949951 1329.178955 1499.891968 1514.660034 1514.660034 1569.676025 1644.415039 1647.364990
11224592633 392.946991 1263.709961 1291.131958 1341.360962 1512.073975 1526.842041 1526.842041 1581.858032 1632.233032 1659.546997
11224592634 362.889008 1293.767944 1321.189941 1371.418945 1542.131958 1556.900024 1556.900024 1602.175049 1611.916016 1647.284058
11224592635 404.954010 1315.300049 1342.722046 1392.951050 1563.663940 1578.432007 1578.432007 1633.447998 1644.239990 1689.348999
11224592636 526.257019 1313.577026 1340.999023 1391.228027 1561.941040 1576.708984 1576.708984 1591.637939 1631.724976 1709.413940
11224607837 352.937988 1303.718994 1331.140991 1381.369995 1552.083008 1566.850952 1566.850952 1592.223999 1621.866943 1637.333008
11224607838 342.132996 1314.524048 1341.946045 1392.175049 1562.887939 1577.656006 1577.656006 1596.791992 1631.265991 1632.671997
11224607839 333.376007 1323.281006 1350.703003 1400.932007 1571.645020 1586.412964 1586.412964 1602.218994 1636.532959 1641.428955
11224607840 613.419006 1468.312012 1495.734009 1545.963013 1716.676025 1731.443970 1731.443970 1739.602051 1786.459961 1864.149048
11224607841 607.888000 1532.484009 1559.906006 1610.135010 1780.848022 1795.615967 1795.615967 1802.860962 1850.631958 1928.321045
11224607849 610.934021 1535.530029 1562.952026 1613.181030 1783.894043 1798.661987 1798.661987 1805.906982 1853.677979 1931.366943
11224607852 961.911011 1109.610962 1148.056030 1224.317993 1323.193970 1400.375977 1400.375977 1401.566040 1471.349976 1533.081055
11224607853 891.935974 1032.795044 1071.239990 1154.343018 1246.378052 1330.401001 1330.401001 1331.590942 1401.375000 1463.105957
11224607854 936.064026 985.156006 1023.601013 1163.201050 1198.739014 1291.537964 1291.537964 1340.448975 1410.233032 1424.243042
11224607856 953.991028 967.229004 1005.674011 1145.274048 1180.812012 1273.610962 1273.610962 1322.521973 1392.306030 1406.316040
11224607857 874.960999 1046.150024 1073.572021 1137.368042 1261.709961 1313.426025 1313.426025 1314.615967 1384.400024 1446.130981
11224607858 945.812012 1117.000977 1144.422974 1208.218994 1332.561035 1384.276978 1384.276978 1385.467041 1455.250977 1516.982056
11224607859 953.663025 1113.172974 1151.618042 1216.069946 1326.755981 1392.128052 1392.128052 1393.317993 1463.102051 1524.833008
11224607860 968.812012 1128.994995 1167.422974 1231.218994 1342.578003 1407.276978 1407.276978 1408.467041 1478.250977 1539.982056
11224607861 960.997986 1132.187012 1159.609009 1223.405029 1347.746948 1399.463013 1399.463013 1400.652954 1470.437012 1532.167969
11224607863 946.263000 954.874023 984.708008 1124.307983 1159.845947 1252.645020 1252.645020 1301.556030 1371.339966 1385.349976
11224607865 935.150024 965.987000 1004.432007 1144.031982 1179.569946 1272.369019 1272.369019 1321.280029 1391.063965 1405.073975
11224607868 1007.349976 1244.845947 1281.813965 1345.609985 1458.428955 1521.667969 1521.667969 1522.858032 1592.641968 1654.373047
11224607869 998.971985 1250.167969 1277.589966 1341.385986 1465.728027 1517.443970 1517.443970 1518.634033 1588.417969 1650.149048
11224607870 1022.861023 1229.334961 1266.302979 1330.098999 1442.917969 1506.156982 1506.156982 1507.347046 1577.130981 1638.862061
11224607871 1018.869019 1230.270996 1257.692993 1321.489014 1445.831055 1497.546997 1497.546997 1498.737061 1568.520996 1630.251953
11224607872 751.398987 1052.126953 1199.595947 1218.369019 1222.839966 1238.843994 1238.843994 1292.624023 1371.548950 1391.348999
11227252843 333.114014 333.114014 803.945984 803.945984 1010.838013 1022.827026 1131.537964 1189.163940 1216.343018 1258.291016
11228152173 238.455994 396.096985 439.218994 511.817993 600.966003 618.379028 650.729004 666.552002 695.070984 790.903992
11228152174 236.501999 394.143005 437.265015 509.864014 599.012024 616.424988 648.775024 664.598022 693.117004 788.950012
11228152182 337.255005 494.895996 588.390991 610.617004 699.765015 710.736023 743.085999 758.908997 797.312012 889.703003
11228181157 142.044006 169.093002 205.518005 372.545013 394.484985 397.846008 443.321014 540.862976 596.796997 632.458984
11228181161 61.731998 125.206001 240.009003 314.173004 316.790985 317.533997 363.009003 516.484985 552.146973 603.695984
11228181162 141.494003 160.246994 204.968002 363.699005 393.934998 397.295990 442.770996 532.017029 596.247009 631.908997
11228187771 172.931000 330.571991 446.292999 500.351013 535.440979 546.411987 578.762024 594.585022 632.987976 725.379028
11228187772 178.738998 336.380005 452.101013 506.158997 541.249023 552.219971 584.570007 600.393005 638.796021 731.187012
11228187788 196.298996 200.123001 315.843994 404.992004 438.855011 472.377014 487.028015 645.734985 649.096008 650.734985
11228187796 207.257004 211.080994 326.802002 415.950012 449.812988 483.334991 497.985992 656.692993 660.054016 661.692993
11228187797 219.723999 223.548004 339.269012 428.416992 462.279999 495.802002 510.453003 669.159973 672.520996 674.159973
11228187801 182.304001 186.128006 301.848999 390.997009 424.859985 458.381989 473.032990 631.739990 635.101013 636.739990
11228187802 194.306000 198.130005 313.851013 402.998993 436.862000 470.384003 485.035004 643.742004 647.103027 648.742004
11228187803 176.192001 180.016006 295.737000 384.885010 418.747986 452.269989 466.920990 625.627991 628.989014 632.762024
11228187815 162.623001 248.774002 364.494995 453.643005 487.506012 521.028015 535.679016 567.658997 694.385986 697.747009
11235679027 1146.733032 1146.733032 1309.551025 1341.865967 1341.865967 1394.008057 1394.008057 1502.314941 1630.319946 1704.982056
11236771921 707.703979 875.854004 926.666016 941.291992 943.551025 1038.303955 1138.055054 1263.562012 1279.468994 1279.723999

4.2 Merge coordinates of network nodes with distances to nearest POIs

net.nodes_df.head()
x y
id
103327043 -75.128666 39.934488
103332711 -75.128062 39.939224
103332730 -75.129329 39.941869
103333406 -75.130257 39.943351
103333412 -75.130332 39.943123
access.head()
1 2 3 4 5 6 7 8 9 10
id
103327043 1752.093018 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103332711 988.283020 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103332730 670.846008 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103333406 597.692993 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
103333412 623.888977 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0
# Merge the nodes and the distance to POIs
nodes = pd.merge(net.nodes_df, access, left_index=True, right_index=True)

# Make into a geodataframe
nodes = gpd.GeoDataFrame(
    nodes, geometry=gpd.points_from_xy(nodes["x"], nodes["y"]), crs="EPSG:4326"
)
nodes.head()
x y 1 2 3 4 5 6 7 8 9 10 geometry
id
103327043 -75.128666 39.934488 1752.093018 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 POINT (-75.12867 39.93449)
103332711 -75.128062 39.939224 988.283020 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 POINT (-75.12806 39.93922)
103332730 -75.129329 39.941869 670.846008 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 POINT (-75.12933 39.94187)
103333406 -75.130257 39.943351 597.692993 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 POINT (-75.13026 39.94335)
103333412 -75.130332 39.943123 623.888977 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 2000.0 POINT (-75.13033 39.94312)

4.3 And now plot it!

Let’s define a function to do this for us, since we’ll repeat this plot multiple times

def plot_walking_distance(net, amenity, distance=1000, n=1):
    """
    Plot the walking distance to the specified amenity
    """
    from mpl_toolkits.axes_grid1 import make_axes_locatable

    # subset of POI
    poi_subset = poi_df[poi_df["amenity"] == amenity]

    # get the distances to nearest num_pois POI
    access = net.nearest_pois(distance=1000, category=amenity, num_pois=num_pois)

    # merge node positions and distances to nearest PO
    nodes = pd.merge(net.nodes_df, access, left_index=True, right_index=True)
    nodes = gpd.GeoDataFrame(
        nodes, geometry=gpd.points_from_xy(nodes["x"], nodes["y"]), crs="EPSG:4326"
    )

    # Create the figure
    fig, ax = plt.subplots(figsize=(10, 10))
    divider = make_axes_locatable(ax)
    cax = divider.append_axes("right", size="5%", pad=0.1)

    # plot the distance to the nth nearest amenity
    ax = nodes.plot(ax=ax, cax=cax, column=nodes[n], legend=True, **plot_kwargs)

    # add the amenities as stars
    for i, row in poi_subset.iterrows():
        ax.scatter(row["lon"], row["lat"], color="red", s=100, marker="*")

    # format
    ax.set_facecolor("black")
    ax.figure.set_size_inches(fig_kwargs["figsize"])

    # set extent
    [xmin, ymin, xmax, ymax] = nodes.geometry.total_bounds
    ax.set_xlim(xmin, xmax)
    ax.set_ylim(ymin, ymax)

    return ax

Evaluating amenity choice

The difference between maps to the nearest amenity and for example, the 5th nearest amenity tells us about the options consumers have

Example: bars

ax = plot_walking_distance(net, "bar", n=1)
ax.set_title("Walking distance to the nearest bar", fontsize=18);

ax = plot_walking_distance(net, "bar", n=3)
ax.set_title("Walking distance to the 3rd nearest bar", fontsize=18);

Example: schools

ax = plot_walking_distance(net, "school", n=1)
ax.set_title("Walking distance to the nearest school", fontsize=18);

ax = plot_walking_distance(net, "school", n=3)
ax.set_title("Walking distance to the 3rd nearest school", fontsize=18);

Example: restaurants

ax = plot_walking_distance(net, "restaurant", n=1)
ax.set_title("Walking distance to the nearest restaurant", fontsize=18);

ax = plot_walking_distance(net, "restaurant", n=10)
ax.set_title("Walking distance to the 10th nearest restaurant", fontsize=18);

Example: car sharing

ax = plot_walking_distance(net, "car_sharing", n=1)
ax.set_title("Walking distance to the nearest car sharing", fontsize=18);

ax = plot_walking_distance(net, "car_sharing", n=10)
ax.set_title("Walking distance to the 10th nearest car sharing", fontsize=18);

At-home exercise: Explore amenities in the neighborhood of your choice

Many, many more amenities are logged throughout the city. Pick your favorite neighborhood and explore.

See this page for the full list of amenities.

Final project idea: With this kind of analysis, you can look at amenity-based influence in housing, neighborhood selection, etc. or something similar to the Walk Score.

Content 2023 by Nick Hand, Quarto layout adapted from Andrew Heiss’s Data Visualization with R course
All content licensed under a Creative Commons Attribution-NonCommercial 4.0 International license (CC BY-NC 4.0)
 
Made with and Quarto
View the source at GitHub