Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@

#### Fixed

- `polygonize` now rejects non-finite values for `simplify_tolerance`
(`nan`, `+inf`, `-inf`) with a clear `ValueError`. Previously `nan`
silently disabled simplification (because `nan > 0` is False) and
`+inf` collapsed every polygon to empty output. Matches the existing
`atol` / `rtol` validation contract: finite and non-negative. (#2575)

- `reproject(..., bounds_policy="auto")` no longer crops valid edge data
on ordinary geographic-to-projected reprojections. The old blow-up
heuristic compared source span (e.g. degrees for EPSG:4326) against
Expand Down
11 changes: 8 additions & 3 deletions xrspatial/polygonize.py
Original file line number Diff line number Diff line change
Expand Up @@ -2280,10 +2280,15 @@ def polygonize(
raise ValueError(
f"Incorrect transform length of {len(transform)} instead of 6")

# Check simplification parameters.
if simplify_tolerance is not None and simplify_tolerance < 0:
# Check simplification parameters. Mirror the atol/rtol validation
# below: reject NaN and +/-inf along with negative values. NaN would
# silently disable simplification because ``nan > 0`` is False, and
# +inf would collapse every polygon to empty output -- neither is
# what a caller asking for simplification wants.
if simplify_tolerance is not None and (
not np.isfinite(simplify_tolerance) or simplify_tolerance < 0):
raise ValueError(
"simplify_tolerance must be non-negative, "
"simplify_tolerance must be a non-negative finite number, "
f"got {simplify_tolerance}")
if simplify_method not in ("douglas-peucker", "visvalingam-whyatt"):
raise ValueError(
Expand Down
28 changes: 28 additions & 0 deletions xrspatial/tests/test_polygonize.py
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,34 @@ def test_negative_tolerance_raises(self):
with pytest.raises(ValueError, match="simplify_tolerance"):
polygonize(data, simplify_tolerance=-1.0)

@pytest.mark.parametrize("bad", [
float("nan"), float("inf"), float("-inf")])
def test_non_finite_tolerance_raises(self, bad):
"""nan/inf/-inf for simplify_tolerance must raise ValueError.

Regression for #2575: ``nan`` silently disabled simplification
(because ``nan > 0`` is False) and ``inf`` collapsed every
polygon to empty output. Mirror the atol/rtol validation
contract: require finite + non-negative.
"""
raster = np.array([[1, 1], [1, 1]], dtype=np.int64)
data = xr.DataArray(raster)
with pytest.raises(ValueError, match="simplify_tolerance"):
polygonize(data, simplify_tolerance=bad)

def test_zero_and_small_positive_tolerance_still_work(self):
"""0.0 and small positive tolerances must still be accepted.

Regression for #2575: guard against an over-eager fix that
bans non-positive values along with non-finite ones.
"""
raster = np.array([[1, 1, 2, 2],
[1, 1, 2, 2]], dtype=np.int64)
data = xr.DataArray(raster)
# Both calls should succeed without raising.
polygonize(data, simplify_tolerance=0.0)
polygonize(data, simplify_tolerance=1e-9)

def test_invalid_method_raises(self):
"""Unknown method should raise ValueError."""
raster = np.array([[1, 1], [1, 1]], dtype=np.int64)
Expand Down
Loading