# [Python]
import duckdb, json
import pandas as pd
import geopandas as gpd
from shapely import wkb
xmin, ymin, xmax, ymax = -123.45, 44.45, -123.15, 44.65
RELEASE = "2026-07-22.0"
WATER_PATH = f"s3://overturemaps-us-west-2/release/{RELEASE}/theme=base/type=water/*"
con = duckdb.connect()
con.execute("""
INSTALL spatial; LOAD spatial;
INSTALL httpfs; LOAD httpfs;
SET s3_region = 'us-west-2';
""")
# ββ Step 1: DESCRIBE β see what columns exist ββββββββββββββββββββββββββββββββ
schema = con.execute(f"DESCRIBE SELECT * FROM read_parquet('{WATER_PATH}') LIMIT 0").df()
print("Available columns:")
print(schema[["column_name", "column_type"]].to_string(index=False))
print()
# ββ Step 2: query β bbox-pushdown filter, WKB bytes for GeoPandas ββββββββββββ
def overture_water(subtypes):
subtype_list = ", ".join(f"'{s}'" for s in subtypes)
sql = f"""
SELECT id, names.primary AS name, subtype, class,
ST_AsWKB(geometry) AS geom_wkb
FROM read_parquet('{WATER_PATH}', hive_partitioning = 1)
WHERE bbox.xmin BETWEEN {xmin} AND {xmax}
AND bbox.ymin BETWEEN {ymin} AND {ymax}
AND subtype IN ({subtype_list})
"""
raw = con.execute(sql).df()
# DuckDB returns WKB as bytearray; shapely.wkb.loads wants bytes.
geom = raw["geom_wkb"].apply(bytes).apply(wkb.loads)
return gpd.GeoDataFrame(raw.drop(columns=["geom_wkb"]), geometry=geom, crs="EPSG:4326")
rivers = overture_water(["river", "stream", "canal"])
waterbodies = overture_water(["lake", "pond", "reservoir"])
print(f"Rows from DuckDB : {len(rivers)} streams/rivers/canals, {len(waterbodies)} waterbodies")
rivers.head()