From da67acf7c50dbd16d7a03752bfce01ffac94b0b0 Mon Sep 17 00:00:00 2001 From: wvangerwen <41104904+wvangerwen@users.noreply.github.com> Date: Thu, 9 Nov 2023 13:09:24 +0100 Subject: [PATCH] black 119 linelength and ruff organize imports (#146) * black 119char per line and ruff organize imports * close dockwidget and set none to fix #81 Will this work properly? Chris added comments that setting dockwidget to None resulted in QGIS crashing. Needs testing. * add docstring * Update environment_services.yml * Update hhnk_toolbox.py --- hhnk_threedi_plugin/__init__.py | 17 +- hhnk_threedi_plugin/dependencies.py | 127 ++++------- .../env/environment_services.yml | 12 +- .../error_messages/input_error_messages.py | 25 +-- hhnk_threedi_plugin/gui/checks/bank_levels.py | 50 ++--- .../proposed_changes_dialog.py | 34 +-- .../proposed_changes_exceptions.py | 3 +- .../proposed_changes_tabs.py | 52 ++--- hhnk_threedi_plugin/gui/checks/one_d_two_d.py | 33 +-- .../gui/checks/sqlite_check_popup.py | 64 +++--- .../controlled_structs_result.py | 5 +- .../cross_section_vertex_result.py | 5 +- .../cross_section_warning_result.py | 5 +- .../sqlite_test_widgets/dem_max_val_result.py | 3 +- .../sqlite_test_widgets/dewatering_result.py | 5 +- .../general_checks_result.py | 8 +- .../sqlite_test_widgets/geometries_result.py | 8 +- .../impervious_surface_result.py | 6 +- .../isolated_channels_result.py | 5 +- .../sqlite_test_widgets/main_result_widget.py | 8 +- .../profiles_used_result.py | 5 +- .../structs_channels_result.py | 5 +- .../watersurface_area_result.py | 5 +- .../sqlite_test_widgets/weir_height_result.py | 37 ++-- .../gui/checks/zero_d_one_d.py | 39 ++-- hhnk_threedi_plugin/gui/general_objects.py | 41 ++-- hhnk_threedi_plugin/gui/input_data.py | 135 +++++++----- .../gui/klimaatsommen/klimaatsommen.py | 69 +++--- hhnk_threedi_plugin/gui/load_layers_popup.py | 107 ++++----- .../model_splitter/model_splitter_dialog.py | 163 +++++++------- hhnk_threedi_plugin/gui/modelbuilder.py | 41 ++-- hhnk_threedi_plugin/gui/new_project_dialog.py | 204 ++++++++--------- ...schematisation_splitter_uploader_dialog.py | 58 +++-- .../gui/sql_preview/model_changes_preview.py | 51 ++--- .../threedi/confirm_rain_scenario_loaded.py | 8 +- .../gui/utility/file_widget.py | 21 +- .../gui/utility/widget_interaction.py | 4 +- hhnk_threedi_plugin/hhnk_toolbox.py | 174 +++++++-------- .../hhnk_toolbox_dockwidget.py | 5 +- hhnk_threedi_plugin/local_settings_default.py | 10 +- hhnk_threedi_plugin/patches/downloader.py | 169 +++++--------- .../qgis_interaction/klimaatsommen_pdfs.py | 26 +-- .../load_layers_interaction.py | 55 ++--- .../qgis_interaction/open_notebook.py | 84 +++---- .../qgis_interaction/project.py | 63 +++--- .../remove_layers_interaction.py | 5 +- hhnk_threedi_plugin/resources.py | 5 +- hhnk_threedi_plugin/tasks/__init__.py | 2 +- .../tasks/execute_model_changes.py | 16 +- .../tasks/load_3di_results_tasks.py | 28 +-- .../base_sqlite_test_task.py | 28 +-- .../sqlite_test_tasks/sqlite_test_tasks.py | 143 ++++++------ hhnk_threedi_plugin/tasks/task_bank_levels.py | 67 +++--- .../tasks/task_check_schematisation.py | 10 +- .../tasks/task_generate_grid.py | 7 +- hhnk_threedi_plugin/tasks/task_one_d_two_d.py | 70 +++--- .../tasks/task_sqlite_tests_main.py | 116 +++++----- .../tasks/task_zero_d_one_d.py | 54 ++--- hhnk_threedi_plugin/tests/Modelsplitter_QT.py | 207 +++++++++--------- hhnk_threedi_plugin/tests/dummy.py | 11 +- hhnk_threedi_plugin/tests/test_scale.py | 2 +- hhnk_threedi_plugin/tests/test_ui.py | 18 +- 62 files changed, 1306 insertions(+), 1537 deletions(-) diff --git a/hhnk_threedi_plugin/__init__.py b/hhnk_threedi_plugin/__init__.py index b1696fb9..b629f5bb 100644 --- a/hhnk_threedi_plugin/__init__.py +++ b/hhnk_threedi_plugin/__init__.py @@ -23,21 +23,23 @@ This script initializes the plugin, making it known to QGIS. """ from .dependencies import ensure_dependencies + ensure_dependencies() # #TODO import sys -#import os -sys.path.append('.') -# research tools installatie uit osgeo weghalen. Sys path append hier van de github repo. +# import os + +sys.path.append(".") +# research tools installatie uit osgeo weghalen. Sys path append hier van de github repo. try: import hhnk_threedi_plugin.local_settings as local_settings except ModuleNotFoundError: import hhnk_threedi_plugin.local_settings_default as local_settings - + # if local_settings.DEBUG: -# try: +# try: # if local_settings.hhnk_research_tools_path not in sys.path: # sys.path.insert(0, local_settings.hhnk_research_tools_path) @@ -60,8 +62,8 @@ # import hhnk_threedi_tools +# sys.path.append(local_settings.threeditoolbox_path) - #sys.path.append(local_settings.threeditoolbox_path) # noinspection PyPep8Naming def classFactory(iface): # pylint: disable=invalid-name @@ -73,6 +75,3 @@ def classFactory(iface): # pylint: disable=invalid-name from .hhnk_toolbox import HHNK_toolbox return HHNK_toolbox(iface) - - - diff --git a/hhnk_threedi_plugin/dependencies.py b/hhnk_threedi_plugin/dependencies.py index 8cecac0a..9480a9a5 100644 --- a/hhnk_threedi_plugin/dependencies.py +++ b/hhnk_threedi_plugin/dependencies.py @@ -22,26 +22,22 @@ https://github.com/nens/ThreeDiToolbox/blob/master/dependencies.py """ -import os -import sys -import pkg_resources +import importlib import logging -import subprocess -from pathlib import Path +import os import platform -import importlib +import shutil +import subprocess +import sys from collections import namedtuple -import yaml -from typing import List +from pathlib import Path from platform import python_version -import shutil +from typing import List +import pkg_resources +import yaml from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QProgressDialog -from PyQt5.QtWidgets import QProgressBar -from PyQt5.QtWidgets import QApplication -from PyQt5.QtWidgets import QMessageBox - +from PyQt5.QtWidgets import QApplication, QMessageBox, QProgressBar, QProgressDialog CREATE_NO_WINDOW = 0x08000000 DETACHED_PROCESS = 0x00000008 @@ -61,9 +57,9 @@ LOG_DIR.mkdir(parents=True, exist_ok=True) PATCH_DIR = HHNK_THREEDI_PLUGIN_DIR / "patches" -PATCHES = {"downloader.py":DEPENDENCY_DIR/r"threedi_scenario_downloader/downloader.py"} +PATCHES = {"downloader.py": DEPENDENCY_DIR / r"threedi_scenario_downloader/downloader.py"} -USERDEPS = ["jupyterlab", "ipywidgets"] #Dependencies in userfolder %appdata%/python/ +USERDEPS = ["jupyterlab", "ipywidgets"] # Dependencies in userfolder %appdata%/python/ Dependency = namedtuple("Dependency", ["package", "version"]) @@ -83,7 +79,7 @@ Verwijder deze packages, of update de environment.yml om deze melding te laten verdwijnen.
En test de plugin voor deze omgeving wanneer je de environment.yml update(!) -""" # noqa: E501 +""" # noqa: E501 """ Helper functions for QGIS QProgressDialog and QMessageBox """ @@ -130,9 +126,7 @@ def _is_windows(): def _is_qgis(): - return any( - (i in _get_python_interpreter().lower() for i in ["qgis", "3di"]) - ) + return any((i in _get_python_interpreter().lower() for i in ["qgis", "3di"])) def _create_progress_dialog(missing_dependencies, qgis=_is_qgis()): @@ -175,18 +169,14 @@ def _update_bar(bar, count, total, qgis=_is_qgis()): QApplication.processEvents() -def _raise_inconsistency_warning( - correct_python_version, inconsistent_dependencies, qgis=_is_qgis() -): - """Raise an inconsistency warning if environment is not compatible with yml.""" # noqa: E501s +def _raise_inconsistency_warning(correct_python_version, inconsistent_dependencies, qgis=_is_qgis()): + """Raise an inconsistency warning if environment is not compatible with yml.""" # noqa: E501s msg = "" if not correct_python_version: msg = f"- python=={python_version()}
" - msg += "
".join( - [f"- {i.package}=={i.version} ({_package_location(i)})" for i in inconsistent_dependencies] - ) + msg += "
".join([f"- {i.package}=={i.version} ({_package_location(i)})" for i in inconsistent_dependencies]) if msg: msg = inconsist_deps_message.format(msg=msg) @@ -201,6 +191,7 @@ def _raise_inconsistency_warning( msg_box.setFixedWidth(1000) msg_box.exec_() + def _raise_restart_warning(qgis=_is_qgis()): """Raise restart warning after installation.""" if qgis: @@ -213,9 +204,7 @@ def _raise_restart_warning(qgis=_is_qgis()): def _add_logger_file_handler(log_file=LOG_DIR / "ensure_dependencies.log"): """Add a logger file_handler.""" fh = logging.FileHandler(log_file) - fh.setFormatter( - logging.Formatter("%(asctime)s %(name)s %(levelname)s - %(message)s") - ) + fh.setFormatter(logging.Formatter("%(asctime)s %(name)s %(levelname)s - %(message)s")) fh.setLevel(logging.DEBUG) logger.addHandler(fh) return fh @@ -284,10 +273,10 @@ def _update_path(directories): sys.path.append(str(dir_path)) logger.info(f"{dir_path} added to sys.path") else: - logger.warning( - f"{dir_path} does not exist and is not added to sys.path" - ) -#%% + logger.warning(f"{dir_path} does not exist and is not added to sys.path") + + +# %% def _package_location(dependency): try: pkg = pkg_resources.get_distribution(dependency.package) @@ -295,7 +284,10 @@ def _package_location(dependency): return f"{location.as_posix()}" except pkg_resources.DistributionNotFound: pass -#%% + + +# %% + def _evaluate_environment(yml_path: Path = YML_PATH): """ @@ -329,17 +321,11 @@ def _evaluate_environment(yml_path: Path = YML_PATH): pkg = pkg_resources.get_distribution(dependency.package) if dependency.version is not None: if pkg.version != dependency.version: - inconsistent_dependencies.append( - Dependency(dependency.package, pkg.version) - ) + inconsistent_dependencies.append(Dependency(dependency.package, pkg.version)) except pkg_resources.DistributionNotFound: missing_dependencies.append(dependency) - return ( - correct_python_version, - inconsistent_dependencies, - missing_dependencies - ) + return (correct_python_version, inconsistent_dependencies, missing_dependencies) """ Installation of patches. Note (!) try to avoid patches!""" @@ -407,9 +393,7 @@ def download_wheels(dependencies, directory=WHEEL_DIR, clean_dir=True): output, error = process.communicate() exit_code = process.wait() if exit_code: - logger.error( - f"Downloading {dependency.package} failed with: {error} {output}" # noqa: E501 - ) + logger.error(f"Downloading {dependency.package} failed with: {error} {output}") # noqa: E501 """ Helper functions to install missing dependencies. """ @@ -418,8 +402,8 @@ def download_wheels(dependencies, directory=WHEEL_DIR, clean_dir=True): def _refresh_python_import_mechanism(): """Refresh the import mechanism. This is required when deps are dynamically installed/removed. The modules - 'importlib' and 'pkg_resources' need to update their internal data structures. - """ # noqa: E501 + 'importlib' and 'pkg_resources' need to update their internal data structures. + """ # noqa: E501 # This function should be called if any modules are created/installed while your # noqa: E501 # program is running to guarantee all finders will notice the new module’s existence. # noqa: E501 importlib.invalidate_caches() @@ -429,12 +413,7 @@ def _refresh_python_import_mechanism(): importlib.reload(pkg_resources) -def _install_dependency( - dependency: Dependency, - dialog=None, - startupinfo=None, - fh=None - ): +def _install_dependency(dependency: Dependency, dialog=None, startupinfo=None, fh=None): """Install a dependency with pip""" command = [ @@ -499,7 +478,7 @@ def _install_dependency( Python-exception na import: {e} - """ # noqa: E501 + """ # noqa: E501 logger.error(msg) @@ -513,14 +492,7 @@ def _install_dependency( def _uninstall_dependency(dependency, startupinfo=None): """Uninstall a dependency with pip""" - command = [ - _get_python_interpreter(), - "-m", - "pip", - "uninstall", - "--yes", - (dependency.package) - ] + command = [_get_python_interpreter(), "-m", "pip", "uninstall", "--yes", (dependency.package)] process = subprocess.Popen( command, universal_newlines=True, @@ -573,15 +545,13 @@ def ensure_dependencies( dir Defaults to DEPENDENCY_DIR. yml_path (Path, optional): Path to environment.yml Defaults to YML_PATH. - """ # noqa: E501 + """ # noqa: E501 # add log-file fh = _add_logger_file_handler() logger.info("start: ensuring dependencies") - logger.info( - f"python-interpreter {_get_python_interpreter()} is QGIS: {_is_qgis()}" - ) + logger.info(f"python-interpreter {_get_python_interpreter()} is QGIS: {_is_qgis()}") # make sure all currently installed modules are patched if necessary _install_patches() @@ -604,37 +574,26 @@ def ensure_dependencies( # try uninstalling inconsistent dependencies inconsistent_dependencies, missing_dependencies = _clean_inconsistent_dependencies( - inconsistent_dependencies, - missing_dependencies - ) + inconsistent_dependencies, missing_dependencies + ) # raise an inconsistency warning if environment is not consistent with tested plugin environment # noqa: E501 if (not correct_python_version) or (inconsistent_dependencies): - _raise_inconsistency_warning( - correct_python_version, - inconsistent_dependencies - ) + _raise_inconsistency_warning(correct_python_version, inconsistent_dependencies) if missing_dependencies: - logger.info( - f"missing dependencies: {' '.join([i.package for i in missing_dependencies])}" # noqa: E501 - ) + logger.info(f"missing dependencies: {' '.join([i.package for i in missing_dependencies])}") # noqa: E501 # create a QGIS progress dialog (if Windows) - dialog, bar, startupinfo = _create_progress_dialog( - missing_dependencies - ) + dialog, bar, startupinfo = _create_progress_dialog(missing_dependencies) # loop trough missing dependencies for count, dependency in enumerate(missing_dependencies): - # update dialog label _update_dialog(dialog, dependency) # install dependency logger.info(f"installing: {dependency.package}") - _install_dependency( - dependency, startupinfo=startupinfo, dialog=dialog, fh=fh - ) + _install_dependency(dependency, startupinfo=startupinfo, dialog=dialog, fh=fh) # update progress bar _update_bar(bar, count, len(missing_dependencies)) diff --git a/hhnk_threedi_plugin/env/environment_services.yml b/hhnk_threedi_plugin/env/environment_services.yml index 4c0b0204..4cc9ea86 100644 --- a/hhnk_threedi_plugin/env/environment_services.yml +++ b/hhnk_threedi_plugin/env/environment_services.yml @@ -1,4 +1,14 @@ -# This is an environment for conda environment on ota155 and ota514 +# """This is an environment for conda environment on ota155 and ota514 +# Can be used as standalone env where the following utils should work: +# - hhnk-threedi-tools +# - hhnk-research-tools +# - datachecker +# - modelbuilder +# +# threedi and research-tools should be installed manually to use the +# latest dev version. Do this by pulling the github branch and running +# bin/install_local.bat in those branches. +# """ name: threedipy channels: diff --git a/hhnk_threedi_plugin/error_messages/input_error_messages.py b/hhnk_threedi_plugin/error_messages/input_error_messages.py index 92ce094e..ce03f6cd 100644 --- a/hhnk_threedi_plugin/error_messages/input_error_messages.py +++ b/hhnk_threedi_plugin/error_messages/input_error_messages.py @@ -12,31 +12,18 @@ # Sqlite tests # ------------------------------------------------------------------------------------------- dem_needed = invalid_dem_path + " (nodig voor {} test)" -datachecker_needed = ( - "Ongeldig pad naar datachecker geodatabase gespecificeerd " "(nodig voor {} test)" -) -invalid_shapefile = ( - "Gegeven shapefile is ongeldig (pad bestaat niet of .shx, .dbf, " - ".prj bestanden ontbreken)" -) -channel_shape_needed_watersurface = ( - invalid_shapefile + "\n" + "Nodig voor oppervlaktewater test" -) -hdb_needed_controlled_structs = ( - "Ongeldig pad gespecificeerd voor HDB {}, " "nodig voor gestuurde kunstwerken test" -) +datachecker_needed = "Ongeldig pad naar datachecker geodatabase gespecificeerd " "(nodig voor {} test)" +invalid_shapefile = "Gegeven shapefile is ongeldig (pad bestaat niet of .shx, .dbf, " ".prj bestanden ontbreken)" +channel_shape_needed_watersurface = invalid_shapefile + "\n" + "Nodig voor oppervlaktewater test" +hdb_needed_controlled_structs = "Ongeldig pad gespecificeerd voor HDB {}, " "nodig voor gestuurde kunstwerken test" damo_needed = "Ongeldig pad gespecificeerd voor DAMO {}, " "nodig voor {} test" -polder_shapefile_needed_imp_surface = ( - invalid_shapefile + "\n" + "Nodig voor ondoorlatend oppervlak test" -) +polder_shapefile_needed_imp_surface = invalid_shapefile + "\n" + "Nodig voor ondoorlatend oppervlak test" no_tests_selected = "Geen tests geselecteerd om uit te voeren" # ------------------------------------------------------------------------------------------- # Model state conversion # ------------------------------------------------------------------------------------------- -from_and_to_states_same = ( - "Begin staat en gekozen nieuwe staat kunnen niet hetzelfde zijn" -) +from_and_to_states_same = "Begin staat en gekozen nieuwe staat kunnen niet hetzelfde zijn" # ------------------------------------------------------------------------------------------- # Create new project diff --git a/hhnk_threedi_plugin/gui/checks/bank_levels.py b/hhnk_threedi_plugin/gui/checks/bank_levels.py index 10d8f208..99b2f3b1 100644 --- a/hhnk_threedi_plugin/gui/checks/bank_levels.py +++ b/hhnk_threedi_plugin/gui/checks/bank_levels.py @@ -1,23 +1,24 @@ import os +from pathlib import Path + +import hhnk_threedi_tools as htt +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import ( - QPushButton, QFileDialog, QLabel, - QVBoxLayout, + QPushButton, QSizePolicy, - QWidget, QSpacerItem, + QVBoxLayout, + QWidget, ) -from PyQt5.QtCore import Qt, pyqtSignal -from qgis.core import QgsApplication -from pathlib import Path -from qgis.core import Qgis -from hhnk_threedi_plugin.gui.utility.file_widget import fileWidget - +from qgis.core import Qgis, QgsApplication -from hhnk_threedi_plugin.gui.checks.bank_levels_widgets.proposed_changes_dialog import modelChangesDialog import hhnk_threedi_plugin.tasks.task_bank_levels as task_bank_levels -import hhnk_threedi_tools as htt +from hhnk_threedi_plugin.gui.checks.bank_levels_widgets.proposed_changes_dialog import ( + modelChangesDialog, +) +from hhnk_threedi_plugin.gui.utility.file_widget import fileWidget from hhnk_threedi_plugin.gui.utility.widget_interaction import update_button_background @@ -57,23 +58,18 @@ def __init__(self, caller, parent=None): self.caller = caller self.parent = parent self.results_widget = None - self.tasks=[] + self.tasks = [] # ---------------------------------------------------------- # Signals # ---------------------------------------------------------- self.start_bank_levels_btn.clicked.connect(self.bank_level_test_execution) - def bank_level_test_execution(self): update_button_background(button=self.start_bank_levels_btn, color="orange") - model_path=self.caller.input_data_dialog.model_selector.filePath() + model_path = self.caller.input_data_dialog.model_selector.filePath() try: - if ( - self.results_widget is not None - and self.results_widget - and self.results_widget.isVisible() - ): + if self.results_widget is not None and self.results_widget and self.results_widget.isVisible(): self.results_widget.close() self.run_bank_levels_test(model_path=model_path) @@ -83,8 +79,7 @@ def bank_level_test_execution(self): update_button_background(button=self.start_bank_levels_btn, color="red") pass - - #Functionality controller + # Functionality controller def handle_model_changes_task(self, task, model_path): task_manager = QgsApplication.taskManager() task.taskCompleted.connect(self.results_widget.handle_execution_result_success) @@ -93,8 +88,7 @@ def handle_model_changes_task(self, task, model_path): self.tasks.append(task) task_manager.addTask(task) - - #Functionality controller + # Functionality controller def run_bank_levels_test(self, model_path): """ Fuctions runs all bank levels test: @@ -113,18 +107,20 @@ def run_bank_levels_test(self, model_path): Creates a task that runs on separate thread for each test """ - try: + try: self.results_widget = modelChangesDialog( model_path=model_path, parent=self.parent, - to_state="0d1d_test", #zero_d_one_d_name - one_d_two_d_source="1d2d uit berekening", #one_d_two_d_from_calc + to_state="0d1d_test", # zero_d_one_d_name + one_d_two_d_source="1d2d uit berekening", # one_d_two_d_from_calc ) self.results_widget.query_execution_task_created.connect( lambda task: self.handle_model_changes_task(task, model_path) ) task_manager = QgsApplication.taskManager() - task = task_bank_levels.get_bank_levels_manholes_task(results_widget=self.results_widget, folder=self.caller.folder) + task = task_bank_levels.get_bank_levels_manholes_task( + results_widget=self.results_widget, folder=self.caller.folder + ) task.taskCompleted.connect(self.results_widget.has_changes) task.taskCompleted.connect(self.results_widget.show) self.tasks.append(task) diff --git a/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_dialog.py b/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_dialog.py index b5c2c63d..5ae2abf9 100644 --- a/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_dialog.py +++ b/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_dialog.py @@ -1,16 +1,23 @@ -from PyQt5.QtWidgets import QDialog, QVBoxLayout, QPushButton, QLabel, QTextEdit -from PyQt5.QtCore import pyqtSignal -from qgis.utils import QgsMessageBar, Qgis -from hhnk_threedi_plugin.gui.checks.bank_levels_widgets.proposed_changes_tabs import modelChangesTabs -from hhnk_threedi_plugin.gui.checks.bank_levels_widgets.proposed_changes_exceptions import exceptionsWidget -from hhnk_threedi_plugin.tasks.execute_model_changes import executeModelChangesTask +from hhnk_threedi_tools.core.schematisation.model_backup import ( + update_bank_levels_last_calc, +) # hhnk-threedi-tests from hhnk_threedi_tools.variables.model_state import ( one_d_two_d_from_calc, one_d_two_d_state, ) -from hhnk_threedi_tools.core.schematisation.model_backup import update_bank_levels_last_calc +from PyQt5.QtCore import pyqtSignal +from PyQt5.QtWidgets import QDialog, QLabel, QPushButton, QTextEdit, QVBoxLayout +from qgis.utils import Qgis, QgsMessageBar + +from hhnk_threedi_plugin.gui.checks.bank_levels_widgets.proposed_changes_exceptions import ( + exceptionsWidget, +) +from hhnk_threedi_plugin.gui.checks.bank_levels_widgets.proposed_changes_tabs import ( + modelChangesTabs, +) +from hhnk_threedi_plugin.tasks.execute_model_changes import executeModelChangesTask class modelChangesDialog(QDialog): @@ -40,10 +47,7 @@ def update_bank_levels_calculated(self): """ Updates timestamp when bank levels were last calculated """ - if ( - self.to_state == one_d_two_d_state - and self.one_d_two_d_source == one_d_two_d_from_calc - ): + if self.to_state == one_d_two_d_state and self.one_d_two_d_source == one_d_two_d_from_calc: update_bank_levels_last_calc(db=self.model_path) def handle_execution_result_success(self): @@ -87,13 +91,9 @@ def submit_done(self): queries = self.tabs.collect_queries() try: if self.model_path is None: - raise Exception( - "No database has been specified (modelChangesDialog.model_path not set)" - ) + raise Exception("No database has been specified (modelChangesDialog.model_path not set)") if queries: - model_changes_task = executeModelChangesTask( - model_path=self.model_path, query=queries - ) + model_changes_task = executeModelChangesTask(model_path=self.model_path, query=queries) self.query_execution_task_created.emit(model_changes_task) else: self.handle_execution_result_success() diff --git a/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_exceptions.py b/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_exceptions.py index 2e27144e..188a614f 100644 --- a/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_exceptions.py +++ b/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_exceptions.py @@ -1,4 +1,5 @@ -from PyQt5.QtWidgets import QWidget, QVBoxLayout +from PyQt5.QtWidgets import QVBoxLayout, QWidget + from hhnk_threedi_plugin.gui.general_objects import create_formatted_text_edit diff --git a/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_tabs.py b/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_tabs.py index 4088635d..6bb7dee5 100644 --- a/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_tabs.py +++ b/hhnk_threedi_plugin/gui/checks/bank_levels_widgets/proposed_changes_tabs.py @@ -1,12 +1,10 @@ -from PyQt5.QtWidgets import QTabWidget -from PyQt5.QtCore import pyqtSignal - - -from hhnk_threedi_tools.core.checks.model_state import get_all_update_queries from hhnk_threedi_tools.core.checks.model_state import ( collect_excluded, collect_manual_adjustments, + get_all_update_queries, ) +from PyQt5.QtCore import pyqtSignal +from PyQt5.QtWidgets import QTabWidget class modelChangesTabs(QTabWidget): @@ -31,13 +29,9 @@ def collect_queries(self): arguments = {} if self.global_settings is not None: arguments["global_settings_df"] = self.global_settings.df - arguments[ - "global_settings_excluded" - ] = self.global_settings.protected_ids_list + arguments["global_settings_excluded"] = self.global_settings.protected_ids_list arguments["global_settings_to_add"] = self.global_settings.add_rows_ids - arguments[ - "global_settings_to_delete" - ] = self.global_settings.delete_rows_ids + arguments["global_settings_to_delete"] = self.global_settings.delete_rows_ids if self.bank_levels is not None: arguments["bank_levels_df"] = self.bank_levels.df arguments["bank_levels_excluded"] = self.bank_levels.protected_ids_list @@ -46,9 +40,7 @@ def collect_queries(self): arguments["new_manholes_excluded"] = self.new_manholes.protected_ids_list if self.update_manholes is not None: arguments["update_manholes_df"] = self.update_manholes.df - arguments[ - "update_manholes_excluded" - ] = self.update_manholes.protected_ids_list + arguments["update_manholes_excluded"] = self.update_manholes.protected_ids_list if self.weirs is not None: arguments["weir_width_df"] = self.weirs.df arguments["weir_width_excluded"] = self.weirs.protected_ids_list @@ -66,37 +58,21 @@ def collect_exceptions_queries(self): skipped_arguments = {} manual_arguments = {} if self.global_settings is not None: - skipped_arguments[ - "global_settings_excluded" - ] = self.global_settings.protected_ids_list - manual_arguments[ - "global_settings_manual_df" - ] = self.global_settings.manual_changes_df + skipped_arguments["global_settings_excluded"] = self.global_settings.protected_ids_list + manual_arguments["global_settings_manual_df"] = self.global_settings.manual_changes_df if self.bank_levels is not None: - skipped_arguments[ - "bank_levels_excluded" - ] = self.bank_levels.protected_ids_list - manual_arguments[ - "bank_levels_manual_df" - ] = self.bank_levels.manual_changes_df + skipped_arguments["bank_levels_excluded"] = self.bank_levels.protected_ids_list + manual_arguments["bank_levels_manual_df"] = self.bank_levels.manual_changes_df if self.new_manholes is not None: - skipped_arguments[ - "new_manholes_excluded" - ] = self.new_manholes.protected_ids_list + skipped_arguments["new_manholes_excluded"] = self.new_manholes.protected_ids_list if self.update_manholes is not None: - skipped_arguments[ - "manhole_updates_excluded" - ] = self.update_manholes.protected_ids_list - manual_arguments[ - "manhole_update_manual_df" - ] = self.update_manholes.manual_changes_df + skipped_arguments["manhole_updates_excluded"] = self.update_manholes.protected_ids_list + manual_arguments["manhole_update_manual_df"] = self.update_manholes.manual_changes_df if self.weirs is not None: skipped_arguments["weirs_heights_excluded"] = self.weirs.protected_ids_list manual_arguments["weir_widths_manual_df"] = self.weirs.manual_changes_df if self.channels is not None: - skipped_arguments[ - "weirs_heights_excluded" - ] = self.channels.protected_ids_list + skipped_arguments["weirs_heights_excluded"] = self.channels.protected_ids_list manual_arguments["channels_manual_df"] = self.channels.manual_changes_df skipped_rows = collect_excluded(**skipped_arguments) manual_changes = collect_manual_adjustments(**manual_arguments) diff --git a/hhnk_threedi_plugin/gui/checks/one_d_two_d.py b/hhnk_threedi_plugin/gui/checks/one_d_two_d.py index 2b60bd2a..0257bda6 100644 --- a/hhnk_threedi_plugin/gui/checks/one_d_two_d.py +++ b/hhnk_threedi_plugin/gui/checks/one_d_two_d.py @@ -1,33 +1,35 @@ import os -import numpy as np from pathlib import Path + +import numpy as np +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import ( - QPushButton, QFileDialog, QLabel, - QSpacerItem, + QPushButton, QSizePolicy, + QSpacerItem, QVBoxLayout, QWidget, ) -from hhnk_threedi_plugin.gui.general_objects import revisionsComboBox -from PyQt5.QtCore import Qt, pyqtSignal from qgis.core import Qgis -from hhnk_threedi_plugin.gui.utility.widget_interaction import update_button_background +from hhnk_threedi_plugin.gui.general_objects import revisionsComboBox +from hhnk_threedi_plugin.gui.utility.widget_interaction import update_button_background from hhnk_threedi_plugin.tasks import task_one_d_two_d + + def setupUi(one_d_two_d_widget): one_d_two_d_widget.select_revision_label = QLabel("Selecteer revisie:") one_d_two_d_widget.select_revision_box = revisionsComboBox() one_d_two_d_widget.start_1d2d_tests_btn = QPushButton("Begin tests") - # Main layout main_layout = QVBoxLayout() main_layout.setAlignment(Qt.AlignTop) main_layout.setContentsMargins(25, 25, 25, 25) - #Revision selection + # Revision selection main_layout.addWidget(one_d_two_d_widget.select_revision_label) main_layout.addWidget(one_d_two_d_widget.select_revision_box) @@ -77,22 +79,21 @@ def populate_revisions_combobox(self): for rev in revisions: self.select_revision_box.addItem(rev.name) - def one_d_two_d_tests_execution(self): try: update_button_background(button=self.start_1d2d_tests_btn, color="orange") - - task_one_d_two_d.task_one_d_two_d(folder = self.caller.fenv, - revision = self.select_revision_box.currentText(), - dem_path = self.caller.input_data_dialog.dem_selector.filePath()) + + task_one_d_two_d.task_one_d_two_d( + folder=self.caller.fenv, + revision=self.select_revision_box.currentText(), + dem_path=self.caller.input_data_dialog.dem_selector.filePath(), + ) update_button_background(button=self.start_1d2d_tests_btn, color="green") - + except Exception as e: self.caller.iface.messageBar().pushMessage(str(e), Qgis.Critical) update_button_background(button=self.start_1d2d_tests_btn, color="red") pass - def reset_buttons(self): update_button_background(button=self.start_1d2d_tests_btn) - diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_check_popup.py b/hhnk_threedi_plugin/gui/checks/sqlite_check_popup.py index 1b67f1d4..13d699ca 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_check_popup.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_check_popup.py @@ -1,26 +1,26 @@ from msilib.schema import CheckBox + +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import ( - QPushButton, - QVBoxLayout, - QGroupBox, - QGridLayout, - QFileDialog, - QLabel, + QApplication, QCheckBox, - QFrame, - QSpacerItem, QDialog, - QSizePolicy, + QFileDialog, + QFrame, + QGridLayout, + QGroupBox, QHBoxLayout, - QApplication, + QLabel, + QPushButton, + QSizePolicy, + QSpacerItem, + QVBoxLayout, ) -from qgis.core import QgsTask, Qgis -from qgis.utils import QgsMessageLog, iface -from PyQt5.QtCore import Qt, pyqtSignal +from qgis.core import Qgis, QgsTask from qgis.gui import QgsMessageBar -from hhnk_threedi_plugin.gui.utility.widget_interaction import update_button_background - +from qgis.utils import QgsMessageLog, iface +from hhnk_threedi_plugin.gui.utility.widget_interaction import update_button_background def setupUi(sqlite_dialog): @@ -40,7 +40,7 @@ def setupUi(sqlite_dialog): sqlite_dialog.data_verification = QCheckBox("Data verificatie") sqlite_dialog.data_verification.setCheckable(True) sqlite_dialog.data_verification.setChecked(True) - + ## versie met check-boxes per test # sqlite_dialog.impervious_surface_chk = QCheckBox("Ondoorlatend oppervlak") # sqlite_dialog.impervious_surface_chk.setObjectName("impervious_surface_chk") @@ -65,13 +65,11 @@ def setupUi(sqlite_dialog): # sqlite_dialog.cross_section_no_vertex_chk = QCheckBox("Cross-section niet op channel vertex") # sqlite_dialog.cross_section_no_vertex_chk.setObjectName("cross_section_no_vertex_chk") - - # Create slow tests checkboxes and group sqlite_dialog.one_time_checks = QCheckBox("Eenmalige tests", sqlite_dialog.all_tests) sqlite_dialog.one_time_checks.setCheckable(True) sqlite_dialog.one_time_checks.setChecked(False) - + ## versie met check-boxes per test # sqlite_dialog.max_dem_chk = QCheckBox(text="Maximale waarde DEM") # sqlite_dialog.max_dem_chk.setObjectName("max_dem_chk") @@ -81,9 +79,9 @@ def setupUi(sqlite_dialog): # sqlite_dialog.watersurface_area_chk.setObjectName("watersurface_area_chk") # Layouts - #separator = QFrame() - #separator.setFrameShape(QFrame.HLine) - #separator.setFrameShadow(QFrame.Sunken) + # separator = QFrame() + # separator.setFrameShape(QFrame.HLine) + # separator.setFrameShadow(QFrame.Sunken) # Create checkboxes layout # quick checks @@ -117,19 +115,20 @@ def setupUi(sqlite_dialog): sqlite_dialog.all_tests.setLayout(checkboxes_layout) # Main layout - #paths_selection = QLabel("Selecteer benodigde bestanden") + # paths_selection = QLabel("Selecteer benodigde bestanden") main_layout = QVBoxLayout() main_layout.setAlignment(Qt.AlignTop) main_layout.setContentsMargins(25, 25, 25, 25) main_layout.addWidget(sqlite_dialog.bar) - #main_layout.addWidget(paths_selection) - #main_layout.addLayout(path_selection_layout) + # main_layout.addWidget(paths_selection) + # main_layout.addLayout(path_selection_layout) main_layout.addSpacerItem(QSpacerItem(10, 5, QSizePolicy.Expanding)) main_layout.addWidget(sqlite_dialog.all_tests) main_layout.addSpacerItem(QSpacerItem(10, 5, QSizePolicy.Expanding)) main_layout.addWidget(sqlite_dialog.start_sqlite_tests_btn, alignment=Qt.AlignRight) sqlite_dialog.setLayout(main_layout) + class sqliteCheckDialog(QDialog): """ Initialization: @@ -152,7 +151,7 @@ def __init__(self, caller, parent): self.data_verification.clicked.connect(self.group_clicked) self.one_time_checks.clicked.connect(self.group_clicked) self.start_sqlite_tests_btn.clicked.connect(self.verify_submit) - + for child in self.data_verification.findChildren(QCheckBox): child.setChecked(True) @@ -175,7 +174,7 @@ def construct_chosen_tests_list(self): """Checks every checkbox. If one is enabled and checked, it is added to the list of selected tests""" lst = [] - + ## versie met check-boxes per test # for child in self.data_verification.findChildren(QCheckBox): # if child.isEnabled() and child.isChecked(): @@ -195,14 +194,10 @@ def construct_chosen_tests_list(self): "isolated_channels_chk", "cross_section_duplicate_chk", "cross_section_no_vertex_chk", - ] + ] if self.one_time_checks.isChecked(): - lst += [ - "max_dem_chk", - "dewatering_depth_chk", - "watersurface_area_chk" - ] - + lst += ["max_dem_chk", "dewatering_depth_chk", "watersurface_area_chk"] + return lst def verify_submit(self): @@ -216,7 +211,6 @@ def verify_submit(self): self.accept() update_button_background(button=self.start_sqlite_tests_btn, color="green") - def set_current_paths(self): """ Sets current paths as known to main widget to this widget's fields diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/controlled_structs_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/controlled_structs_result.py index 9e01303c..4fad01bf 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/controlled_structs_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/controlled_structs_result.py @@ -1,7 +1,8 @@ -from PyQt5.QtWidgets import QWidget, QVBoxLayout +from PyQt5.QtWidgets import QVBoxLayout, QWidget + from hhnk_threedi_plugin.gui.general_objects import ( - create_view_layer_attributes_button, create_layer_added_label, + create_view_layer_attributes_button, ) controlled_structs_titel = "Gestuurde kunstwerken" diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/cross_section_vertex_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/cross_section_vertex_result.py index 0dba101e..ef51800f 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/cross_section_vertex_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/cross_section_vertex_result.py @@ -1,7 +1,8 @@ -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel +from PyQt5.QtWidgets import QLabel, QVBoxLayout, QWidget + from hhnk_threedi_plugin.gui.general_objects import ( - create_view_layer_attributes_button, create_layer_added_label, + create_view_layer_attributes_button, ) cross_section_no_vertex_chk_title = "Cross-section op channel vertex" diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/cross_section_warning_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/cross_section_warning_result.py index 19ab9259..e468297c 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/cross_section_warning_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/cross_section_warning_result.py @@ -1,7 +1,8 @@ -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel +from PyQt5.QtWidgets import QLabel, QVBoxLayout, QWidget + from hhnk_threedi_plugin.gui.general_objects import ( - create_view_layer_attributes_button, create_layer_added_label, + create_view_layer_attributes_button, ) cross_section_duplicate_chk_title = "Dubbele cross-sections" diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/dem_max_val_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/dem_max_val_result.py index 64e061ff..7a184a98 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/dem_max_val_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/dem_max_val_result.py @@ -1,4 +1,5 @@ -from PyQt5.QtWidgets import QWidget, QVBoxLayout +from PyQt5.QtWidgets import QVBoxLayout, QWidget + from hhnk_threedi_plugin.gui.general_objects import create_formatted_text_edit dem_max_val_title = "Maximale waarde DEM" diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/dewatering_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/dewatering_result.py index d138d44d..8f7798ab 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/dewatering_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/dewatering_result.py @@ -1,7 +1,8 @@ -from PyQt5.QtWidgets import QWidget, QVBoxLayout +from PyQt5.QtWidgets import QVBoxLayout, QWidget + from hhnk_threedi_plugin.gui.general_objects import ( - create_view_layer_attributes_button, create_layer_added_label, + create_view_layer_attributes_button, ) dewatering_title = "Drooglegging" diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/general_checks_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/general_checks_result.py index d780badd..3591e278 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/general_checks_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/general_checks_result.py @@ -1,6 +1,6 @@ -from hhnk_threedi_plugin.gui.general_objects import CsvAsTable -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton -from hhnk_threedi_plugin.gui.general_objects import create_no_errors_label +from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QWidget + +from hhnk_threedi_plugin.gui.general_objects import CsvAsTable, create_no_errors_label geometry_titel = "Algemene tests" @@ -9,7 +9,7 @@ class generalChecksWidget(QWidget): def __init__(self, csv_path): super(generalChecksWidget, self).__init__() self.table = CsvAsTable(csv_path=csv_path) - self.table.setGeometry(100,100,900,900) + self.table.setGeometry(100, 100, 900, 900) self.btn = QPushButton("Bekijk fouten in model") self.btn.clicked.connect(self.table.show) layout = QVBoxLayout() diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/geometries_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/geometries_result.py index 37308797..24cfe833 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/geometries_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/geometries_result.py @@ -1,7 +1,9 @@ -from hhnk_threedi_plugin.gui.general_objects import CsvAsTable, create_no_errors_label -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton import os +from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QWidget + +from hhnk_threedi_plugin.gui.general_objects import CsvAsTable, create_no_errors_label + geometry_titel = "Geometrie" @@ -9,7 +11,7 @@ class geometryWidget(QWidget): def __init__(self, csv_path): super(geometryWidget, self).__init__() self.table = CsvAsTable(csv_path=csv_path) - self.table.setGeometry(100,100,900,900) + self.table.setGeometry(100, 100, 900, 900) self.btn = QPushButton("Bekijk fouten in geometrie") self.btn.clicked.connect(self.table.show) layout = QVBoxLayout() diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/impervious_surface_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/impervious_surface_result.py index 03e942e5..4d7aa52b 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/impervious_surface_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/impervious_surface_result.py @@ -1,5 +1,5 @@ - -from PyQt5.QtWidgets import QWidget, QTextEdit, QVBoxLayout +from PyQt5.QtWidgets import QTextEdit, QVBoxLayout, QWidget + from hhnk_threedi_plugin.gui.general_objects import create_formatted_text_edit impervious_surface_title = "Ondoorlatend oppervlak" @@ -8,7 +8,7 @@ def create_impervious_surface_widget(result_text): widget = QWidget() layout = QVBoxLayout() - result = QTextEdit("
".join(result_text.splitlines())) #was create_formatted_text_edit + result = QTextEdit("
".join(result_text.splitlines())) # was create_formatted_text_edit result.setMaximumHeight(60) layout.addWidget(result) widget.setLayout(layout) diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/isolated_channels_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/isolated_channels_result.py index b2283885..97f61b5d 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/isolated_channels_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/isolated_channels_result.py @@ -1,8 +1,9 @@ -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel +from PyQt5.QtWidgets import QLabel, QVBoxLayout, QWidget + from hhnk_threedi_plugin.gui.general_objects import ( - create_view_layer_attributes_button, create_formatted_text_edit, create_layer_added_label, + create_view_layer_attributes_button, ) isolated_channels_title = "Geisoleerde watergangen" diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/main_result_widget.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/main_result_widget.py index 0c5987ce..c39a0df8 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/main_result_widget.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/main_result_widget.py @@ -1,12 +1,12 @@ +from PyQt5.QtCore import pyqtSignal from PyQt5.QtWidgets import ( QPushButton, + QTreeView, QTreeWidget, QTreeWidgetItem, QVBoxLayout, - QTreeView, QWidget, ) -from PyQt5.QtCore import pyqtSignal class SectionExpandButton(QPushButton): @@ -16,9 +16,7 @@ class SectionExpandButton(QPushButton): def __init__(self, item, text="", parent=None): super().__init__(text, parent) - self.setStyleSheet( - "background-color: #a6a9ad; text-align: left; padding: 5px 10px 5px 10px" - ) + self.setStyleSheet("background-color: #a6a9ad; text-align: left; padding: 5px 10px 5px 10px") self.section = item self.section.setExpanded(True) self.clicked.connect(self.on_clicked) diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/profiles_used_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/profiles_used_result.py index e738efe2..2bf1f293 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/profiles_used_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/profiles_used_result.py @@ -1,7 +1,8 @@ -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel +from PyQt5.QtWidgets import QLabel, QVBoxLayout, QWidget + from hhnk_threedi_plugin.gui.general_objects import ( - create_view_layer_attributes_button, create_layer_added_label, + create_view_layer_attributes_button, ) profiles_used_title = "Gebruikte profielen watergangen" diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/structs_channels_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/structs_channels_result.py index 4167fed8..d0f6922b 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/structs_channels_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/structs_channels_result.py @@ -1,7 +1,8 @@ -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel +from PyQt5.QtWidgets import QLabel, QVBoxLayout, QWidget + from hhnk_threedi_plugin.gui.general_objects import ( - create_view_layer_attributes_button, create_layer_added_label, + create_view_layer_attributes_button, ) structs_channels_titel = "Bodemhoogte kunstwerken" diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/watersurface_area_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/watersurface_area_result.py index 57a43f9e..80e33f49 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/watersurface_area_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/watersurface_area_result.py @@ -1,8 +1,9 @@ -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel +from PyQt5.QtWidgets import QLabel, QVBoxLayout, QWidget + from hhnk_threedi_plugin.gui.general_objects import ( - create_view_layer_attributes_button, create_formatted_text_edit, create_layer_added_label, + create_view_layer_attributes_button, ) watersurface_area_title = "Oppervlaktewater" diff --git a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/weir_height_result.py b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/weir_height_result.py index a4f9d326..f5cdddc8 100644 --- a/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/weir_height_result.py +++ b/hhnk_threedi_plugin/gui/checks/sqlite_test_widgets/weir_height_result.py @@ -1,19 +1,20 @@ -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton, QTextEdit -from PyQt5.QtCore import pyqtSignal -from qgis.utils import QgsMessageBar, Qgis -from hhnk_threedi_plugin.gui.general_objects import ( - create_view_layer_attributes_button, - create_no_errors_label, - create_layer_added_label, -) -from hhnk_threedi_plugin.gui.sql_preview.model_changes_preview import modelChangesPreview import hhnk_research_tools as hrt - - +from hhnk_threedi_tools.utils.queries import create_update_reference_level_query from hhnk_threedi_tools.variables.database_aliases import a_weir_cross_loc_id from hhnk_threedi_tools.variables.database_variables import reference_level_col from hhnk_threedi_tools.variables.weirs import new_ref_lvl -from hhnk_threedi_tools.utils.queries import create_update_reference_level_query +from PyQt5.QtCore import pyqtSignal +from PyQt5.QtWidgets import QLabel, QPushButton, QTextEdit, QVBoxLayout, QWidget +from qgis.utils import Qgis, QgsMessageBar + +from hhnk_threedi_plugin.gui.general_objects import ( + create_layer_added_label, + create_no_errors_label, + create_view_layer_attributes_button, +) +from hhnk_threedi_plugin.gui.sql_preview.model_changes_preview import ( + modelChangesPreview, +) controlled_structs_titel = "Bodemhoogte stuw" @@ -64,9 +65,7 @@ def make_changes(self): self.setWindowTitle("Uitgevoerde aanpassingen aan model") self.results.setHidden(False) except Exception as e: - self.message_bar.pushMessage( - "Changes could not be completed: " + str(e), Qgis.Critical - ) + self.message_bar.pushMessage("Changes could not be completed: " + str(e), Qgis.Critical) class weirHeightWidget(QWidget): @@ -79,9 +78,7 @@ def __init__(self, layer_source, gdf, model_path): layer_button = create_view_layer_attributes_button(layer_source) self.dialog_button = QPushButton("Bekijk voorgestelde aanpassingen") self.dialog_button.clicked.connect(self.dialog.show) - self.dialog.query_executed.connect( - lambda: self.dialog_button.setText("Bekijk uitgevoerde aanpassingen") - ) + self.dialog.query_executed.connect(lambda: self.dialog_button.setText("Bekijk uitgevoerde aanpassingen")) layout.addWidget(layer_label) layout.addWidget(layer_button) layout.addWidget(self.dialog_button) @@ -90,9 +87,7 @@ def __init__(self, layer_source, gdf, model_path): def create_weir_height_widget(layer_source, gdf, model_path): if not gdf.empty: - widget = weirHeightWidget( - layer_source=layer_source, gdf=gdf, model_path=model_path - ) + widget = weirHeightWidget(layer_source=layer_source, gdf=gdf, model_path=model_path) else: widget = QWidget() layout = QVBoxLayout() diff --git a/hhnk_threedi_plugin/gui/checks/zero_d_one_d.py b/hhnk_threedi_plugin/gui/checks/zero_d_one_d.py index aaa18e42..d0605b57 100644 --- a/hhnk_threedi_plugin/gui/checks/zero_d_one_d.py +++ b/hhnk_threedi_plugin/gui/checks/zero_d_one_d.py @@ -1,22 +1,26 @@ import os -import numpy as np from pathlib import Path + +import numpy as np +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import ( - QWidget, - QPushButton, QFileDialog, QLabel, - QSpacerItem, + QPushButton, QSizePolicy, + QSpacerItem, QVBoxLayout, + QWidget, ) -from hhnk_threedi_plugin.gui.general_objects import revisionsComboBox from qgis.core import Qgis -from PyQt5.QtCore import Qt, pyqtSignal -from hhnk_threedi_plugin.tasks import task_zero_d_one_d -from hhnk_threedi_plugin.error_messages.input_error_messages import no_output_folder, no_result_selected +from hhnk_threedi_plugin.error_messages.input_error_messages import ( + no_output_folder, + no_result_selected, +) +from hhnk_threedi_plugin.gui.general_objects import revisionsComboBox from hhnk_threedi_plugin.gui.utility.widget_interaction import update_button_background +from hhnk_threedi_plugin.tasks import task_zero_d_one_d def setupUi(zero_d_one_d_widget): @@ -29,11 +33,11 @@ def setupUi(zero_d_one_d_widget): zero_d_one_d_widget.main_layout.setAlignment(Qt.AlignTop) zero_d_one_d_widget.main_layout.setContentsMargins(25, 25, 25, 25) - #Revision selection + # Revision selection zero_d_one_d_widget.main_layout.addWidget(zero_d_one_d_widget.select_revision_label) zero_d_one_d_widget.main_layout.addWidget(zero_d_one_d_widget.select_revision_box) - #Start test + # Start test zero_d_one_d_widget.main_layout.addSpacerItem(QSpacerItem(25, 5, QSizePolicy.Expanding)) zero_d_one_d_widget.main_layout.addWidget(zero_d_one_d_widget.start_0d1d_tests_btn) @@ -68,11 +72,11 @@ def __init__(self, caller, parent=None): self.start_0d1d_tests_btn.clicked.connect(self.verify_submit) self.select_revision_box.currentTextChanged.connect(self.reset_buttons) - def verify_submit(self): """ Checks whether all fields are correctly filled """ + def verify_input(output_path, revision_selected): """ return values: valid_input (bool), error_message (empty string if no error, else message to display) @@ -82,7 +86,7 @@ def verify_input(output_path, revision_selected): if revision_selected is None or not revision_selected: return False, no_result_selected return True, "" - + res, message = verify_input( output_path=self.caller.input_data_dialog.output_0d_1d__selector.filePath(), revision_selected=self.select_revision_box.currentText(), @@ -94,7 +98,6 @@ def verify_input(output_path, revision_selected): # self.start_0d1d_tests.emit(test_environment) self.zero_d_one_d_test_execution() - def populate_revisions_combobox(self): """ Accumulates a list of valid 3di results (directories) and populates the revision selection @@ -111,18 +114,18 @@ def populate_revisions_combobox(self): for rev in revisions: self.select_revision_box.addItem(rev.name) - def zero_d_one_d_test_execution(self): try: update_button_background(button=self.start_0d1d_tests_btn, color="orange") - task_zero_d_one_d.task_zero_d_one_d(folder = self.caller.fenv, - revision = self.select_revision_box.currentText()) + task_zero_d_one_d.task_zero_d_one_d( + folder=self.caller.fenv, revision=self.select_revision_box.currentText() + ) update_button_background(button=self.start_0d1d_tests_btn, color="green") - + except Exception as e: self.caller.iface.messageBar().pushMessage(str(e), Qgis.Critical) update_button_background(button=self.start_0d1d_tests_btn, color="red") pass def reset_buttons(self): - update_button_background(button=self.start_0d1d_tests_btn) \ No newline at end of file + update_button_background(button=self.start_0d1d_tests_btn) diff --git a/hhnk_threedi_plugin/gui/general_objects.py b/hhnk_threedi_plugin/gui/general_objects.py index 3fd626c3..1581e95d 100644 --- a/hhnk_threedi_plugin/gui/general_objects.py +++ b/hhnk_threedi_plugin/gui/general_objects.py @@ -1,25 +1,22 @@ import csv + +from PyQt5.Qt import QStandardItem, QStandardItemModel, pyqtSignal +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import ( + QComboBox, + QDialog, QFileDialog, - QPushButton, - QLineEdit, QHBoxLayout, - QTextEdit, - QDialog, + QLabel, + QLineEdit, + QPushButton, QTableView, + QTextEdit, QVBoxLayout, - QLabel, QWidget, - QComboBox, ) -from PyQt5.Qt import QStandardItemModel, QStandardItem, pyqtSignal -from qgis.utils import iface from qgis.core import QgsProject - - -from PyQt5.QtCore import Qt -from PyQt5.QtCore import pyqtSignal - +from qgis.utils import iface def create_layer_added_label(): @@ -67,8 +64,8 @@ def __init__(self, csv_path): self.layoutVertical = QVBoxLayout(self) self.layoutVertical.addWidget(self.table) self.populate_table() - - self.table.resizeColumnToContents(0) #resize col1 so it shows all + + self.table.resizeColumnToContents(0) # resize col1 so it shows all def populate_table(self): with open(file=self.csv, mode="r") as fileInput: @@ -107,9 +104,7 @@ class fileWidget(QWidget): """ fileSelected = pyqtSignal(str) - def __init__( - self, file_dialog_title, file_mode, name_filter=None, select_text=None - ): + def __init__(self, file_dialog_title, file_mode, name_filter=None, select_text=None): super(fileWidget, self).__init__() # ---------------------------------------------------------- # Widgets @@ -140,15 +135,11 @@ def __init__( # To prevent the cursor jumping back to the end of the line while the user is typing, we save and # reset the cursor every time a character is typed self.file_selected_edit.textChanged.connect(self.save_cursor_position) - self.file_selected_edit.textChanged.connect( - lambda: self.fileSelected.emit(self.file_selected_edit.text()) - ) + self.file_selected_edit.textChanged.connect(lambda: self.fileSelected.emit(self.file_selected_edit.text())) self.file_selected_edit.textChanged.connect(self.set_cursor_position) # If a file is chosen with the file dialog, save the path to that directory and open the file dialog there # next time - self.file_dialog.fileSelected.connect( - lambda: self.file_dialog.setDirectory(self.file_dialog.directory()) - ) + self.file_dialog.fileSelected.connect(lambda: self.file_dialog.setDirectory(self.file_dialog.directory())) # Handle layout layout = QHBoxLayout() @@ -179,4 +170,4 @@ def filePath(self): def setEnabled(self, state): self.file_selected_edit.setEnabled(state) - self.select_file_btn.setEnabled(state) \ No newline at end of file + self.select_file_btn.setEnabled(state) diff --git a/hhnk_threedi_plugin/gui/input_data.py b/hhnk_threedi_plugin/gui/input_data.py index e69fd2a8..8523910c 100644 --- a/hhnk_threedi_plugin/gui/input_data.py +++ b/hhnk_threedi_plugin/gui/input_data.py @@ -1,31 +1,34 @@ # %% -#TODO refactor en doet nu niet wat het zou moeten; +# TODO refactor en doet nu niet wat het zou moeten; import os from collections import OrderedDict +from pathlib import Path + import pandas as pd +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import ( - QPushButton, - QVBoxLayout, - QGroupBox, - QGridLayout, - QFileDialog, - QLabel, + QApplication, QCheckBox, - QFrame, - QSpacerItem, QDialog, - QSizePolicy, + QFileDialog, + QFrame, + QGridLayout, + QGroupBox, QHBoxLayout, - QApplication, + QLabel, + QPushButton, + QSizePolicy, + QSpacerItem, + QVBoxLayout, ) -from PyQt5.QtCore import Qt, pyqtSignal from qgis.gui import QgsMessageBar + # from hhnk_threedi_plugin.gui.tests.verify_sqlite_tests_input import verify_input from hhnk_threedi_plugin.gui.utility.file_widget import fileWidget -from pathlib import Path + def setupUi(input_data): - #Color + # Color input_data.setWindowTitle("Selecteer benodigde bestanden") input_data.setMinimumWidth(500) @@ -37,74 +40,81 @@ def setupUi(input_data): # Create all file widgets input_data.polder_label = QLabel("Project Folder:") - input_data.polders_map_selector = fileWidget( - file_dialog_title="", file_mode=QFileDialog.Directory ) + input_data.polders_map_selector = fileWidget(file_dialog_title="", file_mode=QFileDialog.Directory) input_data.polders_map_selector.setEnabled(False) input_data.output_selector_label = QLabel("Selecteer output map:") input_data.output_selector_label.setStyleSheet("background-color: lightgreen;border: 1px solid black;") input_data.output_selector = fileWidget( file_dialog_title="Selecteer map om output in aan te maken", - file_mode=QFileDialog.Directory, ) + file_mode=QFileDialog.Directory, + ) input_data.output_selector.setEnabled(False) input_data.model_selector_label = QLabel("Selecteer model:") input_data.model_selector = fileWidget( file_dialog_title="Selecteer een model (.sqlite)", file_mode=QFileDialog.ExistingFile, - name_filter="*.sqlite", ) + name_filter="*.sqlite", + ) input_data.model_selector.setEnabled(False) input_data.dem_label = QLabel("Selecteer DEM raster") input_data.dem_selector = fileWidget( file_dialog_title="Selecteer DEM raster (.tif)", file_mode=QFileDialog.ExistingFile, - name_filter="*.tif", ) + name_filter="*.tif", + ) input_data.dem_selector.setEnabled(True) - input_data.datachecker_label = QLabel("Selecteer datachecker output:") input_data.datachecker_selector = fileWidget( file_dialog_title="Selecteer datachecker output (.gdb)", - file_mode=QFileDialog.Directory, ) + file_mode=QFileDialog.Directory, + ) input_data.datachecker_selector.setEnabled(False) input_data.channels_from_label = QLabel("Watergangen van profielen:") input_data.channel_from_profiles_selector = fileWidget( file_dialog_title="Selecteer channels from profile " "shapefile (.shp)", file_mode=QFileDialog.ExistingFile, - name_filter="*.shp", ) + name_filter="*.shp", + ) input_data.channel_from_profiles_selector.setEnabled(False) input_data.hdb_label = QLabel("HDB:") input_data.hdb_selector = fileWidget( file_dialog_title="Selecteer hydrologen database (.gdb)", - file_mode=QFileDialog.Directory, ) + file_mode=QFileDialog.Directory, + ) input_data.hdb_selector.setEnabled(False) input_data.damo_label = QLabel("DAMO:") input_data.damo_selector = fileWidget( file_dialog_title="Selecteer DAMO database (.gdb)", - file_mode=QFileDialog.Directory, ) + file_mode=QFileDialog.Directory, + ) input_data.damo_selector.setEnabled(False) input_data.polder_shape_label = QLabel("Polder shapefile:") input_data.polder_shape_selector = fileWidget( file_dialog_title="Selecteer polder shapefile (.shp)", - file_mode=QFileDialog.ExistingFile, ) + file_mode=QFileDialog.ExistingFile, + ) input_data.polder_shape_selector.setEnabled(False) - input_data.output_0d_1d_label = QLabel("Selecteer output voor 0d_1d test:") input_data.output_0d_1d__selector = fileWidget( file_dialog_title="Selecteer map om output in aan te maken", - file_mode=QFileDialog.Directory, ) + file_mode=QFileDialog.Directory, + ) input_data.output_0d_1d__selector.setEnabled(False) - + input_data.results_dir_selector_label = QLabel("Selecteer 3di resultaat map:") input_data.results_dir_selector = fileWidget( file_dialog_title="Selecteer 3di revisie map " "(bevat .nc en .h5 files)", - file_mode=QFileDialog.Directory, ) + file_mode=QFileDialog.Directory, + ) input_data.results_dir_selector.setEnabled(False) # Layouts @@ -112,7 +122,7 @@ def setupUi(input_data): separator.setFrameShape(QFrame.HLine) separator.setFrameShadow(QFrame.Sunken) -# Create layout for file dialogs + # Create layout for file dialogs path_selection_layout = QGridLayout() path_selection_layout.setAlignment(Qt.AlignTop) path_selection_layout.setHorizontalSpacing(25) @@ -146,7 +156,7 @@ def setupUi(input_data): main_layout.setAlignment(Qt.AlignTop) main_layout.setContentsMargins(25, 25, 25, 25) main_layout.addWidget(input_data.polder_label) - main_layout.addWidget( input_data.polders_map_selector) + main_layout.addWidget(input_data.polders_map_selector) main_layout.addWidget(input_data.bar) # main_layout.addWidget(paths_selection) main_layout.addLayout(path_selection_layout) @@ -157,9 +167,7 @@ def setupUi(input_data): input_data.setLayout(main_layout) - class inputDataDialog(QDialog): - def __init__(self, caller, parent): super(inputDataDialog, self).__init__(parent) setupUi(self) @@ -167,7 +175,6 @@ def __init__(self, caller, parent): self.setup_main_paths_signals() self.model_selector.fileSelected.connect(self.caller.reset_ui) - def setup_main_paths_signals(self): """ Connects changes in fields (for example the selection of a file) to the function @@ -176,15 +183,22 @@ def setup_main_paths_signals(self): self.datachecker_selector.fileSelected.connect(lambda path: self.caller.update_current_paths(datachecker=path)) self.damo_selector.fileSelected.connect(lambda path: self.caller.update_current_paths(damo=path)) self.hdb_selector.fileSelected.connect(lambda path: self.caller.update_current_paths(hdb=path)) - self.polder_shape_selector.fileSelected.connect(lambda path: self.caller.update_current_paths(polder_shapefile=path)) - self.channel_from_profiles_selector.fileSelected.connect(lambda path: self.caller.update_current_paths(channels_shapefile=path)) + self.polder_shape_selector.fileSelected.connect( + lambda path: self.caller.update_current_paths(polder_shapefile=path) + ) + self.channel_from_profiles_selector.fileSelected.connect( + lambda path: self.caller.update_current_paths(channels_shapefile=path) + ) self.model_selector.fileSelected.connect(lambda path: self.caller.update_current_paths(model=path)) self.dem_selector.fileSelected.connect(lambda path: self.caller.update_current_paths(dem=path)) # self.output_selector_sqlite.fileSelected.connect(lambda path: self.caller.update_current_paths(sqlite_output=path)) # self.result_selector_1d2d.fileSelected.connect(lambda path: self.caller.update_current_paths(one_d_results=path)) - self.output_0d_1d__selector.fileSelected.connect(lambda path: self.caller.update_current_paths(zero_d_output=path)) - self.results_dir_selector.fileSelected.connect(lambda path: self.caller.update_current_paths(zero_d_output=path)) - + self.output_0d_1d__selector.fileSelected.connect( + lambda path: self.caller.update_current_paths(zero_d_output=path) + ) + self.results_dir_selector.fileSelected.connect( + lambda path: self.caller.update_current_paths(zero_d_output=path) + ) def set_current_paths(self): """ @@ -193,32 +207,38 @@ def set_current_paths(self): paths = self.caller.current_source_paths if paths is not None: - - widgets = OrderedDict({"polders_map_selector":"polder_folder","model_selector":"model", - "dem_selector":"dem", "datachecker_selector":"datachecker", "channel_from_profiles_selector":"channels_shapefile", - "hdb_selector":"hdb", "damo_selector":"damo", "polder_shape_selector":"polder_shapefile"}) + widgets = OrderedDict( + { + "polders_map_selector": "polder_folder", + "model_selector": "model", + "dem_selector": "dem", + "datachecker_selector": "datachecker", + "channel_from_profiles_selector": "channels_shapefile", + "hdb_selector": "hdb", + "damo_selector": "damo", + "polder_shape_selector": "polder_shapefile", + } + ) for key, value in widgets.items(): widgt = getattr(self, key) - - filepath = paths[value] #Get filepath from current source paths - name=filepath + filepath = paths[value] # Get filepath from current source paths + + name = filepath widgt.setFilePath(name) if filepath is not None: if Path(filepath).exists(): widgt.setStyleSheet("background-color: lightgreen;border: 1px solid black") - else: + else: widgt.setStyleSheet("background-color: orange; border: 1px solid black") - else: + else: widgt.setStyleSheet("background-color: blue; border: 1px solid black") - # self.polders_map_selector.setFilePath(paths["polder_folder"]) - # self.polders_map_selector.setFilePath(paths["polder_folder"]) # self.model_selector.setFilePath(paths["model"].split(self.polders_map_selector.filePath())[-1]) # self.dem_selector.setFilePath(paths["dem"]) @@ -230,15 +250,14 @@ def set_current_paths(self): # self.output_selector.setFilePath(paths["sqlite_tests_output"].split(self.polders_map_selector.filePath())[-1]) self.output_0d_1d__selector.setFilePath(paths["0d1d_output"]) # self.one_d_two_d.dem_selector.setFilePath(paths["dem"]) - - #Loop over widgets, check if name is None, color the box accordingly - # if (pd.isnull(widgt.filePath())) or (widgt.filePath()==''): - # widgt.setStyleSheet("background-color: Blue; border: 1px solid black;") - # else: - # widgt.setStyleSheet("background-color: lightgreen;border: 1px solid black;") - # self.output_selector.setFilePath(paths["sqlite_tests_output"]) + # Loop over widgets, check if name is None, color the box accordingly + # if (pd.isnull(widgt.filePath())) or (widgt.filePath()==''): + # widgt.setStyleSheet("background-color: Blue; border: 1px solid black;") + # else: + # widgt.setStyleSheet("background-color: lightgreen;border: 1px solid black;") + # self.output_selector.setFilePath(paths["sqlite_tests_output"]) # def set_current_paths_1d_2d(self): # """ @@ -251,4 +270,6 @@ def set_current_paths(self): # self.results_dir_selector.setFilePath(paths["1d2d_results_dir"]) # self.output_selector.setFilePath(paths["1d2d_output"]) # # E:\02.modellen\model_test_v2_juan + + # %% diff --git a/hhnk_threedi_plugin/gui/klimaatsommen/klimaatsommen.py b/hhnk_threedi_plugin/gui/klimaatsommen/klimaatsommen.py index a81ab5a0..c9ae26a9 100644 --- a/hhnk_threedi_plugin/gui/klimaatsommen/klimaatsommen.py +++ b/hhnk_threedi_plugin/gui/klimaatsommen/klimaatsommen.py @@ -1,29 +1,32 @@ import os + +import hhnk_research_tools as hrt +import hhnk_threedi_tools as htt +from hhnk_threedi_tools.qgis import layer_structure +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import ( - QPushButton, + QComboBox, QFileDialog, QLabel, - QSpacerItem, + QLineEdit, + QMessageBox, + QPlainTextEdit, + QPushButton, QSizePolicy, + QSpacerItem, QVBoxLayout, QWidget, - QPlainTextEdit, - QLineEdit, - QLabel, - QMessageBox, - QComboBox, ) -from ..general_objects import revisionsComboBox -from PyQt5.QtCore import Qt, pyqtSignal +import hhnk_threedi_plugin.qgis_interaction.project as project from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR from hhnk_threedi_plugin.gui.utility.widget_interaction import update_button_background -from hhnk_threedi_tools.qgis import layer_structure -import hhnk_threedi_plugin.qgis_interaction.project as project -import hhnk_research_tools as hrt -import hhnk_threedi_tools as htt +from hhnk_threedi_plugin.qgis_interaction.klimaatsommen_pdfs import ( + create_pdfs, + load_print_layout, +) -from hhnk_threedi_plugin.qgis_interaction.klimaatsommen_pdfs import create_pdfs, load_print_layout +from ..general_objects import revisionsComboBox SUBJECT = "Klimaatsommen" @@ -46,7 +49,7 @@ class KlimaatSommenWidget(QWidget): def __init__(self, caller, parent=None): super().__init__() self.setupUi() - + # ---------------------------------------------------------- # Variables # ---------------------------------------------------------- @@ -73,7 +76,6 @@ def __init__(self, caller, parent=None): def fenv(self): return self.caller.fenv - def setupUi(self): self.select_revision_label = QLabel("Selecteer revisie:") self.select_revision_box = revisionsComboBox() @@ -82,7 +84,6 @@ def setupUi(self): self.create_pdfs_btn = QPushButton("Maak pdfs") self.create_clean_btn = QPushButton("clean") - # Main layout main_layout = QVBoxLayout() main_layout.setAlignment(Qt.AlignTop) @@ -100,7 +101,6 @@ def setupUi(self): self.setLayout(main_layout) - def verify_submit_laad_layout(self): """ Checks if all input is legal, if so, creates test environment (variable container) and @@ -109,19 +109,15 @@ def verify_submit_laad_layout(self): update_button_background(button=self.laad_layout_btn, color="orange") - df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, - name="qgis_layer_structure.csv") - - - + df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, name="qgis_layer_structure.csv") + revisions = layer_structure.SelectedRevisions(klimaatsommen=self.select_revision_box.currentText()) - #Load layers + # Load layers proj = project.Project() - proj.run(layer_structure_path=df_path, - subjects=['klimaatsommen'], - revisions=revisions, - folder=self.caller.fenv) + proj.run( + layer_structure_path=df_path, subjects=["klimaatsommen"], revisions=revisions, folder=self.caller.fenv + ) load_print_layout() update_button_background(button=self.laad_layout_btn, color="green") @@ -141,7 +137,7 @@ def verify_submit_create_pdfs(self): - Laadt de revisie laag in. - Extents verschillen per monitor. Werkt het niet? Pas de extent aan in de layout manager. (project -> layouts -> wsa_kaarten) - """ + """, ) # load_print_layout() @@ -156,14 +152,13 @@ def populate_combobox(self): for rev in revisions: self.select_revision_box.addItem(rev.name) - def verify_submit_create_clean(self): - msgBox = QMessageBox() - msgBox.setIcon(QMessageBox.Information) - msgBox.setText("AL GOOD") - msgBox.setWindowTitle("GOOD MESSAGE") - msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) - msgBox.buttonClicked.connect(self.verify_submit_create_clean) + msgBox = QMessageBox() + msgBox.setIcon(QMessageBox.Information) + msgBox.setText("AL GOOD") + msgBox.setWindowTitle("GOOD MESSAGE") + msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) + msgBox.buttonClicked.connect(self.verify_submit_create_clean) def reset_buttons(self): - update_button_background(button=self.laad_layout_btn) \ No newline at end of file + update_button_background(button=self.laad_layout_btn) diff --git a/hhnk_threedi_plugin/gui/load_layers_popup.py b/hhnk_threedi_plugin/gui/load_layers_popup.py index b61500c3..9d70daf6 100644 --- a/hhnk_threedi_plugin/gui/load_layers_popup.py +++ b/hhnk_threedi_plugin/gui/load_layers_popup.py @@ -1,67 +1,60 @@ import os + +import hhnk_research_tools as hrt +import hhnk_threedi_tools as htt +from hhnk_threedi_tools import MigrateSchema, SqliteCheck +from hhnk_threedi_tools.qgis import layer_structure +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import ( + QCheckBox, QDialog, - QVBoxLayout, + QDialogButtonBox, QLabel, - QSpacerItem, QSizePolicy, - QCheckBox, - QDialogButtonBox, + QSpacerItem, + QVBoxLayout, ) -from PyQt5.QtCore import Qt, pyqtSignal from qgis.core import Qgis from qgis.utils import QgsMessageBar, iface - -from hhnk_threedi_tools import SqliteCheck, MigrateSchema -import hhnk_research_tools as hrt -import hhnk_threedi_tools as htt - -# new - -from .general_objects import revisionsComboBox import hhnk_threedi_plugin.qgis_interaction.project as project -from hhnk_threedi_plugin.qgis_interaction import load_layers_interaction -from hhnk_threedi_tools.qgis import layer_structure # hhnk-threedi-tests from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR +from hhnk_threedi_plugin.gui.utility.widget_interaction import update_button_background +from hhnk_threedi_plugin.qgis_interaction import load_layers_interaction # get plugin-tasks from hhnk_threedi_plugin.tasks import generateGridTask -from hhnk_threedi_plugin.gui.utility.widget_interaction import update_button_background + +# new +from .general_objects import revisionsComboBox def setup_ui(load_layers_popup): load_layers_popup.setMinimumWidth(400) # Creates items to be in widget load_layers_popup.bar = QgsMessageBar() - load_layers_popup.zero_d_one_d_selector_label = QLabel( - "Selecteer 0d1d test revisie:" - ) + load_layers_popup.zero_d_one_d_selector_label = QLabel("Selecteer 0d1d test revisie:") load_layers_popup.zero_d_one_d_selector = revisionsComboBox() - load_layers_popup.one_d_two_d_selector_label = QLabel( - "Selecteer 1d2d test revisie:" - ) + load_layers_popup.one_d_two_d_selector_label = QLabel("Selecteer 1d2d test revisie:") load_layers_popup.one_d_two_d_selector = revisionsComboBox() - load_layers_popup.klimaatsommen_selector_label = QLabel( - "Selecteer klimaatsom revisie:" - ) + load_layers_popup.klimaatsommen_selector_label = QLabel("Selecteer klimaatsom revisie:") load_layers_popup.klimaatsommen_selector = revisionsComboBox() load_layers_popup.sqlite_selector = QCheckBox("Sqlite (3Di plugin)") load_layers_popup.sqlite_selector.setChecked(True) - + load_layers_popup.grid_selector = QCheckBox("Grid genereren") load_layers_popup.grid_selector.setChecked(False) - + load_layers_popup.sqlite_test_selector = QCheckBox("Sqlite testen") load_layers_popup.sqlite_test_selector.setChecked(False) load_layers_popup.banklevel_test_selector = QCheckBox("Banklevel test") load_layers_popup.banklevel_test_selector.setChecked(False) - + load_layers_popup.test_protocol_selector = QCheckBox("Basis layout") load_layers_popup.test_protocol_selector.setChecked(True) @@ -105,10 +98,9 @@ def setup_ui(load_layers_popup): main_layout.addWidget(load_layers_popup.sqlite_test_selector) main_layout.addSpacerItem(QSpacerItem(20, 10, QSizePolicy.Expanding)) - + main_layout.addWidget(load_layers_popup.banklevel_test_selector) main_layout.addSpacerItem(QSpacerItem(20, 10, QSizePolicy.Expanding)) - main_layout.addWidget(load_layers_popup.test_protocol_selector) main_layout.addSpacerItem(QSpacerItem(20, 10, QSizePolicy.Expanding)) @@ -157,8 +149,6 @@ def __init__(self, caller, parent): self.buttons.rejected.connect(self.close) # Verify on accept # self.buttons.accepted.connect(self.verify_submit) - - def populate_one_d_two_combobox(self): """Add available revisions to dropdown""" @@ -197,31 +187,27 @@ def set_current_paths(self): self.sqlite_output_path = paths["sqlite_tests_output"] self.zero_d_one_d_output_path = paths["0d1d_output"] self.one_d_two_d_output_path = paths["1d2d_output"] - + # combobox self.populate_klimaatsommen_combobox() self.populate_zero_d_one_d_combobox() self.populate_one_d_two_combobox() - def load_layers(self): update_button_background(button=self.buttons, color="orange") iface.messageBar().pushMessage("Inladen van lagen gestart", level=Qgis.Info) - - df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, - name="qgis_layer_structure.csv") - subjects=[] - revisions = layer_structure.SelectedRevisions() + df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, name="qgis_layer_structure.csv") + subjects = [] + revisions = layer_structure.SelectedRevisions() if self.sqlite_selector.isChecked() == True: - - #Migrate sqlite to newest version + # Migrate sqlite to newest version migrate_schema = MigrateSchema(filename=self.caller.fenv.model.schema_base.sqlite_paths[0].as_posix()) migrate_schema.run() - #load in project + # load in project load_layers_interaction.load_sqlite(filepath=self.caller.fenv.model.schema_base.sqlite_paths[0].as_posix()) if self.grid_selector.isChecked() == True: @@ -233,61 +219,58 @@ def load_layers(self): # subjects.append('grid') - # Sqlite test if self.sqlite_test_selector.isChecked() == True: - subjects.append('test_sqlite') + subjects.append("test_sqlite") if self.banklevel_test_selector.isChecked() == True: - subjects.append('test_banklevels') + subjects.append("test_banklevels") # Test protocol if self.test_protocol_selector.isChecked() == True: - #FIXME tijdelijke implementatie om gdb in gpkg om te zetten. Als dit in alle projectmappen staat kan het weer weg. + # FIXME tijdelijke implementatie om gdb in gpkg om te zetten. Als dit in alle projectmappen staat kan het weer weg. for source in ["datachecker", "damo", "hdb"]: in_gdb = hrt.FileGDB(getattr(self.caller.fenv.source_data, source).path.with_suffix(".gdb")) out_gpkg = getattr(self.caller.fenv.source_data, source) - hrt.convert_gdb_to_gpkg(gdb=in_gdb, gpkg=out_gpkg, overwrite=False, verbose=False) + hrt.convert_gdb_to_gpkg(gdb=in_gdb, gpkg=out_gpkg, overwrite=False, verbose=False) if in_gdb.exists(): iface.messageBar().pushMessage( - f"{source}_gdb is omgezet in {source}_gpkg. {source}.gdb kan verwijderd worden.", level=Qgis.Warning + f"{source}_gdb is omgezet in {source}_gpkg. {source}.gdb kan verwijderd worden.", + level=Qgis.Warning, ) - subjects.append('test_protocol') + subjects.append("test_protocol") # 0d1d test if self.zero_d_one_d_selector.currentText() != "": - subjects.append('test_0d1d') + subjects.append("test_0d1d") revisions.check_0d1d = self.zero_d_one_d_selector.currentText() # 1d2d test if self.one_d_two_d_selector.currentText() != "": - subjects.append('test_1d2d') + subjects.append("test_1d2d") revisions.check_1d2d = self.one_d_two_d_selector.currentText() # Achtergrond - if self.achtergrond_selector.isChecked() == True: #Todo naam button veranderen en andere achtergrond buttons weg. - subjects.append('achtergrond') + if ( + self.achtergrond_selector.isChecked() == True + ): # Todo naam button veranderen en andere achtergrond buttons weg. + subjects.append("achtergrond") # Klimaatsommen if self.klimaatsommen_selector.currentText() != "": - subjects.append('klimaatsommen') + subjects.append("klimaatsommen") revisions.klimaatsommen = self.klimaatsommen_selector.currentText() - - #Laad geselecteerde lagen. + # Laad geselecteerde lagen. if subjects != []: proj = project.Project() - proj.run(layer_structure_path=df_path, - subjects=subjects, - revisions=revisions, - folder=self.caller.fenv) + proj.run(layer_structure_path=df_path, subjects=subjects, revisions=revisions, folder=self.caller.fenv) - #TODO moet dit een keuze worden? + # TODO moet dit een keuze worden? # project.zoom_to_layer(layer_name='polder_polygon') update_button_background(button=self.buttons) self.accept() - diff --git a/hhnk_threedi_plugin/gui/model_splitter/model_splitter_dialog.py b/hhnk_threedi_plugin/gui/model_splitter/model_splitter_dialog.py index 4dea96c4..8a7384f0 100644 --- a/hhnk_threedi_plugin/gui/model_splitter/model_splitter_dialog.py +++ b/hhnk_threedi_plugin/gui/model_splitter/model_splitter_dialog.py @@ -1,46 +1,47 @@ -import os - -from qgis.PyQt.QtWidgets import QListWidgetItem -from qgis.PyQt import QtWidgets, uic -from PyQt5.QtGui import QTextCursor -from PyQt5.QtWidgets import QApplication - import datetime -from pathlib import Path +import os import re +from pathlib import Path +import hhnk_research_tools as hrt import hhnk_threedi_tools as htt -from hhnk_threedi_tools import MigrateSchema import hhnk_threedi_tools.core.schematisation.upload as upload +from hhnk_threedi_tools import MigrateSchema +from PyQt5.QtGui import QTextCursor +from PyQt5.QtWidgets import QApplication +from qgis.PyQt import QtWidgets, uic +from qgis.PyQt.QtWidgets import QListWidgetItem -import hhnk_research_tools as hrt -from hhnk_threedi_plugin.tasks import generalChecksTask, checkSchematisationTask from hhnk_threedi_plugin.gui.utility.widget_interaction import update_button_background - +from hhnk_threedi_plugin.tasks import checkSchematisationTask, generalChecksTask CHECK_PARAMETERS = ["kmax", "grid_space", "output_time_step"] -#%% + + +# %% def strip_special_characters(input_string): # Replace all backslashes with forward slashes - input_string = input_string.replace('\\', '/') - + input_string = input_string.replace("\\", "/") + # Remove all characters except alphanumeric, underscores, hyphens, and forward slashes - return re.sub(r'[^a-zA-Z0-9-_\/. ]', '', input_string) + return re.sub(r"[^a-zA-Z0-9-_\/. ]", "", input_string) + + +# %% -#%% class modelSplitterDialog(QtWidgets.QDialog): def __init__(self, caller, parent=None): super().__init__(parent) - uic.loadUi(os.path.join(os.path.dirname(__file__), "model_splitter_dialog.ui"),self) - self.caller=caller + uic.loadUi(os.path.join(os.path.dirname(__file__), "model_splitter_dialog.ui"), self) + self.caller = caller self.dockwidget = parent - self.setWindowTitle('Modelsplitter') + self.setWindowTitle("Modelsplitter") self.api_key = self.dockwidget.threedi_api_key_textbox.text() self.sql_error = None self.model_splitted = False - self.settings_path = False #Track so we only update when xlsx was changed. + self.settings_path = False # Track so we only update when xlsx was changed. # init widget self.dockwidget.model_splitter_btn.clicked.connect(self.migration_check) @@ -68,16 +69,21 @@ def init_widgets(self): """Load model settings and default settings. Thet are added as .settings_df and .settings_default_series""" if self.settings_path == self.model_settings_path.filePath(): return - + self.settings_path = self.model_settings_path.filePath() - self.modelschematisations = htt.model_splitter.ModelSchematisations(folder=self.caller.fenv, - modelsettings_path=self.settings_path) + self.modelschematisations = htt.model_splitter.ModelSchematisations( + folder=self.caller.fenv, modelsettings_path=self.settings_path + ) self.add_models_to_widget() if self.modelschematisations.settings_loaded: - # Add logging that file was changed + # Add logging that file was changed folder_path = self.model_settings_path.filePath() self.info_list.addItem("") - self.add_list_item(self.info_list, "-----------------------------------------------------------------------------*", addtime=True) + self.add_list_item( + self.info_list, + "-----------------------------------------------------------------------------*", + addtime=True, + ) self.info_list.addItem("Current model settings folder:") self.add_list_item(self.info_list, f"- {folder_path}") @@ -85,26 +91,25 @@ def update_widgets(self): """Clear modelwidgets and add the new ones.""" if self.settings_path == self.model_settings_path.filePath(): return - #Clear the widgets of all items + # Clear the widgets of all items self.enabled_list.clear() self.disabled_list.clear() - #Load the new settings file. + # Load the new settings file. self.init_widgets() @property def enabled_lst(self): return self.get_lst_items(listwidget=self.enabled_list) - def check_consistency_enabled_models(self): """Check settings_df if any of the CHECK_PARAMETERS columns have different values give this back as warning so user is aware of the differences.""" if self.enabled_lst: if "" in self.enabled_lst: - #itemChanged geeft als er meerdere items aan enabled toe worden gevoegd - #een signaal af voor elk item. Met daarna lege entries. We hoeven alleen - #check te draaien als alle items zijn toegevoegd aan enabled_list. + # itemChanged geeft als er meerdere items aan enabled toe worden gevoegd + # een signaal af voor elk item. Met daarna lege entries. We hoeven alleen + # check te draaien als alle items zijn toegevoegd aan enabled_list. return else: models_df = self.modelschematisations.settings_df.loc[self.enabled_lst] @@ -113,13 +118,12 @@ def check_consistency_enabled_models(self): if models_df[parameter].nunique() != 1: self.info_list.addItem( f"WARNING: value of '{parameter}' is not unique: {models_df[parameter].to_dict()}" - ) + ) - #Something changed in selected so we need to split again. + # Something changed in selected so we need to split again. self.model_splitted = False self.reset_buttons() - def reset_buttons(self): self.upload_push_btn.setEnabled(False) if self.modelschematisations.settings_loaded: @@ -129,7 +133,6 @@ def reset_buttons(self): update_button_background(self.run_splitter_btn) update_button_background(self.upload_push_btn) - def close_widget(self): self.settings_path = False @@ -141,39 +144,40 @@ def close_widget(self): # enable all buttons for next time self.reset_buttons() - - #Reset styles + + # Reset styles update_button_background(self.check_push_btn) update_button_background(self.upload_push_btn) # close the widget self.close() - def verify_upload(self, verbose=True): """Check if upload is ready; model is splitted and commit-message supplied.""" self.upload_push_btn.setEnabled(False) cont = True - #Error in sqlite + # Error in sqlite if cont and self.sql_error is None: message = "Run Check Sqlite to continue" cont = False - #Error in sqlite + # Error in sqlite if cont and self.sql_error: - message = "Model contains errors in sqlite database and cannot be uploaded. Run sqlite checks and fix errors." + message = ( + "Model contains errors in sqlite database and cannot be uploaded. Run sqlite checks and fix errors." + ) cont = False - #Model not split + # Model not split if not self.model_splitted: message = "Split model to upload version(s)" cont = False - #empty list - if cont and not self.enabled_lst: + # empty list + if cont and not self.enabled_lst: message = "Enable a schematisation and use splitter" - cont = False + cont = False if cont and (len(self.get_commit_message()) <= 2): message = "Provide commit message (minimal 3 characters) to upload version(s)" @@ -185,7 +189,7 @@ def verify_upload(self, verbose=True): if verbose: self.info_list.addItem(message) - self.add_list_item(self.info_list, "") + self.add_list_item(self.info_list, "") def add_models_to_widget(self): """Add models to the listwidgets""" @@ -194,7 +198,6 @@ def add_models_to_widget(self): for item_name in self.modelschematisations.settings_df.index: self.disabled_list.addItem(QListWidgetItem(item_name)) self.check_consistency_enabled_models() - def get_lst_items(self, listwidget) -> list: """Get items from widgets""" @@ -202,8 +205,7 @@ def get_lst_items(self, listwidget) -> list: for x in range(listwidget.count()): items.append(listwidget.item(x).text()) return items - - + def get_commit_message(self): commit_message = self.commitMessage.toPlainText() cleaned_commit_message = strip_special_characters(commit_message) @@ -218,15 +220,15 @@ def sqlite_check(self): """Check if sqlite is OK according to 3Di:schematisation_checker and HHNK general checks""" update_button_background(button=self.check_push_btn, color="orange") - + # init checks check_schematisation = checkSchematisationTask(folder=self.caller.fenv, add_to_project=True) check_general = generalChecksTask(folder=self.caller.fenv) - + # run checks check_schematisation.run() check_general.run() - + # check errors self.sql_error = any((check_schematisation.error, check_general.error)) self.info_list.addItem("") @@ -237,18 +239,16 @@ def sqlite_check(self): update_button_background(button=self.check_push_btn, color="green") self.verify_upload(verbose=True) - def migration_check(self): """Migrate schema to newest version using htt.MigrateSchema""" print(self.caller.fenv.model.schema_base.sqlite_paths[0]) migrate_schema = MigrateSchema(filename=self.caller.fenv.model.schema_base.sqlite_paths[0]) migrate_schema.run() - def create_schematisations(self): """Loop over the selected models in the list widget on the right Create individual schematisations for each""" - + update_button_background(button=self.run_splitter_btn, color="orange") for list_name in self.enabled_lst: @@ -267,7 +267,9 @@ def create_schematisations(self): self.info_list.addItem("Model versions disabled: " + str(self.get_lst_items(listwidget=self.disabled_list))) self.info_list.addItem("") # create local split-revision - response = self.modelschematisations.create_local_sqlite_revision(commit_message=str(" (local split revision)" )) + response = self.modelschematisations.create_local_sqlite_revision( + commit_message=str(" (local split revision)") + ) self.info_list.addItem(response) self.info_list.addItem("") self.info_list.addItem("Selected Organisation ID: " + self.dockwidget.org_name_comboBox.currentText()) @@ -276,23 +278,27 @@ def create_schematisations(self): update_button_background(button=self.run_splitter_btn, color="green") self.verify_upload(verbose=True) - def revision_check(self): """Log latest revision.""" - + self.info_list.addItem("") - self.add_list_item(self.info_list, f"-----------------------------------------------------------------------------*", addtime=True) + self.add_list_item( + self.info_list, + f"-----------------------------------------------------------------------------*", + addtime=True, + ) self.info_list.addItem(self.modelschematisations.get_latest_local_revision_str()) for list_name in self.enabled_lst: - self.info_list.addItem(self.modelschematisations.get_model_revision_info(name=list_name, api_key=self.api_key)) + self.info_list.addItem( + self.modelschematisations.get_model_revision_info(name=list_name, api_key=self.api_key) + ) # Logging self.info_list.addItem("") self.info_list.addItem("Check revisions and continue to upload the versions") - - def upload_schematisations(self): + def upload_schematisations(self): """Upload selected schematisations to the 3Di servers.""" try: update_button_background(self.upload_push_btn, color="orange") @@ -303,26 +309,36 @@ def upload_schematisations(self): polder_path = Path(polders_dir) / polder # settings for upload - organisations = upload.threedi.api.contracts_list(organisation__name=self.dockwidget.org_name_comboBox.currentText()).results - for org in organisations: - uuid_slug = org.organisation - - # upload the schematisation + organisations = upload.threedi.api.contracts_list( + organisation__name=self.dockwidget.org_name_comboBox.currentText() + ).results + for org in organisations: + uuid_slug = org.organisation + + # upload the schematisation for list_name in self.enabled_lst: self.info_list.addItem("") self.add_list_item(self.info_list, f"Started uploading: {list_name}", addtime=True) - self.modelschematisations.upload_schematisation(name=list_name, commit_message=commit_message, api_key=self.api_key, organisation_uuid=uuid_slug) + self.modelschematisations.upload_schematisation( + name=list_name, commit_message=commit_message, api_key=self.api_key, organisation_uuid=uuid_slug + ) self.add_list_item(self.info_list, f"Finished uploading: {list_name}", addtime=True) # Logging self.info_list.addItem("") - self.add_list_item(self.info_list, f"-----------------------------------------------------------------------------*", addtime=True) + self.add_list_item( + self.info_list, + "-----------------------------------------------------------------------------*", + addtime=True, + ) self.info_list.addItem(f"Model versions uploaded: {self.enabled_lst}") self.info_list.addItem(f"Path: {polder_path}") - + # create local upload revision - response = self.modelschematisations.create_local_sqlite_revision(commit_message = ("upload revision " + commit_message)) + response = self.modelschematisations.create_local_sqlite_revision( + commit_message=("upload revision " + commit_message) + ) self.add_list_item(self.info_list, response) self.model_splitted = False self.upload_push_btn.setEnabled(False) @@ -330,7 +346,6 @@ def upload_schematisations(self): except Exception as e: update_button_background(self.upload_push_btn, color="red") raise e - def add_list_item(self, lst_widget, text, addtime=False): """add item to info_list and scroll to botom""" @@ -340,4 +355,4 @@ def add_list_item(self, lst_widget, text, addtime=False): lst_widget.addItem(f"{text}") lst_widget.scrollToBottom() - lst_widget.repaint() #update widgets \ No newline at end of file + lst_widget.repaint() # update widgets diff --git a/hhnk_threedi_plugin/gui/modelbuilder.py b/hhnk_threedi_plugin/gui/modelbuilder.py index c4b80e5c..533835ea 100644 --- a/hhnk_threedi_plugin/gui/modelbuilder.py +++ b/hhnk_threedi_plugin/gui/modelbuilder.py @@ -49,30 +49,22 @@ class ModelBuilder: status: dict = None _online: bool = None - datachecker_log: LogDialog = LogDialog( - path=r"/datachecker/log", - title="Datachecker log" - ) - modelbuilder_log: LogDialog = LogDialog( - path=r"/modelbuilder/log", - title="Modelbuilder log" - ) + datachecker_log: LogDialog = LogDialog(path=r"/datachecker/log", title="Datachecker log") + modelbuilder_log: LogDialog = LogDialog(path=r"/modelbuilder/log", title="Modelbuilder log") def __post_init__(self): """Connect all callback-functions to widgets.""" - + self.dockwidget.input_dir_select.setFilePath( r"//corp.hhnk.nl/data/Hydrologen_data/Data/modelbuilder/data/input/" - ) + ) self.dockwidget.output_dir_select.setFilePath( r"//corp.hhnk.nl/data/Hydrologen_data/Data/modelbuilder/data/output/" - ) + ) self.timer.timeout.connect(self.check_available) self.dockwidget.tabWidget.currentChanged.connect(self.change_tab) - self.dockwidget.select_server_box.currentTextChanged.connect( - self.connect_modelbuilder - ) + self.dockwidget.select_server_box.currentTextChanged.connect(self.connect_modelbuilder) self.dockwidget.datachecker_log_btn.clicked.connect(self.show_datachecker_log) self.dockwidget.modelbuilder_log_btn.clicked.connect(self.show_modelbuilder_log) self.dockwidget.start_datachecker_btn.clicked.connect(self.start_datachecker) @@ -81,7 +73,6 @@ def __post_init__(self): # we check if we are in Modelbuilder. self.change_tab() - def _request_status(self): try: response = requests.get(f"{self.url}/status", timeout=1) @@ -130,15 +121,11 @@ def set_select_server_label(self): """Set the select_server_label text and styling.""" if self.online: self.dockwidget.select_server_label.setText("Server (online):") - self.dockwidget.select_server_label.setStyleSheet( - "color: green; font: bold" - ) + self.dockwidget.select_server_label.setStyleSheet("color: green; font: bold") else: self.dockwidget.select_server_label.setText("Server (offline):") - self.dockwidget.select_server_label.setStyleSheet( - "color: red; font: bold" - ) - + self.dockwidget.select_server_label.setStyleSheet("color: red; font: bold") + def set_modules_labels(self): self.get_status() for module in self.status.keys(): @@ -149,7 +136,6 @@ def set_modules_labels(self): else: label.setText(f"{module} (bezig):") label.setStyleSheet("color: orange; font: bold") - def set_active_buttons(self, available): """Enable the correct buttons depending on online or available server.""" @@ -175,9 +161,8 @@ def start_modelbuilder(self): polder_name = self.dockwidget.poldernaam_textbox.text() if polder_id and polder_name and self.status["modelbuilder"]: response = requests.post( - url=f"{self.url}/modelbuilder/start", - data={"polder_id": polder_id, "polder_name": polder_name} - ) + url=f"{self.url}/modelbuilder/start", data={"polder_id": polder_id, "polder_name": polder_name} + ) if response.ok: self.set_unavailable() @@ -203,7 +188,7 @@ def connect_modelbuilder(self): """connect to a datachecker server and check availability.""" # check if server is online and set label - self._online = None # forces next line to check for status + self._online = None # forces next line to check for status self.set_select_server_label() # check if server is available and set buttons active @@ -218,7 +203,7 @@ def connect_modelbuilder(self): if not available: self.set_unavailable() else: - self.set_modules_labels() + self.set_modules_labels() else: self.stop_timer() diff --git a/hhnk_threedi_plugin/gui/new_project_dialog.py b/hhnk_threedi_plugin/gui/new_project_dialog.py index 7489452c..fa004b8d 100644 --- a/hhnk_threedi_plugin/gui/new_project_dialog.py +++ b/hhnk_threedi_plugin/gui/new_project_dialog.py @@ -1,31 +1,33 @@ +import glob import os -import pandas as pd import shutil -import glob - from pathlib import Path + +import hhnk_research_tools as hrt +import hhnk_threedi_tools as htt +import pandas as pd +from hhnk_threedi_tools.core.folders import Folders +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import ( QComboBox, QDialog, - QVBoxLayout, QFileDialog, - QLineEdit, QLabel, + QLineEdit, + QMessageBox, + QPushButton, QSizePolicy, QSpacerItem, - QPushButton, - QMessageBox, + QVBoxLayout, ) -from PyQt5.QtCore import Qt, pyqtSignal from qgis.utils import Qgis, iface + +from hhnk_threedi_plugin.hhnk_toolbox_dockwidget import HHNK_toolboxDockWidget + from ..error_messages.input_error_messages import ( - invalid_character_in_filename, folder_exists_already, + invalid_character_in_filename, ) -from hhnk_threedi_tools.core.folders import Folders -from hhnk_threedi_plugin.hhnk_toolbox_dockwidget import HHNK_toolboxDockWidget -import hhnk_threedi_tools as htt -import hhnk_research_tools as hrt def setupUi(new_project_dialog): @@ -34,7 +36,7 @@ def setupUi(new_project_dialog): layout.setContentsMargins(25, 25, 25, 25) new_project_dialog.setWindowTitle("Nieuw project aanmaken") new_project_dialog.setMinimumWidth(275) - + # Creates items to be in widget new_project_dialog.reference_model_label = QLabel("Geef referentie polder op:") new_project_dialog.reference_model_box = QComboBox() @@ -50,37 +52,38 @@ def setupUi(new_project_dialog): layout.addWidget(new_project_dialog.reference_model_box, alignment=Qt.AlignTop) layout.addSpacerItem(QSpacerItem(20, 10, QSizePolicy.Expanding)) - layout.addWidget(new_project_dialog.polder_name_label, alignment=Qt.AlignTop) + layout.addWidget(new_project_dialog.polder_name_label, alignment=Qt.AlignTop) layout.addWidget(new_project_dialog.polder_name_field, alignment=Qt.AlignTop) layout.addSpacerItem(QSpacerItem(20, 10, QSizePolicy.Expanding)) layout.addWidget(new_project_dialog.create_project_btn, alignment=Qt.AlignTop) new_project_dialog.setLayout(layout) - #set reference model + # set reference model dockwidget = HHNK_toolboxDockWidget() base_path = Path(dockwidget.polders_map_selector.filePath()) base_path = str(base_path.parent) print(base_path) if base_path == "." or "": - base_path = r'E:\02.modellen' - + base_path = r"E:\02.modellen" + print(base_path) reference_models_paths = glob.glob(str(base_path + "\\cbt-[0-9]")) + glob.glob(str(base_path + "\\cbt-[0-9][0-9]")) - new_project_dialog.reference_model_box.addItem("",) + new_project_dialog.reference_model_box.addItem( + "", + ) for paths in reference_models_paths: files = os.listdir(paths) for file in files: - if file.endswith('.sqlite'): + if file.endswith(".sqlite"): new_project_dialog.reference_model_box.addItem((os.path.splitext(file)[0])) - - + new_project_dialog.reference_model_box.setStyleSheet("QComboBox { combobox-popup: 0; }") new_project_dialog.reference_model_box.setMaxVisibleItems(10) - new_project_dialog.reference_model_box.setPlaceholderText(str('-Select Polder-')) + new_project_dialog.reference_model_box.setPlaceholderText(str("-Select Polder-")) new_project_dialog.reference_model_box.setCurrentIndex(-1) - + class newProjectDialog(QDialog): """ @@ -100,139 +103,122 @@ def __init__(self, base_path): setupUi(self) self.base_path = Path(base_path) self.polder_path = None - + # ---------------------------------------------------------- # Signals # ---------------------------------------------------------- self.create_project_btn.clicked.connect(self.make_folders) def make_folders(self): - project_name = self.polder_name_field.text().replace(" ","_") - if not project_name: - iface.messageBar().pushMessage( - "Geen projectnaam opgegeven", Qgis.Critical - ) + project_name = self.polder_name_field.text().replace(" ", "_") + if not project_name: + iface.messageBar().pushMessage("Geen projectnaam opgegeven", Qgis.Critical) + else: + polder_path = self.base_path / project_name + if polder_path.is_dir(): + iface.messageBar().pushMessage(folder_exists_already, Qgis.Critical) else: - polder_path = self.base_path / project_name - if polder_path.is_dir(): - iface.messageBar().pushMessage( - folder_exists_already, Qgis.Critical - ) + try: + Folders(polder_path, create=True) + self.project_folder_path.emit(polder_path.as_posix()) + self.accept() + self.polder_path = polder_path + QMessageBox.information(None, "Create project", "Your folders are created!") + except Exception: + iface.messageBar().pushMessage(invalid_character_in_filename, Qgis.Critical) + pass + else: try: - Folders(polder_path, create=True) - self.project_folder_path.emit(polder_path.as_posix()) - self.accept() - self.polder_path = polder_path - QMessageBox.information( - None, "Create project", "Your folders are created!" - ) + full_path = "" + + # os.mkdir(str(full_path)) + # print("succes0") + + # Folders(full_path, create=True) + # print("succes1") + + # self.project_folder_path.emit(full_path) + + # self.accept() + # QMessageBox.information( + # None, "Create project", "Your folders are created!" + # ) + # self.full_path = full_path + except Exception: - iface.messageBar().pushMessage( - invalid_character_in_filename, Qgis.Critical - ) - pass - + iface.messageBar().pushMessage(invalid_character_in_filename, Qgis.Critical) + else: + print(self.reference_model_box.currentText() == ("")) try: - full_path = '' - - # os.mkdir(str(full_path)) - # print("succes0") - - # Folders(full_path, create=True) - # print("succes1") - - # self.project_folder_path.emit(full_path) - - # self.accept() - # QMessageBox.information( - # None, "Create project", "Your folders are created!" - # ) - # self.full_path = full_path - - except Exception: - iface.messageBar().pushMessage( - invalid_character_in_filename, Qgis.Critical - ) - + self.copy_files() + except: + iface.messageBar().pushMessage("Settings, sqlite of rasters niet gekopieerd", Qgis.Info) else: - print(self.reference_model_box.currentText()==("")) - try: - self.copy_files() - except: - iface.messageBar().pushMessage( - "Settings, sqlite of rasters niet gekopieerd", Qgis.Info - ) - else: - if self.reference_model_box.currentText() == (""): - iface.messageBar().pushMessage( - "Geen referentie model opgegeven", Qgis.Info - ) - pass - + if self.reference_model_box.currentText() == (""): + iface.messageBar().pushMessage("Geen referentie model opgegeven", Qgis.Info) + pass def copy_files(self): - #setting the paths + # setting the paths dockwidget = HHNK_toolboxDockWidget() base_path = Path(dockwidget.polders_map_selector.filePath()) base_path = str(base_path.parent) print(base_path + " copy_files") - if not base_path == r'E:\02.modellen': - base_path = r'E:\02.modellen' - - #base_path = self.folder_selector.filePath() + if not base_path == r"E:\02.modellen": + base_path = r"E:\02.modellen" + + # base_path = self.folder_selector.filePath() project_name = self.polder_name_field.text() print(project_name) dst = Folders(os.path.join(str(base_path), str(project_name))) print(dst) - + reference_model_base = self.reference_model_box.currentText() reference_model = reference_model_base[4:] bwn_paths = glob.glob(str(base_path + "\\cbt-[0-9]")) + glob.glob(str(base_path + "\\cbt-[0-9][0-9]")) - raster_paths = glob.glob(str(base_path + "\\cbt-[0-9]\\rasters")) + glob.glob(str(base_path + "\\cbt-[0-9][0-9]\\rasters")) - - #adjust and copy model settings + raster_paths = glob.glob(str(base_path + "\\cbt-[0-9]\\rasters")) + glob.glob( + str(base_path + "\\cbt-[0-9][0-9]\\rasters") + ) + + # adjust and copy model settings if reference_model == (""): value = "[--set raster name--]" - else: + else: value = reference_model - p = hrt.get_pkg_resource_path(package_resource=htt.resources, - name="model_settings.xslx") + p = hrt.get_pkg_resource_path(package_resource=htt.resources, name="model_settings.xslx") raw_model_settings = pd.read_excel(p, engine="openpyxl") - new_model_settings = pd.DataFrame(raw_model_settings.replace(regex=['callantsoog'], value=value)) - new_model_settings['name'] = (new_model_settings['name'] + str('_' + project_name)) + new_model_settings = pd.DataFrame(raw_model_settings.replace(regex=["callantsoog"], value=value)) + new_model_settings["name"] = new_model_settings["name"] + str("_" + project_name) new_model_settings.to_excel(dst.model.settings.base) - #copy model settings default file - p = hrt.get_pkg_resource_path(package_resource=htt.resources, - name="model_settings_default.xslx") + # copy model settings default file + p = hrt.get_pkg_resource_path(package_resource=htt.resources, name="model_settings_default.xslx") model_settings_default = pd.read_excel(p, engine="openpyxl") model_settings_default.to_excel(dst.model.settings_default.base) - + if reference_model != (""): - #searching sqlite file and copy to destination folder + # searching sqlite file and copy to destination folder for paths in bwn_paths: files = os.listdir(paths) copy_sqlite = [] for file in files: if reference_model_base in file: - if file.endswith('.sqlite'): + if file.endswith(".sqlite"): copy_sqlite.append(os.path.join(paths, file)) for files in copy_sqlite: - shutil.copy(files, os.path.join(dst.model.schema_base.path)) - - #searching raster files and copy to destination folder + shutil.copy(files, os.path.join(dst.model.schema_base.path)) + + # searching raster files and copy to destination folder for paths in raster_paths: files = os.listdir(paths) copy_rasters = [] for file in files: if reference_model in file: - if file.endswith('.tif'): - copy_rasters.append(os.path.join(paths, file)) + if file.endswith(".tif"): + copy_rasters.append(os.path.join(paths, file)) for files in copy_rasters: shutil.copy(files, os.path.join(dst.model.schema_base.rasters.path)) - - diff --git a/hhnk_threedi_plugin/gui/schematisation_splitter_uploader_dialog.py b/hhnk_threedi_plugin/gui/schematisation_splitter_uploader_dialog.py index 10adc88b..ce4d8b86 100644 --- a/hhnk_threedi_plugin/gui/schematisation_splitter_uploader_dialog.py +++ b/hhnk_threedi_plugin/gui/schematisation_splitter_uploader_dialog.py @@ -1,29 +1,28 @@ +import pandas as pd +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import ( - QPushButton, - QVBoxLayout, - QGroupBox, - QGridLayout, - QFileDialog, - QLabel, + QApplication, QCheckBox, - QFrame, - QSpacerItem, QDialog, - QSizePolicy, + QFileDialog, + QFrame, + QGridLayout, + QGroupBox, QHBoxLayout, - QApplication, + QLabel, + QPushButton, + QSizePolicy, + QSpacerItem, + QVBoxLayout, ) -from qgis.core import QgsTask, Qgis -from qgis.utils import QgsMessageLog, iface -from PyQt5.QtCore import Qt, pyqtSignal +from qgis.core import Qgis, QgsTask from qgis.gui import QgsMessageBar +from qgis.utils import QgsMessageLog, iface -import pandas as pd # from hhnk_threedi_plugin.gui.tests.verify_sqlite_tests_input import verify_input from hhnk_threedi_plugin.gui.utility.file_widget import fileWidget - def setupUi(splitter_dialog): splitter_dialog.setWindowTitle("Schematisation splitter and uploader") splitter_dialog.setMinimumWidth(500) @@ -40,9 +39,8 @@ def setupUi(splitter_dialog): splitter_dialog.schema_chk = {} splitter_dialog.upload_chk = {} - for index, row in splitter_dialog.settings_df.iterrows(): - schema_name=row['name'] + schema_name = row["name"] # Schematisation name labels splitter_dialog.schema_label[schema_name] = QLabel(f"{schema_name}") @@ -54,7 +52,7 @@ def setupUi(splitter_dialog): # Upload checkboxes splitter_dialog.upload_chk[schema_name] = QCheckBox("") splitter_dialog.upload_chk[schema_name].setObjectName(f"upload_{schema_name}_chk") - + selection_label = QLabel("Selecteer schematisaties") selection_layout = QGridLayout() selection_layout.setAlignment(Qt.AlignTop) @@ -67,15 +65,12 @@ def setupUi(splitter_dialog): rows = len(splitter_dialog.schema_chk) for index, row in splitter_dialog.settings_df.iterrows(): - schema_name=row['name'] - selection_layout.addWidget(splitter_dialog.schema_label[schema_name], index+1, 0) - selection_layout.addWidget(splitter_dialog.schema_chk[schema_name], index+1, 1) - selection_layout.addWidget(splitter_dialog.upload_chk[schema_name], index+1, 2) - - splitter_dialog.browse_btn = fileWidget( - file_dialog_title="Blabla", file_mode=QFileDialog.Directory - ) + schema_name = row["name"] + selection_layout.addWidget(splitter_dialog.schema_label[schema_name], index + 1, 0) + selection_layout.addWidget(splitter_dialog.schema_chk[schema_name], index + 1, 1) + selection_layout.addWidget(splitter_dialog.upload_chk[schema_name], index + 1, 2) + splitter_dialog.browse_btn = fileWidget(file_dialog_title="Blabla", file_mode=QFileDialog.Directory) main_layout = QVBoxLayout() main_layout.setAlignment(Qt.AlignTop) @@ -87,9 +82,9 @@ def setupUi(splitter_dialog): main_layout.addWidget(splitter_dialog.start_upload_btn) main_layout.addWidget(splitter_dialog.browse_btn) - splitter_dialog.setLayout(main_layout) + class schematisationDialog(QDialog): """ Initialization: @@ -107,19 +102,18 @@ class schematisationDialog(QDialog): def __init__(self, caller, parent): super(schematisationDialog, self).__init__(parent) self.caller = caller - self.setStyleSheet(""" + self.setStyleSheet( + """ QCheckBox::indicator { width: 30px; height: 30px }""" ) - + def set_current_paths(self): self.settings_df = pd.read_excel(self.caller.fenv.model.settings.path, engine="openpyxl") - - setupUi(self) - + setupUi(self) # %% diff --git a/hhnk_threedi_plugin/gui/sql_preview/model_changes_preview.py b/hhnk_threedi_plugin/gui/sql_preview/model_changes_preview.py index 117e3792..54db47aa 100644 --- a/hhnk_threedi_plugin/gui/sql_preview/model_changes_preview.py +++ b/hhnk_threedi_plugin/gui/sql_preview/model_changes_preview.py @@ -1,8 +1,8 @@ import numpy as np -from PyQt5.QtWidgets import QTableView, QWidget, QVBoxLayout, QLabel, QLineEdit -from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel -from PyQt5.QtGui import QColor from hhnk_threedi_tools.variables.definitions import proposed_value_col +from PyQt5.QtCore import QAbstractTableModel, QSortFilterProxyModel, Qt, QVariant +from PyQt5.QtGui import QColor +from PyQt5.QtWidgets import QLabel, QLineEdit, QTableView, QVBoxLayout, QWidget class pandasModel(QAbstractTableModel): @@ -72,8 +72,7 @@ def data(self, index, role=Qt.DisplayRole): if ( role == Qt.BackgroundRole and index.column() == self.old_col_idx - and self._data.iloc[index.row(), self.id_col_ind] - not in self.delete_rows_ids + and self._data.iloc[index.row(), self.id_col_ind] not in self.delete_rows_ids ): return self.red if self.new_col_idx is not None: @@ -81,25 +80,16 @@ def data(self, index, role=Qt.DisplayRole): if ( role == Qt.BackgroundRole and index.column() == self.new_col_idx - and self._data.iloc[index.row(), self.id_col_ind] - not in self.delete_rows_ids + and self._data.iloc[index.row(), self.id_col_ind] not in self.delete_rows_ids ): return self.green if self.delete_rows_ids is not None: """Rows to be deleted are coloured red""" - if ( - role == Qt.BackgroundRole - and self._data.iloc[index.row(), self.id_col_ind] - in self.delete_rows_ids - ): + if role == Qt.BackgroundRole and self._data.iloc[index.row(), self.id_col_ind] in self.delete_rows_ids: return self.red if self.add_rows_ids is not None: """Rows to be added are coloured green""" - if ( - role == Qt.BackgroundRole - and self._data.iloc[index.row(), self.id_col_ind] - in self.add_rows_ids - ): + if role == Qt.BackgroundRole and self._data.iloc[index.row(), self.id_col_ind] in self.add_rows_ids: return self.green return QVariant() @@ -146,9 +136,7 @@ def convert_to_type(type_val, val): if role == Qt.EditRole: """If the cell is editable, we receive the new data as a string, then try to convert it to the type of the column""" - self._data.iloc[row, column] = convert_to_type( - type(self._data.iloc[row, column]), value - ) + self._data.iloc[row, column] = convert_to_type(type(self._data.iloc[row, column]), value) self.dataChanged.emit(index, index) return True return False @@ -161,13 +149,11 @@ def flags(self, index): if ( ( self.delete_rows_ids is not None - and self._data.iloc[index.row(), self.id_col_ind] - in self.delete_rows_ids + and self._data.iloc[index.row(), self.id_col_ind] in self.delete_rows_ids ) or ( self.add_rows_ids is not None - and self._data.iloc[index.row(), self.id_col_ind] - in self.add_rows_ids + and self._data.iloc[index.row(), self.id_col_ind] in self.add_rows_ids ) or self.new_col_editable ): @@ -175,10 +161,7 @@ def flags(self, index): if ( index.column() == self.new_col_idx and self.new_col_editable - and ( - not self.add_rows_ids - or self._data.iloc[index.row(), self.id_col_ind] in self.add_rows_ids - ) + and (not self.add_rows_ids or self._data.iloc[index.row(), self.id_col_ind] in self.add_rows_ids) ): """If cells are in the column containing new values and that column is editable, make te cell editable if we are not adding rows. If we are adding rows, we first make sure the id is in the rows @@ -293,9 +276,7 @@ def __init__( layout.addWidget(description_label) if self.searchable: """Implements the actual searching functionality""" - self.search_bar.textChanged.connect( - lambda: self.proxy_model.setFilterRegExp(f"{self.search_bar.text()}") - ) + self.search_bar.textChanged.connect(lambda: self.proxy_model.setFilterRegExp(f"{self.search_bar.text()}")) layout.addWidget(self.search_bar_label) layout.addWidget(self.search_bar) layout.addWidget(self.view) @@ -307,9 +288,7 @@ def return_changed_value_rows(self): as well as the rows that were excluded from updating """ if self.rows_selectable or self.new_col_editable: - protected_ids = ( - self.df[~self.df["select"]].iloc[:, self.id_col_idx].tolist() - ) + protected_ids = self.df[~self.df["select"]].iloc[:, self.id_col_idx].tolist() self.protected_ids_list = protected_ids if self.new_col_editable: @@ -317,7 +296,5 @@ def return_changed_value_rows(self): combine = self.df combine[proposed_value_col] = self.df_before[new_val_col] changed_rows = combine[combine[new_val_col] != combine[proposed_value_col]] - changed_rows = changed_rows[ - ~changed_rows[self.id_col].isin(self.protected_ids_list) - ] + changed_rows = changed_rows[~changed_rows[self.id_col].isin(self.protected_ids_list)] self.manual_changes_df = changed_rows diff --git a/hhnk_threedi_plugin/gui/threedi/confirm_rain_scenario_loaded.py b/hhnk_threedi_plugin/gui/threedi/confirm_rain_scenario_loaded.py index 4b4c81e2..bdf5ceab 100644 --- a/hhnk_threedi_plugin/gui/threedi/confirm_rain_scenario_loaded.py +++ b/hhnk_threedi_plugin/gui/threedi/confirm_rain_scenario_loaded.py @@ -1,7 +1,7 @@ -from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas +import matplotlib as mplt import matplotlib.pyplot as plt +from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure -import matplotlib as mplt from PyQt5 import QtWidgets @@ -16,9 +16,7 @@ def __init__(self, parent=None, window_title="3di scenario regen", **kwargs): self.setWindowTitle(window_title) layout = QtWidgets.QVBoxLayout() self.canvas = FigureCanvas(self.figure) - self.button_box = QtWidgets.QDialogButtonBox( - QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel - ) + self.button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) layout.addWidget(self.canvas) diff --git a/hhnk_threedi_plugin/gui/utility/file_widget.py b/hhnk_threedi_plugin/gui/utility/file_widget.py index 8b126685..ac8c40e2 100644 --- a/hhnk_threedi_plugin/gui/utility/file_widget.py +++ b/hhnk_threedi_plugin/gui/utility/file_widget.py @@ -1,15 +1,14 @@ # %% +from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import ( QFileDialog, - QPushButton, - QLineEdit, QHBoxLayout, - QWidget, QLabel, + QLineEdit, + QPushButton, QVBoxLayout, + QWidget, ) -from PyQt5.QtCore import Qt -from PyQt5.QtCore import pyqtSignal class fileWidget(QWidget): @@ -26,9 +25,7 @@ class fileWidget(QWidget): """ fileSelected = pyqtSignal(str) - def __init__( - self, file_dialog_title, file_mode, name_filter=None, select_text=None - ): + def __init__(self, file_dialog_title, file_mode, name_filter=None, select_text=None): super(fileWidget, self).__init__() # ---------------------------------------------------------- # Widgets @@ -59,15 +56,11 @@ def __init__( # To prevent the cursor jumping back to the end of the line while the user is typing, we save and # reset the cursor every time a character is typed self.file_selected_edit.textChanged.connect(self.save_cursor_position) - self.file_selected_edit.textChanged.connect( - lambda: self.fileSelected.emit(self.file_selected_edit.text()) - ) + self.file_selected_edit.textChanged.connect(lambda: self.fileSelected.emit(self.file_selected_edit.text())) self.file_selected_edit.textChanged.connect(self.set_cursor_position) # If a file is chosen with the file dialog, save the path to that directory and open the file dialog there # next time - self.file_dialog.fileSelected.connect( - lambda: self.file_dialog.setDirectory(self.file_dialog.directory()) - ) + self.file_dialog.fileSelected.connect(lambda: self.file_dialog.setDirectory(self.file_dialog.directory())) # Handle layout layout = QHBoxLayout() diff --git a/hhnk_threedi_plugin/gui/utility/widget_interaction.py b/hhnk_threedi_plugin/gui/utility/widget_interaction.py index 1e20da43..8d0eee3f 100644 --- a/hhnk_threedi_plugin/gui/utility/widget_interaction.py +++ b/hhnk_threedi_plugin/gui/utility/widget_interaction.py @@ -3,8 +3,8 @@ def update_button_background(button, color=None): if color is None: - #reset button to default style + # reset button to default style button.setStyleSheet(f"QPushButton") else: button.setStyleSheet(f"QPushButton {'{'}background-color: {color}; color:black{'}'}") - QApplication.processEvents() \ No newline at end of file + QApplication.processEvents() diff --git a/hhnk_threedi_plugin/hhnk_toolbox.py b/hhnk_threedi_plugin/hhnk_toolbox.py index df4f95a2..c4f71b3c 100644 --- a/hhnk_threedi_plugin/hhnk_toolbox.py +++ b/hhnk_threedi_plugin/hhnk_toolbox.py @@ -21,69 +21,72 @@ * * ***************************************************************************/ """ +import datetime import os.path from pathlib import Path + from pyexpat import model -from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, Qt +from qgis.core import Qgis, QgsApplication, QgsProject, QgsVectorLayer +from qgis.PyQt.QtCore import QCoreApplication, QSettings, Qt, QTranslator from qgis.PyQt.QtGui import QIcon from qgis.PyQt.QtWidgets import QAction, QMessageBox -from qgis.core import QgsApplication, Qgis, QgsProject, QgsVectorLayer from qgis.utils import QgsMessageLog, showPluginHelp -import datetime # Initialize Qt resources from file resources.py from hhnk_threedi_plugin.resources import * + # Import the code for the DockWidget # %% -try: +try: import hhnk_threedi_plugin.local_settings as local_settings except ModuleNotFoundError: import hhnk_threedi_plugin.local_settings_default as local_settings # Import the code for the plugin content # GUI -from hhnk_threedi_plugin.hhnk_toolbox_dockwidget import HHNK_toolboxDockWidget -from hhnk_threedi_plugin.gui.load_layers_popup import loadLayersDialog -# from hhnk_threedi_plugin.gui.schematisation_splitter_uploader_dialog import schematisationDialog -from hhnk_threedi_plugin.gui.checks.sqlite_check_popup import sqliteCheckDialog -from hhnk_threedi_plugin.gui.checks.zero_d_one_d import zeroDOneDWidget -from hhnk_threedi_plugin.gui.checks.one_d_two_d import oneDTwoDWidget -#from hhnk_threedi_plugin.gui.model_states.model_states import modelStateDialog -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.main_result_widget import collapsibleTree -from hhnk_threedi_plugin.gui.checks.bank_levels import bankLevelsWidget -from hhnk_threedi_plugin.gui.klimaatsommen.klimaatsommen import KlimaatSommenWidget -from hhnk_threedi_plugin.qgis_interaction.project import Project -from hhnk_threedi_plugin.gui.new_project_dialog import newProjectDialog -from hhnk_threedi_plugin.gui.input_data import inputDataDialog -from hhnk_threedi_plugin.qgis_interaction.open_notebook import NotebookWidget +import os -from hhnk_threedi_plugin.gui.modelbuilder import ModelBuilder +# docs +import webbrowser +import hhnk_research_tools as hrt +import hhnk_threedi_tools.core.schematisation.upload as upload # %% # Functions from hhnk_threedi_tools.core.folders import Folder, Folders -# from hhnk_threedi_tools.core.checks.model_state import detect_model_states +# from hhnk_threedi_tools.core.checks.model_state import detect_model_states # Variables from hhnk_threedi_tools.variables.model_state import invalid_path -import hhnk_threedi_tools.core.schematisation.upload as upload - -from hhnk_threedi_plugin.tasks.task_sqlite_tests_main import task_sqlite_tests_main - -import os - -from hhnk_threedi_plugin.gui.model_splitter.model_splitter_dialog import modelSplitterDialog -import hhnk_research_tools as hrt - +from hhnk_threedi_plugin.gui.checks.bank_levels import bankLevelsWidget +from hhnk_threedi_plugin.gui.checks.one_d_two_d import oneDTwoDWidget -# docs +# from hhnk_threedi_plugin.gui.schematisation_splitter_uploader_dialog import schematisationDialog +from hhnk_threedi_plugin.gui.checks.sqlite_check_popup import sqliteCheckDialog -import webbrowser +# from hhnk_threedi_plugin.gui.model_states.model_states import modelStateDialog +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.main_result_widget import ( + collapsibleTree, +) +from hhnk_threedi_plugin.gui.checks.zero_d_one_d import zeroDOneDWidget +from hhnk_threedi_plugin.gui.input_data import inputDataDialog +from hhnk_threedi_plugin.gui.klimaatsommen.klimaatsommen import KlimaatSommenWidget +from hhnk_threedi_plugin.gui.load_layers_popup import loadLayersDialog +from hhnk_threedi_plugin.gui.model_splitter.model_splitter_dialog import ( + modelSplitterDialog, +) +from hhnk_threedi_plugin.gui.modelbuilder import ModelBuilder +from hhnk_threedi_plugin.gui.new_project_dialog import newProjectDialog +from hhnk_threedi_plugin.hhnk_toolbox_dockwidget import HHNK_toolboxDockWidget +from hhnk_threedi_plugin.qgis_interaction.open_notebook import NotebookWidget +from hhnk_threedi_plugin.qgis_interaction.project import Project +from hhnk_threedi_plugin.tasks.task_sqlite_tests_main import task_sqlite_tests_main DOCS_LINK = "https://threedi.github.io/hhnk-threedi-plugin/" + class HHNK_toolbox: """QGIS Plugin Implementation.""" @@ -105,10 +108,8 @@ def __init__(self, iface): # initialize locale locale = QSettings().value("locale/userLocale") if locale is not None: - locale_path = os.path.join( - self.plugin_dir, "i18n", "HHNK_threedi_toolbox_{}.qm".format(locale[0:2]) - ) - + locale_path = os.path.join(self.plugin_dir, "i18n", "HHNK_threedi_toolbox_{}.qm".format(locale[0:2])) + if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) @@ -116,10 +117,10 @@ def __init__(self, iface): # Declare instance attributes self.actions = [] - self.menu = self.tr(u"&HHNK threedi toolbox") + self.menu = self.tr("&HHNK threedi toolbox") # TODO: We are going to let the user set this up in a future iteration - self.toolbar = self.iface.addToolBar(u"hhnk_threedi_plugin") - self.toolbar.setObjectName(u"hhnk_threedi_plugin") + self.toolbar = self.iface.addToolBar("hhnk_threedi_plugin") + self.toolbar.setObjectName("hhnk_threedi_plugin") # print "** INITIALIZING HHNK_toolbox" @@ -139,7 +140,7 @@ def __init__(self, iface): self.modelbuilder = None self.debug = local_settings.DEBUG - + @property def polders_path(self): if self.dockwidget.polders_map_selector.filePath(): @@ -244,10 +245,12 @@ def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = os.path.join(self.plugin_dir, "icons/hhnk_logo.jpg") - help_path = os.path.join(self.plugin_dir, "icons/help_icon.png") #":/plugins/hhnk_toolbox/icons/help_icon.png" + help_path = os.path.join( + self.plugin_dir, "icons/help_icon.png" + ) # ":/plugins/hhnk_toolbox/icons/help_icon.png" self.add_action( icon_path, - text=self.tr(u"HHNK Threedi Plugin"), + text=self.tr("HHNK Threedi Plugin"), callback=self.run, parent=self.iface.mainWindow(), ) @@ -258,7 +261,7 @@ def initGui(self): parent=self.iface.mainWindow(), add_to_toolbar=True, ) - + # -------------------------------------------------------------------------- def onClosePlugin(self): @@ -272,6 +275,12 @@ def onClosePlugin(self): # for reuse if plugin is reopened # Commented next statement since it causes QGIS crashe # when closing the docked window: + # TODO dit fixed nog steeds niet de window size problemen. + try: + self.dockwidget.close() + except AttributeError: + print("closing plugin failed. dockwidget already None?") + # self.dockwidget = None self.pluginIsActive = False @@ -279,8 +288,9 @@ def onClosePlugin(self): def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" # print "** UNLOAD HHNK_toolbox" + for action in self.actions: - self.iface.removePluginMenu(self.tr(u"&HHNK threedi toolbox"), action) + self.iface.removePluginMenu(self.tr("&HHNK threedi toolbox"), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar @@ -298,14 +308,10 @@ def reset_ui(self, polder=None, model=None): and self.model_states_results_widget.isVisible() ): self.model_states_results_widget.close() - if ( - self.bank_levels is not None - and self.bank_levels - and self.bank_levels.isVisible() - ): - self.bank_levels.close() + if self.bank_levels is not None and self.bank_levels and self.bank_levels.isVisible(): + self.bank_levels.close() - # Select from the dockwidget the path where the polder is located. If the path is not correct or if it is empty I will not enabled the buttons + # Select from the dockwidget the path where the polder is located. If the path is not correct or if it is empty I will not enabled the buttons def polders_folder_changed(self): """ Updates polder_selector from the contents of the path in polders_map_selector @@ -321,9 +327,8 @@ def polders_folder_changed(self): folder = Folder(path) # clean the contents (only accept valid Folders directories) - items = [i.name for i in folder.content if Folders.is_valid(Path(path)/i)] + items = [i.name for i in folder.content if Folders.is_valid(Path(path) / i)] - # add items to the polder_selector self.dockwidget.polder_selector.clear() if items: @@ -335,7 +340,6 @@ def polders_folder_changed(self): if self.debug: self.add_message("polders_folder_changed end") - def polder_changed(self): """ If a new polder is selected, based on validity of provided path: @@ -353,7 +357,7 @@ def polder_changed(self): self.reset_ui(polder=polder) if (polder != "") and path.exists(): folder = Folders(path) - self.fenv = folder #FIXME replace with self.folder in all scripts. + self.fenv = folder # FIXME replace with self.folder in all scripts. self.folder = folder self.polder_folder = path.as_posix() self.current_source_paths = folder.to_file_dict() @@ -364,7 +368,7 @@ def polder_changed(self): else: self.initialize_current_paths() else: - self.fenv=None + self.fenv = None self.folder = None self.polder_folder = None # TODO: verify if deleting the commented block with self.current_source_paths = None is a good idea @@ -380,14 +384,12 @@ def polder_changed(self): if self.debug: self.add_message("polder_changed end") - - def initialize_current_paths(self): """ When we create the default paths dict, set values to all widgets """ self.load_layers_dialog.set_current_paths() - #self.model_states_dialog.set_current_paths() + # self.model_states_dialog.set_current_paths() # self.sqlite_tests_dialog.set_current_paths() # self.zero_d_one_d.set_current_paths() # self.one_d_two_d.set_current_paths() @@ -447,7 +449,7 @@ def update_current_paths( if dem is not None: self.current_source_paths["dem"] = dem - #self.sqlite_tests_dialog.dem_selector.setFilePath(dem) + # self.sqlite_tests_dialog.dem_selector.setFilePath(dem) # self.input_data_dialog.dem_selector.setFilePath(dem) # self.one_d_two_d.dem_selector.setFilePath(dem) @@ -461,7 +463,7 @@ def update_current_paths( if sqlite_output is not None: self.current_source_paths["sqlite_tests_output"] = sqlite_output - + if zero_d_output is not None: self.current_source_paths["0d1d_output"] = zero_d_output if bank_levels_output is not None: @@ -472,37 +474,33 @@ def update_current_paths( # self.input_data_dialog.output_selector.setFilePath(one_d_output) # self.one_d_two_d.output_selector.setFilePath(one_d_output) - # -------------------------------------------------------------------------- # Start tests and conversions # -------------------------------------------------------------------------- def sqlite_tests_execution(self, selected_tests): try: # test_env.polder_folder = self.polder_folder - task_sqlite_tests_main(parent_widget=self.sqlite_results_widget, folder=self.fenv, selected_tests=selected_tests) + task_sqlite_tests_main( + parent_widget=self.sqlite_results_widget, folder=self.fenv, selected_tests=selected_tests + ) except Exception as e: self.iface.messageBar().pushMessage(str(e), Qgis.Critical) pass - def new_project_folder_execute(self): dialog = newProjectDialog(self.polders_path) result = dialog.exec() if result: if dialog.polder_path is not None: self.dockwidget.polder_selector.addItem(dialog.polder_path.name) - self.dockwidget.polder_selector.setCurrentText( - dialog.polder_path.name - ) - + self.dockwidget.polder_selector.setCurrentText(dialog.polder_path.name) def open_model_splitter_dialog(self): - if not hasattr(self, 'model_splitter_dialog'): + if not hasattr(self, "model_splitter_dialog"): self.model_splitter_dialog = modelSplitterDialog(caller=self, parent=self.dockwidget) self.model_splitter_dialog.show() - def open_documentatie_link(self): webbrowser.open(DOCS_LINK, new=2) @@ -510,18 +508,17 @@ def open_help(self): os.startfile(self.help_address) def hide_apikeys_lizard(self): - getattr(self.dockwidget, f'lizard_api_key_textbox').setEchoMode(2) #password echo mode + getattr(self.dockwidget, f"lizard_api_key_textbox").setEchoMode(2) # password echo mode def hide_apikeys_threedi(self): - #TODO kan connect input meegeven zodat deze samen kan met lizard? - getattr(self.dockwidget, f'threedi_api_key_textbox').setEchoMode(2) #password echo mode + # TODO kan connect input meegeven zodat deze samen kan met lizard? + getattr(self.dockwidget, f"threedi_api_key_textbox").setEchoMode(2) # password echo mode def get_org_names(self): - if self.debug: self.add_message("org names start") - api_key = getattr(self.dockwidget, f'threedi_api_key_textbox').text() + api_key = getattr(self.dockwidget, f"threedi_api_key_textbox").text() self.dockwidget.org_name_comboBox.clear() try: organisation_names = upload.get_organisation_names(api_key) @@ -529,10 +526,9 @@ def get_org_names(self): self.dockwidget.org_name_comboBox.addItem(str(i)) except: self.iface.messageBar().pushMessage( - 'no organisation names available - check 3Di api_key and permissions', - level=Qgis.Warning - ) - + "no organisation names available - check 3Di api_key and permissions", level=Qgis.Warning + ) + if self.debug: self.add_message("org names done") @@ -555,16 +551,14 @@ def run(self): self.dockwidget = HHNK_toolboxDockWidget() - # disable predefined buttons + # disable predefined buttons self.enable_buttons(False) # self.dockwidget.load_layers_btn.setEnabled(False) - self.dockwidget.lizard_api_key_textbox.textChanged.connect(self.hide_apikeys_lizard) self.dockwidget.threedi_api_key_textbox.textChanged.connect(self.hide_apikeys_threedi) self.dockwidget.threedi_api_key_textbox.textChanged.connect(self.get_org_names) - self.load_layers_dialog = loadLayersDialog(caller=self, parent=self.dockwidget) self.sqlite_tests_dialog = sqliteCheckDialog(caller=self, parent=self.dockwidget) @@ -577,7 +571,6 @@ def run(self): self.one_d_two_d = oneDTwoDWidget(caller=self, parent=self.dockwidget) self.klimaatsommen = KlimaatSommenWidget(caller=self, parent=self.dockwidget) self.notebook_widget = NotebookWidget(caller=self, parent=self.dockwidget) - # If a polder folder is selected self.dockwidget.polders_map_selector.fileChanged.connect(self.polders_folder_changed) @@ -593,7 +586,9 @@ def run(self): # Connect popups to buttons that prompt them self.dockwidget.load_layers_btn.clicked.connect(self.load_layers_dialog.set_current_paths) - self.dockwidget.load_layers_btn.clicked.connect(self.load_layers_dialog.exec) # exec dwingt af dat je 1 window open kan hebben. + self.dockwidget.load_layers_btn.clicked.connect( + self.load_layers_dialog.exec + ) # exec dwingt af dat je 1 window open kan hebben. self.dockwidget.start_sqlite_check.clicked.connect(self.sqlite_tests_dialog.set_current_paths) self.dockwidget.start_sqlite_check.clicked.connect(self.sqlite_tests_dialog.show) @@ -601,10 +596,9 @@ def run(self): self.dockwidget.input_btn.clicked.connect(self.input_data_dialog.show) self.dockwidget.model_splitter_btn.clicked.connect(self.open_model_splitter_dialog) self.dockwidget.create_new_project_btn.clicked.connect(self.new_project_folder_execute) - + # self.dockwidget.documentatie_button.clicked.connect(self.open_documentatie_link) self.dockwidget.server_btn.clicked.connect(self.notebook_widget.start_server) - # Connect start buttons to appropriate function calls @@ -614,11 +608,11 @@ def run(self): # define modelbuilder. Note, all callbacks and functions you can find in ModelBuilder class self.modelbuilder = ModelBuilder(dockwidget=self.dockwidget) - + # note that for 'klimaatsomme # n' functions are run from the widget # self.dlg = modelSplitterDialog(caller=self) - + # connect to provide cleanup on closing of dockwidget self.dockwidget.closingPlugin.connect(self.onClosePlugin) @@ -627,16 +621,14 @@ def run(self): self.iface.addTabifiedDockWidget(Qt.RightDockWidgetArea, self.dockwidget, raiseTab=True) self.dockwidget.show() - #set project_path from local_settings. + # set project_path from local_settings. try: self.dockwidget.polders_map_selector.setFilePath(local_settings.project_path) except: pass - #TODO centraal ergens zetten? + # TODO centraal ergens zetten? def add_message(self, message): message = f"{hrt.current_time()}: {message}" # QgsMessageLog.logMessage(message, level=level) print(message) - - \ No newline at end of file diff --git a/hhnk_threedi_plugin/hhnk_toolbox_dockwidget.py b/hhnk_threedi_plugin/hhnk_toolbox_dockwidget.py index f4300293..c3ba38c7 100644 --- a/hhnk_threedi_plugin/hhnk_toolbox_dockwidget.py +++ b/hhnk_threedi_plugin/hhnk_toolbox_dockwidget.py @@ -27,13 +27,10 @@ from qgis.PyQt import QtGui, QtWidgets, uic from qgis.PyQt.QtCore import pyqtSignal -FORM_CLASS, _ = uic.loadUiType( - os.path.join(os.path.dirname(__file__), "hhnk_toolbox_dockwidget_base.ui") -) +FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), "hhnk_toolbox_dockwidget_base.ui")) class HHNK_toolboxDockWidget(QtWidgets.QDockWidget, FORM_CLASS): - closingPlugin = pyqtSignal() def __init__(self, parent=None): diff --git a/hhnk_threedi_plugin/local_settings_default.py b/hhnk_threedi_plugin/local_settings_default.py index 482c879a..37982084 100644 --- a/hhnk_threedi_plugin/local_settings_default.py +++ b/hhnk_threedi_plugin/local_settings_default.py @@ -1,8 +1,10 @@ -#rename to local_settings.py -import os +# rename to local_settings.py +import os -DEBUG=False +DEBUG = False -threeditoolbox_path = os.path.join(os.getenv('APPDATA'), r'3Di\QGIS3\profiles\default\python\plugins\ThreeDiToolbox\deps') +threeditoolbox_path = os.path.join( + os.getenv("APPDATA"), r"3Di\QGIS3\profiles\default\python\plugins\ThreeDiToolbox\deps" +) project_path = None diff --git a/hhnk_threedi_plugin/patches/downloader.py b/hhnk_threedi_plugin/patches/downloader.py index 571500a3..b8425ee2 100644 --- a/hhnk_threedi_plugin/patches/downloader.py +++ b/hhnk_threedi_plugin/patches/downloader.py @@ -1,15 +1,16 @@ # -*- coding: utf-8 -*- """PATCH: create_raster_task -> bbox""" """The downloader part of the threedi_scenario_downloader supplies the user with often used functionality to look up and export 3Di results using the Lizard API""" -from datetime import datetime, timedelta -from urllib.parse import urlparse -from urllib.error import HTTPError -from time import sleep +import csv import logging +import math import os +from datetime import datetime, timedelta +from time import sleep +from urllib.error import HTTPError +from urllib.parse import urlparse + import requests -import csv -import math LIZARD_URL = "https://demo.lizard.net/api/v4/" RESULT_LIMIT = 10 @@ -30,21 +31,21 @@ "offset": "offset", } -#results endpoint +# results endpoint WATER_DEPTH = "depth-dtri" MAX_WATER_DEPTH = "depth-max-dtri" WATER_LEVEL = "s1-dtri" RATE_OF_RISE = "rise-velocity-quad" PRECIPITATION = "rain-quad" -#basic sub-endpoint +# basic sub-endpoint MAX_FLOW_VELOCITY = "ucr-max-quad" MAX_WATER_LEVEL = "s1-max-dtri" -#arrival sub-endpoint +# arrival sub-endpoint ARRIVAL_TIME = "depth-first-dtri" -#damage sub-endpoint +# damage sub-endpoint TOTAL_DAMAGE = "total-damage" @@ -184,9 +185,7 @@ def get_logging_link(scenario_uuid): def get_raster_url(scenario_uuid, raster_code, subendpoint=None): - result_list = get_scenario_instance_results( - scenario_uuid=scenario_uuid, subendpoint=subendpoint - ) + result_list = get_scenario_instance_results(scenario_uuid=scenario_uuid, subendpoint=subendpoint) for result in result_list: if result["code"] == raster_code: @@ -197,20 +196,19 @@ def get_raster_url(scenario_uuid, raster_code, subendpoint=None): def get_raster(scenario_uuid, raster_code, subendpoint=None): """return json of raster based on scenario uuid and raster type""" - raster_url = get_raster_url( - scenario_uuid=scenario_uuid, raster_code=raster_code, subendpoint=subendpoint - ) + raster_url = get_raster_url(scenario_uuid=scenario_uuid, raster_code=raster_code, subendpoint=subendpoint) - r = requests.get(url=raster_url, auth=("__key__", get_api_key()),) + r = requests.get( + url=raster_url, + auth=("__key__", get_api_key()), + ) r.raise_for_status() raster = r.json() return raster -def create_raster_task( - raster, scenario_instance, projection=None, resolution=None, bbox=None, time=None -): +def create_raster_task(raster, scenario_instance, projection=None, resolution=None, bbox=None, time=None): """create Lizard raster task""" if bbox is None: x1 = scenario_instance["origin_x"] @@ -218,8 +216,7 @@ def create_raster_task( x2 = scenario_instance["upper_bound_x"] y2 = scenario_instance["upper_bound_y"] else: - x1,y1,x2,y2 = [float(i) for i in bbox.split(',')] - + x1, y1, x2, y2 = [float(i) for i in bbox.split(",")] if projection is None: projection = raster["projection"] @@ -304,7 +301,6 @@ def download_task(task_uuid, pathname=None): if get_task_status(task_uuid) == "SUCCESS": download_url = get_task_download_url(task_uuid) if pathname is None: - logging.debug("download_url: {}".format(download_url)) logging.debug("urlparse(download_url): {}".format(urlparse(download_url))) pathname = os.path.basename(urlparse(download_url).path) @@ -328,6 +324,7 @@ def download_raster( To download multiple rasters at the same time, simply pass the required input parameters as list. Scenario and pathname should be of same length. Other paramerts can be tuple to apply the same settings to all rasters. """ + # If task is called for single raster, prepare list. def transform_to_list(var, length=1): """Transform input to list if for instance only one input is given""" @@ -347,9 +344,7 @@ def transform_to_list(var, length=1): bbox_list = transform_to_list(var=bbox, length=len(scenario_list)) time_list = transform_to_list(var=time, length=len(scenario_list)) pathname_list = transform_to_list(var=pathname) - is_threedi_scenario_list = transform_to_list( - var=is_threedi_scenario, length=len(scenario_list) - ) + is_threedi_scenario_list = transform_to_list(var=is_threedi_scenario, length=len(scenario_list)) # Helper parameters. processed_list = transform_to_list(var=False, length=len(scenario_list)) @@ -389,7 +384,6 @@ def transform_to_list(var, length=1): is_threedi_scenario_list, ): if is_threedi_scenario: - if type(scenario) is str: # assume 'scenario' is an uuid scenario_instance = get_scenario_instance(scenario) @@ -402,14 +396,10 @@ def transform_to_list(var, length=1): scenario_instance = scenario subendpoint = subendpoint_per_raster_code.get(raster_code) - raster = get_raster_from_json( - scenario, raster_code, subendpoint=subendpoint - ) + raster = get_raster_from_json(scenario, raster_code, subendpoint=subendpoint) else: logging.debug("Invalid scenario: supply a json object or uuid string") - raise ValueError( - "Invalid scenario: supply a json object or uuid string" - ) + raise ValueError("Invalid scenario: supply a json object or uuid string") else: # If no bbox are passed the function will probably crash. if (type(scenario) is str) and (bbox is not None): @@ -445,52 +435,36 @@ def transform_to_list(var, length=1): task_export = [] # Create a list with task url's and pathnames - for (index, task_id), task_url, pathname in zip( - enumerate(task_id_list), task_url_list, pathname_list - ): + for (index, task_id), task_url, pathname in zip(enumerate(task_id_list), task_url_list, pathname_list): task_export.append({"uuid": task_id, "url": task_url, "pathname": pathname}) logging.debug("task_export: {}".format(task_export)) with open(export_task_csv, "w", newline="") as f: - # using csv.writer method from CSV package field_names = ["uuid", "url", "pathname"] - writer = csv.DictWriter( - f, field_names, delimiter=",", quotechar="|", quoting=csv.QUOTE_MINIMAL - ) + writer = csv.DictWriter(f, field_names, delimiter=",", quotechar="|", quoting=csv.QUOTE_MINIMAL) writer.writeheader() writer.writerows(task_export) # Check status of task and download while not all(processed_list): - for (index, task_uuid), pathname, processed in zip( - enumerate(task_id_list), pathname_list, processed_list - ): + for (index, task_uuid), pathname, processed in zip(enumerate(task_id_list), pathname_list, processed_list): if not processed: - task_status = get_task_status(task_uuid) if task_status == "SUCCESS": # task is a succes, return download url try: logging.debug( - "Task succeeded, start downloading url: {}".format( - get_task_download_url(task_uuid) - ) - ) - logging.debug( - "Remaining tasks: {}".format( - processed_list.count(False) - 1 - ) + "Task succeeded, start downloading url: {}".format(get_task_download_url(task_uuid)) ) + logging.debug("Remaining tasks: {}".format(processed_list.count(False) - 1)) download_task(task_uuid, pathname) processed_list[index] = True except HTTPError as err: if err.code == 503: - logging.debug( - "503 Server Error: Lizard has lost it. Let's ignore this." - ) + logging.debug("503 Server Error: Lizard has lost it. Let's ignore this.") task_status = "UNKNOWN" else: raise @@ -498,16 +472,12 @@ def transform_to_list(var, length=1): elif task_status in ("PENDING", "UNKNOWN", "STARTED", "RETRY"): pass else: - logging.debug( - "Task {} failed, status was: {}".format(task_uuid, task_status) - ) + logging.debug("Task {} failed, status was: {}".format(task_uuid, task_status)) processed_list[index] = True sleep(5) -def download_maximum_waterdepth_raster( - scenario_uuid, projection=None, resolution=None, bbox=None, pathname=None -): +def download_maximum_waterdepth_raster(scenario_uuid, projection=None, resolution=None, bbox=None, pathname=None): """download Maximum waterdepth raster""" download_raster( scenario_uuid, @@ -519,9 +489,7 @@ def download_maximum_waterdepth_raster( ) -def download_maximum_waterlevel_raster( - scenario_uuid, projection=None, resolution=None, bbox=None, pathname=None -): +def download_maximum_waterlevel_raster(scenario_uuid, projection=None, resolution=None, bbox=None, pathname=None): """download Maximum waterlevel raster""" download_raster( scenario_uuid, @@ -533,9 +501,7 @@ def download_maximum_waterlevel_raster( ) -def download_maximum_flow_velocity_raster( - scenario_uuid, projection=None, resolution=None, bbox=None, pathname=None -): +def download_maximum_flow_velocity_raster(scenario_uuid, projection=None, resolution=None, bbox=None, pathname=None): """download Maximum waterdepth raster""" download_raster( scenario_uuid, @@ -547,9 +513,7 @@ def download_maximum_flow_velocity_raster( ) -def download_total_damage_raster( - scenario_uuid, projection=None, resolution=None, bbox=None, pathname=None -): +def download_total_damage_raster(scenario_uuid, projection=None, resolution=None, bbox=None, pathname=None): """download Total Damage raster""" download_raster( scenario_uuid, @@ -561,9 +525,7 @@ def download_total_damage_raster( ) -def download_arrival_time_raster( - scenario_uuid, projection=None, resolution=None, bbox=None, pathname=None -): +def download_arrival_time_raster(scenario_uuid, projection=None, resolution=None, bbox=None, pathname=None): """download arrival time raster""" download_raster( scenario_uuid, @@ -681,16 +643,12 @@ def get_attachment_links(scenario_json): def rasters_in_scenario(scenario_json, subendpoint=None): """return two lists of static and temporal rasters including 3di result name and code""" scenario_uuid = scenario_json["uuid"] - result_list = get_scenario_instance_results( - scenario_uuid=scenario_uuid, subendpoint=subendpoint - ) + result_list = get_scenario_instance_results(scenario_uuid=scenario_uuid, subendpoint=subendpoint) temporal_rasters = [] static_rasters = [] for result in result_list: - if result["raster"]: - raster_url = result["raster"] raster_instance = get_raster(scenario_uuid, result["code"]) name_3di = result["name"] @@ -704,9 +662,7 @@ def rasters_in_scenario(scenario_json, subendpoint=None): return static_rasters, temporal_rasters -def get_raster_download_link( - raster, scenario_instance, resolution=None, projection=None, bbox=None, time=None -): +def get_raster_download_link(raster, scenario_instance, resolution=None, projection=None, bbox=None, time=None): """get url to download raster""" task = create_raster_task( raster=raster, @@ -736,9 +692,7 @@ def get_raster_download_link( return None -def get_static_rasters_links( - static_rasters, projection=None, resolution=None, bbox=None, time=None -): +def get_static_rasters_links(static_rasters, projection=None, resolution=None, bbox=None, time=None): """return a dict of urls to geotiff files of static rasters in scenario the dict items are formatted as result_name: link.tif""" static_raster_urls = {} @@ -756,15 +710,17 @@ def get_static_rasters_links( def get_temporal_raster_links( - temporal_raster, projection=None, resolution=None, bbox=None, interval_hours=None, + temporal_raster, + projection=None, + resolution=None, + bbox=None, + interval_hours=None, ): """return a dict of urls to geotiff files of a temporal raster the dict items are formatted as name_3di_datetime: link.tif""" temporal_raster_urls = {} name = temporal_raster["name_3di"] - timesteps = get_raster_timesteps( - raster=temporal_raster, interval_hours=interval_hours - ) + timesteps = get_raster_timesteps(raster=temporal_raster, interval_hours=interval_hours) for timestep in timesteps: download_url = get_raster_download_link( raster=temporal_raster, @@ -781,15 +737,17 @@ def get_temporal_raster_links( name_timestep = "_".join([name, timestep]) else: # if not equal, indicate the datetime discrepancy in file name - name_timestep = "{}_get_{}_got_{}".format( - name, timestep_url_format, url_timestep - ) + name_timestep = "{}_get_{}_got_{}".format(name, timestep_url_format, url_timestep) temporal_raster_urls[name_timestep] = download_url return temporal_raster_urls def get_temporal_rasters_links( - temporal_rasters, projection=None, resolution=None, bbox=None, interval_hours=None, + temporal_rasters, + projection=None, + resolution=None, + bbox=None, + interval_hours=None, ): """get links to all temporal rasters""" temporal_rasters_urls = {} @@ -838,15 +796,10 @@ def get_raster_timesteps(raster, interval_hours=None): timesteps_ms[round(len(timesteps_ms) / 2)], timesteps_ms[-1], ] - timestep_obj_list = [ - to_datetime_obj(time_string) for time_string in timesteps_ms - ] + timestep_obj_list = [to_datetime_obj(time_string) for time_string in timesteps_ms] # Format the datetime object - timesteps = [ - timestep_obj.strftime("%Y-%m-%dT%H:%M:%S") - for timestep_obj in timestep_obj_list - ] + timesteps = [timestep_obj.strftime("%Y-%m-%dT%H:%M:%S") for timestep_obj in timestep_obj_list] else: # use interval from argument @@ -867,10 +820,7 @@ def get_raster_timesteps(raster, interval_hours=None): if not last_timestamp in timestep_obj_list: timestep_obj_list.append(last_timestamp) - timesteps = [ - timestep_obj.strftime("%Y-%m-%dT%H:%M:%S") - for timestep_obj in timestep_obj_list - ] + timesteps = [timestep_obj.strftime("%Y-%m-%dT%H:%M:%S") for timestep_obj in timestep_obj_list] return timesteps @@ -879,7 +829,10 @@ def get_raster_from_json(scenario_json, raster_code, subendpoint=None): scenario_uuid = scenario_json["uuid"] raster_url = get_raster_url(scenario_uuid=scenario_uuid, raster_code=raster_code) - r = requests.get(url=raster_url, auth=("__key__", get_api_key()),) + r = requests.get( + url=raster_url, + auth=("__key__", get_api_key()), + ) r.raise_for_status() @@ -925,9 +878,7 @@ def resume_download_tasks(task_file, overwrite=False): download_task(task_uuid=uuid, pathname=pathname) except HTTPError as err: if err.code == 503: - logging.debug( - "503 Server Error: Lizard has lost it. Let's ignore this." - ) + logging.debug("503 Server Error: Lizard has lost it. Let's ignore this.") task_status = "UNKNOWN" else: raise @@ -939,7 +890,5 @@ def resume_download_tasks(task_file, overwrite=False): elif task_status in ("PENDING", "UNKNOWN", "STARTED", "RETRY"): pass else: - logging.debug( - "Task {} failed, status was: {}".format(uuid, task_status) - ) + logging.debug("Task {} failed, status was: {}".format(uuid, task_status)) sleep(5) diff --git a/hhnk_threedi_plugin/qgis_interaction/klimaatsommen_pdfs.py b/hhnk_threedi_plugin/qgis_interaction/klimaatsommen_pdfs.py index f896af0a..2732d3f3 100644 --- a/hhnk_threedi_plugin/qgis_interaction/klimaatsommen_pdfs.py +++ b/hhnk_threedi_plugin/qgis_interaction/klimaatsommen_pdfs.py @@ -5,29 +5,27 @@ @author: chris.kerklaan """ import os -import pandas as pd -from hhnk_threedi_plugin.qgis_interaction.project import Project from pathlib import Path + import hhnk_research_tools as hrt import hhnk_threedi_tools as htt +import pandas as pd + +from hhnk_threedi_plugin.qgis_interaction.project import Project def load_print_layout(): - """Loads layout in project. """ + """Loads layout in project.""" - template_path = Path(htt.__file__).parent.joinpath( - "resources", - "qgis_print_layouts", - "wsa_kaarten_landscape.qpt" - ) + template_path = Path(htt.__file__).parent.joinpath("resources", "qgis_print_layouts", "wsa_kaarten_landscape.qpt") - project = Project() #subject="Layout klimaatsommen") + project = Project() # subject="Layout klimaatsommen") project.layout.add_from_template(template_path=template_path, name="wsa_kaarten1") def create_pdfs(folder, revisie): - #TODO verplaatsen naar csv - project = Project() #subject="Mapcomposer klimaatsommen") + # TODO verplaatsen naar csv + project = Project() # subject="Mapcomposer klimaatsommen") polder = folder.name output_path = folder.threedi_results.climate_results[revisie].path @@ -58,7 +56,7 @@ def create_pdfs(folder, revisie): "legenda": "legenda_schade", } - #Gecorrigeerde schadekaarten + # Gecorrigeerde schadekaarten dic[3] = { "composer_name": "wsa_kaarten1", "pdf_name": "{}_rev{}_cw_schade_totaal_corr.pdf".format(polder, revisie), @@ -123,9 +121,7 @@ def create_pdfs(folder, revisie): # } # Set dict in dataframe that will be looped. - df = pd.DataFrame( - columns=["composer_name", "pdf_name", "theme", "title", "legenda"] - ) + df = pd.DataFrame(columns=["composer_name", "pdf_name", "theme", "title", "legenda"]) df = df.append([dic[a] for a in dic], ignore_index=True) df["pdf_path"] = df["pdf_name"].apply(lambda x: os.path.join(output_path, x)) diff --git a/hhnk_threedi_plugin/qgis_interaction/load_layers_interaction.py b/hhnk_threedi_plugin/qgis_interaction/load_layers_interaction.py index e2be3153..e928c80e 100644 --- a/hhnk_threedi_plugin/qgis_interaction/load_layers_interaction.py +++ b/hhnk_threedi_plugin/qgis_interaction/load_layers_interaction.py @@ -8,27 +8,30 @@ and essentially forms the configuration for klimaatsommen (qgis3_export_pdfs) """ -if __name__ == '__main__': - #add hhnk_threedi_plugin to path. - import pathlib, sys, os +if __name__ == "__main__": + # add hhnk_threedi_plugin to path. + import os + import pathlib + import sys + sys.path.append(str(pathlib.Path(os.path.abspath(__file__)).parents[2])) # First-party imports import os import pathlib +# Local imports +import hhnk_research_tools as hrt + # Third-party imports import pandas as pd +from hhnk_threedi_tools.core.folders import Folders +from hhnk_threedi_tools.qgis import layer_structure -# Local imports -import hhnk_research_tools as hrt import hhnk_threedi_plugin.qgis_interaction.project as project # from hhnk_threedi_plugin.qgis_interaction.styling import path as PATH #TODO deze verwijderen uit init? from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR -from hhnk_threedi_tools.core.folders import Folders -from hhnk_threedi_tools.qgis import layer_structure - # globals STYLING_DIR = pathlib.Path(__file__).parent / "styling" @@ -36,14 +39,19 @@ def load_sqlite(filepath): """use the 3Di NenS plugin to load the sqlite into the project. - + filepath (str): path to sqlite""" - from ThreeDiToolbox.tool_result_selection.result_selection_view import ThreeDiResultSelectionWidget, add_spatialite_connection - from ThreeDiToolbox.tool_result_selection.models import TimeseriesDatasourceModel - from ThreeDiToolbox.tool_result_selection.result_selection import ThreeDiResultSelection import qgis from qgis.PyQt.QtCore import QSettings + from ThreeDiToolbox.tool_result_selection.models import TimeseriesDatasourceModel + from ThreeDiToolbox.tool_result_selection.result_selection import ( + ThreeDiResultSelection, + ) + from ThreeDiToolbox.tool_result_selection.result_selection_view import ( + ThreeDiResultSelectionWidget, + add_spatialite_connection, + ) def select_model_spatialite_file_custom(dialog, filepath): """custom function to open 3Di toolbox and load spatialite into project. @@ -59,10 +67,10 @@ def select_model_spatialite_file_custom(dialog, filepath): # logger.debug("Last used datasource path is no string, setting it to our home dir.") init_path = os.path.expanduser("~") - #Disabled the popup and return for custom input. - #filepath, __ = QFileDialog.getOpenFileName( + # Disabled the popup and return for custom input. + # filepath, __ = QFileDialog.getOpenFileName( # self, "Open 3Di model spatialite file", init_path, "Spatialite (*.sqlite)" - #) + # ) # if filepath == "": # return False @@ -77,16 +85,13 @@ def select_model_spatialite_file_custom(dialog, filepath): add_spatialite_connection(filepath, self.iface) settings.setValue("last_used_spatialite_path", os.path.dirname(filepath)) + # Main function + threeditoolbox = qgis.utils.plugins["ThreeDiToolbox"] - #Main function - threeditoolbox = qgis.utils.plugins['ThreeDiToolbox'] - - threeditoolbox.result_selection_tool.run() #open result selection window of ThreediToolbox + threeditoolbox.result_selection_tool.run() # open result selection window of ThreediToolbox - #Loading empty filepath and normal after that ensures to reload te sqlite. - select_model_spatialite_file_custom(dialog=threeditoolbox.result_selection_tool.dialog, - filepath='') - select_model_spatialite_file_custom(dialog=threeditoolbox.result_selection_tool.dialog, - filepath=filepath) + # Loading empty filepath and normal after that ensures to reload te sqlite. + select_model_spatialite_file_custom(dialog=threeditoolbox.result_selection_tool.dialog, filepath="") + select_model_spatialite_file_custom(dialog=threeditoolbox.result_selection_tool.dialog, filepath=filepath) - threeditoolbox.result_selection_tool.dialog.close() #close the window when loading is done. + threeditoolbox.result_selection_tool.dialog.close() # close the window when loading is done. diff --git a/hhnk_threedi_plugin/qgis_interaction/open_notebook.py b/hhnk_threedi_plugin/qgis_interaction/open_notebook.py index b4f60320..b0d29289 100644 --- a/hhnk_threedi_plugin/qgis_interaction/open_notebook.py +++ b/hhnk_threedi_plugin/qgis_interaction/open_notebook.py @@ -1,34 +1,40 @@ # %% -import os import json +import os + import numpy as np -if __name__ =='__main__': +if __name__ == "__main__": import sys from pathlib import Path + sys.path.append(str(Path(os.getcwd()).parent.parent)) -from hhnk_threedi_plugin.dependencies import DEPENDENCY_DIR, THREEDI_DEPENDENCY_DIR -from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR -try: +from hhnk_threedi_plugin.dependencies import ( + DEPENDENCY_DIR, + HHNK_THREEDI_PLUGIN_DIR, + THREEDI_DEPENDENCY_DIR, +) + +try: import hhnk_threedi_plugin.local_settings as local_settings except ModuleNotFoundError: import hhnk_threedi_plugin.local_settings_default as local_settings from pathlib import Path -from qgis.PyQt.QtWidgets import QAction, QMessageBox -from hhnk_threedi_tools.utils.notebooks.run import create_command_bat_file import hhnk_research_tools as hrt import hhnk_threedi_tools as htt +from hhnk_threedi_tools.utils.notebooks.run import create_command_bat_file +from qgis.PyQt.QtWidgets import QAction, QMessageBox # %% -class NotebookWidget(): +class NotebookWidget: """Class to interact with the notebook widget.""" - def __init__(self, caller, parent): + def __init__(self, caller, parent): self.caller = caller - self.parent= parent - self.api_file = os.path.join(HHNK_THREEDI_PLUGIN_DIR, 'api_key.txt') + self.parent = parent + self.api_file = os.path.join(HHNK_THREEDI_PLUGIN_DIR, "api_key.txt") self.load_api_key() @@ -36,7 +42,7 @@ def notebook_paths(self): notebook_paths = [str(THREEDI_DEPENDENCY_DIR), str(DEPENDENCY_DIR)] # if local_settings.hhnk_threedi_tools_path not in [None, '']: # notebook_paths.append(local_settings.hhnk_threedi_tools_path) - # try: + # try: # if local_settings.hhnk_research_tools_path not in [None, '']: # notebook_paths.append(local_settings.hhnk_research_tools_path) # except: @@ -46,15 +52,15 @@ def notebook_paths(self): def load_api_key(self): """Load api_key from file and update textbox""" api_keys = hrt.read_api_file(self.api_file) - if api_keys['lizard']: - self.parent.lizard_api_key_textbox.setText(api_keys['lizard']) - - if api_keys['threedi']: - self.parent.threedi_api_key_textbox.setText(api_keys['threedi']) + if api_keys["lizard"]: + self.parent.lizard_api_key_textbox.setText(api_keys["lizard"]) + + if api_keys["threedi"]: + self.parent.threedi_api_key_textbox.setText(api_keys["threedi"]) def _check_api_key_valid(self, api_keys): """Lizard API keys are 41 characters and have a dot in the name""" - return_value=[] + return_value = [] for key in api_keys: if len(api_keys[key]) == 41 and "." in api_keys[key]: return_value.append(True) @@ -66,32 +72,34 @@ def _check_api_key_valid(self, api_keys): else: return False - def generate_notebook_valid(self): api_keys = {} - api_keys['lizard'] = self.parent.lizard_api_key_textbox.text() - api_keys['threedi'] = self.parent.threedi_api_key_textbox.text() + api_keys["lizard"] = self.parent.lizard_api_key_textbox.text() + api_keys["threedi"] = self.parent.threedi_api_key_textbox.text() - if api_keys['lizard'] == "Vul hier je Lizard API key in!" or api_keys['threedi'] == "Vul hier je Threedi API key in!": + if ( + api_keys["lizard"] == "Vul hier je Lizard API key in!" + or api_keys["threedi"] == "Vul hier je Threedi API key in!" + ): if os.path.exists(self.api_file): api_keys = hrt.read_api_file(self.api_file) - - if api_keys['lizard'] != '' and api_keys['threedi'] != '': + + if api_keys["lizard"] != "" and api_keys["threedi"] != "": return api_keys - + QMessageBox.warning( - None, - "Starting Jupyter server", - "Vul de lizard api key in, deze is niet ingevuld! Heb je deze niet? Ga naar: \nhttps://hhnk.lizard.net/management/#/personal_api_keys", - ) + None, + "Starting Jupyter server", + "Vul de lizard api key in, deze is niet ingevuld! Heb je deze niet? Ga naar: \nhttps://hhnk.lizard.net/management/#/personal_api_keys", + ) return None else: if self._check_api_key_valid(api_keys): # copy to api directory output_file = Path(self.api_file) - if output_file.parents[2].exists(): #Does plugin dir exist. - if not output_file.parent.exists(): #Does api_key dir exist + if output_file.parents[2].exists(): # Does plugin dir exist. + if not output_file.parent.exists(): # Does api_key dir exist os.mkdir(output_file.parent) with open(self.api_file, "w") as f: f.write(json.dumps(api_keys)) @@ -105,9 +113,8 @@ def generate_notebook_valid(self): None, "Starting Jupyter server", "Er is geen correcte API key ingevuld. Heb je deze niet? Ga naar: \nhttps://hhnk.lizard.net/management/#/personal_api_keys", - ) + ) return None - def generate_notebook_folder(self, api_key): """retrieves the polder folder and loads the""" @@ -125,16 +132,13 @@ def generate_notebook_folder(self, api_key): ) # htt.add_notebook_paths(self.notebook_paths()) - + def start_server(self): api_key = self.generate_notebook_valid() if not api_key: return - + self.generate_notebook_folder(api_key) htt.open_server( - directory=self.polder_notebooks, - location="user", - use="run", - notebook_paths=self.notebook_paths() - ) \ No newline at end of file + directory=self.polder_notebooks, location="user", use="run", notebook_paths=self.notebook_paths() + ) diff --git a/hhnk_threedi_plugin/qgis_interaction/project.py b/hhnk_threedi_plugin/qgis_interaction/project.py index 3e16b571..be3b332e 100644 --- a/hhnk_threedi_plugin/qgis_interaction/project.py +++ b/hhnk_threedi_plugin/qgis_interaction/project.py @@ -7,24 +7,23 @@ """ import logging from pathlib import Path +from typing import Union import hhnk_threedi_tools as htt from hhnk_threedi_tools.qgis import layer_structure from qgis.core import ( + QgsLayoutExporter, QgsMapLayerStyle, QgsMapThemeCollection, QgsPrintLayout, QgsProject, QgsRasterLayer, QgsReadWriteContext, - QgsVectorLayer, - QgsLayoutExporter, QgsRenderContext, + QgsVectorLayer, ) - from qgis.PyQt.QtXml import QDomDocument from qgis.utils import iface -from typing import Union logger = logging.getLogger(__name__) @@ -71,7 +70,7 @@ def name(self): @property def id(self): return self.settings.id - + @property def layer(self): if self._layer is None: @@ -192,13 +191,13 @@ def get_layer(self) -> Union[QgsVectorLayer, QgsRasterLayer]: group = None if self.settings.group_lst: group = self.get_group() - if group: # find layer in group, if None, layer has been removed. + if group: # find layer in group, if None, layer has been removed. layer = next((child.layer() for child in group.children() if child.name() == self.name), None) - else: # Group does not exist, so layer has been removed. + else: # Group does not exist, so layer has been removed. layer = None - else: # No groups in QGIS instance. + else: # No groups in QGIS instance. layer = self.instance.mapLayersByName(self.name) - + return layer def zoom_to_layer(self): @@ -216,10 +215,9 @@ def zoom_to_layer(self): class QgisAllThemes: - def __init__(self) -> None: self.instance = QgsProject.instance() - + @property def mapthemecollection(self): return self.instance.mapThemeCollection() @@ -239,9 +237,9 @@ def theme_names(self): def get_theme(self, theme_name): return self.mapthemecollection.mapThemeState(theme_name) - def get_theme_layers(self, theme_name:str) -> dict: + def get_theme_layers(self, theme_name: str) -> dict: """ - + Parameters ---------- theme_name (str): name of theme @@ -259,42 +257,41 @@ def get_theme_layers(self, theme_name:str) -> dict: return layers def add_theme(self, theme_settings, layers, verbose=False): - """Add a theme to qgis project. If the theme already exists, + """Add a theme to qgis project. If the theme already exists, it wil instead add/replace layers. Note that themes can be quite tricky if they are edited after they have been edited. - Therefore we here retrieve the layers in the theme and then remove it before + Therefore we here retrieve the layers in the theme and then remove it before creating it again, see issue #143 Parameters ---------- theme_settings (htt.qgis.QgisThemeSettings): class with name and layerids layers (pd.Series): series with QgisLayer entries. - verbose (bool, optional): + verbose (bool, optional): """ if verbose: print(f"Creating theme: {theme_settings.name}") # Bestaande theme verwijderen, eerst layers ophalen. Omdat niet alle layers - # ook in theme_settings.layer_ids staan, bijvoorbeeld als er eerst een + # ook in theme_settings.layer_ids staan, bijvoorbeeld als er eerst een # 0d1d_check resultaat is ingeladen van een bepaalde revisie. current_theme_layers = self.get_theme_layers(theme_settings.name) self.mapthemecollection.removeMapTheme(theme_settings.name) theme = self.get_theme(theme_settings.name) - if verbose: print(f"\t\ttheme has layers: {current_theme_layers.keys()}") theme_layers = {} - # Bestaande layers in de visibility preset overnemen. Layername blijft een + # Bestaande layers in de visibility preset overnemen. Layername blijft een # key en dus uniek. Deze wordt later overschreven als die ook in de theme_settings # staat. Als er twee keer een 0d1d_check resultaat wordt ingeladen blijft de meest # recent ingeladen group onder het thema hangen. for layer_name, layer in current_theme_layers.items(): theme_layers[layer_name] = QgsMapThemeCollection.MapThemeLayerRecord(layer) - + for layer_id in theme_settings.layer_ids: layer = layers[layer_id] @@ -399,14 +396,14 @@ def layer_list(self) -> list: class QgisPrintLayout: - """Layout manager met voorgedefineerde kaarten. + """Layout manager met voorgedefineerde kaarten. Kan templates toevoegen en laden""" def __init__(self) -> None: self.instance = QgsProject.instance() self.layoutmanager = self.instance.layoutManager() - def get_layout(self, layout_name:str): + def get_layout(self, layout_name: str): """Get layout bij name""" return self.layoutmanager.layoutByName(layout_name) @@ -426,7 +423,8 @@ def add_from_template(self, template_path, name): layout.setName(name) self.instance.layoutManager().addLayout(layout) - def create_pdf_from_composer(self, + def create_pdf_from_composer( + self, composer_name, title, subtitle, @@ -435,7 +433,7 @@ def create_pdf_from_composer(self, theme, output_file, ): - """Create pdf from a print compusing using """ + """Create pdf from a print compusing using""" layout_item = self.get_layout(composer_name) # ------------------------------------------------------------------------------------- @@ -459,7 +457,7 @@ def create_pdf_from_composer(self, # Poging om extent goed te zetten, maar handmatig is beter. # ref_map.setExtent(project.mapcanvas_extent) - + # ------------------------------------------------------------------------------------- # Export # ------------------------------------------------------------------------------------- @@ -474,6 +472,7 @@ def create_pdf_from_composer(self, result = export.exportToPdf(output_file, pdf_settings) return result + class Project: """ Project instance which loads a layer_structure from file and then @@ -508,12 +507,14 @@ def add_themes(self): for theme_settings in self.structure.themes: self.themes.add_theme(theme_settings=theme_settings, layers=self.layers, verbose=self.verbose) - def run(self, - layer_structure_path=None, - subjects=None, - revisions: htt.SelectedRevisions = htt.SelectedRevisions(), - folder=None, - **kwargs): + def run( + self, + layer_structure_path=None, + subjects=None, + revisions: htt.SelectedRevisions = htt.SelectedRevisions(), + folder=None, + **kwargs, + ): """Run project, load layer structure and load selected layers.""" self.get_structure(layer_structure_path, subjects, revisions, folder, **kwargs) self.groups = QgisAllGroups(settings=self.structure.groups) diff --git a/hhnk_threedi_plugin/qgis_interaction/remove_layers_interaction.py b/hhnk_threedi_plugin/qgis_interaction/remove_layers_interaction.py index 0d61cec4..267160f9 100644 --- a/hhnk_threedi_plugin/qgis_interaction/remove_layers_interaction.py +++ b/hhnk_threedi_plugin/qgis_interaction/remove_layers_interaction.py @@ -1,7 +1,6 @@ - -from qgis.core import QgsProject from pathlib import Path +from qgis.core import QgsProject # Loop through all layers in the project @@ -17,4 +16,4 @@ def remove_layers(files: list): for layer_id, layer in instance.mapLayers().items(): # compare layer.source() in posix format with posix formated files if any(i in Path(layer.source()).as_posix() for i in files): - instance.removeMapLayer(layer_id) \ No newline at end of file + instance.removeMapLayer(layer_id) diff --git a/hhnk_threedi_plugin/resources.py b/hhnk_threedi_plugin/resources.py index 7f230421..949370ca 100644 --- a/hhnk_threedi_plugin/resources.py +++ b/hhnk_threedi_plugin/resources.py @@ -1666,7 +1666,7 @@ \x00\x00\x01\x7d\xd7\x18\xad\x2a\ " -qt_version = [int(v) for v in QtCore.qVersion().split('.')] +qt_version = [int(v) for v in QtCore.qVersion().split(".")] if qt_version < [5, 8, 0]: rcc_version = 1 qt_resource_struct = qt_resource_struct_v1 @@ -1674,10 +1674,13 @@ rcc_version = 2 qt_resource_struct = qt_resource_struct_v2 + def qInitResources(): QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + def qCleanupResources(): QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + qInitResources() diff --git a/hhnk_threedi_plugin/tasks/__init__.py b/hhnk_threedi_plugin/tasks/__init__.py index c04952cb..7fe5ed12 100644 --- a/hhnk_threedi_plugin/tasks/__init__.py +++ b/hhnk_threedi_plugin/tasks/__init__.py @@ -3,4 +3,4 @@ # checks tasks from hhnk_threedi_plugin.tasks.sqlite_test_tasks.sqlite_test_tasks import generalChecksTask -from hhnk_threedi_plugin.tasks.task_check_schematisation import checkSchematisationTask \ No newline at end of file +from hhnk_threedi_plugin.tasks.task_check_schematisation import checkSchematisationTask diff --git a/hhnk_threedi_plugin/tasks/execute_model_changes.py b/hhnk_threedi_plugin/tasks/execute_model_changes.py index 2adace30..f7d8ef36 100644 --- a/hhnk_threedi_plugin/tasks/execute_model_changes.py +++ b/hhnk_threedi_plugin/tasks/execute_model_changes.py @@ -1,6 +1,6 @@ -from qgis.core import QgsTask, Qgis -from qgis.utils import QgsMessageLog, iface import hhnk_research_tools as hrt +from qgis.core import Qgis, QgsTask +from qgis.utils import QgsMessageLog, iface description = "aanpassingen aan model uitvoeren" @@ -34,22 +34,16 @@ def finished(self, result): """ if not result: if self.exception is None: - iface.messageBar().pushMessage( - f"Taak {self.description} onderbroken", level=Qgis.Warning - ) + iface.messageBar().pushMessage(f"Taak {self.description} onderbroken", level=Qgis.Warning) else: iface.messageBar().pushMessage( f"Taak {self.description} mislukt: zie Message Log", level=Qgis.Critical, ) QgsMessageLog.logMessage( - '"{name}" Exception: {exception}'.format( - name=self.description, exception=self.exception - ), + '"{name}" Exception: {exception}'.format(name=self.description, exception=self.exception), level=Qgis.Critical, ) raise self.exception else: - iface.messageBar().pushMessage( - f"Taak {self.description} succesvol uitgevoerd", level=Qgis.Info - ) + iface.messageBar().pushMessage(f"Taak {self.description} succesvol uitgevoerd", level=Qgis.Info) diff --git a/hhnk_threedi_plugin/tasks/load_3di_results_tasks.py b/hhnk_threedi_plugin/tasks/load_3di_results_tasks.py index 9405ae15..a4376609 100644 --- a/hhnk_threedi_plugin/tasks/load_3di_results_tasks.py +++ b/hhnk_threedi_plugin/tasks/load_3di_results_tasks.py @@ -1,14 +1,16 @@ from copy import copy -from PyQt5.QtCore import pyqtSignal -from qgis.core import QgsTask, Qgis -from qgis.utils import QgsMessageLog, iface + from hhnk_research_tools.threedi.construct_rain_scenario import construct_scenario -from ..gui.threedi.construct_rain_scenario_plot import create_results_plot from hhnk_research_tools.threedi.construct_rain_scenario_dataframe import ( create_results_dataframe, ) -from ..gui.threedi.confirm_rain_scenario_loaded import ConfirmScenario from hhnk_research_tools.threedi.variables.variables_container import ThreediInformation +from PyQt5.QtCore import pyqtSignal +from qgis.core import Qgis, QgsTask +from qgis.utils import QgsMessageLog, iface + +from ..gui.threedi.confirm_rain_scenario_loaded import ConfirmScenario +from ..gui.threedi.construct_rain_scenario_plot import create_results_plot load_description = "Laden 3di resultaten" @@ -46,9 +48,7 @@ def run(self): self.days_dry_start, self.days_dry_end, ) = construct_scenario(test_env=self.test_env) - self.df = create_results_dataframe( - self.timestep, self.days_dry_start, self.days_dry_end - ) + self.df = create_results_dataframe(self.timestep, self.days_dry_start, self.days_dry_end) if self.confirm_scenario: self.plotting_args = create_results_plot( rain=self.rain, @@ -70,27 +70,21 @@ def finished(self, result): """ if not result: if self.exception is None: - iface.messageBar().pushMessage( - f"Taak {self.description} onderbroken", level=Qgis.Warning - ) + iface.messageBar().pushMessage(f"Taak {self.description} onderbroken", level=Qgis.Warning) else: iface.messageBar().pushMessage( f"Taak {self.description} mislukt: zie Message Log", level=Qgis.Critical, ) QgsMessageLog.logMessage( - '"{name}" Exception: {exception}'.format( - name=self.description, exception=self.exception - ), + '"{name}" Exception: {exception}'.format(name=self.description, exception=self.exception), level=Qgis.Critical, ) raise self.exception else: # On succesful run threedi_vars = ThreediInformation(result=self.result, df=self.df) - iface.messageBar().pushMessage( - f"Taak {self.description} succesvol uitgevoerd", level=Qgis.Info - ) + iface.messageBar().pushMessage(f"Taak {self.description} succesvol uitgevoerd", level=Qgis.Info) if self.confirm_scenario: confirm_dialog = ConfirmScenario(**self.plotting_args) res = confirm_dialog.exec() diff --git a/hhnk_threedi_plugin/tasks/sqlite_test_tasks/base_sqlite_test_task.py b/hhnk_threedi_plugin/tasks/sqlite_test_tasks/base_sqlite_test_task.py index 182fd6f2..955c2efe 100644 --- a/hhnk_threedi_plugin/tasks/sqlite_test_tasks/base_sqlite_test_task.py +++ b/hhnk_threedi_plugin/tasks/sqlite_test_tasks/base_sqlite_test_task.py @@ -1,11 +1,10 @@ import copy -from PyQt5.QtCore import pyqtSignal -from qgis.core import QgsTask, Qgis -from qgis.utils import QgsMessageLog, iface -from PyQt5.QtCore import QMutex, QWaitCondition # hhnk-threedi-tests from hhnk_threedi_tools import SqliteCheck +from PyQt5.QtCore import QMutex, QWaitCondition, pyqtSignal +from qgis.core import Qgis, QgsTask +from qgis.utils import QgsMessageLog, iface class BaseSqliteTask(QgsTask): @@ -29,12 +28,10 @@ def __init__(self, folder, mutex=QMutex(), wait_cond=QWaitCondition(), descripti def set_result(self, res): self.os_retry = res - - def run_custom(self): + def run_custom(self): """This function is unique for every test and actually starts a calculation.""" pass - def run(self): QgsMessageLog.logMessage(f"Taak {self.description} gestart", level=Qgis.Info) try: @@ -56,15 +53,13 @@ def run(self): self.exception = e return False - def finished_custom(self): """Custom additional actions when task is finished. For instance loading layers.""" # title, widget = self.create_result_widget(self.result_text, self.layer_source) #EXAMPLE - title=None - widget=None + title = None + widget = None return title, widget - def finished(self, result): """ If result is False, either an exception occured or the task was cancelled. @@ -73,10 +68,7 @@ def finished(self, result): """ if not result: if self.exception is None: - iface.messageBar().pushMessage( - f"Taak {self.description} onderbroken", - level=Qgis.Warning - ) + iface.messageBar().pushMessage(f"Taak {self.description} onderbroken", level=Qgis.Warning) else: iface.messageBar().pushMessage( f"Taak {self.description} mislukt: zie Message Log", @@ -94,9 +86,9 @@ def finished(self, result): level=Qgis.Info, ) QgsMessageLog.logMessage( - f"Taak {self.description} en opslag resultaten succesvol uitgevoerd", - level=Qgis.Info, - ) + f"Taak {self.description} en opslag resultaten succesvol uitgevoerd", + level=Qgis.Info, + ) try: title, widget = self.finished_custom() if widget is not None: diff --git a/hhnk_threedi_plugin/tasks/sqlite_test_tasks/sqlite_test_tasks.py b/hhnk_threedi_plugin/tasks/sqlite_test_tasks/sqlite_test_tasks.py index 576ae916..546cace9 100644 --- a/hhnk_threedi_plugin/tasks/sqlite_test_tasks/sqlite_test_tasks.py +++ b/hhnk_threedi_plugin/tasks/sqlite_test_tasks/sqlite_test_tasks.py @@ -1,32 +1,57 @@ - - -from doctest import OutputChecker -from hhnk_threedi_plugin.tasks.sqlite_test_tasks.base_sqlite_test_task import BaseSqliteTask import copy +from doctest import OutputChecker + +import geopandas as gpd +import hhnk_research_tools as hrt from PyQt5.QtCore import pyqtSignal -from qgis.core import QgsTask, Qgis +from qgis.core import Qgis, QgsTask from qgis.utils import QgsMessageLog, iface -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.impervious_surface_result import create_impervious_surface_widget -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.profiles_used_result import create_profiles_used_widget -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.controlled_structs_result import create_controlled_structs_widget -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.weir_height_result import create_weir_height_widget -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.geometries_result import create_geometries_result_widget -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.structs_channels_result import create_structs_channels_result_widget -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.general_checks_result import create_general_checks_result_widget -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.isolated_channels_result import create_isolated_channels_result_widget -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.dem_max_val_result import create_dem_max_val_result_widget -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.watersurface_area_result import create_watersurface_area_result_widget -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.cross_section_warning_result import cross_section_duplicate_widget -from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.cross_section_vertex_result import cross_section_no_vertex_widget -import hhnk_research_tools as hrt -import geopandas as gpd +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.controlled_structs_result import ( + create_controlled_structs_widget, +) +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.cross_section_vertex_result import ( + cross_section_no_vertex_widget, +) +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.cross_section_warning_result import ( + cross_section_duplicate_widget, +) +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.dem_max_val_result import ( + create_dem_max_val_result_widget, +) +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.general_checks_result import ( + create_general_checks_result_widget, +) +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.geometries_result import ( + create_geometries_result_widget, +) +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.impervious_surface_result import ( + create_impervious_surface_widget, +) +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.isolated_channels_result import ( + create_isolated_channels_result_widget, +) +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.profiles_used_result import ( + create_profiles_used_widget, +) +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.structs_channels_result import ( + create_structs_channels_result_widget, +) +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.watersurface_area_result import ( + create_watersurface_area_result_widget, +) +from hhnk_threedi_plugin.gui.checks.sqlite_test_widgets.weir_height_result import ( + create_weir_height_widget, +) +from hhnk_threedi_plugin.tasks.sqlite_test_tasks.base_sqlite_test_task import ( + BaseSqliteTask, +) class impSurfaceTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder, mutex=None, wait_cond=None) - self.description="bereken ondoorlatend oppervlak model en polder" + self.description = "bereken ondoorlatend oppervlak model en polder" def run(self): if self.sqlite_test.verify_inputs("run_imp_surface_area"): @@ -38,7 +63,9 @@ def run(self): self.exception = e return False else: - QgsMessageLog.logMessage(f"Taak {self.description} kan niet worden gestart wegens ontbrekende input", level=Qgis.Info) + QgsMessageLog.logMessage( + f"Taak {self.description} kan niet worden gestart wegens ontbrekende input", level=Qgis.Info + ) return False def finished_custom(self): @@ -49,16 +76,15 @@ def finished_custom(self): class profilesUsedTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder) - self.description="bepalen gebruikte profielen watergangen" + self.description = "bepalen gebruikte profielen watergangen" self.layer_source = self.folder.output.sqlite_tests.gebruikte_profielen.path def run_custom(self): if self.os_retry is None: self.gdf = self.sqlite_test.run_used_profiles() - self.gdf.to_file(self.layer_source, index=False, driver='GPKG') + self.gdf.to_file(self.layer_source, index=False, driver="GPKG") - def finished_custom(self): # add_layers(self.layers_list, self.test_env.group_structure) #TODO title, widget = create_profiles_used_widget(layer_source=self.layer_source) @@ -68,7 +94,7 @@ def finished_custom(self): class controlledStructsTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder) - self.description="gestuurde kunstwerken overzicht aanmaken" + self.description = "gestuurde kunstwerken overzicht aanmaken" self.layer_source = self.folder.output.sqlite_tests.gestuurde_kunstwerken.path def run_custom(self): @@ -86,24 +112,24 @@ def finished_custom(self): class weirHeightTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder) - self.description="stuw hoogtes en bodemhoogtes vergelijken" + self.description = "stuw hoogtes en bodemhoogtes vergelijken" self.layer_source = self.folder.output.sqlite_tests.bodemhoogte_stuw.path def run_custom(self): if self.os_retry is None: self.gdf, self.update_query = self.sqlite_test.run_weir_floor_level() - self.gdf.to_file(self.layer_source, index=False, driver='GPKG') + self.gdf.to_file(self.layer_source, index=False, driver="GPKG") return True def finished_custom(self): # add_layers(self.layers_list, self.test_env.group_structure) #TODO title, widget = create_weir_height_widget( - layer_source=self.layer_source, - gdf=self.gdf, - model_path=self.folder.model.schema_base.database.path, - ) + layer_source=self.layer_source, + gdf=self.gdf, + model_path=self.folder.model.schema_base.database.path, + ) return title, widget @@ -111,17 +137,14 @@ def finished_custom(self): class geometriesTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder) - self.description="nakijken geometrie" + self.description = "nakijken geometrie" self.layer_source = self.folder.output.sqlite_tests.geometry_check.path def run_custom(self): if self.os_retry is None: self.gdf = self.sqlite_test.run_geometry_checks() - self.csv_path = hrt.gdf_write_to_csv( - self.gdf, - filepath=self.layer_source - ) + self.csv_path = hrt.gdf_write_to_csv(self.gdf, filepath=self.layer_source) return True def finished_custom(self): @@ -135,7 +158,7 @@ def finished_custom(self): class structsChannelsTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder) - self.description="bepalen kunstwerken met referentie level onder bodem niveau" + self.description = "bepalen kunstwerken met referentie level onder bodem niveau" self.layer_source = self.folder.output.sqlite_tests.bodemhoogte_kunstwerken.path # print(self.layer_source) @@ -143,7 +166,7 @@ def run_custom(self): if self.sqlite_test.verify_inputs("run_struct_channel_bed_level"): if self.os_retry is None: self.gdf = self.sqlite_test.run_struct_channel_bed_level() - + # print(self.gdf) hrt.gdf_write_to_geopackage(self.gdf, filepath=str(self.layer_source)) return True @@ -159,7 +182,7 @@ def finished_custom(self): class generalChecksTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder) - self.description="algemene model checks" + self.description = "algemene model checks" self.layer_source = self.folder.output.sqlite_tests.general_sqlite_checks.path self.error = True @@ -179,7 +202,7 @@ def finished_custom(self): class isolatedChannelsTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder) - self.description="geïsoleerde watergangen bepalen" + self.description = "geïsoleerde watergangen bepalen" self.layer_source = self.folder.output.sqlite_tests.geisoleerde_watergangen.path def run_custom(self): @@ -197,7 +220,7 @@ def finished_custom(self): class demMaxValTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder, mutex=None, wait_cond=None) - self.description="maximale waarde DEM bepalen" + self.description = "maximale waarde DEM bepalen" def run(self): QgsMessageLog.logMessage(f"Taak gestart {self.description}", level=Qgis.Info) @@ -208,7 +231,6 @@ def run(self): self.exception = e return False - def finished_custom(self): """Add layer so it is seen by the widget""" title, widget = create_dem_max_val_result_widget(result_text=self.result_text) @@ -218,7 +240,7 @@ def finished_custom(self): class dewateringTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder, mutex=None, wait_cond=None) - self.description="bepalen ontwateringsdiepte op basis van DEM hoogtes" + self.description = "bepalen ontwateringsdiepte op basis van DEM hoogtes" def run(self): QgsMessageLog.logMessage(f"Taak gestart {self.description}", level=Qgis.Info) @@ -229,17 +251,16 @@ def run(self): self.exception = e return False - def finished_custom(self): """Add layer so it is seen by the widget""" # add_layers(self.layers_list, self.test_env.group_structure) #TODO - return None, None #No widget created. + return None, None # No widget created. class watersurfaceAreaTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder) - self.description="wateroppervlak damo/model vergelijken" + self.description = "wateroppervlak damo/model vergelijken" self.layer_source = self.folder.output.sqlite_tests.wateroppervlak.path def run_custom(self): @@ -250,7 +271,7 @@ def run_custom(self): return True def finished_custom(self): - # add_layers(self.layers_list, self.test_env.group_structure) #TODO + # add_layers(self.layers_list, self.test_env.group_structure) #TODO title, widget = create_watersurface_area_result_widget(self.result_text, self.layer_source) return title, widget @@ -258,7 +279,7 @@ def finished_custom(self): class gridTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder, mutex=None, wait_cond=None) - self.description="grid genereren" + self.description = "grid genereren" def run(self): QgsMessageLog.logMessage(f"Taak gestart {self.description}", level=Qgis.Info) @@ -272,44 +293,40 @@ def run(self): def finished_custom(self): """Add layer so it is seen by the widget""" # add_layers(self.layers_list, self.test_env.group_structure) #TODO - return None, None #No widget created. + return None, None # No widget created. + class crossSectionDuplicateTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder) - self.description="dubbele cross sections" + self.description = "dubbele cross sections" self.layer_source = self.folder.output.sqlite_tests.cross_section_duplicates.path - self.database = self.folder.model.schema_base.database + self.database = self.folder.model.schema_base.database def run_custom(self): if self.os_retry is None: - self.gdf = self.sqlite_test.run_cross_section_duplicates(database = self.database) + self.gdf = self.sqlite_test.run_cross_section_duplicates(database=self.database) - self.gdf.to_file(self.layer_source, index=False, driver='GPKG') + self.gdf.to_file(self.layer_source, index=False, driver="GPKG") - def finished_custom(self): - title, widget = cross_section_duplicate_widget(layer_source=self.layer_source) return title, widget + class crossSectionNoVertexTask(BaseSqliteTask): def __init__(self, folder): super().__init__(folder) - self.description="profielen geen snijpunt in vertex " - self.database = self.folder.model.schema_base.database + self.description = "profielen geen snijpunt in vertex " + self.database = self.folder.model.schema_base.database self.layer_source = self.folder.output.sqlite_tests.cross_section_no_vertex.path def run_custom(self): - if self.os_retry is None: - self.gdf = self.sqlite_test.run_cross_section_no_vertex(database = self.database) + self.gdf = self.sqlite_test.run_cross_section_no_vertex(database=self.database) - self.gdf.to_file(self.layer_source, index=False, driver='GPKG') + self.gdf.to_file(self.layer_source, index=False, driver="GPKG") - def finished_custom(self): - title, widget = cross_section_no_vertex_widget(layer_source=self.layer_source) return title, widget - diff --git a/hhnk_threedi_plugin/tasks/task_bank_levels.py b/hhnk_threedi_plugin/tasks/task_bank_levels.py index 9538e725..f22743d5 100644 --- a/hhnk_threedi_plugin/tasks/task_bank_levels.py +++ b/hhnk_threedi_plugin/tasks/task_bank_levels.py @@ -1,29 +1,30 @@ import os -from PyQt5.QtCore import pyqtSignal, QMutex, QWaitCondition -from qgis.core import QgsTask, Qgis -from qgis.utils import QgsMessageLog, iface -from hhnk_threedi_plugin.gui.sql_preview.model_changes_preview import modelChangesPreview +import hhnk_research_tools as hrt +import hhnk_threedi_tools as htt # new from hhnk_threedi_tools import BankLevelTest +from hhnk_threedi_tools.variables.bank_levels import ( + new_bank_level_col, + new_storage_area_col, +) from hhnk_threedi_tools.variables.database_aliases import a_cross_loc_id from hhnk_threedi_tools.variables.database_variables import ( bank_level_col, conn_node_id_col, storage_area_col, ) -from hhnk_threedi_tools.variables.bank_levels import ( - new_bank_level_col, - new_storage_area_col, -) - -from hhnk_threedi_plugin.tasks.utility_functions.handle_os_errors import check_os_error +from PyQt5.QtCore import QMutex, QWaitCondition, pyqtSignal +from qgis.core import Qgis, QgsTask +from qgis.utils import QgsMessageLog, iface -from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR import hhnk_threedi_plugin.qgis_interaction.project as project -import hhnk_research_tools as hrt -import hhnk_threedi_tools as htt +from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR +from hhnk_threedi_plugin.gui.sql_preview.model_changes_preview import ( + modelChangesPreview, +) +from hhnk_threedi_plugin.tasks.utility_functions.handle_os_errors import check_os_error def get_bank_levels_manholes_task(results_widget, folder, output=True): @@ -40,12 +41,8 @@ def get_bank_levels_manholes_task(results_widget, folder, output=True): folder, create_output=output, mutex=mutex, wait_cond=wait_cond ) calculate_task.os_error.connect(check_os_error) - calculate_task.bank_level_widget_created.connect( - results_widget.tabs.add_bank_levels_tab - ) - calculate_task.new_manholes_widget_created.connect( - results_widget.tabs.add_new_manholes_tab - ) + calculate_task.bank_level_widget_created.connect(results_widget.tabs.add_bank_levels_tab) + calculate_task.new_manholes_widget_created.connect(results_widget.tabs.add_new_manholes_tab) return calculate_task except Exception as e: raise e from None @@ -53,6 +50,7 @@ def get_bank_levels_manholes_task(results_widget, folder, output=True): description = "berekenen nieuwe bank levels en manholes" + class calculateBankLevelsManholesTask(QgsTask): bank_level_widget_created = pyqtSignal(object) new_manholes_widget_created = pyqtSignal(object) @@ -138,9 +136,7 @@ def create_widgets(self): id_col=conn_node_id_col, old_col=storage_area_col, new_col=new_storage_area_col, - add_rows_ids=self.bl_test.results["new_manholes_df"][ - conn_node_id_col - ].tolist(), + add_rows_ids=self.bl_test.results["new_manholes_df"][conn_node_id_col].tolist(), rows_selectable=True, searchable=True, ) @@ -154,39 +150,30 @@ def finished(self, result): """ if not result: if self.exception is None: - iface.messageBar().pushMessage( - f"Taak {self.description} onderbroken", level=Qgis.Warning - ) + iface.messageBar().pushMessage(f"Taak {self.description} onderbroken", level=Qgis.Warning) else: iface.messageBar().pushMessage( f"Taak {self.description} mislukt: zie Message Log", level=Qgis.Critical, ) QgsMessageLog.logMessage( - '"{name}" Exception: {exception}'.format( - name=self.description, exception=self.exception - ), + '"{name}" Exception: {exception}'.format(name=self.description, exception=self.exception), level=Qgis.Critical, ) raise self.exception else: - iface.messageBar().pushMessage( - f"Taak {self.description} succesvol uitgevoerd", level=Qgis.Info - ) + iface.messageBar().pushMessage(f"Taak {self.description} succesvol uitgevoerd", level=Qgis.Info) try: - #if self.create_out: + # if self.create_out: bank_levels_widget, new_manholes_widget = self.create_widgets() self.bank_level_widget_created.emit(bank_levels_widget) self.new_manholes_widget_created.emit(new_manholes_widget) - #Load layers - df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, - name="qgis_layer_structure.csv") - + # Load layers + df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, name="qgis_layer_structure.csv") + proj = project.Project() - proj.run(layer_structure_path=df_path, - subjects=['test_banklevels'], - folder=self.folder) - + proj.run(layer_structure_path=df_path, subjects=["test_banklevels"], folder=self.folder) + except Exception as e: raise e from None diff --git a/hhnk_threedi_plugin/tasks/task_check_schematisation.py b/hhnk_threedi_plugin/tasks/task_check_schematisation.py index d8459ae7..d3a7f3f6 100644 --- a/hhnk_threedi_plugin/tasks/task_check_schematisation.py +++ b/hhnk_threedi_plugin/tasks/task_check_schematisation.py @@ -1,8 +1,7 @@ -from qgis.core import QgsTask, Qgis +import pandas as pd import processing +from qgis.core import Qgis, QgsTask from qgis.utils import QgsMessageLog -import pandas as pd - description = "controleer een 3Di schematisatie op fouten: (threedi:check_schematisation)" @@ -23,8 +22,8 @@ def run(self): params = { "INPUT": self.input_sqlite.as_posix(), "OUTPUT": self.output_csv.as_posix(), - "ADD_TO_PROJECT": self.add_to_project - } + "ADD_TO_PROJECT": self.add_to_project, + } # we run the tool result = processing.run("threedi:check_schematisation", params) @@ -32,4 +31,3 @@ def run(self): if self.output_csv.exists(): self.df = pd.read_csv(self.output_csv) self.error = (self.df.level == "ERROR").any() - diff --git a/hhnk_threedi_plugin/tasks/task_generate_grid.py b/hhnk_threedi_plugin/tasks/task_generate_grid.py index c6106358..17c24eef 100644 --- a/hhnk_threedi_plugin/tasks/task_generate_grid.py +++ b/hhnk_threedi_plugin/tasks/task_generate_grid.py @@ -17,10 +17,7 @@ def run(self): # we get the processing-tool parameters from folder - params = { - "INPUT_SPATIALITE": self.input_sqlite.as_posix(), - "OUTPUT": self.output_gpkg.as_posix() - } + params = {"INPUT_SPATIALITE": self.input_sqlite.as_posix(), "OUTPUT": self.output_gpkg.as_posix()} # we run the tool - processing.run("threedi:threedi_generate_computational_grid", params) \ No newline at end of file + processing.run("threedi:threedi_generate_computational_grid", params) diff --git a/hhnk_threedi_plugin/tasks/task_one_d_two_d.py b/hhnk_threedi_plugin/tasks/task_one_d_two_d.py index 3fd22c03..87468dc1 100644 --- a/hhnk_threedi_plugin/tasks/task_one_d_two_d.py +++ b/hhnk_threedi_plugin/tasks/task_one_d_two_d.py @@ -1,75 +1,67 @@ # %% -if __name__ == '__main__': +if __name__ == "__main__": + import os import sys from pathlib import Path - import os + sys.path.append(str(Path(os.getcwd()).parent.parent)) -from hhnk_threedi_tools.core.checks.one_d_two_d import OneDTwoDTest -from hhnk_threedi_tools.qgis import layer_structure -import hhnk_threedi_plugin.qgis_interaction.project as project -from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR import os -import hhnk_threedi_tools as htt -import hhnk_research_tools as hrt +import hhnk_research_tools as hrt +import hhnk_threedi_tools as htt +from hhnk_threedi_tools.core.checks.one_d_two_d import OneDTwoDTest +from hhnk_threedi_tools.qgis import layer_structure from qgis.core import Qgis from qgis.utils import QgsMessageLog +import hhnk_threedi_plugin.qgis_interaction.project as project +from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR + def task_one_d_two_d(folder, revision, dem_path): - #Define file locations + # Define file locations output_file_flowline = folder.output.one_d_two_d[revision].stroming_1d2d_test.path output_file_node = folder.output.one_d_two_d[revision].grid_nodes_2d.path - - #Create folder - folder.output.one_d_two_d[revision].create() - #Initialize test instance - test_1d2d = OneDTwoDTest(folder=folder, - revision=revision, - dem_path=dem_path) + # Create folder + folder.output.one_d_two_d[revision].create() + # Initialize test instance + test_1d2d = OneDTwoDTest(folder=folder, revision=revision, dem_path=dem_path) - #flowline results + # flowline results description = "flowlines levels en stroming bepalen" QgsMessageLog.logMessage(f"1d2d test - {description}", level=Qgis.Info) - flowlines_df=test_1d2d.run_flowline_stats() - flowlines_df.to_file(output_file_flowline, driver='GPKG', index=False) + flowlines_df = test_1d2d.run_flowline_stats() + flowlines_df.to_file(output_file_flowline, driver="GPKG", index=False) - - #Node results + # Node results description = "uitlezen waterstanden op tijdstappen en locaties uit 3di resultaten" QgsMessageLog.logMessage(f"1d2d test - {description}", level=Qgis.Info) - nodes_df=test_1d2d.run_node_stats() - nodes_df.to_file(output_file_node, driver='GPKG', index=False) - + nodes_df = test_1d2d.run_node_stats() + nodes_df.to_file(output_file_node, driver="GPKG", index=False) - #Raster results + # Raster results description = "waterstandraster per tijdstap genereren" QgsMessageLog.logMessage(f"1d2d test - {description}", level=Qgis.Info) test_1d2d.run_wlvl_depth_at_timesteps(overwrite=False) - - #Add layers to project - df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, - name="qgis_layer_structure.csv") + # Add layers to project + df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, name="qgis_layer_structure.csv") revisions = layer_structure.SelectedRevisions(check_1d2d=revision) - - #Load layers + + # Load layers proj = project.Project() - proj.run(layer_structure_path=df_path, - subjects=['test_1d2d'], - revisions=revisions, - folder=folder) + proj.run(layer_structure_path=df_path, subjects=["test_1d2d"], revisions=revisions, folder=folder) + # %% -if __name__ == '__main__': - path = r'C:\Users\wvangerwen\Downloads\model_test_v2' +if __name__ == "__main__": + path = r"C:\Users\wvangerwen\Downloads\model_test_v2" folder = htt.folders(path) - revision='BWN bwn_test #5 1d2d_test' + revision = "BWN bwn_test #5 1d2d_test" dem_path = folder.model.schema_base.rasters.dem.path - \ No newline at end of file diff --git a/hhnk_threedi_plugin/tasks/task_sqlite_tests_main.py b/hhnk_threedi_plugin/tasks/task_sqlite_tests_main.py index bef957e0..dd6def44 100644 --- a/hhnk_threedi_plugin/tasks/task_sqlite_tests_main.py +++ b/hhnk_threedi_plugin/tasks/task_sqlite_tests_main.py @@ -1,35 +1,33 @@ -from qgis.core import QgsApplication +import os -from qgis.core import QgsTask, Qgis -from qgis.utils import QgsMessageLog, iface +import hhnk_research_tools as hrt +import hhnk_threedi_tools as htt from PyQt5.QtCore import QMutex, QWaitCondition +from qgis.core import Qgis, QgsApplication, QgsTask +from qgis.utils import QgsMessageLog, iface -from hhnk_threedi_plugin.tasks.utility_functions.handle_os_errors import check_os_error import hhnk_threedi_plugin.qgis_interaction.project as project -import hhnk_threedi_tools as htt -import hhnk_research_tools as hrt +from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR from hhnk_threedi_plugin.tasks.sqlite_test_tasks.sqlite_test_tasks import ( - impSurfaceTask, - profilesUsedTask, - controlledStructsTask, - weirHeightTask, - geometriesTask, - structsChannelsTask, - generalChecksTask, - isolatedChannelsTask, - gridTask, + controlledStructsTask, + crossSectionDuplicateTask, + crossSectionNoVertexTask, demMaxValTask, dewateringTask, + generalChecksTask, + geometriesTask, + gridTask, + impSurfaceTask, + isolatedChannelsTask, + profilesUsedTask, + structsChannelsTask, watersurfaceAreaTask, - crossSectionDuplicateTask, - crossSectionNoVertexTask, - ) + weirHeightTask, +) +from hhnk_threedi_plugin.tasks.utility_functions.handle_os_errors import check_os_error -from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR -import os - -def task_sqlite_tests_main(parent_widget, folder, selected_tests): +def task_sqlite_tests_main(parent_widget, folder, selected_tests): """ Fuctions runs all tests that are part of model (sqlite) tests: input: tests_env ---> contains information about: @@ -44,78 +42,64 @@ def task_sqlite_tests_main(parent_widget, folder, selected_tests): Output: returns information about success of issues found in the user interface """ - task_manager = QgsApplication.taskManager() - #Map buttons to tasks - test_task={ - "impervious_surface_chk":impSurfaceTask, - "profiles_used_chk":profilesUsedTask, - "controlled_structs_chk":controlledStructsTask, - "weir_height_chk":weirHeightTask, - "geometry_chk":geometriesTask, - "structs_channel_chk":structsChannelsTask, - "general_tests_chk":generalChecksTask, - "isolated_channels_chk":isolatedChannelsTask, - "grid_chk":gridTask, - "max_dem_chk":demMaxValTask, - "dewatering_depth_chk":dewateringTask, - "watersurface_area_chk":watersurfaceAreaTask, - "cross_section_duplicate_chk":crossSectionDuplicateTask, - "cross_section_no_vertex_chk":crossSectionNoVertexTask, - } - - - - folder.tasks=[] + # Map buttons to tasks + test_task = { + "impervious_surface_chk": impSurfaceTask, + "profiles_used_chk": profilesUsedTask, + "controlled_structs_chk": controlledStructsTask, + "weir_height_chk": weirHeightTask, + "geometry_chk": geometriesTask, + "structs_channel_chk": structsChannelsTask, + "general_tests_chk": generalChecksTask, + "isolated_channels_chk": isolatedChannelsTask, + "grid_chk": gridTask, + "max_dem_chk": demMaxValTask, + "dewatering_depth_chk": dewateringTask, + "watersurface_area_chk": watersurfaceAreaTask, + "cross_section_duplicate_chk": crossSectionDuplicateTask, + "cross_section_no_vertex_chk": crossSectionNoVertexTask, + } + + folder.tasks = [] for selected_test in selected_tests: print(selected_test) if selected_test in test_task: task = test_task[selected_test](folder=folder) task.os_error.connect(check_os_error) - task.result_widget_created.connect(parent_widget.add_section) #Voeg widget van taak toe aan de parent_widget. + task.result_widget_created.connect( + parent_widget.add_section + ) # Voeg widget van taak toe aan de parent_widget. - folder.tasks.append(task) #Voeg tasks aan folders toe zodat ze blijven bestaan. Anders werkt 'finished' binnen de taak niet. + folder.tasks.append( + task + ) # Voeg tasks aan folders toe zodat ze blijven bestaan. Anders werkt 'finished' binnen de taak niet. task_manager.addTask(task) - - def print_done(): - QgsMessageLog.logMessage( - f"All sqlite tasks finished - loading results into project", level=Qgis.Info - ) + QgsMessageLog.logMessage(f"All sqlite tasks finished - loading results into project", level=Qgis.Info) - df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, - name="qgis_layer_structure.csv") - #Load layers + df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, name="qgis_layer_structure.csv") + # Load layers proj = project.Project() - proj.run(layer_structure_path=df_path, - subjects=['test_sqlite'], - folder=folder) - + proj.run(layer_structure_path=df_path, subjects=["test_sqlite"], folder=folder) + QgsApplication.taskManager().allTasksFinished.disconnect() task_manager_connect = task_manager.allTasksFinished.connect(print_done) - # QgsMessageLog.logMessage( # f"Alle sqlite taken gestart main", level=Qgis.Info # ) - - - - # if "impervious_surface_chk" in selected_tests: # task = impSurfaceTask(folder=folder, mutex=None, wait_cond=None) # task.result_widget_created.connect(parent_widget.add_section) # # test_env.tasks.append(task) # task_manager.addTask(task) - - - # if "profiles_used_chk" in selected_tests: # profiles_mutex = QMutex() # profiles_wait_cond = QWaitCondition() diff --git a/hhnk_threedi_plugin/tasks/task_zero_d_one_d.py b/hhnk_threedi_plugin/tasks/task_zero_d_one_d.py index afcb79b1..ab29033c 100644 --- a/hhnk_threedi_plugin/tasks/task_zero_d_one_d.py +++ b/hhnk_threedi_plugin/tasks/task_zero_d_one_d.py @@ -1,66 +1,66 @@ # %% -if __name__ == '__main__': +if __name__ == "__main__": + import os import sys from pathlib import Path - import os + sys.path.append(str(Path(os.getcwd()).parent.parent)) +import os + import hhnk_research_tools as hrt -import hhnk_threedi_tools.core.checks.zero_d_one_d as htt_0d1d +import hhnk_threedi_tools as htt import hhnk_threedi_tools.core.checks.grid_result_metadata as grid_result_metadata +import hhnk_threedi_tools.core.checks.zero_d_one_d as htt_0d1d from hhnk_threedi_tools.qgis import layer_structure -import hhnk_threedi_plugin.qgis_interaction.project as project -from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR -import os -import hhnk_threedi_tools as htt - from qgis.core import Qgis from qgis.utils import QgsMessageLog -if __name__ == '__main__': - path = r'C:\Users\wvangerwen\Downloads\model_test_v2' +import hhnk_threedi_plugin.qgis_interaction.project as project +from hhnk_threedi_plugin.dependencies import HHNK_THREEDI_PLUGIN_DIR + +if __name__ == "__main__": + path = r"C:\Users\wvangerwen\Downloads\model_test_v2" folder = htt.folders(path) - revision='BWN bwn_test #5 0d1d_test' - + revision = "BWN bwn_test #5 0d1d_test" + # %% + def task_zero_d_one_d(folder, revision): -# %% + # %% # grid_result = folder.threedi_results.zero_d_one_d[revision].grid output_file_node = folder.output.zero_d_one_d[revision].nodes_0d1d_test.path output_file_channels = folder.output.zero_d_one_d[revision].hydraulische_toets_watergangen.path output_file_structs = folder.output.zero_d_one_d[revision].hydraulische_toets_kunstwerken.path - #Create folder + # Create folder folder.output.zero_d_one_d[revision].create() - #Initialize to get information from the netcdf + # Initialize to get information from the netcdf # rain, detected_rain, timestep, days_dry_start, days_dry_end, timestep_df = grid_result_metadata.construct_scenario(grid_result) zero_d_one_d_test = htt_0d1d.ZeroDOneDTest(folder=folder, revision=revision) - #Hydraulische toets + # Hydraulische toets QgsMessageLog.logMessage(f"0d1d test - Hydraulische toets", level=Qgis.Info) channels_gdf, structs_gdf = zero_d_one_d_test.run_hydraulic() - channels_gdf.to_file(output_file_channels, driver='GPKG', index=False) - structs_gdf.to_file(output_file_structs, driver='GPKG', index=False) + channels_gdf.to_file(output_file_channels, driver="GPKG", index=False) + structs_gdf.to_file(output_file_structs, driver="GPKG", index=False) - #Waterlevels at nodes + # Waterlevels at nodes QgsMessageLog.logMessage(f"0d1d test - Waterlevel at nodes", level=Qgis.Info) gdf_node = zero_d_one_d_test.run() - gdf_node.to_file(output_file_node, driver='GPKG', index=False) + gdf_node.to_file(output_file_node, driver="GPKG", index=False) - #Add layers to project - df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, - name="qgis_layer_structure.csv") + # Add layers to project + df_path = hrt.get_pkg_resource_path(package_resource=htt.resources, name="qgis_layer_structure.csv") revisions = layer_structure.SelectedRevisions(check_0d1d=revision) proj = project.Project() - proj.run(layer_structure_path=df_path, - subjects=['test_0d1d'], - revisions=revisions, - folder=folder) + proj.run(layer_structure_path=df_path, subjects=["test_0d1d"], revisions=revisions, folder=folder) + # %% diff --git a/hhnk_threedi_plugin/tests/Modelsplitter_QT.py b/hhnk_threedi_plugin/tests/Modelsplitter_QT.py index 88d1624f..e27bf902 100644 --- a/hhnk_threedi_plugin/tests/Modelsplitter_QT.py +++ b/hhnk_threedi_plugin/tests/Modelsplitter_QT.py @@ -1,127 +1,133 @@ # %% +import os import sys from pathlib import Path -import os + sys.path.append(str(Path(os.getcwd()).parent.parent)) -from hhnk_threedi_tools.core.folders import Folders import shutil + import hhnk_research_tools as hrt +import matplotlib.pyplot as plt import numpy as np import pandas as pd -import matplotlib.pyplot as plt - - from hhnk_threedi_tools.core import folders +from hhnk_threedi_tools.core.folders import Folders -#--------------------------------------------------------------------------------------------------------------# +# --------------------------------------------------------------------------------------------------------------# -path = r'E:\Data\02.modellen\model_test_v2' +path = r"E:\Data\02.modellen\model_test_v2" folder = Folders(path) settings_df = pd.read_excel(folder.model.settings.path, engine="openpyxl") -settings_default_series = pd.read_excel(folder.model.settings_default.path, engine="openpyxl").iloc[0] #Series, only has one row. +settings_default_series = pd.read_excel(folder.model.settings_default.path, engine="openpyxl").iloc[ + 0 +] # Series, only has one row. -#Sanity check settings tables +# Sanity check settings tables inter = settings_df.keys().intersection(settings_default_series.keys()) if len(inter) > 0: - print(f"""Er staan kolommen zowel in de defaut als in de andere modelsettings. -Dat lijkt me een slecht plan. Kolommen: {inter.values}""") - -INFILTRATION_COLS = ["infiltration_rate", -"infiltration_rate_file", -"infiltration_surface_option", -"max_infiltration_capacity_file", -"display_name", + print( + f"""Er staan kolommen zowel in de defaut als in de andere modelsettings. +Dat lijkt me een slecht plan. Kolommen: {inter.values}""" + ) + +INFILTRATION_COLS = [ + "infiltration_rate", + "infiltration_rate_file", + "infiltration_surface_option", + "max_infiltration_capacity_file", + "display_name", ] -#--------------------------------------------------------------------------------------------------------------# +# --------------------------------------------------------------------------------------------------------------# def modelsplitter(self): - overwrite = True + overwrite = True path = self.dockwidget.polders_map_selector.filePath() folder = Folders(path) settings_df = pd.read_excel(folder.model.settings.path, engine="openpyxl") - settings_default_series = pd.read_excel(folder.model.settings_default.path, engine="openpyxl").iloc[0] #Series, only has one row. + settings_default_series = pd.read_excel(folder.model.settings_default.path, engine="openpyxl").iloc[ + 0 + ] # Series, only has one row. - - #Sanity check settings tables + # Sanity check settings tables inter = settings_df.keys().intersection(settings_default_series.keys()) if len(inter) > 0: - print(f"""Er staan kolommen zowel in de defaut als in de andere modelsettings. - Dat lijkt me een slecht plan. Kolommen: {inter.values}""") - - INFILTRATION_COLS = ["infiltration_rate", - "infiltration_rate_file", - "infiltration_surface_option", - "max_infiltration_capacity_file", - "display_name", + print( + f"""Er staan kolommen zowel in de defaut als in de andere modelsettings. + Dat lijkt me een slecht plan. Kolommen: {inter.values}""" + ) + + INFILTRATION_COLS = [ + "infiltration_rate", + "infiltration_rate_file", + "infiltration_surface_option", + "max_infiltration_capacity_file", + "display_name", ] - RASTER_FILES = ['dem_file', 'frict_coef_file', 'infiltration_rate_file', 'max_infiltration_capacity_file'] - -#--------------------------------------------------------------------------------------------------------------# - -## Iterate trough names in QtlistWidget, dragged and dropped, from source:"setting_default.xlsx" + RASTER_FILES = ["dem_file", "frict_coef_file", "infiltration_rate_file", "max_infiltration_capacity_file"] + + # --------------------------------------------------------------------------------------------------------------# + + ## Iterate trough names in QtlistWidget, dragged and dropped, from source:"setting_default.xlsx" selectedLayers = self.listWidget.selectedItems() for names in selectedLayers: + # Add schematisation to folder structure + schema_name = folder.model.add_modelpath(str(names)) - #Add schematisation to folder structure - schema_name = folder.model.add_modelpath(str (names)) - # Copy the files that are in the global settings. - # This menas rasters that are not defined are not added to the schematisation. + # This menas rasters that are not defined are not added to the schematisation. schema_base = folder.model.schema_base schema_new = getattr(folder.model, schema_name) - + for index, row in settings_df.iterrows(): - #Write the sqlite and rasters to new folders. + # Write the sqlite and rasters to new folders. if overwrite: - #Copy sqlite - src=schema_base.database.path + # Copy sqlite + src = schema_base.database.path dst = schema_new.full_path(schema_base.database.name) - shutil.copyfile(src=src, dst=dst.path) + shutil.copyfile(src=src, dst=dst.path) - raster_path = os.path.join(schema_new.path, 'rasters') + raster_path = os.path.join(schema_new.path, "rasters") if not os.path.exists(raster_path): os.mkdir(raster_path) - #Copy rasters that are defined in the settings file + # Copy rasters that are defined in the settings file for raster_file in RASTER_FILES: if not pd.isnull(row[raster_file]): src = os.path.join(schema_base.path, row[raster_file]) if os.path.exists(src): dst = os.path.join(schema_new.path, row[raster_file]) - shutil.copyfile(src=src, dst=dst) + shutil.copyfile(src=src, dst=dst) else: - print(f'Couldnt find raster:\t{row[raster_file]}') + print(f"Couldnt find raster:\t{row[raster_file]}") database_path_base = schema_base.database.path database_path_new = schema_new.database.path - - #Edit theSQLITE - table_names=['v2_global_settings','v2_simple_infiltration'] + # Edit theSQLITE + table_names = ["v2_global_settings", "v2_simple_infiltration"] for table_name in table_names: print(f"\tUpdate {table_name}") - #Set the id in the v2_simple_iniltration to the id defined in global settings. - if table_name=='v2_simple_infiltration': - row['id'] = row['simple_infiltration_settings_id'] - - #Clear the table - hrt.execute_sql_changes(query=f"""DELETE FROM {table_name}""", - database=database_path_new) - + # Set the id in the v2_simple_iniltration to the id defined in global settings. + if table_name == "v2_simple_infiltration": + row["id"] = row["simple_infiltration_settings_id"] + + # Clear the table + hrt.execute_sql_changes(query=f"""DELETE FROM {table_name}""", database=database_path_new) + # Create new value and column pairs. The new values are used from the settings.xlsx file. - if not pd.isnull(row['id']): + if not pd.isnull(row["id"]): df_table = hrt.sqlite_table_to_df(database_path=database_path_new, table_name=table_name) - columns=[] - values=[] + columns = [] + values = [] for key in df_table.keys(): columns.append(key) if key in row: @@ -129,39 +135,39 @@ def modelsplitter(self): elif key in settings_default_series: value = settings_default_series[key] else: - value=None - print(f'Column {key} not defined') + value = None + print(f"Column {key} not defined") if pd.isnull(value): - value=None + value = None - #Exceptions - #startdate is interpreted as timestamp by pandas but we only need YYYY-MM-DD format. - if key=='start_date': + # Exceptions + # startdate is interpreted as timestamp by pandas but we only need YYYY-MM-DD format. + if key == "start_date": try: - value=str(value)[:10] + value = str(value)[:10] except: pass values.append(value) - #Make sure None is interpreted as NULL by sqlite. - columns= tuple(columns) - values = str(tuple(values)).replace('None', 'NULL') - - #Prepare insert query - query=f"""INSERT INTO {table_name} {columns} + # Make sure None is interpreted as NULL by sqlite. + columns = tuple(columns) + values = str(tuple(values)).replace("None", "NULL") + + # Prepare insert query + query = f"""INSERT INTO {table_name} {columns} VALUES {values}""" - #Insert new row + # Insert new row hrt.execute_sql_changes(query, database=database_path_new) - #Additional model changes for different model types + # Additional model changes for different model types - if row['name'] == '0d1d_test': - #Set every channel to isolated + if row["name"] == "0d1d_test": + # Set every channel to isolated hrt.execute_sql_changes(query="UPDATE v2_channel SET calculation_type=101", database=database_path_new) - #Set controlled weirs to 10x width because we dont use controlled strcutures in hyd test. - #To get the weir with we use the base database, so we cant accidentally run this twice. + # Set controlled weirs to 10x width because we dont use controlled strcutures in hyd test. + # To get the weir with we use the base database, so we cant accidentally run this twice. controlled_weirs_selection_query = f""" SELECT v2_weir.cross_section_definition_id as cross_def_id, @@ -172,27 +178,26 @@ def modelsplitter(self): INNER JOIN v2_cross_section_definition ON v2_weir.cross_section_definition_id = v2_cross_section_definition.id INNER JOIN v2_control_table ON v2_weir.id = v2_control_table.target_id """ - controlled_weirs_df = hrt.execute_sql_selection(controlled_weirs_selection_query, database_path=database_path_base) - - controlled_weirs_df.insert(controlled_weirs_df.columns.get_loc('width') + 1, 'width_new', - controlled_weirs_df['width'].apply(lambda x: round((float(x) * 10), 3)) - ) - - query = hrt.sql_create_update_case_statement(df=controlled_weirs_df, - layer='v2_cross_section_definition', - df_id_col='cross_def_id', - db_id_col='id', - old_val_col= 'width', - new_val_col= 'width_new',) + controlled_weirs_df = hrt.execute_sql_selection( + controlled_weirs_selection_query, database_path=database_path_base + ) + + controlled_weirs_df.insert( + controlled_weirs_df.columns.get_loc("width") + 1, + "width_new", + controlled_weirs_df["width"].apply(lambda x: round((float(x) * 10), 3)), + ) + + query = hrt.sql_create_update_case_statement( + df=controlled_weirs_df, + layer="v2_cross_section_definition", + df_id_col="cross_def_id", + db_id_col="id", + old_val_col="width", + new_val_col="width_new", + ) hrt.execute_sql_changes(query=query, database=database_path_new) -#--------------------------------------------------------------------------------------------------------------# - - - - - - - +# --------------------------------------------------------------------------------------------------------------# diff --git a/hhnk_threedi_plugin/tests/dummy.py b/hhnk_threedi_plugin/tests/dummy.py index f88dcf29..2147862b 100644 --- a/hhnk_threedi_plugin/tests/dummy.py +++ b/hhnk_threedi_plugin/tests/dummy.py @@ -4,17 +4,16 @@ @author: chris.kerklaan """ +import logging +import sys + +from PyQt5.QtCore import QCoreApplication, QObject, QSize, pyqtSlot from qgis._core import QgsVectorLayer -from PyQt5.QtCore import QObject, pyqtSlot, QCoreApplication, QSize # from PyQt5.QtGui import QWidget -from qgis.core import QgsProject, QgsApplication, QgsVectorLayer +from qgis.core import QgsApplication, QgsProject, QgsVectorLayer from qgis.gui import QgsMapCanvas -import logging -import sys - - LOGGER = logging.getLogger("QGIS") diff --git a/hhnk_threedi_plugin/tests/test_scale.py b/hhnk_threedi_plugin/tests/test_scale.py index 77096b1b..7a5eb555 100644 --- a/hhnk_threedi_plugin/tests/test_scale.py +++ b/hhnk_threedi_plugin/tests/test_scale.py @@ -8,4 +8,4 @@ r = hrt.Raster(src) -# arr = r._read_array() \ No newline at end of file +# arr = r._read_array() diff --git a/hhnk_threedi_plugin/tests/test_ui.py b/hhnk_threedi_plugin/tests/test_ui.py index f97cf28c..ba030871 100644 --- a/hhnk_threedi_plugin/tests/test_ui.py +++ b/hhnk_threedi_plugin/tests/test_ui.py @@ -5,30 +5,27 @@ """ # System imports +import os import os.path as path -import unittest import pathlib -import os +import unittest # Add the correct path -__file__ = ( - "C:/Users/chris.kerklaan/Documents/Github/hhnk_threedi_plugin/tests/test_ui.py" -) +__file__ = "C:/Users/chris.kerklaan/Documents/Github/hhnk_threedi_plugin/tests/test_ui.py" import sys sys.path.append(str(pathlib.Path(__file__).parent.parent.parent)) # qgis imports -from qgis.core import QgsSettings from qgis.core import * +from qgis.core import QgsSettings qgs = QgsApplication([], False) qgs.initQgis() from qgis.gui import QgisInterface - -from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, Qt +from qgis.PyQt.QtCore import QCoreApplication, QSettings, Qt, QTranslator # Local imports from hhnk_threedi_plugin.hhnk_toolbox import HHNK_toolbox @@ -109,11 +106,8 @@ def dummy(*args, **kwargs): # del(self.app) # do not forget this if __name__ == "__main__": - iface = QgisInterfaceDummy() test = HHNK_toolbox(iface) ui = test.dlg.ui - s = QSettings( - os.path.join(os.getenv('APPDATA'), r"3Di/QGIS3/profiles/default/QGIS/QGIS3.ini") - ) + s = QSettings(os.path.join(os.getenv("APPDATA"), r"3Di/QGIS3/profiles/default/QGIS/QGIS3.ini"))