コード例 #1
0
def test_viewshed_invalid_y_view():
    OBSERVER_X = 0
    OBSERVER_Y = ys[-1] + 1
    with pytest.raises(Exception) as e_info:  # NOQA
        viewshed(raster=empty_agg,
                 x=OBSERVER_X,
                 y=OBSERVER_Y,
                 observer_elev=10)
コード例 #2
0
def test_viewshed_invalid_x_view():
    OBSERVER_X = xs[0] - 1
    OBSERVER_Y = 0
    with pytest.raises(Exception) as e_info:  # NOQA
        viewshed(raster=empty_agg,
                 x=OBSERVER_X,
                 y=OBSERVER_Y,
                 observer_elev=10)
コード例 #3
0
def test_viewshed_invalid_y_view(empty_agg):
    ys = empty_agg.coords['y'].values
    OBSERVER_X = 0
    OBSERVER_Y = ys[-1] + 1
    with pytest.raises(Exception):
        viewshed(raster=empty_agg,
                 x=OBSERVER_X,
                 y=OBSERVER_Y,
                 observer_elev=10)
コード例 #4
0
def test_viewshed_invalid_x_view(empty_agg):
    xs = empty_agg.coords['x'].values
    OBSERVER_X = xs[0] - 1
    OBSERVER_Y = 0
    with pytest.raises(Exception):
        viewshed(raster=empty_agg,
                 x=OBSERVER_X,
                 y=OBSERVER_Y,
                 observer_elev=10)
コード例 #5
0
def test_viewshed_flat(backend, observer_elev, target_elev):
    if backend == "cupy":
        if not has_rtx():
            pytest.skip("rtxpy not available")
        else:
            import cupy as cp

    x, y = 0, 0
    ny, nx = 5, 4
    arr = np.full((ny, nx), 1.3)
    xs = np.arange(nx) * 0.5
    ys = np.arange(ny) * 1.5
    if backend == "cupy":
        arr = cp.asarray(arr)
    xarr = xa.DataArray(arr, coords=dict(x=xs, y=ys), dims=["y", "x"])
    v = viewshed(xarr,
                 x=x,
                 y=y,
                 observer_elev=observer_elev,
                 target_elev=target_elev)
    if backend == "cupy":
        v.data = cp.asnumpy(v.data)
    xs2, ys2 = np.meshgrid(xs, ys)
    d_vert = observer_elev - target_elev
    d_horz = np.sqrt((xs2 - x)**2 + (ys2 - y)**2)
    angle = np.rad2deg(np.arctan2(d_horz, d_vert))
    # Don't want to compare value under observer.
    angle[0, 0] = v.data[0, 0]
    if backend == "numpy":
        np.testing.assert_allclose(v.data, angle)
    else:
        # Should do better with viewshed gpu output angles.
        mask = (v.data < 90)
        np.testing.assert_allclose(v.data[mask], angle[mask], atol=0.03)
コード例 #6
0
def test_viewshed_output_properties():
    for obs_elev in OBS_ELEVS:
        OBSERVER_X = xs[0]
        OBSERVER_Y = ys[0]
        v = viewshed(raster=empty_agg,
                     x=OBSERVER_X,
                     y=OBSERVER_Y,
                     observer_elev=obs_elev)

        assert v.shape[0] == empty_agg.shape[0]
        assert v.shape[1] == empty_agg.shape[1]
        assert isinstance(v, xa.DataArray)
        assert isinstance(v.values, np.ndarray)
        assert type(v.values[0, 0]) == np.float64
コード例 #7
0
def test_viewshed_output_properties():

    # add crs for tests
    empty_agg_crs = _add_EPSG4326_crs_to_da(empty_agg)

    for obs_elev in OBS_ELEVS:
        OBSERVER_X = xs[0]
        OBSERVER_Y = ys[0]
        v = viewshed(raster=empty_agg_crs,
                     x=OBSERVER_X,
                     y=OBSERVER_Y,
                     observer_elev=obs_elev)

        assert v.shape[0] == empty_agg_crs.shape[0]
        assert v.shape[1] == empty_agg_crs.shape[1]
        assert isinstance(v, xa.DataArray)
        assert isinstance(v.values, np.ndarray)
        assert type(v.values[0, 0]) == np.float64

        # crs tests
        assert v.attrs == empty_agg_crs.attrs
        for coord in empty_agg_crs.coords:
            assert np.all(v[coord] == empty_agg_crs[coord])
コード例 #8
0
 def time_viewshed(self, nx, type):
     viewshed(self.xr, x=self.x, y=self.y, observer_elev=1.0)
コード例 #9
0
def test_viewshed(empty_agg):
    H, W = empty_agg.shape

    # coordinates
    xs = empty_agg.coords['x'].values
    ys = empty_agg.coords['y'].values

    # define some values for observer's elevation to test
    OBS_ELEVS = [-1, 0, 1]
    TERRAIN_ELEV_AT_VP = [-1, 0, 1]

    # check if a matrix is symmetric
    def check_symmetric(matrix, rtol=1e-05, atol=1e-08):
        return np.allclose(matrix, matrix.T, rtol=rtol, atol=atol)

    def get_matrices(y, x, height, width):
        # indexing 0 1 ... height-1 and 0 1 ... width-1
        height = height - 1
        width = width - 1

        # find first matrix's diagonal
        tmp = min(y, x)
        f_top_y, f_left_x = y - tmp, x - tmp

        tmp = min(height - y, width - x)
        f_bottom_y, f_right_x = y + tmp, x + tmp

        # find second matrix's antidiagonal
        tmp = min(y, width - x)
        s_top_y, s_right_x = y - tmp, x + tmp

        tmp = min(height - y, x)
        s_bottom_y, s_left_x = y + tmp, x - tmp

        return ((f_top_y, f_left_x, f_bottom_y + 1, f_right_x + 1),
                (s_top_y, s_left_x, s_bottom_y + 1, s_right_x + 1))

    # test on 3 scenarios:
    #   empty image.
    #   image with all 0s, except 1 cell with a negative value.
    #   image with all 0s, except 1 cell with a positive value.

    # for each scenario:
    #   if not empty image,
    #      observer is located at the same position as the non zero value.
    #   observer elevation can be: negative, zero, or positive.

    # assertion:
    #   angle at viewpoint is always 180.
    #   when the observer is above the terrain, all cells are visible.
    #   the symmetric property of observer's visibility.

    for obs_elev in OBS_ELEVS:
        for elev_at_vp in TERRAIN_ELEV_AT_VP:
            for col_id, x in enumerate(xs):
                for row_id, y in enumerate(ys):

                    empty_agg.values[row_id, col_id] = elev_at_vp
                    v = viewshed(raster=empty_agg,
                                 x=x,
                                 y=y,
                                 observer_elev=obs_elev)

                    # validate output properties
                    general_output_checks(empty_agg, v)

                    # angle at viewpoint is always 180
                    assert v[row_id, col_id] == 180

                    if obs_elev + elev_at_vp >= 0 and obs_elev >= abs(
                            elev_at_vp):
                        # all cells are visible
                        assert (v.values > -1).all()

                    b1, b2 = get_matrices(row_id, col_id, H, W)
                    m1 = v.values[b1[0]:b1[2], b1[1]:b1[3]]
                    m2 = v.values[b2[0]:b2[2], b2[1]:b2[3]]

                    assert check_symmetric(m1)
                    assert check_symmetric(m2[::-1])

                    # empty image for next uses
                    empty_agg.values[row_id, col_id] = 0