示例#1
0
def test_numpy_equals_dask():

    # input data
    data = np.asarray(
        [[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
         [1584.8767, 1584.8767, 1585.0546, 1585.2324, 1585.2324, 1585.2324],
         [1585.0546, 1585.0546, 1585.2324, 1585.588, 1585.588, 1585.588],
         [1585.2324, 1585.4102, 1585.588, 1585.588, 1585.588, 1585.588],
         [1585.588, 1585.588, 1585.7659, 1585.7659, 1585.7659, 1585.7659],
         [1585.7659, 1585.9437, 1585.7659, 1585.7659, 1585.7659, 1585.7659],
         [1585.9437, 1585.9437, 1585.9437, 1585.7659, 1585.7659, 1585.7659]],
        dtype=np.float32)

    small_numpy_based_data_array = xr.DataArray(data,
                                                attrs={'res': (10.0, 10.0)})
    small_das_based_data_array = xr.DataArray(da.from_array(data,
                                                            chunks=(2, 2)),
                                              attrs={'res': (10.0, 10.0)})

    numpy_result = aspect(small_numpy_based_data_array,
                          name='numpy_slope',
                          use_cuda=False)
    dask_result = aspect(small_das_based_data_array,
                         name='dask_slope',
                         use_cuda=False)
    dask_result.data = dask_result.data.compute()

    assert np.isclose(numpy_result, dask_result, equal_nan=True).all()
示例#2
0
def test_cpu_equals_gpu():

    import cupy

    small_da = xr.DataArray(INPUT_DATA, attrs={'res': (10.0, 10.0)})
    small_da_cupy = xr.DataArray(cupy.asarray(INPUT_DATA),
                                 attrs={'res': (10.0, 10.0)})

    # aspect by xrspatial
    cpu = aspect(small_da, name='aspect_agg')
    gpu = aspect(small_da_cupy, name='aspect_agg')
    general_output_checks(small_da_cupy, gpu)
    np.testing.assert_allclose(cpu.data, gpu.data.get(), equal_nan=True)
示例#3
0
def test_numpy_equals_dask():
    small_numpy_based_data_array = xr.DataArray(INPUT_DATA,
                                                attrs={'res': (10.0, 10.0)})
    small_dask_based_data_array = xr.DataArray(da.from_array(INPUT_DATA,
                                                             chunks=(2, 2)),
                                               attrs={'res': (10.0, 10.0)})

    numpy_result = aspect(small_numpy_based_data_array, name='numpy_result')
    dask_result = aspect(small_dask_based_data_array, name='dask_result')
    general_output_checks(small_dask_based_data_array, dask_result)
    np.testing.assert_allclose(numpy_result.data,
                               dask_result.data.compute(),
                               equal_nan=True)
示例#4
0
def test_numpy_equals_cupy():

    import cupy

    small_da = xr.DataArray(INPUT_DATA, attrs={'res': (10.0, 10.0)})
    small_da_cupy = xr.DataArray(cupy.asarray(INPUT_DATA),
                                 attrs={'res': (10.0, 10.0)})

    # aspect by xrspatial
    cpu = aspect(small_da, name='aspect_agg')
    gpu = aspect(small_da_cupy, name='aspect_agg')

    assert isinstance(gpu.data, cupy.ndarray)
    assert np.isclose(cpu, gpu, equal_nan=True).all()
示例#5
0
def test_numpy_equals_dask():
    small_numpy_based_data_array = xr.DataArray(INPUT_DATA,
                                                attrs={'res': (10.0, 10.0)})
    small_dask_based_data_array = xr.DataArray(da.from_array(INPUT_DATA,
                                                             chunks=(2, 2)),
                                               attrs={'res': (10.0, 10.0)})

    numpy_result = aspect(small_numpy_based_data_array, name='numpy_result')
    dask_result = aspect(small_dask_based_data_array, name='dask_result')

    assert isinstance(dask_result.data, da.Array)

    dask_result.data = dask_result.data.compute()
    assert np.isclose(numpy_result, dask_result, equal_nan=True).all()
示例#6
0
def test_numpy_equals_qgis():

    small_da = xr.DataArray(INPUT_DATA, attrs={'res': (10.0, 10.0)})
    xrspatial_aspect = aspect(small_da, name='numpy_aspect')

    general_output_checks(small_da, xrspatial_aspect)
    assert xrspatial_aspect.name == 'numpy_aspect'

    # validate output values
    xrspatial_vals = xrspatial_aspect.data[1:-1, 1:-1]
    qgis_vals = QGIS_OUTPUT[1:-1, 1:-1]
    # aspect is nan if nan input
    # aspect is invalid (-1) if slope equals 0
    # otherwise aspect are from 0 - 360
    np.testing.assert_allclose(xrspatial_vals, qgis_vals, equal_nan=True)

    # nan edge effect
    xrspatial_edges = [
        xrspatial_aspect.data[0, :],
        xrspatial_aspect.data[-1, :],
        xrspatial_aspect.data[:, 0],
        xrspatial_aspect.data[:, -1],
    ]
    for edge in xrspatial_edges:
        np.testing.assert_allclose(edge,
                                   np.full(edge.shape, np.nan),
                                   equal_nan=True)
示例#7
0
def test_numpy_equals_qgis():

    small_da = xr.DataArray(INPUT_DATA, attrs={'res': (10.0, 10.0)})
    xrspatial_aspect = aspect(small_da, name='numpy_aspect')

    # validate output attributes
    assert xrspatial_aspect.dims == small_da.dims
    assert xrspatial_aspect.attrs == small_da.attrs
    assert xrspatial_aspect.shape == small_da.shape
    assert xrspatial_aspect.name == 'numpy_aspect'
    for coord in small_da.coords:
        assert np.all(xrspatial_aspect[coord] == small_da[coord])

    # TODO: We shouldn't ignore edges!
    # validate output values
    # ignore border edges
    xrspatial_vals = xrspatial_aspect.values[1:-1, 1:-1]
    qgis_vals = QGIS_OUTPUT[1:-1, 1:-1]

    # TODO: use np.is_close instead
    # set a tolerance of 1e-4
    # aspect is nan if nan input
    # aspect is invalid (nan) if slope equals 0
    # otherwise aspect are from 0 - 360
    assert np.isclose(xrspatial_vals, qgis_vals, equal_nan=True).all()
示例#8
0
def _numpy_equals_dask_cupy():

    # NOTE: Dask + GPU code paths don't currently work because of
    # dask casting cupy arrays to numpy arrays during
    # https://github.com/dask/dask/issues/4842

    import cupy

    cupy_data = cupy.asarray(INPUT_DATA)
    dask_cupy_data = da.from_array(cupy_data, chunks=(3, 3))

    small_da = xr.DataArray(INPUT_DATA, attrs={'res': (10.0, 10.0)})
    cpu = aspect(small_da, name='numpy_result')

    small_dask_cupy = xr.DataArray(dask_cupy_data, attrs={'res': (10.0, 10.0)})
    gpu = aspect(small_dask_cupy, name='cupy_result')

    assert is_cupy_backed(gpu)
    assert np.isclose(cpu, gpu, equal_nan=True).all()
示例#9
0
def test_aspect_transfer_function():
    """
    Assert aspect transfer function
    """
    da = xr.DataArray(data_gaussian, dims=['y', 'x'], attrs={'res': 1})
    da_aspect = aspect(da)
    assert da_aspect.dims == da.dims
    assert da_aspect.coords == da.coords
    assert da_aspect.attrs == da.attrs
    assert da.shape == da_aspect.shape
    assert pytest.approx(da_aspect.data.max(), .1) == 360.
    assert pytest.approx(da_aspect.data.min(), .1) == 0.
示例#10
0
def test_summarize_terrain(random_data):
    test_terrain = create_test_raster(random_data, name='myterrain')
    summarized_ds = summarize_terrain(test_terrain)
    variables = [v for v in summarized_ds]
    should_have = ['myterrain',
                   'myterrain-slope',
                   'myterrain-curvature',
                   'myterrain-aspect']
    assert variables == should_have

    np.testing.assert_allclose(summarized_ds['myterrain-slope'], slope(test_terrain))
    np.testing.assert_allclose(summarized_ds['myterrain-curvature'], curvature(test_terrain))
    np.testing.assert_allclose(summarized_ds['myterrain-aspect'], aspect(test_terrain))
示例#11
0
def test_aspect_gpu_equals_cpu():

    # input data
    data = np.asarray(
        [[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
         [1584.8767, 1584.8767, 1585.0546, 1585.2324, 1585.2324, 1585.2324],
         [1585.0546, 1585.0546, 1585.2324, 1585.588, 1585.588, 1585.588],
         [1585.2324, 1585.4102, 1585.588, 1585.588, 1585.588, 1585.588],
         [1585.588, 1585.588, 1585.7659, 1585.7659, 1585.7659, 1585.7659],
         [1585.7659, 1585.9437, 1585.7659, 1585.7659, 1585.7659, 1585.7659],
         [1585.9437, 1585.9437, 1585.9437, 1585.7659, 1585.7659, 1585.7659]],
        dtype=np.float32)

    small_da = xr.DataArray(data, attrs={'res': (10.0, 10.0)})

    # aspect by xrspatial
    xrspatial_aspect_cpu = aspect(small_da, name='aspect_agg', use_cuda=False)
    xrspatial_aspect_gpu = aspect(small_da, name='aspect_agg', use_cuda=True)

    assert np.isclose(xrspatial_aspect_cpu,
                      xrspatial_aspect_gpu,
                      equal_nan=True).all()
示例#12
0
def test_aspect_against_qgis():
    # input data
    data = np.asarray(
        [[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
         [1584.8767, 1584.8767, 1585.0546, 1585.2324, 1585.2324, 1585.2324],
         [1585.0546, 1585.0546, 1585.2324, 1585.588, 1585.588, 1585.588],
         [1585.2324, 1585.4102, 1585.588, 1585.588, 1585.588, 1585.588],
         [1585.588, 1585.588, 1585.7659, 1585.7659, 1585.7659, 1585.7659],
         [1585.7659, 1585.9437, 1585.7659, 1585.7659, 1585.7659, 1585.7659],
         [1585.9437, 1585.9437, 1585.9437, 1585.7659, 1585.7659, 1585.7659]],
        dtype=np.float32)
    small_da = xr.DataArray(data, attrs={'res': (10.0, 10.0)})

    # aspect by QGIS
    qgis_aspect = np.asarray(
        [[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
         [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
         [330.94687, 335.55496, 320.70786, 330.94464, 0., 0.],
         [333.43494, 333.43494, 329.03394, 341.56897, 0., 18.434948],
         [338.9621, 338.20062, 341.56506, 0., 0., 45.],
         [341.56506, 351.8699, 26.56505, 45., -1., 90.],
         [351.86676, 11.306906, 45., 45., 45., 108.431015]],
        dtype=np.float32)

    # aspect by xrspatial
    xrspatial_aspect = aspect(small_da, name='aspect_agg', use_cuda=False)

    # validate output attributes
    assert xrspatial_aspect.dims == small_da.dims
    assert xrspatial_aspect.attrs == small_da.attrs
    assert xrspatial_aspect.shape == small_da.shape
    assert xrspatial_aspect.name == 'aspect_agg'
    for coord in small_da.coords:
        assert np.all(xrspatial_aspect[coord] == small_da[coord])

    # validate output values
    # ignore border edges
    xrspatial_vals = xrspatial_aspect.values[1:-1, 1:-1]
    qgis_vals = qgis_aspect[1:-1, 1:-1]
    # set a tolerance of 1e-4
    # aspect is nan if nan input
    # aspect is invalid (nan) if slope equals 0
    # otherwise aspect are from 0 - 360
    assert ((np.isnan(xrspatial_vals) & np.isnan(qgis_vals)) |
            (np.isnan(xrspatial_vals) & (qgis_vals == -1)) |
            (abs(xrspatial_vals - qgis_vals) <= 1e-4)).all()

    assert (np.isnan(xrspatial_vals) |
            ((0 <= xrspatial_vals) & (xrspatial_vals <= 360) |
             (xrspatial_vals == -1))).all()
示例#13
0
def test_aspect_transfer_function():
    """
    Assert aspect transfer function
    """
    da = xr.DataArray(data_gaussian, dims=['y', 'x'], attrs={'res': 1})
    da_aspect = aspect(da, use_cuda=False)
    # default name
    assert da_aspect.name == 'aspect'
    assert da_aspect.dims == da.dims
    assert da_aspect.attrs == da.attrs
    assert da.shape == da_aspect.shape
    for coord in da.coords:
        assert np.all(da[coord] == da_aspect[coord])
    assert pytest.approx(np.nanmax(da_aspect.data), .1) == 360.
    assert pytest.approx(np.nanmin(da_aspect.data), .1) == -1.
示例#14
0
def test_numpy_equals_qgis(qgis_output):
    numpy_agg = input_data()
    xrspatial_aspect = aspect(numpy_agg, name='numpy_aspect')

    general_output_checks(numpy_agg, xrspatial_aspect, verify_dtype=True)
    assert xrspatial_aspect.name == 'numpy_aspect'

    xrspatial_vals = xrspatial_aspect.data[1:-1, 1:-1]
    qgis_vals = qgis_output[1:-1, 1:-1]
    # aspect is nan if nan input
    # aspect is invalid (-1) if slope equals 0
    # otherwise aspect are from 0 to 360
    np.testing.assert_allclose(xrspatial_vals, qgis_vals, equal_nan=True)
    # nan edge effect
    assert_nan_edges_effect(xrspatial_aspect)
示例#15
0
def test_cupy_equals_qgis():

    import cupy

    small_da = xr.DataArray(INPUT_DATA, attrs={'res': (10.0, 10.0)})
    small_da_cupy = xr.DataArray(cupy.asarray(INPUT_DATA),
                                 attrs={'res': (10.0, 10.0)})
    xrspatial_aspect = aspect(small_da_cupy, name='aspect_agg')

    # validate output attributes
    assert xrspatial_aspect.dims == small_da.dims
    assert xrspatial_aspect.attrs == small_da.attrs
    assert xrspatial_aspect.shape == small_da.shape
    assert xrspatial_aspect.name == 'aspect_agg'
    for coord in small_da.coords:
        assert np.all(xrspatial_aspect[coord] == small_da[coord])

    # TODO: We shouldn't ignore edges!
    # validate output values
    # ignore border edges
    xrspatial_vals = xrspatial_aspect.values[1:-1, 1:-1]
    qgis_vals = QGIS_OUTPUT[1:-1, 1:-1]
    assert np.isclose(xrspatial_vals, qgis_vals, equal_nan=True).all()
示例#16
0
def summarize_terrain(terrain: xr.DataArray):
    """
    Calculates slope, aspect, and curvature of an elevation terrain and return a dataset
    of the computed data.

    Parameters
    ----------
    terrain: xarray.DataArray
        2D NumPy, CuPy, or Dask with NumPy-backed xarray DataArray of elevation values.

    Returns
    -------
    summarized_terrain: xarray.Dataset
        Dataset with slope, aspect, curvature variables with a naming convention of
        `terrain.name-variable_name`

    Examples
    --------
    .. sourcecode:: python

        >>> import numpy as np
        >>> import xarray as xr
        >>> from xrspatial.analytics import summarize_terrain
        >>> data = np.array([
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 1, 0, 0, -1, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0]], dtype=np.float64)
        >>> raster = xr.DataArray(data, name='myraster', attrs={'res': (1, 1)})
        >>> summarized_terrain = summarize_terrain(raster)
        >>> summarized_terrain
        <xarray.Dataset>
        Dimensions:             (dim_0: 5, dim_1: 8)
        Dimensions without coordinates: dim_0, dim_1
        Data variables:
            myraster            (dim_0, dim_1) float64 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0
            myraster-slope      (dim_0, dim_1) float32 nan nan nan nan ... nan nan nan
            myraster-curvature  (dim_0, dim_1) float64 nan nan nan nan ... nan nan nan
            myraster-aspect     (dim_0, dim_1) float32 nan nan nan nan ... nan nan nan
        >>> summarized_terrain['myraster-slope']
        <xarray.DataArray 'myraster-slope' (dim_0: 5, dim_1: 8)>
        array([[      nan,       nan,       nan,       nan,       nan,       nan,       nan,   nan],
               [      nan, 10.024988, 14.036243, 10.024988, 10.024988, 14.036243, 10.024988,   nan],
               [      nan, 14.036243,  0.      , 14.036243, 14.036243,  0.      , 14.036243,   nan],
               [      nan, 10.024988, 14.036243, 10.024988, 10.024988, 14.036243, 10.024988,   nan],
               [      nan,       nan,       nan,       nan,       nan,       nan,       nan,   nan]], dtype=float32)  # noqa
        Dimensions without coordinates: dim_0, dim_1
        Attributes:
            res:      (1, 1)

        >>> summarized_terrain['myraster-curvature']
        <xarray.DataArray 'myraster-curvature' (dim_0: 5, dim_1: 8)>
        array([[  nan,   nan,   nan,   nan,   nan,   nan,   nan,   nan],
               [  nan,   -0., -100.,   -0.,   -0.,  100.,   -0.,   nan],
               [  nan, -100.,  400., -100.,  100., -400.,  100.,   nan],
               [  nan,   -0., -100.,   -0.,   -0.,  100.,   -0.,   nan],
               [  nan,   nan,   nan,   nan,   nan,   nan,   nan,   nan]])
        Dimensions without coordinates: dim_0, dim_1
        Attributes:
            res:      (1, 1)

        >>> summarized_terrain['myraster-aspect']
        <xarray.DataArray 'myraster-aspect' (dim_0: 5, dim_1: 8)>
        array([[ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan],
               [ nan, 315.,   0.,  45., 135., 180., 225.,  nan],
               [ nan, 270.,  -1.,  90.,  90.,  -1., 270.,  nan],
               [ nan, 225., 180., 135.,  45.,   0., 315.,  nan],
               [ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan]], dtype=float32)
        Dimensions without coordinates: dim_0, dim_1
        Attributes:
            res:      (1, 1)
    """

    if terrain.name is None:
        raise NameError('Requires xr.DataArray.name property to be set')

    ds = terrain.to_dataset()
    ds[f'{terrain.name}-slope'] = slope(terrain)
    ds[f'{terrain.name}-curvature'] = curvature(terrain)
    ds[f'{terrain.name}-aspect'] = aspect(terrain)
    return ds