Skip to content

Commit

Permalink
Small fixes (#384)
Browse files Browse the repository at this point in the history
* Allow different distance units for Raster.shift() and improve description

* Add tests for Raster.shift()

* Linting

* Remove skip_equivalent which is now default
  • Loading branch information
rhugonnet authored Aug 9, 2023
1 parent 2f3a547 commit fac1de0
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
2 changes: 1 addition & 1 deletion geoutils/projtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ def reproject_shape(inshape: BaseGeometry, in_crs: CRS, out_crs: CRS) -> BaseGeo
:returns: Reprojected geometry
"""
reproj = pyproj.Transformer.from_crs(in_crs, out_crs, always_xy=True, skip_equivalent=True).transform
reproj = pyproj.Transformer.from_crs(in_crs, out_crs, always_xy=True).transform
return shapely.ops.transform(reproj, inshape)


Expand Down
19 changes: 16 additions & 3 deletions geoutils/raster/raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -2140,17 +2140,30 @@ def reproject(

return dst_r

def shift(self, xoff: float, yoff: float) -> None:
def shift(
self, xoff: float, yoff: float, distance_unit: Literal["georeferenced"] | Literal["pixel"] = "georeferenced"
) -> None:
"""
Shift the raster by a (x,y) offset.
The shifting only updates the geotransform (no resampling is performed).
:param xoff: Translation x offset.
:param yoff: Translation y offset.
:param distance_unit: Distance unit, either 'georeferenced' (default) or 'pixel'.
"""
if distance_unit not in ["georeferenced", "pixel"]:
raise ValueError("Argument 'distance_unit' should be either 'pixel' or 'georeferenced'.")

# Get transform
dx, b, xmin, d, dy, ymax = list(self.transform)[:6]

# Convert pixel offsets to georeferenced units
if distance_unit == "pixel":
xoff *= self.res[0]
yoff *= self.res[1]

# Overwrite transform by shifted transform
self.transform = rio.transform.Affine(dx, b, xmin + xoff, d, dy, ymax + yoff)

def save(
Expand Down
24 changes: 24 additions & 0 deletions tests/test_raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -1102,8 +1102,11 @@ def test_shift(self, example: str) -> None:

r = gu.Raster(example)

# Get original transform
orig_transform = r.transform
orig_bounds = r.bounds

# Shift raster by georeferenced units (default)
r.shift(xoff=1, yoff=1)

# Only bounds should change
Expand All @@ -1117,6 +1120,27 @@ def test_shift(self, example: str) -> None:
assert orig_bounds.bottom + 1 == r.bounds.bottom
assert orig_bounds.top + 1 == r.bounds.top

# Shift raster using pixel units
orig_transform = r.transform
orig_bounds = r.bounds
orig_res = r.res
r.shift(xoff=1, yoff=1, distance_unit="pixel")

# Only bounds should change
assert orig_transform.c + 1 * orig_res[0] == r.transform.c
assert orig_transform.f + 1 * orig_res[1] == r.transform.f
for attr in ["a", "b", "d", "e"]:
assert getattr(orig_transform, attr) == getattr(r.transform, attr)

assert orig_bounds.left + 1 * orig_res[0] == r.bounds.left
assert orig_bounds.right + 1 * orig_res[0] == r.bounds.right
assert orig_bounds.bottom + 1 * orig_res[1] == r.bounds.bottom
assert orig_bounds.top + 1 * orig_res[1] == r.bounds.top

# Check that an error is raised for a wrong distance_unit
with pytest.raises(ValueError, match="Argument 'distance_unit' should be either 'pixel' or 'georeferenced'."):
r.shift(xoff=1, yoff=1, distance_unit="wrong_value") # type: ignore

@pytest.mark.parametrize("example", [landsat_b4_path, aster_dem_path]) # type: ignore
def test_reproject(self, example: str) -> None:
warnings.simplefilter("error")
Expand Down

0 comments on commit fac1de0

Please sign in to comment.