def download_csv_file(self, filename):
        settings = QSettings()
        settings.setValue(
            'Asistente-LADM_COL/wizards/points_csv_file_delimiter',
            self.txt_delimiter.text().strip())

        new_filename, filter = QFileDialog.getSaveFileName(
            self, QCoreApplication.translate("WizardTranslations",
                                             "Save File"),
            os.path.join(
                settings.value(
                    'Asistente-LADM_COL/wizards/points_download_csv_path',
                    '.'), filename),
            QCoreApplication.translate("WizardTranslations",
                                       "CSV File (*.csv *.txt)"))

        if new_filename:
            settings.setValue(
                'Asistente-LADM_COL/wizards/points_download_csv_path',
                os.path.dirname(new_filename))
            template_file = QFile(":/Asistente-LADM_COL/resources/csv/" +
                                  filename)

            if not template_file.exists():
                self.logger.critical(
                    __name__,
                    "CSV doesn't exist! Probably due to a missing 'make' execution to generate resources..."
                )
                msg = QCoreApplication.translate(
                    "WizardTranslations",
                    "CSV file not found. Update your plugin. For details see log."
                )
                self.show_message(msg, Qgis.Warning)
                return

            if os.path.isfile(new_filename):
                self.logger.info(
                    __name__,
                    'Removing existing file {}...'.format(new_filename))
                os.chmod(new_filename, 0o777)
                os.remove(new_filename)

            if template_file.copy(new_filename):
                os.chmod(
                    new_filename,
                    stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
                msg = QCoreApplication.translate(
                    "WizardTranslations",
                    """The file <a href="file:///{}">{}</a> was successfully saved!"""
                ).format(normalize_local_url(new_filename),
                         os.path.basename(new_filename))
                self.show_message(msg, Qgis.Info)
            else:
                self.logger.warning(
                    __name__,
                    'There was an error copying the CSV file {}!'.format(
                        new_filename))
                msg = QCoreApplication.translate(
                    "WizardTranslations", "The file couldn\'t be saved.")
                self.show_message(msg, Qgis.Warning)
    def _save_dependency_file(self, fetcher_task):
        self._downloading = False
        if fetcher_task.reply() is not None:
            try:
                if not os.path.exists(DEPENDENCY_CRYPTO_DIR):
                    os.makedirs(DEPENDENCY_CRYPTO_DIR)

                # Write response to tmp file
                out_file = QFile(CRYPTO_LIBRARY_PATH)
                out_file.open(QIODevice.WriteOnly)
                out_file.write(fetcher_task.reply().readAll())
                out_file.close()

            except PermissionError as e:
                self.logger.warning_msg(
                    __name__,
                    QCoreApplication.translate(
                        "EncrypterDecrypter",
                        "The dependency used to encrypt/decrypt couldn't be installed. Check if it is possible to write into this folder: <a href='file:///{path}'>{path}</a>"
                    ).format(path=normalize_local_url(DEPENDENCY_CRYPTO_DIR)))
            else:
                self.logger.clear_message_bar()
                self.logger.info_msg(
                    __name__,
                    QCoreApplication.translate(
                        "EncrypterDecrypter",
                        "The dependency used to encrypt/decrypt is properly installed!"
                    ))
Example #3
0
    def download_excel_file(self, filename):
        settings = QSettings()

        new_filename, filter = QFileDialog.getSaveFileName(
            self,
            QCoreApplication.translate("ImportFromExcelDialog", "Save File"),
            os.path.join(
                settings.value(
                    'Asistente-LADM-COL/import_from_excel_dialog/template_save_path',
                    '.'), filename),
            QCoreApplication.translate("ImportFromExcelDialog",
                                       "Excel File (*.xlsx *.xls)"))

        if new_filename:
            settings.setValue(
                'Asistente-LADM-COL/import_from_excel_dialog/template_save_path',
                os.path.dirname(new_filename))
            template_file = QFile(":/Asistente-LADM-COL/resources/excel/" +
                                  filename)

            if not template_file.exists():
                self.logger.critical(
                    __name__,
                    "Excel doesn't exist! Probably due to a missing 'make' execution to generate resources..."
                )
                msg = QCoreApplication.translate(
                    "ImportFromExcelDialog",
                    "Excel file not found. Update your plugin. For details see log."
                )
                self.show_message(msg, Qgis.Warning)
                return

            if os.path.isfile(new_filename):
                self.logger.info(
                    __name__,
                    'Removing existing file {}...'.format(new_filename))
                os.chmod(new_filename, 0o777)
                os.remove(new_filename)

            if template_file.copy(new_filename):
                os.chmod(
                    new_filename,
                    stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
                msg = QCoreApplication.translate(
                    "ImportFromExcelDialog",
                    """The file <a href="file:///{}">{}</a> was successfully saved!"""
                ).format(normalize_local_url(new_filename),
                         os.path.basename(new_filename))
                self.show_message(msg, Qgis.Info)
            else:
                self.logger.info(
                    __name__,
                    'There was an error copying the CSV file {}!'.format(
                        new_filename))
                msg = QCoreApplication.translate(
                    "ImportFromExcelDialog", "The file couldn\'t be saved.")
                self.show_message(msg, Qgis.Warning)
Example #4
0
    def validate_qrs(self):
        if self.__qr_engine is None:
            self.__qr_engine = QualityRuleEngine(self.__db,
                                                 self.__selected_qrs,
                                                 self.app.settings.tolerance,
                                                 self.__qr_results_dir_path)
            self.__qr_engine.progress_changed.connect(
                self.total_progress_changed)
        else:
            self.__qr_engine.initialize(self.__db, self.__selected_qrs,
                                        self.app.settings.tolerance,
                                        self.__qr_results_dir_path)
        #self.__qr_engine.qr_logger.show_message_emitted.connect(self.show_log_quality_message)
        #self.__qr_engine.qr_logger.show_button_emitted.connect(self.show_log_quality_button)
        #self.__qr_engine.qr_logger.set_initial_progress_emitted.connect(self.set_log_quality_initial_progress)
        #self.__qr_engine.qr_logger.set_final_progress_emitted.connect(self.set_log_quality_final_progress)

        use_roads = bool(QSettings().value(
            'Asistente-LADM-COL/quality/use_roads', DEFAULT_USE_ROADS_VALUE,
            bool))
        options = {QR_IGACR3006: {'use_roads': use_roads}}

        res, msg, qrs_res = self.__qr_engine.validate_quality_rules(options)
        if not res:
            return res, msg, None

        self.__qrs_results = qrs_res

        self.__connect_layer_willbedeleted_signals(
        )  # Note: Call it after validate_quality_rules!

        res_u, msg_u, output_qr_dir = QualityErrorDBUtils.get_quality_validation_output_path(
            self.__qr_results_dir_path, self.__qr_engine.get_timestamp())

        if len(self.__selected_qrs) == 1:
            pre_text = QCoreApplication.translate(
                "QualityRules", "The quality rule was checked!")
        else:
            pre_text = QCoreApplication.translate(
                "QualityRules",
                "All the {} quality rules were checked!").format(
                    len(self.__selected_qrs))

        post_text = QCoreApplication.translate(
            "QualityRules",
            "Both a PDF report and a GeoPackage database with errors can be found in <a href='file:///{}'>{}</a>."
        ).format(normalize_local_url(output_qr_dir), output_qr_dir)

        self.logger.success_msg(__name__, "{} {}".format(pre_text, post_text))

        self.__emit_refresh_error_layer_symbology()

        return res, msg, self.__qrs_results
Example #5
0
    def export_field_data(self, export_dir):
        names = self._db.names

        # Get list of basket t_ili_tids to export
        receivers_data = self._ladm_data.get_fdc_receivers_data(
            names,
            self.user_layer(),
            self._get_receiver_referenced_field(),
            self.receiver_type,
            full_name=False)
        receiver_idx = self.parcel_layer().fields().indexOf(
            self._get_parcel_field_referencing_receiver())
        receiver_ids = self.parcel_layer().uniqueValues(receiver_idx)
        # Only t_basket of receivers with allocated parcels
        basket_t_ids = [k for k in receivers_data.keys() if k in receiver_ids]
        basket_table = self._ladm_data.get_basket_table(self._db)
        basket_dict = {
            f[names.T_ILI_TID_F]: receivers_data[f[names.T_ID_F]][0]
            for f in basket_table.getFeatures()
            if f[self._db.names.T_ID_F] in basket_t_ids
        }

        if not basket_dict:
            return False, QCoreApplication.translate(
                "FieldDataCaptureAdminController",
                "First allocate parcels to at least one coordinator.")

        # Now set basket id for allocated parcels' related features
        res = self._ladm_data.set_basket_for_features_related_to_allocated_parcels_field_data_capture(
            self._db, self.receiver_type,
            self._get_parcel_field_referencing_receiver(),
            self._get_receiver_referenced_field(), self.parcel_layer(),
            self.plot_layer(), self.user_layer())

        # Finally, export each basket to XTF
        basket_exporter = BasketExporter(self._db, basket_dict, export_dir)
        basket_exporter.total_progress_updated.connect(
            self.export_field_data_progress)  # Signal chaining
        all_res = basket_exporter.export_baskets()

        for basket, res in all_res.items():
            if not res[0]:  # res: (bool, msg)
                return res

        return True, QCoreApplication.translate(
            "FieldDataCaptureAdminController",
            "{count} XTFs were succcessfully generated in <a href='file:///{normalized_path}'>{path}</a>!"
        ).format(count=len(basket_dict),
                 normalized_path=normalize_local_url(export_dir),
                 path=export_dir)
Example #6
0
    def _save_dependency_file(self, fetcher_task):
        if fetcher_task.reply() is not None:
            # Write response to tmp file
            tmp_file = tempfile.mktemp()
            out_file = QFile(tmp_file)
            out_file.open(QIODevice.WriteOnly)
            out_file.write(fetcher_task.reply().readAll())
            out_file.close()

            if not os.path.exists(DEPENDENCIES_BASE_PATH):
                os.makedirs(DEPENDENCIES_BASE_PATH)

            if md5sum(tmp_file) == DICT_JAVA_MD5SUM[KEY_JAVA_OS_VERSION]:

                try:
                    tar = tarfile.open(tmp_file)
                    tar.extractall(DEPENDENCIES_BASE_PATH)
                    tar.close()
                except tarfile.ReadError as e:
                    self.logger.warning_msg(
                        __name__,
                        QCoreApplication.translate(
                            "JavaDependency",
                            "There was an error with the download. The downloaded file is invalid."
                        ))
                except PermissionError as e:
                    self.logger.warning_msg(
                        __name__,
                        QCoreApplication.translate(
                            "JavaDependency",
                            "Java couldn't be installed. Check if it is possible to write into this folder: <a href='file:///{path}'>{path}</a>"
                        ).format(path=normalize_local_url(
                            os.path.join(
                                DEPENDENCIES_BASE_PATH,
                                DICT_JAVA_DIR_NAME[KEY_JAVA_OS_VERSION]))))

            else:
                self.logger.warning_msg(
                    __name__,
                    QCoreApplication.translate(
                        "JavaDependency",
                        "There was an error with the download. The downloaded file is invalid."
                    ))
            try:
                os.remove(tmp_file)
            except:
                pass

        self._downloading = False
    def save_dependency_file(self, fetcher_task):
        if fetcher_task.reply() is not None:
            # Write response to tmp file
            tmp_file = tempfile.mktemp()
            out_file = QFile(tmp_file)
            out_file.open(QIODevice.WriteOnly)
            out_file.write(fetcher_task.reply().readAll())
            out_file.close()

            if not os.path.exists(DEPENDENCIES_BASE_PATH):
                os.makedirs(DEPENDENCIES_BASE_PATH)

            try:
                with zipfile.ZipFile(tmp_file, "r") as zip_ref:
                    zip_ref.extractall(DEPENDENCIES_BASE_PATH)
            except zipfile.BadZipFile as e:
                self.logger.warning_msg(
                    __name__,
                    QCoreApplication.translate(
                        "ReportGenerator",
                        "There was an error with the download. The downloaded file is invalid."
                    ))
            except PermissionError as e:
                self.logger.warning_msg(
                    __name__,
                    QCoreApplication.translate(
                        "ReportGenerator",
                        "Dependencies to generate reports couldn't be installed. Check if it is possible to write into this folder: <a href='file:///{path}'>{path}</a>"
                    ).format(path=normalize_local_url(
                        os.path.join(DEPENDENCIES_BASE_PATH),
                        DEPENDENCY_REPORTS_DIR_NAME)))
            else:
                self.logger.info_msg(
                    __name__,
                    QCoreApplication.translate(
                        "ReportGenerator",
                        "The dependency to generate reports is properly installed! Select plots and click again the button in the toolbar to generate reports."
                    ))

            try:
                os.remove(tmp_file)
            except:
                pass

        self._downloading = False
Example #8
0
    def remove_dependency_directory(dir_name_dependency):
        """
        We need to get rid of dependencies when they don't match the version
        that should be installed for this version of the plugin.
        """
        base_path = os.path.join(DEPENDENCIES_BASE_PATH, dir_name_dependency)

        # Since folders might contain read only files, we need to delete them
        # using a callback (see https://docs.python.org/3/library/shutil.html#rmtree-example)
        shutil.rmtree(base_path, onerror=remove_readonly)
        Logger().clear_message_bar()

        if os.path.exists(base_path):
            Logger().warning_msg(
                __name__,
                QCoreApplication.translate(
                    "Utils",
                    "It wasn't possible to remove the dependency folder. You need to remove this folder yourself to generate reports: <a href='file:///{path}'>{path}</a>"
                ).format(path=normalize_local_url(base_path)))
    def load_lis_files(self, alphanumeric_file_paths):
        root = QgsProject.instance().layerTreeRoot()
        alphanumeric_group = root.addGroup(
            QCoreApplication.translate("MissingSuppliesBaseDialog",
                                       "LIS Supplies"))

        for name in alphanumeric_file_paths:
            uri = 'file:///{}?type=csv&delimiter=;&detectTypes=yes&geomType=none&subsetIndex=no&watchFile=no'.format(
                normalize_local_url(alphanumeric_file_paths[name]))
            layer = QgsVectorLayer(uri, name, 'delimitedtext')
            if layer.isValid():
                self.alphanumeric_file_paths[name] = layer
                QgsProject.instance().addMapLayer(layer, False)
                alphanumeric_group.addLayer(layer)
            else:
                return False, QCoreApplication.translate(
                    "MissingSuppliesBaseDialog",
                    "There were troubles loading the LIS file called '{}'.".
                    format(name))

        return True, ''
Example #10
0
    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)
Example #11
0
    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 = []
        multi_polygons = []

        for selected_plot in selected_plots:
            plot_id = selected_plot[db.names.T_ID_F]

            geometry = selected_plot.geometry()
            abstract_geometry = geometry.get()
            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
            if abstract_geometry.numGeometries() > 1:
                multi_polygons.append(str(plot_id))
                self.logger.warning(
                    __name__,
                    QCoreApplication.translate(
                        "ReportGenerator",
                        "Skipping Annex 17 for plot with {}={} because it is a multi-polygon. 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 ['']
            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
                progress.setValue(step * 100 / total)

        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 multi_polygons:
                details_msg += QCoreApplication.translate(
                    "ReportGenerator",
                    " The following polygons were skipped because they are multi-polygons and are not supported: {}."
                ).format(", ".join(multi_polygons))

            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)
Example #12
0
    def load_alphanumeric_layers(self):
        self.alphanumeric_file_paths = {
            'blo': self.data_source_widget.txt_file_path_blo.text().strip(),
            'uni': self.data_source_widget.txt_file_path_uni.text().strip(),
            'ter': self.data_source_widget.txt_file_path_ter.text().strip(),
            'pro': self.data_source_widget.txt_file_path_pro.text().strip()
        }

        root = QgsProject.instance().layerTreeRoot()
        lis_group = root.addGroup(QCoreApplication.translate(self.CLASS_NAME, "LIS Supplies"))

        for name in self.alphanumeric_file_paths:
            uri = 'file:///{}?encoding=latin1&type=csv&delimiter=;&quote=&escape=&detectTypes=yes&geomType=none&subsetIndex=no&watchFile=no'.format(normalize_local_url(self.alphanumeric_file_paths[name]))
            layer = QgsVectorLayer(uri, name, 'delimitedtext')
            if layer.isValid():
                self.alphanumeric_file_paths[name] = layer
                QgsProject.instance().addMapLayer(layer, False)
                lis_group.addLayer(layer)
            else:
                if name == 'blo':
                    # BLO is kind of optional, if it is not given, we pass a default one
                    uri = 'file:///{}?encoding=latin1&type=csv&delimiter=;&quote=&escape=&detectTypes=yes&geomType=none&subsetIndex=no&watchFile=no'.format(normalize_local_url(BLO_LIS_FILE_PATH))
                    layer = QgsVectorLayer(uri, name, 'delimitedtext')
                    self.alphanumeric_file_paths[name] = layer
                    QgsProject.instance().addMapLayer(layer, False)
                    lis_group.addLayer(layer)
                else:
                    return False, QCoreApplication.translate(self.CLASS_NAME, "There were troubles loading the LIS file called '{}'.".format(name))

        return True, ''
Example #13
0
    def convert_to_offline(self, db, surveyor_expression_dict, export_dir):
        sys.path.append(PLUGINS_DIR)
        from qfieldsync.core.layer import LayerSource, SyncAction
        from qfieldsync.core.offline_converter import OfflineConverter
        from qfieldsync.core.project import ProjectConfiguration

        project = QgsProject.instance()
        extent = QgsRectangle()
        offline_editing = QgsOfflineEditing()

        # Configure project
        project_configuration = ProjectConfiguration(project)
        project_configuration.create_base_map = False
        project_configuration.offline_copy_only_aoi = False
        project_configuration.use_layer_selection = True

        # Layer config
        layer_sync_action = LayerConfig.get_field_data_capture_layer_config(
            db.names)

        total_projects = len(surveyor_expression_dict)
        current_progress = 0

        for surveyor, layer_config in surveyor_expression_dict.items():
            export_folder = os.path.join(export_dir, surveyor)

            # Get layers (cannot be done out of this for loop because the project is closed and layers are deleted)
            layers = {
                layer_name: None
                for layer_name, _ in layer_sync_action.items()
            }
            self.app.core.get_layers(db, layers, True)
            if not layers:
                return False, QCoreApplication.translate(
                    "FieldDataCapture",
                    "At least one layer could not be found.")

            # Configure layers
            for layer_name, layer in layers.items():
                layer_source = LayerSource(layer)
                layer_source.action = layer_sync_action[layer_name]
                if layer_name in layer_config:
                    layer_source.select_expression = layer_config[layer_name]
                layer_source.apply()

            offline_converter = OfflineConverter(project, export_folder,
                                                 extent, offline_editing)
            offline_converter.convert()
            offline_editing.layerProgressUpdated.disconnect(
                offline_converter.on_offline_editing_next_layer)
            offline_editing.progressModeSet.disconnect(
                offline_converter.on_offline_editing_max_changed)
            offline_editing.progressUpdated.disconnect(
                offline_converter.offline_editing_task_progress)

            current_progress += 1
            self.total_progress_updated.emit(
                int(100 * current_progress / total_projects))

        return True, QCoreApplication.translate(
            "FieldDataCapture",
            "{count} offline projects have been successfully created in <a href='file:///{normalized_path}'>{path}</a>!"
        ).format(count=total_projects,
                 normalized_path=normalize_local_url(export_dir),
                 path=export_dir)