def test_routedem_no_options_default_band(self): """RouteDEM: default to band 1 when not specified.""" from natcap.invest import routedem # Intentionally leaving out the dem_band_index parameter, # should default to band 1. args = { 'workspace_dir': self.workspace_dir, 'dem_path': os.path.join(self.workspace_dir, 'dem.tif'), 'results_suffix': 'foo', } RouteDEMTests._make_dem(args['dem_path']) routedem.execute(args) filled_raster_path = os.path.join(args['workspace_dir'], 'filled_foo.tif') self.assertTrue( os.path.exists(filled_raster_path), 'Filled DEM not created.') # The first band has only values of 1, no hydrological pits. # So, the filled band should match the source band. expected_filled_array = gdal.OpenEx(args['dem_path']).ReadAsArray()[0] filled_array = gdal.OpenEx(filled_raster_path).ReadAsArray() numpy.testing.assert_almost_equal( expected_filled_array, filled_array)
def test_routedem_slope(self): """RouteDEM: assert slope option.""" from natcap.invest import routedem args = { 'workspace_dir': self.workspace_dir, 'dem_path': os.path.join(self.workspace_dir, 'dem.tif'), 'dem_band_index': 2, 'results_suffix': 'foo', 'calculate_slope': True, } RouteDEMTests._make_dem(args['dem_path']) routedem.execute(args) for path in ('filled_foo.tif', 'slope_foo.tif'): self.assertTrue(os.path.exists( os.path.join(args['workspace_dir'], path)), 'File not found: %s' % path) slope_array = gdal.OpenEx( os.path.join(args['workspace_dir'], 'slope_foo.tif')).ReadAsArray() # These were determined by inspection of the output array. expected_unique_values = numpy.array( [4.999998, 4.9999995, 5.000001, 5.0000043, 7.126098, 13.235317, 45.017357, 48.226353, 48.75, 49.56845, 50.249374, 50.24938, 50.249382, 55.17727, 63.18101], dtype=numpy.float32).reshape((15,)) numpy.testing.assert_almost_equal( expected_unique_values, numpy.unique(slope_array)) numpy.testing.assert_almost_equal(numpy.sum(slope_array), 4088.7358, decimal=4)
def test_routedem_no_options(self): """RouteDEM: assert pitfilling when no other options given.""" from natcap.invest import routedem args = { 'workspace_dir': self.workspace_dir, 'dem_path': os.path.join(self.workspace_dir, 'dem.tif'), 'dem_band_index': 2, 'results_suffix': 'foo', } RouteDEMTests._make_dem(args['dem_path']) routedem.execute(args) filled_raster_path = os.path.join(args['workspace_dir'], 'filled_foo.tif') self.assertTrue( os.path.exists(filled_raster_path), 'Filled DEM not created.') # The one sink in the array should have been filled to 1.3. expected_filled_array = gdal.OpenEx(args['dem_path']).ReadAsArray()[1] expected_filled_array[expected_filled_array < 1.3] = 1.3 # Filled rasters are copies of only the desired band of the input DEM, # and then with pixels filled. filled_array = gdal.OpenEx(filled_raster_path).ReadAsArray() numpy.testing.assert_almost_equal( expected_filled_array, filled_array)
def test_routedem_mfd(self): """RouteDEM: test mfd routing.""" from natcap.invest import routedem args = { 'workspace_dir': self.workspace_dir, 'algorithm': 'mfd', 'dem_path': os.path.join(self.workspace_dir, 'dem.tif'), 'dem_band_index': 2, 'results_suffix': 'foo', 'calculate_flow_direction': True, 'calculate_flow_accumulation': True, 'calculate_stream_threshold': True, 'calculate_downstream_distance': True, 'calculate_slope': False, 'threshold_flow_accumulation': 4, } RouteDEMTests._make_dem(args['dem_path']) routedem.execute(args) expected_stream_mask = numpy.array([ [0, 0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], ]) numpy.testing.assert_allclose( expected_stream_mask, gdal.OpenEx( os.path.join(args['workspace_dir'], 'stream_mask_foo.tif')).ReadAsArray(), rtol=0, atol=1e-6) # Raster sums are from manually-inspected outputs. for filename, expected_sum in (('flow_accumulation_foo.tif', 678.94551294), ('flow_direction_foo.tif', 40968303668.0), ('downstream_distance_foo.tif', 162.28624753707527)): raster_path = os.path.join(args['workspace_dir'], filename) raster = gdal.OpenEx(raster_path) if raster is None: self.fail('Could not open raster %s' % filename) self.assertEqual(raster.RasterYSize, expected_stream_mask.shape[0]) self.assertEqual(raster.RasterXSize, expected_stream_mask.shape[1]) raster_sum = numpy.sum(raster.ReadAsArray(), dtype=numpy.float64) numpy.testing.assert_allclose(raster_sum, expected_sum, rtol=0, atol=1e-6)
def test_routedem_invalid_algorithm(self): """RouteDEM: fail when the algorithm isn't recognized.""" from natcap.invest import routedem args = { 'workspace_dir': self.workspace_dir, 'algorithm': 'invalid', 'dem_path': os.path.join(self.workspace_dir, 'dem.tif'), 'results_suffix': 'foo', 'calculate_flow_direction': True, } RouteDEMTests._make_dem(args['dem_path']) with self.assertRaises(RuntimeError) as cm: routedem.execute(args) self.assertTrue('Invalid algorithm specified' in str(cm.exception))
def test_routedem_d8(self): """RouteDEM: test d8 routing.""" from natcap.invest import routedem args = { 'workspace_dir': self.workspace_dir, 'algorithm': 'd8', 'dem_path': os.path.join(self.workspace_dir, 'dem.tif'), 'dem_band_index': 2, 'results_suffix': 'foo', 'calculate_flow_direction': True, 'calculate_flow_accumulation': True, 'calculate_stream_threshold': True, 'calculate_downstream_distance': True, 'calculate_slope': True, 'threshold_flow_accumulation': 4, } RouteDEMTests._make_dem(args['dem_path']) routedem.execute(args) for expected_file in ( 'downstream_distance_foo.tif', 'filled_foo.tif', 'flow_accumulation_foo.tif', 'flow_direction_foo.tif', 'slope_foo.tif', 'stream_mask_foo.tif'): self.assertTrue( os.path.exists( os.path.join(args['workspace_dir'], expected_file)), 'Raster not found: %s' % expected_file) expected_stream_mask = numpy.array([ [0, 0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], ]) numpy.testing.assert_almost_equal( expected_stream_mask, gdal.OpenEx(os.path.join( args['workspace_dir'], 'stream_mask_foo.tif')).ReadAsArray()) expected_flow_accum = numpy.empty((10, 9), dtype=numpy.float64) expected_flow_accum[:, 0:4] = numpy.arange(1, 5) expected_flow_accum[:, 5:9] = numpy.flipud(numpy.arange(1, 5)) expected_flow_accum[:, 4] = numpy.array( [82, 77, 72, 63, 54, 45, 36, 27, 18, 9]) expected_flow_accum[1, 5] = 1 expected_flow_accum[0, 5] = 8 numpy.testing.assert_almost_equal( expected_flow_accum, gdal.OpenEx(os.path.join( args['workspace_dir'], 'flow_accumulation_foo.tif')).ReadAsArray()) expected_flow_direction = numpy.empty((10, 9), dtype=numpy.uint8) expected_flow_direction[:, 0:4] = 0 expected_flow_direction[:, 5:9] = 4 expected_flow_direction[:, 4] = 2 expected_flow_direction[0:2, 5] = 2 expected_flow_direction[1, 6] = 3 numpy.testing.assert_almost_equal( expected_flow_direction, gdal.OpenEx(os.path.join( args['workspace_dir'], 'flow_direction_foo.tif')).ReadAsArray()) expected_downstream_distance = numpy.empty((10, 9), dtype=numpy.float64) expected_downstream_distance[:, 0:5] = numpy.flipud(numpy.arange(5)) expected_downstream_distance[2:, 5:] = numpy.arange(1, 5) expected_downstream_distance[0, 5:] = numpy.arange(4) expected_downstream_distance[1, 5] = 1 expected_downstream_distance[1, 6:] = numpy.arange(1, 4) + 0.41421356 numpy.testing.assert_almost_equal( expected_downstream_distance, gdal.OpenEx(os.path.join( args['workspace_dir'], 'downstream_distance_foo.tif')).ReadAsArray())