def accept(self): """Method invoked when OK button is clicked.""" self.save_state() self.dock.show_busy() # The order of the components are matter. components = self.prepare_components() error_code, message = self.impact_function.generate_report( components, iface=self.iface) if error_code == ImpactReport.REPORT_GENERATION_FAILED: self.dock.hide_busy() LOGGER.info(tr('The impact report could not be generated.')) send_error_message(self, message) LOGGER.info(message.to_text()) return ANALYSIS_FAILED_BAD_CODE, message sender_name = self.sender().objectName() try: if sender_name == 'button_print_pdf': self.create_pdf = True self.open_as_pdf() else: self.create_pdf = False self.open_in_composer() self.dock.hide_busy() except Exception: self.dock.hide_busy() QtWidgets.QDialog.accept(self)
def accept(self): """Method invoked when OK button is clicked.""" self.save_state() self.dock.show_busy() # The order of the components are matter. components = self.prepare_components() error_code, message = self.impact_function.generate_report( components, iface=self.iface) if error_code == ImpactReport.REPORT_GENERATION_FAILED: self.dock.hide_busy() LOGGER.info(tr( 'The impact report could not be generated.')) send_error_message(self, message) LOGGER.info(message.to_text()) return ANALYSIS_FAILED_BAD_CODE, message sender_name = self.sender().objectName() try: if sender_name == 'button_print_pdf': self.create_pdf = True self.open_as_pdf() else: self.create_pdf = False self.open_in_composer() self.dock.hide_busy() except Exception: self.dock.hide_busy() QtWidgets.QDialog.accept(self)
def analysis_error(self, exception, message): """A helper to spawn an error and halt processing. An exception will be logged, busy status removed and a message displayed. .. note:: Copied from the dock :param message: an ErrorMessage to display :type message: ErrorMessage, Message :param exception: An exception that was raised :type exception: Exception """ self.hide_busy() LOGGER.exception(message) message = get_error_message(exception, context=message) send_error_message(self, message) self.analysisDone.emit(False)
def validate_impact_function(self): """Check validity of the current impact function.""" # Always set it to False self.btn_run.setEnabled(False) for combo in list(self.combos_exposures.values()): if combo.count() == 1: combo.setEnabled(False) hazard = layer_from_combo(self.cbx_hazard) aggregation = layer_from_combo(self.cbx_aggregation) exposures = [] for combo in list(self.combos_exposures.values()): exposures.append(layer_from_combo(combo)) exposures = [layer for layer in exposures if layer] multi_exposure_if = MultiExposureImpactFunction() multi_exposure_if.hazard = hazard multi_exposure_if.exposures = exposures multi_exposure_if.debug = False multi_exposure_if.callback = self.progress_callback if aggregation: multi_exposure_if.use_selected_features_only = ( self.use_selected_only) multi_exposure_if.aggregation = aggregation else: multi_exposure_if.crs = ( self.iface.mapCanvas().mapSettings().destinationCrs()) if len(self.ordered_expected_layers()) != 0: self._multi_exposure_if.output_layers_ordered = ( self.ordered_expected_layers()) status, message = multi_exposure_if.prepare() if status == PREPARE_SUCCESS: self._multi_exposure_if = multi_exposure_if self.btn_run.setEnabled(True) send_static_message(self, ready_message()) self.list_layers_in_map_report.clear() return else: disable_busy_cursor() send_error_message(self, message) self._multi_exposure_if = None
def print_map_to_pdf(self, impact_report): """Print map to PDF given MapReport instance. :param impact_report: Impact Report instance that is ready to print :type impact_report: ImpactReport """ impact_report.setup_composition() # Get Filename map_title = impact_report.map_title if map_title is not None: default_file_name = map_title + '.pdf' default_file_name = default_file_name.replace(' ', '_') else: send_error_message( self, self.tr('Keyword "map_title" not found.')) return # Get output path # noinspection PyCallByClass,PyTypeChecker output_path = QtGui.QFileDialog.getSaveFileName( self.parent, self.tr('Write to PDF'), os.path.join(temp_dir(), default_file_name), self.tr('Pdf File (*.pdf)')) output_path = str(output_path) if output_path is None or output_path == '': # noinspection PyTypeChecker self.show_dynamic_message( self, m.Message( m.Heading(self.tr('Map Creator'), **WARNING_STYLE), m.Text(self.tr('Printing cancelled!')))) return try: map_pdf_path, table_pdf_path = impact_report.print_to_pdf( output_path) # Make sure the file paths can wrap nicely: wrapped_map_path = map_pdf_path.replace(os.sep, '<wbr>' + os.sep) wrapped_table_path = table_pdf_path.replace( os.sep, '<wbr>' + os.sep) status = m.Message( m.Heading(self.tr('Map Creator'), **INFO_STYLE), m.Paragraph(self.tr('Your PDF was created....')), m.Paragraph(self.tr( 'Opening using the default PDF viewer on your system. ' 'The generated pdfs were saved as:')), m.Paragraph(wrapped_map_path), m.Paragraph(self.tr('and')), m.Paragraph(wrapped_table_path)) # noinspection PyCallByClass,PyTypeChecker,PyArgumentList QtGui.QDesktopServices.openUrl( QtCore.QUrl.fromLocalFile(table_pdf_path)) # noinspection PyCallByClass,PyTypeChecker,PyArgumentList QtGui.QDesktopServices.openUrl( QtCore.QUrl.fromLocalFile(map_pdf_path)) # noinspection PyTypeChecker self.show_dynamic_message(self, status) except TemplateLoadingError, e: send_error_message(self, get_error_message(e))
m.Paragraph(self.tr('and')), m.Paragraph(wrapped_table_path)) # noinspection PyCallByClass,PyTypeChecker,PyArgumentList QtGui.QDesktopServices.openUrl( QtCore.QUrl.fromLocalFile(table_pdf_path)) # noinspection PyCallByClass,PyTypeChecker,PyArgumentList QtGui.QDesktopServices.openUrl( QtCore.QUrl.fromLocalFile(map_pdf_path)) # noinspection PyTypeChecker self.show_dynamic_message(self, status) except TemplateLoadingError, e: send_error_message(self, get_error_message(e)) except Exception, e: # pylint: disable=broad-except send_error_message(self, get_error_message(e)) def open_map_in_composer(self, impact_report): """Open map in composer given MapReport instance. ..note:: (AG) See https://github.com/AIFDR/inasafe/issues/911. We need to set the composition to the composer before loading the template. :param impact_report: Impact Report to be opened in composer. :type impact_report: ImpactReport """ impact_report.setup_composition() self.composer = self.iface.createNewComposer() self.composer.setComposition(impact_report.composition) impact_report.load_template()
def run_task(self, task_item, status_item, count=0, index=''): """Run a single task. :param task_item: Table task_item containing task name / details. :type task_item: QTableWidgetItem :param status_item: Table task_item that holds the task status. :type status_item: QTableWidgetItem :param count: Count of scenarios that have been run already. :type count: :param index: The index for the table item that will be run. :type index: int :returns: Flag indicating if the task succeeded or not. :rtype: bool """ self.enable_busy_cursor() for layer_group in self.layer_group_container: layer_group.setVisible(False) # set status to 'running' status_item.setText(self.tr('Running')) # .. see also:: :func:`appendRow` to understand the next 2 lines variant = task_item.data(QtCore.Qt.UserRole) value = variant[0] result = True if isinstance(value, str): filename = value # run script try: self.run_script(filename) # set status to 'OK' status_item.setText(self.tr('Script OK')) except Exception as e: # pylint: disable=W0703 # set status to 'fail' status_item.setText(self.tr('Script Fail')) LOGGER.exception('Running macro failed. The exception: ' + str(e)) result = False elif isinstance(value, dict): # start in new project if toggle is active if self.start_in_new_project: self.iface.newProject() # create layer group group_name = value['scenario_name'] self.layer_group = self.root.addGroup(group_name) self.layer_group_container.append(self.layer_group) # Its a dict containing files for a scenario success, parameters = self.prepare_task(value) if not success: # set status to 'running' status_item.setText(self.tr('Please update scenario')) self.disable_busy_cursor() return False # If impact function parameters loaded successfully, initiate IF. impact_function = ImpactFunction() impact_function.hazard = parameters[layer_purpose_hazard['key']] impact_function.exposure = ( parameters[layer_purpose_exposure['key']]) if parameters[layer_purpose_aggregation['key']]: impact_function.aggregation = ( parameters[layer_purpose_aggregation['key']]) elif parameters['extent']: impact_function.requested_extent = parameters['extent'] impact_function.requested_extent_crs = parameters['crs'] prepare_status, prepare_message = impact_function.prepare() if prepare_status == PREPARE_SUCCESS: LOGGER.info('Impact function ready') status, message = impact_function.run() if status == ANALYSIS_SUCCESS: status_item.setText(self.tr('Analysis Success')) impact_layer = impact_function.impact if impact_layer.isValid(): layer_list = [ impact_layer, parameters[layer_purpose_hazard['key']], parameters[layer_purpose_exposure['key']], parameters[layer_purpose_aggregation['key']]] QgsMapLayerRegistry.instance().addMapLayers( layer_list, False) for layer in layer_list: self.layer_group.addLayer(layer) map_canvas = QgsMapLayerRegistry.instance().mapLayers() for layer in map_canvas: # turn of layer visibility if not impact layer if map_canvas[layer].id() == impact_layer.id(): self.legend.setLayerVisible( map_canvas[layer], True) else: self.legend.setLayerVisible( map_canvas[layer], False) # generate map report and impact report try: # this line is to save the impact report in default # InaSAFE directory. generate_impact_report(impact_function, self.iface) generate_impact_map_report( impact_function, self.iface) # this line is to save the report in user specified # directory. self.generate_pdf_report( impact_function, self.iface, group_name) except: status_item.setText( self.tr('Report failed to generate.')) else: LOGGER.info('Impact layer is invalid') elif status == ANALYSIS_FAILED_BAD_INPUT: LOGGER.info('Bad input detected') elif status == ANALYSIS_FAILED_BAD_CODE: LOGGER.info('Impact function encountered a bug') else: LOGGER.warning('Impact function not ready') send_error_message(self, prepare_message) else: LOGGER.exception('Data type not supported: "%s"' % value) result = False self.disable_busy_cursor() return result
def run_task(self, task_item, status_item, count=0, index=''): """Run a single task. :param task_item: Table task_item containing task name / details. :type task_item: QTableWidgetItem :param status_item: Table task_item that holds the task status. :type status_item: QTableWidgetItem :param count: Count of scenarios that have been run already. :type count: :param index: The index for the table item that will be run. :type index: int :returns: Flag indicating if the task succeeded or not. :rtype: bool """ self.enable_busy_cursor() for layer_group in self.layer_group_container: layer_group.setItemVisibilityChecked(False) # set status to 'running' status_item.setText(self.tr('Running')) # .. see also:: :func:`appendRow` to understand the next 2 lines variant = task_item.data(QtCore.Qt.UserRole) value = variant[0] result = True if isinstance(value, str): filename = value # run script try: self.run_script(filename) # set status to 'OK' status_item.setText(self.tr('Script OK')) except Exception as e: # pylint: disable=W0703 # set status to 'fail' status_item.setText(self.tr('Script Fail')) LOGGER.exception( 'Running macro failed. The exception: ' + str(e)) result = False elif isinstance(value, dict): # start in new project if toggle is active if self.start_in_new_project: self.iface.newProject() # create layer group group_name = value['scenario_name'] self.layer_group = self.root.addGroup(group_name) self.layer_group_container.append(self.layer_group) # Its a dict containing files for a scenario success, parameters = self.prepare_task(value) if not success: # set status to 'running' status_item.setText(self.tr('Please update scenario')) self.disable_busy_cursor() return False directory = self.output_directory.text() if self.scenario_directory_radio.isChecked(): directory = self.source_directory.text() output_directory = os.path.join(directory, group_name) if not os.path.exists(output_directory): os.makedirs(output_directory) # If impact function parameters loaded successfully, initiate IF. impact_function = ImpactFunction() impact_function.datastore = Folder(output_directory) impact_function.datastore.default_vector_format = "geojson" impact_function.hazard = parameters[layer_purpose_hazard['key']] impact_function.exposure = ( parameters[layer_purpose_exposure['key']]) if parameters[layer_purpose_aggregation['key']]: impact_function.aggregation = ( parameters[layer_purpose_aggregation['key']]) elif parameters['extent']: impact_function.requested_extent = parameters['extent'] impact_function.crs = parameters['crs'] prepare_status, prepare_message = impact_function.prepare() if prepare_status == PREPARE_SUCCESS: LOGGER.info('Impact function ready') status, message = impact_function.run() if status == ANALYSIS_SUCCESS: status_item.setText(self.tr('Analysis Success')) impact_layer = impact_function.impact if impact_layer.isValid(): layer_list = [ impact_layer, impact_function.analysis_impacted, parameters[layer_purpose_hazard['key']], parameters[layer_purpose_exposure['key']], parameters[layer_purpose_aggregation['key']]] QgsProject.instance().addMapLayers( layer_list, False) for layer in layer_list: self.layer_group.addLayer(layer) map_canvas = QgsProject.instance().mapLayers() for layer in map_canvas: # turn of layer visibility if not impact layer if map_canvas[layer].id() == impact_layer.id(): self.set_layer_visible( map_canvas[layer], True) else: self.set_layer_visible( map_canvas[layer], False) # we need to set analysis_impacted as an active layer # because we need to get all qgis variables that we # need from this layer for infographic. if self.iface: self.iface.setActiveLayer( impact_function.analysis_impacted) report_directory = os.path.join( output_directory, 'output') # generate map report and impact report try: error_code, message = ( impact_function.generate_report( all_default_report_components, report_directory)) except BaseException: status_item.setText( self.tr('Report failed to generate.')) else: LOGGER.info('Impact layer is invalid') elif status == ANALYSIS_FAILED_BAD_INPUT: LOGGER.info('Bad input detected') elif status == ANALYSIS_FAILED_BAD_CODE: LOGGER.info( 'Impact function encountered a bug: %s' % message) else: LOGGER.warning('Impact function not ready') send_error_message(self, prepare_message) else: LOGGER.exception('Data type not supported: "%s"' % value) result = False self.disable_busy_cursor() return result
def setup_and_run_analysis(self): """Execute analysis after the tab is displayed. Please check the code in dock.py accept(). It should follow approximately the same code. """ self.show_busy() # Read user's settings self.read_settings() # Prepare impact function from wizard dialog user input self.impact_function = self.prepare_impact_function() # Prepare impact function status, message = self.impact_function.prepare() # Check status if status == PREPARE_FAILED_BAD_INPUT: self.hide_busy() LOGGER.info(tr( 'The impact function will not be able to run because of the ' 'inputs.')) LOGGER.info(message.to_text()) send_error_message(self, message) return status, message if status == PREPARE_FAILED_BAD_CODE: self.hide_busy() LOGGER.exception(tr( 'The impact function was not able to be prepared because of a ' 'bug.')) LOGGER.info(message.to_text()) send_error_message(self, message) return status, message # Start the analysis status, message = self.impact_function.run() # Check status if status == ANALYSIS_FAILED_BAD_INPUT: self.hide_busy() LOGGER.info(tr( 'The impact function could not run because of the inputs.')) LOGGER.info(message.to_text()) send_error_message(self, message) return status, message elif status == ANALYSIS_FAILED_BAD_CODE: self.hide_busy() LOGGER.exception(tr( 'The impact function could not run because of a bug.')) LOGGER.exception(message.to_text()) send_error_message(self, message) return status, message LOGGER.info(tr('The impact function could run without errors.')) # Add result layer to QGIS add_impact_layers_to_canvas(self.impact_function, self.parent.iface) # Some if-s i.e. zoom, debug, hide exposure if self.zoom_to_impact_flag: self.iface.zoomToActiveLayer() qgis_exposure = ( QgsMapLayerRegistry.instance().mapLayer( self.parent.exposure_layer.id())) if self.hide_exposure_flag: legend = self.iface.legendInterface() legend.setLayerVisible(qgis_exposure, False) # Generate impact report error_code, message = generate_impact_report( self.impact_function, self.parent.iface) if error_code == ImpactReport.REPORT_GENERATION_FAILED: self.hide_busy() LOGGER.info(tr( 'The impact report could not be generated.')) send_error_message(self, message) LOGGER.info(message.to_text()) return ANALYSIS_FAILED_BAD_CODE, message # Generate Impact Map Report error_code, message = generate_impact_map_report( self.impact_function, self.iface) if error_code == ImpactReport.REPORT_GENERATION_FAILED: self.hide_busy() LOGGER.info(tr( 'The impact report could not be generated.')) send_error_message(self, message) LOGGER.info(message.to_text()) return ANALYSIS_FAILED_BAD_CODE, message self.extent.set_last_analysis_extent( self.impact_function.analysis_extent, qgis_exposure.crs()) # Hide busy self.hide_busy() # Setup gui if analysis is done self.setup_gui_analysis_done() return ANALYSIS_SUCCESS, None
def setup_and_run_analysis(self): """Execute analysis after the tab is displayed. Please check the code in dock.py accept(). It should follow approximately the same code. """ self.show_busy() # Read user's settings self.read_settings() # Prepare impact function from wizard dialog user input self.impact_function = self.prepare_impact_function() # Prepare impact function status, message = self.impact_function.prepare() # Check status if status == PREPARE_FAILED_BAD_INPUT: self.hide_busy() LOGGER.info( tr('The impact function will not be able to run because of the ' 'inputs.')) LOGGER.info(message.to_text()) send_error_message(self, message) return status, message if status == PREPARE_FAILED_BAD_CODE: self.hide_busy() LOGGER.exception( tr('The impact function was not able to be prepared because of a ' 'bug.')) LOGGER.info(message.to_text()) send_error_message(self, message) return status, message # Start the analysis status, message = self.impact_function.run() # Check status if status == ANALYSIS_FAILED_BAD_INPUT: self.hide_busy() LOGGER.info( tr('The impact function could not run because of the inputs.')) LOGGER.info(message.to_text()) send_error_message(self, message) return status, message elif status == ANALYSIS_FAILED_BAD_CODE: self.hide_busy() LOGGER.exception( tr('The impact function could not run because of a bug.')) LOGGER.exception(message.to_text()) send_error_message(self, message) return status, message LOGGER.info(tr('The impact function could run without errors.')) # Add result layer to QGIS add_impact_layers_to_canvas(self.impact_function, self.parent.iface) # Some if-s i.e. zoom, debug, hide exposure if self.zoom_to_impact_flag: self.iface.zoomToActiveLayer() qgis_exposure = (QgsMapLayerRegistry.instance().mapLayer( self.parent.exposure_layer.id())) if self.hide_exposure_flag: legend = self.iface.legendInterface() legend.setLayerVisible(qgis_exposure, False) # Generate impact report error_code, message = generate_impact_report(self.impact_function, self.parent.iface) if error_code == ImpactReport.REPORT_GENERATION_FAILED: self.hide_busy() LOGGER.info(tr('The impact report could not be generated.')) send_error_message(self, message) LOGGER.info(message.to_text()) return ANALYSIS_FAILED_BAD_CODE, message # Generate Impact Map Report error_code, message = generate_impact_map_report( self.impact_function, self.iface) if error_code == ImpactReport.REPORT_GENERATION_FAILED: self.hide_busy() LOGGER.info(tr('The impact report could not be generated.')) send_error_message(self, message) LOGGER.info(message.to_text()) return ANALYSIS_FAILED_BAD_CODE, message self.extent.set_last_analysis_extent( self.impact_function.analysis_extent, qgis_exposure.crs()) # Hide busy self.hide_busy() # Setup gui if analysis is done self.setup_gui_analysis_done() return ANALYSIS_SUCCESS, None
def setup_and_run_analysis(self): """Execute analysis after the tab is displayed. Please check the code in dock.py accept(). It should follow approximately the same code. """ self.show_busy() # Read user's settings self.read_settings() # Prepare impact function from wizard dialog user input self.impact_function = self.prepare_impact_function() # Prepare impact function status, message = self.impact_function.prepare() message = basestring_to_message(message) # Check status if status == PREPARE_FAILED_BAD_INPUT: self.hide_busy() LOGGER.warning( tr('The impact function will not be able to run because of the ' 'inputs.')) LOGGER.warning(message.to_text()) send_error_message(self, message) return status, message if status == PREPARE_FAILED_BAD_CODE: self.hide_busy() LOGGER.warning( tr('The impact function was not able to be prepared because of a ' 'bug.')) LOGGER.exception(message.to_text()) send_error_message(self, message) return status, message # Start the analysis status, message = self.impact_function.run() message = basestring_to_message(message) # Check status if status == ANALYSIS_FAILED_BAD_INPUT: self.hide_busy() LOGGER.warning( tr('The impact function could not run because of the inputs.')) LOGGER.warning(message.to_text()) send_error_message(self, message) return status, message elif status == ANALYSIS_FAILED_BAD_CODE: self.hide_busy() LOGGER.warning( tr('The impact function could not run because of a bug.')) LOGGER.exception(message.to_text()) send_error_message(self, message) return status, message LOGGER.info(tr('The impact function could run without errors.')) # Add result layer to QGIS add_impact_layers_to_canvas(self.impact_function, iface=self.parent.iface) # Some if-s i.e. zoom, debug, hide exposure if self.zoom_to_impact_flag: self.iface.zoomToActiveLayer() qgis_exposure = (QgsProject.instance().mapLayer( self.parent.exposure_layer.id())) if self.hide_exposure_flag and qgis_exposure is not None: treeroot = QgsProject.instance().layerTreeRoot() treelayer = treeroot.findLayer(qgis_exposure.id()) if treelayer: treelayer.setItemVisibilityChecked(False) # we only want to generate non pdf/qpt report html_components = [standard_impact_report_metadata_html] error_code, message = self.impact_function.generate_report( html_components) message = basestring_to_message(message) if error_code == ImpactReport.REPORT_GENERATION_FAILED: self.hide_busy() LOGGER.info(tr('The impact report could not be generated.')) send_error_message(self, message) LOGGER.exception(message.to_text()) return ANALYSIS_FAILED_BAD_CODE, message self.extent.set_last_analysis_extent( self.impact_function.analysis_extent, qgis_exposure.crs()) # Hide busy self.hide_busy() # Setup gui if analysis is done self.setup_gui_analysis_done() return ANALYSIS_SUCCESS, None
def setup_and_run_analysis(self): """Execute analysis after the tab is displayed. Please check the code in dock.py accept(). It should follow approximately the same code. """ self.show_busy() # Read user's settings self.read_settings() # Prepare impact function from wizard dialog user input self.impact_function = self.prepare_impact_function() # Prepare impact function status, message = self.impact_function.prepare() message = basestring_to_message(message) # Check status if status == PREPARE_FAILED_BAD_INPUT: self.hide_busy() LOGGER.warning(tr( 'The impact function will not be able to run because of the ' 'inputs.')) LOGGER.warning(message.to_text()) send_error_message(self, message) return status, message if status == PREPARE_FAILED_BAD_CODE: self.hide_busy() LOGGER.warning(tr( 'The impact function was not able to be prepared because of a ' 'bug.')) LOGGER.exception(message.to_text()) send_error_message(self, message) return status, message # Start the analysis status, message = self.impact_function.run() message = basestring_to_message(message) # Check status if status == ANALYSIS_FAILED_BAD_INPUT: self.hide_busy() LOGGER.warning(tr( 'The impact function could not run because of the inputs.')) LOGGER.warning(message.to_text()) send_error_message(self, message) return status, message elif status == ANALYSIS_FAILED_BAD_CODE: self.hide_busy() LOGGER.warning(tr( 'The impact function could not run because of a bug.')) LOGGER.exception(message.to_text()) send_error_message(self, message) return status, message LOGGER.info(tr('The impact function could run without errors.')) # Add result layer to QGIS add_impact_layers_to_canvas( self.impact_function, iface=self.parent.iface) # Some if-s i.e. zoom, debug, hide exposure if self.zoom_to_impact_flag: self.iface.zoomToActiveLayer() qgis_exposure = ( QgsProject.instance().mapLayer( self.parent.exposure_layer.id())) if self.hide_exposure_flag and qgis_exposure is not None: treeroot = QgsProject.instance().layerTreeRoot() treelayer = treeroot.findLayer(qgis_exposure.id()) if treelayer: treelayer.setItemVisibilityChecked(False) # we only want to generate non pdf/qpt report html_components = [standard_impact_report_metadata_html] error_code, message = self.impact_function.generate_report( html_components) message = basestring_to_message(message) if error_code == ImpactReport.REPORT_GENERATION_FAILED: self.hide_busy() LOGGER.info(tr( 'The impact report could not be generated.')) send_error_message(self, message) LOGGER.exception(message.to_text()) return ANALYSIS_FAILED_BAD_CODE, message self.extent.set_last_analysis_extent( self.impact_function.analysis_extent, qgis_exposure.crs()) # Hide busy self.hide_busy() # Setup gui if analysis is done self.setup_gui_analysis_done() return ANALYSIS_SUCCESS, None
def accept(self): """Launch the multi exposure analysis.""" if not isinstance(self._multi_exposure_if, MultiExposureImpactFunction): # This should not happen as the "accept" button must be disabled if # the impact function is not ready. return ANALYSIS_FAILED_BAD_CODE, None self.tab_widget.setCurrentIndex(2) self.set_enabled_buttons(False) enable_busy_cursor() try: code, message, exposure = self._multi_exposure_if.run() message = basestring_to_message(message) if code == ANALYSIS_FAILED_BAD_INPUT: LOGGER.warning( tr('The impact function could not run because of the inputs.' )) send_error_message(self, message) LOGGER.warning(message.to_text()) disable_busy_cursor() self.set_enabled_buttons(True) return code, message elif code == ANALYSIS_FAILED_BAD_CODE: LOGGER.warning( tr('The impact function could not run because of a bug.')) LOGGER.exception(message.to_text()) send_error_message(self, message) disable_busy_cursor() self.set_enabled_buttons(True) return code, message if setting('generate_report', True, bool): LOGGER.info( 'Reports are going to be generated for the multiexposure.') # Report for the multi exposure report = [standard_multi_exposure_impact_report_metadata_html] error_code, message = ( self._multi_exposure_if.generate_report(report)) message = basestring_to_message(message) if error_code == ImpactReport.REPORT_GENERATION_FAILED: LOGGER.warning('The impact report could not be generated.') send_error_message(self, message) LOGGER.exception(message.to_text()) disable_busy_cursor() self.set_enabled_buttons(True) return error_code, message else: LOGGER.warning( 'Reports are not generated because of your settings.') display_warning_message_bar( tr('Reports'), tr('Reports are not going to be generated because of your ' 'InaSAFE settings.'), duration=10, iface_object=self.iface) # We always create the multi exposure group because we need # reports to be generated. root = QgsProject.instance().layerTreeRoot() if len(self.ordered_expected_layers()) == 0: group_analysis = root.insertGroup(0, self._multi_exposure_if.name) group_analysis.setItemVisibilityChecked(True) group_analysis.setCustomProperty(MULTI_EXPOSURE_ANALYSIS_FLAG, True) for layer in self._multi_exposure_if.outputs: QgsProject.instance().addMapLayer(layer, False) layer_node = group_analysis.addLayer(layer) layer_node.setItemVisibilityChecked(False) # set layer title if any try: title = layer.keywords['title'] if qgis_version() >= 21800: layer.setName(title) else: layer.setLayerName(title) except KeyError: pass for analysis in self._multi_exposure_if.impact_functions: detailed_group = group_analysis.insertGroup( 0, analysis.name) detailed_group.setItemVisibilityChecked(True) add_impact_layers_to_canvas(analysis, group=detailed_group) if self.iface: self.iface.setActiveLayer( self._multi_exposure_if.analysis_impacted) else: add_layers_to_canvas_with_custom_orders( self.ordered_expected_layers(), self._multi_exposure_if, self.iface) if setting('generate_report', True, bool): LOGGER.info( 'Reports are going to be generated for each single ' 'exposure.') # Report for the single exposure with hazard for analysis in self._multi_exposure_if.impact_functions: # we only want to generate non pdf/qpt report html_components = [standard_impact_report_metadata_html] error_code, message = ( analysis.generate_report(html_components)) message = basestring_to_message(message) if error_code == (ImpactReport.REPORT_GENERATION_FAILED): LOGGER.info( 'The impact report could not be generated.') send_error_message(self, message) LOGGER.info(message.to_text()) disable_busy_cursor() self.set_enabled_buttons(True) return error_code, message else: LOGGER.info( 'Reports are not generated because of your settings.') display_warning_message_bar( tr('Reports'), tr('Reports are not going to be generated because of your ' 'InaSAFE settings.'), duration=10, iface_object=self.iface) # If zoom to impact is enabled if setting('setZoomToImpactFlag', expected_type=bool): self.iface.zoomToActiveLayer() # If hide exposure layers if setting('setHideExposureFlag', expected_type=bool): treeroot = QgsProject.instance().layerTreeRoot() for combo in list(self.combos_exposures.values()): layer = layer_from_combo(combo) if layer is not None: treelayer = treeroot.findLayer(layer.id()) if treelayer: treelayer.setItemVisibilityChecked(False) # Set last analysis extent self._extent.set_last_analysis_extent( self._multi_exposure_if.analysis_extent, self._multi_exposure_if.crs) self.done(QDialog.Accepted) except Exception as e: error_message = get_error_message(e) send_error_message(self, error_message) LOGGER.exception(e) LOGGER.debug(error_message.to_text()) finally: disable_busy_cursor() self.set_enabled_buttons(True)