Exemple #1
0
def test_reprojection_failure():
    ds = generate_test_dataset()
    transform = warp.get_transform(ds)
    extent = warp.get_extent(ds)
    with assert_raises_regex(
            ValueError, ".* must also specify the `width` and `height`.*"):
        _ = warp.Reprojection(crs=epsg4326, transform=transform)
    with assert_raises_regex(
            ValueError, "Need to provide either `width` and `height` .*"):
        _ = warp.Reprojection(crs=epsg4326, extent=extent)
Exemple #2
0
def test_reprojection_nan_values():
    src_crs = epsg4326
    dst_crs = sinusoidal
    ds = generate_test_dataset(crs=src_crs)
    bounds = warp.get_bounds(ds)
    proj = warp.Reprojection(crs=dst_crs)
    warped = proj.apply(ds)
    xgrid, ygrid = np.meshgrid(warped.x, warped.y)
    lon, lat = rasterio.warp.transform(dst_crs, src_crs, xgrid.flatten(),
                                       ygrid.flatten())
    lon = np.array(lon).reshape(xgrid.shape)
    lat = np.array(lat).reshape(ygrid.shape)

    inside_bounds = np.logical_and(
        np.logical_and(lon >= bounds.left, lon <= bounds.right),
        np.logical_and(lat >= bounds.bottom, lat <= bounds.top)
    )
    for v in warped.data_vars:
        if not set(warped[v].dims).issuperset({'y', 'x'}):
            continue
        dim_order = tuple(set(warped[v].dims) - {'y', 'x'}) + ('y', 'x')
        values = warped[v].transpose(*dim_order, transpose_coords=True).values
        # Check that pixels strictly inside the original bounds are not NaN
        assert np.isnan(values[..., inside_bounds]).sum() == 0
        # Pixel outside of the original bounds should be mostly NaN,
        # although some pixels near the edges may have values.
        outside_values = values[..., ~inside_bounds]
        assert np.isnan(outside_values).sum() / outside_values.size > 0.5
Exemple #3
0
def test_reprojection_with_target(generator):
    src_crs = epsg4326
    dst_crs = sinusoidal
    ds = generator(crs=src_crs)
    src_bounds = warp.get_bounds(ds)
    dst_bounds_latlon = BoundingBox(
        left=src_bounds.left - 1,
        bottom=src_bounds.bottom - 1,
        right=src_bounds.right + 1,
        top=src_bounds.top + 1,
    )
    dst_bounds = BoundingBox(*rasterio.warp.transform_bounds(
        src_crs, dst_crs, **dst_bounds_latlon._asdict()
    ))
    dst_width, dst_height = 35, 21
    resx = (dst_bounds.right - dst_bounds.left) / (dst_width - 1)
    resy = (dst_bounds.bottom - dst_bounds.top) / (dst_height - 1)
    res = (abs(resx), abs(resy))
    xoff = dst_bounds.left
    yoff = dst_bounds.top
    dst_transform = Affine(resx, 0, xoff, 0, resy, yoff)

    target = generator(
        dims={'x': dst_width, 'y': dst_height, 'time': 1},
        extent=dst_bounds, crs=dst_crs
    )

    projected = [
        warp.Reprojection(crs=dst_crs, transform=dst_transform,
                          width=dst_width, height=dst_height).apply(ds),
        warp.Reprojection(crs=dst_crs, extent=dst_bounds,
                          res=res).apply(ds),
        warp.Reprojection(crs=dst_crs, extent=dst_bounds,
                          width=dst_width, height=dst_height).apply(ds),
        warp.Reprojection(target=target).apply(ds),
    ]
    for i, proj in enumerate(projected[1:]):
        print(i)
        xr_assert_equal(proj, projected[0])
        assert_almost_equal(warp.get_resolution(proj), res)
        assert_almost_equal(warp.get_bounds(proj), dst_bounds)
        assert_almost_equal(warp.get_transform(proj), dst_transform)
        assert_equal_crs(warp.get_crs(proj), dst_crs)
Exemple #4
0
def test_reprojection_with_src_crs():
    src_crs = epsg4326
    dst_crs = sinusoidal
    # Set up test dataset with and without CRS information
    ds = generate_test_dataset(crs=src_crs)
    assert_equal_crs(src_crs, ds.nd.crs)
    ds_nocrs = ds.copy()
    del ds_nocrs.attrs['crs']
    assert ds_nocrs.nd.crs is None

    with assert_raises_regex(
            CRSError,
            "Could not infer projection from input data. "
            "Please provide the parameter `src_crs`."):
        warp.Reprojection(dst_crs=dst_crs).apply(ds_nocrs)

    xr_assert_equal(
        warp.Reprojection(dst_crs=dst_crs).apply(ds),
        warp.Reprojection(src_crs=src_crs, dst_crs=dst_crs).apply(ds_nocrs)
    )
