File size: 2,306 Bytes
a74054f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Spatially match each station to the catchment polygon that actually
contains it (point-in-polygon), rather than guessing at a shared ID
field across BD TOPO and Hub'Eau. This is the correct approach when
two datasets don't share a clean join key.
"""
import sys
sys.path.insert(0, ".")
from pathlib import Path
import pandas as pd
import geopandas as gpd

from src.data.loaders.bdtopo_hydro import BDTopoHydroLoader

loader = BDTopoHydroLoader(data_path=Path("datasets/bdtopo_hydro"))
catchments = loader.load_catchments()
catchments_metric = catchments.to_crs(epsg=2154)  # Lambert-93 for accurate area in meters
catchments["area_km2"] = catchments_metric.geometry.area / 1e6

stations = pd.read_csv("datasets/station_elevations.csv")
hubeau = pd.read_csv("datasets/catchment_area.csv").dropna(subset=["catchment_area_km2"])

stations_gdf = gpd.GeoDataFrame(
    stations,
    geometry=gpd.points_from_xy(stations["longitude"], stations["latitude"]),
    crs="EPSG:4326",
).to_crs(catchments.crs)

# Spatial join: which catchment polygon contains each station?
joined = gpd.sjoin(stations_gdf, catchments[["area_km2", "toponyme", "geometry"]],
                    how="left", predicate="within")

result = joined[["station_code", "toponyme", "area_km2"]].rename(
    columns={"area_km2": "bdtopo_area_km2", "toponyme": "bdtopo_catchment_name"}
)
result = result.merge(hubeau[["station_code", "catchment_area_km2"]], on="station_code", how="left")
result = result.rename(columns={"catchment_area_km2": "hubeau_area_km2"})
result["ratio"] = result["bdtopo_area_km2"] / result["hubeau_area_km2"]

print(result.to_string(index=False))
print()
matched = result.dropna(subset=["bdtopo_area_km2", "hubeau_area_km2"])
print(f"Stations with BOTH a containing BD TOPO polygon AND a Hub'Eau value: {len(matched)}")
if len(matched) > 0:
    print(f"Area ratio (BD TOPO / Hub'Eau) — mean: {matched['ratio'].mean():.2f}, "
          f"median: {matched['ratio'].median():.2f}")
    print("(A ratio near 1.0 across most stations would confirm both sources agree; "
          "large/inconsistent ratios would suggest the polygons represent something "
          "other than the gauge's own catchment -- e.g. a downstream aggregate, or "
          "no polygon actually contains that point due to bbox edge effects.)")