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)

Gallery generated by Sphinx-Gallery