Skip to content

Commit

Permalink
Merge pull request #275 from pnuu/bugfix-get_area_slices
Browse files Browse the repository at this point in the history
Check area slices for correct step
  • Loading branch information
pnuu authored May 13, 2020
2 parents 914a424 + 5db5ae8 commit b453994
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
20 changes: 9 additions & 11 deletions pyresample/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
from pyresample._spatial_mp import Cartesian, Cartesian_MP, Proj, Proj_MP
from pyresample.boundary import AreaDefBoundary, Boundary, SimpleBoundary
from pyresample.utils import (proj4_str_to_dict, proj4_dict_to_str,
convert_proj_floats, proj4_radius_parameters)
convert_proj_floats, proj4_radius_parameters,
check_slice_orientation)
from pyresample.area_config import create_area_def

try:
Expand Down Expand Up @@ -1980,15 +1981,11 @@ def get_area_slices(self, area_to_cover, shape_divisible_by=None):

xstart = 0 if x[0] is np.ma.masked else x[0]
ystart = 0 if y[1] is np.ma.masked else y[1]
if self.area_extent[0] > self.area_extent[2]:
xstop = self.width if x[0] is np.ma.masked else x[0] + 1
else:
xstop = self.width if x[1] is np.ma.masked else x[1] + 1
if self.area_extent[1] > self.area_extent[3]:
ystop = self.height if y[1] is np.ma.masked else y[1] + 1
else:
ystop = self.height if y[0] is np.ma.masked else y[0] + 1
return slice(xstart, xstop), slice(ystart, ystop)
xstop = self.width if x[1] is np.ma.masked else x[1] + 1
ystop = self.height if y[0] is np.ma.masked else y[0] + 1

return (check_slice_orientation(slice(xstart, xstop)),
check_slice_orientation(slice(ystart, ystop)))

if self.proj_dict.get('proj') != 'geos':
raise NotImplementedError("Source projection must be 'geos' if "
Expand Down Expand Up @@ -2018,7 +2015,8 @@ def get_area_slices(self, area_to_cover, shape_divisible_by=None):
y_slice = _make_slice_divisible(y_slice, self.height,
factor=shape_divisible_by)

return (x_slice, y_slice)
return (check_slice_orientation(x_slice),
check_slice_orientation(y_slice))

def crop_around(self, other_area):
"""Crop this area around `other_area`."""
Expand Down
29 changes: 29 additions & 0 deletions pyresample/test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,3 +645,32 @@ def test_norotation_yaml(self):
test_area = load_area(f.name, 'regionB')
self.assertEqual(test_area.rotation, 0)
os.remove(f.name)


def test_check_slice_orientation():
"""Test that slicing fix is doing what it should."""
from pyresample.utils import check_slice_orientation

# Forward slicing should not be changed
start, stop, step = 0, 10, None
slice_in = slice(start, stop, step)
res = check_slice_orientation(slice_in)
assert res is slice_in

# Reverse slicing should not be changed if the step is negative
start, stop, step = 10, 0, -1
slice_in = slice(start, stop, step)
res = check_slice_orientation(slice_in)
assert res is slice_in

# Reverse slicing should be fixed if step is positive
start, stop, step = 10, 0, 2
slice_in = slice(start, stop, step)
res = check_slice_orientation(slice_in)
assert res == slice(start, stop, -step)

# Reverse slicing should be fixed if step is None
start, stop, step = 10, 0, None
slice_in = slice(start, stop, step)
res = check_slice_orientation(slice_in)
assert res == slice(start, stop, -1)
10 changes: 10 additions & 0 deletions pyresample/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,13 @@ def recursive_dict_update(d, u):
def is_pyproj2():
"""Determine whether the current pyproj version is >= 2.0"""
return pyproj.__version__ >= '2'


def check_slice_orientation(sli):
"""Check that the slice is slicing the right way."""
if sli.start > sli.stop:
if sli.step is None or sli.step > 0:
step = -(sli.step or 1)
sli = slice(sli.start, sli.stop, step)

return sli

0 comments on commit b453994

Please sign in to comment.