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#

from polaris.network.consistency.network_objects import Location
from shapely.geometry import Point

sphinx_gallery_thumbnail_path = ‘../../examples/model_building/map_import_osm_locations.png’

from tests.create_test_files import use_test_network
from tqdm import tqdm

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")

# We may consider only hospitals with emergency rooms ("real hospitals"), for example
valid_hospitals = [x for x in hospitals if x.get("tags", {}).get("emergency", "no") == "yes"]
print(len(valid_hospitals))

Adds these hospitals to the model

land_use = "MEDICAL"
max_loc = net.conn.execute("Select coalesce(max(location) + 1, 1) from Location").fetchone()[0]

for hosp in tqdm(valid_hospitals):
    loc = Location(max_loc, net.geotools, net.data_tables)
    loc.land_use = land_use
    loc.notes = f'osmid {hosp["id"]}'
    loc.geo = Point(hosp["lon"], hosp["lat"])

    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.census_zone = loc.anchored = 0
    loc.link = net.geotools.get_link_for_point_by_mode(loc.geo, ["AUTO"])[0]
    loc.save()
    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 = [i for i in schools if "HIGH SCHOOL" in i.get("tags", {}).get("name", "").upper()]
esch = [i for i in schools if "ELEMENTARY SCHOOL" in i.get("tags", {}).get("name", "").upper()]
print(f"High Schools: {len(hsch)}, Elementary schools: {len(esch)}")

Now let’s add schools to the model

added_schools = []
land_use = "EDUCATION"

for sch in tqdm(schools):
    loc = Location(max_loc, net.geotools, net.data_tables)
    loc.land_use = land_use
    loc.notes = f'osmid {sch["id"]}'
    loc.geo = Point(sch["lon"], sch["lat"])
    zone = net.geotools.get_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.census_zone = loc.anchored = 0
    loc.link = net.geotools.get_link_for_point_by_mode(loc.geo, ["AUTO"])[0]
    loc.save()
    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")
print(f"Universities: {len(universities)}")

Now let’s add universities to the model

land_use = "HIGHER_EDUCATION"

for sch in tqdm(universities):
    loc = Location(max_loc, net.geotools, net.data_tables)
    loc.land_use = land_use
    loc.notes = f'osmid {sch["id"]}'
    loc.geo = Point(sch["lon"], sch["lat"])
    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.census_zone = loc.anchored = 0
    loc.link = net.geotools.get_link_for_point_by_mode(loc.geo, ["AUTO"])[0]
    loc.save()
    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 tqdm(hotel_tags):
    hot_data = osm.get_tag("tourism", tag)
    hotels.extend(hot_data)

Now let’s add hotels to the model

land_use = "HOTEL"

for hotel in tqdm(hotels):
    loc = Location(max_loc, net.geotools, net.data_tables)
    loc.land_use = land_use
    loc.notes = f'osmid {hotel["id"]}'
    loc.geo = Point(hotel["lon"], hotel["lat"])

    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.census_zone = loc.anchored = 0
    loc.link = net.geotools.get_link_for_point_by_mode(loc.geo, ["AUTO"])[0]
    loc.save()
    max_loc += 1
print(f"Added {len(hotels)} hotels to the model")

Visualizing the results#

from polaris.network.data.data_table_cache import DataTableCache
import folium
import shapely.wkt
import geopandas as gpd

locations = DataTableCache(net.path_to_file).plotting_layer("location", net.conn).reset_index()
locations.geo = locations.geo.apply(shapely.wkt.loads)

js = locations[["location", "land_use", "geo"]]
js = gpd.GeoDataFrame(js, geometry="geo", crs=4326)

map_osm = folium.Map(location=[js.geo.y.mean(), js.geo.x.mean()], zoom_start=9)

if hotels:
    hot = "HOTEL"
    m1 = folium.Marker(icon=folium.Icon(color="blue", prefix="fa", icon="bed"))
    folium.GeoJson(js[js.land_use == hot].to_json(), name="Hotels", show=True, marker=m1, tooltip=hot).add_to(map_osm)

if universities:
    u = "Universities"
    m2 = folium.Marker(icon=folium.Icon(color="blue", prefix="fa", icon="graduation-cap"))
    folium.GeoJson(js[js.land_use == "HIGHER_EDUCATION"].to_json(), name=u, show=True, marker=m2, tooltip=u).add_to(
        map_osm
    )

if added_schools:
    ed = "EDUCATION"
    m3 = folium.Marker(icon=folium.Icon(color="green", prefix="fa", icon="bicycle"))
    folium.GeoJson(js[js.land_use == ed].to_json(), name="Schools", show=True, marker=m3, tooltip=ed).add_to(map_osm)

if valid_hospitals:
    h = "Hospitals"
    m4 = folium.Marker(icon=folium.Icon(color="green", prefix="fa", icon="hospital-o"))
    folium.GeoJson(js[js.land_use == "MEDICAL"].to_json(), name=h, show=True, marker=m4, tooltip=h).add_to(map_osm)

folium.LayerControl().add_to(map_osm)
map_osm

Closes project#

print("REFERENCE: You can keep navigating the map after closing the project")
net.close()

Gallery generated by Sphinx-Gallery