Note
Go to the end to download the full example code.
Creation of locations from OSM data#
On this example we show how to use polaris to query OSM and retrieve specific types of amenities to represent as locations on a Polaris Model.
Imports#
import pandas as pd
from polaris.network.consistency.network_objects.location import Location
from polaris.utils.database.db_utils import commit_and_close
sphinx_gallery_thumbnail_path = ‘../../examples/model_building/map_import_osm_locations.png’
from tests.create_test_files import use_test_network
Open the project and get the OSM class
# net = Network()
# net.open("my_model_path/Chicago-Supply.sqlite")
net = use_test_network("walk_link_tests")
# Let's delete what's already in the locations table so we can see exactly what we have added
net.conn.execute("DELETE FROM Location")
net.conn.commit()
osm = net.osm
Configuring the model#
We need to make sure that all land uses needed for the locations we are creating are in the model
medical_lu = "INSERT OR IGNORE INTO land_use(land_use, is_home, is_work,is_school,is_discretionary,notes) VALUES('MEDICAL',0,1,0,1,'');"
hotel_lu = "INSERT OR IGNORE INTO land_use(land_use, is_home, is_work,is_school,is_discretionary,notes) VALUES('HOTEL',0,1,0,1,'');"
school_lu = "INSERT OR IGNORE INTO land_use(land_use, is_home, is_work,is_school,is_discretionary,notes) VALUES('EDUCATION',0,1,1,0,'');"
univ_lu = "INSERT OR IGNORE INTO land_use(land_use, is_home, is_work,is_school,is_discretionary,notes) VALUES('HIGHER_EDUCATION',0,1,1,0,'');"
for sql in [medical_lu, hotel_lu, school_lu, univ_lu]:
net.conn.execute(sql)
net.conn.commit()
Hospitals#
For documentation on how hospitals are coded on OSM: https://wiki.openstreetmap.org/wiki/Healthcare
hospitals = osm.get_tag("healthcare", "hospital")
hospitals.head()
Adds these hospitals to the model
land_use = "MEDICAL"
max_loc = net.conn.execute("Select coalesce(max(location) + 1, 1) from Location").fetchone()[0]
with commit_and_close(net.path_to_file, spatial=True) as conn:
for _, hosp in hospitals.iterrows():
loc = Location(max_loc, net.geotools, net.tables, conn)
loc.land_use = land_use
loc.notes = f"osmid {hosp.osm_id}"
loc.geo = hosp.geo
loc.avg_parking_cost = loc.stop_flag = loc.dir = loc.offset = loc.setback = loc.x = loc.y = 0
loc.truck_org = loc.truck_des = loc.auto_org = loc.auto_des = 1
loc.transit = loc.area_type = loc.lu_area = loc.popsyn_region = loc.anchored = loc.tod_distance = 0
loc.link = net.geotools.get_link_for_point_by_mode(loc.geo, ["AUTO"])
loc.save(conn)
max_loc += 1
Schools#
For documentation on how schools are coded on OSM: https://wiki.openstreetmap.org/wiki/Tag:amenity%3Dschool
schools = osm.get_tag("amenity", "school")
hsch = schools.query("all_tags.str.contains('HIGH SCHOOL', case=False, na=False)")
esch = schools.query("all_tags.str.contains('ELEMENTARY SCHOOL', case=False, na=False)")
print(f"High Schools: {hsch.shape[0]}, Elementary schools: {esch.shape[0]}")
Now let’s add schools to the model
added_schools = []
land_use = "EDUCATION"
with commit_and_close(net.path_to_file, spatial=True) as conn:
for _, sch in schools.iterrows():
loc = Location(max_loc, net.geotools, net.tables, conn)
loc.land_use = land_use
loc.notes = f"osmid {sch.osm_id}"
loc.geo = sch.geo
zone = net.geotools.get_geo_item("zone", loc.geo)
added_schools.append(zone)
loc.avg_parking_cost = loc.stop_flag = loc.dir = loc.offset = loc.setback = loc.x = loc.y = 0
loc.truck_org = loc.truck_des = loc.auto_org = loc.auto_des = 1
loc.transit = loc.area_type = loc.lu_area = loc.popsyn_region = loc.anchored = loc.tod_distance = 0
loc.link = net.geotools.get_link_for_point_by_mode(loc.geo, ["AUTO"])
loc.save(conn)
max_loc += 1
print(f"Added {len(schools)} schools in {len(set(added_schools))} different zones")
Universities#
For documentation on how Universities are coded on OSM: https://wiki.openstreetmap.org/wiki/Tag:amenity%3Duniversity
universities = osm.get_tag("amenity", "university")
universities
Now let’s add universities to the model
land_use = "HIGHER_EDUCATION"
with commit_and_close(net.path_to_file, spatial=True) as conn:
for _, sch in universities.iterrows():
loc = Location(max_loc, net.geotools, net.tables, conn)
loc.land_use = land_use
loc.notes = f"osmid {sch.osm_id}"
loc.geo = sch.geo
loc.avg_parking_cost = loc.stop_flag = loc.dir = loc.offset = loc.setback = loc.x = loc.y = 0
loc.truck_org = loc.truck_des = loc.auto_org = loc.auto_des = 1
loc.transit = loc.area_type = loc.lu_area = loc.popsyn_region = loc.anchored = loc.tod_distance = 0
loc.link = net.geotools.get_link_for_point_by_mode(loc.geo, ["AUTO"])
loc.save(conn)
max_loc += 1
Hotels#
For documentation on how hotels are coded on OSM: https://wiki.openstreetmap.org/wiki/Key:tourism
hotel_tags = ["hotel", "hostel", "motel", "guest_house", "chalet", "apartment"]
hotels = []
for tag in hotel_tags:
hot_data = osm.get_tag("tourism", tag)
hotels.append(hot_data)
all_hotels = pd.concat(hotels)
all_hotels
Now let’s add hotels to the model
land_use = "HOTEL"
with commit_and_close(net.path_to_file, spatial=True) as conn:
for _, hotel in all_hotels.iterrows():
loc = Location(max_loc, net.geotools, net.tables, conn)
loc.land_use = land_use
loc.notes = f"osmid {hotel.osm_id}"
loc.geo = hotel.geo
loc.avg_parking_cost = loc.stop_flag = loc.dir = loc.offset = loc.setback = loc.x = loc.y = 0
loc.truck_org = loc.truck_des = loc.auto_org = loc.auto_des = 1
loc.transit = loc.area_type = loc.lu_area = loc.popsyn_region = loc.anchored = loc.tod_distance = 0
loc.link = net.geotools.get_link_for_point_by_mode(loc.geo, ["AUTO"])
loc.save(conn)
max_loc += 1
print(f"Added {len(hotels)} hotels to the model")
Visualizing the results#
from polaris.utils.database.data_table_access import DataTableAccess
import folium
import geopandas as gpd
locations = DataTableAccess(net.path_to_file).get("location", net.conn)
js = locations[["location", "land_use", "geo"]]
js = gpd.GeoDataFrame(js, geometry="geo", crs=4326)
map = folium.Map(location=[js.geo.y.mean(), js.geo.x.mean()], zoom_start=9)
criteria = [
["HOTEL", "HOTEL", "bed", "blue", "Hotels"],
["MEDICAL", "MEDICAL", "hospital-o", "green", "Hospitals"],
["EDUCATION", "EDUCATION", "bicycle", "green", "Schools"],
["Universities", "HIGHER_EDUCATION", "graduation-cap", "blue", "Universities"],
]
for crit, filter, icon, color, name in criteria:
map = js[js.land_use == filter].explore(
m=map, color=color, tool_tip=crit, marker_kwds={"icon": icon, "prefix": "fa", "color": color}, name=name
)
folium.LayerControl().add_to(map)
map
Closes project#
print("REFERENCE: You can keep navigating the map after closing the project")
net.close(False)