rasterio/tests/test_boundless_read.py
2026-01-05 10:56:51 -06:00

230 lines
7.9 KiB
Python

"""Test of boundless reads"""
import sys
from affine import Affine
import shutil
from hypothesis import example, given
import hypothesis.strategies as st
import numpy
from numpy.testing import assert_almost_equal
import pytest
import rasterio
from rasterio.io import MemoryFile
from rasterio.windows import Window
@given(
col_start=st.integers(min_value=-700, max_value=0),
row_start=st.integers(min_value=-700, max_value=0),
col_stop=st.integers(min_value=0, max_value=700),
row_stop=st.integers(min_value=0, max_value=700),
)
@pytest.mark.skipif(
sys.platform != "linux", reason="https://github.com/rasterio/rasterio/issues/1696"
)
def test_outer_boundless_pixel_fidelity(
path_rgb_byte_tif, col_start, row_start, col_stop, row_stop
):
"""An outer boundless read doesn't change pixels"""
with rasterio.open(path_rgb_byte_tif) as dataset:
width = dataset.width + col_stop - col_start
height = dataset.height + row_stop - row_start
window = Window(col_start, row_start, width, height)
rgb_padded = dataset.read(window=window, boundless=True)
assert rgb_padded.shape == (dataset.count, height, width)
rgb = dataset.read()
assert numpy.all(
rgb
== rgb_padded[
:, -row_start : height - row_stop, -col_start : width - col_stop
]
)
@pytest.mark.xfail(reason="The bug reported in gh-2382")
@given(height=st.integers(min_value=500, max_value=20000))
@example(height=9508)
def test_issue2382(height):
data_array = numpy.arange(height, dtype="f4").reshape((height, 1))
with MemoryFile() as memfile:
with memfile.open(
driver="GTiff",
count=1,
height=height,
width=1,
dtype=data_array.dtype,
transform=Affine(1.0, 0.0, 0, 0.0, -1.0, 0),
) as dataset:
dataset.write(data_array[numpy.newaxis, ...])
with memfile.open(driver="GTiff") as dataset:
# read first column, rows 0-388
a = dataset.read(
1,
window=Window(col_off=0, row_off=0, width=1, height=388),
boundless=True,
fill_value=-9999,
)[:, 0]
assert_almost_equal(a, numpy.arange(388))
b = dataset.read(
1,
window=Window(col_off=0, row_off=-12, width=1, height=400),
boundless=True,
fill_value=-9999,
)[:, 0]
# the expected result is 12 * -9999 and then the same as above
assert_almost_equal(b, numpy.concatenate([[-9999] * 12, a]))
@pytest.mark.xfail(reason="Likely the bug reported in gh-2382")
@given(
col_start=st.integers(min_value=-700, max_value=0),
row_start=st.integers(min_value=-700, max_value=0),
col_stop=st.integers(min_value=0, max_value=700),
row_stop=st.integers(min_value=0, max_value=700),
)
def test_outer_upper_left_boundless_pixel_fidelity(
path_rgb_byte_tif, col_start, row_start, col_stop, row_stop
):
"""A partially outer boundless read doesn't change pixels"""
with rasterio.open(path_rgb_byte_tif) as dataset:
width = dataset.width - col_stop - col_start
height = dataset.height - row_stop - row_start
window = Window(col_start, row_start, width, height)
rgb_boundless = dataset.read(window=window, boundless=True)
assert rgb_boundless.shape == (dataset.count, height, width)
rgb = dataset.read()
assert numpy.all(
rgb[:, 0 : height + row_start, 0 : width + col_start]
== rgb_boundless[:, -row_start:height, -col_start:width]
)
def test_image(red_green):
"""Read a red image with black background"""
with rasterio.Env():
with rasterio.open(str(red_green.join("red.tif"))) as src:
data = src.read(
boundless=True,
window=Window(-src.width, -src.height, src.width * 3, src.height * 3),
)
image = numpy.moveaxis(data, 0, -1)
assert image[63, 63, 0] == 0
assert image[64, 64, 0] == 204
def test_hit_ovr(red_green):
"""Zoomed out read hits the overviews"""
# GDAL doesn't log overview hits for local files , so we copy the
# overviews of green.tif over the red overviews and expect to find
# green pixels below.
green_ovr = red_green.join("green.tif.ovr")
shutil.move(green_ovr, red_green.join("red.tif.ovr"))
assert not green_ovr.exists()
with rasterio.open(str(red_green.join("red.tif.ovr"))) as ovr:
data = ovr.read()
assert (data[1] == 204).all()
with rasterio.Env():
with rasterio.open(str(red_green.join("red.tif"))) as src:
data = src.read(out_shape=(3, 32, 32))
image = numpy.moveaxis(data, 0, -1)
assert image[0, 0, 0] == 17
assert image[0, 0, 1] == 204
def test_boundless_mask_not_all_valid():
"""Confirm resolution of issue #1449"""
with rasterio.open("tests/data/red.tif") as src:
masked = src.read(1, boundless=True, masked=True, window=Window(-1, -1, 66, 66))
assert not masked.mask.all()
assert masked.mask[:, 0].all()
assert masked.mask[:, -1].all()
assert masked.mask[0, :].all()
assert masked.mask[-1, :].all()
def test_boundless_fill_value():
"""Confirm resolution of issue #1471"""
with rasterio.open("tests/data/red.tif") as src:
filled = src.read(
1, boundless=True, fill_value=5, window=Window(-1, -1, 66, 66)
)
assert (filled[:, 0] == 5).all()
assert (filled[:, -1] == 5).all()
assert (filled[0, :] == 5).all()
assert (filled[-1, :] == 5).all()
def test_boundless_masked_special():
"""Confirm resolution of special case in issue #1471"""
with rasterio.open("tests/data/green.tif") as src:
masked = src.read(2, boundless=True, masked=True, window=Window(-1, -1, 66, 66))
assert not masked[:, 0].any()
assert not masked[:, -1].any()
assert not masked[0, :].any()
assert not masked[-1, :].any()
def test_boundless_mask_special():
"""Confirm resolution of special case in issue #1471"""
with rasterio.open("tests/data/green.tif") as src:
mask = src.read_masks(2, boundless=True, window=Window(-1, -1, 66, 66))
assert not mask[:, 0].any()
assert not mask[:, -1].any()
assert not mask[0, :].any()
assert not mask[-1, :].any()
def test_boundless_fill_value_overview_masks():
"""Confirm a more general resolution to issue #1471"""
with rasterio.open("tests/data/cogeo.tif") as src:
data = src.read(
1,
boundless=True,
window=Window(-300, -335, 1000, 1000),
fill_value=5,
out_shape=(512, 512),
)
assert (data[:, 0] == 5).all()
def test_boundless_masked_fill_value_overview_masks():
"""Confirm a more general resolution to issue #1471"""
with rasterio.open("tests/data/cogeo.tif") as src:
data = src.read(
1,
masked=True,
boundless=True,
window=Window(-300, -335, 1000, 1000),
fill_value=5,
out_shape=(512, 512),
)
assert data.fill_value == 5
assert data.mask[:, 0].all()
def test_boundless_open_options():
"""Open options are taken into account"""
with rasterio.open("tests/data/cogeo.tif", overview_level=1) as src:
data1 = src.read(1, boundless=True)
with rasterio.open("tests/data/cogeo.tif", overview_level=2) as src:
data2 = src.read(1, boundless=True)
assert not numpy.array_equal(data1, data2)
def test_issue3245(data):
"""Boundless read of a dataset without a mask should have no masking."""
with rasterio.open(data / "RGB.byte.tif", "r+") as dst:
dst.nodata = None
assert not dst.read(masked=True).mask.any()
data = dst.read(
boundless=True, masked=True, window=Window(0, 0, dst.width, dst.height)
)
assert not data.mask.any()
assert (data >= 0).all()