Skip to content

Commit

Permalink
py2.7 fix, docstring improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
brendan-ward committed Sep 14, 2017
1 parent 4a09df2 commit 3323213
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 54 deletions.
3 changes: 3 additions & 0 deletions rasterio/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,9 @@ def geometry_window(raster, shapes, pad_x=0, pad_y=0, north_up=True,
pad_y: float
Amount of padding (as fraction of raster's y pixel size) to add to top
and bottom of bounds.
north_up: bool
If True (default), the origin point of the raster's transform is the
northernmost point and y pixel values are negative.
pixel_precision: int
Number of places of rounding precision for evaluating bounds of shapes.
Expand Down
44 changes: 24 additions & 20 deletions rasterio/mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
logger = logging.getLogger(__name__)


def raster_geom_mask(raster, shapes, all_touched=False, invert=False,
crop=False, pad=False):
def raster_geometry_mask(raster, shapes, all_touched=False, invert=False,
crop=False, pad=False):
"""Create a mask from shapes, transform, and optional window within original
raster.
Expand All @@ -31,13 +31,13 @@ def raster_geom_mask(raster, shapes, all_touched=False, invert=False,
GeoJSON-like dict representation of polygons that will be used to
create the mask.
all_touched: bool (opt)
Use all pixels touched by features. If False (default), use only
pixels whose center is within the polygon or that are selected by
Bresenham's line algorithm.
Include a pixel in the mask if it touches any of the shapes.
If False (default), include a pixel only if its center is within one of
the shapes, or if it is selected by Bresenham's line algorithm.
invert: bool (opt)
If True, mask will be `True` for pixels inside shapes and `False`
outside shapes.
False by default.
If False (default), mask will be `False` inside shapes and `True`
outside. If True, mask will be `True` inside shapes and `False`
outside.
crop: bool (opt)
Whether to crop the raster to the extent of the shapes. Defaults to
False.
Expand Down Expand Up @@ -92,12 +92,12 @@ def raster_geom_mask(raster, shapes, all_touched=False, invert=False,

if crop:
transform = raster.window_transform(window)
out_shape = (window.height, window.width)
out_shape = (int(window.height), int(window.width))

else:
window = None
transform = raster.transform
out_shape = (raster.height, raster.width)
out_shape = (int(raster.height), int(raster.width))

mask = geometry_mask(shapes, transform=transform, invert=invert,
out_shape=out_shape, all_touched=all_touched)
Expand All @@ -122,13 +122,12 @@ def mask(raster, shapes, all_touched=False, invert=False, nodata=None,
GeoJSON-like dict representation of polygons that will be used to
create the mask.
all_touched: bool (opt)
Use all pixels touched by features. If False (default), use only
pixels whose center is within the polygon or that are selected by
Bresenham's line algorithm.
Include a pixel in the mask if it touches any of the shapes.
If False (default), include a pixel only if its center is within one of
the shapes, or if it is selected by Bresenham's line algorithm.
invert: bool (opt)
If True, mask will be `True` for pixels inside shapes and `False`
outside shapes.
False by default.
If False (default) pixels outside shapes will be masked. If True,
pixels inside shape will be masked.
nodata: int or float (opt)
Value representing nodata within each raster band. If not set,
defaults to the nodata value for the input raster. If there is no
Expand All @@ -151,9 +150,14 @@ def mask(raster, shapes, all_touched=False, invert=False, nodata=None,
Two elements:
masked : numpy ndarray or numpy.ma.MaskedArray
Data contained in raster after applying the mask (`filled` is
`True`) and mask where all pixels are `True` outside shapes
(`invert` is `False`).
Data contained in the raster after applying the mask. If
`filled` is `True` and `invert` is `False`, the return will be
an array where pixels outside shapes are set to the nodata value
(or nodata inside shapes if `invert` is `True`).
If `filled` is `False`, the return will be a MaskedArray in
which pixels outside shapes are `True` (or `False` if `invert`
is `True`).
out_transform : affine.Affine()
Information for mapping pixel coordinates in `masked` to another
Expand All @@ -166,7 +170,7 @@ def mask(raster, shapes, all_touched=False, invert=False, nodata=None,
else:
nodata = 0

shape_mask, transform, window = raster_geom_mask(
shape_mask, transform, window = raster_geometry_mask(
raster, shapes, all_touched=all_touched, invert=invert, crop=crop,
pad=pad)

Expand Down
68 changes: 34 additions & 34 deletions tests/test_mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,133 +3,133 @@
from affine import Affine

import rasterio
from rasterio.mask import raster_geom_mask, mask
from rasterio.mask import raster_geometry_mask, mask


def test_raster_geom_mask(basic_image_2x2, basic_image_file, basic_geometry):
def test_raster_geometrymask(basic_image_2x2, basic_image_file, basic_geometry):
"""Pixels inside the geometry are False in the mask"""

geometries = [basic_geometry]

with rasterio.open(basic_image_file) as src:
geom_mask, transform, window = raster_geom_mask(src, geometries)
geometrymask, transform, window = raster_geometry_mask(src, geometries)

assert np.array_equal(geom_mask, (basic_image_2x2 == 0))
assert np.array_equal(geometrymask, (basic_image_2x2 == 0))
assert transform == Affine.identity()
assert window is None


def test_raster_geom_mask_invert(basic_image_2x2, basic_image_file, basic_geometry):
def test_raster_geometrymask_invert(basic_image_2x2, basic_image_file, basic_geometry):
"""Pixels inside the geometry are True in the mask"""

geometries = [basic_geometry]

with rasterio.open(basic_image_file) as src:
geom_mask, transform, window = raster_geom_mask(src, geometries,
invert=True)
geometrymask, transform, window = raster_geometry_mask(src, geometries,
invert=True)

assert np.array_equal(geom_mask, basic_image_2x2)
assert np.array_equal(geometrymask, basic_image_2x2)
assert transform == Affine.identity()


def test_raster_geom_mask_all_touched(basic_image, basic_image_file,
def test_raster_geometrymask_all_touched(basic_image, basic_image_file,
basic_geometry):
"""Pixels inside the geometry are False in the mask"""

geometries = [basic_geometry]

with rasterio.open(basic_image_file) as src:
geom_mask, transform, window = raster_geom_mask(src, geometries,
all_touched=True)
geometrymask, transform, window = raster_geometry_mask(src, geometries,
all_touched=True)

assert np.array_equal(geom_mask, (basic_image == 0))
assert np.array_equal(geometrymask, (basic_image == 0))
assert transform == Affine.identity()


def test_raster_geom_mask_crop(basic_image_2x2, basic_image_file,
def test_raster_geometrymask_crop(basic_image_2x2, basic_image_file,
basic_geometry):
"""Mask returned will be cropped to extent of geometry, and transform
is transposed 2 down and 2 over"""

geometries = [basic_geometry]

with rasterio.open(basic_image_file) as src:
geom_mask, transform, window = raster_geom_mask(src, geometries,
crop=True)
geometrymask, transform, window = raster_geometry_mask(src, geometries,
crop=True)

image = basic_image_2x2[2:5, 2:5] == 0 # invert because invert=False

assert geom_mask.shape == (3, 3)
assert np.array_equal(geom_mask, image)
assert geometrymask.shape == (3, 3)
assert np.array_equal(geometrymask, image)
assert transform == Affine(1, 0, 2, 0, 1, 2)
assert window is not None and window.flatten() == (2, 2, 3, 3)


def test_raster_geom_mask_crop_invert(basic_image_file, basic_geometry):
def test_raster_geometrymask_crop_invert(basic_image_file, basic_geometry):
"""crop and invert cannot be combined"""

geometries = [basic_geometry]

with rasterio.open(basic_image_file) as src:
with pytest.raises(ValueError):
raster_geom_mask(src, geometries, crop=True, invert=True)
raster_geometry_mask(src, geometries, crop=True, invert=True)


def test_raster_geom_mask_crop_all_touched(basic_image, basic_image_file,
def test_raster_geometrymask_crop_all_touched(basic_image, basic_image_file,
basic_geometry):
"""Mask returned will be cropped to extent of geometry, and transform
is transposed 2 down and 2 over"""

geometries = [basic_geometry]

with rasterio.open(basic_image_file) as src:
geom_mask, transform, window = raster_geom_mask(src, geometries,
crop=True,
all_touched=True)
geometrymask, transform, window = raster_geometry_mask(src, geometries,
crop=True,
all_touched=True)

image = basic_image[2:5, 2:5] == 0 # invert because invert=False

assert geom_mask.shape == (3, 3)
assert np.array_equal(geom_mask, image)
assert geometrymask.shape == (3, 3)
assert np.array_equal(geometrymask, image)
assert transform == Affine(1, 0, 2, 0, 1, 2)
assert window is not None and window.flatten() == (2, 2, 3, 3)


def test_raster_geom_mask_crop_pad(basic_image_2x2, basic_image_file,
def test_raster_geometrymask_crop_pad(basic_image_2x2, basic_image_file,
basic_geometry):
"""Mask returned will be cropped to extent of geometry plus 1/2 pixel on
all sides, and transform is transposed 1 down and 1 over"""

geometries = [basic_geometry]

with rasterio.open(basic_image_file) as src:
geom_mask, transform, window = raster_geom_mask(src, geometries,
crop=True, pad=True)
geometrymask, transform, window = raster_geometry_mask(src, geometries,
crop=True, pad=True)

image = basic_image_2x2[1:5, 1:5] == 0 # invert because invert=False

assert geom_mask.shape == (4, 4)
assert np.array_equal(geom_mask, image)
assert geometrymask.shape == (4, 4)
assert np.array_equal(geometrymask, image)
assert transform == Affine(1, 0, 1, 0, 1, 1)
assert window is not None and window.flatten() == (1, 1, 4, 4)


def test_raster_geom_mask_no_overlap(path_rgb_byte_tif, basic_geometry):
def test_raster_geometrymask_no_overlap(path_rgb_byte_tif, basic_geometry):
"""If there is no overlap, a warning should be raised"""

with rasterio.open(path_rgb_byte_tif) as src:
with pytest.warns(UserWarning) as warning:
raster_geom_mask(src, [basic_geometry])
raster_geometry_mask(src, [basic_geometry])

assert 'outside bounds of raster' in warning[0].message.args[0]


def test_raster_geom_mask_crop_no_overlap(path_rgb_byte_tif, basic_geometry):
def test_raster_geometrymask_crop_no_overlap(path_rgb_byte_tif, basic_geometry):
"""If there is no overlap with crop=True, an Exception should be raised"""

with rasterio.open(path_rgb_byte_tif) as src:
with pytest.raises(ValueError) as excinfo:
raster_geom_mask(src, [basic_geometry], crop=True)
raster_geometry_mask(src, [basic_geometry], crop=True)

assert 'shapes do not overlap raster' in repr(excinfo)

Expand Down

0 comments on commit 3323213

Please sign in to comment.