def test_run(self): """TestVolcanoPolygonBuildingFunction: Test running the IF.""" volcano_path = test_data_path('hazard', 'volcano_krb.shp') building_path = test_data_path('exposure', 'buildings.shp') hazard_layer = read_layer(volcano_path) exposure_layer = read_layer(building_path) impact_function = VolcanoPolygonBuildingFunction.instance() impact_function.hazard = SafeLayer(hazard_layer) impact_function.exposure = SafeLayer(exposure_layer) impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In the event of volcano krb how many buildings ' 'might be affected') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) # The buildings should all be categorised into 5000 zone zone_sum = impact_layer.get_data( attribute=impact_function.target_field) krb3_zone_count = zone_sum.count('High Hazard Zone') krb2_zone_count = zone_sum.count('Medium Hazard Zone') # The result (counted by hand) expected_krb3_count = 11 expected_krb2_count = 161 message = 'Expecting %s for KRB III zone, but it returns %s' % ( krb3_zone_count, expected_krb3_count) self.assertEqual(krb3_zone_count, expected_krb3_count, message) message = 'Expecting %s for KRB II zone, but it returns %s' % ( krb2_zone_count, expected_krb2_count) self.assertEqual(krb2_zone_count, expected_krb2_count, message)
def test_run(self): function = ContinuousHazardPopulationFunction.instance() hazard_path = test_data_path( 'hazard', 'continuous_flood_20_20.asc') exposure_path = test_data_path( 'exposure', 'pop_binary_raster_20_20.asc') hazard_layer = read_layer(hazard_path) exposure_layer = read_layer(exposure_path) function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.run() impact = function.impact # print "keywords", keywords keywords = impact.get_keywords() total_needs_full = keywords['total_needs'] total_needs_weekly = OrderedDict([ [x['table name'], x['amount']] for x in total_needs_full['weekly'] ]) total_needs_single = OrderedDict([ [x['table name'], x['amount']] for x in total_needs_full['single'] ]) self.assertEqual(total_needs_weekly['Rice [kg]'], 336) self.assertEqual(total_needs_weekly['Drinking Water [l]'], 2100) self.assertEqual(total_needs_weekly['Clean Water [l]'], 8040) self.assertEqual(total_needs_weekly['Family Kits'], 24) self.assertEqual(total_needs_single['Toilets'], 6)
def test_run(self): """TestVolcanoPointPopulationFunction: Test running the IF.""" merapi_point_path = test_data_path('hazard', 'volcano_point.shp') population_path = test_data_path('exposure', 'pop_binary_raster_20_20.asc') merapi_point_layer = read_layer(merapi_point_path) population_layer = read_layer(population_path) impact_function = VolcanoPointPopulationFunction.instance() # Run merapi point impact_function.hazard = SafeLayer(merapi_point_layer) impact_function.exposure = SafeLayer(population_layer) impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In the event of a volcano point how many ' 'people might be impacted') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) # Count by hand expected_affected_population = 200 result = numpy.nansum(impact_layer.get_data()) message = 'Expecting %s, but it returns %s' % ( expected_affected_population, result) self.assertEqual(expected_affected_population, result, message)
def test_run(self): """TestEarthquakeBuildingFunction: Test running the IF.""" eq_path = test_data_path('hazard', 'earthquake.tif') building_path = test_data_path('exposure', 'buildings.shp') eq_layer = read_layer(eq_path) building_layer = read_layer(building_path) impact_function = EarthquakeBuildingFunction.instance() impact_function.hazard = eq_layer impact_function.exposure = building_layer impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In the event of earthquake how many ' 'buildings might be affected') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) # Count by hand, # 1 = low, 2 = medium, 3 = high impact = {1: 0, 2: 181, 3: 0} result = {1: 0, 2: 0, 3: 0} impact_features = impact_layer.get_data() for i in range(len(impact_features)): impact_feature = impact_features[i] level = impact_feature.get('Shake_cls') result[level] += 1 message = 'Expecting %s, but it returns %s' % (impact, result) self.assertEqual(impact, result, message)
def test_run(self): function = FloodEvacuationRasterHazardFunction.instance() hazard_path = test_data_path('hazard', 'continuous_flood_20_20.asc') exposure_path = test_data_path( 'exposure', 'pop_binary_raster_20_20.asc') hazard_layer = read_layer(hazard_path) exposure_layer = read_layer(exposure_path) function.hazard = hazard_layer function.exposure = exposure_layer function.run() impact = function.impact # Count of flooded objects is calculated "by the hands" # print "keywords", keywords keywords = impact.get_keywords() evacuated = float(keywords['evacuated']) total_needs_full = keywords['total_needs'] total_needs_weekly = OrderedDict([ [x['table name'], x['amount']] for x in total_needs_full['weekly'] ]) total_needs_single = OrderedDict([ [x['table name'], x['amount']] for x in total_needs_full['single'] ]) expected_evacuated = 100 self.assertEqual(evacuated, expected_evacuated) self.assertEqual(total_needs_weekly['Rice [kg]'], 280) self.assertEqual(total_needs_weekly['Family Kits'], 20) self.assertEqual(total_needs_weekly['Drinking Water [l]'], 1750) self.assertEqual(total_needs_weekly['Clean Water [l]'], 6700) self.assertEqual(total_needs_single['Toilets'], 5)
def test_run(self): impact_function = TsunamiRasterBuildingFunction.instance() hazard_path = test_data_path("hazard", "continuous_flood_20_20.asc") exposure_path = test_data_path("exposure", "buildings.shp") hazard_layer = read_layer(hazard_path) exposure_layer = read_layer(exposure_path) impact_function.hazard = SafeLayer(hazard_layer) impact_function.exposure = SafeLayer(exposure_layer) impact_function.run() impact_layer = impact_function.impact # Extract calculated result impact_data = impact_layer.get_data() self.assertEqual(len(impact_data), 181) # 1 = inundated, 2 = wet, 3 = dry expected_result = {0: 1, 1: 116, 2: 64, 3: 0, 4: 0} result = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0} for feature in impact_data: inundated_status = feature[impact_function.target_field] result[inundated_status] += 1 message = "Expecting %s, but it returns %s" % (expected_result, result) self.assertEqual(expected_result, result, message)
def test_run(self): """TestVolcanoPolygonPopulationFunction: Test running the IF.""" merapi_krb_path = test_data_path('hazard', 'volcano_krb.shp') population_path = test_data_path( 'exposure', 'pop_binary_raster_20_20.asc') merapi_krb_layer = read_layer(merapi_krb_path) population_layer = read_layer(population_path) impact_function = VolcanoPolygonPopulationFunction.instance() # 2. Run merapi krb impact_function.hazard = SafeLayer(merapi_krb_layer) impact_function.exposure = SafeLayer(population_layer) impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In the event of volcano krb how many population ' 'might need evacuation') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) # Count by hand expected_affected_population = 181 result = numpy.nansum(impact_layer.get_data()) self.assertEqual(expected_affected_population, result, message)
def test_run(self): function = FloodPolygonBuildingFunction.instance() hazard_path = test_data_path('hazard', 'flood_multipart_polygons.shp') exposure_path = test_data_path('exposure', 'buildings.shp') # noinspection PyCallingNonCallable hazard_layer = QgsVectorLayer(hazard_path, 'Flood', 'ogr') # noinspection PyCallingNonCallable exposure_layer = QgsVectorLayer(exposure_path, 'Buildings', 'ogr') # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()] function.hazard = QgisWrapper(hazard_layer) function.exposure = QgisWrapper(exposure_layer) function.requested_extent = rect_extent function.parameters['building_type_field'] = 'TYPE' function.parameters['affected_field'] = 'FLOODPRONE' function.parameters['affected_value'] = 'YES' function.run() impact = function.impact # Count of flooded objects is calculated "by the hands" # total flooded = 27, total buildings = 129 count = sum(impact.get_data(attribute='INUNDATED')) self.assertEquals(count, 33) count = len(impact.get_data()) self.assertEquals(count, 176)
def test_is_polygonal_layer(self): """Test we can get the correct attributes back""" # Polygon layer layer = clone_shp_layer( name='district_osm_jakarta', include_keywords=True, source_directory=test_data_path('boundaries')) message = 'isPolygonLayer, %s layer should be polygonal' % layer self.assertTrue(is_polygon_layer(layer), message) # Point layer layer = clone_shp_layer( name='volcano_point', include_keywords=True, source_directory=test_data_path('hazard')) message = '%s layer should be polygonal' % layer self.assertFalse(is_polygon_layer(layer), message) layer = clone_raster_layer( name='padang_tsunami_mw8', extension='.tif', include_keywords=True, source_directory=test_data_path('hazard') ) message = ('%s raster layer should not be polygonal' % layer) self.assertFalse(is_polygon_layer(layer), message)
def test_run(self): """TestVolcanoPointPopulationFunction: Test running the IF.""" merapi_point_path = test_data_path('hazard', 'volcano_point.shp') population_path = test_data_path( 'exposure', 'pop_binary_raster_20_20.asc') merapi_point_layer = read_layer(merapi_point_path) population_layer = read_layer(population_path) impact_function = VolcanoPointPopulationFunction.instance() # Run merapi point impact_function.hazard = merapi_point_layer impact_function.exposure = population_layer impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ( 'In the event of a volcano point how many ' 'people might be impacted') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) # Count by hand expected_affected_population = 200 result = numpy.nansum(impact_layer.get_data()) message = 'Expecting %s, but it returns %s' % ( expected_affected_population, result) self.assertEqual(expected_affected_population, result, message)
def test_run(self): function = FloodVectorRoadsExperimentalFunction.instance() hazard_path = test_data_path('hazard', 'flood_multipart_polygons.shp') exposure_path = test_data_path('exposure', 'roads.shp') # noinspection PyCallingNonCallable hazard_layer = QgsVectorLayer(hazard_path, 'Flood', 'ogr') # noinspection PyCallingNonCallable exposure_layer = QgsVectorLayer(exposure_path, 'Roads', 'ogr') # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum() ] function.hazard = QgisWrapper(hazard_layer) function.exposure = QgisWrapper(exposure_layer) function.requested_extent = rect_extent function.parameters['affected_field'] = 'FLOODPRONE' function.parameters['affected_value'] = 'YES' function.run() impact = function.impact # Count of flooded objects is calculated "by the hands" # the count = 69 expected_feature_total = 69 count = sum(impact.get_data(attribute='FLOODED')) message = 'Expecting %s, but it returns %s' % (expected_feature_total, count) self.assertEquals(count, expected_feature_total, message)
def test_run(self): function = FloodRasterRoadsFunction.instance() hazard_path = test_data_path('hazard', 'continuous_flood_20_20.asc') exposure_path = test_data_path('exposure', 'roads.shp') # noinspection PyCallingNonCallable hazard_layer = QgsRasterLayer(hazard_path, 'Flood') # noinspection PyCallingNonCallable exposure_layer = QgsVectorLayer(exposure_path, 'Roads', 'ogr') # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum() ] function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.requested_extent = rect_extent function.run() impact = function.impact keywords = impact.get_keywords() self.assertEquals(function.target_field, keywords['target_field']) expected_inundated_feature = 182 count = sum(impact.get_data(attribute=function.target_field)) self.assertEquals(count, expected_inundated_feature)
def test_building_native_impact_experimental(self): """Test flood_building_native_impact_experimental.""" hazard_name = test_data_path('hazard', 'multipart_polygons_osm_4326.shp') qgis_hazard = QgsVectorLayer(hazard_name, 'HAZARD', 'ogr') exposure_name = test_data_path('exposure', 'buildings_osm_4326.shp') qgis_exposure = QgsVectorLayer(exposure_name, 'EXPOSURE', 'ogr') plugin_name = "FloodNativePolygonExperimentalFunction" params = OrderedDict([('target_field', 'FLOODED'), ('building_type_field', 'TYPE'), ('affected_field', 'FLOOD'), ('affected_value', 'YES')]) # The params are not match field names of hazard self.assertRaises(GetDataError, self._get_impact_function, qgis_hazard, qgis_exposure, plugin_name, params) # Set up real field name params = OrderedDict([('target_field', 'FLOODED'), ('building_type_field', 'TYPE'), ('affected_field', 'FLOODPRONE'), ('affected_value', 'YES')]) impact = self._get_impact_function(qgis_hazard, qgis_exposure, plugin_name, params) keywords = impact.get_keywords() self.assertEquals(params['target_field'], keywords['target_field']) # Count of flooded objects is calculated "by the hands" # the count = 68 count = sum(impact.get_data(attribute=keywords['target_field'])) self.assertEquals(count, 68)
def test_state(self): """Check if the save/restore state methods work. See also https://github.com/AIFDR/inasafe/issues/58 """ # default selected layer is the third layer exposure # so, decrease the index by one to change it DOCK.cboExposure.setCurrentIndex(DOCK.cboExposure.currentIndex() - 1) DOCK.save_state() expected_dict = get_ui_state(DOCK) # myState = DOCK.state # Now reset and restore and check that it gets the old state # Html is not considered in restore test since the ready # message overwrites it in dock implementation DOCK.cboExposure.setCurrentIndex(DOCK.cboExposure.currentIndex() - 1) DOCK.restore_state() result_dict = get_ui_state(DOCK) message = 'Got unexpected state: %s\nExpected: %s\n%s' % ( result_dict, expected_dict, combos_to_string(DOCK)) self.assertTrue(expected_dict == result_dict, message) # Corner case test when two layers can have the # same functions - when switching layers the selected function should # remain unchanged self.tearDown() file_list = [ test_data_path('hazard', 'jakarta_flood_design.tif'), test_data_path('hazard', 'continuous_flood_20_20.asc'), test_data_path('exposure', 'pop_binary_raster_20_20.asc') ] hazard_layer_count, exposure_layer_count = load_layers(file_list) self.assertTrue(hazard_layer_count == 2) self.assertTrue(exposure_layer_count == 1) # we will have 2 impact function available right now: # - ContinuousHazardPopulationFunction, titled: 'Be impacted' # - FloodEvacuationRasterHazardFunction, titled: 'Need evacuation' # set it to the second for testing purposes DOCK.cboFunction.setCurrentIndex(1) DOCK.cboHazard.setCurrentIndex(0) DOCK.cboExposure.setCurrentIndex(0) expected_function = str(DOCK.cboFunction.currentText()) # Now move down one hazard in the combo then verify # the function remains unchanged DOCK.cboHazard.setCurrentIndex(1) current_function = str(DOCK.cboFunction.currentText()) message = ( 'Expected selected impact function to remain unchanged when ' 'choosing a different hazard of the same category:' ' %s\nExpected: %s\n%s' % ( expected_function, current_function, combos_to_string(DOCK))) self.assertTrue(expected_function == current_function, message) DOCK.cboHazard.setCurrentIndex(0) # Selected function should remain the same # RM: modified it, because there is generic one right now as the first. # the selected one should be FloodEvacuationRasterHazardFunction DOCK.cboFunction.setCurrentIndex(1) expected = 'Need evacuation' function = DOCK.cboFunction.currentText() message = 'Expected: %s, Got: %s' % (expected, function) self.assertTrue(function == expected, message)
def test_run(self): """TestVolcanoPointBuildingFunction: Test running the IF.""" volcano_path = test_data_path('hazard', 'volcano_point.shp') building_path = test_data_path('exposure', 'buildings.shp') hazard_layer = read_layer(volcano_path) exposure_layer = read_layer(building_path) impact_function = VolcanoPointBuildingFunction.instance() impact_function.hazard = SafeLayer(hazard_layer) impact_function.exposure = SafeLayer(exposure_layer) impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ( 'In the event of volcano point how many buildings might be ' 'affected') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) # The buildings should all be categorised into 3000 zone zone_sum = sum( impact_layer.get_data(attribute=impact_function.target_field)) expected_sum = 3 * 181 message = 'Expecting %s, but it returns %s' % (expected_sum, zone_sum) self.assertEqual(zone_sum, expected_sum, message)
def test_run(self): function = FloodEvacuationRasterHazardFunction.instance() hazard_path = test_data_path('hazard', 'continuous_flood_20_20.asc') exposure_path = test_data_path('exposure', 'pop_binary_raster_20_20.asc') hazard_layer = read_layer(hazard_path) exposure_layer = read_layer(exposure_path) function.hazard = hazard_layer function.exposure = exposure_layer function.run() impact = function.impact # Count of flooded objects is calculated "by the hands" # print "keywords", keywords keywords = impact.get_keywords() evacuated = float(keywords['evacuated']) total_needs_full = keywords['total_needs'] total_needs_weekly = OrderedDict([[x['table name'], x['amount']] for x in total_needs_full['weekly']]) total_needs_single = OrderedDict([[x['table name'], x['amount']] for x in total_needs_full['single']]) expected_evacuated = 100 self.assertEqual(evacuated, expected_evacuated) self.assertEqual(total_needs_weekly['Rice [kg]'], 280) self.assertEqual(total_needs_weekly['Family Kits'], 20) self.assertEqual(total_needs_weekly['Drinking Water [l]'], 1750) self.assertEqual(total_needs_weekly['Clean Water [l]'], 6700) self.assertEqual(total_needs_single['Toilets'], 5)
def test_run(self): """TestClassifiedPolygonPopulationFunction: Test running the IF.""" generic_polygon_path = test_data_path( 'hazard', 'classified_generic_polygon.shp') population_path = test_data_path('exposure', 'pop_binary_raster_20_20.asc') generic_polygon_layer = read_layer(generic_polygon_path) population_layer = read_layer(population_path) impact_function = ClassifiedPolygonHazardPopulationFunction.instance() impact_function.hazard = generic_polygon_layer impact_function.exposure = population_layer impact_function.parameters['hazard zone attribute'] = 'h_zone' impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In each of the hazard zones how many people ' 'might be impacted.') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) # Count by hand expected_affected_population = 181 result = numpy.nansum(impact_layer.get_data()) self.assertEqual(expected_affected_population, result, message)
def test_run(self): function = FloodPolygonRoadsFunction.instance() hazard_path = test_data_path('hazard', 'flood_multipart_polygons.shp') exposure_path = test_data_path('exposure', 'roads.shp') # noinspection PyCallingNonCallable hazard_layer = QgsVectorLayer(hazard_path, 'Flood', 'ogr') # noinspection PyCallingNonCallable exposure_layer = QgsVectorLayer(exposure_path, 'Roads', 'ogr') # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()] function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.requested_extent = rect_extent function.run() impact = function.impact # Count of flooded objects is calculated "by the hands" # the count = 69 expected_feature_total = 69 count = sum(impact.get_data(attribute=function.target_field)) message = 'Expecting %s, but it returns %s' % ( expected_feature_total, count) self.assertEquals(count, expected_feature_total, message)
def test_run(self): impact_function = FloodRasterBuildingFunction.instance() hazard_path = test_data_path('hazard', 'continuous_flood_20_20.asc') exposure_path = test_data_path('exposure', 'buildings.shp') hazard_layer = read_layer(hazard_path) exposure_layer = read_layer(exposure_path) impact_function.hazard = hazard_layer impact_function.exposure = exposure_layer impact_function.run() impact_layer = impact_function.impact # Extract calculated result impact_data = impact_layer.get_data() self.assertEqual(len(impact_data), 181) # 1 = inundated, 2 = wet, 3 = dry expected_result = { 1: 64, 2: 117, 3: 0 } result = { 1: 0, 2: 0, 3: 0 } for feature in impact_data: inundated_status = feature['INUNDATED'] result[inundated_status] += 1 message = 'Expecting %s, but it returns %s' % (expected_result, result) self.assertEqual(expected_result, result, message)
def test_get_keyword_from_file(self): """Get keyword from a filesystem file's .keyword file.""" raster_shake_path = test_data_path('hazard', 'jakarta_flood_design.tif') vector_path = test_data_path('exposure', 'buildings_osm_4326.shp') raster_tsunami_path = test_data_path('hazard', 'tsunami_wgs84.tif') keyword = read_file_keywords(raster_shake_path, 'layer_purpose') expected_keyword = 'hazard' message = ( 'The keyword "layer_purpose" for %s is %s. Expected keyword is: ' '%s') % (raster_shake_path, keyword, expected_keyword) self.assertEqual(keyword, expected_keyword, message) # Test we get an exception if keyword is not found self.assertRaises(KeywordNotFoundError, read_file_keywords, raster_shake_path, 'boguskeyword') # Test if all the keywords are all ready correctly keywords = read_file_keywords(raster_shake_path) expected_keywords = { 'hazard_category': 'single_event', 'hazard': 'flood', 'continuous_hazard_unit': 'metres', 'layer_purpose': 'hazard', 'layer_mode': 'continuous', 'title': 'Jakarta flood like 2007 with structural improvements', 'keyword_version': inasafe_keyword_version } message = 'Expected:\n%s\nGot:\n%s\n' % (expected_keywords, keywords) self.assertDictEqual(keywords, expected_keywords, message) # Test reading keywords from vector layer keywords = read_file_keywords(vector_path) expected_keywords = { 'keyword_version': inasafe_keyword_version, 'structure_class_field': 'FLOODED', 'title': 'buildings_osm_4326', 'layer_geometry': 'polygon', 'layer_purpose': 'exposure', 'layer_mode': 'classified', 'exposure': 'structure' } message = 'Expected:\n%s\nGot:\n%s\n' % (expected_keywords, keywords) self.assertDictEqual(keywords, expected_keywords, message) # tsunami example keywords = read_file_keywords(raster_tsunami_path) expected_keywords = { 'hazard_category': 'single_event', 'title': 'Tsunami', 'hazard': 'tsunami', 'continuous_hazard_unit': 'metres', 'layer_geometry': 'raster', 'layer_purpose': 'hazard', 'layer_mode': 'continuous', 'keyword_version': inasafe_keyword_version } message = 'Expected:\n%s\nGot:\n%s\n' % (expected_keywords, keywords) self.assertEqual(keywords, expected_keywords, message)
def test_zonal_with_exact_cell_boundaries(self): """Test that zonal stats returns the expected output.""" raster_layer, _ = load_layer( test_data_path('other', 'tenbytenraster.asc')) # Note this is a matrix of 11x11 polygons - one per cell # and one poly extending beyond to the right of each row # and one poly extending beyond the bottom of each col vector_layer, _ = load_layer( test_data_path('other', 'ten_by_ten_raster_as_polys.shp')) result = calculate_zonal_stats( raster_layer=raster_layer, polygon_layer=vector_layer) expected_result = { 0L: {'count': 1.0, 'sum': 0.0, 'mean': 0.0}, # TL polygon 9L: {'count': 1.0, 'sum': 9.0, 'mean': 9.0}, # TR polygon 25L: {'count': 1.0, 'sum': 3.0, 'mean': 3.0}, # Central polygon 88L: {'count': 1.0, 'sum': 0.0, 'mean': 0.0}, # BL polygon 108L: {'count': 1.0, 'sum': 9.0, 'mean': 9.0}} # BR polygon # We will just check TL, TR, Middle, BL and BR cells result = { 0L: result[0L], 9L: result[9L], 25L: result[25L], 88L: result[88L], 108L: result[108L]} # noinspection PyPep8Naming self.maxDiff = None self.assertDictEqual(expected_result, result)
def test_run(self): impact_function = FloodRasterBuildingFunction.instance() hazard_path = test_data_path('hazard', 'continuous_flood_20_20.asc') exposure_path = test_data_path('exposure', 'buildings.shp') hazard_layer = read_layer(hazard_path) exposure_layer = read_layer(exposure_path) impact_function.hazard = SafeLayer(hazard_layer) impact_function.exposure = SafeLayer(exposure_layer) impact_function.run() impact_layer = impact_function.impact # Extract calculated result impact_data = impact_layer.get_data() self.assertEqual(len(impact_data), 181) # 1 = inundated, 2 = wet, 3 = dry expected_result = { 1: 64, 2: 117, 3: 0 } result = { 1: 0, 2: 0, 3: 0 } for feature in impact_data: inundated_status = feature[impact_function.target_field] result[inundated_status] += 1 message = 'Expecting %s, but it returns %s' % (expected_result, result) self.assertEqual(expected_result, result, message)
def test_polygon_roads_impact(self): """Test FloodVectorRoadsExperimentalFunction work.""" hazard_name = test_data_path( 'hazard', 'multipart_polygons_osm_4326.shp') qgis_hazard = QgsVectorLayer(hazard_name, 'HAZARD', 'ogr') exposure_name = test_data_path('exposure', 'roads_osm_4326.shp') qgis_exposure = QgsVectorLayer(exposure_name, 'EXPOSURE', 'ogr') plugin_name = "FloodVectorRoadsExperimentalFunction" params = OrderedDict([ ('target_field', 'flooded'), ('road_type_field', 'TYPE'), ('affected_field', 'FLOODPRONE'), ('affected_value', 'YES') ]) impact = self._get_impact_function( qgis_hazard, qgis_exposure, plugin_name, params) keywords = impact.get_keywords() self.assertEquals(params['target_field'], keywords['target_field']) # Count of flooded objects is calculated "by hand" # the count = 63 count = sum(impact.get_data(attribute=keywords['target_field'])) self.assertEquals(count, 63)
def test_get_keyword_from_file(self): """Get keyword from a filesystem file's .keyword file.""" raster_layer = clone_raster_layer( 'jakarta_flood_design', '.tif', False, test_data_path('hazard')) raster_layer_path = raster_layer.source() keyword_file = test_data_path('other', 'jakarta_flood_design.keywords') raster_keyword_path = ( os.path.splitext(raster_layer_path)[0] + '.keywords') shutil.copy2(keyword_file, raster_keyword_path) keyword = read_file_keywords(raster_layer_path, 'layer_purpose') expected_keyword = 'hazard' self.assertEqual(keyword, expected_keyword) # Test we get an exception if keyword is not found self.assertRaises( KeywordNotFoundError, read_file_keywords, raster_layer_path, 'boguskeyword') # Test if all the keywords are all ready correctly keywords = read_file_keywords(raster_layer_path) expected_keywords = { 'hazard_category': 'single_event', 'hazard': 'flood', 'continuous_hazard_unit': 'metres', 'layer_purpose': 'hazard', 'layer_mode': 'continuous', 'title': 'Jakarta flood like 2007 with structural improvements', 'keyword_version': '3.2' } self.assertDictEqual(keywords, expected_keywords)
def test_run(self): function = FloodPolygonBuildingFunction.instance() hazard_path = test_data_path('hazard', 'flood_multipart_polygons.shp') # exposure_path = test_data_path('exposure', 'buildings.shp') # noinspection PyCallingNonCallable hazard_layer = QgsVectorLayer(hazard_path, 'Flood', 'ogr') # noinspection PyCallingNonCallable # exposure_layer = QgsVectorLayer(exposure_path, 'Buildings', 'ogr') exposure_layer = clone_shp_layer( name='buildings', include_keywords=True, source_directory=test_data_path('exposure')) # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum() ] function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.requested_extent = rect_extent function.run() impact = function.impact # Count of flooded objects is calculated "by the hands" # total flooded = 27, total buildings = 129 count = sum(impact.get_data(attribute=function.target_field)) self.assertEquals(count, 33) count = len(impact.get_data()) self.assertEquals(count, 176)
def test_run(self): function = ClassifiedRasterHazardBuildingFunction.instance() hazard_path = test_data_path('hazard', 'classified_flood_20_20.asc') exposure_path = test_data_path('exposure', 'buildings.shp') hazard_layer = read_layer(hazard_path) exposure_layer = read_layer(exposure_path) function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.run() impact_layer = function.impact impact_data = impact_layer.get_data() # Count expected_impact = {1.0: 67, 2.0: 49, 3.0: 64} result_impact = {1.0: 0, 2.0: 0, 3.0: 0} for impact_feature in impact_data: level = impact_feature['level'] if not math.isnan(level): result_impact[level] += 1 message = 'Expecting %s, but it returns %s' % (expected_impact, result_impact) self.assertEqual(expected_impact, result_impact, message)
def test_polygon_roads_impact(self): """Test FloodVectorRoadsExperimentalFunction work.""" hazard_name = test_data_path('hazard', 'multipart_polygons_osm_4326.shp') qgis_hazard = QgsVectorLayer(hazard_name, 'HAZARD', 'ogr') exposure_name = test_data_path('exposure', 'roads_osm_4326.shp') qgis_exposure = QgsVectorLayer(exposure_name, 'EXPOSURE', 'ogr') plugin_name = "FloodVectorRoadsExperimentalFunction" params = OrderedDict([('target_field', 'flooded'), ('road_type_field', 'TYPE'), ('affected_field', 'FLOODPRONE'), ('affected_value', 'YES')]) impact = self._get_impact_function(qgis_hazard, qgis_exposure, plugin_name, params) keywords = impact.get_keywords() self.assertEquals(params['target_field'], keywords['target_field']) # Count of flooded objects is calculated "by hand" # the count = 63 count = sum(impact.get_data(attribute=keywords['target_field'])) self.assertEquals(count, 63)
def test_run(self): """TestVolcanoPointBuildingFunction: Test running the IF.""" volcano_path = test_data_path('hazard', 'volcano_point.shp') building_path = test_data_path('exposure', 'buildings.shp') hazard_layer = read_layer(volcano_path) exposure_layer = read_layer(building_path) impact_function = VolcanoPointBuildingFunction.instance() impact_function.hazard = SafeLayer(hazard_layer) impact_function.exposure = SafeLayer(exposure_layer) impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ( 'In the event of volcano point how many buildings might be ' 'affected') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) # The buildings should all be categorised into 3000 zone zone_sum = sum(impact_layer.get_data( attribute=impact_function.target_field)) expected_sum = 3000 * 181 message = 'Expecting %s, but it returns %s' % (expected_sum, zone_sum) self.assertEqual(zone_sum, expected_sum, message)
def test_run(self): function = ClassifiedRasterHazardBuildingFunction.instance() hazard_path = test_data_path('hazard', 'classified_flood_20_20.asc') exposure_path = test_data_path('exposure', 'buildings.shp') hazard_layer = read_layer(hazard_path) exposure_layer = read_layer(exposure_path) function.hazard = hazard_layer function.exposure = exposure_layer function.run() impact_layer = function.impact impact_data = impact_layer.get_data() # Count expected_impact = { 1.0: 67, 2.0: 49, 3.0: 64 } result_impact = { 1.0: 0, 2.0: 0, 3.0: 0 } for impact_feature in impact_data: level = impact_feature['level'] if not math.isnan(level): result_impact[level] += 1 message = 'Expecting %s, but it returns %s' % ( expected_impact, result_impact) self.assertEqual(expected_impact, result_impact, message)
def test_run(self): function = FloodPolygonBuildingFunction.instance() hazard_path = test_data_path('hazard', 'flood_multipart_polygons.shp') # exposure_path = test_data_path('exposure', 'buildings.shp') # noinspection PyCallingNonCallable hazard_layer = QgsVectorLayer(hazard_path, 'Flood', 'ogr') # noinspection PyCallingNonCallable # exposure_layer = QgsVectorLayer(exposure_path, 'Buildings', 'ogr') exposure_layer = clone_shp_layer( name='buildings', include_keywords=True, source_directory=test_data_path('exposure')) # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()] function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.requested_extent = rect_extent function.run() impact = function.impact # Count of flooded objects is calculated "by the hands" # total flooded = 27, total buildings = 129 count = sum(impact.get_data(attribute=function.target_field)) self.assertEquals(count, 33) count = len(impact.get_data()) self.assertEquals(count, 176)
def test_run(self): """TestEarthquakeBuildingFunction: Test running the IF.""" eq_path = test_data_path("hazard", "earthquake.tif") building_path = test_data_path("exposure", "buildings.shp") eq_layer = read_layer(eq_path) building_layer = read_layer(building_path) impact_function = EarthquakeBuildingFunction.instance() impact_function.hazard = SafeLayer(eq_layer) impact_function.exposure = SafeLayer(building_layer) impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = "In the event of earthquake how many buildings might be affected" message = "The question should be %s, but it returns %s" % (expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) # Count by hand, # 1 = low, 2 = medium, 3 = high impact = {1: 0, 2: 181, 3: 0} result = {1: 0, 2: 0, 3: 0} impact_features = impact_layer.get_data() for i in range(len(impact_features)): impact_feature = impact_features[i] level = impact_feature.get(impact_function.target_field) result[level] += 1 message = "Expecting %s, but it returns %s" % (impact, result) self.assertEqual(impact, result, message)
def test_run(self): """TestClassifiedPolygonPopulationFunction: Test running the IF.""" generic_polygon_path = test_data_path( 'hazard', 'classified_generic_polygon.shp') population_path = test_data_path( 'exposure', 'pop_binary_raster_20_20.asc') generic_polygon_layer = read_layer(generic_polygon_path) population_layer = read_layer(population_path) impact_function = ClassifiedPolygonHazardPopulationFunction.instance() impact_function.hazard = SafeLayer(generic_polygon_layer) impact_function.exposure = SafeLayer(population_layer) impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In each of the hazard zones how many people ' 'might be impacted.') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) # Count by hand expected_affected_population = 181 result = numpy.nansum(impact_layer.get_data()) self.assertEqual(expected_affected_population, result, message)
def test_run(self): function = ContinuousHazardPopulationFunction.instance() hazard_path = test_data_path('hazard', 'continuous_flood_20_20.asc') exposure_path = test_data_path('exposure', 'pop_binary_raster_20_20.asc') hazard_layer = read_layer(hazard_path) exposure_layer = read_layer(exposure_path) function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.run() impact = function.impact # print "keywords", keywords keywords = impact.get_keywords() total_needs_full = keywords['total_needs'] total_needs_weekly = OrderedDict([[x['table name'], x['amount']] for x in total_needs_full['weekly']]) total_needs_single = OrderedDict([[x['table name'], x['amount']] for x in total_needs_full['single']]) self.assertEqual(total_needs_weekly['Rice [kg]'], 336) self.assertEqual(total_needs_weekly['Drinking Water [l]'], 2100) self.assertEqual(total_needs_weekly['Clean Water [l]'], 8040) self.assertEqual(total_needs_weekly['Family Kits'], 24) self.assertEqual(total_needs_single['Toilets'], 6)
def test_get_keyword_from_file(self): """Get keyword from a filesystem file's .keyword file.""" raster_shake_path = test_data_path("hazard", "jakarta_flood_design.tif") vector_path = test_data_path("exposure", "buildings_osm_4326.shp") raster_tsunami_path = test_data_path("hazard", "tsunami_wgs84.tif") keyword = read_file_keywords(raster_shake_path, "layer_purpose") expected_keyword = "hazard" message = ('The keyword "layer_purpose" for %s is %s. Expected keyword is: ' "%s") % ( raster_shake_path, keyword, expected_keyword, ) self.assertEqual(keyword, expected_keyword, message) # Test we get an exception if keyword is not found self.assertRaises(KeywordNotFoundError, read_file_keywords, raster_shake_path, "boguskeyword") # Test if all the keywords are all ready correctly keywords = read_file_keywords(raster_shake_path) expected_keywords = { "hazard_category": "single_event", "hazard": "flood", "continuous_hazard_unit": "metres", "layer_purpose": "hazard", "layer_mode": "continuous", "title": "Jakarta flood like 2007 with structural improvements", "keyword_version": inasafe_keyword_version, } message = "Expected:\n%s\nGot:\n%s\n" % (expected_keywords, keywords) self.assertDictEqual(keywords, expected_keywords, message) # Test reading keywords from vector layer keywords = read_file_keywords(vector_path) expected_keywords = { "keyword_version": inasafe_keyword_version, "structure_class_field": "FLOODED", "title": "buildings_osm_4326", "layer_geometry": "polygon", "layer_purpose": "exposure", "layer_mode": "classified", "exposure": "structure", } message = "Expected:\n%s\nGot:\n%s\n" % (expected_keywords, keywords) self.assertDictEqual(keywords, expected_keywords, message) # tsunami example keywords = read_file_keywords(raster_tsunami_path) expected_keywords = { "hazard_category": "single_event", "title": "Tsunami", "hazard": "tsunami", "continuous_hazard_unit": "metres", "layer_geometry": "raster", "layer_purpose": "hazard", "layer_mode": "continuous", "keyword_version": inasafe_keyword_version, } message = "Expected:\n%s\nGot:\n%s\n" % (expected_keywords, keywords) self.assertEqual(keywords, expected_keywords, message)
def test_state(self): """Check if the save/restore state methods work. See also https://github.com/AIFDR/inasafe/issues/58 """ # default selected layer is the third layer exposure # so, decrease the index by one to change it DOCK.cboExposure.setCurrentIndex(DOCK.cboExposure.currentIndex() - 1) DOCK.save_state() expected_dict = get_ui_state(DOCK) # myState = DOCK.state # Now reset and restore and check that it gets the old state # Html is not considered in restore test since the ready # message overwrites it in dock implementation DOCK.cboExposure.setCurrentIndex(DOCK.cboExposure.currentIndex() - 1) DOCK.restore_state() result_dict = get_ui_state(DOCK) message = 'Got unexpected state: %s\nExpected: %s\n%s' % ( result_dict, expected_dict, combos_to_string(DOCK)) self.assertTrue(expected_dict == result_dict, message) # Corner case test when two layers can have the # same functions - when switching layers the selected function should # remain unchanged self.tearDown() file_list = [ test_data_path('hazard', 'jakarta_flood_design.tif'), test_data_path('hazard', 'continuous_flood_20_20.asc'), test_data_path('exposure', 'pop_binary_raster_20_20.asc') ] hazard_layer_count, exposure_layer_count = load_layers(file_list) self.assertTrue(hazard_layer_count == 2) self.assertTrue(exposure_layer_count == 1) # we will have 2 impact function available right now: # - ContinuousHazardPopulationFunction, titled: 'Be impacted' # - FloodEvacuationRasterHazardFunction, titled: 'Need evacuation' # set it to the second for testing purposes DOCK.cboFunction.setCurrentIndex(1) DOCK.cboHazard.setCurrentIndex(0) DOCK.cboExposure.setCurrentIndex(0) expected_function = str(DOCK.cboFunction.currentText()) # Now move down one hazard in the combo then verify # the function remains unchanged DOCK.cboHazard.setCurrentIndex(1) current_function = str(DOCK.cboFunction.currentText()) message = ( 'Expected selected impact function to remain unchanged when ' 'choosing a different hazard of the same category:' ' %s\nExpected: %s\n%s' % (expected_function, current_function, combos_to_string(DOCK))) self.assertTrue(expected_function == current_function, message) DOCK.cboHazard.setCurrentIndex(0) # Selected function should remain the same # RM: modified it, because there is generic one right now as the first. # the selected one should be FloodEvacuationRasterHazardFunction DOCK.cboFunction.setCurrentIndex(1) expected = 'Need evacuation' function = DOCK.cboFunction.currentText() message = 'Expected: %s, Got: %s' % (expected, function) self.assertTrue(function == expected, message)
def test_run(self): """TestVolcanoPolygonBuildingFunction: Test running the IF.""" volcano_path = test_data_path('hazard', 'volcano_krb.shp') building_path = test_data_path('exposure', 'buildings.shp') hazard_layer = read_layer(volcano_path) exposure_layer = read_layer(building_path) impact_function = VolcanoPolygonBuildingFunction.instance() impact_function.hazard = hazard_layer impact_function.exposure = exposure_layer impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In the event of volcano krb how many buildings ' 'might be affected') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) # The buildings should all be categorised into 5000 zone zone_sum = impact_layer.get_data(attribute='zone') krb3_zone_count = zone_sum.count('Kawasan Rawan Bencana III') krb2_zone_count = zone_sum.count('Kawasan Rawan Bencana II') # The result (counted by hand) expected_krb3_count = 11 expected_krb2_count = 161 message = 'Expecting %s for KRB III zone, but it returns %s' % ( krb3_zone_count, expected_krb3_count) self.assertEqual(krb3_zone_count, expected_krb3_count, message) message = 'Expecting %s for KRB II zone, but it returns %s' % ( krb2_zone_count, expected_krb2_count) self.assertEqual(krb2_zone_count, expected_krb2_count, message)
def test_run(self): function = FloodRasterRoadsFunction.instance() hazard_path = test_data_path('hazard', 'continuous_flood_20_20.asc') exposure_path = test_data_path('exposure', 'roads.shp') # noinspection PyCallingNonCallable hazard_layer = QgsRasterLayer(hazard_path, 'Flood') # noinspection PyCallingNonCallable exposure_layer = QgsVectorLayer(exposure_path, 'Roads', 'ogr') # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()] function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.requested_extent = rect_extent function.run() impact = function.impact keywords = impact.get_keywords() self.assertEquals(function.target_field, keywords['target_field']) expected_inundated_feature = 182 count = sum(impact.get_data(attribute=function.target_field)) self.assertEquals(count, expected_inundated_feature)
def test_issue160(self): """Test that multipart features can be used in a scenario - issue #160 """ exposure = test_data_path('exposure', 'buildings.shp') hazard = test_data_path('hazard', 'flood_multipart_polygons.shp') # See https://github.com/AIFDR/inasafe/issues/71 # Push OK with the left mouse button # print 'Using QGIS: %s' % qgis_version() self.tearDown() button = DOCK.pbnRunStop # First part of scenario should have enabled run file_list = [hazard, exposure] hazard_layer_count, exposure_layer_count = load_layers(file_list) message = ( 'Incorrect number of Hazard layers: expected 1 got %s' % hazard_layer_count) self.assertTrue(hazard_layer_count == 1, message) message = ( 'Incorrect number of Exposure layers: expected 1 got %s' % exposure_layer_count) self.assertTrue(exposure_layer_count == 1, message) message = 'Run button was not enabled' self.assertTrue(button.isEnabled(), message) # Second part of scenario - run disabled when adding invalid layer # and select it - run should be disabled path = os.path.join(TESTDATA, 'issue71.tif') file_list = [path] # This layer has incorrect keywords clear_flag = False _, _ = load_layers(file_list, clear_flag) result, message = setup_scenario( DOCK, hazard='Flood Polygon', exposure='Buildings', function='Be flooded', function_id='FloodPolygonBuildingFunction') self.assertTrue(result, message) # Enable on-the-fly reprojection set_canvas_crs(GEOCRS, True) expected_extent = QgsRectangle( 106.80801, -6.19531, 106.83456946836641, -6.167526) CANVAS.setExtent(expected_extent) crs = QgsCoordinateReferenceSystem('EPSG:4326') DOCK.define_user_analysis_extent(expected_extent, crs) # Press RUN # noinspection PyCallByClass,PyCallByClass,PyTypeChecker DOCK.accept() result = DOCK.wvResults.page_to_text() message = 'Result not as expected: %s' % result self.assertTrue(format_int(33) in result, message)
def test_issue71(self): """Test issue #71 in github - cbo changes should update ok button.""" # See https://github.com/AIFDR/inasafe/issues/71 settings = QtCore.QSettings() settings.setValue('inasafe/analysis_extents_mode', 'HazardExposure') self.tearDown() button = self.dock.pbnRunStop # First part of scenario should have enabled run file_list = [ test_data_path('hazard', 'continuous_flood_20_20.asc'), test_data_path('exposure', 'pop_binary_raster_20_20.asc') ] hazard_layer_count, exposure_layer_count = load_layers(file_list) message = ('Incorrect number of Hazard layers: expected 1 got %s' % hazard_layer_count) self.assertTrue(hazard_layer_count == 1, message) message = ('Incorrect number of Exposure layers: expected 1 got %s' % exposure_layer_count) self.assertTrue(exposure_layer_count == 1, message) message = 'Run button was not enabled' self.assertTrue(button.isEnabled(), message) # Second part of scenario - run disabled when adding invalid layer # and select it - run should be disabled path = os.path.join(TESTDATA, 'issue71.tif') file_list = [path] # This layer has incorrect keywords clear_flag = False _, _ = load_layers(file_list, clear_flag) # set exposure to : Population Count (5kmx5km) # by moving one down self.dock.cboExposure.setCurrentIndex( self.dock.cboExposure.currentIndex() + 1) actual_dict = get_ui_state(self.dock) expected_dict = { 'Run Button Enabled': False, 'Impact Function Id': '', 'Impact Function Title': '', 'Hazard': 'Continuous Flood', 'Exposure': 'Population Count (5kmx5km)' } message = (('Run button was not disabled when exposure set to \n%s' '\nUI State: \n%s\nExpected State:\n%s\n%s') % (self.dock.cboExposure.currentText(), actual_dict, expected_dict, combos_to_string(self.dock))) self.assertTrue(expected_dict == actual_dict, message) # Now select again a valid layer and the run button # should be enabled self.dock.cboExposure.setCurrentIndex( self.dock.cboExposure.currentIndex() - 1) message = ('Run button was not enabled when exposure set to \n%s' % self.dock.cboExposure.currentText()) self.assertTrue(button.isEnabled(), message)
def test_issue160(self): """Test that multipart features can be used in a scenario - issue #160 """ exposure = test_data_path('exposure', 'buildings.shp') hazard = test_data_path('hazard', 'flood_multipart_polygons.shp') # See https://github.com/AIFDR/inasafe/issues/71 # Push OK with the left mouse button # print 'Using QGIS: %s' % qgis_version() self.tearDown() button = DOCK.pbnRunStop # First part of scenario should have enabled run file_list = [hazard, exposure] hazard_layer_count, exposure_layer_count = load_layers(file_list) message = ('Incorrect number of Hazard layers: expected 1 got %s' % hazard_layer_count) self.assertTrue(hazard_layer_count == 1, message) message = ('Incorrect number of Exposure layers: expected 1 got %s' % exposure_layer_count) self.assertTrue(exposure_layer_count == 1, message) message = 'Run button was not enabled' self.assertTrue(button.isEnabled(), message) # Second part of scenario - run disabled when adding invalid layer # and select it - run should be disabled path = os.path.join(TESTDATA, 'issue71.tif') file_list = [path] # This layer has incorrect keywords clear_flag = False _, _ = load_layers(file_list, clear_flag) result, message = setup_scenario( DOCK, hazard='Flood Polygon', exposure='Buildings', function='Be flooded', function_id='FloodPolygonBuildingFunction') self.assertTrue(result, message) # Enable on-the-fly reprojection set_canvas_crs(GEOCRS, True) expected_extent = QgsRectangle(106.80801, -6.19531, 106.83456946836641, -6.167526) CANVAS.setExtent(expected_extent) crs = QgsCoordinateReferenceSystem('EPSG:4326') DOCK.define_user_analysis_extent(expected_extent, crs) # Press RUN # noinspection PyCallByClass,PyCallByClass,PyTypeChecker DOCK.accept() result = DOCK.wvResults.page_to_text() message = 'Result not as expected: %s' % result self.assertTrue(format_int(33) in result, message)
def test_run_point_exposure(self): """Run the IF for point exposure. See https://github.com/AIFDR/inasafe/issues/2156. """ generic_polygon_path = test_data_path( 'hazard', 'classified_generic_polygon.shp') building_path = test_data_path('exposure', 'building-points.shp') hazard_layer = QgsVectorLayer(generic_polygon_path, 'Hazard', 'ogr') exposure_layer = QgsVectorLayer(building_path, 'Buildings', 'ogr') # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum() ] impact_function = ClassifiedPolygonHazardBuildingFunction.instance() impact_function.hazard = SafeLayer(hazard_layer) impact_function.exposure = SafeLayer(exposure_layer) impact_function.requested_extent = rect_extent impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In each of the hazard zones how many buildings ' 'might be affected.') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) zone_sum = impact_layer.get_data( attribute=impact_function.target_field) high_zone_count = zone_sum.count('High Hazard Zone') medium_zone_count = zone_sum.count('Medium Hazard Zone') low_zone_count = zone_sum.count('Low Hazard Zone') # The result expected_high_count = 12 expected_medium_count = 172 expected_low_count = 3 message = 'Expecting %s for High Hazard Zone, but it returns %s' % ( high_zone_count, expected_high_count) self.assertEqual(high_zone_count, expected_high_count, message) message = 'Expecting %s for Medium Hazard Zone, but it returns %s' % ( expected_medium_count, medium_zone_count) self.assertEqual(medium_zone_count, expected_medium_count, message) message = 'Expecting %s for Low Hazard Zone, but it returns %s' % ( expected_low_count, low_zone_count) self.assertEqual(expected_low_count, low_zone_count, message)
def test_get_keyword_from_file(self): """Get keyword from a filesystem file's .keyword file.""" raster_shake_path = test_data_path( 'hazard', 'jakarta_flood_design.tif') vector_path = test_data_path( 'exposure', 'buildings_osm_4326.shp') raster_tsunami_path = test_data_path( 'hazard', 'tsunami_wgs84.tif') keyword = read_file_keywords(raster_shake_path, 'category') expected_keyword = 'hazard' message = ('The keyword "category" for %s is %s. Expected keyword is: ' '%s') % (raster_shake_path, keyword, expected_keyword) self.assertEqual(keyword, expected_keyword, message) # Test we get an exception if keyword is not found self.assertRaises( KeywordNotFoundError, read_file_keywords, raster_shake_path, 'boguskeyword') # Test if all the keywords are all ready correctly keywords = read_file_keywords(raster_shake_path) expected_keywords = { 'category': 'hazard', 'subcategory': 'flood', 'data_type': 'continuous', 'unit': 'metres_depth', 'title': 'Jakarta flood like 2007 with structural improvements'} message = 'Expected:\n%s\nGot:\n%s\n' % (expected_keywords, keywords) self.assertEqual(keywords, expected_keywords, message) # Test reading keywords from vector layer keywords = read_file_keywords(vector_path) expected_keywords = { 'category': 'exposure', 'datatype': 'osm', 'subcategory': 'structure', 'title': 'buildings_osm_4326', 'purpose': 'dki'} message = 'Expected:\n%s\nGot:\n%s\n' % (expected_keywords, keywords) self.assertEqual(keywords, expected_keywords, message) # tsunami example keywords = read_file_keywords(raster_tsunami_path) expected_keywords = { 'category': 'hazard', 'unit': 'metres_depth', 'subcategory': 'tsunami', 'data_type': 'continuous', 'title': 'Tsunami' } message = 'Expected:\n%s\nGot:\n%s\n' % (expected_keywords, keywords) self.assertEqual(keywords, expected_keywords, message)
def test_run(self): """TestPagerEarthquakeFatalityFunction: Test running the IF.""" eq_path = test_data_path('hazard', 'earthquake.tif') population_path = test_data_path( 'exposure', 'pop_binary_raster_20_20.asc') # For EQ on Pops we need to clip the hazard and exposure first to the # same dimension clipped_hazard, clipped_exposure = clip_layers(eq_path, population_path) # noinspection PyUnresolvedReferences eq_layer = read_layer( str(clipped_hazard.source())) # noinspection PyUnresolvedReferences population_layer = read_layer( str(clipped_exposure.source())) impact_function = PAGFatalityFunction.instance() impact_function.hazard = eq_layer impact_function.exposure = population_layer impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In the event of earthquake how many ' 'population might die or be displaced according ' 'pager model') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) expected_exposed_per_mmi = { 2.0: 0, 2.5: 0, 3.0: 0, 3.5: 0, 4.0: 0, 4.5: 0, 5.0: 0, 5.5: 0, 6.5: 0, 6.0: 0, 7.0: 0, 7.5: 60, 8.0: 140, 8.5: 0, 9.0: 0, 9.5: 0} result = impact_layer.get_keywords('exposed_per_mmi') message = 'Expecting %s, but it returns %s' % ( expected_exposed_per_mmi, result) self.assertEqual(expected_exposed_per_mmi, result, message)
def test_run(self): """TestPagerEarthquakeFatalityFunction: Test running the IF.""" eq_path = test_data_path('hazard', 'earthquake.tif') population_path = test_data_path('exposure', 'pop_binary_raster_20_20.asc') # For EQ on Pops we need to clip the hazard and exposure first to the # same dimension clipped_hazard, clipped_exposure = clip_layers(eq_path, population_path) # noinspection PyUnresolvedReferences eq_layer = read_layer(str(clipped_hazard.source())) # noinspection PyUnresolvedReferences population_layer = read_layer(str(clipped_exposure.source())) impact_function = PAGFatalityFunction.instance() impact_function.hazard = eq_layer impact_function.exposure = population_layer impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In the event of earthquake how many ' 'population might die or be displaced according ' 'pager model') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) expected_exposed_per_mmi = { 2.0: 0, 2.5: 0, 3.0: 0, 3.5: 0, 4.0: 0, 4.5: 0, 5.0: 0, 5.5: 0, 6.5: 0, 6.0: 0, 7.0: 0, 7.5: 60, 8.0: 140, 8.5: 0, 9.0: 0, 9.5: 0 } result = impact_layer.get_keywords('exposed_per_mmi') message = 'Expecting %s, but it returns %s' % ( expected_exposed_per_mmi, result) self.assertEqual(expected_exposed_per_mmi, result, message)
def test_get_keyword_from_file(self): """Get keyword from a filesystem file's .keyword file.""" raster_shake_path = test_data_path('hazard', 'jakarta_flood_design.tif') vector_path = test_data_path('exposure', 'buildings_osm_4326.shp') raster_tsunami_path = test_data_path('hazard', 'tsunami_wgs84.tif') keyword = read_file_keywords(raster_shake_path, 'category') expected_keyword = 'hazard' message = ('The keyword "category" for %s is %s. Expected keyword is: ' '%s') % (raster_shake_path, keyword, expected_keyword) self.assertEqual(keyword, expected_keyword, message) # Test we get an exception if keyword is not found self.assertRaises(KeywordNotFoundError, read_file_keywords, raster_shake_path, 'boguskeyword') # Test if all the keywords are all ready correctly keywords = read_file_keywords(raster_shake_path) expected_keywords = { 'category': 'hazard', 'subcategory': 'flood', 'data_type': 'continuous', 'unit': 'metres_depth', 'title': 'Jakarta flood like 2007 with structural improvements' } message = 'Expected:\n%s\nGot:\n%s\n' % (expected_keywords, keywords) self.assertEqual(keywords, expected_keywords, message) # Test reading keywords from vector layer keywords = read_file_keywords(vector_path) expected_keywords = { 'category': 'exposure', 'datatype': 'osm', 'subcategory': 'structure', 'title': 'buildings_osm_4326', 'purpose': 'dki' } message = 'Expected:\n%s\nGot:\n%s\n' % (expected_keywords, keywords) self.assertEqual(keywords, expected_keywords, message) # tsunami example keywords = read_file_keywords(raster_tsunami_path) expected_keywords = { 'category': 'hazard', 'unit': 'metres_depth', 'subcategory': 'tsunami', 'data_type': 'continuous', 'title': 'Tsunami' } message = 'Expected:\n%s\nGot:\n%s\n' % (expected_keywords, keywords) self.assertEqual(keywords, expected_keywords, message)
def test_run_point_exposure(self): """Run the IF for point exposure. See https://github.com/AIFDR/inasafe/issues/2156. """ generic_polygon_path = test_data_path( 'hazard', 'classified_generic_polygon.shp') building_path = test_data_path('exposure', 'building-points.shp') hazard_layer = QgsVectorLayer(generic_polygon_path, 'Hazard', 'ogr') exposure_layer = QgsVectorLayer(building_path, 'Buildings', 'ogr') # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()] impact_function = ClassifiedPolygonHazardBuildingFunction.instance() impact_function.hazard = SafeLayer(hazard_layer) impact_function.exposure = SafeLayer(exposure_layer) impact_function.requested_extent = rect_extent impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In each of the hazard zones how many buildings ' 'might be affected.') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) zone_sum = impact_layer.get_data( attribute=impact_function.target_field) high_zone_count = zone_sum.count('High Hazard Zone') medium_zone_count = zone_sum.count('Medium Hazard Zone') low_zone_count = zone_sum.count('Low Hazard Zone') # The result expected_high_count = 12 expected_medium_count = 172 expected_low_count = 3 message = 'Expecting %s for High Hazard Zone, but it returns %s' % ( high_zone_count, expected_high_count) self.assertEqual(high_zone_count, expected_high_count, message) message = 'Expecting %s for Medium Hazard Zone, but it returns %s' % ( expected_medium_count, medium_zone_count) self.assertEqual(medium_zone_count, expected_medium_count, message) message = 'Expecting %s for Low Hazard Zone, but it returns %s' % ( expected_low_count, low_zone_count) self.assertEqual(expected_low_count, low_zone_count, message)
def test_calculate_impact(self): """Test calculating impact.""" eq_path = test_data_path('hazard', 'earthquake.tif') building_path = test_data_path('exposure', 'buildings.shp') eq_layer = read_layer(eq_path) building_layer = read_layer(building_path) impact_function = EarthquakeBuildingFunction.instance() impact_function.hazard = SafeLayer(eq_layer) impact_function.exposure = SafeLayer(building_layer) impact_layer = calculate_impact(impact_function) self.assertIsNotNone(impact_layer)
def test_raster_to_vector_and_line_intersection(self): """Test the core part of the analysis. 1. Test creation of spatial index of flood cells 2. Test intersection of flood cells with roads layer """ raster_name = test_data_path( 'hazard', 'tsunami_wgs84.tif') exposure_name = test_data_path( 'exposure', 'roads_osm_4326.shp') raster = QgsRasterLayer(raster_name, 'Flood') exposure = QgsVectorLayer(exposure_name, 'Exposure', 'ogr') ranges = OrderedDict() ranges[0] = [0, 1] ranges[1] = [1, 2] ranges[2] = [2, 100] index, flood_cells_map = _raster_to_vector_cells( raster, ranges, exposure.crs()) self.assertEqual(len(flood_cells_map), 4198) rect_with_all_cells = raster.extent() rect_with_4_cells = QgsRectangle(106.824, -6.177, 106.825, -6.179) rect_with_0_cells = QgsRectangle(106.818, -6.168, 106.828, -6.175) self.assertEqual(len(index.intersects(rect_with_all_cells)), 4198) self.assertEqual(len(index.intersects(rect_with_4_cells)), 43) self.assertEqual(len(index.intersects(rect_with_0_cells)), 504) layer = create_layer(exposure) new_field = QgsField('flooded', QVariant.Int) layer.dataProvider().addAttributes([new_field]) request = QgsFeatureRequest() _intersect_lines_with_vector_cells( exposure, request, index, flood_cells_map, layer, 'flooded') feature_count = layer.featureCount() self.assertEqual(feature_count, 388) flooded = 0 iterator = layer.getFeatures() for feature in iterator: attributes = feature.attributes() if attributes[3] == 1: flooded += 1 self.assertEqual(flooded, 40)
def test_building_native_impact_experimental(self): """Test flood_building_native_impact_experimental.""" hazard_name = test_data_path( 'hazard', 'multipart_polygons_osm_4326.shp') qgis_hazard = QgsVectorLayer(hazard_name, 'HAZARD', 'ogr') exposure_name = test_data_path('exposure', 'buildings_osm_4326.shp') qgis_exposure = QgsVectorLayer(exposure_name, 'EXPOSURE', 'ogr') plugin_name = "FloodNativePolygonExperimentalFunction" params = OrderedDict( [ ('target_field', 'FLOODED'), ('building_type_field', 'TYPE'), ('affected_field', 'FLOOD'), ('affected_value', 'YES') ] ) # The params are not match field names of hazard self.assertRaises( GetDataError, self._get_impact_function, qgis_hazard, qgis_exposure, plugin_name, params ) # Set up real field name params = OrderedDict( [ ('target_field', 'FLOODED'), ('building_type_field', 'TYPE'), ('affected_field', 'FLOODPRONE'), ('affected_value', 'YES') ] ) impact = self._get_impact_function( qgis_hazard, qgis_exposure, plugin_name, params) keywords = impact.get_keywords() self.assertEquals(params['target_field'], keywords['target_field']) # Count of flooded objects is calculated "by the hands" # the count = 68 count = sum(impact.get_data(attribute=keywords['target_field'])) self.assertEquals(count, 68)
def test_zonal_with_exact_cell_boundaries(self): """Test that zonal stats returns the expected output.""" raster_layer, _ = load_layer( test_data_path('other', 'tenbytenraster.asc')) # Note this is a matrix of 11x11 polygons - one per cell # and one poly extending beyond to the right of each row # and one poly extending beyond the bottom of each col vector_layer, _ = load_layer( test_data_path('other', 'ten_by_ten_raster_as_polys.shp')) result = calculate_zonal_stats(raster_layer=raster_layer, polygon_layer=vector_layer) expected_result = { 0L: { 'count': 1.0, 'sum': 0.0, 'mean': 0.0 }, # TL polygon 9L: { 'count': 1.0, 'sum': 9.0, 'mean': 9.0 }, # TR polygon 25L: { 'count': 1.0, 'sum': 3.0, 'mean': 3.0 }, # Central polygon 88L: { 'count': 1.0, 'sum': 0.0, 'mean': 0.0 }, # BL polygon 108L: { 'count': 1.0, 'sum': 9.0, 'mean': 9.0 } } # BR polygon # We will just check TL, TR, Middle, BL and BR cells result = { 0L: result[0L], 9L: result[9L], 25L: result[25L], 88L: result[88L], 108L: result[108L] } # noinspection PyPep8Naming self.maxDiff = None self.assertDictEqual(expected_result, result)
def test_stacktrace_html(self): """Stack traces can be caught and rendered as html """ # This is about general exception handling, so ok to use catch-all # pylint: disable=W0703 try: bbox_intersection('aoeu', 'oaeu', []) except Exception, e: # Display message and traceback message = get_error_message(e) # print message message = message.to_text() self.assertIn(str(e), message) self.assertIn('line', message) self.assertIn('file', message) message = get_error_message(e) message = message.to_html() assert str(e) in message message = message.decode('string_escape') control_file_path = test_data_path( 'control', 'files', 'test-stacktrace-html.txt') expected_results = open(control_file_path).read().replace('\n', '') self.assertIn(expected_results, message)
def test_full_run_pyzstats(self): """Aggregation results correct using our own python zonal stats code. """ path = os.path.join(BOUNDDATA, 'kabupaten_jakarta.shp') file_list = [path] load_layers(file_list, clear_flag=False) result, message = setup_scenario( DOCK, hazard='A flood in Jakarta like in 2007', exposure='People', function='Need evacuation', function_id='Flood Evacuation Function', aggregation_layer='kabupaten jakarta', aggregation_enabled_flag=True) self.assertTrue(result, message) # Enable on-the-fly reprojection set_canvas_crs(GEOCRS, True) set_jakarta_extent(DOCK) # Press RUN # noinspection PyCallByClass,PyTypeChecker DOCK.accept() result = DOCK.wvResults.page_to_text() control_file_path = test_data_path('control', 'files', 'test-full-run-results.txt') expected_result = open(control_file_path, 'r').readlines() result = result.replace('</td> <td>', ' ').replace('</td><td>', ' ') for line in expected_result: line = line.replace('\n', '') self.assertIn(line, result)
def test_volcano_building_impact(self): """Building impact from volcanic hazard is computed correctly.""" # Name file names for hazard level, exposure and expected fatalities hazard_filename = os.path.join(TESTDATA, 'donut.shp') exposure_filename = test_data_path('exposure', 'bangunan.shp') # Calculate impact using API hazard = read_layer(hazard_filename) exposure = read_layer(exposure_filename) plugin_name = 'Volcano Building Impact' impact_function = get_plugin(plugin_name) impact_function.parameters['name attribute'] = 'GUNUNG' print 'Calculating' # Call calculation engine impact_layer = calculate_impact( layers=[hazard, exposure], impact_fcn=impact_function) impact_filename = impact_layer.get_filename() impact = read_layer(impact_filename) keywords = impact.get_keywords() # Check for expected results: for value in ['Merapi', 5, 86, 91, 1, 21, 22, 6, 107, 113]: if isinstance(value, int): x = format_int(value) else: x = value summary = keywords['impact_summary'] message = ( 'Did not find expected value %s in summary %s' % (x, summary)) self.assertIn(x, summary, message)
def test_write_keyword_in_iso_metadata(self): keyword_file = test_data_path('other', 'expected_multilayer.keywords') with open(keyword_file) as f: keywords = f.read() basename, _ = os.path.splitext(keyword_file) xml_file = basename + '.xml' if os.path.isfile(xml_file): os.remove(xml_file) # there should be no xml file now self.assertFalse( os.path.isfile(xml_file), 'File %s should not exist' % xml_file) xml_file = write_keyword_in_iso_metadata(keyword_file) tree = ElementTree.parse(xml_file) root = tree.getroot() keyword_tag = root.find(ISO_METADATA_KEYWORD_TAG) self.assertIn(keywords, keyword_tag.text) # there should be an xml file now self.assertTrue( os.path.isfile(xml_file), 'File %s should exist' % xml_file) # lets update the file xml_file = write_keyword_in_iso_metadata(keyword_file) tree = ElementTree.parse(xml_file) keyword_tag = tree.getroot().find(ISO_METADATA_KEYWORD_TAG) self.assertIn(keywords, keyword_tag.text) os.remove(xml_file)