Skip to content

Commit d44c2e8

Browse files
committed
Process KD/C masks and improve overlap handling
kh: Rework kh processing to compute C and KD layers from NHDZ and Bergen sources. Added mask-based clipping of KD inputs and assembled KD formulas into summed parts before filling boundaries; write overlap and fill GeoJSONs for C layers. Adjusted Bergen constants and name mapping and changed several fill/overlap priorities (use 'last' and 'sum' where appropriate). params_helper_functions: Add _compute_pairwise_overlaps and clip_polygons_to_mask helpers, strengthen geometry buffering/validation, and extend fill_boundary_with_polygons to return (result, overlaps_gdf, fill_gdf), detect/report overlaps more robustly, and support an overlap_priority 'sum' mode that sums values in overlapping regions. Overall improves handling of overlapping geometries and mask-based clipping for kh generation.
1 parent c7cd9d4 commit d44c2e8

2 files changed

Lines changed: 327 additions & 72 deletions

File tree

src/nhflodata/data/mockup/bodemlagen_pwn_2024/v2.0.0/kh/kh.py

Lines changed: 133 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import logging
22

33
import geopandas as gpd
4-
import matplotlib.pyplot as plt
5-
import numpy as np
6-
from params_helper_functions import fill_boundary_with_polygons
7-
from shapely import MultiPolygon, Polygon, make_valid
4+
import pandas as pd
5+
from params_helper_functions import clip_polygons_to_mask, fill_boundary_with_polygons
86

97
from nhflodata.get_paths import get_abs_data_path
108

@@ -16,17 +14,34 @@
1614
data_path_nhdz = get_abs_data_path("bodemlagen_pwn_nhdz", "1.0.0")
1715

1816
layer_names = ["W11", "S11", "W12", "S12", "W13", "S13", "W21", "S21", "W22", "S22", "W31", "S31", "W32", "S32"]
17+
c_nhdz_fill_values = { # From bodemlagen_pwn_nhdz/v1.0.0/Ontleding_model_v2.xlsx
18+
"S11": 1.0,
19+
"S12": 10.0,
20+
"S13": 10.0,
21+
"S21": 10.0,
22+
"S22": 10.0,
23+
"S31": 10.0,
24+
"S32": 10.0,
25+
}
26+
1927
kh_bergen_fill_values = {
20-
"W11": 8.0,
21-
"S11": np.nan,
28+
"W11": 7.0, # Triwaco Excel uses 7.0, but prior nhflo implementations used 8.0.
2229
"W12": 7.0,
23-
"S12": np.nan,
2430
"W13": 12.0,
25-
"S13": np.nan,
2631
"W21": 15.0,
27-
"S21": np.nan,
2832
}
29-
33+
c_bergen_fill_values = {
34+
"S11": 1.0,
35+
"S12": 100.0,
36+
"S13": 100.0,
37+
"S21": 1.0,
38+
}
39+
bergen_name_mapping = {
40+
"11": "1A",
41+
"12": "1B",
42+
"13": "1C",
43+
"21": "2",
44+
}
3045

