-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstreetTalk.py
72 lines (61 loc) · 2.88 KB
/
streetTalk.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import osmnx as ox
import geopandas as gpd
from shapely.geometry import Point
def streetTalk(point,cityname,networkType='drive'):
'''
This function takes a lat/lng pair and a city name as inputs, and returns
a conversational string stating nearest street as well as enclosing streets
point: shapely.geometry.Point
cityname: string
networkType: string
'''
if cityname not in globals():
try:
#If the map of city is downloaded, use them directly
globals()[cityname] = gpd.read_file('data/'+cityname+'/edges/edges.shp')
#print('the map of city is downloaded')
except:
#If the map is not downloaded, download the map of city via OpenStreetMap
G = ox.graph_from_place(cityname + ', USA', network_type=networkType)
#Save the map in shapefile locally
ox.save_load.save_graph_shapefile(G, filename=cityname, folder=None, encoding='utf-8')
#print('Map of ' + cityname + 'is saved in shapefile locally!')
#citymap_node = gpd.read_file('data/'+cityname+'/nodes/nodes.shp')
globals()[cityname] = gpd.read_file('data/'+cityname+'/edges/edges.shp')
citymap_edge = globals()[cityname]
#print('map loaded')
point = Point(lon,lat)
nearest_name, nearest_id, from_id, to_id = nearestSegment(point,citymap_edge)
enclosing_from = intersectingStreets(from_id,citymap_edge)
enclosing_to = intersectingStreets(to_id,citymap_edge)
try:
street_from = enclosing_from[1] if enclosing_from[0] == nearest_name else enclosing_from[0]
street_to = enclosing_to[1] if enclosing_to[0] == nearest_name else enclosing_to[0]
conversational = "{} between {} and {}".format(nearest_name,street_from,street_to)
except:
conversational = nearest_name
return conversational
def nearestSegment(point,city):
'''
This function takes a lat/lon point and a geodataframe of city shapefile
as inputs and returns a name and unique id for nearest street segment to
that point as well as unique ids for the segment's enclosing intersections
point: shapely.geometry.Point (lon/lat)
city: geodataframe of edges of segments in city
return: nearest_name, nearest_id, from_id, to_id
'''
idx = city.geometry.distance(point).sort_values().index[0]
nearest_name = city.loc[idx,'name']
nearest_id = city.loc[idx,'osmid']
from_id = city.loc[idx,'from']
to_id = city.loc[idx,'to']
return nearest_name, nearest_id, from_id, to_id
def intersectingStreets(node_id,city):
'''
This function takes a lat/lng pair as an input, and returns the names of
intersecting streets
node_id: node id, string
city: geodataframe of edges of segments in city
return: street_name, street_name_1
'''
return city[(city['from'] == node_id) | (city['to'] == node_id)].name.unique()