def test_osm2padang(self): """OSM structure types maps to Padang vulnerability curves """ hazard_filename = '%s/Shakemap_Padang_2009.asc' % HAZDATA exposure_filename = ('%s/OSM_building_polygons_20110905.shp' % TESTDATA) # Calculate impact using API H = read_layer(hazard_filename) E = read_layer(exposure_filename) # Map from OSM attributes to the padang building classes Emap = osm2padang(E) for i, feature in enumerate(E.get_data()): vclass = int(Emap.get_data('VCLASS', i)) levels = feature['levels'] structure = feature['structure'] msg = ('Unexpected VCLASS %i. ' 'I have levels == %s and structure == %s.' % (vclass, levels, structure)) if levels is None or structure is None: assert vclass == 2, msg continue # Map string variable levels to integer if levels.endswith('+'): levels = 100 try: levels = int(levels) except: # E.g. 'ILP jalan' assert vclass == 2, msg continue levels = int(levels) # Check the main cases if levels >= 10: assert vclass == 6, msg elif 4 <= levels < 10: assert vclass == 4, msg elif 1 <= levels < 4: if structure in ['plastered', 'reinforced masonry', 'reinforced_masonry']: assert vclass == 7, msg elif structure == 'confined_masonry': assert vclass == 8, msg elif 'kayu' in structure or 'wood' in structure: assert vclass == 9, msg else: assert vclass == 2, msg else: assert vclass == 2, msg
def test_aggregate(self): """Aggregation by boundaries works """ # Name file names for hazard level and exposure boundary_filename = ('%s/kecamatan_jakarta_osm.shp' % TESTDATA) #data_filename = ('%s/Population_Jakarta_geographic.asc' % TESTDATA) # Get reference building impact data building_filename = ('%s/building_impact_scenario.shp' % TESTDATA) boundary_layer = read_layer(boundary_filename) building_layer = read_layer(building_filename) res = aggregate(data=building_layer, boundaries=boundary_layer, attribute_name='AFFECTED', aggregation_function='count') #print res, len(res) #print boundary_layer, len(boundary_layer) msg = ('Number of aggregations %i should be the same as the ' 'number of specified boundaries %i' % (len(res), len(boundary_layer))) assert len(res) == len(boundary_layer), msg
def test_osm2bnpb(self): """OSM structure types maps to BNPB vulnerability curves """ hazard_filename = '%s/Shakemap_Padang_2009.asc' % HAZDATA exposure_filename = ('%s/OSM_building_polygons_20110905.shp' % TESTDATA) # Calculate impact using API H = read_layer(hazard_filename) E = read_layer(exposure_filename) # Map from OSM attributes to the padang building classes Emap = osm2bnpb(E, target_attribute='VCLASS') for i, feature in enumerate(E.get_data()): try: vclass = Emap.get_data('VCLASS', i) except KeyError: print print i, Emap.get_data()[i] #import sys; sys.exit() pass levels = feature['levels'] structure = feature['structure'] msg = ('Unexpected VCLASS %s. ' 'I have levels == %s and structure == %s.' % (vclass, levels, structure)) if levels is None or structure is None: assert vclass == 'URM', msg continue # Map string variable levels to integer if levels.endswith('+'): levels = 100 try: levels = int(levels) except: # E.g. 'ILP jalan' assert vclass == 'URM', msg continue levels = int(levels) # Check the main cases if levels >= 4: assert vclass == 'RM', msg elif 1 <= levels < 4: if structure in ['reinforced_masonry', 'confined_masonry']: assert vclass == 'RM', msg elif 'kayu' in structure or 'wood' in structure: assert vclass == 'RM', msg else: assert vclass == 'URM', msg else: assert vclass == 'URM', msg
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: InsufficientParametersException if not all parameters are set. """ self.__filename = None self.__result = None if not self.__hazard_layer or self.__hazard_layer == '': msg = tr('Error: Hazard layer not set.') raise InsufficientParametersException(msg) if not self.__exposure_layer or self.__exposure_layer == '': msg = tr('Error: Exposure layer not set.') raise InsufficientParametersException(msg) if not self.__function or self.__function == '': msg = tr('Error: Function not set.') raise InsufficientParametersException(msg) # Call impact calculation engine myHazardLayer = read_layer(makeAscii(self.__hazard_layer)) myExposureLayer = read_layer(makeAscii(self.__exposure_layer)) myFunctions = get_plugins(makeAscii(self.__function)) myFunction = myFunctions[0][makeAscii(self.__function)] return ImpactCalculatorThread(myHazardLayer, myExposureLayer, myFunction)
def test_getOptimalExtent(self): """Optimal extent is calculated correctly """ exposure_path = os.path.join(TESTDATA, 'Population_2010.asc') hazard_path = os.path.join(TESTDATA, '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 = read_layer(hazard_path) E = read_layer(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_res = [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_res, rtol=1.0e-12, atol=1.0e-12) bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, ref_res, 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_res, 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 Exception, e: msg = 'Did not find expected error message in %s' % str(e) assert 'did not overlap' in str(e), msg
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 test_filename in ['Population_Jakarta_geographic.asc', 'Population_2010.asc']: myRasterPath = ('%s/%s' % (TESTDATA, test_filename)) # Get reference values R = read_layer(myRasterPath) R_min_ref, R_max_ref = R.get_extrema() native_resolution = R.get_resolution() # Get the Hazard extents as an array in EPSG:4326 bounding_box = R.get_bounding_box() # Test for a range of resolutions for res 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 test_filename.startswith('Population_2010'): if res > 0.01 or res < 0.005: break # Clip the raster to the bbox extraKeywords = {'resolution': native_resolution} myRasterLayer = QgsRasterLayer(myRasterPath, 'xxx') myResult = clipLayer(myRasterLayer, bounding_box, res, extraKeywords=extraKeywords) R = read_layer(myResult) A_native = R.get_data(scaling=False) A_scaled = R.get_data(scaling=True) sigma = (R.get_resolution()[0] / native_resolution[0]) ** 2 # Compare extrema expected_scaled_max = sigma * numpy.nanmax(A_native) msg = ('Resampled raster was not rescaled correctly: ' 'max(A_scaled) was %f but expected %f' % (numpy.nanmax(A_scaled), 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(A_scaled) was 12083021.000000 but # expected 12083020.414316 # Is something being rounded to the nearest # integer? assert numpy.allclose(expected_scaled_max, numpy.nanmax(A_scaled), rtol=1.0e-6, atol=1.0e-8), msg expected_scaled_min = sigma * numpy.nanmin(A_native) msg = ('Resampled raster was not rescaled correctly: ' 'min(A_scaled) was %f but expected %f' % (numpy.nanmin(A_scaled), expected_scaled_min)) assert numpy.allclose(expected_scaled_min, numpy.nanmin(A_scaled), rtol=1.0e-8, atol=1.0e-12), msg # Compare elementwise msg = 'Resampled raster was not rescaled correctly' assert nanallclose(A_native * sigma, A_scaled, rtol=1.0e-8, atol=1.0e-8), msg # Check that it also works with manual scaling A_manual = R.get_data(scaling=sigma) msg = 'Resampled raster was not rescaled correctly' assert nanallclose(A_manual, A_scaled, rtol=1.0e-8, atol=1.0e-8), msg # Check that an exception is raised for bad arguments try: R.get_data(scaling='bad') except: pass else: msg = 'String argument should have raised exception' raise Exception(msg) try: R.get_data(scaling='(1, 3)') except: pass else: msg = 'Tuple argument should have raised exception' raise Exception(msg) # Check None option without keyword datatype == 'density' R.keywords['datatype'] = 'undefined' A_none = R.get_data(scaling=None) msg = 'Data should not have changed' assert nanallclose(A_native, A_none, rtol=1.0e-12, atol=1.0e-12), msg # Try with None and density keyword R.keywords['datatype'] = 'density' A_none = R.get_data(scaling=None) msg = 'Resampled raster was not rescaled correctly' assert nanallclose(A_scaled, A_none, rtol=1.0e-12, atol=1.0e-12), msg R.keywords['datatype'] = 'counts' A_none = R.get_data(scaling=None) msg = 'Data should not have changed' assert nanallclose(A_native, A_none, rtol=1.0e-12, atol=1.0e-12), msg
def test_clipBoth(self): """Raster and Vector layers can be clipped """ # Create a vector layer myName = 'padang' myVectorLayer = QgsVectorLayer(VECTOR_PATH, myName, 'ogr') msg = 'Did not find layer "%s" in path "%s"' % (myName, VECTOR_PATH) assert myVectorLayer is not None, msg # Create a raster layer myName = 'shake' myRasterLayer = QgsRasterLayer(RASTERPATH, myName) msg = 'Did not find layer "%s" in path "%s"' % (myName, RASTERPATH) assert myRasterLayer is not None, msg # 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) read_layer(myResult) # Clip the raster to the bbox myResult = clipLayer(myRasterLayer, myGeoExtent) # Check the output is valid assert os.path.exists(myResult) read_layer(myResult) # ------------------------------- # Check the extra keywords option # ------------------------------- # Clip the vector to the bbox myResult = clipLayer(myVectorLayer, myGeoExtent, extraKeywords={'kermit': 'piggy'}) # Check the output is valid assert os.path.exists(myResult) L = read_layer(myResult) kwds = L.get_keywords() msg = 'Extra keyword was not found in %s: %s' % (myResult, kwds) assert kwds['kermit'] == 'piggy' # Clip the raster to the bbox myResult = clipLayer(myRasterLayer, myGeoExtent, extraKeywords={'zoot': 'animal'}) # Check the output is valid assert os.path.exists(myResult) L = read_layer(myResult) kwds = L.get_keywords() msg = 'Extra keyword was not found in %s: %s' % (myResult, kwds) assert kwds['zoot'] == 'animal', msg