def test_reprojection_nan_values(): src_crs = epsg4326 dst_crs = sinusoidal ds = generate_test_dataset(crs=src_crs) bounds = get_bounds(ds) proj = 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).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
def test_get_resolution(name, kwargs): ds = generate_test_dataset(**kwargs) res = get_resolution(ds) bounds = get_bounds(ds) resx = abs(bounds.right - bounds.left) / (ncols(ds) - 1) resy = abs(bounds.bottom - bounds.top) / (nrows(ds) - 1) assert_almost_equal(res, (resx, resy))
def test_alignment(tmpdir, extent, from_files): datapath = tmpdir.mkdir('data') path = tmpdir.mkdir('aligned') 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) ] datasets = [generate_test_dataset(extent=ext) for ext in bounds] if extent is None: common_bounds = warp.get_common_bounds(datasets) else: common_bounds = extent files = [str(datapath.join('data_%d.nc' % i)) for i in range(len(datasets))] if from_files: for ds, f in zip(datasets, files): to_netcdf(ds, f) datasets = files warp.Alignment(extent=extent).apply(datasets, path=str(path)) aligned = [open_dataset(str(f)) for f in path.listdir()] for ds in aligned: assert_equal(warp.get_bounds(ds), common_bounds) assert_equal( warp.get_transform(ds), warp.get_transform(aligned[0]) ) xr_assert_equal(ds['x'], aligned[0]['x']) xr_assert_equal(ds['y'], aligned[0]['y'])
def test_get_geometry(generator, bounds, src_crs, dst_crs): ds = generator(extent=bounds, crs=src_crs) box = shapely.geometry.box(*warp.get_bounds(ds)) assert_equal( warp.get_geometry(ds, crs=src_crs), box) geom = warp.get_geometry(ds, crs=dst_crs) try: # pyproj >= 2.1.0 project = pyproj.Transformer.from_crs( src_crs, dst_crs, always_xy=True).transform inverse_project = pyproj.Transformer.from_crs( dst_crs, src_crs, always_xy=True).transform except Exception: # pyproj < 2.1 project = partial( pyproj.transform, warp._to_pyproj(src_crs), warp._to_pyproj(dst_crs)) inverse_project = partial( pyproj.transform, warp._to_pyproj(dst_crs), warp._to_pyproj(src_crs)) expected = shapely.ops.transform(project, box) assert_equal(geom, expected) expected_inverse = shapely.ops.transform(inverse_project, geom) assert expected_inverse.equals_exact(box, tolerance=1e-6)
def test_get_bounds_from_metadata(): ds = generate_test_dataset() assert_equal( warp._get_bounds_from_metadata(ds), warp.get_bounds(ds) ) del ds.attrs['transform'] assert_equal( warp._get_bounds_from_metadata(ds), warp.get_bounds(ds) ) del ds.attrs['bounds'] assert_equal( warp._get_bounds_from_metadata(ds), None )
def test_equal_datasets(): ds0 = open_dataset(slc_files[0]) for f in slc_files[1:]: ds = open_dataset(f) assert_equal(ds0['x'].values, ds['x'].values, 'x coordinates are not equal') assert_equal(ds0['y'].values, ds['y'].values, 'y coordinates are not equal') assert_equal(get_transform(ds0), get_transform(ds), 'transforms are not equal') assert_equal_crs(get_crs(ds0), get_crs(ds), 'CRS are not equal') assert_equal(get_resolution(ds0), get_resolution(ds), 'resolutions are not equal') assert_equal(get_bounds(ds0), get_bounds(ds), 'bounds are not equal') assert_equal(get_extent(ds0), get_extent(ds), 'extents are not equal') ds.close() ds0.close()
def test_get_transform(name, kwargs): ds = generate_test_dataset(**kwargs) bounds = get_bounds(ds) resx = (bounds.right - bounds.left) / (ds.dims['x'] - 1) resy = (bounds.bottom - bounds.top) / (ds.dims['y'] - 1) xoff = bounds.left yoff = bounds.top transform = Affine(resx, 0, xoff, 0, resy, yoff) assert_equal(get_transform(ds), transform)
def test_reproject(generator): src_crs = epsg4326 dst_crs = sinusoidal ds = generator(crs=src_crs) src_bounds = 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) projected = [ _reproject(ds, dst_crs=dst_crs, dst_transform=dst_transform, width=dst_width, height=dst_height), _reproject(ds, dst_crs=dst_crs, dst_transform=dst_transform, extent=dst_bounds), _reproject(ds, dst_crs=dst_crs, extent=dst_bounds, res=res), _reproject(ds, dst_crs=dst_crs, extent=dst_bounds, width=dst_width, height=dst_height) ] for proj in projected[1:]: xr_assert_equal(proj, projected[0]) assert_almost_equal(get_resolution(proj), res) assert_almost_equal(get_bounds(proj), dst_bounds) assert_almost_equal(get_transform(proj), dst_transform) assert_equal_crs(get_crs(proj), dst_crs)
def test_rasterize(tmpdir): path = str(tmpdir.join('polygons.shp')) ds = generate_test_dataset(dims=dict(x=100, y=100, time=5)) df = generate_test_geodataframe() schema = gpd.io.file.infer_schema(df) schema['properties']['date'] = 'date' df.to_file(path, schema=schema) # Rasterize raster = vector.rasterize(path, ds) # Check that the raster contains all fields as variables assert set(raster.data_vars).union({'geometry'}) == set(df.columns) # Check dtypes assert np.issubdtype(raster.float.dtype, np.floating) assert np.issubdtype(raster.integer.dtype, np.signedinteger) assert np.issubdtype(raster.category.dtype, np.signedinteger) # Check that extent, projection etc. are identical to the reference raster assert_equal(warp.get_bounds(raster), warp.get_bounds(ds)) assert_equal_crs(warp.get_crs(raster), warp.get_crs(ds)) assert_equal(warp.get_transform(raster), warp.get_transform(ds)) # Check raster content shape = (ds.dims['y'], ds.dims['x']) transform = warp.get_transform(ds) for i, row in df.iterrows(): poly = row['geometry'] mask = rasterio.features.rasterize([poly], out_shape=shape, transform=transform) # Erode mask to avoid edge effects mask = ndimage.morphology.binary_erosion(mask) == 1 for v in raster.data_vars: if 'legend' in raster[v].attrs: expected = sorted(raster[v].attrs['legend'], key=lambda x: x[1] == str(row[v]))[-1][0] else: expected = row[v] values = raster[v].isel(time=0).values values[mask] assert_allclose(values[mask], expected)
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)
def test_get_bounds_dataarray(): bounds = (-10.0, 50.0, 0.0, 60.0) da = generate_test_dataarray(extent=bounds) assert_equal(bounds, get_bounds(da))
def test_get_bounds_dataset(): bounds = (-10.0, 50.0, 0.0, 60.0) ds = generate_test_dataset(extent=bounds) assert_equal(bounds, get_bounds(ds))