Exemple #5
0
def test_reproject_coordinates():
    ds = generate_test_dataset(crs=epsg4326)
    dims = warp.get_dim_sizes(ds)
    ds.coords['lat'] = ds['y']
    ds.coords['lon'] = ds['x']
    ds.coords['altitude'] = (('y', 'x'),
                             np.zeros((dims['y'], dims['x'])))
    proj = warp.Reprojection(crs=sinusoidal)
    warped = proj.apply(ds)
    for c in ds.coords:
        if c in ['lat', 'lon']:
            continue
        assert c in warped.coords
        assert_equal(sorted(ds[c].dims), sorted(warped[c].dims))
Exemple #6
0
def test_reproject_one_dimensional_coords():
    ds = generate_test_dataset(crs=epsg4326)
    # Add coordinates that are not dimensions
    ds.coords['longitude'] = (('x',), ds.x.values)
    ds.coords['latitude'] = (('y',), ds.y.values)

    warped = warp.Reprojection(
        crs=warp.get_crs(ds), width=15, height=15,
        resampling=rasterio.warp.Resampling.bilinear
    ).apply(ds)

    # Check that xvar and yvar are still proportional to longitude
    # and latitude
    for coord, dim in [
        ('longitude', 'x'), ('latitude', 'y')
    ]:
        assert_array_almost_equal(
            warped.coords[coord], warped.coords[dim])
Exemple #7
0
def test_reproject_with_extra_dims(dims):
    crs1 = warp._parse_crs('epsg:4326')
    crs2 = warp._parse_crs('epsg:3395')
    ds = generate_test_dataset(
        dims=dims, crs=crs1
    )

    proj = warp.Reprojection(crs=crs2)
    reprojected = proj.apply(ds)

    # Check that a reprojected slice of the dataset is the same as
    # the slice of the reprojection of the entire dataset.
    slices = [
        {'band': 3},
        {'time': slice(1, 3)}
    ]
    for s in slices:
        xr_assert_equal(
            proj.apply(ds.isel(**s)),
            reprojected.isel(**s)
        )
Exemple #8
0
def test_reproject_one_dimensional_vars():
    ds = generate_test_dataset(crs=epsg4326)
    ds['xvar'] = (('x',), ds.x.values * 10)
    ds['yvar'] = (('y',), ds.y.values * 10)
    ds['timevar'] = (('time',), np.random.rand(ds.dims['time']))

    warped = warp.Reprojection(
        crs=sinusoidal, resampling=rasterio.warp.Resampling.bilinear
    ).apply(ds)

    xr_assert_equal(
        warped['timevar'], ds['timevar'])

    # Check that xvar and yvar are still proportional to longitude
    # and latitude
    for v, coord in [
        ('xvar', 'lon'), ('yvar', 'lat')
    ]:
        ratios = warped[v].values / warped[coord].values
        print(v, coord)
        print(np.nanmin(ratios), np.nanmax(ratios), np.nanstd(ratios))
        # There is quite a bit of error, for now accept relatively
        # high error.
        assert np.nanstd(ratios) < 1.5
Exemple #9
0
def test_get_common_extent():
    bounds = [
        (-10.0, 50.0, 0.0, 60.0),
        (-12.0, 40.0, -2.0, 52.0),
        (-13.0, 50.0, -3.0, 60.0),
        (-9.0, 51.0, 1.0, 61.0)
    ]
    common_extent = (-13.0, 40.0, 1.0, 61.0)
    datasets = [generate_test_dataset(extent=ext) for ext in bounds]

    # Reproject such that the projected bounds change,
    # but the extent remains the same:
    proj = warp.Reprojection(crs=sinusoidal)
    datasets_sinu = [proj.apply(ds) for ds in datasets]

    common_bounds = warp.get_common_bounds(datasets_sinu)
    expected_result = BoundingBox(*rasterio.warp.transform_bounds(
        sinusoidal, epsg4326, **common_bounds._asdict()
    ))

    assert_raises(AssertionError, assert_equal,
                  common_bounds, common_extent)
    assert_almost_equal(warp.get_common_extent(datasets_sinu),
                        expected_result)
Exemple #10
0
def test_reprojection(name, kwargs):
    ds = generate_test_dataset(**kwargs)
    crs = warp._parse_crs('epsg:4326')
    proj = warp.Reprojection(crs=crs)
    reprojected = proj.apply(ds)
    assert_equal_crs(crs, warp.get_crs(reprojected))