OpenStreetMap Waterways
Rivers, streams and canals mapped by OpenStreetMap contributors. The most detailed open river lines, updated continuously.
Waterways tagged river, stream and canal, often traced from aerial imagery at a few metres. Detail is high in Europe and much of Asia and uneven elsewhere; lines are not guaranteed to be connected or oriented downstream, so check the network before routing. Keep Overpass requests to small areas; use a Geofabrik country extract (its shapefile has a waterways layer) for large ones.
- Source
- OpenStreetMap contributors
- Resolution
- Lines (mapped at local detail)
- Data type
- Lines
- Time span
- Continuously updated
- Temporal
- Live
- Access type
- API (external) · Overpass for small areas (send a user agent), Geofabrik extracts for countries
- Formats
- JSON (Overpass), Shapefile and PBF (Geofabrik extracts)
- Coverage
- Global (completeness varies by country) (-180, -90, 180, 90)
- Licence
- Open Database License (ODbL)
- Provider page
- wiki.openstreetmap.org/wiki/Key:waterway
Access
apiRivers, streams and canals in the box, in Overpass Turbo (map view, export to GeoJSON or KML)
https://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3Bway%5B%22waterway%22~%22%5E%28river%7Cstream%7Ccanal%29%24%22%5D%28{south}%2C{west}%2C{north}%2C{east}%29%3Bout%20geom%3B&R
linkCountry and region extracts (Geofabrik, shapefile layer gis_osm_waterways)
# Overpass wants a user agent that identifies you; keep the box small
curl -A "your-project (you@example.org)" -G "https://overpass-api.de/api/interpreter" \
--data-urlencode 'data=[out:json][timeout:90];way["waterway"~"^(river|stream|canal)$"](-20,-75,5,-50);out geom;' \
-o waterways.json
import requests
query = """[out:json][timeout:90];
way["waterway"~"^(river|stream|canal)$"](-20,-75,5,-50);
out geom;"""
r = requests.post("https://overpass-api.de/api/interpreter", data={"data": query},
headers={"User-Agent": "your-project (you@example.org)"})
ways = r.json()["elements"]
lines = [[(p["lon"], p["lat"]) for p in w["geometry"]] for w in ways]
print(len(lines), "waterways")
const query = `[out:json][timeout:90];
way["waterway"~"^(river|stream|canal)$"](-20,-75,5,-50);
out geom;`;
const res = await fetch("https://overpass-api.de/api/interpreter", {
method: "POST",
body: new URLSearchParams({ data: query }),
});
const { elements } = await res.json();
console.log(elements.length, "waterways");
Also available as JSON: links · manifest · dataset record