-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
120 connect damo exporter #178
base: main
Are you sure you want to change the base?
Changes from 11 commits
9df6555
fd87592
85ad21c
0131cb5
3483cfb
adb75eb
28a3cb6
2dcee64
faf161e
f48e181
51a8c3e
35edcbc
1d2df47
cc2de7a
e789bf3
0a28473
325d83d
5ccd281
c88d7c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# **Schematisation builder** | ||
HHNK heeft de werkwijze voor het opstellen en valideren van modellen geactualiseerd. De datachecker en modelbuilder zijn vervangen door de Schematisation builder. | ||
|
||
... link naar andere pagina voor meer info (2_werkwijze_bwn) | ||
|
||
## Werkproces | ||
* Omschrijving uit welke stappen het werkproces bestaat | ||
* Ondersteund door stroomschema | ||
|
||
### Stap 0. Een project beginnen of een bestaand project verder oppakken | ||
|
||
|
||
... plaatje UI volgt later na evt wijzigingen adhv sprint review | ||
|
||
### Stap 1. Data exporteren | ||
Het exportproces begint met het selecteren van het bestand met de poldergrenzen. Zodra ingeladen, kan de export gestart worden door op de knop te drukken. | ||
|
||
Er wordt een connectie gemaakt naar de DAMO database. Op basis van de polygoon (Polygon of MultiPolygon) wordt data opgehaald uit DAMO. De output wordt weggeschreven in een geopackage (DAMO.gpkg). Vervolgens wordt deze data direct omgezet in HyDAMO-formaat (HyDAMO.gpkg). De HyDAMO geopackage wordt automatisch ingeladen in QGIS met de juiste styling. | ||
|
||
Hoe styling automatisch meegeven? | ||
|
||
... plaatje UI volgt later na evt wijzigingen adhv sprint review | ||
|
||
### Stap 2. Data valideren | ||
... | ||
|
||
### Stap x. Data verbeteren | ||
... | ||
|
||
### Stap x. Data omzetten tot 3Di model | ||
... | ||
|
||
## Achtergrond en uitgangspunten | ||
... hier moet een link komen naar andere pagina (3_achtergronden_en_uitgangpunten) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
import os | ||
from dataclasses import dataclass | ||
|
||
import geopandas as gpd | ||
import pandas as pd | ||
from hhnk_threedi_tools.core.project import Project | ||
from hhnk_threedi_tools.core.schematisation_builder.DAMO_exporter import DAMO_exporter | ||
from osgeo import ogr | ||
from PyQt5.QtWidgets import QMessageBox, QPlainTextEdit | ||
from qgis.core import QgsLayerTreeGroup, QgsProject, QgsVectorLayer | ||
from qgis.PyQt.QtCore import QObject | ||
|
||
from hhnk_threedi_plugin.hhnk_toolbox_dockwidget import HHNK_toolboxDockWidget | ||
|
||
BASE_FOLDER = r"\\corp.hhnk.nl\data\Hydrologen_data\Data\09.modellen_speeltuin" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dit lijkt niet hier thuis te horen maar in een local_settings of ergens anders? |
||
TABLE_NAMES = ["HYDROOBJECT"] | ||
|
||
|
||
@dataclass | ||
class SchematisationBuilder: | ||
""" | ||
All actions in the schematisation_builder tab of the HHNK 3Di Toolbox. | ||
|
||
UI includes: | ||
- SelectProjectLabel : QLabel | ||
- SelectProjectComboBox : QComboBox | ||
- CreateProjectLabel : QLabel | ||
- CreateProjectPlainTextEdit : QPlainTextEdit | ||
- CreateProjectPushButton : QPushButton | ||
- SchematisationBuilderVerticalSpacer : Spacer | ||
- ProjectTabWidget : QTabWidget | ||
- tab_status_0 : QWidget | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Zonder het gezien te hebben, is deze naam beschrijvend genoeg? |
||
- SelectPolderLabel : QLabel | ||
- SelectPolderFileWidget : QgsFileWidget | ||
- ExportDAMOandHyDAMOPushButton : QPushButton | ||
- tab_status_1 : QWidget | ||
- ValidatePushButton : QPushButton | ||
""" | ||
|
||
dockwidget: HHNK_toolboxDockWidget | ||
prewritten_text_CreateProjectPlainTextEdit: str = "Enter project name here" | ||
|
||
def __post_init__(self): | ||
"""Connect all callback-functions to widgets.""" | ||
self._setup_callbacks() | ||
self._initialize_ui() | ||
|
||
def _setup_callbacks(self): | ||
"""Setup all widget actions.""" | ||
dock = self.dockwidget | ||
|
||
# Populate the combobox | ||
self.populate_combobox() | ||
|
||
# Top-level UI actions | ||
dock.SelectProjectComboBox.currentIndexChanged.connect(self.on_project_selected) | ||
dock.CreateProjectPlainTextEdit.focusInEvent = self.create_project_text_focus | ||
dock.CreateProjectPushButton.clicked.connect(self.create_project) | ||
|
||
# Tab 0 actions | ||
dock.ExportDAMOandHyDAMOPushButton.clicked.connect(self.export_damo_and_hydamo) | ||
|
||
# Tab 1 actions | ||
dock.ValidatePushButton.clicked.connect(self.validate_project) | ||
|
||
def _initialize_ui(self): | ||
"""Initialize UI elements with default states.""" | ||
self.dockwidget.CreateProjectPlainTextEdit.setPlainText(self.prewritten_text_CreateProjectPlainTextEdit) | ||
self.dockwidget.ProjectTabWidget.setCurrentIndex(0) | ||
self.dockwidget.ExportDAMOandHyDAMOPushButton.setEnabled(True) | ||
|
||
def populate_combobox(self): | ||
"""Populate the combobox with folder names from the base folder.""" | ||
if os.path.exists(BASE_FOLDER): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. liefst zoveel mogelijk pathlib.Path gebruiken. |
||
folder_names = [f for f in os.listdir(BASE_FOLDER) if os.path.isdir(os.path.join(BASE_FOLDER, f))] | ||
self.dockwidget.SelectProjectComboBox.addItems(folder_names) | ||
else: | ||
QMessageBox.warning(None, "Error", f"Base folder not found: {BASE_FOLDER}") | ||
|
||
def update_tab_based_on_status(self): | ||
"""Switch to the correct tab based on the project status.""" | ||
if self.project_status in range(self.dockwidget.ProjectTabWidget.count()): | ||
self.dockwidget.ProjectTabWidget.setCurrentIndex(self.project_status) | ||
else: | ||
QMessageBox.warning(None, "Error", f"Invalid project status: {self.project_status}") | ||
|
||
def on_project_selected(self): | ||
"""Handle project selection from the combo box.""" | ||
selected_folder = self.dockwidget.SelectProjectComboBox.currentText() | ||
full_path = os.path.join(BASE_FOLDER, selected_folder) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
self.project = Project(full_path) | ||
self.project_status = self.project.retrieve_project_status() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. gelijk aan Wat zijn de mogelijke waarden van project_status? Is daar ergens domeintabel van? Die
|
||
self.update_tab_based_on_status() | ||
|
||
def create_project(self): | ||
"""Handle creation of a new project.""" | ||
project_name = self.dockwidget.CreateProjectPlainTextEdit.toPlainText() | ||
if project_name.strip() and project_name != self.prewritten_text_CreateProjectPlainTextEdit: | ||
if project_name not in os.listdir(BASE_FOLDER): | ||
full_path = os.path.join(BASE_FOLDER, project_name) | ||
self.project = Project(full_path) | ||
self.dockwidget.SelectProjectComboBox.addItem(project_name) | ||
QMessageBox.information(None, "Project", f"Project created: {project_name}") | ||
self.dockwidget.SelectProjectComboBox.setCurrentText(project_name) | ||
self.project_status = self.project.retrieve_project_status() | ||
self.update_tab_based_on_status() | ||
else: | ||
QMessageBox.warning(None, "Error", "Project name already exists.") | ||
else: | ||
QMessageBox.warning(None, "Error", "Project name cannot be empty or default text.") | ||
|
||
def create_project_text_focus(self, event): | ||
"""Clear the text in the plain text edit when it gains focus.""" | ||
if self.dockwidget.CreateProjectPlainTextEdit.toPlainText() == self.prewritten_text_CreateProjectPlainTextEdit: | ||
self.dockwidget.CreateProjectPlainTextEdit.clear() | ||
QPlainTextEdit.focusInEvent(self.dockwidget.CreateProjectPlainTextEdit, event) | ||
|
||
def load_layers_from_geopackage(self, geopackage_path, group_name): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
""" | ||
Load all layers from a GeoPackage into QGIS and group them under a specified group name. | ||
|
||
Args: | ||
geopackage_path (str): Path to the GeoPackage file. | ||
group_name (str): Name of the group under which to load the layers. | ||
""" | ||
if not os.path.exists(geopackage_path): | ||
raise FileNotFoundError(f"GeoPackage not found: {geopackage_path}") | ||
|
||
# Get the QGIS project instance and create/retrieve the specified group | ||
project = QgsProject.instance() | ||
root = project.layerTreeRoot() | ||
group = root.findGroup(group_name) or root.addGroup(group_name) | ||
|
||
# Use OGR to list layers in the GeoPackage | ||
data_source = ogr.Open(geopackage_path) | ||
if not data_source: | ||
raise ValueError(f"Unable to open GeoPackage: {geopackage_path}") | ||
|
||
for i in range(data_source.GetLayerCount()): | ||
layer_name = data_source.GetLayerByIndex(i).GetName() | ||
layer_path = f"{geopackage_path}|layername={layer_name}" | ||
layer = QgsVectorLayer(layer_path, layer_name, "ogr") | ||
|
||
if layer.isValid(): | ||
project.addMapLayer(layer, addToLegend=False) | ||
group.addLayer(layer) | ||
else: | ||
raise ValueError(f"Failed to load layer: {layer_name}") | ||
|
||
def export_damo_and_hydamo(self): | ||
"""Handle export of DAMO and HyDAMO.""" | ||
file_path = self.dockwidget.SelectPolderFileWidget.filePath() | ||
damo_gpkg_path = os.path.join(self.project.project_folder, "01_source_data", "DAMO.gpkg") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dit zou al in de folderstructuur moeten staan. Dus hier; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. project.project_folder is ook nog beetje dubbel? project.folder duidelijker. Maar het folder object is eigenlijk ook het project dus nog even naar kijken wat dit Project dan toevoegd. |
||
|
||
if file_path: | ||
# DAMO export | ||
gdf_polder = gpd.read_file(file_path) | ||
dict_gdfs_damo = DAMO_exporter(gdf_polder, TABLE_NAMES) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Zie review Wouter htt. Lijkt me beter om opslaan per tabel te doen? Daarnaast lijkt me dit functionaliteit die je in htt wilt hebben en niet in de plugin. |
||
|
||
for table_name, damo_gdf in dict_gdfs_damo.items(): | ||
damo_gdf.to_file(damo_gpkg_path, layer=table_name, driver="GPKG") | ||
|
||
# Load GeoPackage layers into QGIS | ||
try: | ||
damo_gpkg_path = os.path.join(self.project.project_folder, "01_source_data", "DAMO.gpkg") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tweede keer declaren zelfde variabele? |
||
self.load_layers_from_geopackage(geopackage_path=damo_gpkg_path, group_name="DAMO") | ||
except Exception as e: | ||
QMessageBox.warning(None, "Error", f"Failed to load DAMO layers: {e}") | ||
|
||
# Conversion to HyDAMO | ||
# | ||
# | ||
|
||
QMessageBox.information( | ||
None, "Export", f"DAMO exported for file: {file_path}" | ||
) # TODO later rename to HyDAMO | ||
self.project_status = 1 | ||
self.project.update_project_status(self.project_status) | ||
self.update_tab_based_on_status() | ||
self.dockwidget.ValidatePushButton.setEnabled(True) | ||
else: | ||
QMessageBox.warning(None, "Error", "No file selected for export.") | ||
|
||
def validate_project(self): | ||
"""Handle validation of the project.""" | ||
QMessageBox.information(None, "Validation", "Validation not implemented yet.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Todo's graag opnemen met
# TODO