OSMnx: custom Overpass server and node elevations
OSMnx downloads street networks and features from an Overpass server, overpass-api.de by default. One setting switches the server, and node elevations and edge grades work without a Google API key.
ox.settings.overpass_url to the base URL of the server, without /interpreter. On overpass.ch every other setting can keep its default:
import osmnx as ox
ox.settings.overpass_url = "https://api.overpass.ch/v1/YOUR_API_KEY"
On a server whose /status page OSMnx cannot read, also set ox.settings.overpass_rate_limit = False; see why.
Use another Overpass server
import os
import osmnx as ox
KEY = os.environ["OVERPASS_CH_KEY"] # keep the key out of your code
ox.settings.overpass_url = f"https://api.overpass.ch/v1/{KEY}"
G = ox.graph_from_place("Zermatt, Switzerland", network_type="walk")
water = ox.features_from_place("Zermatt, Switzerland", tags={"amenity": "drinking_water"})
- No
/interpreter: OSMnx appends it tooverpass_urlitself. - Place names such as “Zermatt, Switzerland” are looked up with Nominatim, not Overpass, so they are not affected.
- Big areas are split into several Overpass requests (
max_query_area_size). They run one after another, which suits per-key limits.
We tested this with OSMnx 2.1.1: the walking network of Zermatt (1,882 nodes) arrives in about 7 seconds.
What overpass_rate_limit does
With overpass_rate_limit on (the default), OSMnx reads the /status page of the server before every request, to find out when the next query slot becomes free. It expects the plain-text format of overpass-api.de.
- On overpass.ch,
/v1/YOUR_API_KEY/statusanswers in that format with the slots of your key: one for each query your plan can run at the same time. When you have used up the per-minute rate, it shows when the next request is allowed, and OSMnx waits until then instead of getting a429. Reading the status does not count towards the per-minute rate. With the default settings, three feature queries in Zermatt took 1.1 seconds in total. - On a server that answers differently or has no status page, OSMnx logs “Unable to parse” or “Unrecognized server status” and waits 60 seconds, its default, before every request. There, set
ox.settings.overpass_rate_limit = False.
Node elevations without a Google key
ox.elevation.add_node_elevations_google() works with any API that speaks the Google Elevation format; its URL is a setting. The overpass.ch elevation API does, with the same key:
ox.settings.elevation_url_template = (
"https://api.overpass.ch/v1/{key}/elevation?locations={locations}"
)
G = ox.elevation.add_node_elevations_google(G, api_key=KEY, batch_size=512)
G = ox.elevation.add_edge_grades(G) # grade and grade_abs on every edge
# the steepest street segment of at least 100 m
long_edges = [e for e in G.edges(data=True) if e[2]["length"] >= 100]
steepest = max(long_edges, key=lambda e: e[2]["grade_abs"])
print(steepest[2].get("name"), round(steepest[2]["grade_abs"] * 100), "%")
- For the 1,882 nodes in Zermatt this takes four requests of up to 512 locations, about a tenth of a second in total.
- Each node is one lookup of your monthly allowance: the free plan has 1 million a month, the Elevation plan 50 million for CHF 5 a month.
batch_sizecan go up to 1,000 on the free plan. 512 is a safe default and keeps the URLs short.- Heights come from the Copernicus 90 m elevation model. That suits grades over street segments and longer paths. On very short edges, a few metres of difference between grid cells produce large grades: in Zermatt, a 13 m edge comes out at 102%. Filter by
length, as above, before you look for the steepest street.
OSMnx also has add_node_elevations_raster() for local GeoTIFF files. That avoids any API, but you have to find, download and merge the tiles for your area first.
Other useful settings
ox.settings.requests_timeout(default 180 s) also sets the[timeout:…]of the queries. On overpass.ch a value above the plan maximum is lowered to it.ox.settings.use_cache = True(the default) stores answers in./cache. Repeated runs then cost no requests.- Getting errors anyway? See Overpass errors explained.