1from grass.gunittest.case import TestCase 2from grass.gunittest.main import test 3from grass.gunittest.gmodules import call_module 4 5SMALL_MAP = """\ 6north: 15 7south: 10 8east: 25 9west: 20 10rows: 5 11cols: 5 12 13100.0 150.0 150.0 100.0 100.0 14100.0 150.0 150.0 100.0 100.0 15100.0 150.0 150.0 150.0 150.0 16100.0 150.0 150.0 100.0 100.0 17100.0 150.0 150.0 100.0 100.0 18""" 19 20class TestSlopeAspect(TestCase): 21 22 slope = 'limits_slope' 23 aspect = 'limits_aspect' 24 25 def setUp(self): 26 self.use_temp_region() 27 call_module('g.region', raster='elevation') 28 29 def tearDown(self): 30 self.del_temp_region() 31 call_module('g.remove', flags='f', type_='raster', 32 name=[self.slope, self.aspect]) 33 34 def test_limits(self): 35 self.assertModule('r.slope.aspect', elevation='elevation', 36 slope=self.slope, aspect=self.aspect) 37 self.assertRasterMinMax(map=self.slope, refmin=0, refmax=90, 38 msg="Slope in degrees must be between 0 and 90") 39 self.assertRasterMinMax(map=self.aspect, refmin=0, refmax=360, 40 msg="Aspect in degrees must be between 0 and 360") 41 42 def test_limits_precent(self): 43 """Assumes NC elevation and allows slope up to 100% (45deg)""" 44 self.assertModule('r.slope.aspect', elevation='elevation', 45 slope=self.slope, aspect=self.aspect, format='percent') 46 self.assertRasterMinMax(map=self.slope, refmin=0, refmax=100, 47 msg="Slope in percent must be between 0 and 100") 48 self.assertRasterMinMax(map=self.aspect, refmin=0, refmax=360, 49 msg="Aspect in degrees must be between 0 and 360") 50 51 52class TestSlopeAspectAgainstReference(TestCase): 53 """ 54 55 Data created using:: 56 57 g.region n=20 s=10 e=25 w=15 res=1 58 r.surf.fractal output=fractal_surf 59 r.out.ascii input=fractal_surf output=data/fractal_surf.ascii 60 gdaldem slope .../fractal_surf.ascii .../gdal_slope.grd -of GSAG 61 gdaldem aspect .../fractal_surf.ascii .../gdal_aspect.grd -of GSAG -trigonometric 62 63 GDAL version 1.11.0 was used. Note: GDAL-slope/aspect implementation is originally based on 64 GRASS GIS 4.1. 65 """ 66 67 # precision for comparisons 68 precision = 0.0001 69 ref_aspect = 'reference_aspect' 70 aspect = 'fractal_aspect' 71 ref_slope = 'reference_slope' 72 slope = 'fractal_slope' 73 74 @classmethod 75 def setUpClass(cls): 76 cls.use_temp_region() 77 call_module('g.region', n=20, s=10, e=25, w=15, res=1) 78 cls.elevation = 'fractal_surf' 79 cls.runModule('r.in.ascii', input='data/fractal_surf.ascii', 80 output=cls.elevation) 81 82 @classmethod 83 def tearDownClass(cls): 84 cls.del_temp_region() 85 cls.runModule('g.remove', flags='f', type='raster', 86 name=[cls.elevation, cls.slope, cls.aspect, cls.ref_aspect, cls.ref_slope]) 87 88 def test_slope(self): 89 # TODO: using gdal instead of ascii because of cannot seek error 90 self.runModule('r.in.gdal', flags='o', 91 input='data/gdal_slope.grd', output=self.ref_slope) 92 self.assertModule('r.slope.aspect', elevation=self.elevation, 93 slope=self.slope) 94 # check we have expected values 95 self.assertRasterMinMax(map=self.slope, refmin=0, refmax=90, 96 msg="Slope in degrees must be between 0 and 90") 97 # check against reference data 98 self.assertRastersNoDifference(actual=self.slope, reference=self.ref_slope, 99 precision=self.precision) 100 101 def test_aspect(self): 102 # TODO: using gdal instead of ascii because of cannot seek error 103 self.runModule('r.in.gdal', flags='o', 104 input='data/gdal_aspect.grd', output=self.ref_aspect) 105 self.assertModule('r.slope.aspect', elevation=self.elevation, 106 aspect=self.aspect) 107 # check we have expected values 108 self.assertRasterMinMax(map=self.aspect, refmin=0, refmax=360, 109 msg="Aspect in degrees must be between 0 and 360") 110 # check against reference data 111 self.assertRastersNoDifference(actual=self.aspect, reference=self.ref_aspect, 112 precision=self.precision) 113 114 115class TestSlopeAspectAgainstItself(TestCase): 116 117 precision = 0.0000001 118 elevation = 'elevation' 119 t_aspect = 'sa_together_aspect' 120 t_slope = 'sa_together_slope' 121 s_aspect = 'sa_separately_aspect' 122 s_slope = 'sa_separately_slope' 123 124 @classmethod 125 def setUpClass(cls): 126 cls.use_temp_region() 127 call_module('g.region', raster='elevation') 128 129 @classmethod 130 def tearDownClass(cls): 131 cls.del_temp_region() 132 call_module('g.remove', flags='f', type_='raster', 133 name=[cls.t_aspect, cls.t_slope, cls.s_slope, cls.s_aspect]) 134 135 def test_slope_aspect_together(self): 136 """Slope and aspect computed separately and together should be the same 137 """ 138 self.assertModule('r.slope.aspect', elevation=self.elevation, 139 aspect=self.s_aspect) 140 self.assertModule('r.slope.aspect', elevation=self.elevation, 141 slope=self.s_slope) 142 self.assertModule('r.slope.aspect', elevation=self.elevation, 143 slope=self.t_slope, aspect=self.t_aspect) 144 self.assertRastersNoDifference(actual=self.t_aspect, reference=self.s_aspect, 145 precision=self.precision) 146 self.assertRastersNoDifference(actual=self.t_slope, reference=self.s_slope, 147 precision=self.precision) 148 149 150# TODO: implement this class 151class TestExtremes(TestCase): 152 153 slope = 'small_slope' 154 aspect = 'small_aspect' 155 elevation = 'small_elevation' 156 157 def setUp(self): 158 self.use_temp_region() 159 160 def tearDown(self): 161 self.del_temp_region() 162 call_module('g.remove', flags='f', type_='raster', 163 name=[self.slope, self.aspect, self.elevation]) 164 165 def test_small(self): 166 self.runModule('r.in.ascii', input='-', output=self.elevation, 167 stdin_=SMALL_MAP) 168 call_module('g.region', raster=self.elevation) 169 self.assertModule('r.slope.aspect', elevation=self.elevation, 170 slope=self.slope, aspect=self.aspect) 171 self.assertRasterMinMax(map=self.slope, refmin=0, refmax=90, 172 msg="Slope in degrees must be between 0 and 90") 173 self.assertRasterMinMax(map=self.aspect, refmin=0, refmax=360, 174 msg="Aspect in degrees must be between 0 and 360") 175 176 177if __name__ == '__main__': 178 test() 179