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#
from polaris.network.consistency.network_objects.location 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"])
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_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.census_zone = loc.anchored = 0
loc.link = net.geotools.get_link_for_point_by_mode(loc.geo, ["AUTO"])
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"])
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"])
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(False)