def test_can_paste(): src = AlbersGS.tile_geobox((17, -40)) def check_true(dst, **kwargs): ok, reason = can_paste(compute_reproject_roi(src, dst), **kwargs) if not ok: assert ok is True, reason def check_false(dst, **kwargs): ok, reason = can_paste(compute_reproject_roi(src, dst), **kwargs) if ok: assert ok is False, "Expected can_paste to return False, but got True" check_true(gbx.pad(src, 100)) check_true(src[:10, :10]) check_true(gbx.translate_pix(src, 0.1, 0.3), ttol=0.5) check_true(gbx.translate_pix(src, 3, -4)) check_true(gbx.flipx(src)) check_true(gbx.flipy(src)) check_true(gbx.flipx(gbx.flipy(src))) check_true(gbx.zoom_out(src, 2)) check_true(gbx.zoom_out(src, 4)) check_true(gbx.zoom_out(src[:9, :9], 3)) # Check False code paths dst = GeoBox.from_geopolygon(src.extent.to_crs(epsg3857).buffer(10), resolution=src.resolution) check_false(dst) # non ST check_false(gbx.affine_transform_pix(src, Affine.rotation(1))) # non ST check_false(gbx.zoom_out(src, 1.9)) # non integer scale check_false(gbx.affine_transform_pix(src, Affine.scale(1, 2))) # sx != sy dst = gbx.translate_pix(src, -1, -1) dst = gbx.zoom_out(dst, 2) check_false(dst) # src_roi doesn't align for scale check_false(dst, stol=0.7) # src_roi/scale != dst_roi check_false(gbx.translate_pix(src, 0.3, 0.4)) # sub-pixel translation
def test_gbox_ops(): s = GeoBox(1000, 100, Affine(10, 0, 12340, 0, -10, 316770), epsg3857) assert s.shape == (100, 1000) d = gbx.flipy(s) assert d.shape == s.shape assert d.crs is s.crs assert d.resolution == (-s.resolution[0], s.resolution[1]) assert d.extent.contains(s.extent) with pytest.raises(ValueError): # flipped grid (s | d) with pytest.raises(ValueError): # flipped grid (s & d) d = gbx.flipx(s) assert d.shape == s.shape assert d.crs is s.crs assert d.resolution == (s.resolution[0], -s.resolution[1]) assert d.extent.contains(s.extent) assert gbx.flipy(gbx.flipy(s)).affine == s.affine assert gbx.flipx(gbx.flipx(s)).affine == s.affine d = gbx.zoom_out(s, 2) assert d.shape == (50, 500) assert d.crs is s.crs assert d.extent.contains(s.extent) assert d.resolution == (s.resolution[0]*2, s.resolution[1]*2) d = gbx.zoom_out(s, 2*max(s.shape)) assert d.shape == (1, 1) assert d.crs is s.crs assert d.extent.contains(s.extent) d = gbx.zoom_out(s, 1.33719) assert d.crs is s.crs assert d.extent.contains(s.extent) assert all(ds < ss for ds, ss in zip(d.shape, s.shape)) with pytest.raises(ValueError): # lower resolution grid (s | d) with pytest.raises(ValueError): # lower resolution grid (s & d) d = gbx.zoom_to(s, s.shape) assert d == s d = gbx.zoom_to(s, (1, 3)) assert d.shape == (1, 3) assert d.extent == s.extent d = gbx.zoom_to(s, (10000, 10000)) assert d.shape == (10000, 10000) assert d.extent == s.extent d = gbx.pad(s, 1) assert d.crs is s.crs assert d.resolution == s.resolution assert d.extent.contains(s.extent) assert s.extent.contains(d.extent) is False assert d[1:-1, 1:-1].affine == s.affine assert d[1:-1, 1:-1].shape == s.shape assert d == (s | d) assert s == (s & d) d = gbx.pad_wh(s, 10) assert d == s d = gbx.pad_wh(s, 100, 8) assert d.width == s.width assert d.height % 8 == 0 assert 0 < d.height - s.height < 8 assert d.affine == s.affine assert d.crs is s.crs d = gbx.pad_wh(s, 13, 17) assert d.affine == s.affine assert d.crs is s.crs assert d.height % 17 == 0 assert d.width % 13 == 0 assert 0 < d.height - s.height < 17 assert 0 < d.width - s.width < 13 d = gbx.translate_pix(s, 1, 2) assert d.crs is s.crs assert d.resolution == s.resolution assert d.extent != s.extent assert s[2:3, 1:2].extent == d[:1, :1].extent d = gbx.translate_pix(s, -10, -2) assert d.crs is s.crs assert d.resolution == s.resolution assert d.extent != s.extent assert s[:1, :1].extent == d[2:3, 10:11].extent d = gbx.translate_pix(s, 0.1, 0) assert d.crs is s.crs assert d.shape == s.shape assert d.resolution == s.resolution assert d.extent != s.extent assert d.extent.contains(s[:, 1:].extent) d = gbx.translate_pix(s, 0, -0.5) assert d.crs is s.crs assert d.shape == s.shape assert d.resolution == s.resolution assert d.extent != s.extent assert s.extent.contains(d[1:, :].extent) d = gbx.affine_transform_pix(s, Affine(1, 0, 0, 0, 1, 0)) assert d.crs is s.crs assert d.shape == s.shape assert d.resolution == s.resolution assert d.extent == s.extent d = gbx.rotate(s, 180) assert d.crs is s.crs assert d.shape == s.shape assert d.extent != s.extent np.testing.assert_almost_equal(d.extent.area, s.extent.area, 1e-5) assert s[49:52, 499:502].extent.contains(d[50:51, 500:501].extent), "Check that center pixel hasn't moved"
def test_read_paste(tmpdir): from datacube.testutils import mk_test_image from datacube.testutils.io import write_gtiff from pathlib import Path pp = Path(str(tmpdir)) xx = mk_test_image(128, 64, nodata=None) assert (xx != -999).all() mm = write_gtiff(pp / 'tst-read-paste-128x64-int16.tif', xx, nodata=None) def _read(gbox, resampling='nearest', fallback_nodata=-999, dst_nodata=-999, check_paste=False): with RasterFileDataSource(mm.path, 1, nodata=fallback_nodata).open() as rdr: if check_paste: # check that we are using paste paste_ok, reason = can_paste( compute_reproject_roi(rdr_geobox(rdr), gbox)) assert paste_ok is True, reason yy = np.full(gbox.shape, dst_nodata, dtype=rdr.dtype) roi = read_time_slice(rdr, yy, gbox, resampling, dst_nodata) return yy, roi # read native whole yy, roi = _read(mm.gbox) np.testing.assert_array_equal(xx, yy) assert roi == np.s_[0:64, 0:128] # read native whole, no nodata case yy, roi = _read(mm.gbox, fallback_nodata=None) np.testing.assert_array_equal(xx, yy) assert roi == np.s_[0:64, 0:128] # read native whole, ignoring small sub-pixel translation yy, roi = _read(gbx.translate_pix(mm.gbox, 0.3, -0.4), fallback_nodata=-33) np.testing.assert_array_equal(xx, yy) assert roi == np.s_[0:64, 0:128] # no overlap between src and dst yy, roi = _read(gbx.translate_pix(mm.gbox, 10000, -10000)) assert roi_is_empty(roi) # read with Y flipped yy, roi = _read(gbx.flipy(mm.gbox)) np.testing.assert_array_equal(xx[::-1, :], yy) assert roi == np.s_[0:64, 0:128] # read with X flipped yy, roi = _read(gbx.flipx(mm.gbox)) np.testing.assert_array_equal(xx[:, ::-1], yy) assert roi == np.s_[0:64, 0:128] # read with X and Y flipped yy, roi = _read(gbx.flipy(gbx.flipx(mm.gbox))) assert roi == np.s_[0:64, 0:128] np.testing.assert_array_equal(xx[::-1, ::-1], yy[roi]) # dst is fully inside src sroi = np.s_[10:19, 31:47] yy, roi = _read(mm.gbox[sroi]) np.testing.assert_array_equal(xx[sroi], yy[roi]) # partial overlap yy, roi = _read(gbx.translate_pix(mm.gbox, -3, -10)) assert roi == np.s_[10:64, 3:128] np.testing.assert_array_equal(xx[:-10, :-3], yy[roi]) assert (yy[:10, :] == -999).all() assert (yy[:, :3] == -999).all() # scaling paste yy, roi = _read(gbx.zoom_out(mm.gbox, 2), check_paste=True) assert roi == np.s_[0:32, 0:64] np.testing.assert_array_equal(xx[1::2, 1::2], yy)
def test_gbox_ops(): s = GeoBox(1000, 100, Affine(10, 0, 12340, 0, -10, 316770), epsg3857) assert s.shape == (100, 1000) d = gbx.flipy(s) assert d.shape == s.shape assert d.crs is s.crs assert d.resolution == (-s.resolution[0], s.resolution[1]) assert d.extent.contains(s.extent) d = gbx.flipx(s) assert d.shape == s.shape assert d.crs is s.crs assert d.resolution == (s.resolution[0], -s.resolution[1]) assert d.extent.contains(s.extent) assert gbx.flipy(gbx.flipy(s)).affine == s.affine assert gbx.flipx(gbx.flipx(s)).affine == s.affine d = gbx.zoom_out(s, 2) assert d.shape == (50, 500) assert d.crs is s.crs assert d.extent.contains(s.extent) assert d.resolution == (s.resolution[0] * 2, s.resolution[1] * 2) d = gbx.zoom_out(s, 2 * max(s.shape)) assert d.shape == (1, 1) assert d.crs is s.crs assert d.extent.contains(s.extent) d = gbx.zoom_out(s, 1.33719) assert d.crs is s.crs assert d.extent.contains(s.extent) assert all(ds < ss for ds, ss in zip(d.shape, s.shape)) d = gbx.zoom_to(s, s.shape) assert d == s d = gbx.zoom_to(s, (1, 3)) assert d.shape == (1, 3) assert d.extent == s.extent d = gbx.zoom_to(s, (10000, 10000)) assert d.shape == (10000, 10000) assert d.extent == s.extent d = gbx.pad(s, 1) assert d.crs is s.crs assert d.resolution == s.resolution assert d.extent.contains(s.extent) assert s.extent.contains(d.extent) is False assert d[1:-1, 1:-1].affine == s.affine assert d[1:-1, 1:-1].shape == s.shape d = gbx.translate_pix(s, 1, 2) assert d.crs is s.crs assert d.resolution == s.resolution assert d.extent != s.extent assert s[2:3, 1:2].extent == d[:1, :1].extent d = gbx.translate_pix(s, -10, -2) assert d.crs is s.crs assert d.resolution == s.resolution assert d.extent != s.extent assert s[:1, :1].extent == d[2:3, 10:11].extent d = gbx.translate_pix(s, 0.1, 0) assert d.crs is s.crs assert d.shape == s.shape assert d.resolution == s.resolution assert d.extent != s.extent assert d.extent.contains(s[:, 1:].extent) d = gbx.translate_pix(s, 0, -0.5) assert d.crs is s.crs assert d.shape == s.shape assert d.resolution == s.resolution assert d.extent != s.extent assert s.extent.contains(d[1:, :].extent) d = gbx.affine_transform_pix(s, Affine(1, 0, 0, 0, 1, 0)) assert d.crs is s.crs assert d.shape == s.shape assert d.resolution == s.resolution assert d.extent == s.extent d = gbx.affine_transform_pix(s, Affine.rotation(10)) assert d.crs is s.crs assert d.shape == s.shape assert d.extent != s.extent for deg in (33, -33, 20, 90, 180): d = gbx.rotate(s, 33) assert d.crs is s.crs assert d.shape == s.shape assert d.extent != s.extent np.testing.assert_almost_equal(d.extent.area, s.extent.area, 1e-5) assert s[49:52, 499:502].extent.contains( d[50:51, 500:501].extent), "Check that center pixel hasn't moved"