geotiff: validate coord regularity in _coords_to_transform (#1720)#1726
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR prevents to_geotiff from silently writing an incorrect affine geotransform when x/y coordinates are non-uniformly spaced (GeoTIFF can only represent affine transforms). It adds a regularity check in _coords_to_transform and introduces regression tests covering non-uniform coords and tolerance for small floating-point jitter.
Changes:
- Add spacing-regularity validation for
x/ycoords in_coords_to_transform, raisingValueErroron non-uniform or constant coords. - Add a dedicated regression test module for issue #1720 covering uniform spacing, non-uniform spacing, jitter tolerance, and constant coords.
- Fix an existing round-trip test to use truly uniform coordinates (switch to
np.linspace) to comply with the new validation.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
xrspatial/geotiff/__init__.py |
Adds coord regularity validation to avoid writing silently-wrong affine transforms. |
xrspatial/geotiff/tests/test_coord_regularity_1720.py |
New regression tests for uniform/non-uniform coords, jitter tolerance, and constant coords. |
xrspatial/geotiff/tests/test_edge_cases.py |
Updates PixelIsPoint round-trip test coords to be truly uniform under the new validation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+310
to
+313
| step = float(np.median(diffs)) | ||
| if step == 0: | ||
| raise ValueError( | ||
| f"{name} coords are constant; cannot infer pixel size" |
Comment on lines
+323
to
327
| _is_regular(x, "x") | ||
| _is_regular(y, "y") | ||
|
|
||
| pixel_width = float(x[1] - x[0]) | ||
| pixel_height = float(y[1] - y[0]) |
`_coords_to_transform` used `x[1] - x[0]` and `y[1] - y[0]` as the affine pixel sizes without checking that the rest of the spacing matched. GeoTIFF only supports an affine transform, so non-uniform coords cannot be expressed faithfully; the writer silently used the first-step spacing and produced a wrong transform. Validate `np.diff` against the median step with a 1e-6 relative tolerance and raise `ValueError` naming the offending dim and the worst residual. Median (not mean) keeps a single bad sample from shifting the reference step. Also fix `test_pixel_is_point_round_trip`, whose hand-typed coords had ~3.6e-3 relative deviation and were exactly the silent-wrong- transform case the new check now catches. Closes #1720
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_coords_to_transformusedx[1] - x[0]andy[1] - y[0]as the affine pixel sizes without checking that the rest of the spacing matched. GeoTIFF only supports an affine transform, so non-uniform coords can't be expressed faithfully. The writer silently used the first-step spacing and produced a wrong transform.Repro
Fix
Validate
np.diff(x)andnp.diff(y)against the median step with a 1e-6 relative tolerance in_coords_to_transform. RaiseValueErrornaming the offending dim and the worst residual. Median (not mean) keeps a single bad sample from shifting the reference step.Tolerance rationale
1e-6 relative is forgiving for float artifacts in otherwise-uniform coords (e.g.
np.linspaceround-trip jitter is well below 1e-12) but strict enough to catch real non-uniform data. The tolerance is in the error message so the next maintainer can see why their array failed.Tests
New
xrspatial/geotiff/tests/test_coord_regularity_1720.py:ValueError, message names x.ValueError, message names y.step == 0branch).Also fixed
test_pixel_is_point_round_trip, whose hand-typed coords had ~3.6e-3 relative deviation between steps. That is exactly the silent-wrong-transform case the new check catches. Switched tonp.linspace.Closes #1720