Open Street Map using OSMNX: how to retrieve bus routes? - openstreetmap

import osmnx as ox
ox.__version__ # '0.13.0'
I would like to show the bus routes from the Open Street Map for Hannover on a map using OSMNX by retrieving them as ".graph...". E.g.:
G = ox.graph_from_place('Hannover, Germany', retain_all=False, truncate_by_edge=True,
simplify=True, network_type=None, custom_filter='["route"~"bus"]')
# returns EmptyOverpassResponse: There are no data elements in the response JSON
But I guess this only works for OSM Nodes and Ways, not for Relations? (and public transport routes are stored as relations)?
Therefore I use this workaround:
tags = {'route' : 'bus'}
gdfox = ox.pois_from_place('Hannover, Germany', tags)
gdfox.shape # (4022, 988)
gdfox['element_type'].value_counts() # node 2412, way 1610
This works but it is not perfect as there are some gaps in the routes:
Please advice if there is a better way?

Related

how to download precipitation data for latitude-longitude coordinates from NOAA in R

I'm trying to download precipitation data for a list of latitude-longitude coordinates in R. I've came across this question which gets me most of the way there, but over half of the weather stations don't have precipitation data. I've pasted code below up to this point.
I'm now trying to figure out how to only get data from the closest station with precipitation data, or run a second function on the sites with missing data to get data from the second closest station. However, I haven't been able to figure out how to do this. Any suggestions or resources that might help?
`
library(rnoaa)
# load station data - takes some minutes
station_data <- ghcnd_stations() %>% filter(element == "PRCP")
# add id column for each location (necessary for next function)
sites_df$id <- 1:nrow(sites_df)
# retrieve all stations in radius (e.g. 20km) using lapply
stations <- lapply(1:nrow(sites_df),
function(i) meteo_nearby_stations(sites_df[i,],lat_colname = 'Lattitude',lon_colname = 'Longitude',radius = 20,station_data = station_data)[[1]])
# pull data for nearest stations - x$id[1] selects ID of closest station
stations_data <- lapply(stations,function(x) meteo_pull_monitors(x$id[1], date_min = "2022-05-01", date_max = "2022-05-31", var = c("prcp")))
stations_data`
# poor attempt its making me include- trying to rerun subset for second closest station. I know this isn't working but don't know how to get lapply to run for a subset of a list, or understand exactly how the function is running to code it another way
for (i in c(1,2,3,7,9,10,11,14,16,17,19,20)){
stations_data[[i]] <- lapply(stations,function(x) meteo_pull_monitors(x$id[2], date_min = "2022-05-01", date_max = "2022-05-31", var = c("prcp")))
}

nearest building with open street map

I have a csv of relevant points with latitude and longitude and trying to get the nearest
building data to each point and add a column to the csv (or panda) in python. Tried using Pyrosm and various libraries but can't seem to prune the data to get the nearest building and then add the data. Thanks
This is what I have
from pyrosm import OSM
from pyrosm import get_data
import geopandas as gpd
from sklearn.neighbors import BallTree
import numpy as np
import osmnx as ox
# get rid of weird error
import shapely
import warnings
from shapely.errors import ShapelyDeprecationWarning
import csv
def get_gig_data(csv_fname):
with open(csv_fname, "r", encoding="latin-1") as gig_records:
for gig_record in csv.reader(gig_records):
yield gig_record
def main():
warnings.filterwarnings("ignore", category=ShapelyDeprecationWarning)
chicago_osm = OSM(get_data("chicago"))
#get a Point of Interest GeoDataFrame
points_of_interest = chicago_osm.get_pois() #can use a custom filter if we want to filter the types, but I think no filter might be the best
# get buildings nodes and edges
nodes, edges = chicago_osm.get_network(nodes=True, network_type="walking")
buildings = chicago_osm.get_buildings()
b_cnt = len(buildings)
G = chicago_osm.to_graph(nodes, edges)
#nodes = get_igraph_nodes(G)
buildings['geometry'] = buildings.centroid
# poi_list = np.asarray([ point.coords for point in points_of_interest['geometry'] ]) #if point.geom_type == point])
#print(poi_list.shape)
#tree = BallTree( np.asarray([ point.coords for point in points_of_interest['geometry'] if point.geom_type == point]), metric="manhattan") #Note: the scipy implementation of manhattan/cityblock distance might be faster according to the internet bc it uses a C function
#Read in the gig work data - I think the best way to do this will probably be with the CSV.reader with open thing because it will go line by line and save a ton of memory
'''for i in points_of_interest:
print('Type: ', type(i) , ' ',i)'''
gig_fp = "data_sample.csv"
#gig_data = gpd.read_file(gig_fp)
iter_gig = iter(get_gig_data(gig_fp))
next(iter_gig)
ids=dict()
for building in buildings.iterrows():
#print(type(building[1][32]) , ' ', building[1][32])
#tup = tuple(float(x) for x in [trip[17][8:-1].split()])
ids[building[1][32]] = building
#make the tree that determines closest POI
#if we use the CSV reader this for loop will be done already
for trip in iter_gig:
# Using generator so this should be efficient memory wise.
tup = tuple([float(x) for x in trip[17][8:-1].split() ])
print(type(tup), ' ', tup)
src_ids,euclidean_distance=ox.distance.nearest_nodes(G,tup)
src_ids, euclidean_distance= ox.distance.nearest_nodes(G,tup)
# find nearest node
#THEN ADD THE PICKUP AND DROPOFF IDS TO THIS TUPLE AND ADD TO A NEW NP ARRAY
if __name__ == '__main__':
main()

