class QKanTools: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'Flaechenzuordnungen_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlgpr = QgsadaptDialog() self.dlgop = QKanOptionsDialog() self.dlgro = RunoffParamsDialog() # Anfang Eigene Funktionen ------------------------------------------------- # (jh, 12.06.2017) logger.info(u'\n\nQKan_Tools initialisiert...') # -------------------------------------------------------------------------- # Pfad zum Arbeitsverzeichnis sicherstellen wordir = os.path.join(site.getuserbase(), 'qkan') if not os.path.isdir(wordir): os.makedirs(wordir) # -------------------------------------------------------------------------------------------------- # Konfigurationsdatei qkan.json lesen # self.configfil = os.path.join(wordir, 'qkan.json') if os.path.exists(self.configfil): with open(self.configfil, 'r') as fileconfig: self.config = json.loads(fileconfig.read()) else: self.config = {'epsg': '25832'} # Projektionssystem with open(self.configfil, 'w') as fileconfig: fileconfig.write(json.dumps(self.config)) # Formularereignisse anbinden ---------------------------------------------- # Formular dlgpr self.dlgpr.pb_selectProjectFile.clicked.connect(self.dlgpr_selectFileProjectfile) self.dlgpr.pb_selectQKanDB.clicked.connect(self.dlgpr_selectFile_qkanDB) self.dlgpr.pb_selectProjectTemplate.clicked.connect(self.dlgpr_selectFileProjectTemplate) # Formular dlgop self.dlgop.pb_fangradiusDefault.clicked.connect(self.dlgop_fangradiusDefault) self.dlgop.pb_mindestflaecheDefault.clicked.connect(self.dlgop_mindestflaecheDefault) self.dlgop.pb_max_loopsDefault.clicked.connect(self.dlgop_maxLoopsDefault) self.dlgop.pb_selectKBS.clicked.connect(self.dlgop_selectKBS) # Formular dlgro self.dlgro.lw_teilgebiete.itemClicked.connect(self.dlgro_lwTeilgebieteClick) self.dlgro.lw_abflussparameter.itemClicked.connect(self.dlgro_lwAbflussparamsClick) self.dlgro.cb_selTgbActive.stateChanged.connect(self.dlgro_selTgbActiveClick) self.dlgro.cb_selParActive.stateChanged.connect(self.dlgro_selParActiveClick) self.dlgro.button_box.helpRequested.connect(self.dlgro_helpClick) self.dlgro.pb_selectQKanDB.clicked.connect(self.dlgro_selectFile_qkanDB) # Ende Eigene Funktionen --------------------------------------------------- # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('Flaechenzuordnungen', message) def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_qgsadapt_path = ':/plugins/qkan/tools/res/icon_qgsadapt.png' Dummy.instance.add_action( icon_qgsadapt_path, text=self.tr(u'Projektdatei auf bestehende QKan-Datenbank übertragen'), callback=self.run_qgsadapt, parent=self.iface.mainWindow()) icon_qkanoptions_path = ':/plugins/qkan/tools/res/icon_qkanoptions.png' Dummy.instance.add_action( icon_qkanoptions_path, text=self.tr(u'Allgemeine Optionen'), callback=self.run_qkanoptions, parent=self.iface.mainWindow()) icon_runoffparams_path = ':/plugins/qkan/tools/res/icon_runoffparams.png' Dummy.instance.add_action( icon_runoffparams_path, text=self.tr(u'Oberflächenabflussparameter eintragen'), callback=self.run_runoffparams, parent=self.iface.mainWindow()) def unload(self): pass # ----------------------------------------------------------------------------------------------------- # Erstellen einer Projektdatei aus einer Vorlage # 1. Formularfunktionen def dlgpr_selectFileProjectfile(self): """Zu erstellende Projektdatei festlegen""" filename = QFileDialog.getSaveFileName(self.dlgpr, "Dateinamen der zu erstellenden Projektdatei eingeben", self.default_dir, "*.qgs") # logger.info('Dateiname wurde erkannt zu:\n{}'.format(filename)) if os.path.dirname(filename) != '': os.chdir(os.path.dirname(filename)) self.dlgpr.tf_projectFile.setText(filename) def dlgpr_selectFile_qkanDB(self): """Anzubindende QKan-Datenbank festlegen""" filename = QFileDialog.getOpenFileName(self.dlgpr, "QKan-Datenbank auswählen", self.default_dir, "*.sqlite") if os.path.dirname(filename) != '': os.chdir(os.path.dirname(filename)) self.dlgpr.tf_qkanDB.setText(filename) def dlgpr_selectFileProjectTemplate(self): """Vorlage-Projektdatei auswählen""" self.setPathToTemplateDir = self.dlgpr.cb_setPathToTemplateDir.isChecked() if self.setPathToTemplateDir: self.templateDir = os.path.join(pluginDirectory('qkan'), u"database/templates") else: try: self.templateDir = os.path.dirname(self.database_QKan) except: logger.error('Programmfehler in tools.run_qgsadapt:\nPfad konnte nicht auf ' + \ 'database_QKan gesetzt werden.\n database_QKan = {}'.format( self.database_QKan)) self.templateDir = '' filename = QFileDialog.getOpenFileName(self.dlgpr, "Vorlage für zu erstellende Projektdatei auswählen", self.templateDir, "*.qgs") if os.path.dirname(filename) != '': os.chdir(os.path.dirname(filename)) self.dlgpr.tf_projectTemplate.setText(filename) # ----------------------------------------------------------------------------------------------------- # 2. Aufruf des Formulars def run_qgsadapt(self): '''Erstellen einer Projektdatei aus einer Vorlage''' # Formularfelder setzen ------------------------------------------------------------------------- # Formularfeld Datenbank # Falls eine Datenbank angebunden ist, wird diese zunächst in das Formular eingetragen. self.database_QKan, epsg = get_database_QKan(silent = True) if self.database_QKan: self.default_dir = os.path.dirname(self.database_QKan) # bereits geladene QKan-Datenbank übernehmen elif 'database_QKan' in self.config: self.database_QKan = self.config['database_QKan'] self.dlgpr.tf_qkanDB.setText(self.database_QKan) self.default_dir = os.path.dirname(self.database_QKan) else: self.database_QKan = '' self.default_dir = '.' self.dlgpr.tf_qkanDB.setText(self.database_QKan) # Formularfeld Vorlagedatei if 'projectTemplate' in self.config: projectTemplate = self.config['projectTemplate'] else: projectTemplate = '' # Formularfeld Projektdatei if 'projectfile' in self.config: projectfile = self.config['projectfile'] else: projectfile = '' # Option: Suchpfad für Vorlagedatei auf template-Verzeichnis setzen if 'setPathToTemplateDir' in self.config: self.setPathToTemplateDir = self.config['setPathToTemplateDir'] else: self.setPathToTemplateDir = True self.dlgpr.cb_setPathToTemplateDir.setChecked(self.setPathToTemplateDir) # Option: QKan-Datenbank aktualisieren if 'qkanDBUpdate' in self.config: qkanDBUpdate = self.config['qkanDBUpdate'] else: qkanDBUpdate = True self.dlgpr.cb_qkanDBUpdate.setChecked(qkanDBUpdate) # show the dialog self.dlgpr.show() # Run the dialog event loop result = self.dlgpr.exec_() # See if OK was pressed if result: # Inhalte aus Formular lesen -------------------------------------------------------------- projectTemplate = self.dlgpr.tf_projectTemplate.text() self.database_QKan = self.dlgpr.tf_qkanDB.text() projectfile = self.dlgpr.tf_projectFile.text() self.setPathToTemplateDir = self.dlgpr.cb_setPathToTemplateDir.isChecked() qkanDBUpdate = self.dlgpr.cb_qkanDBUpdate.isChecked() # Konfigurationsdaten schreiben ----------------------------------------------------------- self.config['projectTemplate'] = projectTemplate self.config['database_QKan'] = self.database_QKan self.config['projectfile'] = projectfile self.config['setPathToTemplateDir'] = self.setPathToTemplateDir self.config['qkanDBUpdate'] = qkanDBUpdate with open(self.configfil, 'w') as fileconfig: fileconfig.write(json.dumps(self.config)) qgsadapt(projectTemplate, self.database_QKan, epsg, projectfile, self.setPathToTemplateDir, u'SpatiaLite') # ---------------------------------------------------------------------------------------------------- # Allgemeine QKan-Optionen bearbeiten # 1. Formularfunktionen def dlgop_selectKBS(self): """KBS auswählen. Setzt das KBS für die weiteren Funktionen :returns: void """ projSelector = QgsGenericProjectionSelector() projSelector.exec_() erg = projSelector.selectedAuthId() if len(erg.split(u':')) == 2: self.dlgop.tf_epsg.setText(erg.split(u':')[1]) else: self.dlgop.tf_epsg.setText(erg) def dlgop_fangradiusDefault(self): self.dlgop.tf_fangradius.setText('0.1') def dlgop_mindestflaecheDefault(self): self.dlgop.tf_mindestflaeche.setText('0.5') def dlgop_maxLoopsDefault(self): self.dlgop.tf_max_loops.setText('1000') # ----------------------------------------------------------------------------------------- # 2. Aufruf des Formulars def run_qkanoptions(self): '''Bearbeitung allgemeiner QKan-Optionen''' # Formularfelder setzen ------------------------------------------------------------------------- # Fangradius für Anfang der Anbindungslinie if 'fangradius' in self.config: fangradius = self.config['fangradius'] else: fangradius = u'0.1' self.dlgop.tf_fangradius.setText(str(fangradius)) # Mindestflächengröße if 'mindestflaeche' in self.config: mindestflaeche = self.config['mindestflaeche'] else: mindestflaeche = u'0.5' self.dlgop.tf_mindestflaeche.setText(str(mindestflaeche)) # Maximalzahl Schleifendurchläufe if 'max_loops' in self.config: max_loops = self.config['max_loops'] else: max_loops = '1000' self.dlgop.tf_max_loops.setText(str(max_loops)) # Optionen zum Typ der QKan-Datenbank if 'datenbanktyp' in self.config: datenbanktyp = self.config['datenbanktyp'] else: datenbanktyp = u'spatialite' if datenbanktyp == u'spatialite': self.dlgop.rb_spatialite.setChecked(True) # elif datenbanktyp == u'postgis': # self.dlgop.rb_postgis.setChecked(True) if 'epsg' in self.config: self.epsg = self.config['epsg'] else: self.epsg = u'25832' self.dlgop.tf_epsg.setText(self.epsg) # show the dialog self.dlgop.show() # Run the dialog event loop result = self.dlgop.exec_() # See if OK was pressed if result: # Inhalte aus Formular lesen -------------------------------------------------------------- fangradius = self.dlgop.tf_fangradius.text() mindestflaeche = self.dlgop.tf_mindestflaeche.text() max_loops = self.dlgop.tf_max_loops.text() if self.dlgop.rb_spatialite.isChecked(): datenbanktyp = u'spatialite' # elif self.dlgop.rb_postgis.isChecked(): # datenbanktyp = u'postgis' else: fehlermeldung(u"tools.application.run", u"Fehlerhafte Option: \ndatenbanktyp = {}".format(repr(datenbanktyp))) epsg = self.dlgop.tf_epsg.text() self.config['fangradius'] = fangradius self.config['mindestflaeche'] = mindestflaeche self.config['max_loops'] = max_loops self.config['datenbanktyp'] = datenbanktyp self.config['epsg'] = epsg with open(self.configfil, 'w') as fileconfig: # logger.debug(u"Config-Dictionary: {}".format(self.config)) fileconfig.write(json.dumps(self.config)) # ---------------------------------------------------------------------------------------------------- # Oberflächenabflussparameter in QKan-Tabellen eintragen, ggfs. nur für ausgewählte Teilgebiete # 1. Formularfunktionen def dlgro_selectFile_qkanDB(self): """Datenbankverbindung zur QKan-Datenbank (SpatiLite) auswaehlen.""" filename = QFileDialog.getOpenFileName(self.dlgro, u"QKan-Datenbank auswählen", self.default_dir, "*.sqlite") # if os.path.dirname(filename) != '': # os.chdir(os.path.dirname(filename)) self.dlgro.tf_QKanDB.setText(filename) def dlgro_helpClick(self): """Reaktion auf Klick auf Help-Schaltfläche""" helpfile = os.path.join(self.plugin_dir, '../doc/sphinx/build/html/Qkan_Formulare.html#berechnung-von-oberflachenabflussparametern') webbrowser.open_new_tab(helpfile) def dlgro_lwTeilgebieteClick(self): """Reaktion auf Klick in Tabelle""" self.dlgro.cb_selTgbActive.setChecked(True) self.dlgro_countselection() def dlgro_lwAbflussparamsClick(self): """Reaktion auf Klick in Tabelle""" self.dlgro.cb_selParActive.setChecked(True) self.dlgro_countselection() def dlgro_selTgbActiveClick(self): """Reagiert auf Checkbox zur Aktivierung der Auswahl""" # Checkbox hat den Status nach dem Klick if self.dlgro.cb_selTgbActive.isChecked(): # Nix tun ... logger.debug('\nChecked = True') else: # Auswahl deaktivieren und Liste zurücksetzen anz = self.dlgro.lw_teilgebiete.count() for i in range(anz): item = self.dlgro.lw_teilgebiete.item(i) self.dlgro.lw_teilgebiete.setItemSelected(item, False) # Anzahl in der Anzeige aktualisieren self.dlgro_countselection() def dlgro_selParActiveClick(self): """Reagiert auf Checkbox zur Aktivierung der Auswahl""" # Checkbox hat den Status nach dem Klick if self.dlgro.cb_selParActive.isChecked(): # Nix tun ... logger.debug('\nChecked = True') else: # Auswahl deaktivieren und Liste zurücksetzen anz = self.dlgro.lw_abflussparameter.count() for i in range(anz): item = self.dlgro.lw_abflussparameter.item(i) self.dlgro.lw_abflussparameter.setItemSelected(item, False) # Anzahl in der Anzeige aktualisieren self.dlgro_countselection() def dlgro_countselection(self): """Zählt nach Änderung der Auswahlen in den Listen im Formular die Anzahl der betroffenen Flächen und Haltungen""" liste_teilgebiete = self.dlgro_listselecteditems(self.dlgro.lw_teilgebiete) liste_abflussparameter = self.dlgro_listselecteditems(self.dlgro.lw_abflussparameter) # Auswahl der zu bearbeitenden Flächen auswahl = sqlconditions('WHERE', ('teilgebiet', 'abflussparameter'), (liste_teilgebiete, liste_abflussparameter)) sql = u"""SELECT count(*) AS anzahl FROM flaechen{auswahl}""".format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan_Tools.application.dlgro_countselection (1)"): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlgro.lf_anzahl_flaechen.setText(str(daten[0])) else: self.dlgro.lf_anzahl_flaechen.setText('0') # ------------------------------------------------------------------------- # Funktion zur Zusammenstellung einer Auswahlliste für eine SQL-Abfrage def dlgro_listselecteditems(self, listWidget): """Erstellt eine Liste aus den in einem Auswahllisten-Widget angeklickten Objektnamen :param listWidget: String for translation. :type listWidget: QListWidgetItem :returns: Tuple containing selected teilgebiete :rtype: tuple """ items = listWidget.selectedItems() liste = [] for elem in items: liste.append(elem.text()) return liste def run_runoffparams(self): """Berechnen und Eintragen der Oberflächenabflussparameter in die Tabelle flaechen""" # Check, ob die relevanten Layer nicht editable sind. if len({'flaechen'} & get_editable_layers()) > 0: iface.messageBar().pushMessage(u"Bedienerfehler: ", u'Die zu verarbeitenden Layer dürfen nicht im Status "bearbeitbar" sein. Abbruch!', level=QgsMessageBar.CRITICAL) return False # Übernahme der Quelldatenbank: # Wenn ein Projekt geladen ist, wird die Quelldatenbank daraus übernommen. # Wenn dies nicht der Fall ist, wird die Quelldatenbank aus der # json-Datei übernommen. database_QKan = '' database_QKan, epsg = get_database_QKan() if not database_QKan: if 'database_QKan' in self.config: database_QKan = self.config['database_QKan'] else: database_QKan = '' self.dlgro.tf_QKanDB.setText(database_QKan) # Datenbankverbindung für Abfragen if database_QKan != '': self.dbQK = DBConnection(dbname=database_QKan) # Datenbankobjekt der QKan-Datenbank zum Lesen if self.dbQK is None: fehlermeldung("Fehler in tools.runoffparams", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format(database_QKan)) iface.messageBar().pushMessage("Fehler in tools.runoffparams", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( \ database_QKan), level=QgsMessageBar.CRITICAL) return None # Check, ob alle Teilgebiete in Flächen auch in Tabelle "teilgebiete" enthalten sql = u"""INSERT INTO teilgebiete (tgnam) SELECT teilgebiet FROM flaechen WHERE teilgebiet IS NOT NULL AND teilgebiet NOT IN (SELECT tgnam FROM teilgebiete) GROUP BY teilgebiet""" if not self.dbQK.sql(sql, u"QKan_Tools.application.run (1) "): return False # Check, ob alle Abflussparameter in Flächen auch in Tabelle "abflussparameter" enthalten sql = u"""INSERT INTO abflussparameter (apnam) SELECT abflussparameter FROM flaechen WHERE abflussparameter IS NOT NULL AND abflussparameter NOT IN (SELECT apnam FROM abflussparameter) GROUP BY abflussparameter""" if not self.dbQK.sql(sql, u"QKan_Tools.application.run (2) "): return False self.dbQK.commit() # Anlegen der Tabelle zur Auswahl der Teilgebiete # Zunächst wird die Liste der beim letzten Mal gewählten Teilgebiete aus config gelesen liste_teilgebiete = [] if 'liste_teilgebiete' in self.config: liste_teilgebiete = self.config['liste_teilgebiete'] # Abfragen der Tabelle teilgebiete nach Teilgebieten sql = '''SELECT "tgnam" FROM "teilgebiete" GROUP BY "tgnam"''' if not self.dbQK.sql(sql, u"QKan_Tools.application.run (4) "): return False daten = self.dbQK.fetchall() self.dlgro.lw_teilgebiete.clear() for ielem, elem in enumerate(daten): self.dlgro.lw_teilgebiete.addItem(QListWidgetItem(elem[0])) try: if elem[0] in liste_teilgebiete: self.dlgro.lw_teilgebiete.setCurrentRow(ielem) except BaseException as err: fehlermeldung(u'QKan_Tools (6), Fehler in elem = {}\n'.format(elem), repr(err)) # if len(daten) == 1: # self.dlgro.lw_teilgebiete.setCurrentRow(0) # Anlegen der Tabelle zur Auswahl der Abflussparameter # Zunächst wird die Liste der beim letzten Mal gewählten Abflussparameter aus config gelesen liste_abflussparameter = [] if 'liste_abflussparameter' in self.config: liste_abflussparameter = self.config['liste_abflussparameter'] # Abfragen der Tabelle abflussparameter nach Abflussparametern sql = '''SELECT "apnam" FROM "abflussparameter" GROUP BY "apnam"''' if not self.dbQK.sql(sql, u"QKan_Tools.application.run (4) "): return False daten = self.dbQK.fetchall() self.dlgro.lw_abflussparameter.clear() for ielem, elem in enumerate(daten): self.dlgro.lw_abflussparameter.addItem(QListWidgetItem(elem[0])) try: if elem[0] in liste_abflussparameter: self.dlgro.lw_abflussparameter.setCurrentRow(ielem) except BaseException as err: fehlermeldung(u'QKan_Tools (6), Fehler in elem = {}\n'.format(elem), repr(err)) # if len(daten) == 1: # self.dlgro.lw_abflussparameter.setCurrentRow(0) self.dlgro_countselection() # Optionen zur Berechnung der befestigten Flächen if 'runoffparamstype_choice' in self.config: runoffparamstype_choice = self.config['runoffparamstype_choice'] else: runoffparamstype_choice = u'itwh' if runoffparamstype_choice == u'itwh': self.dlgro.rb_runoffparamsitwh.setChecked(True) elif runoffparamstype_choice == u'dyna': self.dlgro.rb_runoffparamsdyna.setChecked(True) if 'datenbanktyp' in self.config: datenbanktyp = self.config['datenbanktyp'] else: datenbanktyp = 'spatialite' # Formular anzeigen self.dlgro.show() # Run the dialog event loop result = self.dlgro.exec_() # See if OK was pressed if result: # Abrufen der ausgewählten Elemente in den Listen liste_teilgebiete = self.dlgro_listselecteditems(self.dlgro.lw_teilgebiete) liste_abflussparameter = self.dlgro_listselecteditems(self.dlgro.lw_abflussparameter) # Eingaben aus Formular übernehmen database_QKan = self.dlgro.tf_QKanDB.text() if self.dlgro.rb_runoffparamsitwh.isChecked(): runoffparamstype_choice = u'itwh' elif self.dlgro.rb_runoffparamsdyna.isChecked(): runoffparamstype_choice = u'dyna' else: fehlermeldung(u"tools.runoffparams.run_runoffparams", u"Fehlerhafte Option: \nrunoffparamstype_choice = {}".format(repr(runoffparamstype_choice))) # Konfigurationsdaten schreiben self.config['database_QKan'] = database_QKan self.config['liste_teilgebiete'] = liste_teilgebiete self.config['liste_abflussparameter'] = liste_abflussparameter self.config['runoffparamstype_choice'] = runoffparamstype_choice with open(self.configfil, 'w') as fileconfig: # logger.debug(u"Config-Dictionary: {}".format(self.config)) fileconfig.write(json.dumps(self.config)) setRunoffparams(self.dbQK, runoffparamstype_choice, liste_teilgebiete, liste_abflussparameter, datenbanktyp)
class ExportToKP: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ self.templatepath = os.path.join(pluginDirectory('qkan'), u"database/templates") # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'ExportToKP_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlg = ExportToKPDialog() # Anfang Eigene Funktionen ------------------------------------------------- # (jh, 08.02.2017) logger.info('\n\nQKan_ExportKP initialisiert...') # -------------------------------------------------------------------------- # Pfad zum Arbeitsverzeichnis sicherstellen wordir = os.path.join(site.getuserbase(), 'qkan') if not os.path.isdir(wordir): os.makedirs(wordir) # -------------------------------------------------------------------------- # Konfigurationsdatei qkan.json lesen # self.configfil = os.path.join(wordir, 'qkan.json') if os.path.exists(self.configfil): with open(self.configfil, 'r') as fileconfig: self.config = json.loads(fileconfig.read()) else: self.config['dynafile'] = '' # Vorlagedatenbank nur für den Fall, dass der Anwender keine eigene Vorlage erstellen will self.config['template_dyna'] = os.path.join(os.path.dirname(__file__), "templates", "dyna.ein") self.config['database_QKan'] = '' with open(self.configfil, 'w') as fileconfig: fileconfig.write(json.dumps(self.config)) # Standard für Suchverzeichnis festlegen project = QgsProject.instance() self.default_dir = os.path.dirname(project.fileName()) # Formularereignisse anbinden ---------------------------------------------- self.dlg.pb_select_KP_dest.clicked.connect(self.selectFile_kpDB_dest) self.dlg.pb_select_KP_template.clicked.connect(self.selectFile_kpDB_template) self.dlg.lw_teilgebiete.itemClicked.connect(self.lw_teilgebieteClick) self.dlg.cb_selActive.stateChanged.connect(self.selActiveClick) self.dlg.button_box.helpRequested.connect(self.helpClick) self.dlg.pb_selectQKanDB.clicked.connect(self.selectFile_QKanDB) # Ende Eigene Funktionen --------------------------------------------------- # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('ExportToKP', message) def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/qkan/exportdyna/res/icon_qk2kp.png' Dummy.instance.add_action(icon_path, text=self.tr(u'Export in DYNA-Datei...'), callback=self.run, parent=self.iface.mainWindow()) def unload(self): pass # Anfang Eigene Funktionen ------------------------------------------------- # (jh, 08.02.2017) def selectFile_kpDB_dest(self): """Zu erstellende DYNA-Datei eingeben""" filename = QFileDialog.getSaveFileName(self.dlg, "Dateinamen der zu schreibenden DYNA-Datei eingeben", self.default_dir, "*.ein") # if os.path.dirname(filename) != '': # os.chdir(os.path.dirname(filename)) self.dlg.tf_KP_dest.setText(filename) def selectFile_kpDB_template(self): """Vorlage-DYNA-Datei auswaehlen.""" filename = QFileDialog.getOpenFileName(self.dlg, u"Vorlage-DYNA-Datei auswählen", self.default_dir, "*.ein") # if os.path.dirname(filename) != '': # os.chdir(os.path.dirname(filename)) self.dlg.tf_KP_template.setText(filename) def selectFile_QKanDB(self): """Datenbankverbindung zur QKan-Datenbank (SpatiLite) auswaehlen.""" filename = QFileDialog.getOpenFileName(self.dlg, u"QKan-Datenbank auswählen", self.default_dir, "*.sqlite") # if os.path.dirname(filename) != '': # os.chdir(os.path.dirname(filename)) self.dlg.tf_QKanDB.setText(filename) # ------------------------------------------------------------------------- # Formularfunktionen def helpClick(self): """Reaktion auf Klick auf Help-Schaltfläche""" helpfile = os.path.join(self.plugin_dir, '..\doc', 'exportdyna.html') os.startfile(helpfile) def lw_teilgebieteClick(self): """Reaktion auf Klick in Tabelle""" self.dlg.cb_selActive.setChecked(True) self.countselection() def selActiveClick(self): """Reagiert auf Checkbox zur Aktivierung der Auswahl""" # Checkbox hat den Status nach dem Klick if self.dlg.cb_selActive.isChecked(): # Nix tun ... logger.debug('\nChecked = True') else: # Auswahl deaktivieren und Liste zurücksetzen anz = self.dlg.lw_teilgebiete.count() for i in range(anz): item = self.dlg.lw_teilgebiete.item(i) self.dlg.lw_teilgebiete.setItemSelected(item, False) # Anzahl in der Anzeige aktualisieren self.countselection() def countselection(self): """Zählt nach Änderung der Auswahlen in den Listen im Formular die Anzahl der betroffenen Flächen und Haltungen""" liste_teilgebiete = self.listselecteditems(self.dlg.lw_teilgebiete) # Zu berücksichtigende Flächen zählen auswahl = '' if len(liste_teilgebiete) != 0: auswahl = u" WHERE flaechen.teilgebiet in ('{}')".format("', '".join(liste_teilgebiete)) sql = u"""SELECT count(*) AS anzahl FROM flaechen{auswahl}""".format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan_ExportDYNA.application.countselection (1)"): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlg.lf_anzahl_flaechen.setText(str(daten[0])) else: self.dlg.lf_anzahl_flaechen.setText('0') # Zu berücksichtigende Schächte zählen auswahl = '' if len(liste_teilgebiete) != 0: auswahl = u" WHERE schaechte.teilgebiet in ('{}')".format("', '".join(liste_teilgebiete)) sql = u"""SELECT count(*) AS anzahl FROM schaechte{auswahl}""".format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan_ExportDYNA.application.countselection (2) "): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlg.lf_anzahl_schaechte.setText(str(daten[0])) else: self.dlg.lf_anzahl_schaechte.setText('0') # Zu berücksichtigende Haltungen zählen auswahl = '' if len(liste_teilgebiete) != 0: auswahl = u" WHERE haltungen.teilgebiet in ('{}')".format("', '".join(liste_teilgebiete)) sql = u"""SELECT count(*) AS anzahl FROM haltungen{auswahl}""".format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan_ExportDYNA.application.countselection (3) "): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlg.lf_anzahl_haltungen.setText(str(daten[0])) else: self.dlg.lf_anzahl_haltungen.setText('0') # ------------------------------------------------------------------------- # Funktion zur Zusammenstellung einer Auswahlliste für eine SQL-Abfrage def listselecteditems(self, listWidget): """Erstellt eine Liste aus den in einem Auswahllisten-Widget angeklickten Objektnamen :param listWidget: String for translation. :type listWidget: QListWidgetItem :returns: Tuple containing selected teilgebiete :rtype: tuple """ items = listWidget.selectedItems() liste = [] for elem in items: liste.append(elem.text()) return liste # Ende Eigene Funktionen --------------------------------------------------- def run(self): """Run method that performs all the real work""" # show the dialog # Check, ob die relevanten Layer nicht editable sind. if len({'flaechen', 'haltungen', 'linkfl', 'tezg', 'schaechte'} & get_editable_layers()) > 0: iface.messageBar().pushMessage(u"Bedienerfehler: ", u'Die zu verarbeitenden Layer dürfen nicht im Status "bearbeitbar" sein. Abbruch!', level=QgsMessageBar.CRITICAL) return False if 'dynafile' in self.config: dynafile = self.config['dynafile'] else: dynafile = '' self.dlg.tf_KP_dest.setText(dynafile) if 'template_dyna' in self.config: template_dyna = self.config['template_dyna'] else: template_dyna = '' self.dlg.tf_KP_template.setText(template_dyna) if 'datenbanktyp' in self.config: datenbanktyp = self.config['datenbanktyp'] else: datenbanktyp = 'spatialite' pass # Es gibt noch keine Wahlmöglichkeit # Übernahme der Quelldatenbank: # Wenn ein Projekt geladen ist, wird die Quelldatenbank daraus übernommen. # Wenn dies nicht der Fall ist, wird die Quelldatenbank aus der # json-Datei übernommen. database_QKan = '' database_QKan, epsg = get_database_QKan() if not database_QKan: if 'database_QKan' in self.config: database_QKan = self.config['database_QKan'] else: database_QKan = '' self.dlg.tf_QKanDB.setText(database_QKan) # Datenbankverbindung für Abfragen if database_QKan != '': # Nur wenn schon eine Projekt geladen oder eine QKan-Datenbank ausgewählt self.dbQK = DBConnection(dbname=database_QKan) # Datenbankobjekt der QKan-Datenbank zum Lesen if self.dbQK is None: fehlermeldung("Fehler in QKan_CreateUnbefFl", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format(database_QKan)) iface.messageBar().pushMessage("Fehler in QKan_Import_from_HE", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( \ database_QKan), level=QgsMessageBar.CRITICAL) return None # Check, ob alle Teilgebiete in Flächen, Schächten und Haltungen auch in Tabelle "teilgebiete" enthalten sql = u"""INSERT INTO teilgebiete (tgnam) SELECT teilgebiet FROM flaechen WHERE teilgebiet IS NOT NULL AND teilgebiet NOT IN (SELECT tgnam FROM teilgebiete) GROUP BY teilgebiet""" if not self.dbQK.sql(sql, u"QKan_ExportDYNA.application.run (1) "): return False sql = u"""INSERT INTO teilgebiete (tgnam) SELECT teilgebiet FROM haltungen WHERE teilgebiet IS NOT NULL AND teilgebiet NOT IN (SELECT tgnam FROM teilgebiete) GROUP BY teilgebiet""" if not self.dbQK.sql(sql, u"QKan_ExportDYNA.application.run (2) "): return False sql = u"""INSERT INTO teilgebiete (tgnam) SELECT teilgebiet FROM schaechte WHERE teilgebiet IS NOT NULL AND teilgebiet NOT IN (SELECT tgnam FROM teilgebiete) GROUP BY teilgebiet""" if not self.dbQK.sql(sql, u"QKan_ExportDYNA.application.run (3) "): return False self.dbQK.commit() # Anlegen der Tabelle zur Auswahl der Teilgebiete # Zunächst wird die Liste der beim letzten Mal gewählten Teilgebiete aus config gelesen liste_teilgebiete = [] if 'liste_teilgebiete' in self.config: liste_teilgebiete = self.config['liste_teilgebiete'] # Abfragen der Tabelle teilgebiete nach Teilgebieten sql = 'SELECT "tgnam" FROM "teilgebiete" GROUP BY "tgnam"' if not self.dbQK.sql(sql, u"QKan_ExportDYNA.application.run (4) "): return False daten = self.dbQK.fetchall() self.dlg.lw_teilgebiete.clear() for ielem, elem in enumerate(daten): self.dlg.lw_teilgebiete.addItem(QListWidgetItem(elem[0])) try: if elem[0] in liste_teilgebiete: self.dlg.lw_teilgebiete.setCurrentRow(ielem) except BaseException as err: fehlermeldung(u'QKan_ExportDYNA (6), Fehler in elem = {}\n'.format(elem), repr(err)) # if len(daten) == 1: # self.dlg.lw_teilgebiete.setCurrentRow(0) # Ereignis bei Auswahländerung in Liste Teilgebiete self.countselection() # Autokorrektur if 'autokorrektur' in self.config: autokorrektur = self.config['autokorrektur'] else: autokorrektur = True self.dlg.cb_autokorrektur.setChecked(autokorrektur) if 'autonummerierung_dyna' in self.config: autonummerierung_dyna = self.config['autonummerierung_dyna'] else: autonummerierung_dyna = False self.dlg.cb_autonummerierung_dyna.setChecked(autonummerierung_dyna) # Festlegung des Fangradius # Kann über Menü "Optionen" eingegeben werden if 'fangradius' in self.config: fangradius = self.config['fangradius'] else: fangradius = u'0.1' # Mindestflächengröße # Kann über Menü "Optionen" eingegeben werden if 'mindestflaeche' in self.config: mindestflaeche = self.config['mindestflaeche'] else: mindestflaeche = u'0.5' # Maximalzahl Schleifendurchläufe if 'max_loops' in self.config: max_loops = self.config['max_loops'] else: max_loops = 1000 # Optionen zur Berechnung der befestigten Flächen if 'dynabef_choice' in self.config: dynabef_choice = self.config['dynabef_choice'] else: dynabef_choice = u'flaechen' if dynabef_choice == u'flaechen': self.dlg.rb_flaechen.setChecked(True) elif dynabef_choice == u'tezg': self.dlg.rb_tezg.setChecked(True) # Optionen zur Zuordnung des Profilschlüssels if 'dynaprof_choice' in self.config: dynaprof_choice = self.config['dynaprof_choice'] else: dynaprof_choice = u'profilname' if dynaprof_choice == u'profilname': self.dlg.rb_profnam.setChecked(True) elif dynaprof_choice == u'profilkey': self.dlg.rb_profkey.setChecked(True) # Formular anzeigen self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Abrufen der ausgewählten Elemente in beiden Listen liste_teilgebiete = self.listselecteditems(self.dlg.lw_teilgebiete) # Eingaben aus Formular übernehmen database_QKan = self.dlg.tf_QKanDB.text() dynafile = self.dlg.tf_KP_dest.text() template_dyna = self.dlg.tf_KP_template.text() autokorrektur = self.dlg.cb_autokorrektur.isChecked() autonummerierung_dyna = self.dlg.cb_autonummerierung_dyna.isChecked() if self.dlg.rb_flaechen.isChecked(): dynabef_choice = u'flaechen' elif self.dlg.rb_tezg.isChecked(): dynabef_choice = u'tezg' else: fehlermeldung(u"exportdyna.application.run", u"Fehlerhafte Option: \ndynabef_choice = {}".format(repr(dynabef_choice))) if self.dlg.rb_profnam.isChecked(): dynaprof_choice = u'profilname' elif self.dlg.rb_profkey.isChecked(): dynaprof_choice = u'profilkey' else: fehlermeldung(u"exportdyna.application.run", u"Fehlerhafte Option: \ndynaprof_choice = {}".format(repr(dynaprof_choice))) # Konfigurationsdaten schreiben self.config['dynafile'] = dynafile self.config['template_dyna'] = template_dyna self.config['database_QKan'] = database_QKan self.config['liste_teilgebiete'] = liste_teilgebiete self.config['autokorrektur'] = autokorrektur self.config['autonummerierung_dyna'] = autonummerierung_dyna self.config['fangradius'] = fangradius self.config['mindestflaeche'] = mindestflaeche self.config['max_loops'] = max_loops self.config['dynabef_choice'] = dynabef_choice self.config['dynaprof_choice'] = dynaprof_choice with open(self.configfil, 'w') as fileconfig: # logger.debug(u"Config-Dictionary: {}".format(self.config)) fileconfig.write(json.dumps(self.config)) exportKanaldaten(iface, dynafile, template_dyna, self.dbQK, dynabef_choice, dynaprof_choice, liste_teilgebiete, autokorrektur, autonummerierung_dyna, fangradius, mindestflaeche, max_loops, datenbanktyp)
class LinkFl: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'Flaechenzuordnungen_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlg_at = AssigntgebDialog() self.dlg_cl = CreatelineflDialog() self.dlg_sw = CreatelineswDialog() self.dlg_ul = UpdateLinksDialog() self.dlg_mg = ManagegroupsDialog() # Anfang Eigene Funktionen ------------------------------------------------- # (jh, 12.06.2017) logger.info(u'\n\nQKan_LinkFlaechen initialisiert...') # -------------------------------------------------------------------------- # Pfad zum Arbeitsverzeichnis sicherstellen wordir = os.path.join(site.getuserbase(), 'qkan') if not os.path.isdir(wordir): os.makedirs(wordir) # -------------------------------------------------------------------------------------------------- # Konfigurationsdatei qkan.json lesen # self.configfil = os.path.join(wordir, 'qkan.json') if os.path.exists(self.configfil): with open(self.configfil, 'r') as fileconfig: self.config = json.loads(fileconfig.read()) else: self.config = {'epsg': '25832'} # Projektionssystem self.config['autokorrektur'] = False self.config['suchradius'] = u'50' self.config['mindestflaeche'] = u'0.5' self.config['bezug_abstand'] = 'kante' with open(self.configfil, 'w') as fileconfig: fileconfig.write(json.dumps(self.config)) # Formularereignisse anbinden ---------------------------------------------- # Dialog dlg_cl self.dlg_cl.lw_flaechen_abflussparam.itemClicked.connect(self.cl_lw_flaechen_abflussparamClick) self.dlg_cl.lw_hal_entw.itemClicked.connect(self.cl_lw_hal_entwClick) self.dlg_cl.lw_teilgebiete.itemClicked.connect(self.cl_lw_teilgebieteClick) self.dlg_cl.cb_selFlActive.stateChanged.connect(self.cl_selFlActiveClick) self.dlg_cl.cb_selHalActive.stateChanged.connect(self.cl_selHalActiveClick) self.dlg_cl.cb_selTgbActive.stateChanged.connect(self.cl_selTgbActiveClick) self.dlg_cl.button_box.helpRequested.connect(self.cl_helpClick) # Dialog dlg_sw self.dlg_sw.lw_hal_entw.itemClicked.connect(self.sw_lw_hal_entwClick) self.dlg_sw.lw_teilgebiete.itemClicked.connect(self.sw_lw_teilgebieteClick) self.dlg_sw.cb_selHalActive.stateChanged.connect(self.sw_selHalActiveClick) self.dlg_sw.cb_selTgbActive.stateChanged.connect(self.sw_selTgbActiveClick) self.dlg_sw.button_box.helpRequested.connect(self.sw_helpClick) # Dialog dlg_at self.dlg_at.rb_within.clicked.connect(self.select_within) self.dlg_at.rb_overlaps.clicked.connect(self.select_overlaps) # Dialog dlg_mg self.dlg_mg.lw_gruppen.itemClicked.connect(self.listGroupAttr) self.dlg_mg.pb_storegroup.clicked.connect(self.storegrouptgb) self.dlg_mg.pb_reloadgroup.clicked.connect(self.reloadgrouptgb) # Ende Eigene Funktionen --------------------------------------------------- # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('Flaechenzuordnungen', message) def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_assigntgeb_path = ':/plugins/qkan/linkflaechen/res/icon_assigntgeb.png' Dummy.instance.add_action( icon_assigntgeb_path, text=self.tr(u'Alle Elemente des Entwässerungsnetzes zu Teilgebiet zuordnen'), callback=self.run_assigntgeb, parent=self.iface.mainWindow()) icon_createlinefl_path = ':/plugins/qkan/linkflaechen/res/icon_createlinefl.png' Dummy.instance.add_action( icon_createlinefl_path, text=self.tr(u'Erzeuge Verknüpfungslinien von Flaechen zu Haltungen'), callback=self.run_createlinefl, parent=self.iface.mainWindow()) icon_createlinesw_path = ':/plugins/qkan/linkflaechen/res/icon_createlinesw.png' Dummy.instance.add_action( icon_createlinesw_path, text=self.tr(u'Erzeuge Verknüpfungslinien von Direkteinleitungen zu Haltungen'), callback=self.run_createlinesw, parent=self.iface.mainWindow()) icon_updatelinks_path = ':/plugins/qkan/linkflaechen/res/icon_updatelinks.png' Dummy.instance.add_action( icon_updatelinks_path, text=self.tr(u'Verknüpfungen bereinigen'), callback=self.run_updatelinks, parent=self.iface.mainWindow()) icon_managegroups_path = ':/plugins/qkan/linkflaechen/res/icon_managegroups.png' Dummy.instance.add_action( icon_managegroups_path, text=self.tr(u'Teilgebietszuordnungen als Gruppen verwalten'), callback=self.run_managegroups, parent=self.iface.mainWindow()) def unload(self): pass # ------------------------------------------------------------------------- # Formularfunktionen linkfl def cl_helpClick(self): """Reaktion auf Klick auf Help-Schaltfläche""" helpfile = os.path.join(self.plugin_dir, '../doc/sphinx/build/html/Qkan_Formulare.html#automatisches-erzeugen-von-flachenanbindungen') webbrowser.open_new_tab(helpfile) def cl_lw_flaechen_abflussparamClick(self): """Reaktion auf Klick in Tabelle""" self.dlg_cl.cb_selFlActive.setChecked(True) self.countselectionfl() def cl_lw_hal_entwClick(self): """Reaktion auf Klick in Tabelle""" self.dlg_cl.cb_selHalActive.setChecked(True) self.countselectionfl() def cl_lw_teilgebieteClick(self): """Reaktion auf Klick in Tabelle""" self.dlg_cl.cb_selTgbActive.setChecked(True) self.countselectionfl() def cl_selFlActiveClick(self): """Reagiert auf Checkbox zur Aktivierung der Auswahl""" # Checkbox hat den Status nach dem Klick if self.dlg_cl.cb_selFlActive.isChecked(): # Nix tun ... pass else: # Auswahl deaktivieren und Liste zurücksetzen anz = self.dlg_cl.lw_flaechen_abflussparam.count() for i in range(anz): item = self.dlg_cl.lw_flaechen_abflussparam.item(i) self.dlg_cl.lw_flaechen_abflussparam.setItemSelected(item, False) # Anzahl in der Anzeige aktualisieren self.countselectionfl() def cl_selHalActiveClick(self): """Reagiert auf Checkbox zur Aktivierung der Auswahl""" # Checkbox hat den Status nach dem Klick if self.dlg_cl.cb_selHalActive.isChecked(): # Nix tun ... pass else: # Auswahl deaktivieren und Liste zurücksetzen anz = self.dlg_cl.lw_hal_entw.count() for i in range(anz): item = self.dlg_cl.lw_hal_entw.item(i) self.dlg_cl.lw_hal_entw.setItemSelected(item, False) # Anzahl in der Anzeige aktualisieren self.countselectionfl() def cl_selTgbActiveClick(self): """Reagiert auf Checkbox zur Aktivierung der Auswahl""" # Checkbox hat den Status nach dem Klick if self.dlg_cl.cb_selTgbActive.isChecked(): # Nix tun ... pass else: # Auswahl deaktivieren und Liste zurücksetzen anz = self.dlg_cl.lw_teilgebiete.count() for i in range(anz): item = self.dlg_cl.lw_teilgebiete.item(i) self.dlg_cl.lw_teilgebiete.setItemSelected(item, False) # Anzahl in der Anzeige aktualisieren self.countselectionfl() def countselectionfl(self): """Zählt nach Änderung der Auswahlen in den Listen im Formular die Anzahl der betroffenen Flächen und Haltungen""" liste_flaechen_abflussparam = self.listselecteditems(self.dlg_cl.lw_flaechen_abflussparam) liste_hal_entw = self.listselecteditems(self.dlg_cl.lw_hal_entw) liste_teilgebiete = self.listselecteditems(self.dlg_cl.lw_teilgebiete) # Aufbereiten für SQL-Abfrage # Zu berücksichtigende ganze Flächen zählen if len(liste_flaechen_abflussparam) == 0: # Keine Auswahl. Soll eigentlich nicht vorkommen, funktioniert aber... auswahl = u'' logger.debug(u'liste_flaechen_abflussparam:\n{}'.format(liste_flaechen_abflussparam)) else: auswahl = u" AND flaechen.abflussparameter in ('{}')".format(u"', '".join(liste_flaechen_abflussparam)) if len(liste_teilgebiete) != 0: auswahl += u" and flaechen.teilgebiet in ('{}')".format(u"', '".join(liste_teilgebiete)) sql = u"""SELECT count(*) AS anzahl FROM flaechen WHERE (aufteilen <> 'ja' OR aufteilen IS NULL){auswahl}""".format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.countselectionfl (1)"): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlg_cl.lf_anzahl_flaechen.setText(str(daten[0])) else: self.dlg_cl.lf_anzahl_flaechen.setText(u'0') # Zu berücksichtigende zu verschneidende Flächen zählen sql = u"""SELECT count(*) AS anzahl FROM flaechen WHERE aufteilen = 'ja'{auswahl}""".format(auswahl=auswahl) logger.debug(u'sql Flaechen zu verschneiden:\n{}'.format(sql)) if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.countselectionfl (2)"): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlg_cl.lf_anzahl_flaechsec.setText(str(daten[0])) else: self.dlg_cl.lf_anzahl_flaechsec.setText(u'0') # Zu berücksichtigende Haltungen zählen if len(liste_hal_entw) == 0: auswahl = u'' else: auswahl = u" WHERE haltungen.entwart in ('{}')".format(u"', '".join(liste_hal_entw)) if len(liste_teilgebiete) != 0: if auswahl == u'': auswahl = u" WHERE haltungen.teilgebiet in ('{}')".format(u"', '".join(liste_teilgebiete)) else: auswahl += u" and haltungen.teilgebiet in ('{}')".format(u"', '".join(liste_teilgebiete)) sql = u"""SELECT count(*) AS anzahl FROM haltungen{auswahl}""".format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.countselectionfl (3)"): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlg_cl.lf_anzahl_haltungen.setText(str(daten[0])) else: self.dlg_cl.lf_anzahl_haltungen.setText(u'0') # ------------------------------------------------------------------------- # Formularfunktionen linksw def sw_helpClick(self): """Reaktion auf Klick auf Help-Schaltfläche""" helpfile = os.path.join(self.plugin_dir, '../doc/sphinx/build/html/Qkan_Formulare.html#automatisches-erzeugen-von-anbindungen-von-einzeleinleitern') webbrowser.open_new_tab(helpfile) def sw_lw_hal_entwClick(self): """Reaktion auf Klick in Tabelle""" self.dlg_sw.cb_selHalActive.setChecked(True) self.countselectionsw() def sw_lw_teilgebieteClick(self): """Reaktion auf Klick in Tabelle""" self.dlg_sw.cb_selTgbActive.setChecked(True) self.countselectionsw() def sw_selHalActiveClick(self): """Reagiert auf Checkbox zur Aktivierung der Auswahl""" # Checkbox hat den Status nach dem Klick if self.dlg_sw.cb_selHalActive.isChecked(): # Nix tun ... pass else: # Auswahl deaktivieren und Liste zurücksetzen anz = self.dlg_sw.lw_hal_entw.count() for i in range(anz): item = self.dlg_sw.lw_hal_entw.item(i) self.dlg_sw.lw_hal_entw.setItemSelected(item, False) # Anzahl in der Anzeige aktualisieren self.countselectionsw() def sw_selTgbActiveClick(self): """Reagiert auf Checkbox zur Aktivierung der Auswahl""" # Checkbox hat den Status nach dem Klick if self.dlg_sw.cb_selTgbActive.isChecked(): # Nix tun ... pass else: # Auswahl deaktivieren und Liste zurücksetzen anz = self.dlg_sw.lw_teilgebiete.count() for i in range(anz): item = self.dlg_sw.lw_teilgebiete.item(i) self.dlg_sw.lw_teilgebiete.setItemSelected(item, False) # Anzahl in der Anzeige aktualisieren self.countselectionsw() def countselectionsw(self): """Zählt nach Änderung der Auswahlen in den Listen im Formular die Anzahl der betroffenen Haltungen""" liste_hal_entw = self.listselecteditems(self.dlg_sw.lw_hal_entw) liste_teilgebiete = self.listselecteditems(self.dlg_sw.lw_teilgebiete) # Aufbereiten für SQL-Abfrage # Zu berücksichtigende Haltungen zählen if len(liste_hal_entw) == 0: auswahl = u'' else: auswahl = u" WHERE haltungen.entwart in ('{}')".format(u"', '".join(liste_hal_entw)) if len(liste_teilgebiete) != 0: if auswahl == u'': auswahl = u" WHERE haltungen.teilgebiet in ('{}')".format(u"', '".join(liste_teilgebiete)) else: auswahl += u" and haltungen.teilgebiet in ('{}')".format(u"', '".join(liste_teilgebiete)) sql = u"""SELECT count(*) AS anzahl FROM haltungen{auswahl}""".format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.countselectionsw (1)"): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlg_sw.lf_anzahl_haltungen.setText(str(daten[0])) else: self.dlg_sw.lf_anzahl_haltungen.setText(u'0') # Zu berücksichtigende Direkteinleitungen zählen if len(liste_teilgebiete) != 0: auswahl = u" WHERE einleit.teilgebiet in ('{}')".format(u"', '".join(liste_teilgebiete)) else: auswahl = u'' sql = u"""SELECT count(*) AS anzahl FROM einleit{auswahl}""".format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.countselectionsw (2)"): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlg_sw.lf_anzahl_einleit.setText(str(daten[0])) else: self.dlg_sw.lf_anzahl_einleit.setText(u'0') # ------------------------------------------------------------------------- # Funktion zur Zusammenstellung einer Auswahlliste für eine SQL-Abfrage def listselecteditems(self, listWidget): """Erstellt eine Liste aus den in einem Auswahllisten-Widget angeklickten Objektnamen :param listWidget: String for translation. :type listWidget: QListWidgetItem :returns: Tuple containing selected teilgebiete :rtype: tuple """ items = listWidget.selectedItems() liste = [] for elem in items: liste.append(elem.text()) return liste # ---------------------------------------------------------------------------- # Funktion zum Auflisten der Gruppen def showgroups(self): """Abfragen der Tabelle gruppen nach verwendeten vorhandenen Gruppen""" sql = u"""SELECT grnam FROM gruppen GROUP BY grnam""" if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.showgroups (1)"): return False daten = self.dbQK.fetchall() self.dlg_mg.lw_gruppen.clear() for ielem, elem in enumerate(daten): if elem[0] is not None: self.dlg_mg.lw_gruppen.addItem(QListWidgetItem(elem[0])) # ---------------------------------------------------------------------------- # Funktion zum Abfragen der zugeordneten Teilgebiete, betroffenen Tabellen und # Anzahl für eine ausgewählte Gruppe def listGroupAttr(self): # Angeklickte Gruppe aus QListWidget gr = self.listselecteditems(self.dlg_mg.lw_gruppen) if len(gr) > 0: self.gruppe = self.listselecteditems(self.dlg_mg.lw_gruppen)[0] # Im Formular gesetzt: selectionMode = SingleSelection sql = u""" SELECT teilgebiet, tabelle, printf('%i',count(*)) AS Anzahl FROM gruppen WHERE grnam = '{gruppe}' GROUP BY tabelle, teilgebiet ORDER BY tabelle, teilgebiet """.format(gruppe=self.gruppe) if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.listGroupAttr (1)"): return False daten = self.dbQK.fetchall() logger.debug(u'\ndaten: {}'.format(str(daten))) # debug nzeilen = len(daten) self.dlg_mg.tw_gruppenattr.setRowCount(nzeilen) # self.dlg_mg.tw_gruppenattr.setHorizontalHeaderLabels([u"Teilgebiet", u"Tabelle", u"Anzahl"]) self.dlg_mg.tw_gruppenattr.setColumnWidth(0, 174) # 17 Pixel für Rand und Nummernspalte (und je Spalte?) self.dlg_mg.tw_gruppenattr.setColumnWidth(1, 80) self.dlg_mg.tw_gruppenattr.setColumnWidth(2, 50) for i, elem in enumerate(daten): for j, item in enumerate(elem): self.dlg_mg.tw_gruppenattr.setItem(i, j, QTableWidgetItem(elem[j])) self.dlg_mg.tw_gruppenattr.setRowHeight(i, 20) def reloadgrouptgb(self): reloadgroup(self.dbQK, self.gruppe, dbtyp = u'SpatiaLite') iface.messageBar().pushMessage(u"Fertig!", u'Teilgebiete wurden geladen!', level=QgsMessageBar.INFO) def storegrouptgb(self): neuegruppe = self.dlg_mg.tf_newgroup.text() if neuegruppe != u'' and neuegruppe is not None: kommentar = self.dlg_mg.tf_kommentar.toPlainText() if kommentar is None: kommentar = u'' storegroup(self.dbQK, neuegruppe, kommentar, dbtyp = u'SpatiaLite') self.showgroups() iface.messageBar().pushMessage(u"Fertig!", u'Teilgebiete wurden gespeichert', level=QgsMessageBar.INFO) # ------------------------------------------------------------------------- # Öffnen des Formulars zur Erstellung der Verknüpfungen def run_createlinefl(self): """Run method that performs all the real work""" # Check, ob die relevanten Layer nicht editable sind. if len({u'flaechen', u'haltungen', u'linkfl'} & get_editable_layers()) > 0: iface.messageBar().pushMessage(u"Bedienerfehler: ", u'Die zu verarbeitenden Layer dürfen nicht im Status "bearbeitbar" sein. Abbruch!', level=QgsMessageBar.CRITICAL) return False database_QKan = u'' database_QKan, epsg = get_database_QKan() if not database_QKan: fehlermeldung(u"Fehler in k_link", u"database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") logger.error(u"k_link: database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") return False # Datenbankverbindung für Abfragen self.dbQK = DBConnection(dbname=database_QKan) # Datenbankobjekt der QKan-Datenbank zum Lesen if self.dbQK is None: fehlermeldung(u"Fehler in LinkFl.run_createlinefl", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format(database_QKan)) iface.messageBar().pushMessage(u"Fehler in LinkFl.run_createlinefl", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( \ database_QKan), level=QgsMessageBar.CRITICAL) return None # Check, ob alle Teilgebiete in Flächen und Haltungen auch in Tabelle "teilgebiete" enthalten sql = u"""INSERT INTO teilgebiete (tgnam) SELECT teilgebiet FROM flaechen WHERE teilgebiet IS NOT NULL AND teilgebiet <> '' AND teilgebiet NOT IN (SELECT tgnam FROM teilgebiete) GROUP BY teilgebiet""" if not self.dbQK.sql(sql, u"QKan_LinkFlaechen (1)"): return False sql = u"""INSERT INTO teilgebiete (tgnam) SELECT teilgebiet FROM haltungen WHERE teilgebiet IS NOT NULL AND teilgebiet <> '' AND teilgebiet NOT IN (SELECT tgnam FROM teilgebiete) GROUP BY teilgebiet""" if not self.dbQK.sql(sql, u"QKan_LinkFlaechen (1)"): return False self.dbQK.commit() # Abfragen der Tabelle flaechen nach verwendeten Abflussparametern sql = u'SELECT abflussparameter FROM flaechen GROUP BY abflussparameter' if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.run_createlinefl (1)"): return False daten = self.dbQK.fetchall() # logger.debug(u'\ndaten: {}'.format(str(daten))) # debug self.dlg_cl.lw_flaechen_abflussparam.clear() for ielem, elem in enumerate(daten): if elem[0] is not None: self.dlg_cl.lw_flaechen_abflussparam.addItem(QListWidgetItem(elem[0])) if 'liste_flaechen_abflussparam' in self.config: try: if elem[0] in self.config['liste_flaechen_abflussparam']: self.dlg_cl.lw_flaechen_abflussparam.setCurrentRow(ielem) self.dlg_cl.cb_selFlActive.setChecked(True) # Auswahlcheckbox aktivieren except BaseException as err: del self.dbQK # logger.debug(u'\nelem: {}'.format(str(elem))) # debug # if len(daten) == 1: # self.dlg_cl.lw_flaechen_abflussparam.setCurrentRow(0) # Abfragen der Tabelle haltungen nach vorhandenen Entwässerungsarten sql = u'SELECT "entwart" FROM "haltungen" GROUP BY "entwart"' if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.run_createlinefl (2)"): return False daten = self.dbQK.fetchall() self.dlg_cl.lw_hal_entw.clear() for ielem, elem in enumerate(daten): if elem[0] is not None: self.dlg_cl.lw_hal_entw.addItem(QListWidgetItem(elem[0])) if 'liste_hal_entw' in self.config: if elem[0] in self.config['liste_hal_entw']: self.dlg_cl.lw_hal_entw.setCurrentRow(ielem) self.dlg_cl.cb_selHalActive.setChecked(True) # Auswahlcheckbox aktivieren # if len(daten) == 1: # self.dlg_cl.lw_hal_entw.setCurrentRow(0) # Abfragen der Tabelle teilgebiete nach Teilgebieten sql = u'SELECT "tgnam" FROM "teilgebiete" GROUP BY "tgnam"' if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.run_createlinefl (3)"): return False daten = self.dbQK.fetchall() self.dlg_cl.lw_teilgebiete.clear() for ielem, elem in enumerate(daten): if elem[0] is not None: self.dlg_cl.lw_teilgebiete.addItem(QListWidgetItem(elem[0])) if 'liste_teilgebiete' in self.config: if elem[0] in self.config['liste_teilgebiete']: self.dlg_cl.lw_teilgebiete.setCurrentRow(ielem) self.dlg_cl.cb_selTgbActive.setChecked(True) # Auswahlcheckbox aktivieren # if len(daten) == 1: # self.dlg_cl.lw_teilgebiete.setCurrentRow(0) # config in Dialog übernehmen # Autokorrektur if 'autokorrektur' in self.config: autokorrektur = self.config['autokorrektur'] else: autokorrektur = True self.dlg_cl.cb_autokorrektur.setChecked(autokorrektur) # Verbindungslinien nur innerhalb tezg if 'linksw_in_tezg' in self.config: linksw_in_tezg = self.config['linksw_in_tezg'] else: linksw_in_tezg = True self.dlg_cl.cb_linkswInTezg.setChecked(linksw_in_tezg) # Suchradius if 'suchradius' in self.config: suchradius = self.config['suchradius'] else: suchradius = u'50' self.dlg_cl.tf_suchradius.setText(str(suchradius)) # Mindestflächengröße if 'mindestflaeche' in self.config: mindestflaeche = self.config['mindestflaeche'] else: mindestflaeche = u'0.5' # Fangradius für Anfang der Anbindungslinie # Kann über Menü "Optionen" eingegeben werden if 'fangradius' in self.config: fangradius = self.config['fangradius'] else: fangradius = u'0.1' # Festlegung, ob sich der Abstand auf die Flächenkante oder deren Mittelpunkt bezieht if 'bezug_abstand' in self.config: bezug_abstand = self.config['bezug_abstand'] else: bezug_abstand = 'kante' if bezug_abstand == 'kante': self.dlg_cl.rb_abstandkante.setChecked(True) elif bezug_abstand == 'mittelpunkt': self.dlg_cl.rb_abstandmittelpunkt.setChecked(True) else: fehlermeldung(u"Fehler im Programmcode", u"Nicht definierte Option") return False self.countselectionfl() # show the dialog self.dlg_cl.show() # Run the dialog event loop result = self.dlg_cl.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. # pass # Start der Verarbeitung # Abrufen der ausgewählten Elemente in beiden Listen liste_flaechen_abflussparam = self.listselecteditems(self.dlg_cl.lw_flaechen_abflussparam) liste_hal_entw = self.listselecteditems(self.dlg_cl.lw_hal_entw) liste_teilgebiete = self.listselecteditems(self.dlg_cl.lw_teilgebiete) suchradius = self.dlg_cl.tf_suchradius.text() if self.dlg_cl.rb_abstandkante.isChecked(): bezug_abstand = 'kante' elif self.dlg_cl.rb_abstandmittelpunkt.isChecked(): bezug_abstand = 'mittelpunkt' else: fehlermeldung(u"Fehler im Programmcode", u"Nicht definierte Option") return False autokorrektur = self.dlg_cl.cb_autokorrektur.isChecked() linksw_in_tezg = self.dlg_cl.cb_linkswInTezg.isChecked() # if len(liste_flaechen_abflussparam) == 0 or len(liste_hal_entw) == 0: # iface.messageBar().pushMessage(u"Bedienerfehler: ", # u'Bitte in beiden Tabellen mindestens ein Element auswählen!', # level=QgsMessageBar.CRITICAL) # self.run_createlinefl() # Konfigurationsdaten schreiben self.config['suchradius'] = suchradius self.config['fangradius'] = fangradius self.config['mindestflaeche'] = mindestflaeche self.config['bezug_abstand'] = bezug_abstand self.config['liste_hal_entw'] = liste_hal_entw self.config['liste_flaechen_abflussparam'] = liste_flaechen_abflussparam self.config['liste_teilgebiete'] = liste_teilgebiete self.config['epsg'] = epsg self.config['autokorrektur'] = autokorrektur self.config['linksw_in_tezg'] = linksw_in_tezg with open(self.configfil, 'w') as fileconfig: fileconfig.write(json.dumps(self.config)) # Start der Verarbeitung createlinkfl(self.dbQK, liste_flaechen_abflussparam, liste_hal_entw, liste_teilgebiete, linksw_in_tezg, autokorrektur, suchradius, mindestflaeche, fangradius, bezug_abstand, epsg) # Einfügen der Verbindungslinien in die Layerliste, wenn nicht schon geladen layers = iface.legendInterface().layers() if u'Anbindungen Flächen' not in [lay.name() for lay in layers]: # layers wurde oben erstellt uri = QgsDataSourceURI() uri.setDatabase(database_QKan) uri.setDataSource(u'', u'linkfl', u'glink') vlayer = QgsVectorLayer(uri.uri(), u'Anbindungen Flächen', u'spatialite') QgsMapLayerRegistry.instance().addMapLayer(vlayer) # -------------------------------------------------------------------------- # Datenbankverbindungen schliessen del self.dbQK # ------------------------------------------------------------------------- # Öffnen des Formulars zur Erstellung der Verknüpfungen def run_createlinesw(self): """Run method that performs all the real work""" # Check, ob die relevanten Layer nicht editable sind. if len({u'einleit', u'haltungen', u'linksw'} & get_editable_layers()) > 0: iface.messageBar().pushMessage(u"Bedienerfehler: ", u'Die zu verarbeitenden Layer dürfen nicht im Status "bearbeitbar" sein. Abbruch!', level=QgsMessageBar.CRITICAL) return False database_QKan = u'' database_QKan, epsg = get_database_QKan() if not database_QKan: fehlermeldung(u"Fehler in LinkFl.run_createlinesw", u"database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") logger.error(u"LinkFl.run_createlinesw: database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") return False # Datenbankverbindung für Abfragen self.dbQK = DBConnection(dbname=database_QKan) # Datenbankobjekt der QKan-Datenbank zum Lesen if self.dbQK is None: fehlermeldung(u"Fehler in LinkFl.run_createlinesw", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format(database_QKan)) iface.messageBar().pushMessage(u"Fehler in LinkFl.run_createlinesw", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( \ database_QKan), level=QgsMessageBar.CRITICAL) return None # Check, ob alle Teilgebiete in Flächen und Haltungen auch in Tabelle "teilgebiete" enthalten sql = u"""INSERT INTO teilgebiete (tgnam) SELECT teilgebiet FROM einleit WHERE teilgebiet IS NOT NULL AND teilgebiet <> '' AND teilgebiet NOT IN (SELECT tgnam FROM teilgebiete) GROUP BY teilgebiet""" if not self.dbQK.sql(sql, u"LinkFl.run_createlinesw (1)"): return False sql = u"""INSERT INTO teilgebiete (tgnam) SELECT teilgebiet FROM haltungen WHERE teilgebiet IS NOT NULL AND teilgebiet <> '' AND teilgebiet NOT IN (SELECT tgnam FROM teilgebiete) GROUP BY teilgebiet""" if not self.dbQK.sql(sql, u"LinkFl.run_createlinesw (2)"): return False self.dbQK.commit() # Abfragen der Tabelle haltungen nach vorhandenen Entwässerungsarten sql = u'SELECT "entwart" FROM "haltungen" GROUP BY "entwart"' if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.run_createlinesw (1)"): return False daten = self.dbQK.fetchall() self.dlg_sw.lw_hal_entw.clear() for ielem, elem in enumerate(daten): if elem[0] is not None: self.dlg_sw.lw_hal_entw.addItem(QListWidgetItem(elem[0])) if 'liste_hal_entw' in self.config: if elem[0] in self.config['liste_hal_entw']: self.dlg_sw.lw_hal_entw.setCurrentRow(ielem) self.dlg_sw.cb_selHalActive.setChecked(True) # Auswahlcheckbox aktivieren # if len(daten) == 1: # self.dlg_sw.lw_hal_entw.setCurrentRow(0) # Abfragen der Tabelle teilgebiete nach Teilgebieten sql = u'SELECT "tgnam" FROM "teilgebiete" GROUP BY "tgnam"' if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.run_createlinesw (2)"): return False daten = self.dbQK.fetchall() self.dlg_sw.lw_teilgebiete.clear() for ielem, elem in enumerate(daten): if elem[0] is not None: self.dlg_sw.lw_teilgebiete.addItem(QListWidgetItem(elem[0])) if 'liste_teilgebiete' in self.config: if elem[0] in self.config['liste_teilgebiete']: self.dlg_sw.lw_teilgebiete.setCurrentRow(ielem) self.dlg_sw.cb_selTgbActive.setChecked(True) # Auswahlcheckbox aktivieren # if len(daten) == 1: # self.dlg_sw.lw_teilgebiete.setCurrentRow(0) # config in Dialog übernehmen # Suchradius if 'suchradius' in self.config: suchradius = self.config['suchradius'] else: suchradius = u'50' self.dlg_sw.tf_suchradius.setText(str(suchradius)) # Haltungen direkt in einleit eintragen. Es kann wegen der längeren Zeitdauer sinnvoll # sein, dies erst am Schluss der Bearbeitung in einem eigenen Vorgang zu machen. self.countselectionsw() # show the dialog self.dlg_sw.show() # Run the dialog event loop result = self.dlg_sw.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. # pass # Start der Verarbeitung # Inhalte aus Formular lesen suchradius = self.dlg_sw.tf_suchradius.text() # Abrufen der ausgewählten Elemente in beiden Listen liste_hal_entw = self.listselecteditems(self.dlg_sw.lw_hal_entw) liste_teilgebiete = self.listselecteditems(self.dlg_sw.lw_teilgebiete) # Konfigurationsdaten schreiben self.config['suchradius'] = suchradius self.config['liste_hal_entw'] = liste_hal_entw self.config['liste_teilgebiete'] = liste_teilgebiete self.config['epsg'] = epsg with open(self.configfil, 'w') as fileconfig: fileconfig.write(json.dumps(self.config)) # Start der Verarbeitung createlinksw(self.dbQK, liste_teilgebiete, suchradius, epsg) # Einfügen der Verbindungslinien in die Layerliste, wenn nicht schon geladen layers = iface.legendInterface().layers() if u'Anbindungen Direkteinleitungen' not in [lay.name() for lay in layers]: # layers wurde oben erstellt uri = QgsDataSourceURI() uri.setDatabase(database_QKan) uri.setDataSource(u'', u'linksw', u'glink') vlayer = QgsVectorLayer(uri.uri(), u'Anbindungen Direkteinleitungen', u'spatialite') QgsMapLayerRegistry.instance().addMapLayer(vlayer) # -------------------------------------------------------------------------- # Datenbankverbindungen schliessen del self.dbQK # Zuordnen der Haltungs- etc. -objekte zu (ausgewählten) Teilgebieten # Hilfsfunktionen def enable_bufferradius(self, onoff=True): """Aktiviert/Deaktiviert die Eingabe der Pufferbreite abhängig von der Auswahloption""" self.dlg_at.lb_bufferradius.setEnabled(onoff) self.dlg_at.tf_bufferradius.setEnabled(onoff) self.dlg_at.unit_bufferradius.setEnabled(onoff) def select_within(self): """Aktiviert die Eingabe der Pufferbreite""" self.enable_bufferradius(True) def select_overlaps(self): """Deaktiviert die Eingabe der Pufferbreite""" self.enable_bufferradius(False) # ------------------------------------------------------------------------- # Öffnen des Formulars def run_assigntgeb(self): """Öffnen des Formulars zur Zuordnung von Teilgebieten auf Haltungen und Flächen""" # Check, ob die relevanten Layer nicht editable sind. if len({u'flaechen', u'haltungen', u'linkfl', u'linksw', u'tezg', u'einleit'} & get_editable_layers()) > 0: iface.messageBar().pushMessage(u"Bedienerfehler: ", u'Die zu verarbeitenden Layer dürfen nicht im Status "bearbeitbar" sein. Abbruch!', level=QgsMessageBar.CRITICAL) return False database_QKan = u'' database_QKan, epsg = get_database_QKan() if not database_QKan: fehlermeldung(u"Fehler in k_link", u"database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") logger.error(u"k_link: database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") return False # Datenbankverbindung für Abfragen self.dbQK = DBConnection(dbname=database_QKan) # Datenbankobjekt der QKan-Datenbank zum Lesen if self.dbQK is None: fehlermeldung(u"Fehler in LinkFl.run_assigntgeb", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format(database_QKan)) iface.messageBar().pushMessage(u"Fehler in LinkFl.run_assigntgeb", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( \ database_QKan), level=QgsMessageBar.CRITICAL) return None # config in Dialog übernehmen # Autokorrektur if 'autokorrektur' in self.config: autokorrektur = self.config['autokorrektur'] else: autokorrektur = True self.dlg_at.cb_autokorrektur.setChecked(autokorrektur) # Abfragen der Tabelle teilgebiete nach Teilgebieten sql = u'SELECT "tgnam" FROM "teilgebiete" GROUP BY "tgnam"' if not self.dbQK.sql(sql, u"QKan_LinkFlaechen.run_assigntgeb (1)"): return False daten = self.dbQK.fetchall() self.dlg_at.lw_teilgebiete.clear() for ielem, elem in enumerate(daten): if elem[0] is not None: self.dlg_at.lw_teilgebiete.addItem(QListWidgetItem(elem[0])) if 'liste_teilgebiete' in self.config: if elem[0] in self.config['liste_teilgebiete']: self.dlg_at.lw_teilgebiete.setCurrentRow(ielem) # Festlegung, ob die Auswahl nur Objekte innerhalb oder aller überlappenden berücksichtigt if 'auswahltyp' in self.config: auswahltyp = self.config['auswahltyp'] else: auswahltyp = u'within' if auswahltyp == u'within': self.dlg_at.rb_within.setChecked(True) self.enable_bufferradius(True) elif auswahltyp == u'overlaps': self.dlg_at.rb_overlaps.setChecked(True) self.enable_bufferradius(False) else: fehlermeldung(u"Fehler im Programmcode (3)", u"Nicht definierte Option") return False # Festlegung des Pufferradius if 'bufferradius' in self.config: bufferradius = self.config['bufferradius'] else: bufferradius = u'0' self.dlg_at.tf_bufferradius.setText(bufferradius) # show the dialog self.dlg_at.show() # Run the dialog event loop result = self.dlg_at.exec_() # See if OK was pressed if result: # Inhalte aus Formular lesen liste_teilgebiete = self.listselecteditems(self.dlg_at.lw_teilgebiete) if self.dlg_at.rb_within.isChecked(): auswahltyp = u'within' elif self.dlg_at.rb_overlaps.isChecked(): auswahltyp = u'overlaps' else: fehlermeldung(u"Fehler im Programmcode (4)", u"Nicht definierte Option") return False autokorrektur = self.dlg_at.cb_autokorrektur.isChecked() bufferradius = self.dlg_at.tf_bufferradius.text() # config schreiben self.config['liste_teilgebiete'] = liste_teilgebiete self.config['auswahltyp'] = auswahltyp self.config['epsg'] = epsg self.config['bufferradius'] = bufferradius self.config['autokorrektur'] = autokorrektur with open(self.configfil, 'w') as fileconfig: fileconfig.write(json.dumps(self.config)) # Start der Verarbeitung assigntgeb(self.dbQK, auswahltyp, liste_teilgebiete, [u'haltungen', u'flaechen', u'schaechte', u'einleit', u'tezg', u'linksw', u'linkfl'], autokorrektur, bufferradius) # -------------------------------------------------------------------------- # Datenbankverbindungen schliessen del self.dbQK # ---------------------------------------------------------------------------------------------- # Laden und Speichern von Teilgebietszuordnungen als Gruppe def run_managegroups(self): """Speichern und Wiederherstellen von Teilgebietszuordnungen als Gruppe""" # Check, ob die relevanten Layer nicht editable sind. if len({u'flaechen', u'haltungen', u'schaechte', u'linksw', u'einleit', u'linkfl', u'teilgebiete', u'tezg'} & get_editable_layers()) > 0: iface.messageBar().pushMessage(u"Bedienerfehler: ", u'Die zu verarbeitenden Layer dürfen nicht im Status "bearbeitbar" sein. Abbruch!', level=QgsMessageBar.CRITICAL) return False database_QKan = u'' database_QKan, epsg = get_database_QKan() if not database_QKan: fehlermeldung(u"Fehler in LinkFl.run_managegroups", u"database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") logger.error(u"CreateUnbefFl: database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") return False self.dbQK = DBConnection(dbname=database_QKan) # Datenbankobjekt der QKan-Datenbank zum Lesen if self.dbQK is None: fehlermeldung(u"Fehler in LinkFl.run_managegroups", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format(database_QKan)) iface.messageBar().pushMessage(u"Fehler in LinkFl.run_managegroups", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( \ database_QKan), level=QgsMessageBar.CRITICAL) return None self.showgroups() self.dlg_mg.lw_gruppen.setCurrentRow(0) # Anzeige initialisieren self.listGroupAttr() # show the dialog self.dlg_mg.show() # Run the dialog event loop result = self.dlg_mg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass # Start der Verarbeitung # Nur Formular schließen # ---------------------------------------------------------------------------------------------- # Datenbankverbindungen schliessen del self.dbQK # ---------------------------------------------------------------------------------------------- # Logischen Cache der Verknüpfungen aktualisieren def run_updatelinks(self): '''Aktualisieren des logischen Verknüpfungscaches in linkfl und linksw''' # Check, ob die relevanten Layer nicht editable sind. if len({u'flaechen', u'haltungen', u'linkfl', u'linksw', u'tezg', u'einleit'} & get_editable_layers()) > 0: iface.messageBar().pushMessage(u"Bedienerfehler: ", u'Die zu verarbeitenden Layer dürfen nicht im Status "bearbeitbar" sein. Abbruch!', level=QgsMessageBar.CRITICAL) return False database_QKan = u'' database_QKan, epsg = get_database_QKan() if not database_QKan: fehlermeldung(u"Fehler in k_link", u"database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") logger.error(u"k_link: database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") return False # Datenbankverbindung für Abfragen self.dbQK = DBConnection(dbname=database_QKan) # Datenbankobjekt der QKan-Datenbank zum Lesen if self.dbQK is None: fehlermeldung(u"Fehler in LinkFl.run_assigntgeb", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format(database_QKan)) iface.messageBar().pushMessage(u"Fehler in LinkFl.run_assigntgeb", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( \ database_QKan), level=QgsMessageBar.CRITICAL) return False self.dlg_ul.tf_qkDB.setText(database_QKan) # Festlegung des Fangradius # Kann über Menü "Optionen" eingegeben werden if 'fangradius' in self.config: fangradius = self.config['fangradius'] else: fangradius = u'0.1' # Löschen von Flächenverknüpfungen ohne Linienobjekt if 'deletelinkflGeomNone' in self.config: deletelinkflGeomNone = self.config['deletelinkflGeomNone'] else: deletelinkflGeomNone = True self.dlg_ul.cb_deleteGeomNone.setChecked(deletelinkflGeomNone) # show the dialog self.dlg_ul.show() # Run the dialog event loop result = self.dlg_ul.exec_() # See if OK was pressed if result: # Inhalte aus Formular lesen deletelinkflGeomNone = self.dlg_ul.cb_deleteGeomNone.isChecked() # config schreiben self.config['deletelinkflGeomNone'] = deletelinkflGeomNone self.config['fangradius'] = fangradius with open(self.configfil, 'w') as fileconfig: fileconfig.write(json.dumps(self.config)) # Start der Verarbeitung if self.dlg_ul.cb_linkfl.isChecked(): updatelinkfl(self.dbQK, fangradius, deletelinkflGeomNone) if self.dlg_ul.cb_linksw.isChecked(): updatelinksw(self.dbQK, fangradius, deletelinkflGeomNone) # ---------------------------------------------------------------------------------------------- # Datenbankverbindungen schliessen del self.dbQK
def importResults(database_HE, database_QKan, qml_choice, qmlfileResults, epsg=25832, dbtyp=u'SpatiaLite'): '''Importiert Simulationsergebnisse aus einer HE-Firebird-Datenbank und schreibt diese in Tabellen der QKan-SpatiaLite-Datenbank. :database_HE: Datenbankobjekt, das die Verknüpfung zur HE-Firebird-Datenbank verwaltet :type database: DBConnection (geerbt von firebirdsql...) :database_QKan: Datenbankobjekt, das die Verknüpfung zur QKan-SpatiaLite-Datenbank verwaltet. :type database: DBConnection (geerbt von dbapi...) :dbtyp: Typ der Datenbank (SpatiaLite, PostGIS) :type dbtyp: String :returns: void ''' # ------------------------------------------------------------------------------ # Datenbankverbindungen dbHE = FBConnection( database_HE) # Datenbankobjekt der HE-Datenbank zum Lesen if dbHE is None: fehlermeldung( u"Fehler in QKan_Import_from_HE", u'ITWH-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( database_HE)) return None dbQK = DBConnection(dbname=database_QKan ) # Datenbankobjekt der QKan-Datenbank zum Schreiben if not dbQK.connected: return None if dbQK is None: fehlermeldung( u"Fehler in QKan_Import_from_HE", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( database_QKan)) return None # Vorbereiten der temporären Ergebnistabellen sqllist = [ u'''CREATE TABLE IF NOT EXISTS ResultsSch( pk INTEGER PRIMARY KEY AUTOINCREMENT, schnam TEXT, uebstauhaeuf REAL, uebstauanz REAL, maxuebstauvol REAL, kommentar TEXT, createdat TEXT DEFAULT CURRENT_DATE)''', u"""SELECT AddGeometryColumn('ResultsSch','geom',{},'POINT',2)""". format(epsg), u'''DELETE FROM ResultsSch''' ] # , u'''CREATE TABLE IF NOT EXISTS ResultsHal( # pk INTEGER PRIMARY KEY AUTOINCREMENT, # haltnam TEXT, # uebstauhaeuf REAL, # uebstauanz REAL, # maxuebstauvol REAL, # kommentar TEXT, # createdat TEXT DEFAULT CURRENT_DATE)''', # u"""SELECT AddGeometryColumn('ResultsHal','geom',{},'LINESTRING',2)""".format(epsg) # u'''DELETE FROM ResultsHal'''] for sql in sqllist: if not dbQK.sql(sql, u"QKan_Import_Results (1)"): return False # Die folgende Abfrage gilt sowohl bei Einzel- als auch bei Seriensimulationen: sql = u'''SELECT MR.KNOTEN, LZ.HAEUFIGKEITUEBERSTAU, LZ.ANZAHLUEBERSTAU, MR.UEBERSTAUVOLUMEN FROM LAU_MAX_S AS MR LEFT JOIN LANGZEITKNOTEN AS LZ ON MR.KNOTEN = LZ.KNOTEN ORDER BY KNOTEN''' if not dbHE.sql(sql, u"QKan_Import_Results (4)"): return False for attr in dbHE.fetchall(): # In allen Feldern None durch NULL ersetzen (schnam, uebstauhaeuf, uebstauanz, maxuebstauvol) = \ (u'NULL' if el is None else el for el in attr) sql = u'''INSERT INTO ResultsSch (schnam, uebstauhaeuf, uebstauanz, maxuebstauvol, kommentar) VALUES ('{schnam}', {uebstauhaeuf}, {uebstauanz}, {maxuebstauvol}, '{kommentar}')'''.format( schnam=schnam, uebstauhaeuf=uebstauhaeuf, uebstauanz=uebstauanz, maxuebstauvol=maxuebstauvol, kommentar=os.path.basename(database_HE)) if not dbQK.sql(sql, u'QKan_Import_Results (5)'): return False sql = '''UPDATE ResultsSch SET geom = ( SELECT geop FROM schaechte WHERE schaechte.schnam = ResultsSch.schnam)''' if not dbQK.sql(sql, u'QKan_Import_Results (6)'): return False dbQK.commit() # Einfügen der Ergebnistabelle in die Layerliste, wenn nicht schon geladen layers = iface.legendInterface().layers() if u'Ergebnisse_LZ' not in [lay.name() for lay in layers]: uri = QgsDataSourceURI() uri.setDatabase(database_QKan) uri.setDataSource(u'', u'ResultsSch', u'geom') vlayer = QgsVectorLayer(uri.uri(), u'Überstau Schächte', u'spatialite') QgsMapLayerRegistry.instance().addMapLayer(vlayer) # Stilvorlage nach Benutzerwahl laden templatepath = os.path.join(pluginDirectory('qkan'), u"templates") if qml_choice == 'uebh': template = os.path.join(templatepath, u"Überstauhäufigkeit.qml") try: vlayer.loadNamedStyle(template) except: fehlermeldung( u"Fehler in QKan_Results_from_HE", u'Stildatei "Überstauhäufigkeit.qml" wurde nicht gefunden!\nAbbruch!' ) elif qml_choice == 'uebvol': template = os.path.join(templatepath, u"Überstauvolumen.qml") try: vlayer.loadNamedStyle(template) except: fehlermeldung( u"Fehler in QKan_Results_from_HE", u'Stildatei "Überstauvolumen.qml" wurde nicht gefunden!\nAbbruch!' ) elif qml_choice == 'userqml': try: vlayer.loadNamedStyle(qmlfileResults) except: fehlermeldung( u"Fehler in QKan_Results_from_HE", u'Benutzerdefinierte Stildatei {:s} wurde nicht gefunden!\nAbbruch!' .format(qml_choice)) del dbQK del dbHE
class ExportToHE: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ self.templatepath = os.path.join(pluginDirectory('qkan'), u"templates") # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'ExportToHE_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlg = ExportToHEDialog() # Anfang Eigene Funktionen ------------------------------------------------- # (jh, 08.02.2017) logger.info('\n\nQKan_ExportHE initialisiert...') # -------------------------------------------------------------------------- # Pfad zum Arbeitsverzeichnis sicherstellen wordir = os.path.join(site.getuserbase(), 'qkan') if not os.path.isdir(wordir): os.makedirs(wordir) # -------------------------------------------------------------------------- # Konfigurationsdatei qkan.json lesen # self.configfil = os.path.join(wordir, 'qkan.json') if os.path.exists(self.configfil): with open(self.configfil, 'r') as fileconfig: self.config = json.loads(fileconfig.read()) else: self.config['database_HE'] = '' # Vorlagedatenbank nur für den Fall, dass der Anwender keine eigene Vorlage erstellen will self.config['dbtemplate_HE'] = os.path.join(os.path.dirname(__file__), "templates", "itwh.idbf") self.config['database_QKan'] = '' with open(self.configfil, 'w') as fileconfig: fileconfig.write(json.dumps(self.config)) # Standard für Suchverzeichnis festlegen project = QgsProject.instance() self.default_dir = os.path.dirname(project.fileName()) if 'database_QKan' in self.config: database_QKan = self.config['database_QKan'] else: database_QKan = '' self.dlg.tf_QKanDB.setText(database_QKan) self.dlg.pb_selectQKanDB.clicked.connect(self.selectFile_QKanDB) if 'database_HE' in self.config: database_HE = self.config['database_HE'] else: database_HE = '' self.dlg.tf_heDB_dest.setText(database_HE) self.dlg.pb_selectHeDB_dest.clicked.connect(self.selectFile_HeDB_dest) if 'dbtemplate_HE' in self.config: dbtemplate_HE = self.config['dbtemplate_HE'] else: dbtemplate_HE = '' self.dlg.tf_heDB_template.setText(dbtemplate_HE) self.dlg.pb_selectHeDB_template.clicked.connect(self.selectFile_HeDB_template) self.dlg.pb_selectHeDB_emptytemplate.clicked.connect(self.selectFile_HeDB_emptytemplate) if 'datenbanktyp' in self.config: datenbanktyp = self.config['datenbanktyp'] else: datenbanktyp = 'spatialite' pass # Es gibt noch keine Wahlmöglichkeit # Auswahl der zu exportierenden Tabellen ---------------------------------------------- # Eigene Funktion für die zahlreichen Checkboxen def cb_set(name, cbox, default): if name in self.config: checked = self.config[name] else: checked = default cbox.setChecked(checked) return checked export_schaechte = cb_set('export_schaechte', self.dlg.cb_export_schaechte, True) export_auslaesse = cb_set('export_auslaesse', self.dlg.cb_export_auslaesse, True) export_speicher = cb_set('export_speicher', self.dlg.cb_export_speicher, True) export_haltungen = cb_set('export_haltungen', self.dlg.cb_export_haltungen, True) export_pumpen = cb_set('export_pumpen', self.dlg.cb_export_pumpen, False) export_wehre = cb_set('export_wehre', self.dlg.cb_export_wehre, False) export_flaechenrw = cb_set('export_flaechenrw', self.dlg.cb_export_flaechenrw, True) export_einleitdirekt = cb_set('export_einleitdirekt', self.dlg.cb_export_einleitdirekt, True) export_aussengebiete = cb_set('export_aussengebiete', self.dlg.cb_export_aussengebiete, True) export_abflussparameter = cb_set('export_abflussparameter', self.dlg.cb_export_abflussparameter, True) export_regenschreiber = cb_set('export_regenschreiber', self.dlg.cb_export_regenschreiber, False) export_rohrprofile = cb_set('export_rohrprofile', self.dlg.cb_export_rohrprofile, False) export_speicherkennlinien = cb_set('export_speicherkennlinien', self.dlg.cb_export_speicherkennlinien, False) export_bodenklassen = cb_set('export_bodenklassen', self.dlg.cb_export_bodenklassen, False) modify_schaechte = cb_set('modify_schaechte', self.dlg.cb_modify_schaechte, False) modify_auslaesse = cb_set('modify_auslaesse', self.dlg.cb_modify_auslaesse, False) modify_speicher = cb_set('modify_speicher', self.dlg.cb_modify_speicher, False) modify_haltungen = cb_set('modify_haltungen', self.dlg.cb_modify_haltungen, False) modify_pumpen = cb_set('modify_pumpen', self.dlg.cb_modify_pumpen, False) modify_wehre = cb_set('modify_wehre', self.dlg.cb_modify_wehre, False) modify_flaechenrw = cb_set('modify_flaechenrw', self.dlg.cb_modify_flaechenrw, False) modify_einleitdirekt = cb_set('modify_einleitdirekt', self.dlg.cb_modify_einleitdirekt, False) modify_aussengebiete = cb_set('modify_aussengebiete', self.dlg.cb_modify_aussengebiete, False) modify_abflussparameter = cb_set('modify_abflussparameter', self.dlg.cb_modify_abflussparameter, False) modify_regenschreiber = cb_set('modify_regenschreiber', self.dlg.cb_modify_regenschreiber, False) modify_rohrprofile = cb_set('modify_rohrprofile', self.dlg.cb_modify_rohrprofile, False) modify_speicherkennlinien = cb_set('modify_speicherkennlinien', self.dlg.cb_modify_speicherkennlinien, False) modify_bodenklassen = cb_set('modify_bodenklassen', self.dlg.cb_modify_bodenklassen, False) combine_flaechenrw = cb_set('combine_flaechenrw', self.dlg.cb_combine_flaechenrw, True) combine_einleitdirekt = cb_set('combine_einleitdirekt', self.dlg.cb_combine_einleitdirekt, True) # Formularereignisse anbinden ---------------------------------------------- self.dlg.pb_exportall.clicked.connect(self.exportall) self.dlg.pb_modifyall.clicked.connect(self.modifyall) self.dlg.pb_exportnone.clicked.connect(self.exportnone) self.dlg.pb_modifynone.clicked.connect(self.modifynone) self.dlg.lw_teilgebiete.itemClicked.connect(self.countselection) self.dlg.lw_teilgebiete.itemClicked.connect(self.lw_teilgebieteClick) self.dlg.cb_selActive.stateChanged.connect(self.selActiveClick) self.dlg.button_box.helpRequested.connect(self.helpClick) # Ende Eigene Funktionen --------------------------------------------------- # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('ExportToHE', message) def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/qkan/exporthe/icon_qk2he.png' Dummy.instance.add_action(icon_path, text=self.tr(u'Export to Hystem-Extran'), callback=self.run, parent=self.iface.mainWindow()) def unload(self): pass # Anfang Eigene Funktionen ------------------------------------------------- # (jh, 08.02.2017) def selectFile_HeDB_dest(self): """Datenbankverbindung zur HE-Datenbank (Firebird) auswaehlen und gegebenenfalls die Zieldatenbank erstellen, aber noch nicht verbinden.""" filename = QFileDialog.getSaveFileName(self.dlg, "Dateinamen der Ziel-HE-Datenbank eingeben", self.default_dir, "*.idbf") # if os.path.dirname(filename) != '': # os.chdir(os.path.dirname(filename)) self.dlg.tf_heDB_dest.setText(filename) def selectFile_HeDB_template(self): """Vorlage-HE-Datenbank (Firebird) auswaehlen.""" filename = QFileDialog.getOpenFileName(self.dlg, u"Vorlage-HE-Datenbank auswählen", self.default_dir, "*.idbf") # if os.path.dirname(filename) != '': # os.chdir(os.path.dirname(filename)) self.dlg.tf_heDB_template.setText(filename) def selectFile_HeDB_emptytemplate(self): """Vorlage-HE-Datenbank (Firebird) auswaehlen.""" filename = QFileDialog.getOpenFileName(self.dlg, u"Leere Vorlage-HE-Datenbank auswählen", self.templatepath, "*.idbf") # if os.path.dirname(filename) != '': # os.chdir(os.path.dirname(filename)) self.dlg.tf_heDB_template.setText(filename) def selectFile_QKanDB(self): """Datenbankverbindung zur QKan-Datenbank (SpatiLite) auswaehlen.""" filename = QFileDialog.getOpenFileName(self.dlg, u"QKan-Datenbank auswählen", self.default_dir, "*.sqlite") # if os.path.dirname(filename) != '': # os.chdir(os.path.dirname(filename)) self.dlg.tf_QKanDB.setText(filename) def exportall(self): """Aktiviert alle Checkboxen zm Export""" self.dlg.cb_export_schaechte.setChecked(True) self.dlg.cb_export_auslaesse.setChecked(True) self.dlg.cb_export_speicher.setChecked(True) self.dlg.cb_export_haltungen.setChecked(True) self.dlg.cb_export_pumpen.setChecked(True) self.dlg.cb_export_wehre.setChecked(True) self.dlg.cb_export_flaechenrw.setChecked(True) self.dlg.cb_export_einleitdirekt.setChecked(True) self.dlg.cb_export_aussengebiete.setChecked(True) self.dlg.cb_export_abflussparameter.setChecked(True) self.dlg.cb_export_regenschreiber.setChecked(True) self.dlg.cb_export_rohrprofile.setChecked(True) self.dlg.cb_export_speicherkennlinien.setChecked(True) self.dlg.cb_export_bodenklassen.setChecked(True) def modifyall(self): """Aktiviert alle Checkboxen zm Ändern""" self.dlg.cb_modify_schaechte.setChecked(True) self.dlg.cb_modify_auslaesse.setChecked(True) self.dlg.cb_modify_speicher.setChecked(True) self.dlg.cb_modify_haltungen.setChecked(True) self.dlg.cb_modify_pumpen.setChecked(True) self.dlg.cb_modify_wehre.setChecked(True) self.dlg.cb_modify_flaechenrw.setChecked(True) self.dlg.cb_modify_einleitdirekt.setChecked(True) self.dlg.cb_modify_aussengebiete.setChecked(True) self.dlg.cb_modify_abflussparameter.setChecked(True) self.dlg.cb_modify_regenschreiber.setChecked(True) self.dlg.cb_modify_rohrprofile.setChecked(True) self.dlg.cb_modify_speicherkennlinien.setChecked(True) self.dlg.cb_modify_bodenklassen.setChecked(True) def exportnone(self): """Deaktiviert alle Checkboxen zm Export""" self.dlg.cb_export_schaechte.setChecked(False) self.dlg.cb_export_auslaesse.setChecked(False) self.dlg.cb_export_speicher.setChecked(False) self.dlg.cb_export_haltungen.setChecked(False) self.dlg.cb_export_pumpen.setChecked(False) self.dlg.cb_export_wehre.setChecked(False) self.dlg.cb_export_flaechenrw.setChecked(False) self.dlg.cb_export_einleitdirekt.setChecked(False) self.dlg.cb_export_aussengebiete.setChecked(False) self.dlg.cb_export_abflussparameter.setChecked(False) self.dlg.cb_export_regenschreiber.setChecked(False) self.dlg.cb_export_rohrprofile.setChecked(False) self.dlg.cb_export_speicherkennlinien.setChecked(False) self.dlg.cb_export_bodenklassen.setChecked(False) def modifynone(self): """Deaktiviert alle Checkboxen zm Ändern""" self.dlg.cb_modify_schaechte.setChecked(False) self.dlg.cb_modify_auslaesse.setChecked(False) self.dlg.cb_modify_speicher.setChecked(False) self.dlg.cb_modify_haltungen.setChecked(False) self.dlg.cb_modify_pumpen.setChecked(False) self.dlg.cb_modify_wehre.setChecked(False) self.dlg.cb_modify_flaechenrw.setChecked(False) self.dlg.cb_modify_einleitdirekt.setChecked(False) self.dlg.cb_modify_aussengebiete.setChecked(False) self.dlg.cb_modify_abflussparameter.setChecked(False) self.dlg.cb_modify_regenschreiber.setChecked(False) self.dlg.cb_modify_rohrprofile.setChecked(False) self.dlg.cb_modify_speicherkennlinien.setChecked(False) self.dlg.cb_modify_bodenklassen.setChecked(False) # ------------------------------------------------------------------------- # Formularfunktionen def helpClick(self): """Reaktion auf Klick auf Help-Schaltfläche""" helpfile = os.path.join(self.plugin_dir, '..\doc', 'exporthe.html') os.startfile(helpfile) def lw_teilgebieteClick(self): """Reaktion auf Klick in Tabelle""" self.dlg.cb_selActive.setChecked(True) self.countselection() def selActiveClick(self): """Reagiert auf Checkbox zur Aktivierung der Auswahl""" # Checkbox hat den Status nach dem Klick if self.dlg.cb_selActive.isChecked(): # Nix tun ... logger.debug('\nChecked = True') else: # Auswahl deaktivieren und Liste zurücksetzen anz = self.dlg.lw_teilgebiete.count() for i in range(anz): item = self.dlg.lw_teilgebiete.item(i) self.dlg.lw_teilgebiete.setItemSelected(item, False) # Anzahl in der Anzeige aktualisieren self.countselection() def countselection(self): """Zählt nach Änderung der Auswahlen in den Listen im Formular die Anzahl der betroffenen Flächen und Haltungen""" liste_teilgebiete = self.listselecteditems(self.dlg.lw_teilgebiete) # Zu berücksichtigende Flächen zählen auswahl = '' if len(liste_teilgebiete) != 0: auswahl = u" WHERE flaechen.teilgebiet in ('{}')".format("', '".join(liste_teilgebiete)) sql = u"""SELECT count(*) AS anzahl FROM flaechen{auswahl}""".format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan_ExportHE.application.countselection (1)"): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlg.lf_anzahl_flaechen.setText(str(daten[0])) else: self.dlg.lf_anzahl_flaechen.setText('0') # Zu berücksichtigende Schächte zählen auswahl = '' if len(liste_teilgebiete) != 0: auswahl = u" WHERE schaechte.teilgebiet in ('{}')".format("', '".join(liste_teilgebiete)) sql = u"""SELECT count(*) AS anzahl FROM schaechte{auswahl}""".format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan_ExportHE.application.countselection (2) "): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlg.lf_anzahl_schaechte.setText(str(daten[0])) else: self.dlg.lf_anzahl_schaechte.setText('0') # Zu berücksichtigende Haltungen zählen auswahl = '' if len(liste_teilgebiete) != 0: auswahl = u" WHERE haltungen.teilgebiet in ('{}')".format("', '".join(liste_teilgebiete)) sql = u"""SELECT count(*) AS anzahl FROM haltungen{auswahl}""".format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan_ExportHE.application.countselection (3) "): return False daten = self.dbQK.fetchone() if not (daten is None): self.dlg.lf_anzahl_haltungen.setText(str(daten[0])) else: self.dlg.lf_anzahl_haltungen.setText('0') # ------------------------------------------------------------------------- # Funktion zur Zusammenstellung einer Auswahlliste für eine SQL-Abfrage def listselecteditems(self, listWidget): """Erstellt eine Liste aus den in einem Auswahllisten-Widget angeklickten Objektnamen :param listWidget: String for translation. :type listWidget: QListWidget :returns: Tuple containing selected teilgebiete :rtype: tuple """ items = listWidget.selectedItems() liste = [] for elem in items: liste.append(elem.text()) return liste # Ende Eigene Funktionen --------------------------------------------------- def run(self): """Run method that performs all the real work""" # show the dialog # Check, ob die relevanten Layer nicht editable sind. if len({'flaechen', 'haltungen', 'linkfl', 'tezg', 'schaechte'} & get_editable_layers()) > 0: iface.messageBar().pushMessage(u"Bedienerfehler: ", u'Die zu verarbeitenden Layer dürfen nicht im Status "bearbeitbar" sein. Abbruch!', level=QgsMessageBar.CRITICAL) return False # Übernahme der Quelldatenbank: # Wenn ein Projekt geladen ist, wird die Quelldatenbank daraus übernommen. # Wenn dies nicht der Fall ist, wird die Quelldatenbank aus der # json-Datei übernommen. database_QKan = '' database_QKan, epsg = get_database_QKan() if not database_QKan: fehlermeldung(u"Fehler in k_link", u"database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") logger.error("k_link: database_QKan konnte nicht aus den Layern ermittelt werden. Abbruch!") return False if database_QKan != '': self.dlg.tf_QKanDB.setText(database_QKan) # Datenbankverbindung für Abfragen self.dbQK = DBConnection(dbname=database_QKan) # Datenbankobjekt der QKan-Datenbank zum Lesen if not self.dbQK.connected: logger.error(u"Fehler in exportdyna.application:\n", u'QKan-Datenbank {:s} wurde nicht gefunden oder war nicht aktuell!\nAbbruch!'.format(database_QKan)) return None # Check, ob alle Teilgebiete in Flächen, Schächten und Haltungen auch in Tabelle "teilgebiete" enthalten sql = u"""INSERT INTO teilgebiete (tgnam) SELECT teilgebiet FROM flaechen WHERE teilgebiet IS NOT NULL AND teilgebiet NOT IN (SELECT tgnam FROM teilgebiete) GROUP BY teilgebiet""" if not self.dbQK.sql(sql, u"QKan_ExportHE.application.run (1) "): return False sql = u"""INSERT INTO teilgebiete (tgnam) SELECT teilgebiet FROM haltungen WHERE teilgebiet IS NOT NULL AND teilgebiet NOT IN (SELECT tgnam FROM teilgebiete) GROUP BY teilgebiet""" if not self.dbQK.sql(sql, u"QKan_ExportHE.application.run (2) "): return False sql = u"""INSERT INTO teilgebiete (tgnam) SELECT teilgebiet FROM schaechte WHERE teilgebiet IS NOT NULL AND teilgebiet NOT IN (SELECT tgnam FROM teilgebiete) GROUP BY teilgebiet""" if not self.dbQK.sql(sql, u"QKan_ExportHE.application.run (3) "): return False self.dbQK.commit() # Anlegen der Tabelle zur Auswahl der Teilgebiete # Zunächst wird die Liste der beim letzten Mal gewählten Teilgebiete aus config gelesen liste_teilgebiete = [] if 'liste_teilgebiete' in self.config: liste_teilgebiete = self.config['liste_teilgebiete'] # Abfragen der Tabelle teilgebiete nach Teilgebieten sql = 'SELECT "tgnam" FROM "teilgebiete" GROUP BY "tgnam"' if not self.dbQK.sql(sql, u"QKan_ExportHE.application.run (4) "): return False daten = self.dbQK.fetchall() self.dlg.lw_teilgebiete.clear() for ielem, elem in enumerate(daten): self.dlg.lw_teilgebiete.addItem(QListWidgetItem(elem[0])) try: if elem[0] in liste_teilgebiete: self.dlg.lw_teilgebiete.setCurrentRow(ielem) except BaseException as err: fehlermeldung(u'QKan_ExportHE (6), Fehler in elem = {}\n'.format(elem), repr(err)) # if len(daten) == 1: # self.dlg.lw_teilgebiete.setCurrentRow(0) # Ereignis bei Auswahländerung in Liste Teilgebiete self.countselection() # Autokorrektur if 'autokorrektur' in self.config: autokorrektur = self.config['autokorrektur'] else: autokorrektur = True self.dlg.cb_autokorrektur.setChecked(autokorrektur) # Festlegung des Fangradius # Kann über Menü "Optionen" eingegeben werden if 'fangradius' in self.config: fangradius = self.config['fangradius'] else: fangradius = u'0.1' # Haltungsflächen (tezg) berücksichtigen if 'mit_verschneidung' in self.config: mit_verschneidung = self.config['mit_verschneidung'] else: mit_verschneidung = True self.dlg.cb_regardTezg.setChecked(mit_verschneidung) # Mindestflächengröße # Kann über Menü "Optionen" eingegeben werden if 'mindestflaeche' in self.config: mindestflaeche = self.config['mindestflaeche'] else: mindestflaeche = u'0.5' self.countselection() # Formular anzeigen self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Abrufen der ausgewählten Elemente in beiden Listen liste_teilgebiete = self.listselecteditems(self.dlg.lw_teilgebiete) # Eingaben aus Formular übernehmen database_QKan = self.dlg.tf_QKanDB.text() database_HE = self.dlg.tf_heDB_dest.text() dbtemplate_HE = self.dlg.tf_heDB_template.text() datenbanktyp = 'spatialite' autokorrektur = self.dlg.cb_autokorrektur.isChecked() mit_verschneidung = self.dlg.cb_regardTezg.isChecked() check_export = {} check_export['export_schaechte'] = self.dlg.cb_export_schaechte.isChecked() check_export['export_auslaesse'] = self.dlg.cb_export_auslaesse.isChecked() check_export['export_speicher'] = self.dlg.cb_export_speicher.isChecked() check_export['export_haltungen'] = self.dlg.cb_export_haltungen.isChecked() check_export['export_pumpen'] = self.dlg.cb_export_pumpen.isChecked() check_export['export_wehre'] = self.dlg.cb_export_wehre.isChecked() check_export['export_flaechenrw'] = self.dlg.cb_export_flaechenrw.isChecked() check_export['export_einleitdirekt'] = self.dlg.cb_export_einleitdirekt.isChecked() check_export['export_aussengebiete'] = self.dlg.cb_export_aussengebiete.isChecked() check_export['export_abflussparameter'] = self.dlg.cb_export_abflussparameter.isChecked() check_export['export_regenschreiber'] = self.dlg.cb_export_regenschreiber.isChecked() check_export['export_rohrprofile'] = self.dlg.cb_export_rohrprofile.isChecked() check_export['export_speicherkennlinien'] = self.dlg.cb_export_speicherkennlinien.isChecked() check_export['export_bodenklassen'] = self.dlg.cb_export_bodenklassen.isChecked() check_export['modify_schaechte'] = self.dlg.cb_modify_schaechte.isChecked() check_export['modify_auslaesse'] = self.dlg.cb_modify_auslaesse.isChecked() check_export['modify_speicher'] = self.dlg.cb_modify_speicher.isChecked() check_export['modify_haltungen'] = self.dlg.cb_modify_haltungen.isChecked() check_export['modify_pumpen'] = self.dlg.cb_modify_pumpen.isChecked() check_export['modify_wehre'] = self.dlg.cb_modify_wehre.isChecked() check_export['modify_flaechenrw'] = self.dlg.cb_modify_flaechenrw.isChecked() check_export['modify_einleitdirekt'] = self.dlg.cb_modify_einleitdirekt.isChecked() check_export['modify_aussengebiete'] = self.dlg.cb_modify_aussengebiete.isChecked() check_export['modify_abflussparameter'] = self.dlg.cb_modify_abflussparameter.isChecked() check_export['modify_regenschreiber'] = self.dlg.cb_modify_regenschreiber.isChecked() check_export['modify_rohrprofile'] = self.dlg.cb_modify_rohrprofile.isChecked() check_export['modify_speicherkennlinien'] = self.dlg.cb_modify_speicherkennlinien.isChecked() check_export['modify_bodenklassen'] = self.dlg.cb_modify_bodenklassen.isChecked() check_export['combine_flaechenrw'] = self.dlg.cb_combine_flaechenrw.isChecked() check_export['combine_einleitdirekt'] = self.dlg.cb_combine_einleitdirekt.isChecked() # Konfigurationsdaten schreiben self.config['database_HE'] = database_HE self.config['dbtemplate_HE'] = dbtemplate_HE self.config['database_QKan'] = database_QKan self.config['datenbanktyp'] = datenbanktyp self.config['liste_teilgebiete'] = liste_teilgebiete self.config['autokorrektur'] = autokorrektur self.config['fangradius'] = fangradius self.config['mit_verschneidung'] = mit_verschneidung self.config['mindestflaeche'] = mindestflaeche for el in check_export: self.config[el] = check_export[el] with open(self.configfil, 'w') as fileconfig: # logger.debug(u"Config-Dictionary: {}".format(self.config)) fileconfig.write(json.dumps(self.config)) exportKanaldaten(iface, database_HE, dbtemplate_HE, self.dbQK, liste_teilgebiete, autokorrektur, fangradius, mindestflaeche, mit_verschneidung, datenbanktyp, check_export)