def generate_impact_report(impact_function, iface): """Generate the impact report from an impact function. :param impact_function: The impact function used. :type impact_function: ImpactFunction :param iface: QGIS QGisAppInterface instance. :type iface: QGisAppInterface """ # create impact report instance report_metadata = ReportMetadata( metadata_dict=standard_impact_report_metadata_pdf) impact_report = ImpactReport( iface, report_metadata, impact_function=impact_function) # generate report folder # no other option for now # TODO: retrieve the information from data store if isinstance(impact_function.datastore.uri, QDir): layer_dir = impact_function.datastore.uri.absolutePath() else: # No other way for now return # We will generate it on the fly without storing it after datastore # supports impact_report.output_folder = os.path.join(layer_dir, 'output') return impact_report.process_components()
def generate_pdf_report(self, impact_function, iface, scenario_name): """Generate and store map and impact report from impact function. Directory where the report stored is specified by user input from the dialog. This function is adapted from analysis_utilities.py :param impact_function: Impact Function. :type impact_function: ImpactFunction() :param iface: iface. :type iface: iface :param scenario_name: name of the scenario :type scenario_name: str """ # output folder output_dir = self.output_directory.text() file_path = os.path.join(output_dir, scenario_name) # create impact table report instance table_report_metadata = ReportMetadata( metadata_dict=standard_impact_report_metadata_pdf) impact_table_report = ImpactReport( iface, table_report_metadata, impact_function=impact_function) impact_table_report.output_folder = file_path impact_table_report.process_components() # create impact map report instance map_report_metadata = ReportMetadata( metadata_dict=update_template_component(map_report)) impact_map_report = ImpactReport( iface, map_report_metadata, impact_function=impact_function) # TODO: Get from settings file # get the extent of impact layer impact_map_report.qgis_composition_context.extent = \ impact_function.impact.extent() impact_map_report.output_folder = file_path impact_map_report.process_components()
def generate_impact_map_report(impact_function, iface): """Generate impact map pdf from impact function. :param impact_function: The impact function used. :type impact_function: ImpactFunction :param iface: QGIS QGisAppInterface instance. :type iface: QGisAppInterface """ # create impact report instance report_metadata = ReportMetadata( metadata_dict=map_report_component(report_a4_blue)) impact_report = ImpactReport( iface, report_metadata, impact_function=impact_function) # Get other setting logo_path = setting('organisation_logo_path', None, str) impact_report.inasafe_context.organisation_logo = logo_path disclaimer_text = setting('reportDisclaimer', None, str) impact_report.inasafe_context.disclaimer = disclaimer_text north_arrow_path = setting('north_arrow_path', None, str) impact_report.inasafe_context.north_arrow = north_arrow_path # get the extent of impact layer impact_report.qgis_composition_context.extent = \ impact_function.impact.extent() # generate report folder # no other option for now # TODO: retrieve the information from data store if isinstance(impact_function.datastore.uri, QDir): layer_dir = impact_function.datastore.uri.absolutePath() else: # No other way for now return # We will generate it on the fly without storing it after datastore # supports impact_report.output_folder = os.path.join(layer_dir, 'output') return impact_report.process_components()
def generate_infographic_report(impact_function, iface): """Generate impact map pdf from impact function. :param impact_function: The impact function used. :type impact_function: ImpactFunction :param iface: QGIS QGisAppInterface instance. :type iface: QGisAppInterface """ # get the extra layers that we need extra_layers = [] print_atlas = setting('print_atlas_report', False, bool) if print_atlas: extra_layers.append(impact_function.aggregation_summary) # create impact report instance report_metadata = ReportMetadata( metadata_dict=update_template_component(infographic_report)) impact_report = ImpactReport( iface, report_metadata, impact_function=impact_function, extra_layers=extra_layers) # get the extent of impact layer impact_report.qgis_composition_context.extent = \ impact_function.impact.extent() # generate report folder # no other option for now # TODO: retrieve the information from data store if isinstance(impact_function.datastore.uri, QDir): layer_dir = impact_function.datastore.uri.absolutePath() else: # No other way for now return # We will generate it on the fly without storing it after datastore # supports impact_report.output_folder = os.path.join(layer_dir, 'output') return impact_report.process_components()
def test_hello_world_report(self): """Test for creating hello world report. .. versionadded:: 4.1 """ QGIS_APP, CANVAS, IFACE, PARENT = get_qgis_app(qsetting=INASAFE_TEST) output_folder = self.fixtures_dir('../output/hello_world_report') # sneaky monkey patch ImpactFunction.outputs = ['Not implemented'] impact_function = ImpactFunction() template_metadata = ReportMetadata( metadata_dict=hello_world_metadata_html) impact_report = ImpactReport( iface=IFACE, template_metadata=template_metadata, impact_function=impact_function) impact_report.output_folder = output_folder impact_report.process_components()
def test_hello_world_report(self): """Test for creating hello world report. .. versionadded:: 4.1 """ QGIS_APP, CANVAS, IFACE, PARENT = get_qgis_app() output_folder = self.fixtures_dir('../output/hello_world_report') # sneaky monkey patch ImpactFunction.outputs = ['Not implemented'] impact_function = ImpactFunction() template_metadata = ReportMetadata( metadata_dict=hello_world_metadata_html) impact_report = ImpactReport( iface=IFACE, template_metadata=template_metadata, impact_function=impact_function) impact_report.output_folder = output_folder impact_report.process_components()
def generate_impact_report(impact_function, iface): """Generate the impact report from an impact function. :param impact_function: The impact function used. :type impact_function: ImpactFunction :param iface: QGIS QGisAppInterface instance. :type iface: QGisAppInterface """ # get the extra layers that we need extra_layers = [] print_atlas = setting('print_atlas_report', False, bool) if print_atlas: extra_layers.append(impact_function.aggregation_summary) # create impact report instance report_metadata = ReportMetadata( metadata_dict=standard_impact_report_metadata_pdf) impact_report = ImpactReport(iface, report_metadata, impact_function=impact_function, extra_layers=extra_layers) # generate report folder # no other option for now # TODO: retrieve the information from data store if isinstance(impact_function.datastore.uri, QDir): layer_dir = impact_function.datastore.uri.absolutePath() else: # No other way for now return # We will generate it on the fly without storing it after datastore # supports impact_report.output_folder = os.path.join(layer_dir, 'output') return impact_report.process_components()
def generate_impact_map_report(cli_arguments, impact_function, iface): """Generate impact map pdf from impact function. :param cli_arguments: User inputs. :type cli_arguments: CommandLineArguments :param impact_function: The impact function used. :type impact_function: ImpactFunction :param iface: QGIS QGisAppInterface instance. :type iface: QGisAppInterface .. versionadded:: 4.0 """ layers = [impact_function.hazard, impact_function.exposure] aggregation_layer = impact_function.aggregation if aggregation_layer: layers.append(aggregation_layer) layer_registry = QgsMapLayerRegistry.instance() layer_registry.addMapLayers(layers) layer_registry.addMapLayers(impact_function.outputs) # create impact report instance report_metadata = ReportMetadata( metadata_dict=update_template_component(map_report) ) impact_report = ImpactReport( iface, report_metadata, impact_function=impact_function) # get the extent of impact layer impact_report.qgis_composition_context.extent = \ impact_function.impact.extent() # set the ouput folder impact_report.output_folder = cli_arguments.output_dir return impact_report.process_components()
def test_earthquake_population_without_aggregation(self): """Testing Earthquake in Population without aggregation. .. versionadded:: 4.0 """ output_folder = self.fixtures_dir('../output/earthquake_population') # Classified vector with building-points shutil.rmtree(output_folder, ignore_errors=True) hazard_layer = load_test_raster_layer('hazard', 'earthquake.tif') exposure_layer = load_test_raster_layer('exposure', 'pop_binary_raster_20_20.asc') impact_function = ImpactFunction() impact_function.exposure = exposure_layer impact_function.hazard = hazard_layer impact_function.crs = QgsCoordinateReferenceSystem(4326) impact_function.prepare() return_code, message = impact_function.run() self.assertEqual(return_code, ANALYSIS_SUCCESS, message) report_metadata = ReportMetadata( metadata_dict=standard_impact_report_metadata_html) impact_report = ImpactReport(IFACE, report_metadata, impact_function=impact_function) impact_report.output_folder = output_folder return_code, message = impact_report.process_components() self.assertEqual(return_code, ImpactReport.REPORT_GENERATION_SUCCESS, message) """Checking generated context.""" empty_component_output_message = 'Empty component output' # Check Analysis Summary analysis_summary = impact_report.metadata.component_by_key( general_report_component['key']) """:type: safe.report.report_metadata.Jinja2ComponentsMetadata""" expected_context = { 'table_header': (u'Estimated Number of people affected per MMI intensity'), 'header': u'General Report', 'summary': [{ 'header_label': u'Hazard Zone', 'rows': [{ 'numbers': ['0'], 'name': u'X', 'key': 'X' }, { 'numbers': ['0'], 'name': u'IX', 'key': 'IX' }, { 'numbers': ['200'], 'name': u'VIII', 'key': 'VIII' }, { 'numbers': ['0'], 'name': u'VII', 'key': 'VII' }, { 'numbers': ['0'], 'name': u'VI', 'key': 'VI' }, { 'numbers': ['0'], 'name': u'V', 'key': 'V' }, { 'numbers': ['0'], 'name': u'IV', 'key': 'IV' }, { 'numbers': ['0'], 'name': u'III', 'key': 'III' }, { 'numbers': ['0'], 'name': u'II', 'key': 'II' }, { 'numbers': ['0'], 'name': u'I', 'key': 'I' }, { 'as_header': True, 'key': 'total_exposed_field', 'name': u'Total Exposed', 'numbers': ['200'] }], 'value_labels': [u'Count'] }, { 'header_label': u'Population', 'rows': [{ 'numbers': ['200'], 'name': u'Affected', 'key': 'total_affected_field', }, { 'key': 'total_not_affected_field', 'name': u'Not Affected', 'numbers': ['0'] }, { 'key': 'total_not_exposed_field', 'name': u'Not Exposed', 'numbers': ['0'] }, { 'numbers': ['200'], 'name': u'Displaced', 'key': 'displaced_field' }, { 'numbers': ['0 - 100'], 'name': u'Fatalities', 'key': 'fatalities_field' }], 'value_labels': [u'Count'] }], 'notes': [ u'Exposed People: People who are present in hazard zones and ' u'are thereby subject to potential losses. In InaSAFE, people ' u'who are exposed are those people who are within the extent ' u'of the hazard.', u'Affected People: People who are affected by a hazardous ' u'event. People can be affected directly or indirectly. ' u'Affected people may experience short-term or long-term ' u'consequences to their lives, livelihoods or health and in ' u'the economic, physical, social, cultural and environmental ' u'assets. In InaSAFE, people who are killed during the event ' u'are also considered affected.', u'Displaced People: Displaced people are people who, for ' u'different reasons and circumstances because of risk or ' u'disaster, have to leave their place of residence. ' u'In InaSAFE, demographic and minimum needs reports are based ' u'on displaced / evacuated people.' ] } actual_context = analysis_summary.context self.assertDictEqual(expected_context, actual_context) self.assertTrue(analysis_summary.output, empty_component_output_message) report_metadata = ReportMetadata(metadata_dict=infographic_report) infographic_impact_report = ImpactReport( IFACE, report_metadata, impact_function=impact_function) infographic_impact_report.output_folder = output_folder return_code, message = infographic_impact_report.process_components() self.assertEqual(return_code, ImpactReport.REPORT_GENERATION_SUCCESS, message) # check population pie chart if we have 100% donut slice population_chart_svg = ( infographic_impact_report.metadata.component_by_key( population_chart_svg_component['key'])) expected_slices = [{ 'value': 200, 'show_label': True, 'center': (224.0, 128.0), 'stroke_opacity': 1, 'path': 'M128.000000,0.000000a128.000000,128.000000 0 0 1 ' '0.000000,256.000000l-0.000000,-64.000000a64.000000,' '64.000000 0 0 0 0.000000,-128.000000Z', 'percentage': 100, 'label': u'VIII', 'stroke': u'#ff7000', 'label_position': (256, 0), 'fill': u'#ff7000' }, { 'value': 100, 'show_label': False, 'center': (32.0, 128.0), 'stroke_opacity': 1, 'path': 'M128.000000,256.000000a128.000000,128.000000 0 0 1 ' '-0.000000,-256.000000l0.000000,64.000000a64.000000,' '64.000000 0 0 0 0.000000,128.000000Z', 'percentage': 50.0, 'label': '', 'stroke': u'#ff7000', 'label_position': (256, 0), 'fill': u'#ff7000' }, { 'value': 0, 'show_label': False, 'center': (128.0, 224.0), 'stroke_opacity': 1, 'path': 'M128.000000,256.000000a128.000000,128.000000 0 0 1 ' '0.000000,0.000000l-0.000000,-64.000000a64.000000,' '64.000000 0 0 0 0.000000,0.000000Z', 'percentage': 0.0, 'label': u'Total Not Affected', 'stroke': '#fff', 'label_position': (256, 0), 'fill': u'#1a9641' }] actual_context = population_chart_svg.context['context'] actual_slices = actual_context.slices self.assertEqual(expected_slices, actual_slices) self.assertTrue(population_chart_svg.output, empty_component_output_message) shutil.rmtree(output_folder, ignore_errors=True)
def generate_impact_map_report(impact_function, iface): """Generate impact map pdf from impact function. :param impact_function: The impact function used. :type impact_function: ImpactFunction :param iface: QGIS QGisAppInterface instance. :type iface: QGisAppInterface """ # get the extra layers that we need extra_layers = [] print_atlas = setting('print_atlas_report', False, bool) if print_atlas: extra_layers.append(impact_function.aggregation_summary) # get the hazard and exposure type hazard_layer = impact_function.hazard exposure_layer = impact_function.exposure hazard_type = layer_definition_type(hazard_layer) exposure_type = layer_definition_type(exposure_layer) # create impact report instance report_metadata = ReportMetadata( metadata_dict=update_template_component( component=map_report, hazard=hazard_type, exposure=exposure_type)) impact_report = ImpactReport( iface, report_metadata, impact_function=impact_function, extra_layers=extra_layers) # Get other setting logo_path = setting('organisation_logo_path', None, str) impact_report.inasafe_context.organisation_logo = logo_path disclaimer_text = setting('reportDisclaimer', None, str) impact_report.inasafe_context.disclaimer = disclaimer_text north_arrow_path = setting('north_arrow_path', None, str) impact_report.inasafe_context.north_arrow = north_arrow_path # get the extent of impact layer impact_report.qgis_composition_context.extent = \ impact_function.impact.extent() # generate report folder # no other option for now # TODO: retrieve the information from data store if isinstance(impact_function.datastore.uri, QDir): layer_dir = impact_function.datastore.uri.absolutePath() else: # No other way for now return # We will generate it on the fly without storing it after datastore # supports impact_report.output_folder = os.path.join(layer_dir, 'output') return impact_report.process_components()
def generate_impact_map_report(impact_function, iface): """Generate impact map pdf from impact function. :param impact_function: The impact function used. :type impact_function: ImpactFunction :param iface: QGIS QGisAppInterface instance. :type iface: QGisAppInterface """ # get the extra layers that we need extra_layers = [] print_atlas = setting('print_atlas_report', False, bool) if print_atlas: extra_layers.append(impact_function.aggregation_summary) # get the hazard and exposure type hazard_layer = impact_function.hazard exposure_layer = impact_function.exposure hazard_type = layer_definition_type(hazard_layer) exposure_type = layer_definition_type(exposure_layer) # create impact report instance report_metadata = ReportMetadata( metadata_dict=update_template_component( component=map_report, hazard=hazard_type, exposure=exposure_type)) impact_report = ImpactReport( iface, report_metadata, impact_function=impact_function, extra_layers=extra_layers) # Get other setting logo_path = setting('organisation_logo_path', None, basestring) impact_report.inasafe_context.organisation_logo = logo_path disclaimer_text = setting('reportDisclaimer', None, basestring) impact_report.inasafe_context.disclaimer = disclaimer_text north_arrow_path = setting('north_arrow_path', None, basestring) impact_report.inasafe_context.north_arrow = north_arrow_path # get the extent of impact layer impact_report.qgis_composition_context.extent = \ impact_function.impact.extent() # generate report folder # no other option for now # TODO: retrieve the information from data store if isinstance(impact_function.datastore.uri, QDir): layer_dir = impact_function.datastore.uri.absolutePath() else: # No other way for now return # We will generate it on the fly without storing it after datastore # supports impact_report.output_folder = os.path.join(layer_dir, 'output') return impact_report.process_components()
def test_earthquake_population_without_aggregation(self): """Testing Earthquake in Population without aggregation. .. versionadded:: 4.0 """ output_folder = self.fixtures_dir('../output/earthquake_population') # Classified vector with building-points shutil.rmtree(output_folder, ignore_errors=True) hazard_layer = load_test_raster_layer( 'hazard', 'earthquake.tif') exposure_layer = load_test_raster_layer( 'exposure', 'pop_binary_raster_20_20.asc') impact_function = ImpactFunction() impact_function.exposure = exposure_layer impact_function.hazard = hazard_layer impact_function.prepare() return_code, message = impact_function.run() self.assertEqual(return_code, ANALYSIS_SUCCESS, message) report_metadata = ReportMetadata( metadata_dict=standard_impact_report_metadata_html) impact_report = ImpactReport( IFACE, report_metadata, impact_function=impact_function) impact_report.output_folder = output_folder return_code, message = impact_report.process_component() self.assertEqual( return_code, ImpactReport.REPORT_GENERATION_SUCCESS, message) """Checking generated context""" empty_component_output_message = 'Empty component output' # Check Analysis Summary analysis_summary = impact_report.metadata.component_by_key( general_report_component['key']) """:type: safe.report.report_metadata.Jinja2ComponentsMetadata""" expected_context = { 'table_header': u'Estimated Number of people', 'header': u'General Report', 'summary': [ { 'header_label': u'Hazard Zone', 'rows': [{'value': '0', 'name': u'X', 'key': 'X'}, {'value': '0', 'name': u'IX', 'key': 'IX'}, {'value': '200', 'name': u'VIII', 'key': 'VIII'}, {'value': '0', 'name': u'VII', 'key': 'VII'}, {'value': '0', 'name': u'VI', 'key': 'VI'}, {'value': '0', 'name': u'V', 'key': 'V'}, {'value': '0', 'name': u'IV', 'key': 'IV'}, {'value': '0', 'name': u'III', 'key': 'III'}, {'value': '0', 'name': u'II', 'key': 'II'}, {'value': '0', 'name': u'I', 'key': 'I'}], 'value_label': u'Count' }, { 'header_label': u'Population', 'rows': [{'value': '200', 'name': u'Displaced', 'key': 'displaced_field'}, {'value': '0 - 100', 'name': u'Fatalities', 'key': 'fatalities_field'}], 'value_label': u'Count' } ] } actual_context = analysis_summary.context self.assertDictEqual(expected_context, actual_context) self.assertTrue( analysis_summary.output, empty_component_output_message) # check population pie chart if we have 100% donut slice population_chart_svg = impact_report.metadata.component_by_key( population_chart_svg_component['key']) expected_slices = [ {'value': 0, 'show_label': False, 'center': (128.0, 32.0), 'stroke_opacity': 1, 'path': 'M128.000000,0.000000a128.000000,128.000000 0 0 1 ' '0.000000,0.000000l-0.000000,64.000000a64.000000,' '64.000000 0 0 0 0.000000,0.000000Z', 'percentage': 0.0, 'label': u'X', 'stroke': '#fff', 'label_position': (256, 0), 'fill': u'#dd0000'}, {'value': 0, 'show_label': False, 'center': (128.0, 32.0), 'stroke_opacity': 1, 'path': 'M128.000000,0.000000a128.000000,128.000000 0 0 1 ' '0.000000,0.000000l-0.000000,64.000000a64.000000,' '64.000000 0 0 0 0.000000,0.000000Z', 'percentage': 0.0, 'label': u'IX', 'stroke': '#fff', 'label_position': (256, 0), 'fill': u'#ff0000'}, {'value': 200, 'show_label': True, 'center': (224.0, 128.0), 'stroke_opacity': 1, 'path': 'M128.000000,0.000000a128.000000,128.000000 0 0 1 ' '0.000000,256.000000l-0.000000,-64.000000a64.000000,' '64.000000 0 0 0 0.000000,-128.000000Z', 'percentage': 100, 'label': u'VIII', 'stroke': u'#ff7000', 'label_position': (256, 0), 'fill': u'#ff7000'}, {'value': 100, 'show_label': False, 'center': (32.0, 128.0), 'stroke_opacity': 1, 'path': 'M128.000000,256.000000a128.000000,128.000000 0 0 1 ' '-0.000000,-256.000000l0.000000,64.000000a64.000000,' '64.000000 0 0 0 0.000000,128.000000Z', 'percentage': 50.0, 'label': '', 'stroke': u'#ff7000', 'label_position': (256, 0), 'fill': u'#ff7000'}, {'value': 0, 'show_label': False, 'center': (128.0, 224.0), 'stroke_opacity': 1, 'path': 'M128.000000,256.000000a128.000000,128.000000 0 0 1 ' '0.000000,0.000000l-0.000000,-64.000000a64.000000,' '64.000000 0 0 0 0.000000,0.000000Z', 'percentage': 0.0, 'label': u'VII', 'stroke': '#fff', 'label_position': (256, 0), 'fill': u'#ffa800'}, {'value': 0, 'show_label': False, 'center': (128.0, 224.0), 'stroke_opacity': 1, 'path': 'M128.000000,256.000000a128.000000,128.000000 0 0 1 ' '0.000000,0.000000l-0.000000,-64.000000a64.000000,' '64.000000 0 0 0 0.000000,0.000000Z', 'percentage': 0.0, 'label': u'VI', 'stroke': '#fff', 'label_position': (256, 0), 'fill': u'#fff000'}, {'value': 0, 'show_label': False, 'center': (128.0, 224.0), 'stroke_opacity': 1, 'path': 'M128.000000,256.000000a128.000000,128.000000 0 0 1 ' '0.000000,0.000000l-0.000000,-64.000000a64.000000,' '64.000000 0 0 0 0.000000,0.000000Z', 'percentage': 0.0, 'label': u'V', 'stroke': '#fff', 'label_position': (256, 0), 'fill': u'#aaffff'}, {'value': 0, 'show_label': False, 'center': (128.0, 224.0), 'stroke_opacity': 1, 'path': 'M128.000000,256.000000a128.000000,128.000000 0 0 1 ' '0.000000,0.000000l-0.000000,-64.000000a64.000000,' '64.000000 0 0 0 0.000000,0.000000Z', 'percentage': 0.0, 'label': u'IV', 'stroke': '#fff', 'label_position': (256, 0), 'fill': u'#55ffff'}, {'value': 0, 'show_label': False, 'center': (128.0, 224.0), 'stroke_opacity': 1, 'path': 'M128.000000,256.000000a128.000000,128.000000 0 0 1 ' '0.000000,0.000000l-0.000000,-64.000000a64.000000,' '64.000000 0 0 0 0.000000,0.000000Z', 'percentage': 0.0, 'label': u'III', 'stroke': '#fff', 'label_position': (256, 0), 'fill': u'#00cfff'}, {'value': 0, 'show_label': False, 'center': (128.0, 224.0), 'stroke_opacity': 1, 'path': 'M128.000000,256.000000a128.000000,128.000000 0 0 1 ' '0.000000,0.000000l-0.000000,-64.000000a64.000000,' '64.000000 0 0 0 0.000000,0.000000Z', 'percentage': 0.0, 'label': u'II', 'stroke': '#fff', 'label_position': (256, 0), 'fill': u'#209fff'}] actual_context = population_chart_svg.context['context'] actual_slices = actual_context.slices self.assertEqual(expected_slices, actual_slices) self.assertTrue( population_chart_svg.output, empty_component_output_message) shutil.rmtree(output_folder, ignore_errors=True)
def test_earthquake_population_without_aggregation(self): """Testing Earthquake in Population without aggregation. .. versionadded:: 4.0 """ output_folder = self.fixtures_dir('../output/earthquake_population') # Classified vector with building-points shutil.rmtree(output_folder, ignore_errors=True) hazard_layer = load_test_raster_layer( 'hazard', 'earthquake.tif') exposure_layer = load_test_raster_layer( 'exposure', 'pop_binary_raster_20_20.asc') impact_function = ImpactFunction() impact_function.exposure = exposure_layer impact_function.hazard = hazard_layer impact_function.prepare() return_code, message = impact_function.run() self.assertEqual(return_code, ANALYSIS_SUCCESS, message) report_metadata = ReportMetadata( metadata_dict=standard_impact_report_metadata_html) impact_report = ImpactReport( IFACE, report_metadata, impact_function=impact_function) impact_report.output_folder = output_folder return_code, message = impact_report.process_components() self.assertEqual( return_code, ImpactReport.REPORT_GENERATION_SUCCESS, message) """Checking generated context""" empty_component_output_message = 'Empty component output' # Check Analysis Summary analysis_summary = impact_report.metadata.component_by_key( general_report_component['key']) """:type: safe.report.report_metadata.Jinja2ComponentsMetadata""" expected_context = { 'table_header': ( u'Estimated Number of people affected per MMI intensity'), 'header': u'General Report', 'summary': [ { 'header_label': u'Hazard Zone', 'rows': [ {'value': 0, 'name': u'X', 'key': 'X'}, {'value': 0, 'name': u'IX', 'key': 'IX'}, {'value': '200', 'name': u'VIII', 'key': 'VIII'}, {'value': 0, 'name': u'VII', 'key': 'VII'}, {'value': 0, 'name': u'VI', 'key': 'VI'}, {'value': 0, 'name': u'V', 'key': 'V'}, {'value': 0, 'name': u'IV', 'key': 'IV'}, {'value': 0, 'name': u'III', 'key': 'III'}, {'value': 0, 'name': u'II', 'key': 'II'}, {'value': 0, 'name': u'I', 'key': 'I'}, { 'as_header': True, 'key': 'total_field', 'name': u'Total', 'value': '200' } ], 'value_label': u'Count' }, { 'header_label': u'Population', 'rows': [ { 'value': '200', 'name': u'Affected', 'key': 'total_affected_field', }, { 'key': 'total_not_affected_field', 'name': u'Not Affected', 'value': '0' }, { 'key': 'total_not_exposed_field', 'name': u'Not Exposed', 'value': '0'}, { 'value': '200', 'name': u'Displaced', 'key': 'displaced_field' }, { 'value': '0 - 100', 'name': u'Fatalities', 'key': 'fatalities_field' }], 'value_label': u'Count' } ], 'notes': [ 'Exposed People: People who are present in hazard zones and ' 'are thereby subject to potential losses. In InaSAFE, people ' 'who are exposed are those people who are within the extent ' 'of the hazard.', 'Affected People: People who are affected by a hazardous ' 'event. People can be affected directly or indirectly. ' 'Affected people may experience short-term or long-term ' 'consequences to their lives, livelihoods or health and in ' 'the economic, physical, social, cultural and environmental ' 'assets. In InaSAFE, people who are killed during the event ' 'are also considered affected.', 'Displaced People: Displaced people are people who, for ' 'different reasons and circumstances because of risk or ' 'disaster, have to leave their place of residence. ' 'In InaSAFE, demographic and minimum needs reports are based ' 'on displaced / evacuated people.' ] } actual_context = analysis_summary.context self.assertDictEqual(expected_context, actual_context) self.assertTrue( analysis_summary.output, empty_component_output_message) report_metadata = ReportMetadata( metadata_dict=infographic_report) infographic_impact_report = ImpactReport( IFACE, report_metadata, impact_function=impact_function) infographic_impact_report.output_folder = output_folder return_code, message = infographic_impact_report.process_components() self.assertEqual( return_code, ImpactReport.REPORT_GENERATION_SUCCESS, message) # check population pie chart if we have 100% donut slice population_chart_svg = ( infographic_impact_report.metadata.component_by_key( population_chart_svg_component['key']) ) expected_slices = [ { 'value': 200, 'show_label': True, 'center': (224.0, 128.0), 'stroke_opacity': 1, 'path': 'M128.000000,0.000000a128.000000,128.000000 0 0 1 ' '0.000000,256.000000l-0.000000,-64.000000a64.000000,' '64.000000 0 0 0 0.000000,-128.000000Z', 'percentage': 100, 'label': u'VIII', 'stroke': u'#ff7000', 'label_position': (256, 0), 'fill': u'#ff7000' }, { 'value': 100, 'show_label': False, 'center': (32.0, 128.0), 'stroke_opacity': 1, 'path': 'M128.000000,256.000000a128.000000,128.000000 0 0 1 ' '-0.000000,-256.000000l0.000000,64.000000a64.000000,' '64.000000 0 0 0 0.000000,128.000000Z', 'percentage': 50.0, 'label': '', 'stroke': u'#ff7000', 'label_position': (256, 0), 'fill': u'#ff7000' }, { 'value': 0, 'show_label': False, 'center': (128.0, 224.0), 'stroke_opacity': 1, 'path': 'M128.000000,256.000000a128.000000,128.000000 0 0 1 ' '0.000000,0.000000l-0.000000,-64.000000a64.000000,' '64.000000 0 0 0 0.000000,0.000000Z', 'percentage': 0.0, 'label': u'Total Not Affected', 'stroke': '#fff', 'label_position': (256, 0), 'fill': u'#1a9641' }] actual_context = population_chart_svg.context['context'] actual_slices = actual_context.slices self.assertEqual(expected_slices, actual_slices) self.assertTrue( population_chart_svg.output, empty_component_output_message) shutil.rmtree(output_folder, ignore_errors=True)