Overpass API: query for counting amenity of specified type around set of lat lons

I'm trying to query data from the OSM Overpass API. Specifically I'm trying to determine the count of amenities of a given type around a point (using the 'around' syntax). When running this for many locations (lat, lons) I'm running into a TooManyRequests error.
I have tried to work around by setting sleep time pauses and playing with the timeout header and retry time, but I'm running into the same issue. I'm trying to find a way to adapt the query so that it just returns the count of amenities (of specified type) around each point, rather than the full json of nodes which is more data intensive. My current script is as follows;
# Running Overpass query for each point
results = {}
for n in range(0, 200):
name = df.loc[n]['city']
state = df.loc[n]['state_name']
rad = df.loc[n]['radius_m']
lat = df.loc[n]['lat']
lon = df.loc[n]['lng']
# Overpass query for amenities
start_time = time.time()
api = overpy.Overpass(max_retry_count=None, retry_timeout=2)
r = api.query(f"""
[out:json][timeout:180];
(node["amenity"="charging_station"](around:{rad}, {lat}, {lon});
);
out;
""")
print("query time for "+str(name)+", number "+str(n)+" = "+str(time.time() - start_time))
results[name] = len(r.nodes)
time.sleep(2)
Any help is much appreciated from other Overpass users!
Thanks
In general, you can run out count; to return a count from an overpass API query.
It's hard to say without knowing how your data is specifically structured, but you might have better luck using area to look at specific cities, or regions.
Here is an example that returns the count of all nodes tagged as charging station in Portland, Oregon:
/* charging stations in portland */
area[name="Oregon"]->.state;
area[name="Portland"]->.city;
(
node["amenity"="charging_station"](area.state)(area.city);
);
out count;

Query from OpenStreetMap

At the moment I'm using the Overpass API to query from OpenStreetMap using https://overpass-turbo.eu/ but when I use the following code, not all the schools in the area appear on the map (e.g. Holy Cross College doesn't appear).
area[name = "Council of the City of Ryde"];
node(area)[amenity = school];
out;
Anyone know why this might be the case?
Thanks for any help!
OpenStreetMap data consists of three basic elements: nodes, ways and relations. Your query searches only for nodes. Some schools will be mapped as ways and a few others as relations.
You have to change your query in order to search for all three elements:
area[name = "Council of the City of Ryde"];
(
node(area)[amenity = school];
way(area)[amenity = school];
relation(area)[amenity = school];
);
out;
Alternatively just use the keyword nwr to search for all three elements:
area[name = "Council of the City of Ryde"];
nwr(area)[amenity = school];
out;
If there are still missing schools then either they are mapped with a different tag or they are missing in OSM. In the second case feel free to add them yourself.

OSMnx: Creating Custom Queries with Alternative Infrastructures

I'm new to OSMnx and Overpass queries in general. I am trying to understand the correct way to write custom queries when working with non-street infrastructure types.
Specifically, I am trying to understand why this query works
import osmnx as ox
my_custom_filter = '["railway"~"disused"]'
G = ox.graph_from_point((51.5073509,-0.1277583),
distance = 10000,
distance_type = 'bbox',
infrastructure = 'way["railway]',
network_type = 'none',
custom_filter = my_custom_filter
)
But this one wields a bad request error:
import osmnx as ox
my_custom_filter = '["railway"~"disused"]'
G = ox.graph_from_point((51.5073509,-0.1277583),
distance = 10000,
distance_type = 'bbox',
infrastructure = 'way["railway~"rail"]',
network_type = 'none',
custom_filter = my_custom_filter
)
Notice the difference is simply that I specifying rail as the type of railway in the latter query.
See the OSM Railway Guide here.
If anyone can point me to any resources which would help me further understand how to construct custom filters - particularly custom filters with more than one filter, that would be excellent also. For example, what would be the correct syntax to add an additional customer filter.
You were just missing a " in your argument. This works:
import osmnx as ox
ox.config(log_console=True, use_cache=True)
point = (51.5073509,-0.1277583)
dist = 10000
dt = 'bbox'
cf = '["railway"~"disused"]'
G = ox.graph_from_point(point, dist=dist, dist_type=dt, custom_filter=cf)
But it produces an EmptyOverpassResponse error as there is nothing that matches your query in that search area. You will get a graph however if you change it to this for example:
cf = '["railway"!~"disused"]'
G = ox.graph_from_point(point, dist=dist, dist_type=dt, custom_filter=cf)