|
16 | 16 | import json |
17 | 17 | import os |
18 | 18 | import pathlib |
| 19 | +import tempfile |
19 | 20 |
|
20 | 21 | from absl.testing import absltest |
21 | 22 | from google.auth import identity_pool |
|
26 | 27 |
|
27 | 28 | import ee |
28 | 29 |
|
| 30 | +_SKIP_RASTERIO_TESTS = False |
| 31 | +try: |
| 32 | + import rasterio # pylint: disable=g-import-not-at-top |
| 33 | + import rioxarray # pylint: disable=g-import-not-at-top,unused-import |
| 34 | +except ImportError: |
| 35 | + _SKIP_RASTERIO_TESTS = True |
| 36 | + |
29 | 37 | _CREDENTIALS_PATH_KEY = 'GOOGLE_APPLICATION_CREDENTIALS' |
30 | 38 | _SCOPES = [ |
31 | 39 | 'https://www.googleapis.com/auth/cloud-platform', |
@@ -397,6 +405,79 @@ def test_validate_band_attrs(self): |
397 | 405 | for _, value in variable.attrs.items(): |
398 | 406 | self.assertIsInstance(value, valid_types) |
399 | 407 |
|
| 408 | + @absltest.skipIf(_SKIP_RASTERIO_TESTS, 'rioxarray module not loaded') |
| 409 | + def test_write_projected_dataset_to_raster(self): |
| 410 | + # ensure that a projected dataset written to a raster intersects with the |
| 411 | + # point used to create the initial image collection |
| 412 | + with tempfile.TemporaryDirectory() as temp_dir: |
| 413 | + temp_file = os.path.join(temp_dir, 'test.tif') |
| 414 | + |
| 415 | + crs = 'epsg:32610' |
| 416 | + proj = ee.Projection(crs) |
| 417 | + point = ee.Geometry.Point([-122.44, 37.78]) |
| 418 | + geom = point.buffer(1024).bounds() |
| 419 | + |
| 420 | + col = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED') |
| 421 | + col = col.filterBounds(point) |
| 422 | + col = col.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', 5)) |
| 423 | + col = col.limit(10) |
| 424 | + |
| 425 | + ds = xr.open_dataset( |
| 426 | + col, |
| 427 | + engine=xee.EarthEngineBackendEntrypoint, |
| 428 | + scale=10, |
| 429 | + crs=crs, |
| 430 | + geometry=geom, |
| 431 | + ) |
| 432 | + |
| 433 | + ds = ds.isel(time=0).transpose('Y', 'X') |
| 434 | + ds.rio.set_spatial_dims(x_dim='X', y_dim='Y', inplace=True) |
| 435 | + ds.rio.write_crs(crs, inplace=True) |
| 436 | + ds.rio.reproject(crs, inplace=True) |
| 437 | + ds.rio.to_raster(temp_file) |
| 438 | + |
| 439 | + with rasterio.open(temp_file) as raster: |
| 440 | + # see https://gis.stackexchange.com/a/407755 for evenOdd explanation |
| 441 | + bbox = ee.Geometry.Rectangle(raster.bounds, proj=proj, evenOdd=False) |
| 442 | + intersects = bbox.intersects(point, 1, proj=proj) |
| 443 | + self.assertTrue(intersects.getInfo()) |
| 444 | + |
| 445 | + @absltest.skipIf(_SKIP_RASTERIO_TESTS, 'rioxarray module not loaded') |
| 446 | + def test_write_dataset_to_raster(self): |
| 447 | + # ensure that a dataset written to a raster intersects with the point used |
| 448 | + # to create the initial image collection |
| 449 | + with tempfile.TemporaryDirectory() as temp_dir: |
| 450 | + temp_file = os.path.join(temp_dir, 'test.tif') |
| 451 | + |
| 452 | + crs = 'EPSG:4326' |
| 453 | + proj = ee.Projection(crs) |
| 454 | + point = ee.Geometry.Point([-122.44, 37.78]) |
| 455 | + geom = point.buffer(1024).bounds() |
| 456 | + |
| 457 | + col = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED') |
| 458 | + col = col.filterBounds(point) |
| 459 | + col = col.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', 5)) |
| 460 | + col = col.limit(10) |
| 461 | + |
| 462 | + ds = xr.open_dataset( |
| 463 | + col, |
| 464 | + engine=xee.EarthEngineBackendEntrypoint, |
| 465 | + scale=0.0025, |
| 466 | + geometry=geom, |
| 467 | + ) |
| 468 | + |
| 469 | + ds = ds.isel(time=0).transpose('lat', 'lon') |
| 470 | + ds.rio.set_spatial_dims(x_dim='lon', y_dim='lat', inplace=True) |
| 471 | + ds.rio.write_crs(crs, inplace=True) |
| 472 | + ds.rio.reproject(crs, inplace=True) |
| 473 | + ds.rio.to_raster(temp_file) |
| 474 | + |
| 475 | + with rasterio.open(temp_file) as raster: |
| 476 | + # see https://gis.stackexchange.com/a/407755 for evenOdd explanation |
| 477 | + bbox = ee.Geometry.Rectangle(raster.bounds, proj=proj, evenOdd=False) |
| 478 | + intersects = bbox.intersects(point, 1, proj=proj) |
| 479 | + self.assertTrue(intersects.getInfo()) |
| 480 | + |
400 | 481 |
|
401 | 482 | if __name__ == '__main__': |
402 | 483 | absltest.main() |
0 commit comments