def call_changes_per_parcel_panel(self, item): with OverrideCursor(Qt.WaitCursor): inverse = item.data(Qt.UserRole)['inverse'] base_db = self.utils._supplies_db if inverse else self.utils._db parcel_number = self.tbl_changes_all_parcels.item(item.row(), 0).text() # Obtain t_ids from parcels with NULL or duplicated parcel_number, before calling the per_parcel_panel parcels_t_ids = list() if parcel_number == QgsApplication.nullRepresentation( ): # TODO: does it make sense if the NULL parcels is only one? parcels_t_ids = self.compared_parcels_data[NULL][ base_db.names.T_ID_F] elif parcel_number in self.compared_parcels_data and self.compared_parcels_data[ parcel_number][ PARCEL_STATUS] == CHANGE_DETECTION_SEVERAL_PARCELS: parcels_t_ids = self.compared_parcels_data[parcel_number][ base_db.names.T_ID_F] if parcels_t_ids: dlg_select_parcel = SelectDuplicateParcelDialog( self.utils, parcels_t_ids, self.parent) dlg_select_parcel.exec_() if dlg_select_parcel.parcel_t_id: # User selected one of the duplicated parcels self.changes_per_parcel_panel_requested.emit( dlg_select_parcel.parcel_number, dlg_select_parcel.parcel_t_id) else: self.changes_per_parcel_panel_requested.emit( parcel_number, '') # 2nd parameter is mandatory for the signal :)
def add_format_to_text(self, rule, layers, options): """ Decorator used for registering log quality info :param self: QualityRuleEngine instance :param rule: Quality rule instance :param layers: layers :param options: Options for the quality rule """ self.qr_logger.set_initial_progress_emitted.emit(rule.name()) log_text_content = LOG_QUALITY_LIST_CONTAINER_OPEN start_time = time.time() with OverrideCursor(Qt.WaitCursor): qr_result = func_to_decorate(self, rule, layers, options) end_time = time.time() if qr_result.level == EnumQualityRuleResult.ERRORS: prefix = LOG_QUALITY_LIST_ITEM_ERROR_OPEN suffix = LOG_QUALITY_LIST_ITEM_ERROR_CLOSE elif qr_result.level == EnumQualityRuleResult.SUCCESS: prefix = LOG_QUALITY_LIST_ITEM_SUCCESS_OPEN suffix = LOG_QUALITY_LIST_ITEM_SUCCESS_CLOSE elif qr_result.level == EnumQualityRuleResult.CRITICAL: prefix = LOG_QUALITY_LIST_ITEM_CRITICAL_OPEN suffix = LOG_QUALITY_LIST_ITEM_CRITICAL_CLOSE else: # EnumQualityRuleResult.UNDEFINED prefix = LOG_QUALITY_LIST_ITEM_OPEN suffix = LOG_QUALITY_LIST_ITEM_CLOSE log_text_content += "{}{}{}".format(prefix, qr_result.msg, suffix) self.qr_logger.log_total_time = self.qr_logger.log_total_time + ( end_time - start_time) log_text_content += LOG_QUALITY_LIST_CONTAINER_CLOSE log_text_content += LOG_QUALITY_CONTENT_SEPARATOR self.qr_logger.log_text += "{}{} [{}]{}".format( LOG_QUALITY_PREFIX_TOPOLOGICAL_RULE_TITLE, rule.name(), Utils().set_time_format(end_time - start_time), LOG_QUALITY_SUFFIX_TOPOLOGICAL_RULE_TITLE) if options: # Try to get option titles instead of keys option_texts = list() for k, v in options.items(): obj = rule.options.get_options().get(k, None) option_texts.append("{}: {}".format(obj.title() if obj else k, v)) self.qr_logger.log_text += "{}{} {}{}".format( LOG_QUALITY_OPTIONS_OPEN, QCoreApplication.translate("QualityRules", "(Options)"), "; ".join(option_texts), LOG_QUALITY_OPTIONS_CLOSE) self.qr_logger.log_text += log_text_content self.qr_logger.set_final_progress_emitted.emit(rule.name()) return qr_result
def show_split_data_for_receivers_panel(self): with OverrideCursor(Qt.WaitCursor): self._reset_split_data_for_receivers_panel_vars() self.split_data_for_receivers_panel = self._get_split_data_for_receivers_panel() self.split_data_for_receivers_panel.refresh_parcel_data_clear_selection_requested.connect( self.allocate_panel.panel_accepted_refresh_and_clear_selection) self.widget.showPanel(self.split_data_for_receivers_panel) self.lst_split_data_for_receivers_panel.append(self.split_data_for_receivers_panel)
def show_configure_receivers_panel(self): with OverrideCursor(Qt.WaitCursor): self.__reset_receivers_panel_vars() self.configure_receivers_panel = self._get_receivers_panel() self.configure_receivers_panel.clear_message_bar_requested.connect( self.allocate_panel.panel_accepted_clear_message_bar) self.widget.showPanel(self.configure_receivers_panel) self.lst_configure_receivers_panel.append(self.configure_receivers_panel)
def show_allocate_parcels_to_receiver_panel(self, selected_parcels): with OverrideCursor(Qt.WaitCursor): self._reset_allocate_parcels_to_receiver_panel_vars() self.allocate_parcels_to_receiver_panel = self._get_allocate_to_receiver_panel(selected_parcels) self.allocate_parcels_to_receiver_panel.refresh_parcel_data_requested.connect( self.allocate_panel.panel_accepted_refresh_parcel_data) self.widget.showPanel(self.allocate_parcels_to_receiver_panel) self.lst_allocate_parcels_to_receiver_panel.append(self.allocate_parcels_to_receiver_panel)
def _search_data_by_plot(self, plot_feature): plot_t_id = plot_feature[self._controller.t_id_name()] self.app.gui.flash_features(self._controller.plot_layer(), [plot_feature.id()]) with OverrideCursor(Qt.WaitCursor): if not self.isVisible(): self.show() self._search_data_by_component(plot_t_ids=[plot_t_id], zoom_and_select=False) self._controller.plot_layer().selectByIds([plot_feature.id()])
def show_error_results_panel(self): with OverrideCursor(Qt.WaitCursor): if self.__error_results_panel is not None: try: self.widget.closePanel(self.__error_results_panel) except RuntimeError as e: # Panel in C++ could be already closed... pass self.__error_results_panel = None self.__error_results_panel = QualityRulesErrorResultsPanelWidget(self.__controller, self) self.__error_results_panel.panelAccepted.connect(self.__controller.reset_vars_for_error_results_panel) self.widget.showPanel(self.__error_results_panel)
def features_added(layer_id, features): modified_layer = QgsProject.instance().mapLayer(layer_id) if modified_layer is None or QgsDataSourceUri( modified_layer.source()).table().lower() != layer.name( ).lower(): return with OverrideCursor(Qt.WaitCursor): new_values = self.upload_files(modified_layer, field_index, features) if new_values: modified_layer.dataProvider().changeAttributeValues(new_values)
def show_task_panel(self, task_id): with OverrideCursor(Qt.WaitCursor): if self.task_panel is not None: try: self.widget.closePanel(self.task_panel) except RuntimeError as e: # Panel in C++ could be already closed... pass self.task_panel = None self.task_panel = TaskPanelWidget(task_id, self) self.task_panel.trigger_action_emitted.connect(self.trigger_action_emitted) self.task_panel.panelAccepted.connect(self.reload_tasks) self.widget.showPanel(self.task_panel)
def get_info_by_plot(self, plot_feature): plot_t_id = plot_feature[ID_FIELD] self.canvas.flashFeatureIds(self._plot_layer, [plot_feature.id()], QColor(255, 0, 0, 255), QColor(255, 0, 0, 0), flashes=1, duration=500) with OverrideCursor(Qt.WaitCursor): self._plot_layer.selectByIds([plot_feature.id()]) if not self.isVisible(): self.show() self.search_data_by_component(plot_t_id=plot_t_id)
def show_all_parcels_panel(self, dict_parcels, types_change_detection): with OverrideCursor(Qt.WaitCursor): if self.lst_all_parcels_panels: for panel in self.lst_all_parcels_panels: try: self.widget.closePanel(panel) except RuntimeError as e: # Panel in C++ could be already closed... pass self.lst_all_parcels_panels = list() self.all_parcels_panel = None self.all_parcels_panel = ChangesAllParcelsPanelWidget(self, self.utils, dict_parcels, types_change_detection) self.all_parcels_panel.changes_per_parcel_panel_requested.connect(self.show_parcel_panel) self.widget.showPanel(self.all_parcels_panel) self.lst_all_parcels_panels.append(self.all_parcels_panel)
def get_info_by_plot(self, plot_feature): plot_t_id = plot_feature[self.names.T_ID_F] self.canvas.flashFeatureIds(self._layers[self.names.OP_PLOT_T][LAYER], [plot_feature.id()], QColor(255, 0, 0, 255), QColor(255, 0, 0, 0), flashes=1, duration=500) with OverrideCursor(Qt.WaitCursor): if not self.isVisible(): self.show() self.search_data_by_component(plot_t_id=plot_t_id, zoom_and_select=False) self._layers[self.names.OP_PLOT_T][LAYER].selectByIds( [plot_feature.id()])
def features_added(layer_id, features): modified_layer = QgsProject.instance().mapLayer(layer_id) if modified_layer is None: return modified_layer_name = db.get_ladm_layer_name(modified_layer, validate_is_ladm=True) if modified_layer_name is None: return if modified_layer_name.lower() != layer_name.lower(): return with OverrideCursor(Qt.WaitCursor): new_values = self.upload_files(modified_layer, field_index, features) if new_values: modified_layer.dataProvider().changeAttributeValues(new_values)
def show_general_results_panel(self, mode): """ :params mode: EnumQualityRulePanelMode """ with OverrideCursor(Qt.WaitCursor): self.__delete_general_result_panel() self.__general_results_panel = QualityRulesGeneralResultsPanelWidget(self.__controller, mode, self) self.__controller.total_progress_changed.connect(self.__general_results_panel.update_total_progress) self.__general_results_panel.panelAccepted.connect(self.__controller.reset_vars_for_general_results_panel) self.widget.showPanel(self.__general_results_panel) if mode == EnumQualityRulePanelMode.VALIDATE: self.logger.clear_message_bar() res, msg, db_qr = self.__controller.validate_qrs() if not res: self.__general_results_panel.unblock_panel() self.widget.acceptAllPanels() # Go back to initial panel self.logger.warning_msg(__name__, msg)
def prepare_copy_csv_points_to_db(self): csv_path = self.txt_file_path.text().strip() if not csv_path or not os.path.exists(csv_path): self.logger.warning_msg(__name__, QCoreApplication.translate("WizardTranslations", "No CSV file given or file doesn't exist.")) return target_layer_name = self.current_point_name() with OverrideCursor(Qt.WaitCursor): csv_layer = self.app.core.csv_to_layer(csv_path, self.txt_delimiter.text(), self.cbo_longitude.currentText(), self.cbo_latitude.currentText(), self.crs, self.cbo_elevation.currentText() or None, self.detect_decimal_point(csv_path)) self.app.core.copy_csv_to_db(csv_layer, self._db, target_layer_name)
def add_format_to_text(self, rule_key, layers, **args): """ Decorator used for registering log quality info :param self: QualityDialog instance :param rule_key: rule_key :param layers: layers :param args: 'rule_name' is the executed quality rule name """ rule_name = args['rule_name'] self.quality_rule_logger.set_initial_progress_emitted.emit(rule_name) log_text_content = LOG_QUALITY_LIST_CONTAINER_OPEN start_time = time.time() with OverrideCursor(Qt.WaitCursor): msg, level = func_to_decorate(self, rule_key, layers, **args) end_time = time.time() if level == Qgis.Critical: prefix = LOG_QUALITY_LIST_ITEM_ERROR_OPEN suffix = LOG_QUALITY_LIST_ITEM_ERROR_CLOSE elif level == Qgis.Success: prefix = LOG_QUALITY_LIST_ITEM_CORRECT_OPEN suffix = LOG_QUALITY_LIST_ITEM_CORRECT_CLOSE else: # Qgis.Warning prefix = LOG_QUALITY_LIST_ITEM_OPEN suffix = LOG_QUALITY_LIST_ITEM_CLOSE log_text_content += "{}{}{}".format(prefix, msg, suffix) self.quality_rule_logger.log_total_time = self.quality_rule_logger.log_total_time + ( end_time - start_time) log_text_content += LOG_QUALITY_LIST_CONTAINER_CLOSE log_text_content += LOG_QUALITY_CONTENT_SEPARATOR self.quality_rule_logger.log_text += "{}{} [{}]{}".format( LOG_QUALITY_PREFIX_TOPOLOGICAL_RULE_TITLE, rule_name, Utils().set_time_format(end_time - start_time), LOG_QUALITY_SUFFIX_TOPOLOGICAL_RULE_TITLE) self.quality_rule_logger.log_text += log_text_content self.quality_rule_logger.set_final_progress_emitted.emit(rule_name)
def add_format_to_text(self, db, **args): rule_name = args['rule_name'] self.log_quality_set_initial_progress_emitted.emit(rule_name) self.log_dialog_quality_text_content += LOG_QUALITY_LIST_CONTAINER_OPEN start_time = time.time() with OverrideCursor(Qt.WaitCursor): func_to_decorate(self, db, **args) end_time = time.time() self.total_time = self.total_time + (end_time - start_time) self.log_dialog_quality_text_content += LOG_QUALITY_LIST_CONTAINER_CLOSE self.log_dialog_quality_text_content += LOG_QUALITY_CONTENT_SEPARATOR self.log_dialog_quality_text += "{}{} [{}]{}".format(LOG_QUALITY_PREFIX_TOPOLOGICAL_RULE_TITLE, rule_name, self.utils.set_time_format(end_time - start_time), LOG_QUALITY_SUFFIX_TOPOLOGICAL_RULE_TITLE) self.log_dialog_quality_text += self.log_dialog_quality_text_content self.log_dialog_quality_text_content = "" self.log_quality_set_final_progress_emitted.emit(rule_name)
def accepted(self): self.bar.clearWidgets() self.save_settings(self.data_system) self.folder_path = self.txt_file_path_folder_supplies.text() self.file_names = self.txt_file_names_supplies.text().strip() self.gpkg_path = os.path.join(self.folder_path, '{}.gpkg'.format(self.file_names)) self.xlsx_path = os.path.join(self.folder_path, '{}.xlsx'.format(self.file_names)) reply = self.validate_files_in_folder() csv_paths = {'PREDIO': self.txt_file_path_predio.text().strip()} required_layers = [ 'R_TERRENO', 'U_TERRENO', 'R_VEREDA', 'U_MANZANA', 'R_CONSTRUCCION', 'U_CONSTRUCCION', 'U_UNIDAD', 'R_UNIDAD' ] if reply == QMessageBox.Yes: with OverrideCursor(Qt.WaitCursor): self.set_gui_controls_enabled(False) res_csv, msg_csv = self.load_csv_files(csv_paths) if res_csv: res_gdb, msg_gdb = self.load_gdb_files(required_layers) if res_gdb: self._running_tool = True res_etl, msg_etl = self.run_model_missing_snc_supplies( ) self.progress_base = 100 # We start counting a second step from 100 if res_etl: # Since we have two steps, we need to check at this point if the user already canceled if not self.custom_feedback.isCanceled(): self.logger.clear_status() res_gpkg, msg_gpkg = self.package_results( self.output_etl_missing_snc) if res_gpkg: self.generate_excel_report() if not self.custom_feedback.isCanceled(): self.progress.setValue( self.progress_maximum) self.buttonBox.clear() self.buttonBox.setEnabled(True) self.buttonBox.addButton( QDialogButtonBox.Close) msg = QCoreApplication.translate( "Asistente-LADM-COL", "Missing supplies report successfully generated in folder <a href='file:///{normalized_path1}'>{path1}</a>! The output Geopackage database can be found in <a href='file:///{normalized_path2}'>{path2}</a>" ).format(normalized_path1= normalize_local_url( self.xlsx_path), path1=self.xlsx_path, normalized_path2= normalize_local_url( self.gpkg_path), path2=self.gpkg_path) self.logger.clear_status() self.logger.success_msg(__name__, msg) else: self.initialize_feedback( ) # Get ready for an eventual new execution self.progress_base = 0 self.logger.clear_status() self._running_tool = False else: # User could have canceled while running the second algorithm if self.custom_feedback.isCanceled(): self.initialize_feedback( ) # Get ready for an eventual new execution self.progress_base = 0 self._running_tool = False else: self.show_message( msg_gpkg, Qgis.Warning) else: # User canceled in the first algorithm self.initialize_feedback() self.progress_base = 0 self._running_tool = False self.logger.clear_status() else: self.show_message(msg_etl, Qgis.Warning) else: self.show_message(msg_gdb, Qgis.Warning) else: self.show_message(msg_csv, Qgis.Warning) self.set_gui_controls_enabled(True)
def accepted(self): self._running_tool = True self.txtStdout.clear() self.progress_bar.setValue(0) self.bar.clearWidgets() if not os.path.isfile(self.xtf_file_line_edit.text().strip()): self._running_tool = False error_msg = QCoreApplication.translate( "DialogImportData", "Please set a valid XTF file before importing data. XTF file does not exist." ) self.txtStdout.setText(error_msg) self.show_message(error_msg, Qgis.Warning) self.xtf_file_line_edit.setFocus() return java_home_set = self.java_dependency.set_java_home() if not java_home_set: message_java = QCoreApplication.translate( "DialogImportData", """Configuring Java {}...""").format(JAVA_REQUIRED_VERSION) self.txtStdout.setTextColor(QColor('#000000')) self.txtStdout.clear() self.txtStdout.setText(message_java) self.java_dependency.get_java_on_demand() self.disable() return configuration = self.update_configuration() if configuration.disable_validation: # If data validation at import is disabled, we ask for confirmation self.msg = QMessageBox() self.msg.setIcon(QMessageBox.Question) self.msg.setText( QCoreApplication.translate( "DialogImportData", "Are you sure you want to import your data without validation?" )) self.msg.setWindowTitle( QCoreApplication.translate("DialogImportData", "Import XTF without validation?")) self.msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) res = self.msg.exec_() if res == QMessageBox.No: self._running_tool = False return if not self.xtf_file_line_edit.validator().validate( configuration.xtffile, 0)[0] == QValidator.Acceptable: self._running_tool = False error_msg = QCoreApplication.translate( "DialogImportData", "Please set a valid XTF before importing data.") self.txtStdout.setText(error_msg) self.show_message(error_msg, Qgis.Warning) self.xtf_file_line_edit.setFocus() return if not self.get_ili_models(): self._running_tool = False error_msg = QCoreApplication.translate( "DialogImportData", "The selected XTF file does not have information according to the LADM-COL model to import." ) self.txtStdout.setText(error_msg) self.show_message(error_msg, Qgis.Warning) self.import_models_list_view.setFocus() return # Get list of models present in the XTF file, in the DB and in the list of required models (by the plugin) ili_models = set([ili_model for ili_model in self.get_ili_models()]) supported_models_in_ili = set([ m.full_name() for m in self.__ladmcol_models.supported_models() ]).intersection(ili_models) if not supported_models_in_ili: self._running_tool = False error_msg = QCoreApplication.translate("DialogImportData", "The selected XTF file does not have data from any LADM-COL model supported by the LADM-COL Assistant. " \ "Therefore, you cannot import it! These are the models supported:\n\n * {}").format(" \n * ".join([m.full_alias() for m in self.__ladmcol_models.supported_models()])) self.txtStdout.setText(error_msg) self.show_message(error_msg, Qgis.Warning) self.import_models_list_view.setFocus() return db_models = set(self.db.get_models()) suggested_models = sorted(ili_models.difference(db_models)) if not ili_models.issubset(db_models): self._running_tool = False error_msg = QCoreApplication.translate("DialogImportData", "IMPORT ERROR: The XTF file to import does not have the same models as the target database schema. " \ "Please create a schema that also includes the following missing modules:\n\n * {}").format( " \n * ".join(suggested_models)) self.txtStdout.clear() self.txtStdout.setTextColor(QColor('#000000')) self.txtStdout.setText(error_msg) self.show_message(error_msg, Qgis.Warning) self.xtf_file_line_edit.setFocus() # button is removed to define order in GUI for button in self.buttonBox.buttons(): if button.text() == self.BUTTON_NAME_IMPORT_DATA: self.buttonBox.removeButton(button) # Check if button was previously added self.remove_create_structure_button() if self.link_to_import_schema: self.buttonBox.addButton( self.BUTTON_NAME_GO_TO_CREATE_STRUCTURE, QDialogButtonBox.AcceptRole).setStyleSheet( "color: #aa2222;") self.buttonBox.addButton(self.BUTTON_NAME_IMPORT_DATA, QDialogButtonBox.AcceptRole) return with OverrideCursor(Qt.WaitCursor): self.progress_bar.show() self.disable() self.txtStdout.setTextColor(QColor('#000000')) self.txtStdout.clear() dataImporter = iliimporter.Importer(dataImport=True) db_factory = self._dbs_supported.get_db_factory(self.db.engine) dataImporter.tool = db_factory.get_model_baker_db_ili_mode() dataImporter.configuration = configuration self.save_configuration(configuration) dataImporter.stdout.connect(self.print_info) dataImporter.stderr.connect(self.on_stderr) dataImporter.process_started.connect(self.on_process_started) dataImporter.process_finished.connect(self.on_process_finished) self.progress_bar.setValue(25) try: if dataImporter.run() != iliimporter.Importer.SUCCESS: self._running_tool = False self.show_message( QCoreApplication.translate( "DialogImportData", "An error occurred when importing the data. For more information see the log..." ), Qgis.Warning) return except JavaNotFoundError: self._running_tool = False error_msg_java = QCoreApplication.translate( "DialogImportData", "Java {} could not be found. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again." ).format(JAVA_REQUIRED_VERSION) self.txtStdout.setTextColor(QColor('#000000')) self.txtStdout.clear() self.txtStdout.setText(error_msg_java) self.show_message(error_msg_java, Qgis.Warning) return self._running_tool = False self.buttonBox.clear() self.buttonBox.setEnabled(True) self.buttonBox.addButton(QDialogButtonBox.Close) self.progress_bar.setValue(100) self.show_message( QCoreApplication.translate( "DialogImportData", "Import of the data was successfully completed"), Qgis.Success)
def export_baskets(self): java_home_set = self.java_dependency.set_java_home() if not java_home_set: message_java = QCoreApplication.translate("BasketExporter", """Configuring Java {}...""").format( JAVA_REQUIRED_VERSION) self.logger.status(message_java) self.java_dependency.get_java_on_demand() return self.base_configuration = BaseConfiguration() self.ilicache = IliCache(self.base_configuration) db_factory = self._dbs_supported.get_db_factory(self._db.engine) self.configuration = ExportConfiguration() db_factory.set_ili2db_configuration_params(self._db.dict_conn_params, self.configuration) self.configuration.with_exporttid = True full_java_exe_path = JavaDependency.get_full_java_exe_path() if full_java_exe_path: self.base_configuration.java_path = full_java_exe_path # Check custom model directories if QSettings().value('Asistente-LADM-COL/models/custom_model_directories_is_checked', DEFAULT_USE_CUSTOM_MODELS, type=bool): custom_model_directories = QSettings().value('Asistente-LADM-COL/models/custom_models', DEFAULT_MODELS_DIR) if not custom_model_directories: self.base_configuration.custom_model_directories_enabled = False else: self.base_configuration.custom_model_directories = custom_model_directories self.base_configuration.custom_model_directories_enabled = True self.ilicache.refresh() # Always call it after setting custom_model_directories self.configuration.base_configuration = self.base_configuration if self.get_ili_models(): self.configuration.ilimodels = ';'.join(self.get_ili_models()) self.exporter = iliexporter.Exporter() self.exporter.tool = db_factory.get_model_baker_db_ili_mode() self.exporter.process_started.connect(self.on_process_started) self.exporter.stderr.connect(self.on_stderr) #self.exporter.process_finished.connect(self.on_process_finished) res = dict() count = 0 total = len(self._basket_dict) with OverrideCursor(Qt.WaitCursor): for basket,name in self._basket_dict.items(): self.log = '' self.configuration.xtffile = os.path.join(self._export_dir, "{}.xtf".format(name)) self.configuration.baskets = basket self.exporter.configuration = self.configuration try: if self.exporter.run() != iliexporter.Exporter.SUCCESS: msg = QCoreApplication.translate("BasketExporter", "An error occurred when exporting the data for '{}' (check the QGIS log panel).").format(name) res[basket] = (False, msg) QgsMessageLog.logMessage(self.log, QCoreApplication.translate("BasketExporter", "Allocate to coordinators"), Qgis.Critical) else: res[basket] = (True, QCoreApplication.translate("BasketExporter", "XTF export for '{}' successful!").format(name) ) except JavaNotFoundError: msg = QCoreApplication.translate("BasketExporter", "Java {} could not be found. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again.").format(JAVA_REQUIRED_VERSION) res[basket] = (False, msg) count += 1 self.total_progress_updated.emit(count/total*100) return res
def import_button_clicked(self): self.bar.clearWidgets() self.save_settings() etl_result = False if self.rad_snc_data.isChecked(): etl = ETLSNC(self.names, self._data_source_widget) else: # Cobol etl = ETLCobol(self.names, self._data_source_widget) if self._db.test_connection()[0]: reply = QMessageBox.question( self, QCoreApplication.translate("SuppliesETLWizard", "Warning"), QCoreApplication.translate( "SuppliesETLWizard", "The database <i>{}</i> already has a valid LADM-COL structure.<br/><br/>If such database has any data, loading data into it might cause invalid data.<br/><br/>Do you still want to continue?" ).format(self._db.get_description_conn_string()), QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: self.set_gui_controls_enabled(False) self.button(self.BackButton).setEnabled(False) self.button(self.CustomButton1).setEnabled(False) self.button(self.CancelButton).setText( QCoreApplication.translate("SuppliesETLWizard", "Cancel")) with OverrideCursor(Qt.WaitCursor): res_alpha, msg_alpha = etl.load_alphanumeric_layers() if res_alpha: res_spatial, msg_spatial = etl.load_spatial_layers() if res_spatial: res_model, msg_model = self.load_model_layers( etl.layers) if res_model: layers_feature_count_before = { name: layer.featureCount() for name, layer in etl.layers.items() } self._running_tool = True self.progress.setVisible(True) res_etl_model = etl.run_etl_model( self.custom_feedback) if not self.custom_feedback.isCanceled( ) and res_etl_model: self.progress.setValue(100) self.button( self.NextButton).setVisible(True) self.button( self.CustomButton1).setVisible(False) self.button(self.CancelButton).setText( QCoreApplication.translate( "SuppliesETLWizard", "Close")) self.show_message( QCoreApplication.translate( "SuppliesETLWizard", "The {} has finished successfully!" ).format(self.tool_name), Qgis.Success, 0) self.logger.clear_status() self.fill_summary( layers_feature_count_before, etl.layers) etl_result = True else: self.initialize_feedback( ) # Get ready for an eventual new execution self.logger.clear_status() self._running_tool = False else: self.show_message(msg_model, Qgis.Warning) else: self.show_message(msg_spatial, Qgis.Warning) else: self.show_message(msg_alpha, Qgis.Warning) else: with OverrideCursor(Qt.WaitCursor): # TODO: if an empty schema was selected, do the magic under the hood # self.create_model_into_database() # Now execute "accepted()" msg = QCoreApplication.translate( "SuppliesETLWizard", "To run the ETL, the database (schema) should have the Supplies LADM-COL structure. Choose a proper database (schema) and try again." ) self.show_message(msg, Qgis.Warning) self.logger.warning(__name__, msg) self.on_result.emit( etl_result) # Inform other classes if the execution was successful
def accepted(self): self._running_tool = True self.txtStdout.clear() self.progress_bar.setValue(0) self.bar.clearWidgets() java_home_set = self.java_dependency.set_java_home() if not java_home_set: message_java = QCoreApplication.translate( "DialogImportSchema", """Configuring Java {}...""").format(JAVA_REQUIRED_VERSION) self.txtStdout.setTextColor(QColor('#000000')) self.txtStdout.clear() self.txtStdout.setText(message_java) self.java_dependency.get_java_on_demand() self.disable() return configuration = self.update_configuration() configuration = self.apply_role_model_configuration(configuration) if not self.get_checked_models(): self._running_tool = False message_error = QCoreApplication.translate( "DialogImportSchema", "You should select a valid model(s) before creating the LADM-COL structure." ) self.txtStdout.setText(message_error) self.show_message(message_error, Qgis.Warning) self.import_models_list_widget.setFocus() return self.save_configuration(configuration) with OverrideCursor(Qt.WaitCursor): self.progress_bar.show() self.disable() self.txtStdout.setTextColor(QColor('#000000')) self.txtStdout.clear() importer = iliimporter.Importer() db_factory = self._dbs_supported.get_db_factory(self.db.engine) importer.tool = db_factory.get_model_baker_db_ili_mode() importer.configuration = configuration importer.stdout.connect(self.print_info) importer.stderr.connect(self.on_stderr) importer.process_started.connect(self.on_process_started) importer.process_finished.connect(self.on_process_finished) try: if importer.run() != iliimporter.Importer.SUCCESS: self._running_tool = False self.show_message( QCoreApplication.translate( "DialogImportSchema", "An error occurred when creating the LADM-COL structure. For more information see the log..." ), Qgis.Warning) self.on_result.emit( False ) # Inform other classes that the execution was not successful return except JavaNotFoundError: self._running_tool = False message_error_java = QCoreApplication.translate( "DialogImportSchema", "Java {} could not be found. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again." ).format(JAVA_REQUIRED_VERSION) self.txtStdout.setTextColor(QColor('#000000')) self.txtStdout.clear() self.txtStdout.setText(message_error_java) self.show_message(message_error_java, Qgis.Warning) return self._running_tool = False self.buttonBox.clear() if self.link_to_import_data: self.buttonBox.addButton( self.BUTTON_NAME_GO_TO_IMPORT_DATA, QDialogButtonBox.AcceptRole).setStyleSheet( "color: #007208;") self.buttonBox.setEnabled(True) self.buttonBox.addButton(QDialogButtonBox.Close) self.progress_bar.setValue(100) self.print_info( QCoreApplication.translate("DialogImportSchema", "\nDone!"), '#004905') self.show_message( QCoreApplication.translate( "DialogImportSchema", "LADM-COL structure was successfully created!"), Qgis.Success) self.on_result.emit( True) # Inform other classes that the execution was successful self._db_was_changed = True # Schema could become LADM compliant after a schema import if self.db_source == COLLECTED_DB_SOURCE: self.logger.info( __name__, "Schedule a call to refresh db relations cache since a Schema Import was run on the current 'collected' DB." ) self._schedule_layers_and_relations_refresh = True
def decorated_function(*args, **kwargs): with OverrideCursor(Qt.WaitCursor): func_to_decorate(*args, **kwargs)
def accepted(self): self._running_tool = True self.bar.clearWidgets() java_home_set = self.java_utils.set_java_home() if not java_home_set: message_java = QCoreApplication.translate( "DialogExportData", """Configuring Java {}...""").format(JAVA_REQUIRED_VERSION) self.txtStdout.setTextColor(QColor('#000000')) self.txtStdout.clear() self.txtStdout.setText(message_java) self.java_utils.get_java_on_demand() self.disable() return configuration = self.update_configuration() if not self.xtf_file_line_edit.validator().validate( configuration.xtffile, 0)[0] == QValidator.Acceptable: self._running_tool = False message_error = QCoreApplication.translate( "DialogExportData", "Please set a valid XTF file before exporting data.") self.txtStdout.setText(message_error) self.show_message(message_error, Qgis.Warning) self.xtf_file_line_edit.setFocus() return if not self.get_ili_models(): self._running_tool = False message_error = QCoreApplication.translate( "DialogExportData", "Please set a valid schema to export. This schema does not have information to export." ) self.txtStdout.setText(message_error) self.show_message(message_error, Qgis.Warning) self.export_models_list_view.setFocus() return if not configuration.iliexportmodels: self._running_tool = False message_error = QCoreApplication.translate( "DialogExportData", "Please set a model before exporting data.") self.txtStdout.setText(message_error) self.show_message(message_error, Qgis.Warning) self.export_models_list_view.setFocus() return # If xtf browser was opened and the file exists, the user already chose # to overwrite the file if os.path.isfile(self.xtf_file_line_edit.text().strip() ) and not self.xtf_browser_was_opened: self.msg = QMessageBox() self.msg.setIcon(QMessageBox.Warning) self.msg.setText( QCoreApplication.translate( "DialogExportData", "{filename} already exists.\nDo you want to replace it?"). format(filename=os.path.basename( self.xtf_file_line_edit.text().strip()))) self.msg.setWindowTitle( QCoreApplication.translate("DialogExportData", "Save in XTF Transfer File")) self.msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msg_box = self.msg.exec_() if msg_box == QMessageBox.No: self._running_tool = False return with OverrideCursor(Qt.WaitCursor): self.progress_bar.show() self.disable() self.txtStdout.setTextColor(QColor('#000000')) self.txtStdout.clear() exporter = iliexporter.Exporter() db_factory = self._dbs_supported.get_db_factory(self.db.engine) exporter.tool = db_factory.get_mbaker_db_ili_mode() exporter.configuration = configuration self.save_configuration(configuration) exporter.stdout.connect(self.print_info) exporter.stderr.connect(self.on_stderr) exporter.process_started.connect(self.on_process_started) exporter.process_finished.connect(self.on_process_finished) self.progress_bar.setValue(25) try: if exporter.run() != iliexporter.Exporter.SUCCESS: self._running_tool = False self.show_message( QCoreApplication.translate( "DialogExportData", "An error occurred when exporting the data. For more information see the log..." ), Qgis.Warning) self.on_result.emit( False ) # Inform other classes that the execution was not successful return except JavaNotFoundError: self._running_tool = False message_error_java = QCoreApplication.translate( "DialogExportData", "Java {} could not be found. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again." ).format(JAVA_REQUIRED_VERSION) self.txtStdout.setTextColor(QColor('#000000')) self.txtStdout.clear() self.txtStdout.setText(message_error_java) self.show_message(message_error_java, Qgis.Warning) return self._running_tool = False self.buttonBox.clear() self.buttonBox.setEnabled(True) self.buttonBox.addButton(QDialogButtonBox.Close) self.progress_bar.setValue(100) self.show_message( QCoreApplication.translate( "DialogExportData", "Export of the data was successfully completed."), Qgis.Success) self.on_result.emit( True) # Inform other classes that the execution was successful
def accepted(self): self.bar.clearWidgets() self.save_settings() if self._db.test_connection()[0]: reply = QMessageBox.question( self, QCoreApplication.translate("ETLCobolDialog", "Warning"), QCoreApplication.translate( "ETLCobolDialog", "The database <i>{}</i> already has a valid LADM_COL structure.<br/><br/>If such database has any data, loading data into it might cause invalid data.<br/><br/>Do you still want to continue?" ).format(self._db.get_description_conn_string()), QMessageBox.Yes, QMessageBox.No) lis_paths = { 'blo': self.txt_file_path_blo.text().strip(), 'uni': self.txt_file_path_uni.text().strip(), 'ter': self.txt_file_path_ter.text().strip(), 'pro': self.txt_file_path_pro.text().strip() } required_layers = [ 'R_TERRENO', 'U_TERRENO', 'R_SECTOR', 'U_SECTOR', 'R_VEREDA', 'U_MANZANA', 'U_BARRIO', 'R_CONSTRUCCION', 'U_CONSTRUCCION', 'U_UNIDAD', 'R_UNIDAD', 'U_NOMENCLATURA_DOMICILIARIA', 'R_NOMENCLATURA_DOMICILIARIA', 'U_PERIMETRO' ] if reply == QMessageBox.Yes: self.set_gui_controls_enabled(False) with OverrideCursor(Qt.WaitCursor): res_lis, msg_lis = self.load_lis_files(lis_paths) if res_lis: res_gdb, msg_gdb = self.load_gdb_files(required_layers) if res_gdb: res_model, msg_model = self.load_model_layers() if res_model: self._running_tool = True self.run_model_etl_cobol() if not self.custom_feedback.isCanceled(): self.progress.setValue(100) self.buttonBox.clear() self.buttonBox.setEnabled(True) self.buttonBox.addButton( QDialogButtonBox.Close) self.logger.clear_status() self._etl_result = True else: self.initialize_feedback( ) # Get ready for an eventual new execution self.logger.clear_status() self._running_tool = False else: self.show_message(msg_model, Qgis.Warning) else: self.show_message(msg_gdb, Qgis.Warning) else: self.show_message(msg_lis, Qgis.Warning) self.set_gui_controls_enabled(True) else: with OverrideCursor(Qt.WaitCursor): # TODO: if an empty schema was selected, do the magic under the hood # self.create_model_into_database() # Now execute "accepted()" msg = QCoreApplication.translate( "ETLCobolDialog", "To run the ETL, the database (schema) should have the Supplies LADM_COL structure. Choose a proper database (schema) and try again." ) self.show_message(msg, Qgis.Warning) self.logger.warning(__name__, msg) self.on_result.emit( self._etl_result ) # Inform other classes if the execution was successful self._etl_result = False # Next run?
def generate_report(self, db, report_type): # Check if mapfish and Jasper are installed, otherwise show where to # download them from and return if not self.report_dependency.check_if_dependency_is_valid(): self.report_dependency.download_dependency(URL_REPORTS_LIBRARIES) return java_home_set = self.java_dependency.set_java_home() if not java_home_set: self.java_dependency.get_java_on_demand() self.logger.info_msg( __name__, QCoreApplication.translate( "ReportGenerator", "Java is a prerequisite. Since it was not found, it is being configured..." )) return plot_layer = self.app.core.get_layer(db, db.names.LC_PLOT_T, load=True) if not plot_layer: return selected_plots = plot_layer.selectedFeatures() if not selected_plots: self.logger.warning_msg( __name__, QCoreApplication.translate( "ReportGenerator", "To generate reports, first select at least a plot!")) return # Where to store the reports? previous_folder = QSettings().value( "Asistente-LADM-COL/reports/save_into_dir", ".") save_into_folder = QFileDialog.getExistingDirectory( None, QCoreApplication.translate( "ReportGenerator", "Select a folder to save the reports to be generated"), previous_folder) if not save_into_folder: self.logger.warning_msg( __name__, QCoreApplication.translate( "ReportGenerator", "You need to select a folder where to save the reports before continuing." )) return QSettings().setValue("Asistente-LADM-COL/reports/save_into_dir", save_into_folder) config_path = os.path.join(DEPENDENCY_REPORTS_DIR_NAME, report_type) json_spec_file = os.path.join(config_path, 'spec_json_file.json') script_name = '' if os.name == 'posix': script_name = 'print' elif os.name == 'nt': script_name = 'print.bat' script_path = os.path.join(DEPENDENCY_REPORTS_DIR_NAME, 'bin', script_name) if not os.path.isfile(script_path): self.logger.warning( __name__, "Script file for reports wasn't found! {}".format(script_path)) return self.enable_action_requested.emit(report_type, False) # Update config file yaml_config_path = self.update_yaml_config(db, config_path) self.logger.debug( __name__, "Config file for reports: {}".format(yaml_config_path)) total = len(selected_plots) step = 0 count = 0 tmp_dir = self.get_tmp_dir() # Progress bar setup progress = QProgressBar() if total == 1: progress.setRange(0, 0) else: progress.setRange(0, 100) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.app.gui.create_progress_message_bar( QCoreApplication.translate("ReportGenerator", "Generating {} report{}...").format( total, '' if total == 1 else 's'), progress) polygons_with_holes = [] with OverrideCursor(Qt.WaitCursor): for selected_plot in selected_plots: plot_id = selected_plot[db.names.T_ID_F] geometry = selected_plot.geometry() abstract_geometry = geometry.constGet() if abstract_geometry.ringCount() > 1: polygons_with_holes.append(str(plot_id)) self.logger.warning( __name__, QCoreApplication.translate( "ReportGenerator", "Skipping Annex 17 for plot with {}={} because it has holes. The reporter module does not support such polygons." ).format(db.names.T_ID_F, plot_id)) continue # Generate data file json_file = self.update_json_data(db, json_spec_file, plot_id, tmp_dir, report_type) self.logger.debug( __name__, "JSON file for reports: {}".format(json_file)) # Run sh/bat passing config and data files proc = QProcess() proc.readyReadStandardError.connect( functools.partial(self.stderr_ready, proc=proc)) proc.readyReadStandardOutput.connect( functools.partial(self.stdout_ready, proc=proc)) parcel_number = self.ladm_data.get_parcels_related_to_plots( db, [plot_id], db.names.LC_PARCEL_T_PARCEL_NUMBER_F) or [''] self.app.gui.activate_layer( plot_layer ) # Previous function changed the selected layer, so, select again plot layer file_name = '{}_{}_{}.pdf'.format(report_type, plot_id, parcel_number[0]) current_report_path = os.path.join(save_into_folder, file_name) proc.start(script_path, [ '-config', yaml_config_path, '-spec', json_file, '-output', current_report_path ]) if not proc.waitForStarted(): # Grant execution permissions os.chmod( script_path, stat.S_IXOTH | stat.S_IXGRP | stat.S_IXUSR | stat.S_IRUSR | stat.S_IRGRP) proc.start(script_path, [ '-config', yaml_config_path, '-spec', json_file, '-output', current_report_path ]) if not proc.waitForStarted(): proc = None self.logger.warning( __name__, "Couldn't execute script to generate report...") else: loop = QEventLoop() proc.finished.connect(loop.exit) loop.exec() self.logger.debug(__name__, "{}:{}".format(plot_id, proc.exitCode())) if proc.exitCode() == 0: count += 1 step += 1 try: progress.setValue(step * 100 / total) except RuntimeError: pass # progressBar was deleted os.remove(yaml_config_path) self.enable_action_requested.emit(report_type, True) self.logger.clear_message_bar() if total == count: if total == 1: msg = QCoreApplication.translate( "ReportGenerator", "The report <a href='file:///{}'>{}</a> was successfully generated!" ).format(normalize_local_url(save_into_folder), file_name) else: msg = QCoreApplication.translate( "ReportGenerator", "All reports were successfully generated in folder <a href='file:///{path}'>{path}</a>!" ).format(path=normalize_local_url(save_into_folder)) self.logger.success_msg(__name__, msg) else: details_msg = '' if polygons_with_holes: details_msg += QCoreApplication.translate( "ReportGenerator", " The following polygons were skipped because they have holes and are not supported: {}." ).format(", ".join(polygons_with_holes)) if total == 1: msg = QCoreApplication.translate( "ReportGenerator", "The report for plot {} couldn't be generated!{} See QGIS log (tab '{}') for details." ).format(plot_id, details_msg, self.LOG_TAB) else: if count == 0: msg = QCoreApplication.translate( "ReportGenerator", "No report could be generated!{} See QGIS log (tab '{}') for details." ).format(details_msg, self.LOG_TAB) else: msg = QCoreApplication.translate( "ReportGenerator", "At least one report couldn't be generated!{details_msg} See QGIS log (tab '{log_tab}') for details. Go to <a href='file:///{path}'>{path}</a> to see the reports that were generated." ).format(details_msg=details_msg, path=normalize_local_url(save_into_folder), log_tab=self.LOG_TAB) self.logger.warning_msg(__name__, msg)