def show_welcome_message(self): """Show the welcome message.""" # import here only so that it is AFTER i18n set up from safe.gui.tools.options_dialog import OptionsDialog # Do not show by default show_message = False previous_version = StrictVersion(setting('previous_version')) current_version = StrictVersion(inasafe_version) # Set previous_version to the current inasafe_version set_setting('previous_version', inasafe_version) if setting('always_show_welcome_message', expected_type=bool): # Show if it the setting said so show_message = True elif previous_version < current_version: # Always show if the user installed new version show_message = True # Allow to disable welcome message when running automated tests if os.environ.get('INASAFE_DISABLE_WELCOME_MESSAGE', False): show_message = False if show_message: dialog = OptionsDialog(iface=self.iface, parent=self.iface.mainWindow()) dialog.show_welcome_dialog() if dialog.exec_(): # modal self.dock_widget.read_settings()
def prepare_impact_function(self): """Create analysis as a representation of current situation of IFCW.""" # Impact Functions impact_function = ImpactFunction() impact_function.callback = self.progress_callback # Layers impact_function.hazard = self.parent.hazard_layer impact_function.exposure = self.parent.exposure_layer aggregation = self.parent.aggregation_layer if aggregation: impact_function.aggregation = aggregation impact_function.use_selected_features_only = ( setting('useSelectedFeaturesOnly', False, bool)) else: mode = setting('analysis_extents_mode') if self.extent.user_extent: # This like a hack to transform a geometry to a rectangle. # self.extent.user_extent is a QgsGeometry. # impact_function.requested_extent needs a QgsRectangle. wkt = self.extent.user_extent.exportToWkt() impact_function.requested_extent = wkt_to_rectangle(wkt) impact_function.requested_extent_crs = self.extent.crs elif mode == HAZARD_EXPOSURE_VIEW: impact_function.requested_extent = ( self.iface.mapCanvas().extent()) impact_function.requested_extent_crs = self.extent.crs # We don't have any checkbox in the wizard for the debug mode. impact_function.debug_mode = False return impact_function
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 test_read_write_setting(self): """Test read and write setting.""" # General Setting set_general_setting('key', 'value', self.qsettings) self.assertEqual('value', general_setting('key', qsettings=self.qsettings)) delete_general_setting('key', qsettings=self.qsettings) self.assertEqual( 'default', general_setting('key', default='default', qsettings=self.qsettings)) set_general_setting('key', 'True', self.qsettings) self.assertEqual( 'True', general_setting('key', qsettings=self.qsettings, expected_type=str)) self.assertEqual( True, general_setting('key', qsettings=self.qsettings, expected_type=bool)) delete_general_setting('key', qsettings=self.qsettings) self.assertEqual( 'default', general_setting('key', default='default', qsettings=self.qsettings)) set_general_setting('key', 'false', self.qsettings) self.assertEqual( 'false', general_setting('key', qsettings=self.qsettings, expected_type=str)) self.assertEqual( False, general_setting('key', qsettings=self.qsettings, expected_type=bool)) delete_general_setting('key', qsettings=self.qsettings) self.assertEqual( 'default', general_setting('key', default='default', qsettings=self.qsettings)) # Under InaSAFE scope set_setting('key', 'value', self.qsettings) self.assertEqual('value', setting('key', qsettings=self.qsettings)) delete_setting('key', qsettings=self.qsettings) self.assertEqual( 'default', setting('key', default='default', qsettings=self.qsettings)) # Using InaSAFE setting default key = 'developer_mode' actual_value = inasafe_default_settings.get(key) self.assertEqual(actual_value, setting(key, qsettings=self.qsettings))
def create_profile_layer(profiling): """Create a tabular layer with the profiling. :param profiling: A dict containing benchmarking data. :type profiling: safe.messaging.message.Message :return: A tabular layer. :rtype: QgsVectorLayer """ fields = [ create_field_from_definition(profiling_function_field), create_field_from_definition(profiling_time_field) ] if setting(key='memory_profile', expected_type=bool): fields.append(create_field_from_definition(profiling_memory_field)) tabular = create_memory_layer( 'profiling', QgsWkbTypes.NullGeometry, fields=fields) # Generate profiling keywords tabular.keywords['layer_purpose'] = layer_purpose_profiling['key'] tabular.keywords['title'] = layer_purpose_profiling['name'] if qgis_version() >= 21800: tabular.setName(tabular.keywords['title']) else: tabular.setLayerName(tabular.keywords['title']) tabular.keywords['inasafe_fields'] = { profiling_function_field['key']: profiling_function_field['field_name'], profiling_time_field['key']: profiling_time_field['field_name'], } if setting(key='memory_profile', expected_type=bool): tabular.keywords['inasafe_fields'][ profiling_memory_field['key']] = profiling_memory_field[ 'field_name'] tabular.keywords[inasafe_keyword_version_key] = ( inasafe_keyword_version) table = profiling.to_text().splitlines()[3:] tabular.startEditing() for line in table: feature = QgsFeature() items = line.split(', ') time = items[1].replace('-', '') if setting(key='memory_profile', expected_type=bool): memory = items[2].replace('-', '') feature.setAttributes([items[0], time, memory]) else: feature.setAttributes([items[0], time]) tabular.addFeature(feature) tabular.commitChanges() return tabular
def __init__(self, parent=None, iface=iface_object): """Constructor for the multi exposure dialog. :param parent: Parent widget of this dialog. :type parent: QWidget :param iface: An instance of QgisInterface :type iface: QgisInterface """ QDialog.__init__(self, parent) self.use_selected_only = setting('useSelectedFeaturesOnly', expected_type=bool) self.parent = parent self.iface = iface self.setupUi(self) icon = resources_path('img', 'icons', 'show-multi-exposure.svg') self.setWindowIcon(QIcon(icon)) self.tab_widget.setCurrentIndex(0) self.combos_exposures = OrderedDict() self.keyword_io = KeywordIO() self._create_exposure_combos() self._multi_exposure_if = None self._extent = Extent(iface) self._extent.show_rubber_bands = setting('showRubberBands', False, bool) enable_messaging(self.message_viewer, self) self.btn_back.clicked.connect(self.back_clicked) self.btn_next.clicked.connect(self.next_clicked) self.btn_cancel.clicked.connect(self.reject) self.btn_run.clicked.connect(self.accept) self.validate_impact_function() self.tab_widget.currentChanged.connect(self._tab_changed) self.tree.itemSelectionChanged.connect(self._tree_selection_changed) self.list_layers_in_map_report.itemSelectionChanged.connect( self._list_selection_changed) self.add_layer.clicked.connect(self._add_layer_clicked) self.remove_layer.clicked.connect(self._remove_layer_clicked) self.move_up.clicked.connect(self.move_layer_up) self.move_down.clicked.connect(self.move_layer_down) self.cbx_hazard.currentIndexChanged.connect( self.validate_impact_function) self.cbx_aggregation.currentIndexChanged.connect( self.validate_impact_function) # Keep track of the current panel self._current_index = 0 self.tab_widget.setCurrentIndex(self._current_index)
def test_read_boolean_setting(self): """Test read developer mode setting.""" set_setting('developer_mode', inasafe_default_settings['developer_mode']) actual_setting = setting('developer_mode', inasafe_default_settings['developer_mode']) self.assertFalse(actual_setting) set_setting('developer_mode', not (inasafe_default_settings['developer_mode'])) actual_setting = setting('developer_mode', inasafe_default_settings['developer_mode']) self.assertTrue(actual_setting)
def is_affected(hazard, classification, hazard_class, qsettings=None): """Get affected flag for hazard in classification in hazard class. :param hazard: The hazard key. :type hazard: basestring :param classification: The classification key. :type classification: basestring :param hazard_class: The hazard class key. :type hazard_class: basestring :param qsettings: A custom QSettings to use. If it's not defined, it will use the default one. :type qsettings: qgis.PyQt.QtCore.QSettings :returns: True if it's affected, else False. Default to False. :rtype: bool """ preference_data = setting('population_preference', default=generate_default_profile(), qsettings=qsettings) # Use default from the default profile default_profile = generate_default_profile() default_affected_value = default_profile.get(hazard, {}).get( classification, {}).get(hazard_class, {}).get('affected', not_exposed_class['key']) # noinspection PyUnresolvedReferences return preference_data.get(hazard, {}).get(classification, {}).get(hazard_class, {}).get('affected', default_affected_value)
def restore_population_parameters(self, global_default=True): """Setup UI for population parameter page from setting. :param global_default: If True, set to original default (from the value in definitions). :type global_default: bool """ if global_default: data = generate_default_profile() else: data = setting('population_preference', generate_default_profile()) if not isinstance(data, dict): LOGGER.debug( 'population parameter is not a dictionary. InaSAFE will use ' 'the default one.') data = generate_default_profile() try: self.profile_widget.data = data except KeyError as e: LOGGER.debug( 'Population parameter is not in correct format. InaSAFE will ' 'use the default one.') LOGGER.debug(e) data = generate_default_profile() self.profile_widget.data = data
def is_affected(hazard, classification, hazard_class, qsettings=None): """Get affected flag for hazard in classification in hazard class. :param hazard: The hazard key. :type hazard: basestring :param classification: The classification key. :type classification: basestring :param hazard_class: The hazard class key. :type hazard_class: basestring :param qsettings: A custom QSettings to use. If it's not defined, it will use the default one. :type qsettings: qgis.PyQt.QtCore.QSettings :returns: True if it's affected, else False. Default to False. :rtype: bool """ preference_data = setting( 'population_preference', default=generate_default_profile(), qsettings=qsettings) # Use default from the default profile default_profile = generate_default_profile() default_affected_value = default_profile.get(hazard, {}).get( classification, {}).get(hazard_class, {}).get( 'affected', not_exposed_class['key']) # noinspection PyUnresolvedReferences return preference_data.get(hazard, {}).get(classification, {}).get( hazard_class, {}).get('affected', default_affected_value)
def __init__(self, parent=None, iface=None): """Constructor for import dialog. .. versionadded: 3.3 :param parent: Optional widget to use as parent. :type parent: QWidget :param iface: An instance of QGisInterface. :type iface: QGisInterface """ QDialog.__init__(self, parent) self.parent = parent self.setupUi(self) title = self.tr('PetaBencana Downloader') self.setWindowTitle(title) icon = resources_path('img', 'icons', 'add-petabencana-layer.svg') self.setWindowIcon(QtGui.QIcon(icon)) self.iface = iface self.source = None self.radio_button_group = QButtonGroup() self.radio_button_group.addButton(self.radio_button_production) self.radio_button_group.addButton(self.radio_button_development) self.radio_button_group.setExclusive(True) self.radio_button_production.setChecked(True) self.populate_combo_box() developer_mode = setting('developer_mode', False, bool) if not developer_mode: self.radio_button_widget.hide() self.source_label.hide() self.output_group.adjustSize() # signals self.radio_button_production.clicked.connect(self.populate_combo_box) self.radio_button_development.clicked.connect(self.populate_combo_box) # creating progress dialog for download self.progress_dialog = QProgressDialog(self) self.progress_dialog.setAutoClose(False) self.progress_dialog.setWindowTitle(title) # Set up things for context help self.help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # set up the validator for the file name prefix expression = QRegExp('^[A-Za-z0-9-_]*$') validator = QRegExpValidator(expression, self.filename_prefix) self.filename_prefix.setValidator(validator) self.time_stamp = None self.restore_state()
def test_read_write_setting(self): """Test read and write setting.""" # General Setting set_general_setting('key', 'value', self.qsettings) self.assertEqual( 'value', general_setting('key', qsettings=self.qsettings)) delete_general_setting('key', qsettings=self.qsettings) self.assertEqual('default', general_setting( 'key', default='default', qsettings=self.qsettings)) set_general_setting('key', 'True', self.qsettings) self.assertEqual( 'True', general_setting( 'key', qsettings=self.qsettings, expected_type=str)) self.assertEqual( True, general_setting( 'key', qsettings=self.qsettings, expected_type=bool)) delete_general_setting('key', qsettings=self.qsettings) self.assertEqual('default', general_setting( 'key', default='default', qsettings=self.qsettings)) set_general_setting('key', 'false', self.qsettings) self.assertEqual( 'false', general_setting( 'key', qsettings=self.qsettings, expected_type=str)) self.assertEqual( False, general_setting( 'key', qsettings=self.qsettings, expected_type=bool)) delete_general_setting('key', qsettings=self.qsettings) self.assertEqual('default', general_setting( 'key', default='default', qsettings=self.qsettings)) # Under InaSAFE scope set_setting('key', 'value', self.qsettings) self.assertEqual('value', setting('key', qsettings=self.qsettings)) delete_setting('key', qsettings=self.qsettings) self.assertEqual('default', setting( 'key', default='default', qsettings=self.qsettings)) # Using InaSAFE setting default key = 'developer_mode' actual_value = inasafe_default_settings.get(key) self.assertEqual(actual_value, setting(key, qsettings=self.qsettings))
def restore_state(self): """Restore GUI state from configuration file.""" # restore last source path last_source_path = setting( 'lastSourceDir', self.default_directory, expected_type=str) self.source_directory.setText(last_source_path) # restore path pdf output last_output_dir = setting( 'lastOutputDir', self.default_directory, expected_type=str) self.output_directory.setText(last_output_dir) # restore default output dir combo box use_default_output_dir = bool(setting( 'useDefaultOutputDir', True, expected_type=bool)) self.scenario_directory_radio.setChecked( use_default_output_dir)
def test_read_boolean_setting(self): """Test read developer mode setting.""" set_setting( 'developer_mode', inasafe_default_settings['developer_mode']) actual_setting = setting( 'developer_mode', inasafe_default_settings['developer_mode']) self.assertFalse(actual_setting) set_setting( 'developer_mode', not(inasafe_default_settings['developer_mode'])) actual_setting = setting( 'developer_mode', inasafe_default_settings['developer_mode']) self.assertTrue(actual_setting)
def _populate_reporting_tab(self): """Populate trees about layers.""" self.tree.clear() self.add_layer.setEnabled(False) self.remove_layer.setEnabled(False) self.move_up.setEnabled(False) self.move_down.setEnabled(False) self.tree.setColumnCount(1) self.tree.setRootIsDecorated(False) self.tree.setHeaderHidden(True) analysis_branch = QTreeWidgetItem(self.tree.invisibleRootItem(), [FROM_ANALYSIS['name']]) analysis_branch.setFont(0, bold_font) analysis_branch.setExpanded(True) analysis_branch.setFlags(Qt.ItemIsEnabled) if self._multi_exposure_if: expected = self._multi_exposure_if.output_layers_expected() for group, layers in list(expected.items()): group_branch = QTreeWidgetItem(analysis_branch, [group]) group_branch.setFont(0, bold_font) group_branch.setExpanded(True) group_branch.setFlags(Qt.ItemIsEnabled) for layer in layers: layer = definition(layer) if layer.get('allowed_geometries', None): item = QTreeWidgetItem(group_branch, [layer.get('name')]) item.setData(0, LAYER_ORIGIN_ROLE, FROM_ANALYSIS['key']) item.setData(0, LAYER_PARENT_ANALYSIS_ROLE, group) item.setData(0, LAYER_PURPOSE_KEY_OR_ID_ROLE, layer['key']) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) canvas_branch = QTreeWidgetItem(self.tree.invisibleRootItem(), [FROM_CANVAS['name']]) canvas_branch.setFont(0, bold_font) canvas_branch.setExpanded(True) canvas_branch.setFlags(Qt.ItemIsEnabled) # List layers from the canvas loaded_layers = list(QgsProject.instance().mapLayers().values()) canvas_layers = self.iface.mapCanvas().layers() flag = setting('visibleLayersOnlyFlag', expected_type=bool) for loaded_layer in loaded_layers: if flag and loaded_layer not in canvas_layers: continue title = loaded_layer.name() item = QTreeWidgetItem(canvas_branch, [title]) item.setData(0, LAYER_ORIGIN_ROLE, FROM_CANVAS['key']) item.setData(0, LAYER_PURPOSE_KEY_OR_ID_ROLE, loaded_layer.id()) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) self.tree.resizeColumnToContents(0)
def __init__(self, parent=None, iface=None): """Constructor for import dialog. .. versionadded: 3.3 :param parent: Optional widget to use as parent. :type parent: QWidget :param iface: An instance of QGisInterface. :type iface: QGisInterface """ QDialog.__init__(self, parent) self.parent = parent self.setupUi(self) title = self.tr('PetaBencana Downloader') self.setWindowTitle(title) self.iface = iface self.source = None self.radio_button_group = QButtonGroup() self.radio_button_group.addButton(self.radio_button_production) self.radio_button_group.addButton(self.radio_button_development) self.radio_button_group.setExclusive(True) self.radio_button_production.setChecked(True) self.populate_combo_box() developer_mode = setting('developer_mode', False, bool) if not developer_mode: self.radio_button_widget.hide() self.source_label.hide() self.output_group.adjustSize() # signals self.radio_button_production.clicked.connect(self.populate_combo_box) self.radio_button_development.clicked.connect(self.populate_combo_box) # creating progress dialog for download self.progress_dialog = QProgressDialog(self) self.progress_dialog.setAutoClose(False) self.progress_dialog.setWindowTitle(title) # Set up things for context help self.help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # set up the validator for the file name prefix expression = QRegExp('^[A-Za-z0-9-_]*$') validator = QRegExpValidator(expression, self.filename_prefix) self.filename_prefix.setValidator(validator) self.time_stamp = None self.restore_state()
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 test_get_value(self): """Test we can get a value from a QSettings.""" # The expected type does not match the default value. try: self.assertEqual( 'default_value', setting('test', 'default_value', bool, self.qsetting)) except Exception: self.assertTrue(True) else: self.assertTrue(False) self.assertEqual('default_value', setting('test', 'default_value', str, self.qsetting)) self.assertIsNone(setting('test', None, str, self.qsetting)) # Without default value. self.assertIsNone(setting('test', qsettings=self.qsetting))
def create_qgis_pdf_output(impact_report, output_path, composition, file_format, metadata): """Produce PDF output using QgsComposition. :param output_path: The output path. :type output_path: str :param composition: QGIS Composition object. :type composition: qgis.core.QgsComposition :param qgis_composition_context: QGIS Composition context used by renderer. :type qgis_composition_context: safe.report.impact_report. QGISCompositionContext :param file_format: file format of map output, PDF or PNG. :type file_format: 'pdf', 'png' :param metadata: The component metadata. :type metadata: QgisComposerComponentsMetadata :return: Generated output path. :rtype: str """ # make sure directory is created dirname = os.path.dirname(output_path) if not os.path.exists(dirname): os.makedirs(dirname) qgis_composition_context = impact_report.qgis_composition_context aggregation_summary_layer = ( impact_report.impact_function.aggregation_summary) # process atlas generation print_atlas = setting('print_atlas_report', False, bool) if composition.atlasComposition().enabled() and ( print_atlas and aggregation_summary_layer): output_path = atlas_renderer(composition, aggregation_summary_layer, output_path, file_format) # for QGIS composer only pdf and png output are available elif file_format == QgisComposerComponentsMetadata.OutputFormat.PDF: try: composition.setPlotStyle(qgis_composition_context.plot_style) composition.setPrintResolution(metadata.page_dpi) composition.setPaperSize(metadata.page_width, metadata.page_height) composition.setPrintAsRaster( qgis_composition_context.save_as_raster) composition.exportAsPDF(output_path) except Exception as exc: LOGGER.error(exc) return None elif file_format == QgisComposerComponentsMetadata.OutputFormat.PNG: # TODO: implement PNG generations raise Exception('Not yet supported') return output_path
def add_impact_layers_to_canvas(impact_function, group=None, iface=None): """Helper method to add impact layer to QGIS from impact function. :param impact_function: The impact function used. :type impact_function: ImpactFunction :param group: An existing group as a parent, optional. :type group: QgsLayerTreeGroup :param iface: QGIS QGisAppInterface instance. :type iface: QGisAppInterface """ layers = impact_function.outputs name = impact_function.name if group: group_analysis = group else: # noinspection PyArgumentList root = QgsProject.instance().layerTreeRoot() group_analysis = root.insertGroup(0, name) group_analysis.setVisible(Qt.Checked) group_analysis.setExpanded(group is None) for layer in layers: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(layer, False) layer_node = group_analysis.addLayer(layer) # set layer title if any try: title = layer.keywords['title'] if qgis_version() >= 21800: layer.setName(title) else: layer.setLayerName(title) except KeyError: pass visible_layers = [impact_function.impact.id()] print_atlas = setting('print_atlas_report', False, bool) if print_atlas: visible_layers.append(impact_function.aggregation_summary.id()) # Let's enable only the more detailed layer. See #2925 if layer.id() in visible_layers: layer_node.setVisible(Qt.Checked) else: layer_node.setVisible(Qt.Unchecked) # 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 iface: iface.setActiveLayer(impact_function.analysis_impacted)
def add_impact_layers_to_canvas(impact_function, group=None, iface=None): """Helper method to add impact layer to QGIS from impact function. :param impact_function: The impact function used. :type impact_function: ImpactFunction :param group: An existing group as a parent, optional. :type group: QgsLayerTreeGroup :param iface: QGIS QgisAppInterface instance. :type iface: QgisAppInterface """ layers = impact_function.outputs name = impact_function.name if group: group_analysis = group else: # noinspection PyArgumentList root = QgsProject.instance().layerTreeRoot() group_analysis = root.insertGroup(0, name) group_analysis.setItemVisibilityChecked(True) group_analysis.setExpanded(group is None) for layer in layers: # noinspection PyArgumentList QgsProject.instance().addMapLayer(layer, False) layer_node = group_analysis.addLayer(layer) # set layer title if any try: title = layer.keywords['title'] if qgis_version() >= 21800: layer.setName(title) else: layer.setLayerName(title) except KeyError: pass visible_layers = [impact_function.impact.id()] print_atlas = setting('print_atlas_report', False, bool) if print_atlas: visible_layers.append(impact_function.aggregation_summary.id()) # Let's enable only the more detailed layer. See #2925 if layer.id() in visible_layers: layer_node.setItemVisibilityChecked(True) else: layer_node.setItemVisibilityChecked(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 iface: iface.setActiveLayer(impact_function.analysis_impacted)
def __init__(self, iface): """Class constructor. On instantiation, the plugin instance will be assigned a copy of the QGIS iface object which will allow this plugin to access and manipulate the running QGIS instance that spawned it. :param iface:Quantum GIS iface instance. This instance is automatically passed to the plugin by QGIS when it loads the plugin. :type iface: QgisAppInterface """ # Save reference to the QGIS interface self.iface = iface self.dock_widget = None # Actions self.action_add_layers = None self.action_add_osm_layer = None self.action_add_petabencana_layer = None self.action_batch_runner = None self.action_dock = None self.action_extent_selector = None self.action_field_mapping = None self.action_multi_exposure = None self.action_function_centric_wizard = None self.action_import_dialog = None self.action_keywords_wizard = None self.action_minimum_needs = None self.action_minimum_needs_config = None self.action_multi_buffer = None self.action_options = None self.action_run_tests = None self.action_save_scenario = None self.action_shake_converter = None self.action_show_definitions = None self.action_toggle_rubberbands = None self.action_metadata_converter = None self.translator = None self.toolbar = None self.wizard = None self.actions = [] # list of all QActions we create for InaSAFE self.message_bar_item = None # Flag indicating if toolbar should show only common icons or not self.full_toolbar = False # print self.tr('InaSAFE') # For enable/disable the keyword editor icon self.iface.currentLayerChanged.connect(self.layer_changed) developer_mode = setting('developer_mode', False, expected_type=bool) self.hide_developer_buttons = (inasafe_release_status == 'final' and not developer_mode)
def restore_boolean_setting(self, key, check_box): """Set check_box according to setting of key. :param key: Key to retrieve setting value. :type key: str :param check_box: Check box to show and set the setting. :type check_box: PyQt5.QtWidgets.QCheckBox.QCheckBox """ flag = setting(key, expected_type=bool, qsettings=self.settings) check_box.setChecked(flag)
def restore_text_setting(self, key, line_edit): """Set line_edit text according to setting of key. :param key: Key to retrieve setting value. :type key: str :param line_edit: Line edit for user to edit the setting :type line_edit: PyQt5.QtWidgets.QLineEdit.QLineEdit """ value = setting(key, expected_type=str, qsettings=self.settings) line_edit.setText(value)
def test_get_value(self): """Test we can get a value from a QSettings.""" # The expected type does not match the default value. try: self.assertEqual( 'default_value', setting('test', 'default_value', bool, self.qsetting)) except Exception: self.assertTrue(True) else: self.assertTrue(False) self.assertEqual( 'default_value', setting('test', 'default_value', str, self.qsetting)) self.assertIsNone( setting('test', None, str, self.qsetting)) # Without default value. self.assertIsNone(setting('test', qsettings=self.qsetting))
def test_read_write_dictionary(self): """Test for reading and writing dictionary in QSettings.""" dictionary = { 'a': 'a', 'b': 1, 'c': { 'd': True, 'e': { 'f': 1.0, 'g': 2 } } } set_setting('key', dictionary, self.qsettings) value = setting('key', qsettings=self.qsettings) self.assertDictEqual(dictionary, value) profile_dictionary = generate_default_profile() set_setting('population_preference', profile_dictionary, self.qsettings) value = setting('population_preference', qsettings=self.qsettings) self.assertDictEqual(profile_dictionary, value)
def read_settings(self): """Set the IF state from QSettings.""" extent = setting('user_extent', None, str) if extent: extent = QgsGeometry.fromWkt(extent) if not extent.isGeosValid(): extent = None crs = setting('user_extent_crs', None, str) if crs: crs = QgsCoordinateReferenceSystem(crs) if not crs.isValid(): crs = None mode = setting('analysis_extents_mode', HAZARD_EXPOSURE_VIEW) if crs and extent and mode == HAZARD_EXPOSURE_BOUNDINGBOX: self.extent.set_user_extent(extent, crs) self.extent.show_rubber_bands = setting( 'showRubberBands', False, bool) self.zoom_to_impact_flag = setting('setZoomToImpactFlag', True, bool) # whether exposure layer should be hidden after model completes self.hide_exposure_flag = setting('setHideExposureFlag', False, bool)
def north_arrow_path(feature, parent): """Retrieve the full path of default north arrow logo.""" _ = feature, parent # NOQA north_arrow_file = setting(inasafe_north_arrow_path['setting_key']) if os.path.exists(north_arrow_file): return north_arrow_file else: LOGGER.info( 'The custom north arrow is not found in {north_arrow_file}. ' 'Default north arrow will be used.').format( north_arrow_file=north_arrow_file) return inasafe_default_settings['north_arrow_path']
def setup_metadata_db_path(self): """Helper to set the active path for the metadata. Called at init time, you can override this path by calling set_metadata_db_path.setmetadataDbPath. :returns: The path to where the metadata file is. If the user has never specified what this path is, the defaultmetadataDbPath is returned. :rtype: str """ self.metadata_db_path = str( setting('keywordCachePath', expected_type=unicode))
def organisation_logo_path(feature, parent): """Retrieve the full path of used specified organisation logo.""" _ = feature, parent # NOQA organisation_logo_file = setting( inasafe_organisation_logo_path['setting_key']) if os.path.exists(organisation_logo_file): return organisation_logo_file else: LOGGER.info( 'The custom organisation logo is not found in {logo_path}. ' 'Default organisation logo will be used.').format( logo_path=organisation_logo_file) return inasafe_default_settings['organisation_logo_path']
def current_earthquake_model_name(): """Human friendly name for the currently active earthquake fatality model. :returns: Name of the current EQ fatality model as defined in users settings. """ default_earthquake_function = setting('earthquake_function', expected_type=str) current_function = None for model in EARTHQUAKE_FUNCTIONS: if model['key'] == default_earthquake_function: current_function = model['name'] return current_function
def current_earthquake_model_name(): """Human friendly name for the currently active earthquake fatality model. :returns: Name of the current EQ fatality model as defined in users settings. """ default_earthquake_function = setting( 'earthquake_function', expected_type=str) current_function = None for model in EARTHQUAKE_FUNCTIONS: if model['key'] == default_earthquake_function: current_function = model['name'] return current_function
def populate_function_table_1(self): """Populate the tblFunctions1 table with available functions.""" hazards = deepcopy(hazard_all) exposures = exposure_all self.lblAvailableFunctions1.clear() self.tblFunctions1.clear() self.tblFunctions1.setColumnCount(len(hazards)) self.tblFunctions1.setRowCount(len(exposures)) for i in range(len(hazards)): hazard = hazards[i] item = QtGui.QTableWidgetItem() item.setIcon( QtGui.QIcon( resources_path( 'img', 'wizard', 'keyword-subcategory-%s.svg' % (hazard['key'] or 'notset')))) item.setText(hazard['name'].capitalize()) self.tblFunctions1.setHorizontalHeaderItem(i, item) for i in range(len(exposures)): exposure = exposures[i] item = QtGui.QTableWidgetItem() item.setIcon( QtGui.QIcon( resources_path( 'img', 'wizard', 'keyword-subcategory-%s.svg' % (exposure['key'] or 'notset')))) item.setText(exposure['name'].capitalize()) self.tblFunctions1.setVerticalHeaderItem(i, item) developer_mode = setting('developer_mode', False, bool) for hazard in hazards: for exposure in exposures: item = QtGui.QTableWidgetItem() if (exposure in hazard['disabled_exposures'] and not developer_mode): background_colour = unavailable_option_color # Set it disable and un-selectable item.setFlags(item.flags() & ~QtCore.Qt.ItemIsEnabled & ~QtCore.Qt.ItemIsSelectable) else: background_colour = available_option_color item.setBackground(QtGui.QBrush(background_colour)) item.setFont(big_font) item.setTextAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignHCenter) item.setData(RoleHazard, hazard) item.setData(RoleExposure, exposure) self.tblFunctions1.setItem(exposures.index(exposure), hazards.index(hazard), item) self.parent.pbnNext.setEnabled(False)
def populate_function_table_1(self): """Populate the tblFunctions1 table with available functions.""" hazards = deepcopy(hazard_all) exposures = exposure_all self.lblAvailableFunctions1.clear() self.tblFunctions1.clear() self.tblFunctions1.setColumnCount(len(hazards)) self.tblFunctions1.setRowCount(len(exposures)) for i in range(len(hazards)): hazard = hazards[i] item = QtGui.QTableWidgetItem() item.setIcon(QtGui.QIcon( resources_path('img', 'wizard', 'keyword-subcategory-%s.svg' % (hazard['key'] or 'notset')))) item.setText(hazard['name'].capitalize()) self.tblFunctions1.setHorizontalHeaderItem(i, item) for i in range(len(exposures)): exposure = exposures[i] item = QtGui.QTableWidgetItem() item.setIcon(QtGui.QIcon(resources_path( 'img', 'wizard', 'keyword-subcategory-%s.svg' % (exposure['key'] or 'notset')))) item.setText(exposure['name'].capitalize()) self.tblFunctions1.setVerticalHeaderItem(i, item) developer_mode = setting('developer_mode', False, bool) for hazard in hazards: for exposure in exposures: item = QtGui.QTableWidgetItem() if (exposure in hazard['disabled_exposures'] and not developer_mode): background_colour = unavailable_option_color # Set it disable and un-selectable item.setFlags( item.flags() & ~ QtCore.Qt.ItemIsEnabled & ~ QtCore.Qt.ItemIsSelectable ) else: background_colour = available_option_color item.setBackground(QtGui.QBrush(background_colour)) item.setFont(big_font) item.setTextAlignment( QtCore.Qt.AlignCenter | QtCore.Qt.AlignHCenter) item.setData(RoleHazard, hazard) item.setData(RoleExposure, exposure) self.tblFunctions1.setItem( exposures.index(exposure), hazards.index(hazard), item) self.parent.pbnNext.setEnabled(False)
def set_north_arrow(self): """Auto-connect slot activated when north arrow checkbox is toggled.""" is_checked = self.custom_north_arrow_checkbox.isChecked() if is_checked: # Show previous north arrow path path = setting(key='north_arrow_path', default=default_north_arrow_path(), expected_type=str, qsettings=self.settings) else: # Set the north arrow line edit to default one path = default_north_arrow_path() self.leNorthArrowPath.setText(path) self.splitter_north_arrow.setEnabled(is_checked)
def test_read_write_dictionary(self): """Test for reading and writing dictionary in QSettings.""" dictionary = { 'a': 'a', 'b': 1, 'c': { 'd': True, 'e': { 'f': 1.0, 'g': 2 } } } set_setting('key', dictionary, self.qsettings) value = setting('key', qsettings=self.qsettings) self.assertDictEqual(dictionary, value) profile_dictionary = generate_default_profile() set_setting( 'population_preference', profile_dictionary, self.qsettings) value = setting('population_preference', qsettings=self.qsettings) self.assertDictEqual(profile_dictionary, value)
def getting_started_message(): """Generate a message for initial application state. :returns: Information for the user on how to get started. :rtype: safe.messaging.Message """ message = m.Message() message.add(LOGO_ELEMENT) message.add(m.Heading(tr('Getting started'), **INFO_STYLE)) notes = m.Paragraph( tr( 'These are the minimum steps you need to follow in order ' 'to use InaSAFE:')) message.add(notes) basics_list = m.NumberedList() basics_list.add(m.Paragraph( tr('Add at least one '), m.ImportantText(tr('hazard'), **KEYWORD_STYLE), tr(' layer (e.g. earthquake MMI) to QGIS.'))) basics_list.add(m.Paragraph( tr('Add at least one '), m.ImportantText(tr('exposure'), **KEYWORD_STYLE), tr(' layer (e.g. structures) to QGIS.'))) basics_list.add(m.Paragraph( tr( 'Make sure you have defined keywords for your hazard and ' 'exposure layers. You can do this using the ' 'keywords creation wizard '), m.Image( 'file:///%s/img/icons/show-keyword-wizard.svg' % (resources_path()), **SMALL_ICON_STYLE), tr(' in the toolbar.'))) basics_list.add(m.Paragraph( tr('Click on the '), m.ImportantText(tr('Run'), **KEYWORD_STYLE), tr(' button below.'))) message.add(basics_list) message.add(m.Heading(tr('Limitations'), **WARNING_STYLE)) caveat_list = m.NumberedList() for limitation in limitations(): caveat_list.add(limitation) message.add(caveat_list) message.add(m.Heading(tr('Disclaimer'), **WARNING_STYLE)) disclaimer = setting('reportDisclaimer') message.add(m.Paragraph(disclaimer)) return message
def set_templates_dir(self): """Auto-connect slot activated when templates dir checkbox is toggled. """ is_checked = self.custom_templates_dir_checkbox.isChecked() if is_checked: # Show previous templates dir path = setting(key='reportTemplatePath', default='', expected_type=str, qsettings=self.settings) else: # Set the template report dir to '' path = '' self.leReportTemplatePath.setText(path) self.splitter_custom_report.setEnabled(is_checked)
def set_org_disclaimer(self): """Auto-connect slot activated when org disclaimer checkbox is toggled. """ is_checked = self.custom_org_disclaimer_checkbox.isChecked() if is_checked: # Show previous organisation disclaimer org_disclaimer = setting('reportDisclaimer', default=disclaimer(), expected_type=str, qsettings=self.settings) else: # Set the organisation disclaimer to the default one org_disclaimer = disclaimer() self.txtDisclaimer.setPlainText(org_disclaimer) self.txtDisclaimer.setEnabled(is_checked)
def set_north_arrow(self): """Auto-connect slot activated when north arrow checkbox is toggled.""" is_checked = self.custom_north_arrow_checkbox.isChecked() if is_checked: # Show previous north arrow path path = setting( key='north_arrow_path', default=default_north_arrow_path(), expected_type=str, qsettings=self.settings) else: # Set the north arrow line edit to default one path = default_north_arrow_path() self.leNorthArrowPath.setText(path) self.splitter_north_arrow.setEnabled(is_checked)
def set_org_disclaimer(self): """Auto-connect slot activated when org disclaimer checkbox is toggled. """ is_checked = self.custom_org_disclaimer_checkbox.isChecked() if is_checked: # Show previous organisation disclaimer org_disclaimer = setting( 'reportDisclaimer', default=disclaimer(), expected_type=str, qsettings=self.settings) else: # Set the organisation disclaimer to the default one org_disclaimer = disclaimer() self.txtDisclaimer.setPlainText(org_disclaimer) self.txtDisclaimer.setEnabled(is_checked)
def set_user_dir(self): """Auto-connect slot activated when user dir checkbox is toggled. """ is_checked = self.custom_UseUserDirectory_checkbox.isChecked() if is_checked: # Show previous templates dir path = setting( key='defaultUserDirectory', default='', expected_type=str, qsettings=self.settings) else: # Set the template report dir to '' path = temp_dir('impacts') self.leUserDirectoryPath.setText(path) self.splitter_user_directory.setEnabled(is_checked)
def set_templates_dir(self): """Auto-connect slot activated when templates dir checkbox is toggled. """ is_checked = self.custom_templates_dir_checkbox.isChecked() if is_checked: # Show previous templates dir path = setting( key='reportTemplatePath', default='', expected_type=str, qsettings=self.settings) else: # Set the template report dir to '' path = '' self.leReportTemplatePath.setText(path) self.splitter_custom_report.setEnabled(is_checked)
def toggle_logo_path(self): """Set state of logo path line edit and button.""" is_checked = self.custom_organisation_logo_check_box.isChecked() if is_checked: # Use previous org logo path path = setting( key='organisation_logo_path', default=supporters_logo_path(), expected_type=str, qsettings=self.settings) else: # Set organisation path line edit to default one path = supporters_logo_path() self.organisation_logo_path_line_edit.setText(path) self.organisation_logo_path_line_edit.setEnabled(is_checked) self.open_organisation_logo_path_button.setEnabled(is_checked)
def append_ISO19115_keywords(keywords): """Append ISO19115 from setting to keywords. :param keywords: The keywords destination. :type keywords: dict """ # Map setting's key and metadata key ISO19115_mapping = { 'ISO19115_ORGANIZATION': 'organisation', 'ISO19115_URL': 'url', 'ISO19115_EMAIL': 'email', 'ISO19115_LICENSE': 'license' } ISO19115_keywords = {} # Getting value from setting. for key, value in list(ISO19115_mapping.items()): ISO19115_keywords[value] = setting(key, expected_type=str) keywords.update(ISO19115_keywords)
def template_chooser_clicked(self): """Slot activated when report file tool button is clicked. .. versionadded: 4.3.0 """ path = self.template_path.text() if not path: path = setting('lastCustomTemplate', '', str) if path: directory = dirname(path) else: directory = '' # noinspection PyCallByClass,PyTypeChecker file_name = QFileDialog.getOpenFileName( self, tr('Select report'), directory, tr('QGIS composer templates (*.qpt *.QPT)')) self.template_path.setText(file_name)
def earthquake_fatality_rate(hazard_level): """Earthquake fatality ratio for a given hazard level. It reads the QGIS QSettings to know what is the default earthquake function. :param hazard_level: The hazard level. :type hazard_level: int :return: The fatality rate. :rtype: float """ earthquake_function = setting( 'earthquake_function', EARTHQUAKE_FUNCTIONS[0]['key'], str) ratio = 0 for model in EARTHQUAKE_FUNCTIONS: if model['key'] == earthquake_function: eq_function = model['fatality_rates'] ratio = eq_function().get(hazard_level) return ratio
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()