Skip to content

Commit 7e0bc45

Browse files
dcherianclaude
andcommitted
Allow rusterize-specific merge algorithms
- rasterio and exactextract use "replace" and "add" - rusterize additionally accepts its native algorithms: "first", "min", "max", "count", "any" - "replace" and "add" are translated to "last" and "sum" for rusterize - rusterize native names can also be used directly with engine="rusterize" Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent edde5d5 commit 7e0bc45

2 files changed

Lines changed: 24 additions & 15 deletions

File tree

src/rasterix/rasterize/core.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,22 +95,35 @@ def _get_mask_funcs(engine: Engine):
9595

9696

9797
def _normalize_merge_alg(merge_alg: str, engine: Engine) -> Any:
98-
"""Normalize merge_alg string to engine-specific value."""
99-
valid_values = ("replace", "add")
100-
if merge_alg not in valid_values:
101-
raise ValueError(f"Invalid merge_alg {merge_alg!r}. Must be one of: {list(valid_values)}")
98+
"""Normalize merge_alg string to engine-specific value.
10299
100+
rasterio and exactextract use "replace" and "add".
101+
rusterize uses "last" and "sum" (plus "first", "min", "max", "count", "any").
102+
We translate "replace" -> "last" and "add" -> "sum" for rusterize.
103+
"""
103104
if engine == "rasterio":
104105
from rasterio.features import MergeAlg
105106

106107
mapping = {
107108
"replace": MergeAlg.replace,
108109
"add": MergeAlg.add,
109110
}
111+
if merge_alg not in mapping:
112+
raise ValueError(
113+
f"Invalid merge_alg {merge_alg!r} for rasterio. Must be one of: {list(mapping.keys())}"
114+
)
110115
return mapping[merge_alg]
111-
else:
112-
# rusterize and exactextract handle the translation internally
116+
elif engine == "exactextract":
117+
valid_values = ("replace", "add")
118+
if merge_alg not in valid_values:
119+
raise ValueError(
120+
f"Invalid merge_alg {merge_alg!r} for exactextract. Must be one of: {list(valid_values)}"
121+
)
113122
return merge_alg
123+
else:
124+
# rusterize: translate common names, pass through native names
125+
translation = {"replace": "last", "add": "sum"}
126+
return translation.get(merge_alg, merge_alg)
114127

115128

116129
def replace_values(array: np.ndarray, to, *, from_=0) -> np.ndarray:
@@ -157,10 +170,11 @@ def rasterize(
157170
If True, all pixels touched by geometries will be burned in.
158171
If False, only pixels whose center is within the geometry are burned.
159172
Note: Not supported by rusterize or exactextract engines.
160-
merge_alg : {"replace", "add"}
173+
merge_alg : str
161174
Merge algorithm when geometries overlap.
162175
- "replace": later geometries overwrite earlier ones
163176
- "add": values are summed where geometries overlap
177+
The rusterize engine also accepts: "first", "min", "max", "count", "any".
164178
geoms_rechunk_size : int or None
165179
Size to rechunk the geometry array to *after* conversion from dataframe.
166180
clip : bool

src/rasterix/rasterize/rusterize.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def rasterize_geometries(
4444
affine: Affine,
4545
offset: int,
4646
all_touched: bool = False,
47-
merge_alg: str = "replace",
47+
merge_alg: str = "last",
4848
fill: Any = 0,
4949
**kwargs,
5050
) -> np.ndarray:
@@ -67,7 +67,7 @@ def rasterize_geometries(
6767
If True, all pixels touched by geometries will be burned in.
6868
Note: rusterize may not support this parameter directly.
6969
merge_alg : str
70-
Merge algorithm: "replace" or "add".
70+
Merge algorithm. Supported values: "last", "sum", "first", "min", "max", "count", "any".
7171
fill : Any
7272
Fill value for pixels not covered by any geometry.
7373
**kwargs
@@ -94,18 +94,13 @@ def rasterize_geometries(
9494

9595
extent, (xres, yres) = _affine_to_extent_and_res(affine, shape)
9696

97-
# Translate merge_alg to rusterize's native names
98-
rusterize_merge_alg = {"replace": "last", "add": "sum"}.get(merge_alg)
99-
if rusterize_merge_alg is None:
100-
raise ValueError(f"Unsupported merge_alg: {merge_alg}. Must be 'replace' or 'add'.")
101-
10297
result = rusterize(
10398
gdf,
10499
res=(xres, yres),
105100
extent=extent,
106101
out_shape=shape,
107102
field="value",
108-
fun=rusterize_merge_alg,
103+
fun=merge_alg,
109104
background=fill,
110105
encoding="numpy",
111106
dtype=str(dtype),

0 commit comments

Comments
 (0)