Skip to content

Commit 3df3ec7

Browse files
authored
Test against QGIS, GDAL (#744)
Add QA tests against QGIS / GDAL
1 parent e47c278 commit 3df3ec7

File tree

10 files changed

+301
-134
lines changed

10 files changed

+301
-134
lines changed

xrspatial/tests/conftest.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,48 @@ def random_data(size, dtype):
88
data = rng.integers(-100, 100, size=size)
99
data = data.astype(dtype)
1010
return data
11+
12+
13+
@pytest.fixture
14+
def elevation_raster():
15+
elevation = np.array([
16+
[ np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
17+
[704.237 , 242.24084, 429.3324 , 779.8816 , 193.29506, 984.6926 ],
18+
[226.56795, 815.7483 , 290.6041 , 76.49687, 820.89716, 32.27882],
19+
[344.8238 , 256.34998, 806.8326 , 602.0442 , 721.1633 , 496.95636],
20+
[185.43515, 834.10425, 387.0871 , 716.0262 , 49.61273, 752.95483],
21+
[302.4271 , 151.49211, 442.32797, 358.4702 , 659.8187 , 447.1241 ],
22+
[148.04834, 819.2133 , 468.97913, 977.11694, 597.69666, 999.14185],
23+
[268.1575 , 625.96466, 840.26483, 448.28333, 859.2699 , 528.04095]
24+
], dtype=np.float32)
25+
return elevation
26+
27+
28+
@pytest.fixture
29+
def elevation_raster_no_nans():
30+
elevation = np.array([
31+
[870.5345 , 283.04907, 845.2779 , 51.21859, 990.8278 , 600.64545],
32+
[704.237 , 242.24084, 429.3324 , 779.8816 , 193.29506, 984.6926 ],
33+
[226.56795, 815.7483 , 290.6041 , 76.49687, 820.89716, 32.27882],
34+
[344.8238 , 256.34998, 806.8326 , 602.0442 , 721.1633 , 496.95636],
35+
[185.43515, 834.10425, 387.0871 , 716.0262 , 49.61273, 752.95483],
36+
[302.4271 , 151.49211, 442.32797, 358.4702 , 659.8187 , 447.1241 ],
37+
[148.04834, 819.2133 , 468.97913, 977.11694, 597.69666, 999.14185],
38+
[268.1575 , 625.96466, 840.26483, 448.28333, 859.2699 , 528.04095]
39+
], dtype=np.float32)
40+
return elevation
41+
42+
43+
@pytest.fixture
44+
def raster():
45+
data = np.array([
46+
[6., 7., 3., 4., 8., 1.],
47+
[4., 9., 7., 5., 6., 9.],
48+
[4., 3., 3., 1., 3., 7.],
49+
[3., 4., 9., 3., 7., 0.],
50+
[2., 1., 6., 5., 6., 2.],
51+
[4., 2., 4., 3., 8., 5.],
52+
[4., 1., 8., 5., 7., 0.],
53+
[7., 4., 6., 4., 1., 1.]
54+
], dtype=np.float32)
55+
return data

xrspatial/tests/general_checks.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,26 @@
1111

1212

1313
def create_test_raster(
14-
data, backend='numpy', name='myraster', dims=['y', 'x'], attrs=None, chunks=(3, 3)
14+
data,
15+
backend='numpy',
16+
name='myraster',
17+
dims=['y', 'x'],
18+
attrs={'res': (0.5, 0.5), 'crs': 'EPSG: 4326'},
19+
chunks=(3, 3)
1520
):
1621
raster = xr.DataArray(data, name=name, dims=dims, attrs=attrs)
17-
# set coords for test raster
18-
for i, dim in enumerate(dims):
19-
raster[dim] = np.linspace(0, data.shape[i] - 1, data.shape[i])
22+
23+
# default res if none provided
24+
res = (0.5, 0.5)
25+
if attrs is not None:
26+
if 'res' in attrs:
27+
res = attrs['res']
28+
# set coords for test raster, 2D coords only
29+
raster[dims[0]] = np.linspace((data.shape[0] - 1) * res[0], 0, data.shape[0])
30+
raster[dims[1]] = np.linspace(0, (data.shape[1] - 1) * res[1], data.shape[1])
31+
32+
raster[dims[0]] = np.linspace((data.shape[0] - 1)/2, 0, data.shape[0])
33+
raster[dims[1]] = np.linspace(0, (data.shape[1] - 1)/2, data.shape[1])
2034

2135
if has_cuda_and_cupy() and 'cupy' in backend:
2236
import cupy

xrspatial/tests/test_aspect.py

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,56 +7,46 @@
77
cuda_and_cupy_available, general_output_checks)
88

99

10-
def input_data(backend='numpy'):
11-
data = np.asarray([
12-
[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
13-
[1584.8767, 1584.8767, 1585.0546, 1585.2324, 1585.2324, 1585.2324],
14-
[1585.0546, 1585.0546, 1585.2324, 1585.588, 1585.588, 1585.588],
15-
[1585.2324, 1585.4102, 1585.588, 1585.588, 1585.588, 1585.588],
16-
[1585.588, 1585.588, 1585.7659, 1585.7659, 1585.7659, 1585.7659],
17-
[1585.7659, 1585.9437, 1585.7659, 1585.7659, 1585.7659, 1585.7659],
18-
[1585.9437, 1585.9437, 1585.9437, 1585.7659, 1585.7659, 1585.7659]],
19-
dtype=np.float32
20-
)
21-
raster = create_test_raster(data, backend, attrs={'res': (10.0, 10.0)})
10+
def input_data(data, backend='numpy'):
11+
raster = create_test_raster(data, backend)
2212
return raster
2313

2414

2515
@pytest.fixture
26-
def qgis_output():
16+
def qgis_aspect():
2717
result = np.array([
28-
[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
29-
[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
30-
[330.94687, 335.55496, 320.70786, 330.94464, 0., 0.],
31-
[333.43494, 333.43494, 329.03394, 341.56897, 0., 18.434948],
32-
[338.9621, 338.20062, 341.56506, 0., 0., 45.],
33-
[341.56506, 351.8699, 26.56505, 45., -1., 90.],
34-
[351.86676, 11.306906, 45., 45., 45., 108.431015]], dtype=np.float32
35-
)
18+
[ np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
19+
[ np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
20+
[233.19478 , 278.358 , 45.18813 , 306.6476 , 358.34296 , 106.45898 ],
21+
[267.7002 , 274.42487 , 11.035832, 357.9641 , 129.98279 , 50.069843],
22+
[263.18484 , 238.47426 , 196.37103 , 149.25227 , 187.85748 , 263.684 ],
23+
[266.63937 , 271.05124 , 312.09726 , 348.89136 , 351.618 , 315.59424 ],
24+
[279.90872 , 314.11356 , 345.76315 , 327.5568 , 339.5455 , 312.9249 ],
25+
[271.93985 , 268.81046 , 24.793104, 185.978 , 299.82904 ,159.0188 ]], dtype=np.float32)
3626
return result
3727

3828

39-
def test_numpy_equals_qgis(qgis_output):
40-
numpy_agg = input_data()
29+
def test_numpy_equals_qgis(elevation_raster, qgis_aspect):
30+
numpy_agg = input_data(elevation_raster, backend='numpy')
4131
xrspatial_aspect = aspect(numpy_agg, name='numpy_aspect')
4232

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

4636
xrspatial_vals = xrspatial_aspect.data[1:-1, 1:-1]
47-
qgis_vals = qgis_output[1:-1, 1:-1]
37+
qgis_vals = qgis_aspect[1:-1, 1:-1]
4838
# aspect is nan if nan input
4939
# aspect is invalid (-1) if slope equals 0
5040
# otherwise aspect are from 0 to 360
51-
np.testing.assert_allclose(xrspatial_vals, qgis_vals, equal_nan=True)
41+
np.testing.assert_allclose(xrspatial_vals, qgis_vals, rtol=1e-05, equal_nan=True)
5242
# nan edge effect
5343
assert_nan_edges_effect(xrspatial_aspect)
5444

5545

56-
def test_numpy_equals_dask_qgis_data():
46+
def test_numpy_equals_dask_qgis_data(elevation_raster):
5747
# compare using the data run through QGIS
58-
numpy_agg = input_data('numpy')
59-
dask_agg = input_data('dask+numpy')
48+
numpy_agg = input_data(elevation_raster, 'numpy')
49+
dask_agg = input_data(elevation_raster, 'dask+numpy')
6050
assert_numpy_equals_dask_numpy(numpy_agg, dask_agg, aspect)
6151

6252

@@ -72,8 +62,8 @@ def test_numpy_equals_dask_random_data(random_data):
7262
@cuda_and_cupy_available
7363
def test_numpy_equals_cupy_qgis_data():
7464
# compare using the data run through QGIS
75-
numpy_agg = input_data()
76-
cupy_agg = input_data('cupy')
65+
numpy_agg = input_data(elevation_raster)
66+
cupy_agg = input_data(elevation_raster, 'cupy')
7767
assert_numpy_equals_cupy(numpy_agg, cupy_agg, aspect)
7868

7969

xrspatial/tests/test_classify.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def input_data(backend='numpy'):
1414
[10., 11., 12., 13., 14.],
1515
[15., 16., 17., 18., np.inf],
1616
])
17-
raster = create_test_raster(elevation, backend, attrs={'res': (10.0, 10.0)})
17+
raster = create_test_raster(elevation, backend)
1818
return raster
1919

2020

@@ -218,7 +218,7 @@ def test_natural_breaks_numpy_num_sample(result_natural_breaks_num_sample):
218218
def test_natural_breaks_cpu_deterministic():
219219
results = []
220220
elevation = np.arange(100).reshape(10, 10)
221-
agg = xr.DataArray(elevation, attrs={'res': (10.0, 10.0)})
221+
agg = xr.DataArray(elevation)
222222

223223
k = 5
224224
numIters = 3

xrspatial/tests/test_focal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,15 +270,15 @@ def test_2d_convolution_gpu(
270270

271271

272272
def test_calc_cellsize_unit_input_attrs(convolve_2d_data):
273-
agg = create_test_raster(convolve_2d_data, attrs={'res': 1, 'unit': 'km'})
273+
agg = create_test_raster(convolve_2d_data, attrs={'res': (1, 1), 'unit': 'km'})
274274
cellsize = calc_cellsize(agg)
275275
assert cellsize == (1000, 1000)
276276

277277

278278
def test_calc_cellsize_no_attrs(convolve_2d_data):
279279
agg = create_test_raster(convolve_2d_data)
280280
cellsize = calc_cellsize(agg)
281-
assert cellsize == (1, 1)
281+
assert cellsize == (0.5, 0.5)
282282

283283

284284
@pytest.fixture

0 commit comments

Comments
 (0)