def test_output_geobox_load_hints(): geobox0 = AlbersGS.tile_geobox((15, -40)) geobox = output_geobox(load_hints={'output_crs': geobox0.crs, 'resolution': geobox0.resolution}, geopolygon=geobox0.extent) assert geobox == geobox0
def test_dask_chunks(): coords = {'time': np.arange(10)} sources = xr.DataArray(coords['time'], coords=coords, dims=coords.keys()) geobox = AlbersGS.tile_geobox((0, 0))[:6, :7] assert geobox.dimensions == ('y', 'x') assert sources.dims == ('time', ) assert _calculate_chunk_sizes(sources, geobox, {}) == ((1, ), (6, 7)) assert _calculate_chunk_sizes(sources, geobox, {'time': -1}) == ((10, ), (6, 7)) assert _calculate_chunk_sizes(sources, geobox, { 'time': 'auto', 'x': 'auto' }) == ((1, ), (6, 7)) assert _calculate_chunk_sizes(sources, geobox, { 'y': -1, 'x': 3 }) == ((1, ), (6, 3)) assert _calculate_chunk_sizes(sources, geobox, { 'y': 2, 'x': 3 }) == ((1, ), (2, 3)) with pytest.raises(ValueError): _calculate_chunk_sizes(sources, geobox, {'x': "aouto"}) with pytest.raises(KeyError): _calculate_chunk_sizes(sources, geobox, {'zz': 1})
def test_read_with_reproject(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() tile = AlbersGS.tile_geobox((17, -40))[:64, :128] mm = write_gtiff(pp / 'tst-read-with-reproject-128x64-int16.tif', xx, crs=str(tile.crs), resolution=tile.resolution[::-1], offset=tile.transform * (0, 0), nodata=-999) assert mm.gbox == tile def _read(gbox, resampling='nearest', fallback_nodata=None, dst_nodata=-999): with RasterFileDataSource(mm.path, 1, nodata=fallback_nodata).open() as rdr: yy = np.full(gbox.shape, dst_nodata, dtype=rdr.dtype) roi = read_time_slice(rdr, yy, gbox, resampling, dst_nodata) return yy, roi gbox = gbx.pad(mm.gbox, 10) gbox = gbx.zoom_out(gbox, 0.873) yy, roi = _read(gbox) assert roi[0].start > 0 and roi[1].start > 0 assert (yy[0] == -999).all() yy_expect, _ = rio_slurp(mm.path, gbox) np.testing.assert_array_equal(yy, yy_expect) gbox = gbx.zoom_out(mm.gbox[3:-3, 10:-10], 2.1) yy, roi = _read(gbox) assert roi_shape(roi) == gbox.shape assert not (yy == -999).any() gbox = GeoBox.from_geopolygon(mm.gbox.extent.to_crs(epsg3857).buffer(50), resolution=mm.gbox.resolution) assert gbox.extent.contains(mm.gbox.extent.to_crs(epsg3857)) assert gbox.crs != mm.gbox.crs yy, roi = _read(gbox) assert roi[0].start > 0 and roi[1].start > 0 assert (yy[0] == -999).all() gbox = gbx.zoom_out(gbox, 4) yy, roi = _read(gbox, resampling='average') nvalid = (yy != -999).sum() nempty = (yy == -999).sum() assert nvalid > nempty
def test_rio_reproject(): src = np.zeros((128, 256), dtype='int16') src[10:20, 30:50] = 33 s_gbox = AlbersGS.tile_geobox((15, -40))[:src.shape[0], :src.shape[1]] dst = np.zeros_like(src) dst_ = rio_reproject(src, dst, s_gbox, gbx.translate_pix(s_gbox, 30, 10), resampling='nearest') assert dst_ is dst assert (dst[:10, :20] == 33).all() assert (dst[10:, :] == 0).all() assert (dst[:, 20:] == 0).all() # check GDAL int8 limitation work-around src = src.astype('int8') dst = np.zeros_like(src) dst_ = rio_reproject(src, dst, s_gbox, gbx.translate_pix(s_gbox, 30, 10), resampling='nearest') assert dst_ is dst assert (dst[:10, :20] == 33).all() assert (dst[10:, :] == 0).all() assert (dst[:, 20:] == 0).all() # check GDAL int8 limitation work-around, with no-data src = src.astype('int8') dst = np.zeros_like(src) dst_ = rio_reproject(src, dst, s_gbox, gbx.translate_pix(s_gbox, 30, 10), src_nodata=0, dst_nodata=-3, resampling='nearest') assert dst_ is dst assert (dst[:10, :20] == 33).all() assert (dst[10:, :] == -3).all() assert (dst[:, 20:] == -3).all()
def test_native_geobox_ingested(): from datacube.testutils.io import native_geobox from datacube.testutils.geom import AlbersGS gbox = AlbersGS.tile_geobox((15, -40)) ds = mk_sample_dataset([dict(name='a')], geobox=gbox, product_opts=dict(with_grid_spec=True)) assert native_geobox(ds) == gbox # check that dataset covering several tiles is detected as invalid ds = mk_sample_dataset([dict(name='a')], geobox=gbox.buffered(10, 10), product_opts=dict(with_grid_spec=True)) with pytest.raises(ValueError): native_geobox(ds)
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_compute_reproject_roi(): src = AlbersGS.tile_geobox((15, -40)) dst = geometry.GeoBox.from_geopolygon( src.extent.to_crs(epsg3857).buffer(10), resolution=src.resolution) rr = compute_reproject_roi(src, dst) assert rr.roi_src == np.s_[0:src.height, 0:src.width] assert 0 < rr.scale < 1 assert rr.is_st is False assert rr.transform.linear is None assert rr.scale in rr.scale2 # check pure translation case roi_ = np.s_[113:-100, 33:-10] rr = compute_reproject_roi(src, src[roi_]) assert rr.roi_src == roi_normalise(roi_, src.shape) assert rr.scale == 1 assert rr.is_st is True rr = compute_reproject_roi(src, src[roi_], padding=0, align=0) assert rr.roi_src == roi_normalise(roi_, src.shape) assert rr.scale == 1 assert rr.scale2 == (1, 1) # check pure translation case roi_ = np.s_[113:-100, 33:-10] rr = compute_reproject_roi(src, src[roi_], align=256) assert rr.roi_src == np.s_[0:src.height, 0:src.width] assert rr.scale == 1 roi_ = np.s_[113:-100, 33:-10] rr = compute_reproject_roi(src, src[roi_]) assert rr.scale == 1 assert roi_shape(rr.roi_src) == roi_shape(rr.roi_dst) assert roi_shape(rr.roi_dst) == src[roi_].shape
def test_like_geobox(): from datacube.testutils.geom import AlbersGS from datacube.api.core import output_geobox geobox = AlbersGS.tile_geobox((15, -40)) assert output_geobox(like=geobox) is geobox
def test_like_geobox(): geobox = AlbersGS.tile_geobox((15, -40)) assert output_geobox(like=geobox) is geobox