3146
# Get boundaries that we need to fill up with the data from Bergen and NHDZ
3247
gdf_bergen = gpd.read_file(data_path / "boundaries" / "triwaco_model_bergen.geojson")
@@ -38,31 +53,127 @@
3853
if name.startswith("W"):
3954
fp = data_path_nhdz / "Bodemparams" / "Kwaarden_aquifers" / f"K{name}.shp"
4055
k = gpd.read_file(fp).set_crs("EPSG:28992")
41-
kh_nhdz[name], _ = fill_boundary_with_polygons(
56+
kh_nhdz[name], _, _ = fill_boundary_with_polygons(
4257
boundary_gdf=gdf_nhdz,
4358
source_gdf=k,
4459
value_col="VALUE",
45-
fill_value=kh_bergen_fill_values[name], # Not used as fill method is 'mean'
60+
# fill_value=kh_bergen_fill_values[name], # Not used as fill method is 'mean'
4661
fill_method="mean",
47-
overlap_priority="smallest",
62+
overlap_priority="last",
4863
override_gdf=None,
4964
)
5065

51-
# Bergen
52-
kh_bergen = {}
66+
kd_nhdz = {} # horizontal transmissivity of the aquitards from nhdz
67+
folder = data_path_nhdz / "Bodemparams" / "KDwaarden_aquitards"
68+
s12kd = gpd.read_file(folder / "s12kd.shp").set_crs("EPSG:28992")
69+
s13kd = gpd.read_file(folder / "s13kd.shp").set_crs("EPSG:28992")
70+
s21kd = gpd.read_file(folder / "s21kd.shp").set_crs("EPSG:28992")
71+
s22kd = gpd.read_file(folder / "s22kd.shp").set_crs("EPSG:28992")
72+
folder = data_path_bergen / "Bodemparams" / "Masker_kdwaarden_aquitards"
73+
ms12kd = gpd.read_file(folder / "masker_aquitard12_kd.shp").set_crs("EPSG:28992")
74+
ms13kd = gpd.read_file(folder / "masker_aquitard13_kd.shp").set_crs("EPSG:28992")
75+
ms21kd = gpd.read_file(folder / "masker_aquitard21_kd.shp").set_crs("EPSG:28992")
76+
ms22kd = gpd.read_file(folder / "masker_aquitard22_kd.shp").set_crs("EPSG:28992")
77+
78+
# Each formula is a list of (source_gdf, mask_gdf, mask_value, coefficient) terms
79+
# kd12s = s12kd*(ms12kd==1) + 0.5*s12kd*(ms12kd==2) + 3*s12kd*(ms12kd==3)
80+
# kd13s = (s13kd*(ms13kd==1) + 0.5*s12kd*(ms12kd==2)) * 1.04
81+
# kd21s = (s21kd*(ms21kd==1) + s13kd*(ms13kd==2)) * 0.6
82+
# kd22s = s22kd*(ms22kd==1) + s21kd*(ms21kd==2)
83+
# kd31s = s22kd*(ms22kd==2)
84+
kd_formulas = {
85+
"S12": [
86+
(s12kd, ms12kd, 1, 1.0),
87+
(s12kd, ms12kd, 2, 0.5),
88+
(s12kd, ms12kd, 3, 3.0),
89+
],
90+
"S13": [
91+
(s13kd, ms13kd, 1, 1.04),
92+
(s12kd, ms12kd, 2, 0.5 * 1.04),
93+
],
94+
"S21": [
95+
(s21kd, ms21kd, 1, 0.6),
96+
(s13kd, ms13kd, 2, 0.6),
97+
],
98+
"S22": [
99+
(s22kd, ms22kd, 1, 1.0),
100+
(s21kd, ms21kd, 2, 1.0),
101+
],
102+
"S31": [
103+
(s22kd, ms22kd, 2, 1.0),
104+
],
105+
}
106+
107+
for name, terms in kd_formulas.items():
108+
parts = [clip_polygons_to_mask(src, mask, mask_value=val, coefficient=coeff) for src, mask, val, coeff in terms]
109+
source = gpd.GeoDataFrame(pd.concat(parts, ignore_index=True), crs="EPSG:28992")
110+
kd_nhdz[name], _, _ = fill_boundary_with_polygons(
111+
boundary_gdf=gdf_nhdz,
112+
source_gdf=source,
113+
value_col="VALUE",
114+
fill_method="fill_value",
115+
fill_value=0.01, # From bodemlagen_pwn_nhdz/v1.0.0/Ontleding_model_v2.xlsx
116+
overlap_priority="sum",
117+
)
118+
119+
c_nhdz = {}
53120
for name in layer_names:
54-
if name.startswith("W"):
55-
kh_bergen[name], _ = fill_boundary_with_polygons(
56-
boundary_gdf=gdf_bergen,
57-
source_gdf=None, # Are constants for Bergen, so use fill value only
58-
value_col="VALUE", # Not used as source_gdf is None
59-
fill_value=kh_bergen_fill_values[name],
121+
if name.startswith("S"):
122+
fp = data_path_nhdz / "Bodemparams" / "Cwaarden_aquitards" / f"C{name}.shp"
123+
c = gpd.read_file(fp).set_crs("EPSG:28992")
124+
if name == "S22":
125+
c["VALUE"] *= 1.02 # From bodemlagen_pwn_nhdz/v1.0.0/Ontleding_model_v2.xlsx
126+
127+
c_nhdz[name], overlaps_gdf, fill_gdf = fill_boundary_with_polygons(
128+
boundary_gdf=gdf_nhdz,
129+
source_gdf=c,
130+
value_col="VALUE",
131+
fill_value=c_nhdz_fill_values[name],
60132
fill_method="fill_value",
61-
overlap_priority="smallest", # Not used as source_gdf is None
133+
overlap_priority="last",
62134
override_gdf=None,
63135
)
136+
overlaps_gdf.to_file(data_path / "kh" / f"C{name}_NHDZ_overlaps.geojson", driver="GeoJSON")
137+
fill_gdf.to_file(data_path / "kh" / f"C{name}_NHDZ_fill.geojson", driver="GeoJSON")
138+
139+
# Bergen
140+
kh_bergen = {}
141+
for name in bergen_name_mapping:
142+
kh_bergen[f"W{name}"], _, _ = fill_boundary_with_polygons(
143+
boundary_gdf=gdf_bergen,
144+
source_gdf=None, # Are constants for Bergen, so use fill value only
145+
value_col="VALUE", # Not used as source_gdf is None
146+
fill_value=kh_bergen_fill_values[f"W{name}"],
147+
fill_method="fill_value",
148+
overlap_priority="last", # Not used as source_gdf is None
149+
override_gdf=None,
150+
)
151+
152+
c_bergen = {}
153+
for name, bergen_name in bergen_name_mapping.items():
154+
fp = data_path_bergen / "Bodemparams" / f"C{bergen_name}.shp"
155+
c = gpd.read_file(fp).set_crs("EPSG:28992")
156+
c_bergen[f"S{name}"], overlaps_gdf, fill_gdf = fill_boundary_with_polygons(
157+
boundary_gdf=gdf_bergen,
158+
source_gdf=c,
159+
value_col="VALUE", # Not used as source_gdf is None
160+
fill_value=c_bergen_fill_values[f"S{name}"],
161+
fill_method="fill_value",
162+
overlap_priority="last", # Not used as source_gdf is None
163+
override_gdf=None,
164+
)
165+
overlaps_gdf.to_file(data_path / "kh" / f"C{bergen_name}_Bergen_overlaps.geojson", driver="GeoJSON")
166+
fill_gdf.to_file(data_path / "kh" / f"C{bergen_name}_Bergen_fill.geojson", driver="GeoJSON")
64167

65168
"""
169+
# NHDZ Bergen
170+
S21 S2
171+
S13 S1C
172+
S12 S1B
173+
S11 S1A
174+
175+
176+
66177
kh[0] = 8.0
67178
kh[1] = thickness[1] / clist[0] / f_anisotropy
68179
kh[2] = 7.0

0 commit comments

Comments
 (0)