-
Notifications
You must be signed in to change notification settings - Fork 6
/
osm.py
63 lines (56 loc) · 3.35 KB
/
osm.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
class OSM_extractor:
def __init__(self, minlon, minlat, maxlon, maxlat):
self.minlon, self.minlat, self.maxlon, self.maxlat = minlon, minlat, maxlon, maxlat
def download(self, tag_key='amenity', tag_value='school'):
"""
Get the json of coordinates (or the number of items) within a bbox for a specific osm tag.
https://taginfo.openstreetmap.org/
https://wiki.openstreetmap.org/wiki/Map_Features#Building
"""
from osmnx.core import overpass_request
from shapely.geometry import Point
import geopandas as gpd
import os
if os.path.exists("../Data/Geofiles/OSM/location_{}_{}_{}_{}_{}_{}.json".format(tag_key, tag_value, self.minlat, self.maxlat, self.minlon, self.maxlon)):
print('INFO: OSM data for {} = {} already downloaded'.format(tag_key, tag_value))
gdf = gpd.read_file("../Data/Geofiles/OSM/location_{}_{}_{}_{}_{}_{}.json".format(tag_key, tag_value, self.minlat, self.maxlat, self.minlon, self.maxlon))
return gdf
query_osm = ('[out:json][maxsize:2000000000];'
'('
'node["{tag_key}"="{tag_value}"]({minlat:.8f},{minlon:.8f},{maxlat:.8f},{maxlon:.8f});'
');(._;>;);out center;'
).format(minlat=self.minlat, maxlat=self.maxlat, minlon=self.minlon, maxlon=self.maxlon, tag_key=tag_key, tag_value=tag_value)
print('INFO: Downloading OSM data for {} = {}'.format(tag_key, tag_value))
# overpass_request is already saving json to a cache folder
response_json = overpass_request(data={'data': query_osm}, timeout=10000, error_pause_duration=None)
print('INFO: OSM data for {} = {} downloaded. N lines: '.format(tag_key, tag_value, len(response_json)))
points = []
for result in response_json['elements']:
if 'type' in result and result['type'] == 'node':
p = Point([(result['lon'], result['lat'])])
point = {'geometry': p}
points.append(point)
if 'type' in result and result['type'] == 'way':
p = Point([(result['center']['lon'], result['center']['lat'])])
point = {'geometry': p}
points.append(point)
gdf = gpd.GeoDataFrame(points)
gdf.crs = {'init': 'epsg:4326'}
gdf.to_file("../Data/Geofiles/OSM/location_{}_{}_{}_{}_{}_{}.json".format(tag_key, tag_value, self.minlat, self.maxlat, self.minlon, self.maxlon), driver='GeoJSON')
gdf.to_file("../Data/Geofiles/OSM/location_{}_{}_{}_{}_{}_{}.shp".format(tag_key, tag_value, self.minlat, self.maxlat, self.minlon, self.maxlon), driver='ESRI Shapefile')
return gdf
def distance_to_nearest(self, latitudes, longitudes, gdf):
""" Ditance between a point in a pandas dataframe and the nearest point in a geopandas geodataframe.
"""
from sklearn.neighbors import NearestNeighbors
import numpy as np
gdf_lats = gdf["geometry"].y
gfd_lons = gdf["geometry"].x
X = np.array([gdf_lats, gfd_lons]).T
nbrs = NearestNeighbors(n_neighbors=1, algorithm='kd_tree').fit(X)
features = []
for lat, lon in zip(latitudes, longitudes):
X = np.array([[lat, lon]])
a, _ = nbrs.kneighbors(X)
features.append(a[[0]][0][0])
return features