This page was generated from notebooks/lscp_gis.ipynb. Interactive online version:
Siting First Aid Stations with LSCP on Toronto’s University Campus¶
Authors: Timothy Ellersiek, James Gaboardi, Germano Barcelos
This notebook implements the location set covering problem (LSCP) to site first aid stations for Toronto’s University campus. LSCP determines locations such that as many demand points as possible are within the maximum service radius. By doing so, the number of locations required to cover all demand points is minimized. In contrast to the maximum covering location problem it does not require a maximum amount of locations as an input parameter. Hence, the use cases for LSCP are specific. One common scenario is finding suitable locations for hospitals in cities where the amount is governed by reachability preconditions to households in a certain amount of time.
In this notebook demand is described as buildings within Toronto’s University campus. Possible locations for the first aid stations are determined using Overpass API which fetches geometries directly from OpenStreetMap.org.
The routing matrix is computed using Open Source Routing Machine’s demo server API.
Prerequisites¶
To run this jupyter notebook locally, you will have to install the following additional libraries into your python environment.
[1]:
%config InlineBackend.figure_format = "retina"
%load_ext watermark
%watermark
Last updated: 2024-04-10T20:05:10.264964-03:00
Python implementation: CPython
Python version : 3.10.12
IPython version : 8.14.0
Compiler : GCC 12.3.0
OS : Linux
Release : 6.5.0-26-generic
Machine : x86_64
Processor : x86_64
CPU cores : 8
Architecture: 64bit
[2]:
import folium
import json
import numpy
import overpy
import pulp
import routingpy
from routingpy import OSRM
import shapely
from shapely.geometry import shape, Point
import spopt
from spopt.locate import LSCP
%watermark -w
%watermark -iv
Watermark: 2.4.3
routingpy: 1.2.1
pulp : 2.7.0
json : 2.0.9
shapely : 2.0.1
overpy : 0.6
folium : 0.14.0
numpy : 1.25.0
spopt : 0.6.1.dev10+gc9efa6c.d20240410
Create overpy.Overpass()
instance in order to make queries
[3]:
api = overpy.Overpass()
First of all we want to fetch all buildings in the University of Toronto boundary
[4]:
result = api.query(
"""
[out:json];
area[name="Toronto"]->.b;
way(area.b)[name="University of Toronto"];
map_to_area -> .a;
way[building="university"](area.a);
out center;
"""
)
Create a folium.Map()
instance to visualize the data
[5]:
m = folium.Map(
location=[43.6624674, -79.3988052], tiles="cartodbpositron", zoom_start=15
)
Let’s add our results to the map!
[6]:
def get_centroid(pnt_info, xy=True):
"""Extract centroid from location information."""
if isinstance(pnt_info, overpy.Way):
x, y = pnt_info.center_lon, pnt_info.center_lat
if not xy:
x, y = y, x
else:
x, y = pnt_info["center"][1], pnt_info["center"][0]
return [x, y]
[7]:
get_tag = lambda w: w.tags.get("name", "n/a")
[8]:
university_buildings = []
university_buildings_locations = []
university_buildings_fg = folium.FeatureGroup("University Buildings").add_to(m)
for idx, way in enumerate(result.ways):
tag = get_tag(way)
loc_yx = get_centroid(way, xy=False)
folium.CircleMarker(
location=loc_yx,
radius=3,
fill=True,
fill_opacity=0.3,
popup=folium.Popup(tag, show=False),
color="blue",
).add_to(university_buildings_fg)
# building centroids
university_buildings.append({"name": tag, "center": get_centroid(way), "idx": idx})
university_buildings_locations.append(loc_yx)
n_uni_bld = len(university_buildings)
m
[8]:
And now we want to fetch some roads in the same area and return their center points which we can use for our potential locations for first aid stations
[9]:
result_roads = api.query(
"""
[out:json];
area[name="Toronto"]->.b;
way(area.b)[name="University of Toronto"];
map_to_area -> .a;
way["highway"~"secondary|tertiary|unclassified"](area.a);
out center;
"""
)
Similarly we want to add them to the map
[10]:
first_aid_stations = []
first_aid_stations_locations = []
first_aid_stations_fg = folium.FeatureGroup("First Aid Station Locations").add_to(m)
for idx, way in enumerate(result_roads.ways):
tag = get_tag(way)
loc_yx = get_centroid(way, xy=False)
folium.CircleMarker(
location=loc_yx,
radius=2,
fill=True,
fill_opacity=1,
popup=folium.Popup(tag, show=False),
color="black",
).add_to(first_aid_stations_fg)
# road midpoints
first_aid_stations.append(
{"name": tag, "center": get_centroid(way), "idx": idx + n_uni_bld}
)
first_aid_stations_locations.append(loc_yx)
m
[10]:
Computing the Distance (Routing) Matrix¶
Given our potential first aid station locations and the university buildings on the campus we want to compute our distance matrix. Instead of using simple euclidean distance we can make use of proper routes following roads which will yield more realistic travel times. The routing-py library helps us achieve this which features the ability to use different open source frameworks such as OSRM or Valhalla as well as 3rd party API’s such as Google Maps or HERE.
[11]:
client = OSRM(base_url="https://router.project-osrm.org")
Isolate all location coordinates
[12]:
all_locations = university_buildings_locations + first_aid_stations_locations
all_locations = [[x, y] for y, x in all_locations]
all_locations[:5]
[12]:
[[Decimal('-79.3988052'), Decimal('43.6624674')],
[Decimal('-79.3994442'), Decimal('43.6643897')],
[Decimal('-79.3895107'), Decimal('43.6648522')],
[Decimal('-79.3971848'), Decimal('43.6625440')],
[Decimal('-79.3958563'), Decimal('43.6628344')]]
Define source and target indices
[13]:
source_indices = [i["idx"] for i in university_buildings]
target_indices = [i["idx"] for i in first_aid_stations]
[14]:
source_indices[-5:], target_indices[:5]
[14]:
([117, 118, 119, 120, 121], [122, 123, 124, 125, 126])
Generate routing matrix object
[15]:
osrm_routing_matrix = client.matrix(
dry_run=False,
locations=all_locations,
sources=source_indices,
destinations=target_indices,
profile="pedestrian",
)
Isolate route durations
[16]:
cost_matrix = numpy.array(osrm_routing_matrix.durations)
cost_matrix.shape
[16]:
(122, 36)
[17]:
cost_matrix
[17]:
array([[239.6, 129.1, 164.5, ..., 71.3, 24.7, 39.1],
[217.3, 106.8, 152.5, ..., 49. , 31.3, 45.7],
[183.5, 134.3, 152.5, ..., 141.8, 197.2, 211.6],
...,
[240.1, 129.6, 175.3, ..., 71.8, 18.7, 33.1],
[186.8, 42.6, 88.3, ..., 145.1, 200.5, 214.9],
[136.1, 167.6, 207.3, ..., 116.9, 172.3, 186.7]])
Solving the LSCP¶
Last but not least we want to run the solver. We choose the pulp.COIN_CMD
and set the distance cutoff to 4 minutes and 50 seconds afoot. Note that, the service radius is large since it is the minimum acceptable value that covers all buildings. To decrease this value, there are two options: remove buildings far away from aid stations or add more potential aid stations in sparse regions.
Finally we loop over the solution and add the sited stations and the corresponding allocated buildings to the map with different radiuses.
[18]:
# maximum acceptable service duration, 4 minutes and 50 seconds
SERVICE_RADIUS = 290
# set the solver (for available solvers run ``pulp.listSolvers(onlyAvailable=True)``)
solver = pulp.COIN_CMD(msg=False)
Create and solve an LSCP instance
[19]:
lscp = LSCP.from_cost_matrix(cost_matrix, SERVICE_RADIUS)
lscp = lscp.solve(solver)
How many first aid sites are needed to entirely cover the university buildings?
[20]:
lscp.problem.objective.value()
[20]:
1.0
Add the results to the map
[21]:
sited_first_aid_stations_fg = folium.FeatureGroup("Sited First Aid Stations").add_to(m)
allocated_buildings_demand_fg = folium.FeatureGroup("Allocated Buildings").add_to(m)
solution = {}
colors = [
"darkcyan",
"mediumseagreen",
"saddlebrown",
"lightskyblue",
"darkgoldenrod",
"coral",
"mediumvioletred",
"blueviolet",
"mediumorchid",
]
client_marker_size = 20
numpy.random.seed(0)
for i in range(len(first_aid_stations)):
if lscp.fac2cli[i]:
color_choice_idx = numpy.random.choice(range(len(colors)))
color = colors.pop(color_choice_idx)
# selected candidate facility sites
folium.CircleMarker(
location=first_aid_stations_locations[i],
radius=30,
fill=True,
popup=folium.Popup(f"Sited First Aid Station (index: {i})", show=True),
color=color,
).add_to(sited_first_aid_stations_fg)
# client locations with associated facility symbology
client_marker_size -= 4
solution[i] = []
for j in lscp.fac2cli[i]:
solution[i].append(university_buildings[j])
folium.CircleMarker(
location=university_buildings_locations[j],
radius=client_marker_size,
fill=True,
popup=f"Building allocated to First Aid Station with index: {i}",
color=color,
).add_to(allocated_buildings_demand_fg)
folium.LayerControl().add_to(m)
m
[21]:
It is important to note that the modeling solution is a direct result of the input cost matrix (seconds of travel) obtained from routingpy.OSRM
. Although the solution set and decisions may not appear to optimal, the formulation of and solution to the LSCP are correct based on the input matrix.
[22]:
solution
[22]:
{28: [{'name': 'Sidney Smith Hall',
'center': [Decimal('-79.3988052'), Decimal('43.6624674')],
'idx': 0},
{'name': 'Robarts Library',
'center': [Decimal('-79.3994442'), Decimal('43.6643897')],
'idx': 1},
{'name': 'J. M. Kelly Library',
'center': [Decimal('-79.3895107'), Decimal('43.6648522')],
'idx': 2},
{'name': 'Sir Daniel Wilson Residence (University College)',
'center': [Decimal('-79.3971848'), Decimal('43.6625440')],
'idx': 3},
{'name': 'University College',
'center': [Decimal('-79.3958563'), Decimal('43.6628344')],
'idx': 4},
{'name': 'Toronto Magnetic and Meteorological Observatory',
'center': [Decimal('-79.3946172'), Decimal('43.6631765')],
'idx': 5},
{'name': 'Koffler Student Services Centre',
'center': [Decimal('-79.3968996'), Decimal('43.6591667')],
'idx': 6},
{'name': 'Daniels Building',
'center': [Decimal('-79.4007115'), Decimal('43.6596491')],
'idx': 7},
{'name': 'Warren Stevens Building',
'center': [Decimal('-79.4010325'), Decimal('43.6627537')],
'idx': 8},
{'name': 'E. J. Pratt Library',
'center': [Decimal('-79.3912921'), Decimal('43.6663202')],
'idx': 9},
{'name': 'Northrop Frye Hall',
'center': [Decimal('-79.3921389'), Decimal('43.6664141')],
'idx': 10},
{'name': 'Carr Hall',
'center': [Decimal('-79.3904148'), Decimal('43.6652328')],
'idx': 11},
{'name': 'Muzzo Family Alumni Hall',
'center': [Decimal('-79.3901376'), Decimal('43.6647637')],
'idx': 12},
{'name': 'Ramsay Wright Building',
'center': [Decimal('-79.3990600'), Decimal('43.6632684')],
'idx': 13},
{'name': 'Clara Benson Building',
'center': [Decimal('-79.4002584'), Decimal('43.6629833')],
'idx': 14},
{'name': 'Fisher Rare Book Library',
'center': [Decimal('-79.3989770'), Decimal('43.6640748')],
'idx': 15},
{'name': 'Munk School of Global Affairs & Public Policy',
'center': [Decimal('-79.3966877'), Decimal('43.6650246')],
'idx': 16},
{'name': 'Claude T. Bissell Building',
'center': [Decimal('-79.3993354'), Decimal('43.6650287')],
'idx': 17},
{'name': 'Simcoe Hall',
'center': [Decimal('-79.3959493'), Decimal('43.6607473')],
'idx': 18},
{'name': 'Edward Johnson Building',
'center': [Decimal('-79.3945745'), Decimal('43.6666055')],
'idx': 19},
{'name': 'Flavelle House',
'center': [Decimal('-79.3939081'), Decimal('43.6661332')],
'idx': 20},
{'name': 'Falconer Hall',
'center': [Decimal('-79.3939344'), Decimal('43.6667134')],
'idx': 21},
{'name': 'Joseph L. Rotman Faculty of Management',
'center': [Decimal('-79.3984429'), Decimal('43.6653599')],
'idx': 22},
{'name': 'n/a',
'center': [Decimal('-79.3981669'), Decimal('43.6591511')],
'idx': 23},
{'name': 'UTSU Student Commons',
'center': [Decimal('-79.3980011'), Decimal('43.6586788')],
'idx': 24},
{'name': 'The Terrence Donnelly Centre for Cellular and Biomolecular Research',
'center': [Decimal('-79.3929327'), Decimal('43.6601354')],
'idx': 25},
{'name': 'Lassonde Mining Building',
'center': [Decimal('-79.3934676'), Decimal('43.6595254')],
'idx': 26},
{'name': 'Leslie Dan Pharmacy Building',
'center': [Decimal('-79.3917767'), Decimal('43.6599499')],
'idx': 27},
{'name': 'Wallberg Building',
'center': [Decimal('-79.3952383'), Decimal('43.6592007')],
'idx': 28},
{'name': 'Isabel Bader Theatre',
'center': [Decimal('-79.3923649'), Decimal('43.6672514')],
'idx': 29},
{'name': 'Birge Carnegie',
'center': [Decimal('-79.3929187'), Decimal('43.6670922')],
'idx': 30},
{'name': 'Whitney Hall',
'center': [Decimal('-79.3977761'), Decimal('43.6638039')],
'idx': 31},
{'name': 'Sanford Fleming Building',
'center': [Decimal('-79.3952176'), Decimal('43.6601402')],
'idx': 32},
{'name': 'Howard Ferguson Dining Hall',
'center': [Decimal('-79.3971823'), Decimal('43.6629811')],
'idx': 33},
{'name': 'Centre for Biological Timing and Cognition',
'center': [Decimal('-79.3993038'), Decimal('43.6628627')],
'idx': 34},
{'name': 'The Jones and Edna Davenport Chemical Research Building',
'center': [Decimal('-79.3977963'), Decimal('43.6613289')],
'idx': 35},
{'name': 'McLennan Physical Laboratories',
'center': [Decimal('-79.3985019'), Decimal('43.6610126')],
'idx': 36},
{'name': 'McLennan Physical Laboratories',
'center': [Decimal('-79.3985063'), Decimal('43.6604892')],
'idx': 37},
{'name': 'Cody Hall',
'center': [Decimal('-79.3975700'), Decimal('43.6606429')],
'idx': 38},
{'name': 'South Borden Building',
'center': [Decimal('-79.3997906'), Decimal('43.6600989')],
'idx': 39},
{'name': 'Odette Hall',
'center': [Decimal('-79.3886433'), Decimal('43.6663535')],
'idx': 40},
{'name': 'Cardinal Flahiff Building',
'center': [Decimal('-79.3885826'), Decimal('43.6650353')],
'idx': 41},
{'name': 'Maritain House',
'center': [Decimal('-79.3899690'), Decimal('43.6656445')],
'idx': 42},
{'name': '2',
'center': [Decimal('-79.3898803'), Decimal('43.6654428')],
'idx': 43},
{'name': 'n/a',
'center': [Decimal('-79.3893077'), Decimal('43.6655234')],
'idx': 44},
{'name': 'Phelan House',
'center': [Decimal('-79.3893834'), Decimal('43.6658011')],
'idx': 45},
{'name': 'Sorbara Hall Student Residence',
'center': [Decimal('-79.3888806'), Decimal('43.6657524')],
'idx': 46},
{'name': 'Windle House',
'center': [Decimal('-79.3894576'), Decimal('43.6660491')],
'idx': 47},
{'name': 'Brennan Hall',
'center': [Decimal('-79.3897654'), Decimal('43.6663937')],
'idx': 48},
{'name': 'Burwash Dining Hall',
'center': [Decimal('-79.3917361'), Decimal('43.6674639')],
'idx': 49},
{'name': 'Physical Geography Building',
'center': [Decimal('-79.3965267'), Decimal('43.6603861')],
'idx': 50},
{'name': 'McLennan Physical Laboratories',
'center': [Decimal('-79.3981462'), Decimal('43.6605703')],
'idx': 51},
{'name': 'D. L. Pratt Building',
'center': [Decimal('-79.3948157'), Decimal('43.6596139')],
'idx': 52},
{'name': 'Central Steam Plant',
'center': [Decimal('-79.3978616'), Decimal('43.6599806')],
'idx': 53},
{'name': 'n/a',
'center': [Decimal('-79.3972158'), Decimal('43.6600916')],
'idx': 54},
{'name': 'Munk School of Global Affairs',
'center': [Decimal('-79.3985410'), Decimal('43.6674676')],
'idx': 55},
{'name': 'n/a',
'center': [Decimal('-79.3992100'), Decimal('43.6642407')],
'idx': 56},
{'name': 'n/a',
'center': [Decimal('-79.3994414'), Decimal('43.6647887')],
'idx': 57},
{'name': 'Bancroft Hall',
'center': [Decimal('-79.3998739'), Decimal('43.6609086')],
'idx': 58},
{'name': 'Faculty Club',
'center': [Decimal('-79.4005248'), Decimal('43.6611294')],
'idx': 59},
{'name': 'North Borden Building',
'center': [Decimal('-79.4001115'), Decimal('43.6604056')],
'idx': 60},
{'name': 'Koffler House',
'center': [Decimal('-79.4006308'), Decimal('43.6605786')],
'idx': 61},
{'name': 'Lash Miller Laboratories',
'center': [Decimal('-79.3979944'), Decimal('43.6618573')],
'idx': 62},
{'name': 'Anthropology Building',
'center': [Decimal('-79.3984688'), Decimal('43.6598666')],
'idx': 63},
{'name': 'Newman Centre',
'center': [Decimal('-79.3981613'), Decimal('43.6644228')],
'idx': 64},
{'name': 'Rotman School of Management',
'center': [Decimal('-79.3981827'), Decimal('43.6648252')],
'idx': 65},
{'name': 'Rotman School of Management and Rotman Commerce',
'center': [Decimal('-79.3992073'), Decimal('43.6669050')],
'idx': 66},
{'name': 'Max Gluskin House',
'center': [Decimal('-79.3997863'), Decimal('43.6660720')],
'idx': 67},
{'name': 'School of Continuing Studies',
'center': [Decimal('-79.3999688'), Decimal('43.6667118')],
'idx': 68},
{'name': '162 St. George Street',
'center': [Decimal('-79.4000373'), Decimal('43.6670826')],
'idx': 69},
{'name': 'Innis College',
'center': [Decimal('-79.3995930'), Decimal('43.6656204')],
'idx': 70},
{'name': 'Centre for Industrial Relations and Human Resources',
'center': [Decimal('-79.3990904'), Decimal('43.6666860')],
'idx': 71},
{'name': 'School of Graduate Studies - Office of the Dean',
'center': [Decimal('-79.3971708'), Decimal('43.6620125')],
'idx': 72},
{'name': 'Macdonald-Mullard House',
'center': [Decimal('-79.3970259'), Decimal('43.6618029')],
'idx': 73},
{'name': 'University College Union',
'center': [Decimal('-79.3975750'), Decimal('43.6633987')],
'idx': 74},
{'name': 'n/a',
'center': [Decimal('-79.3878370'), Decimal('43.6608131')],
'idx': 75},
{'name': 'Department of Obstetrics and Gynaecology',
'center': [Decimal('-79.3880876'), Decimal('43.6606226')],
'idx': 76},
{'name': 'Banting Institute',
'center': [Decimal('-79.3886232'), Decimal('43.6605821')],
'idx': 77},
{'name': 'Gerald Larkin Building',
'center': [Decimal('-79.3969449'), Decimal('43.6656724')],
'idx': 78},
{'name': 'Fields Institute for Research in Math Science',
'center': [Decimal('-79.3975564'), Decimal('43.6588127')],
'idx': 79},
{'name': 'Engineering Annex',
'center': [Decimal('-79.3954327'), Decimal('43.6596061')],
'idx': 80},
{'name': 'Haultain Building',
'center': [Decimal('-79.3936379'), Decimal('43.6599224')],
'idx': 81},
{'name': 'Tanz Neuroscience Building',
'center': [Decimal('-79.3918974'), Decimal('43.6603578')],
'idx': 82},
{'name': 'McMurrich Building',
'center': [Decimal('-79.3929260'), Decimal('43.6612699')],
'idx': 83},
{'name': 'Medical Sciences Building',
'center': [Decimal('-79.3933729'), Decimal('43.6607748')],
'idx': 84},
{'name': 'Centre of Criminology, School of Public Policy & Governance',
'center': [Decimal('-79.3929617'), Decimal('43.6619386')],
'idx': 85},
{'name': 'Early Learning Centre',
'center': [Decimal('-79.4011732'), Decimal('43.6639309')],
'idx': 86},
{'name': 'Pontifical Institute of Medieval Studies',
'center': [Decimal('-79.3909407'), Decimal('43.6656444')],
'idx': 87},
{'name': 'Teefy Hall',
'center': [Decimal('-79.3908241'), Decimal('43.6653867')],
'idx': 88},
{'name': 'Elmsley Hall',
'center': [Decimal('-79.3902908'), Decimal('43.6666687')],
'idx': 89},
{'name': 'Old steam plant',
'center': [Decimal('-79.3902904'), Decimal('43.6661749')],
'idx': 90},
{'name': 'Toronto School of Theology',
'center': [Decimal('-79.3906171'), Decimal('43.6647518')],
'idx': 91},
{'name': 'Multicultural History Society of Ontario',
'center': [Decimal('-79.3905489'), Decimal('43.6645719')],
'idx': 92},
{'name': 'Jesuits in English Canada',
'center': [Decimal('-79.3904015'), Decimal('43.6642662')],
'idx': 93},
{'name': 'Goldring Student Centre',
'center': [Decimal('-79.3924051'), Decimal('43.6677618')],
'idx': 94},
{'name': 'Annesley Hall',
'center': [Decimal('-79.3929754'), Decimal('43.6678101')],
'idx': 95},
{'name': 'Rowell Jackman Hall',
'center': [Decimal('-79.3908313'), Decimal('43.6674204')],
'idx': 96},
{'name': 'Loretto College',
'center': [Decimal('-79.3900057'), Decimal('43.6673727')],
'idx': 97},
{'name': 'George Ignatieff Theatre',
'center': [Decimal('-79.3971179'), Decimal('43.6658417')],
'idx': 98},
{'name': 'Arthur M. Kruger Hall (Woodsworth College)',
'center': [Decimal('-79.3987948'), Decimal('43.6666696')],
'idx': 99},
{'name': 'Ernescliff College',
'center': [Decimal('-79.3999649'), Decimal('43.6664969')],
'idx': 100},
{'name': 'Crux Discount Theological Books',
'center': [Decimal('-79.3952518'), Decimal('43.6642008')],
'idx': 101},
{'name': 'former Canadian School of Missions',
'center': [Decimal('-79.3984356'), Decimal('43.6649304')],
'idx': 102},
{'name': 'Law House',
'center': [Decimal('-79.3898938'), Decimal('43.6678167')],
'idx': 103},
{'name': 'Stephenson House',
'center': [Decimal('-79.3898109'), Decimal('43.6678347')],
'idx': 104},
{'name': 'Graduate Students Union',
'center': [Decimal('-79.4003077'), Decimal('43.6608112')],
'idx': 105},
{'name': 'Regis College',
'center': [Decimal('-79.3902796'), Decimal('43.6640045')],
'idx': 106},
{'name': 'Bahen Centre for Information Technology',
'center': [Decimal('-79.3974539'), Decimal('43.6597085')],
'idx': 107},
{'name': 'Cumberland House',
'center': [Decimal('-79.3959338'), Decimal('43.6594572')],
'idx': 108},
{'name': 'Victoria College',
'center': [Decimal('-79.3919559'), Decimal('43.6669263')],
'idx': 109},
{'name': 'Emmanuel College',
'center': [Decimal('-79.3926504'), Decimal('43.6667142')],
'idx': 110},
{'name': 'Goldring Centre',
'center': [Decimal('-79.3983851'), Decimal('43.6669768')],
'idx': 111},
{'name': 'Lash Miller Laboratories',
'center': [Decimal('-79.3984263'), Decimal('43.6615978')],
'idx': 112},
{'name': 'Convocation Hall',
'center': [Decimal('-79.3954478'), Decimal('43.6607760')],
'idx': 113},
{'name': 'Rosebrugh Building',
'center': [Decimal('-79.3932695'), Decimal('43.6600629')],
'idx': 114},
{'name': 'Mechanical Engineering Building',
'center': [Decimal('-79.3938368'), Decimal('43.6600562')],
'idx': 115},
{'name': 'n/a',
'center': [Decimal('-79.3975142'), Decimal('43.6647232')],
'idx': 116},
{'name': 'Myhal Centre',
'center': [Decimal('-79.3965625'), Decimal('43.6607288')],
'idx': 117},
{'name': 'n/a',
'center': [Decimal('-79.3987786'), Decimal('43.6673873')],
'idx': 118},
{'name': 'Robarts Common',
'center': [Decimal('-79.4000387'), Decimal('43.6642971')],
'idx': 119},
{'name': 'Medical Sciences Building',
'center': [Decimal('-79.3934363'), Decimal('43.6613361')],
'idx': 120},
{'name': 'Gilson House',
'center': [Decimal('-79.3899869'), Decimal('43.6657323')],
'idx': 121}]}