def getRunner(self): """ Factory to create a new runner thread. Requires three parameters to be set before execution can take place: * Hazard layer - a path to a raster (string) * Exposure layer - a path to a vector hazard layer (string). * Function - a function name that defines how the Hazard assessment will be computed (string). Args: None. Returns: None Raises: InsufficientParametersError if not all parameters are set. """ self._filename = None self._result = None if self._hazardLayer is None or self._hazardLayer == '': myMessage = self.tr('Error: Hazard layer not set.') raise InsufficientParametersError(myMessage) if self._exposureLayer is None or self._exposureLayer == '': myMessage = self.tr('Error: Exposure layer not set.') raise InsufficientParametersError(myMessage) if self._function is None or self._function == '': myMessage = self.tr('Error: Function not set.') raise InsufficientParametersError(myMessage) # Call impact calculation engine try: myHazardLayer = readSafeLayer(self._hazardLayer) myExposureLayer = readSafeLayer(self._exposureLayer) except: raise myFunctions = getSafeImpactFunctions(self._function) myFunction = myFunctions[0][self._function] return ImpactCalculatorThread(myHazardLayer, myExposureLayer, myFunction)
def setUp(self): """Create shared resources that all tests can use""" self.calculator = ImpactCalculator() self.vector_path = os.path.join(TESTDATA, 'Padang_WGS84.shp') self.vector_layer = readSafeLayer(self.vector_path) self.raster_shake_path = os.path.join( HAZDATA, 'Shakemap_Padang_2009.asc') self.raster_shake = readSafeLayer(self.raster_shake_path) # UTM projected layer fn = 'tsunami_max_inundation_depth_BB_utm.asc' self.raster_tsunami_path = os.path.join(TESTDATA, fn) self.raster_exposure_path = os.path.join( TESTDATA, 'tsunami_building_exposure.shp') self.raster_population_path = os.path.join(EXPDATA, 'glp10ag.asc') self.calculator.set_hazard_layer(self.raster_shake) self.calculator.set_exposure_layer(self.vector_layer) self.calculator.set_function('Earthquake Building Impact Function')
def setUp(self): """Create shared resources that all tests can use""" self.calculator = ImpactCalculator() self.vector_path = os.path.join(TESTDATA, 'Padang_WGS84.shp') self.vector_layer = readSafeLayer(self.vector_path) self.raster_shake_path = os.path.join(HAZDATA, 'Shakemap_Padang_2009.asc') self.raster_shake = readSafeLayer(self.raster_shake_path) # UTM projected layer fn = 'tsunami_max_inundation_depth_BB_utm.asc' self.raster_tsunami_path = os.path.join(TESTDATA, fn) self.raster_exposure_path = os.path.join( TESTDATA, 'tsunami_building_exposure.shp') self.raster_population_path = os.path.join(EXPDATA, 'glp10ag.asc') self.calculator.set_hazard_layer(self.raster_shake) self.calculator.set_exposure_layer(self.vector_layer) self.calculator.set_function('Earthquake Building Impact Function')
def test_issue100(self): """Test for issue 100: unhashable type dict""" exposure_path = os.path.join( TESTDATA, 'OSM_building_polygons_20110905.shp') hazard_path = os.path.join( HAZDATA, 'Flood_Current_Depth_Jakarta_geographic.asc') # Verify relevant metada is ok h = readSafeLayer(hazard_path) e = readSafeLayer(exposure_path) self.calculator.set_hazard_layer(h) self.calculator.set_exposure_layer(e) self.calculator.set_function('Flood Building Impact Function') try: function_runner = self.calculator.get_runner() # Run non threaded function_runner.run() message = function_runner.result() impact_layer = function_runner.impact_layer() file_name = impact_layer.get_filename() assert(file_name and not file_name == '') assert(message and not message == '') except Exception, e: # pylint: disable=W0703 message = 'Calculator run failed. %s' % str(e) assert(), message
def test_issue100(self): """Test for issue 100: unhashable type dict""" exposure_path = os.path.join(TESTDATA, 'OSM_building_polygons_20110905.shp') hazard_path = os.path.join( HAZDATA, 'Flood_Current_Depth_Jakarta_geographic.asc') # Verify relevant metada is ok h = readSafeLayer(hazard_path) e = readSafeLayer(exposure_path) self.calculator.set_hazard_layer(h) self.calculator.set_exposure_layer(e) self.calculator.set_function('Flood Building Impact Function') try: function_runner = self.calculator.get_runner() # Run non threaded function_runner.run() message = function_runner.result() impact_layer = function_runner.impact_layer() file_name = impact_layer.get_filename() assert (file_name and not file_name == '') assert (message and not message == '') except Exception, e: # pylint: disable=W0703 message = 'Calculator run failed. %s' % str(e) assert (), message
def test_raster_scaling_projected(self): """Attempt to scale projected density raster layers raise exception. Automatic scaling when resampling density data does not currently work for projected layers. See issue #123. For the time being this test checks that an exception is raised when scaling is attempted on projected layers. When we resolve issue #123, this test should be rewritten. """ test_filename = 'Population_Jakarta_UTM48N.tif' raster_path = ('%s/%s' % (TESTDATA, test_filename)) # Get reference values safe_layer = readSafeLayer(raster_path) min_value, max_value = safe_layer.get_extrema() native_resolution = safe_layer.get_resolution() print min_value, max_value print native_resolution # Define bounding box in EPSG:4326 bounding_box = [106.61, -6.38, 107.05, -6.07] resolutions = [0.02, 0.01, 0.005, 0.002, 0.001] # Test for a range of resolutions for resolution in resolutions: # Clip the raster to the bbox extra_keywords = {'resolution': native_resolution} raster_layer = QgsRasterLayer(raster_path, 'xxx') try: clip_layer( raster_layer, bounding_box, resolution, extra_keywords=extra_keywords ) except InvalidProjectionError: pass else: message = 'Should have raised InvalidProjectionError' raise Exception(message)
def testRasterScaling_projected(self): """Attempt to scale projected density raster layers raise exception Automatic scaling when resampling density data does not currently work for projected layers. See issue #123. For the time being this test checks that an exception is raised when scaling is attempted on projected layers. When we resolve issue #123, this test should be rewritten. """ myTestFilename = 'Population_Jakarta_UTM48N.tif' myRasterPath = ('%s/%s' % (TESTDATA, myTestFilename)) # Get reference values mySafeLayer = readSafeLayer(myRasterPath) myMinimum, myMaximum = mySafeLayer.get_extrema() myNativeResolution = mySafeLayer.get_resolution() print print myMinimum, myMaximum print myNativeResolution # Define bounding box in EPSG:4326 myBoundingBox = [106.61, -6.38, 107.05, -6.07] # Test for a range of resolutions for myResolution in [0.02, 0.01, 0.005, 0.002, 0.001]: # Clip the raster to the bbox myExtraKeywords = {'resolution': myNativeResolution} myRasterLayer = QgsRasterLayer(myRasterPath, 'xxx') try: clipLayer(myRasterLayer, myBoundingBox, myResolution, theExtraKeywords=myExtraKeywords) except InvalidProjectionError: pass else: myMessage = 'Should have raised InvalidProjectionError' raise Exception(myMessage)
def testRasterScaling_projected(self): """Attempt to scale projected density raster layers raise exception Automatic scaling when resampling density data does not currently work for projected layers. See issue #123. For the time being this test checks that an exception is raised when scaling is attempted on projected layers. When we resolve issue #123, this test should be rewritten. """ myTestFilename = 'Population_Jakarta_UTM48N.tif' myRasterPath = ('%s/%s' % (TESTDATA, myTestFilename)) # Get reference values mySafeLayer = readSafeLayer(myRasterPath) myMinimum, myMaximum = mySafeLayer.get_extrema() myNativeResolution = mySafeLayer.get_resolution() print print myMinimum, myMaximum print myNativeResolution # Define bounding box in EPSG:4326 myBoundingBox = [106.61, -6.38, 107.05, -6.07] # Test for a range of resolutions for myResolution in [0.02, 0.01, 0.005, 0.002, 0.001]: # Clip the raster to the bbox myExtraKeywords = {'resolution': myNativeResolution} myRasterLayer = QgsRasterLayer(myRasterPath, 'xxx') try: clip_layer(myRasterLayer, myBoundingBox, myResolution, extra_keywords=myExtraKeywords) except InvalidProjectionError: pass else: myMessage = 'Should have raised InvalidProjectionError' raise Exception(myMessage)
def testRasterScaling(self): """Raster layers can be scaled when resampled This is a test for ticket #52 Native test .asc data has Population_Jakarta_geographic.asc ncols 638 nrows 649 cellsize 0.00045228819716044 Population_2010.asc ncols 5525 nrows 2050 cellsize 0.0083333333333333 Scaling is necessary for raster data that represents density such as population per km^2 """ for myFilename in ['Population_Jakarta_geographic.asc', 'Population_2010.asc']: myRasterPath = ('%s/%s' % (TESTDATA, myFilename)) # Get reference values mySafeLayer = readSafeLayer(myRasterPath) myMinimum, myMaximum = mySafeLayer.get_extrema() del myMaximum del myMinimum myNativeResolution = mySafeLayer.get_resolution() # Get the Hazard extents as an array in EPSG:4326 myBoundingBox = mySafeLayer.get_bounding_box() # Test for a range of resolutions for myResolution in [0.02, 0.01, 0.005, 0.002, 0.001, 0.0005, # Coarser 0.0002]: # Finer # To save time only do two resolutions for the # large population set if myFilename.startswith('Population_2010'): if myResolution > 0.01 or myResolution < 0.005: break # Clip the raster to the bbox myExtraKeywords = {'resolution': myNativeResolution} myRasterLayer = QgsRasterLayer(myRasterPath, 'xxx') myResult = clip_layer(myRasterLayer, myBoundingBox, myResolution, extra_keywords=myExtraKeywords) mySafeLayer = readSafeLayer(myResult.source()) myNativeData = mySafeLayer.get_data(scaling=False) myScaledData = mySafeLayer.get_data(scaling=True) mySigma = (mySafeLayer.get_resolution()[0] / myNativeResolution[0]) ** 2 # Compare extrema myExpectedScaledMax = mySigma * numpy.nanmax(myNativeData) myMessage = ('Resampled raster was not rescaled correctly: ' 'max(myScaledData) was %f but expected %f' % (numpy.nanmax(myScaledData), myExpectedScaledMax)) # FIXME (Ole): The rtol used to be 1.0e-8 - # now it has to be 1.0e-6, otherwise we get # max(myScaledData) was 12083021.000000 but # expected 12083020.414316 # Is something being rounded to the nearest # integer? assert numpy.allclose(myExpectedScaledMax, numpy.nanmax(myScaledData), rtol=1.0e-6, atol=1.0e-8), myMessage myExpectedScaledMin = mySigma * numpy.nanmin(myNativeData) myMessage = ('Resampled raster was not rescaled correctly: ' 'min(myScaledData) was %f but expected %f' % (numpy.nanmin(myScaledData), myExpectedScaledMin)) assert numpy.allclose(myExpectedScaledMin, numpy.nanmin(myScaledData), rtol=1.0e-8, atol=1.0e-12), myMessage # Compare elementwise myMessage = 'Resampled raster was not rescaled correctly' assert nan_allclose(myNativeData * mySigma, myScaledData, rtol=1.0e-8, atol=1.0e-8), myMessage # Check that it also works with manual scaling myManualData = mySafeLayer.get_data(scaling=mySigma) myMessage = 'Resampled raster was not rescaled correctly' assert nan_allclose(myManualData, myScaledData, rtol=1.0e-8, atol=1.0e-8), myMessage # Check that an exception is raised for bad arguments try: mySafeLayer.get_data(scaling='bad') except GetDataError: pass else: myMessage = 'String argument should have raised exception' raise Exception(myMessage) try: mySafeLayer.get_data(scaling='(1, 3)') except GetDataError: pass else: myMessage = 'Tuple argument should have raised exception' raise Exception(myMessage) # Check None option without keyword datatype == 'density' mySafeLayer.keywords['datatype'] = 'undefined' myUnscaledData = mySafeLayer.get_data(scaling=None) myMessage = 'Data should not have changed' assert nan_allclose(myNativeData, myUnscaledData, rtol=1.0e-12, atol=1.0e-12), myMessage # Try with None and density keyword mySafeLayer.keywords['datatype'] = 'density' myUnscaledData = mySafeLayer.get_data(scaling=None) myMessage = 'Resampled raster was not rescaled correctly' assert nan_allclose(myScaledData, myUnscaledData, rtol=1.0e-12, atol=1.0e-12), myMessage mySafeLayer.keywords['datatype'] = 'counts' myUnscaledData = mySafeLayer.get_data(scaling=None) myMessage = 'Data should not have changed' assert nan_allclose(myNativeData, myUnscaledData, rtol=1.0e-12, atol=1.0e-12), myMessage
def test_clipBoth(self): """Raster and Vector layers can be clipped """ # Create a vector layer myName = 'padang' myVectorLayer = QgsVectorLayer(VECTOR_PATH, myName, 'ogr') myMessage = 'Did not find layer "%s" in path "%s"' % \ (myName, VECTOR_PATH) assert myVectorLayer.isValid(), myMessage # Create a raster layer myName = 'shake' myRasterLayer = QgsRasterLayer(RASTERPATH, myName) myMessage = 'Did not find layer "%s" in path "%s"' % \ (myName, RASTERPATH) assert myRasterLayer.isValid(), myMessage # Create a bounding box myViewportGeoExtent = [99.53, -1.22, 101.20, -0.36] # Get the Hazard extents as an array in EPSG:4326 myHazardGeoExtent = [myRasterLayer.extent().xMinimum(), myRasterLayer.extent().yMinimum(), myRasterLayer.extent().xMaximum(), myRasterLayer.extent().yMaximum()] # Get the Exposure extents as an array in EPSG:4326 myExposureGeoExtent = [myVectorLayer.extent().xMinimum(), myVectorLayer.extent().yMinimum(), myVectorLayer.extent().xMaximum(), myVectorLayer.extent().yMaximum()] # Now work out the optimal extent between the two layers and # the current view extent. The optimal extent is the intersection # between the two layers and the viewport. # Extent is returned as an array [xmin,ymin,xmax,ymax] myGeoExtent = getOptimalExtent(myHazardGeoExtent, myExposureGeoExtent, myViewportGeoExtent) # Clip the vector to the bbox myResult = clip_layer(myVectorLayer, myGeoExtent) # Check the output is valid assert os.path.exists(myResult.source()) readSafeLayer(myResult.source()) # Clip the raster to the bbox myResult = clip_layer(myRasterLayer, myGeoExtent) # Check the output is valid assert os.path.exists(myResult.source()) readSafeLayer(myResult.source()) # ------------------------------- # Check the extra keywords option # ------------------------------- # Clip the vector to the bbox myResult = clip_layer(myVectorLayer, myGeoExtent, extra_keywords={'kermit': 'piggy'}) # Check the output is valid assert os.path.exists(myResult.source()) L = readSafeLayer(myResult.source()) kwds = L.get_keywords() # myMessage = 'Extra keyword wasn\'t found in %s: %s' % (myResult, # kwds) assert kwds['kermit'] == 'piggy' # Clip the raster to the bbox myResult = clip_layer(myRasterLayer, myGeoExtent, extra_keywords={'zoot': 'animal'}) # Check the output is valid assert os.path.exists(myResult.source()) L = readSafeLayer(myResult.source()) kwds = L.get_keywords() myMessage = 'Extra keyword was not found in %s: %s' % ( myResult.source(), kwds) assert kwds['zoot'] == 'animal', myMessage
def test_raster_scaling(self): """Raster layers can be scaled when resampled. This is a test for ticket #52 Native test .asc data has Population_Jakarta_geographic.asc ncols 638 nrows 649 cellsize 0.00045228819716044 Population_2010.asc ncols 5525 nrows 2050 cellsize 0.0083333333333333 Scaling is necessary for raster data that represents density such as population per km^2 """ filenames = [ 'Population_Jakarta_geographic.asc', 'Population_2010.asc' ] for filename in filenames: raster_path = ('%s/%s' % (TESTDATA, filename)) # Get reference values safe_layer = readSafeLayer(raster_path) min_value, max_value = safe_layer.get_extrema() del max_value del min_value native_resolution = safe_layer.get_resolution() # Get the Hazard extents as an array in EPSG:4326 bounding_box = safe_layer.get_bounding_box() resolutions = [ 0.02, 0.01, 0.005, 0.002, 0.001, 0.0005, # Coarser 0.0002 # Finer ] # Test for a range of resolutions for resolution in resolutions: # Finer # To save time only do two resolutions for the # large population set if filename.startswith('Population_2010'): if resolution > 0.01 or resolution < 0.005: break # Clip the raster to the bbox extra_keywords = {'resolution': native_resolution} raster_layer = QgsRasterLayer(raster_path, 'xxx') result = clip_layer( raster_layer, bounding_box, resolution, extra_keywords=extra_keywords ) safe_layer = readSafeLayer(result.source()) native_data = safe_layer.get_data(scaling=False) scaled_data = safe_layer.get_data(scaling=True) sigma_value = (safe_layer.get_resolution()[0] / native_resolution[0]) ** 2 # Compare extrema expected_scaled_max = sigma_value * numpy.nanmax(native_data) message = ( 'Resampled raster was not rescaled correctly: ' 'max(scaled_data) was %f but expected %f' % (numpy.nanmax(scaled_data), expected_scaled_max)) # FIXME (Ole): The rtol used to be 1.0e-8 - # now it has to be 1.0e-6, otherwise we get # max(scaled_data) was 12083021.000000 but # expected 12083020.414316 # Is something being rounded to the nearest # integer? assert numpy.allclose(expected_scaled_max, numpy.nanmax(scaled_data), rtol=1.0e-6, atol=1.0e-8), message expected_scaled_min = sigma_value * numpy.nanmin(native_data) message = ( 'Resampled raster was not rescaled correctly: ' 'min(scaled_data) was %f but expected %f' % (numpy.nanmin(scaled_data), expected_scaled_min)) assert numpy.allclose(expected_scaled_min, numpy.nanmin(scaled_data), rtol=1.0e-8, atol=1.0e-12), message # Compare element-wise message = 'Resampled raster was not rescaled correctly' assert nan_allclose(native_data * sigma_value, scaled_data, rtol=1.0e-8, atol=1.0e-8), message # Check that it also works with manual scaling manual_data = safe_layer.get_data(scaling=sigma_value) message = 'Resampled raster was not rescaled correctly' assert nan_allclose(manual_data, scaled_data, rtol=1.0e-8, atol=1.0e-8), message # Check that an exception is raised for bad arguments try: safe_layer.get_data(scaling='bad') except GetDataError: pass else: message = 'String argument should have raised exception' raise Exception(message) try: safe_layer.get_data(scaling='(1, 3)') except GetDataError: pass else: message = 'Tuple argument should have raised exception' raise Exception(message) # Check None option without keyword datatype == 'density' safe_layer.keywords['datatype'] = 'undefined' unscaled_data = safe_layer.get_data(scaling=None) message = 'Data should not have changed' assert nan_allclose(native_data, unscaled_data, rtol=1.0e-12, atol=1.0e-12), message # Try with None and density keyword safe_layer.keywords['datatype'] = 'density' unscaled_data = safe_layer.get_data(scaling=None) message = 'Resampled raster was not rescaled correctly' assert nan_allclose(scaled_data, unscaled_data, rtol=1.0e-12, atol=1.0e-12), message safe_layer.keywords['datatype'] = 'counts' unscaled_data = safe_layer.get_data(scaling=None) message = 'Data should not have changed' assert nan_allclose(native_data, unscaled_data, rtol=1.0e-12, atol=1.0e-12), message
def testRasterScaling(self): """Raster layers can be scaled when resampled This is a test for ticket #52 Native test .asc data has Population_Jakarta_geographic.asc ncols 638 nrows 649 cellsize 0.00045228819716044 Population_2010.asc ncols 5525 nrows 2050 cellsize 0.0083333333333333 Scaling is necessary for raster data that represents density such as population per km^2 """ for myFilename in [ 'Population_Jakarta_geographic.asc', 'Population_2010.asc' ]: myRasterPath = ('%s/%s' % (TESTDATA, myFilename)) # Get reference values mySafeLayer = readSafeLayer(myRasterPath) myMinimum, myMaximum = mySafeLayer.get_extrema() del myMaximum del myMinimum myNativeResolution = mySafeLayer.get_resolution() # Get the Hazard extents as an array in EPSG:4326 myBoundingBox = mySafeLayer.get_bounding_box() # Test for a range of resolutions for myResolution in [ 0.02, 0.01, 0.005, 0.002, 0.001, 0.0005, # Coarser 0.0002 ]: # Finer # To save time only do two resolutions for the # large population set if myFilename.startswith('Population_2010'): if myResolution > 0.01 or myResolution < 0.005: break # Clip the raster to the bbox myExtraKeywords = {'resolution': myNativeResolution} myRasterLayer = QgsRasterLayer(myRasterPath, 'xxx') myResult = clipLayer(myRasterLayer, myBoundingBox, myResolution, theExtraKeywords=myExtraKeywords) mySafeLayer = readSafeLayer(myResult) myNativeData = mySafeLayer.get_data(scaling=False) myScaledData = mySafeLayer.get_data(scaling=True) mySigma = (mySafeLayer.get_resolution()[0] / myNativeResolution[0])**2 # Compare extrema myExpectedScaledMax = mySigma * numpy.nanmax(myNativeData) myMessage = ('Resampled raster was not rescaled correctly: ' 'max(myScaledData) was %f but expected %f' % (numpy.nanmax(myScaledData), myExpectedScaledMax)) # FIXME (Ole): The rtol used to be 1.0e-8 - # now it has to be 1.0e-6, otherwise we get # max(myScaledData) was 12083021.000000 but # expected 12083020.414316 # Is something being rounded to the nearest # integer? assert numpy.allclose(myExpectedScaledMax, numpy.nanmax(myScaledData), rtol=1.0e-6, atol=1.0e-8), myMessage myExpectedScaledMin = mySigma * numpy.nanmin(myNativeData) myMessage = ('Resampled raster was not rescaled correctly: ' 'min(myScaledData) was %f but expected %f' % (numpy.nanmin(myScaledData), myExpectedScaledMin)) assert numpy.allclose(myExpectedScaledMin, numpy.nanmin(myScaledData), rtol=1.0e-8, atol=1.0e-12), myMessage # Compare elementwise myMessage = 'Resampled raster was not rescaled correctly' assert nanallclose(myNativeData * mySigma, myScaledData, rtol=1.0e-8, atol=1.0e-8), myMessage # Check that it also works with manual scaling myManualData = mySafeLayer.get_data(scaling=mySigma) myMessage = 'Resampled raster was not rescaled correctly' assert nanallclose(myManualData, myScaledData, rtol=1.0e-8, atol=1.0e-8), myMessage # Check that an exception is raised for bad arguments try: mySafeLayer.get_data(scaling='bad') except GetDataError: pass else: myMessage = 'String argument should have raised exception' raise Exception(myMessage) try: mySafeLayer.get_data(scaling='(1, 3)') except GetDataError: pass else: myMessage = 'Tuple argument should have raised exception' raise Exception(myMessage) # Check None option without keyword datatype == 'density' mySafeLayer.keywords['datatype'] = 'undefined' myUnscaledData = mySafeLayer.get_data(scaling=None) myMessage = 'Data should not have changed' assert nanallclose(myNativeData, myUnscaledData, rtol=1.0e-12, atol=1.0e-12), myMessage # Try with None and density keyword mySafeLayer.keywords['datatype'] = 'density' myUnscaledData = mySafeLayer.get_data(scaling=None) myMessage = 'Resampled raster was not rescaled correctly' assert nanallclose(myScaledData, myUnscaledData, rtol=1.0e-12, atol=1.0e-12), myMessage mySafeLayer.keywords['datatype'] = 'counts' myUnscaledData = mySafeLayer.get_data(scaling=None) myMessage = 'Data should not have changed' assert nanallclose(myNativeData, myUnscaledData, rtol=1.0e-12, atol=1.0e-12), myMessage
def test_clipBoth(self): """Raster and Vector layers can be clipped """ # Create a vector layer myName = 'padang' myVectorLayer = QgsVectorLayer(VECTOR_PATH, myName, 'ogr') myMessage = 'Did not find layer "%s" in path "%s"' % \ (myName, VECTOR_PATH) assert myVectorLayer.isValid(), myMessage # Create a raster layer myName = 'shake' myRasterLayer = QgsRasterLayer(RASTERPATH, myName) myMessage = 'Did not find layer "%s" in path "%s"' % \ (myName, RASTERPATH) assert myRasterLayer.isValid(), myMessage # Create a bounding box myViewportGeoExtent = [99.53, -1.22, 101.20, -0.36] # Get the Hazard extents as an array in EPSG:4326 myHazardGeoExtent = [ myRasterLayer.extent().xMinimum(), myRasterLayer.extent().yMinimum(), myRasterLayer.extent().xMaximum(), myRasterLayer.extent().yMaximum() ] # Get the Exposure extents as an array in EPSG:4326 myExposureGeoExtent = [ myVectorLayer.extent().xMinimum(), myVectorLayer.extent().yMinimum(), myVectorLayer.extent().xMaximum(), myVectorLayer.extent().yMaximum() ] # Now work out the optimal extent between the two layers and # the current view extent. The optimal extent is the intersection # between the two layers and the viewport. # Extent is returned as an array [xmin,ymin,xmax,ymax] myGeoExtent = getOptimalExtent(myHazardGeoExtent, myExposureGeoExtent, myViewportGeoExtent) # Clip the vector to the bbox myResult = clipLayer(myVectorLayer, myGeoExtent) # Check the output is valid assert os.path.exists(myResult) readSafeLayer(myResult) # Clip the raster to the bbox myResult = clipLayer(myRasterLayer, myGeoExtent) # Check the output is valid assert os.path.exists(myResult) readSafeLayer(myResult) # ------------------------------- # Check the extra keywords option # ------------------------------- # Clip the vector to the bbox myResult = clipLayer(myVectorLayer, myGeoExtent, theExtraKeywords={'kermit': 'piggy'}) # Check the output is valid assert os.path.exists(myResult) L = readSafeLayer(myResult) kwds = L.get_keywords() myMessage = 'Extra keyword was not found in %s: %s' % (myResult, kwds) assert kwds['kermit'] == 'piggy' # Clip the raster to the bbox myResult = clipLayer(myRasterLayer, myGeoExtent, theExtraKeywords={'zoot': 'animal'}) # Check the output is valid assert os.path.exists(myResult) L = readSafeLayer(myResult) kwds = L.get_keywords() myMessage = 'Extra keyword was not found in %s: %s' % (myResult, kwds) assert kwds['zoot'] == 'animal', myMessage
def test_getOptimalExtent(self): """Optimal extent is calculated correctly """ exposure_path = os.path.join(TESTDATA, 'Population_2010.asc') hazard_path = os.path.join(HAZDATA, 'Lembang_Earthquake_Scenario.asc') # Expected data haz_metadata = { 'bounding_box': (105.3000035, -8.3749994999999995, 110.2914705, -5.5667784999999999), 'resolution': (0.0083330000000000001, 0.0083330000000000001) } exp_metadata = { 'bounding_box': (94.972335000000001, -11.009721000000001, 141.0140016666665, 6.0736123333332639), 'resolution': (0.0083333333333333003, 0.0083333333333333003) } # Verify relevant metada is ok H = readSafeLayer(hazard_path) E = readSafeLayer(exposure_path) hazard_bbox = H.get_bounding_box() assert numpy.allclose(hazard_bbox, haz_metadata['bounding_box'], rtol=1.0e-12, atol=1.0e-12) exposure_bbox = E.get_bounding_box() assert numpy.allclose(exposure_bbox, exp_metadata['bounding_box'], rtol=1.0e-12, atol=1.0e-12) hazard_res = H.get_resolution() assert numpy.allclose(hazard_res, haz_metadata['resolution'], rtol=1.0e-12, atol=1.0e-12) exposure_res = E.get_resolution() assert numpy.allclose(exposure_res, exp_metadata['resolution'], rtol=1.0e-12, atol=1.0e-12) # First, do some examples that produce valid results ref_box = [105.3000035, -8.3749995, 110.2914705, -5.5667785] view_port = [94.972335, -11.009721, 141.014002, 6.073612] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) #testing with viewport clipping disabled bbox = getOptimalExtent(hazard_bbox, exposure_bbox, None) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) view_port = [ 105.3000035, -8.3749994999999995, 110.2914705, -5.5667784999999999 ] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) # Very small viewport fully inside other layers view_port = [106.0, -6.0, 108.0, -5.8] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, view_port, rtol=1.0e-12, atol=1.0e-12) # viewport that intersects hazard layer view_port = [107.0, -6.0, 112.0, -3.0] ref_box = [107, -6, 110.2914705, -5.5667785] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) # Then one where boxes don't overlap view_port = [105.3, -4.3, 110.29, -2.5] try: getOptimalExtent(hazard_bbox, exposure_bbox, view_port) except InsufficientOverlapError, e: myMessage = 'Did not find expected error message in %s' % str(e) assert 'did not overlap' in str(e), myMessage
def test_getOptimalExtent(self): """Optimal extent is calculated correctly """ exposure_path = os.path.join(TESTDATA, 'Population_2010.asc') hazard_path = os.path.join(HAZDATA, 'Lembang_Earthquake_Scenario.asc') # Expected data haz_metadata = {'bounding_box': (105.3000035, -8.3749994999999995, 110.2914705, -5.5667784999999999), 'resolution': (0.0083330000000000001, 0.0083330000000000001)} exp_metadata = {'bounding_box': (94.972335000000001, -11.009721000000001, 141.0140016666665, 6.0736123333332639), 'resolution': (0.0083333333333333003, 0.0083333333333333003)} # Verify relevant metada is ok H = readSafeLayer(hazard_path) E = readSafeLayer(exposure_path) hazard_bbox = H.get_bounding_box() assert numpy.allclose(hazard_bbox, haz_metadata['bounding_box'], rtol=1.0e-12, atol=1.0e-12) exposure_bbox = E.get_bounding_box() assert numpy.allclose(exposure_bbox, exp_metadata['bounding_box'], rtol=1.0e-12, atol=1.0e-12) hazard_res = H.get_resolution() assert numpy.allclose(hazard_res, haz_metadata['resolution'], rtol=1.0e-12, atol=1.0e-12) exposure_res = E.get_resolution() assert numpy.allclose(exposure_res, exp_metadata['resolution'], rtol=1.0e-12, atol=1.0e-12) # First, do some examples that produce valid results ref_box = [105.3000035, -8.3749995, 110.2914705, -5.5667785] view_port = [94.972335, -11.009721, 141.014002, 6.073612] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) #testing with viewport clipping disabled bbox = getOptimalExtent(hazard_bbox, exposure_bbox, None) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) view_port = [105.3000035, -8.3749994999999995, 110.2914705, -5.5667784999999999] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) # Very small viewport fully inside other layers view_port = [106.0, -6.0, 108.0, -5.8] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, view_port, rtol=1.0e-12, atol=1.0e-12) # viewport that intersects hazard layer view_port = [107.0, -6.0, 112.0, -3.0] ref_box = [107, -6, 110.2914705, -5.5667785] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) # Then one where boxes don't overlap view_port = [105.3, -4.3, 110.29, -2.5] try: getOptimalExtent(hazard_bbox, exposure_bbox, view_port) except InsufficientOverlapError, e: myMessage = 'Did not find expected error message in %s' % str(e) assert 'did not overlap' in str(e), myMessage
def test_clip_both(self): """Raster and Vector layers can be clipped.""" # Create a vector layer layer_name = 'padang' vector_layer = QgsVectorLayer(VECTOR_PATH, layer_name, 'ogr') message = ( 'Did not find layer "%s" in path "%s"' % (layer_name, VECTOR_PATH)) assert vector_layer.isValid(), message # Create a raster layer layer_name = 'shake' raster_layer = QgsRasterLayer(RASTERPATH, layer_name) message = ( 'Did not find layer "%s" in path "%s"' % (layer_name, RASTERPATH)) assert raster_layer.isValid(), message # Create a bounding box view_port_geo_extent = [99.53, -1.22, 101.20, -0.36] # Get the Hazard extents as an array in EPSG:4326 hazard_geo_extent = [ raster_layer.extent().xMinimum(), raster_layer.extent().yMinimum(), raster_layer.extent().xMaximum(), raster_layer.extent().yMaximum() ] # Get the Exposure extents as an array in EPSG:4326 exposure_geo_extent = [ vector_layer.extent().xMinimum(), vector_layer.extent().yMinimum(), vector_layer.extent().xMaximum(), vector_layer.extent().yMaximum() ] # Now work out the optimal extent between the two layers and # the current view extent. The optimal extent is the intersection # between the two layers and the viewport. # Extent is returned as an array [xmin,ymin,xmax,ymax] geo_extent = getOptimalExtent( hazard_geo_extent, exposure_geo_extent, view_port_geo_extent) # Clip the vector to the bbox result = clip_layer(vector_layer, geo_extent) # Check the output is valid assert os.path.exists(result.source()) readSafeLayer(result.source()) # Clip the raster to the bbox result = clip_layer(raster_layer, geo_extent) # Check the output is valid assert os.path.exists(result.source()) readSafeLayer(result.source()) # ------------------------------- # Check the extra keywords option # ------------------------------- # Clip the vector to the bbox result = clip_layer( vector_layer, geo_extent, extra_keywords={'kermit': 'piggy'}) # Check the output is valid assert os.path.exists(result.source()) safe_layer = readSafeLayer(result.source()) keywords = safe_layer.get_keywords() # message = 'Extra keyword was not found in %s: %s' % (myResult, # keywords) assert keywords['kermit'] == 'piggy' # Clip the raster to the bbox result = clip_layer( raster_layer, geo_extent, extra_keywords={'zoot': 'animal'}) # Check the output is valid assert os.path.exists(result.source()) safe_layer = readSafeLayer(result.source()) keywords = safe_layer.get_keywords() message = ('Extra keyword was not found in %s: %s' % (result.source(), keywords)) assert keywords['zoot'] == 'animal', message