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
def createUnbefFlaechen(dbQK, liste_selAbflparamTeilgeb, autokorrektur, dbtyp='spatialite'): '''Import der Kanaldaten aus einer HE-Firebird-Datenbank und Schreiben in eine QKan-SpatiaLite-Datenbank. :dbQK: Datenbankobjekt, das die Verknüpfung zur QKan-SpatiaLite-Datenbank verwaltet. :type database: DBConnection (geerbt von dbapi...) :liste_selAbflparamTeilgeb: Liste der bei der Bearbeitung zu berücksichtigenden Kombinationen aus Abflussparameter und Teilgebiet (Tabelle tezg) :type: list :autokorrektur: Option, ob eine automatische Korrektur der Bezeichnungen durchgeführt werden soll. Falls nicht, wird die Bearbeitung mit einer Fehlermeldung abgebrochen. :type autokorrektur: String :dbtyp: Typ der Datenbank (spatialite, postgis) :type dbtyp: String :returns: void Für alle TEZG-Flächen wird, falls nicht schon vorhanden, ein unbefestigtes Flächenobjekt erzeugt. Dazu können in der Auswahlmaske zunächst die Kombinationen aus Abflussparameter und Teilgebiet gewählt werden, die in der Tabelle "tezg" vorkommen und die nachfolgenden Voraussetzungen erfüllen: - Im Feld "abflussparameter" muss auf einen Abflussparameter verwiesen werden, der für unbefestigte Flächen erzeugt wurde (infiltrationsparameter > 0) ''' global progress_bar progress_bar = QProgressBar(iface.messageBar()) progress_bar.setRange(0, 100) status_message = iface.messageBar().createMessage( u"Info", u"Erzeugung von unbefestigten Flächen in Arbeit. Bitte warten.") status_message.layout().addWidget(progress_bar) iface.messageBar().pushWidget(status_message, QgsMessageBar.INFO, 10) # status_message.setText(u"Erzeugung von unbefestigten Flächen ist in Arbeit.") progress_bar.setValue(1) # ------------------------------------------------------------------------------ # Datenbankverbindungen # Kontrolle, ob tezg-Flächen eindeutig Namen haben: if not checknames(dbQK, u'tezg', u'flnam', u'ft_', autokorrektur): return False if not checknames(dbQK, u'flaechen', u'flnam', u'f_', autokorrektur): return False # Prüfung, ob unzulässige Kombinationen ausgewählt wurden if len(liste_selAbflparamTeilgeb) > 0: logger.debug(u'\nliste_selAbflparamTeilgeb (2): {}'.format( liste_selAbflparamTeilgeb)) if False in [(attr[-1] == u'') for attr in liste_selAbflparamTeilgeb]: fehlermeldung( u"Falsche Auswahl", u"Bitte nur zulässige Abflussparameter und Teilgebiete auswählen (siehe Spalte 'Anmerkungen')" ) return False else: sql = u"""SELECT count(*) AS anz FROM tezg AS te LEFT JOIN abflussparameter AS ap ON te.abflussparameter = ap.apnam LEFT JOIN bodenklassen AS bk ON bk.bknam = ap.bodenklasse WHERE te.abflussparameter ISNULL OR bk.infiltrationsrateanfang ISNULL OR bk.infiltrationsrateanfang < 0.00001""" if not dbQK.sql(sql, u'QKan.CreateUnbefFlaechen (1)'): return False data = dbQK.fetchall() if len(data) > 0: if data[0][0] > 0: fehlermeldung( u"Unvollständige Daten", u"In der Tabelle TEZG-Flächen sind noch fehlerhafte Daten zu den Abflussparametern oder den Bodenklassen enthalten. " ) return False # Für die Erzeugung der Restflächen reicht eine SQL-Abfrage aus. # status_message.setText(u"Erzeugung von unbefestigten Flächen") progress_bar.setValue(10) # Vorbereitung des Auswahlkriteriums für die SQL-Abfrage: Kombination aus abflussparameter und teilgebiet # Dieser Block ist identisch in k_unbef und in application enthalten if len(liste_selAbflparamTeilgeb) == 0: auswahl = u'' elif len(liste_selAbflparamTeilgeb) == 1: auswahl = u' AND' elif len(liste_selAbflparamTeilgeb) >= 2: auswahl = u' AND (' else: fehlermeldung(u"Interner Fehler", u"Fehler in Fallunterscheidung!") return False # Anfang SQL-Krierien zur Auswahl der tezg-Flächen first = True for attr in liste_selAbflparamTeilgeb: if attr[4] == u'None' or attr[1] == u'None': fehlermeldung( u'Datenfehler: ', u'In den ausgewählten Daten sind noch Datenfelder nicht definiert ("NULL").' ) return False if first: first = False auswahl += u""" (tezg.abflussparameter = '{abflussparameter}' AND tezg.teilgebiet = '{teilgebiet}')""".format( abflussparameter=attr[0], teilgebiet=attr[1]) else: auswahl += u""" OR\n (tezg.abflussparameter = '{abflussparameter}' AND tezg.teilgebiet = '{teilgebiet}')""".format( abflussparameter=attr[0], teilgebiet=attr[1]) if len(liste_selAbflparamTeilgeb) >= 2: auswahl += u")" # Ende SQL-Krierien zur Auswahl der tezg-Flächen # Erläuterung zur nachfolgenden SQL-Abfrage: # 1. aus der Abfrage werden alle Datensätze ohne geom-Objekte ausgeschlossen # 2. Wenn in einer tezg-Fläche keine Fläche liegt, wird einfach die tezg-Fläche übernommen sql = u"""WITH flbef AS ( SELECT 'fd_' || ltrim(tezg.flnam, 'ft_') AS flnam, tezg.haltnam AS haltnam, tezg.neigkl AS neigkl, tezg.regenschreiber AS regenschreiber, tezg.teilgebiet AS teilgebiet, tezg.abflussparameter AS abflussparameter, 'Erzeugt mit Plugin Erzeuge unbefestigte Flaechen' AS kommentar, MakeValid(tezg.geom) AS geot, ST_Union(MakeValid(flaechen.geom)) AS geob FROM (SELECT * FROM tezg WHERE geom IS NOT NULL) AS tezg LEFT JOIN (SELECT * FROM flaechen WHERE geom IS NOT NULL) AS flaechen ON Intersects(tezg.geom, flaechen.geom) WHERE 'fd_' || ltrim(tezg.flnam, 'ft_') not in ( SELECT flnam FROM flaechen WHERE flnam IS NOT NULL){auswahl} GROUP BY tezg.pk) INSERT INTO flaechen (flnam, haltnam, neigkl, regenschreiber, teilgebiet, abflussparameter, kommentar, geom) SELECT flnam AS flnam, haltnam, neigkl, regenschreiber, teilgebiet, abflussparameter, kommentar, CASE WHEN geob IS NULL THEN geot ELSE CastToMultiPolygon(Difference(geot,geob)) END AS geof FROM flbef WHERE area(geof) > 0.5 AND geof IS NOT NULL""".format( auswahl=auswahl) logger.debug(u'QKan.k_unbef (3) - liste_selAbflparamTeilgeb = \n{}'.format( str(liste_selAbflparamTeilgeb))) if not dbQK.sql(sql, u"QKan.CreateUnbefFlaechen (4)"): return False # # status_message.setText(u"Erstellen der Anbindungen für die unbefestigten Flächen") # progress_bar.setValue(50) # # Hinzufügen von Verknüpfungen in die Tabelle linkfl für die neu erstellten unbefestigten Flächen # sql = u"""INSERT INTO linkfl (flnam, aufteilen, teilgebiet, geom, glink) # SELECT # fl.flnam AS flnam, # NULL AS aufteilen, # fl.teilgebiet AS teilgebiet, # NULL AS geom, # MakeLine(PointOnSurface(fl.geom),Centroid(ha.geom)) AS glink # FROM flaechen AS fl # LEFT JOIN haltungen AS ha # ON fl.haltnam = ha.haltnam # INNER JOIN tezg AS tg # ON 'fd_' || ltrim(tg.flnam, 'ft_') = fl.flnam # WHERE fl.flnam NOT IN # ( SELECT flnam FROM linkfl WHERE flnam IS NOT NULL)""" # if not dbQK.sql(sql, u"QKan.CreateUnbefFlaechen (5)"): # return False # status_message.setText(u"Nachbearbeitung") progress_bar.setValue(90) dbQK.commit() del dbQK # Karte aktualisieren iface.mapCanvas().refreshAllLayers() iface.mainWindow().statusBar().clearMessage() iface.messageBar().pushMessage(u"Information", u"Restflächen sind erstellt!", level=QgsMessageBar.INFO) QgsMessageLog.logMessage(u"\nRestflächen sind erstellt!", level=QgsMessageLog.INFO) progress_bar.setValue(100) status_message.setText( u"Erzeugung von unbefestigten Flächen abgeschlossen.") status_message.setLevel(QgsMessageBar.SUCCESS)
def assigntgeb(dbQK, auswahltyp, liste_teilgebiete, tablist, autokorrektur, bufferradius=u'0', dbtyp=u'SpatiaLite'): '''Ordnet alle Objete aus den in "tablist" enthaltenen Tabellen einer der in "liste_teilgebiete" enthaltenen Teilgebiete zu. Falls sich mehrere dieser Teilgebiete überlappen, ist das Resultat zufällig eines von diesen. :dbQK: Datenbankobjekt, das die Verknüpfung zur QKan-SpatiaLite-Datenbank verwaltet. :type database: DBConnection (geerbt von dbapi...) :liste_teilgebiete: Name des auf die gewählten Tabellen zu übertragenden Teilgebietes :type liste_teilgebiete:list of String :tablist: Liste der Tabellen, auf die die Teilgebiet "liste_teilgebiete" zu übertragen sind. :type tablist: list of String :autokorrektur: Option, ob eine automatische Korrektur der Bezeichnungen durchgeführt werden soll. Falls nicht, wird die Bearbeitung mit einer Fehlermeldung abgebrochen. :type autokorrektur: String :dbtyp: Typ der Datenbank (SpatiaLite, PostGIS) :type dbtyp: String :returns: void ''' # Statusmeldung in der Anzeige global progress_bar progress_bar = QProgressBar(iface.messageBar()) progress_bar.setRange(0, 100) status_message = iface.messageBar().createMessage( u"", u"Teilgebiete werden zugeordnet. Bitte warten...") status_message.layout().addWidget(progress_bar) iface.messageBar().pushWidget(status_message, QgsMessageBar.INFO, 10) logger.debug(u'\nbetroffene Tabellen (1):\n{}\n'.format(str(tablist))) logger.debug(u'\nbetroffene Teilgebiete (2):\n{}\n'.format( str(liste_teilgebiete))) if not checknames(dbQK, u'teilgebiete', u'tgnam', u'tg_', autokorrektur): return False if len(liste_teilgebiete) != 0: tgnames = u"', '".join(liste_teilgebiete) auswahl_1 = u" AND teilgebiete.tgnam in ('{tgnames}')".format( tgnames=tgnames) auswahl_2 = u" WHERE teilgebiete.tgnam in ('{tgnames}')".format( tgnames=tgnames) else: auswahl_1 = '' auswahl_2 = '' for table in tablist: if auswahltyp == 'within': if bufferradius == '0' or bufferradius.strip == '': sql = u""" UPDATE {table} SET teilgebiet = ( SELECT teilgebiete.tgnam FROM teilgebiete INNER JOIN {table} AS tt ON within(tt.geom, teilgebiete.geom) WHERE tt.pk = {table}.pk and tt.geom IS NOT NULL and teilgebiete.geom IS NOT NULL {auswahl_1}) WHERE {table}.pk IN ( SELECT {table}.pk FROM teilgebiete INNER JOIN {table} ON within({table}.geom, teilgebiete.geom) WHERE {table}.geom IS NOT NULL and teilgebiete.geom IS NOT NULL {auswahl_1}) """.format(table=table, bufferradius=bufferradius, auswahl_1=auswahl_1) else: sql = u""" UPDATE {table} SET teilgebiet = ( SELECT teilgebiete.tgnam FROM teilgebiete INNER JOIN {table} AS tt ON within(tt.geom, buffer(teilgebiete.geom, {bufferradius})) WHERE tt.pk = {table}.pk and tt.geom IS NOT NULL and teilgebiete.geom IS NOT NULL{auswahl_1}) WHERE {table}.pk IN ( SELECT {table}.pk FROM teilgebiete INNER JOIN {table} ON within({table}.geom, buffer(teilgebiete.geom, {bufferradius})) WHERE {table}.geom IS NOT NULL and teilgebiete.geom IS NOT NULL{auswahl_1}) """.format(table=table, bufferradius=bufferradius, auswahl_1=auswahl_1) elif auswahltyp == 'overlaps': sql = u""" UPDATE {table} SET teilgebiet = ( SELECT teilgebiete.tgnam FROM teilgebiete INNER JOIN {table} AS tt ON intersects(tt.geom,teilgebiete.geom) WHERE tt.pk = {table}.pk and tt.geom IS NOT NULL and teilgebiete.geom IS NOT NULL{auswahl_1}) WHERE {table}.pk IN ( SELECT {table}.pk FROM teilgebiete INNER JOIN {table} ON intersects({table}.geom,teilgebiete.geom) WHERE {table}.geom IS NOT NULL and teilgebiete.geom IS NOT NULL{auswahl_1}) """.format(table=table, auswahl_1=auswahl_1) else: fehlermeldung( u'Programmfehler', u'k_link.assigntgeb: auswahltyp hat unbekannten Fall {}'. format(str(auswahltyp))) del dbQK return False # logger.debug(u'\nSQL:\n{}\n'.format(sql)) if not dbQK.sql(sql, u"QKan.k_link.assigntgeb (8)"): return False dbQK.commit() progress_bar.setValue(100) status_message.setText(u"Fertig!") status_message.setLevel(QgsMessageBar.SUCCESS) # Karte aktualisieren iface.mapCanvas().refreshAllLayers() # iface.mainWindow().statusBar().clearMessage() # iface.messageBar().pushMessage(u"Information", u"Zuordnung von Haltungen und Flächen ist fertig!", level=QgsMessageBar.INFO) QgsMessageLog.logMessage( u"\nZuordnung von Haltungen und Flächen ist fertig!", level=QgsMessageLog.INFO) return True
def createlinkfl(dbQK, liste_flaechen_abflussparam, liste_hal_entw, liste_teilgebiete, linksw_in_tezg=False, autokorrektur=True, suchradius=50, mindestflaeche=0.5, fangradius=0.1, bezug_abstand=u'kante', epsg=u'25832', dbtyp=u'SpatiaLite'): '''Import der Kanaldaten aus einer HE-Firebird-Datenbank und Schreiben in eine QKan-SpatiaLite-Datenbank. :dbQK: Datenbankobjekt, das die Verknüpfung zur QKan-SpatiaLite-Datenbank verwaltet. :type database: DBConnection (geerbt von dbapi...) :liste_flaechen_abflussparam: Liste der ausgewählten Abflussparameter für die Flächen :type liste_flaechen_abflussparam: String :liste_hal_entw: Liste der ausgewählten Entwässerungsarten für die Haltungen :type liste_hal_entw: list of String :liste_teilgebiete: Liste der ausgewählten Teilgebiete :type liste_teilgebiete: list of String :suchradius: Suchradius in der SQL-Abfrage :type suchradius: Real :mindestflaeche: Mindestflächengröße bei Einzelflächen und Teilflächenstücken :type mindestflaeche: Real :bezug_abstand: Bestimmt, ob in der SQL-Abfrage der Mittelpunkt oder die nächste Kante der Fläche berücksichtigt wird :type bezug_abstand: String :epsg: Nummer des Projektionssystems :type epsg: String :dbtyp: Typ der Datenbank (SpatiaLite, PostGIS) :type dbtyp: String :returns: void Die Bearbeitung erfolgt in einer zusätzlichen Tabelle 'linkfl' Sie wird zunächst aus der Tabelle "flaechen" erstellt, und enthält zusätzlich zwei weitere Geo-Attribute: gbuf - Buffer sind die mit einem Buffer erweiterten Flächen glink - linkfl sind Verbindungslinien, die von der Fläche zur Haltung zeigen zusätzlich wird die zugeordnete Haltung im entsprechenden Attribut verwaltet. Änderungen an der Zuordnung erfolgen ausschließlich über die Bearbeitung des Grafikobjektes, d.h. über die Verbindungslinie. Beim Export werden alle Verknüpfungen über die Attributfelder (!) geprüft und alle Unstimmigkeiten, die z. B. durch spätere Änderungen der Verbindungslinie entstanden sind, in den Attributfeldern aktualisiert. Grund dafür ist, dass nur in dieser Reihenfolge ein schneller Export möglich ist. Der "erste" Export kann dagegen viel mehr Zeit benötigen, wenn bei vielen (allen?) Verbindungslinien die Attribute erst eingetragen werden müssen. Die Tabelle linkfl hat außer dem Primärschlüssel "pk" kein eindeutiges Primärschlüsselfeld. Das Feld tezg.flnam enthält immer den Namen der betreffenden Haltungsfläche, unabhängig davon, ob es sich um eine aufzuteilende Fläche handelt. ''' # Statusmeldung in der Anzeige global progress_bar progress_bar = QProgressBar(iface.messageBar()) progress_bar.setRange(0, 100) status_message = iface.messageBar().createMessage( u"", u"Verknüpfungen zwischen Flächen und Haltungen werden hergestellt. Bitte warten..." ) status_message.layout().addWidget(progress_bar) iface.messageBar().pushWidget(status_message, QgsMessageBar.INFO, 10) # Vorbereitung flaechen: Falls flnam leer ist, plausibel ergänzen: if not checknames(dbQK, u'flaechen', u'flnam', u'f_', autokorrektur): del dbQK return False progress_bar.setValue(5) # Aktualisierung des logischen Cache if not updatelinkfl(dbQK, deletelinkGeomNone=False): fehlermeldung(u'Fehler beim Update der Flächen-Verknüpfungen', u'Der logische Cache konnte nicht aktualisiert werden.') return False progress_bar.setValue(20) # Kopieren der Flaechenobjekte in die Tabelle linkfl lis_einf = [ '' ] # einfache Flächen. Erstes Element leer, damit beim join ' and ' schon am Anfang eingefügt wird lis_teil = [ '' ] # aufzuteilende Flächen. Erstes Element leer, damit beim join ' and ' schon am Anfang eingefügt wird if len(liste_flaechen_abflussparam) == 0: pass # logger.debug(u'Warnung in Link Flaechen: Keine Auswahl bei Flächen...') else: lis_einf.append(u"flaechen.abflussparameter in ('{}')".format( u"', '".join(liste_flaechen_abflussparam))) lis_teil = lis_einf[:] # hier ist ein deepcopy notwendig! if len(liste_teilgebiete) != 0: lis_einf.append(u"flaechen.teilgebiet in ('{}')".format( u"', '".join(liste_teilgebiete))) lis_teil.append(u"tezg.teilgebiet in ('{}')".format( u"', '".join(liste_teilgebiete))) ausw_einf = ' and '.join(lis_einf) ausw_teil = ' and '.join(lis_teil) # Sowohl Flächen, die nicht als auch die, die verschnitten werden müssen # if not checkgeom(dbQK, 'tezg', 'geom', autokorrektur, liste_teilgebiete): # del dbQK # progress_bar.reset() # return False # if not checkgeom(dbQK, 'flaechen', 'geom', autokorrektur, liste_teilgebiete): # del dbQK # progress_bar.reset() # return False sql = u"""WITH linkadd AS ( SELECT linkfl.pk AS lpk, tezg.flnam AS tezgnam, flaechen.flnam, flaechen.aufteilen, flaechen.teilgebiet, flaechen.geom FROM flaechen INNER JOIN tezg ON within(centroid(flaechen.geom),tezg.geom) LEFT JOIN linkfl ON linkfl.flnam = flaechen.flnam WHERE ((flaechen.aufteilen <> 'ja' or flaechen.aufteilen IS NULL) and flaechen.geom IS NOT NULL and tezg.geom IS NOT NULL){ausw_einf} UNION SELECT linkfl.pk AS lpk, tezg.flnam AS tezgnam, flaechen.flnam, flaechen.aufteilen, tezg.teilgebiet, CastToMultiPolygon(intersection(flaechen.geom,tezg.geom)) AS geom FROM flaechen INNER JOIN tezg ON intersects(flaechen.geom,tezg.geom) LEFT JOIN linkfl ON linkfl.flnam = flaechen.flnam AND linkfl.tezgnam = tezg.flnam WHERE (flaechen.aufteilen = 'ja' and flaechen.geom IS NOT NULL and tezg.geom IS NOT NULL){ausw_teil}) INSERT INTO linkfl (flnam, tezgnam, aufteilen, teilgebiet, geom) SELECT flnam, tezgnam, aufteilen, teilgebiet, geom FROM linkadd WHERE lpk IS NULL AND geom > {minfl}""".format( ausw_einf=ausw_einf, ausw_teil=ausw_teil, minfl=mindestflaeche) if not dbQK.sql(sql, u"QKan_LinkFlaechen (4a)"): del dbQK progress_bar.reset() return False progress_bar.setValue(60) # Jetzt werden die Flächenobjekte mit einem Buffer erweitert und jeweils neu # hinzugekommmene mögliche Zuordnungen eingetragen. sql = u"""UPDATE linkfl SET gbuf = CastToMultiPolygon(buffer(geom,{})) WHERE linkfl.glink IS NULL""".format( suchradius) if not dbQK.sql(sql, u"createlinkfl (2)"): del dbQK progress_bar.reset() return False # Erzeugung der Verbindungslinie zwischen dem Zentroiden der Haltung und dem PointonSurface der Fläche. # Filter braucht nur noch für Haltungen berücksichtigt zu werden, da Flächen bereits beim Einfügen # in tlink gefiltert wurden. if len(liste_hal_entw) == 0: auswha = '' else: auswha = u" AND ha.entwart in ('{}')".format( u"', '".join(liste_hal_entw)) if len(liste_teilgebiete) == 0: auswlinkfl = u"" else: auswha += u" AND ha.teilgebiet in ('{}')".format( u"', '".join(liste_teilgebiete)) auswlinkfl = u" AND linkfl.teilgebiet in ('{}')".format( u"', '".join(liste_teilgebiete)) if bezug_abstand == 'mittelpunkt': bezug = u'lf.geom' else: bezug = u'PointonSurface(lf.geom)' # Erläuterung zur nachfolgenden SQL-Abfrage: # tlink enthält alle potenziellen Verbindungen zwischen Flächen und Haltungen mit der jeweiligen Entfernung # t2 enthält von diesen Verbindungen nur die Fläche (als pk) und den minimalen Abstand, # so dass in der Abfrage nach "update" nur die jeweils nächste Verbindung gefiltert wird. # Da diese Abfrage nur für neu zu erstellende Verknüpfungen gelten soll (also noch kein Eintrag # im Feld "flaechen.haltnam" -> fl.haltnam -> tlink.linkhal -> t1.linkhal). # Varianten ohne und mit Beschränkung der Anbindungslinien auf die Haltungsfläche # Tipp: within und intersects schließt Datensätze ohne Geoobjekt ein. Deshalb müssen # sie ausgeschlossen werden. if linksw_in_tezg: sql = u"""WITH tlink AS ( SELECT lf.pk AS pk, ha.haltnam, Distance(ha.geom,{bezug}) AS dist, ha.geom AS geohal, lf.geom AS geolf FROM haltungen AS ha INNER JOIN linkfl AS lf ON Intersects(ha.geom,lf.gbuf) INNER JOIN tezg AS tg ON tg.flnam = lf.tezgnam WHERE (within(centroid(ha.geom),tg.geom) and lf.glink IS NULL and ha.geom IS NOT NULL and lf.gbuf IS NOT NULL and tg.geom IS NOT NULL){auswha}) UPDATE linkfl SET (glink, haltnam) = ( SELECT MakeLine(PointOnSurface(Buffer(t1.geolf, -1.1*{fangradius})),Centroid(t1.geohal)), t1.haltnam FROM tlink AS t1 INNER JOIN (SELECT pk, Min(dist) AS dmin FROM tlink GROUP BY pk) AS t2 ON t1.pk=t2.pk AND t1.dist <= t2.dmin + 0.000001 WHERE linkfl.pk = t1.pk AND area(Buffer(t1.geolf, -1.1*{fangradius})) IS NOT NULL) WHERE linkfl.glink IS NULL{auswlinkfl}""".format( bezug=bezug, fangradius=fangradius, auswha=auswha, auswlinkfl=auswlinkfl) else: sql = u"""WITH tlink AS ( SELECT lf.pk AS pk, ha.haltnam, Distance(ha.geom,{bezug}) AS dist, ha.geom AS geohal, lf.geom AS geolf FROM haltungen AS ha INNER JOIN linkfl AS lf ON Intersects(ha.geom,lf.gbuf) WHERE lf.glink IS NULL and ha.geom IS NOT NULL and lf.gbuf IS NOT NULL{auswha}) UPDATE linkfl SET (glink, haltnam) = ( SELECT MakeLine(PointOnSurface(Buffer(t1.geolf, -1.1*{fangradius})),Centroid(t1.geohal)), t1.haltnam FROM tlink AS t1 INNER JOIN (SELECT pk, Min(dist) AS dmin FROM tlink GROUP BY pk) AS t2 ON t1.pk=t2.pk AND t1.dist <= t2.dmin + 0.000001 WHERE linkfl.pk = t1.pk AND area(Buffer(t1.geolf, -1.1*{fangradius})) IS NOT NULL) WHERE linkfl.glink IS NULL{auswlinkfl}""".format( bezug=bezug, fangradius=fangradius, auswha=auswha, auswlinkfl=auswlinkfl) logger.debug(u'\nSQL-3a:\n{}\n'.format(sql)) if not dbQK.sql(sql, u"createlinkfl (5)"): del dbQK progress_bar.reset() return False progress_bar.setValue(80) # Löschen der Datensätze in linkfl, bei denen keine Verbindung erstellt wurde, weil die # nächste Haltung zu weit entfernt ist. sql = u"""DELETE FROM linkfl WHERE glink IS NULL""" if not dbQK.sql(sql, u"QKan_LinkFlaechen (7)"): del dbQK progress_bar.reset() return False dbQK.commit() # Aktualisierung des logischen Cache if not updatelinkfl(dbQK, deletelinkGeomNone=False): fehlermeldung(u'Fehler beim Update der Flächen-Verknüpfungen', u'Der logische Cache konnte nicht aktualisiert werden.') del dbQK progress_bar.reset() return False progress_bar.setValue(100) status_message.setText(u"Fertig!") status_message.setLevel(QgsMessageBar.SUCCESS) # Karte aktualisieren iface.mapCanvas().refreshAllLayers() # iface.mainWindow().statusBar().clearMessage() # iface.messageBar().pushMessage(u"Information", u"Verknüpfungen sind erstellt!", level=QgsMessageBar.INFO) QgsMessageLog.logMessage(u"\nVerknüpfungen sind erstellt!", level=QgsMessageLog.INFO) return True
def createlinksw(dbQK, liste_teilgebiete, suchradius=50, epsg=u'25832', dbtyp=u'SpatiaLite'): '''Import der Kanaldaten aus einer HE-Firebird-Datenbank und Schreiben in eine QKan-SpatiaLite-Datenbank. :dbQK: Datenbankobjekt, das die Verknüpfung zur QKan-SpatiaLite-Datenbank verwaltet. :type database: DBConnection (geerbt von dbapi...) :liste_teilgebiete: Liste der ausgewählten Teilgebiete :type liste_teilgebiete: list of String :suchradius: Suchradius in der SQL-Abfrage :type suchradius: Real :epsg: Nummer des Projektionssystems :type epsg: String :dbtyp: Typ der Datenbank (SpatiaLite, PostGIS) :type dbtyp: String :returns: void ''' # ------------------------------------------------------------------------------ # Die Bearbeitung erfolgt analog zu createlinkfl, mit folgenden Änderungen: # - Es gibt keine Auswahl nach Abflussparametern und Entwässerungssystem # - Es handelt sich um Punktobjekte anstelle von Flächen. # - Daher entfällt die Option, ob der Abstand auf die Kante oder den # Mittelpunkt bezogen werden soll # - es gibt keine Verschneidung # Kopieren der Direkteinleitungen-Punkte in die Tabelle linksw. Dabei wird aus dem Punktobjekt # aus einleit ein Flächenobjekt, damit ein Spatialindex verwendet werden kann # (für POINT gibt es keinen MBR?) # Statusmeldung in der Anzeige global progress_bar progress_bar = QProgressBar(iface.messageBar()) progress_bar.setRange(0, 100) status_message = iface.messageBar().createMessage( u"", u"Verknüpfungen zwischen Einleitpunkten und Haltungen werden hergestellt. Bitte warten..." ) status_message.layout().addWidget(progress_bar) iface.messageBar().pushWidget(status_message, QgsMessageBar.INFO, 10) # Aktualisierung des logischen Cache if not updatelinksw(dbQK, deletelinkGeomNone=False): fehlermeldung(u'Fehler beim Update der Einzeleinleiter-Verknüpfungen', u'Der logische Cache konnte nicht aktualisiert werden.') return False if len(liste_teilgebiete) != 0: auswahl = u" AND einleit.teilgebiet in ('{}')".format( u"', '".join(liste_teilgebiete)) else: auswahl = '' sql = u"""INSERT INTO linksw (elnam, teilgebiet, geom) SELECT einleit.elnam, einleit.teilgebiet,buffer(einleit.geom,{radius}) FROM einleit LEFT JOIN linksw ON linksw.elnam = einleit.elnam WHERE linksw.pk IS NULL{auswahl}""".format(auswahl=auswahl, radius=0.5) # logger.debug(u'\nSQL-2a:\n{}\n'.format(sql)) if not dbQK.sql(sql, u"QKan_LinkSW (4a)"): return False progress_bar.setValue(25) # Jetzt werden die Direkteinleitungen-Punkte mit einem Buffer erweitert und jeweils neu # hinzugekommmene mögliche Zuordnungen eingetragen. # Wenn das Attribut "haltnam" vergeben ist, gilt die Fläche als zugeordnet. sql = u"""UPDATE linksw SET gbuf = CastToMultiPolygon(buffer(geom,{})) WHERE linksw.glink IS NULL""".format( suchradius) if not dbQK.sql(sql, u"QKan_LinkSW (2)"): return False # Erzeugung der Verbindungslinie zwischen dem Zentroiden der Haltung und dem PointonSurface der Fläche. # Filter braucht nur noch für Haltungen berücksichtigt zu werden, da Flächen bereits beim Einfügen # in tlink gefiltert wurden. if len(liste_teilgebiete) != 0: auswahl = u" AND hal.teilgebiet in ('{}')".format( u"', '".join(liste_teilgebiete)) auswlin = u" AND linksw.teilgebiet in ('{}')".format( u"', '".join(liste_teilgebiete)) else: auswahl = '' auswlin = '' # Erläuterung zur nachfolgenden SQL-Abfrage: # tlink enthält alle potenziellen Verbindungen zwischen Flächen und Haltungen mit der jeweiligen Entfernung # t2 enthält von diesen Verbindungen nur die Fläche (als pk) und den minimalen Abstand, # so dass in der Abfrage nach "update" nur die jeweils nächste Verbindung gefiltert wird. # Da diese Abfrage nur für neu zu erstellende Verknüpfungen gelten soll (also noch kein Eintrag # im Feld "einleit.haltnam" -> sw.haltnam -> tlink.linkhal -> t1.linkhal). sql = u"""WITH tlink AS ( SELECT sw.pk AS pk, Distance(hal.geom,sw.geom) AS dist, hal.geom AS geohal, sw.geom AS geosw FROM haltungen AS hal INNER JOIN linksw AS sw ON Intersects(hal.geom,sw.gbuf) WHERE sw.glink IS NULL AND hal.ROWID IN ( SELECT ROWID FROM SpatialIndex WHERE f_table_name = 'haltungen' AND search_frame = sw.gbuf) and hal.geom IS NOT NULL and sw.gbuf IS NOT NULL{auswahl}) UPDATE linksw SET glink = (SELECT MakeLine(PointOnSurface(t1.geosw),Centroid(t1.geohal)) FROM tlink AS t1 INNER JOIN (SELECT pk, Min(dist) AS dmin FROM tlink GROUP BY pk) AS t2 ON t1.pk=t2.pk AND t1.dist <= t2.dmin + 0.000001 WHERE linksw.pk = t1.pk) WHERE linksw.glink IS NULL{auswlin}""".format(auswahl=auswahl, auswlin=auswlin) # logger.debug(u'\nSQL-3a:\n{}\n'.format(sql)) if not dbQK.sql(sql, u"QKan_LinkSW (5)"): return False progress_bar.setValue(50) # Löschen der Datensätze in linksw, bei denen keine Verbindung erstellt wurde, weil die # nächste Haltung zu weit entfernt ist. sql = u"""DELETE FROM linksw WHERE glink IS NULL""" if not dbQK.sql(sql, u"QKan_LinkSW (7)"): return False # Aktualisierung des logischen Cache if not updatelinksw(dbQK, deletelinkGeomNone=False): fehlermeldung(u'Fehler beim Update der Einzeleinleiter-Verknüpfungen', u'Der logische Cache konnte nicht aktualisiert werden.') return False progress_bar.setValue(100) status_message.setText(u"Fertig!") status_message.setLevel(QgsMessageBar.SUCCESS) # Karte aktualisieren iface.mapCanvas().refreshAllLayers() # iface.mainWindow().statusBar().clearMessage() # iface.messageBar().pushMessage(u"Information", u"Verknüpfungen sind erstellt!", level=QgsMessageBar.INFO) QgsMessageLog.logMessage(u"\nVerknüpfungen sind erstellt!", level=QgsMessageLog.INFO) return True
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)
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))
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)
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
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
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
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
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 countselection(self): """Zählt nach Änderung der Auswahlen in den Listen im Formular die Anzahl der betroffenen TEZG-Flächen""" liste_selAbflparamTeilgeb = self.listselectedTabitems( self.dlg.tw_selAbflparamTeilgeb) # logger.debug(u'QKan.createunbeffl.application.countselection (1)\nlen(liste_selAbflparamTeilgeb) = {}'.format(len(liste_selAbflparamTeilgeb))) # logger.debug(u'QKan.createunbeffl.application.countselection (2)\nliste_selAbflparamTeilgeb = {}'.format(str(liste_selAbflparamTeilgeb))) # Aufbereiten für SQL-Abfrage # Unterschiedliches Vorgehen, je nachdem ob mindestens eine oder keine Zeile # ausgewählt wurde # if len(liste_selAbflparamTeilgeb) == 0: # anzahl = sum([int(attr[-2]) for attr in self.listetezg]) # else: # anzahl = sum([int(attr[-2]) for attr in liste_selAbflparamTeilgeb]) # Vorbereitung des Auswahlkriteriums für die SQL-Abfrage: Kombination aus abflussparameter und teilgebiet # Dieser Block ist identisch in k_unbef und in application enthalten if len(liste_selAbflparamTeilgeb) == 0: auswahl = u'' elif len(liste_selAbflparamTeilgeb) == 1: auswahl = u' AND' elif len(liste_selAbflparamTeilgeb) >= 2: auswahl = u' AND (' else: fehlermeldung(u"Interner Fehler", u"Fehler in Fallunterscheidung!") return False # Anfang SQL-Krierien zur Auswahl der tezg-Flächen first = True for attr in liste_selAbflparamTeilgeb: if attr[4] == u'None' or attr[1] == u'None': fehlermeldung( u'Datenfehler: ', u'In den ausgewählten Daten sind noch Datenfelder nicht definiert ("NULL").' ) return False if first: first = False auswahl += u""" (tezg.abflussparameter = '{abflussparameter}' AND tezg.teilgebiet = '{teilgebiet}')""".format( abflussparameter=attr[0], teilgebiet=attr[1]) else: auswahl += u""" OR\n (tezg.abflussparameter = '{abflussparameter}' AND tezg.teilgebiet = '{teilgebiet}')""".format( abflussparameter=attr[0], teilgebiet=attr[1]) if len(liste_selAbflparamTeilgeb) >= 2: auswahl += u")" # Ende SQL-Krierien zur Auswahl der tezg-Flächen # Ende SQL-Krierien zur Auswahl der tezg-Flächen # Trick: Der Zusatz "WHERE 1" dient nur dazu, dass der Block zur Zusammenstellung von 'auswahl' identisch mit dem # Block in 'k_unbef.py' bleiben kann... sql = u"""SELECT count(*) AS anz FROM tezg WHERE 1{auswahl} """.format(auswahl=auswahl) if not self.dbQK.sql(sql, u"QKan.CreateUnbefFlaechen (5)"): return False data = self.dbQK.fetchone() if not (data is None): self.dlg.lf_anzahl_tezg.setText(u'{}'.format(data[0])) else: self.dlg.lf_anzahl_tezg.setText(u'0')
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)
def run(self): """Run method that performs all the real work""" database_QKan, epsg = get_database_QKan() if not database_QKan: fehlermeldung( u"Fehler in CreateUnbefFl", 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 # Abfragen der Tabelle tezg nach verwendeten Abflussparametern self.dbQK = DBConnection( dbname=database_QKan ) # Datenbankobjekt der QKan-Datenbank zum Lesen if self.dbQK is None: fehlermeldung( u"Fehler in QKan_CreateUnbefFl", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( database_QKan)) iface.messageBar().pushMessage(u"Fehler in QKan_Import_from_HE", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( \ database_QKan), level=QgsMessageBar.CRITICAL) return None # Kontrolle, ob in Tabelle "abflussparameter" ein Datensatz für unbefestigte Flächen vorhanden ist # (Standard: apnam = '$Default_Unbef') sql = u"""SELECT apnam FROM abflussparameter WHERE bodenklasse IS NOT NULL AND trim(bodenklasse) <> ''""" if not self.dbQK.sql(sql, u'createunbeffl.run (1)'): return False data = self.dbQK.fetchone() if data is None: if autokorrektur: daten = [ u"'$Default_Unbef', u'von QKan ergänzt', 0.5, 0.5, 2, 5, 0, 0, 'LehmLoess', '13.01.2011 08:44:50'" ] for ds in daten: sql = u"""INSERT INTO abflussparameter ( 'apnam', 'kommentar', 'anfangsabflussbeiwert', 'endabflussbeiwert', 'benetzungsverlust', 'muldenverlust', 'benetzung_startwert', 'mulden_startwert', 'bodenklasse', 'createdat') Values ({})""".format(ds) if not self.dbQK.sql(sql, u'createunbeffl.run (2)'): return False else: fehlermeldung( u'Datenfehler: ', u'Bitte ergänzen Sie in der Tabelle "abflussparameter" einen Datensatz für unbefestigte Flächen ("bodenklasse" darf nicht leer oder NULL sein)' ) # # Kontrolle, ob noch Flächen in Tabelle "tezg" ohne Zuordnung zu einem Abflussparameter oder zu einem # # Abflussparameter, bei dem keine Bodenklasse definiert ist (Kennzeichen für undurchlässige Flächen). # sql = u"""SELECT te.abflussparameter, te.teilgebiet, count(*) AS anz # FROM tezg AS te # LEFT JOIN abflussparameter AS ap # ON te.abflussparameter = ap.apnam # WHERE ap.bodenklasse IS NULL # GROUP BY abflussparameter, teilgebiet""" # if not self.dbQK.sql(sql, u'createunbeffl.run (3)'): # return False # data = self.dbQK.fetchall() # if len(data) > 0: # liste = [u'{}\t{}\t{}'.format(el1, el2, el3) for el1, el2, el3 in data] # liste.insert(0, u'\nAbflussparameter\tTeilgebiet\tAnzahl') # fehlermeldung(u'In Tabelle "tezg" fehlen Abflussparameter oder gehören zu befestigten Flächen (Bodenklasse = NULL):\n', # u'\n'.join(liste)) # return False sql = u"""SELECT te.abflussparameter, te.teilgebiet, bk.bknam, count(*) AS anz, CASE WHEN te.abflussparameter ISNULL THEN 'Fehler: Kein Abflussparameter angegeben' ELSE CASE WHEN bk.infiltrationsrateanfang ISNULL THEN 'Fehler: Keine Bodenklasse angegeben' WHEN bk.infiltrationsrateanfang < 0.00001 THEN 'Fehler: undurchlässige Bodenart' ELSE '' END END AS status FROM tezg AS te LEFT JOIN abflussparameter AS ap ON te.abflussparameter = ap.apnam LEFT JOIN bodenklassen AS bk ON bk.bknam = ap.bodenklasse GROUP BY abflussparameter, teilgebiet""" if not self.dbQK.sql(sql, u'createunbeffl.run (4)'): return None self.listetezg = self.dbQK.fetchall() nzeilen = len(self.listetezg) self.dlg.tw_selAbflparamTeilgeb.setRowCount(nzeilen) self.dlg.tw_selAbflparamTeilgeb.setHorizontalHeaderLabels([ u"Abflussparameter", u"Teilgebiet", u"Bodenklasse", u"Anzahl", u"Anmerkungen" ]) self.dlg.tw_selAbflparamTeilgeb.setColumnWidth( 0, 144) # 17 Pixel für Rand und Nummernspalte (und je Spalte?) self.dlg.tw_selAbflparamTeilgeb.setColumnWidth(1, 140) self.dlg.tw_selAbflparamTeilgeb.setColumnWidth(2, 90) self.dlg.tw_selAbflparamTeilgeb.setColumnWidth(3, 50) self.dlg.tw_selAbflparamTeilgeb.setColumnWidth(4, 200) for i, elem in enumerate(self.listetezg): for j, item in enumerate(elem): cell = u'{}'.format(elem[j]) self.dlg.tw_selAbflparamTeilgeb.setItem( i, j, QTableWidgetItem(cell)) self.dlg.tw_selAbflparamTeilgeb.setRowHeight(i, 20) # config in Dialog übernehmen # Autokorrektur if 'autokorrektur' in self.config: autokorrektur = self.config['autokorrektur'] else: autokorrektur = True self.dlg.cb_autokorrektur.setChecked(autokorrektur) self.countselection() # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() logger.debug('\n\nresult = {}'.format(repr(result))) # 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 liste_selAbflparamTeilgeb = self.listselectedTabitems( self.dlg.tw_selAbflparamTeilgeb) logger.debug(u'\nliste_selAbflparamTeilgeb (1): {}'.format( liste_selAbflparamTeilgeb)) autokorrektur = self.dlg.cb_autokorrektur.isChecked() self.config['autokorrektur'] = autokorrektur with open(self.configfil, 'w') as fileconfig: fileconfig.write(json.dumps(self.config)) createUnbefFlaechen(self.dbQK, liste_selAbflparamTeilgeb, autokorrektur)
def qgsadapt(projectTemplate, qkanDB, epsg, projectFile, setPathToTemplateDir=True, dbtyp=u'SpatiaLite'): '''Lädt eine (Vorlage-) Projektdatei (*.qgs) und adaptiert diese auf eine QKan-Datenbank an. Anschließend wird dieses Projekt geladen. Voraussetzungen: keine :projectTemplate: Vorlage-Projektdatei :type database: String :qkanDB: Ziel-Datenbank, auf die die Projektdatei angepasst werden soll :type qkanDB: String :projectFile: Zu Erzeugende Projektdatei :type projectFile: String :setPathToTemplateDir: Option, ob das Suchverzeichnis auf das Template-Verzeichnis gesetzt werden soll. :type setPathToTemplateDir: Boolean :dbtyp: Typ der Datenbank (SpatiaLite, PostGIS) :type dbtyp: String :returns: void ''' # ------------------------------------------------------------------------------ # Datenbankverbindungen dbQK = DBConnection( dbname=qkanDB, epsg=epsg) # Datenbankobjekt der QKan-Datenbank zum Schreiben if dbQK is None: fehlermeldung( u"Fehler in qgsadapt", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( qkanDB)) iface.messageBar().pushMessage(u"Fehler in qgsadapt", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( \ qkanDB), level=QgsMessageBar.CRITICAL) return None # -------------------------------------------------------------------------- # Zoom-Bereich für die Projektdatei vorbereiten sql = u'''SELECT min(xsch) AS xmin, max(xsch) AS xmax, min(ysch) AS ymin, max(ysch) AS ymax FROM schaechte''' try: dbQK.sql(sql) except BaseException as e: fehlermeldung('SQL-Fehler', str(e)) fehlermeldung("Fehler in qgsadapt", u"\nFehler in sql_zoom: \n" + sql + '\n\n') daten = dbQK.fetchone() try: zoomxmin, zoomxmax, zoomymin, zoomymax = daten except BaseException as e: fehlermeldung('SQL-Fehler', str(e)) fehlermeldung("Fehler in qgsadapt", u"\nFehler in sql_zoom; daten= " + str(daten) + '\n') # -------------------------------------------------------------------------- # Projektionssystem für die Projektdatei vorbereiten sql = """SELECT srid FROM geom_cols_ref_sys WHERE Lower(f_table_name) = Lower('schaechte') AND Lower(f_geometry_column) = Lower('geom')""" if not dbQK.sql(sql, 'importkanaldaten_dyna (37)'): return None srid = dbQK.fetchone()[0] try: crs = QgsCoordinateReferenceSystem( srid, QgsCoordinateReferenceSystem.EpsgCrsId) srsid = crs.srsid() proj4text = crs.toProj4() description = crs.description() projectionacronym = crs.projectionAcronym() if 'ellipsoidacronym' in dir(crs): ellipsoidacronym = crs.ellipsoidacronym() else: ellipsoidacronym = None except BaseException as e: srid, srsid, proj4text, description, projectionacronym, ellipsoidacronym = \ 'dummy', 'dummy', 'dummy', 'dummy', 'dummy', 'dummy' fehlermeldung('\nFehler in "daten"', str(e)) fehlermeldung("Fehler in qgsadapt", u"\nFehler bei der Ermittlung der srid: \n" + str(daten)) # -------------------------------------------------------------------------- # Datenbankverbindungen schliessen del dbQK # -------------------------------------------------------------------------- # Projektdatei schreiben, falls ausgewählt if projectFile is None or projectFile == u'': fehlermeldung(u'Bedienerfehler!', u'Es wurde keine Projektdatei ausgewählt') return False if setPathToTemplateDir: templatepath = os.path.join(pluginDirectory('qkan'), u"database/templates") projectpath = os.path.dirname(projectFile) if os.path.dirname(qkanDB) == projectpath: datasource = qkanDB.replace(os.path.dirname(qkanDB), u'.') else: datasource = qkanDB # Liste der Geotabellen aus QKan, um andere Tabellen von der Bearbeitung auszuschliessen # Liste steht in 3 Modulen: tools.k_tools, importdyna.import_from_dyna, importhe.import_from_he tabliste = [ u'einleit', u'einzugsgebiete', u'flaechen', u'haltungen', u'linkfl', u'linksw', u'pumpen', u'schaechte', u'teilgebiete', u'tezg', u'wehre' ] # Liste der QKan-Formulare, um individuell erstellte Formulare von der Bearbeitung auszuschliessen formsliste = [ 'qkan_abflussparameter.ui', 'qkan_anbindungageb.ui', 'qkan_anbindungeinleit.ui', 'qkan_anbindungflaechen.ui', 'qkan_auslaesse.ui', 'qkan_auslasstypen.ui', 'qkan_aussengebiete.ui', 'qkan_bodenklassen.ui', 'qkan_einleit.ui', 'qkan_einzugsgebiete.ui', 'qkan_entwaesserungsarten.ui', 'qkan_flaechen.ui', 'qkan_haltungen.ui', 'qkan_profildaten.ui', 'qkan_profile.ui', 'qkan_pumpen.ui', 'qkan_pumpentypen.ui', 'qkan_schaechte.ui', 'qkan_simulationsstatus.ui', 'qkan_speicher.ui', 'qkan_speicherkennlinien.ui', 'qkan_swref.ui', 'qkan_teilgebiete.ui', 'qkan_tezg.ui', 'qkan_wehre.ui' ] # Lesen der Projektdatei ------------------------------------------------------------------ qgsxml = ET.parse(projectTemplate) root = qgsxml.getroot() # Projektionssystem anpassen -------------------------------------------------------------- for tag_maplayer in root.findall(u".//projectlayers/maplayer"): tag_datasource = tag_maplayer.find(u"./datasource") tex = tag_datasource.text # Nur QKan-Tabellen bearbeiten if tex[tex.index(u'table="') + 7:].split(u'" ')[0] in tabliste: # <extend> löschen for tag_extent in tag_maplayer.findall(u"./extent"): tag_maplayer.remove(tag_extent) for tag_spatialrefsys in tag_maplayer.findall( u"./srs/spatialrefsys"): tag_spatialrefsys.clear() elem = ET.SubElement(tag_spatialrefsys, u'proj4') elem.text = proj4text elem = ET.SubElement(tag_spatialrefsys, u'srsid') elem.text = u'{}'.format(srsid) elem = ET.SubElement(tag_spatialrefsys, u'srid') elem.text = u'{}'.format(srid) elem = ET.SubElement(tag_spatialrefsys, u'authid') elem.text = u'EPSG: {}'.format(srid) elem = ET.SubElement(tag_spatialrefsys, u'description') elem.text = description elem = ET.SubElement(tag_spatialrefsys, u'projectionacronym') elem.text = projectionacronym if ellipsoidacronym is not None: elem = ET.SubElement(tag_spatialrefsys, u'ellipsoidacronym') elem.text = ellipsoidacronym # Pfad zu Formularen auf plugin-Verzeichnis setzen ----------------------------------------- formspath = os.path.join(pluginDirectory('qkan'), u"forms") for tag_maplayer in root.findall(u".//projectlayers/maplayer"): tag_editform = tag_maplayer.find(u"./editform") dateiname = os.path.basename(tag_editform.text) if dateiname in formsliste: # Nur QKan-Tabellen bearbeiten tag_editform.text = os.path.join(formspath, dateiname) # Zoom für Kartenfenster einstellen ------------------------------------------------------- for tag_extent in root.findall(u".//mapcanvas/extent"): elem = tag_extent.find(u"./xmin") elem.text = u'{:.3f}'.format(zoomxmin) elem = tag_extent.find(u"./ymin") elem.text = u'{:.3f}'.format(zoomymin) elem = tag_extent.find(u"./xmax") elem.text = u'{:.3f}'.format(zoomxmax) elem = tag_extent.find(u"./ymax") elem.text = u'{:.3f}'.format(zoomymax) # Projektionssystem anpassen -------------------------------------------------------------- for tag_spatialrefsys in root.findall( u".//mapcanvas/destinationsrs/spatialrefsys"): tag_spatialrefsys.clear() elem = ET.SubElement(tag_spatialrefsys, u'proj4') elem.text = proj4text elem = ET.SubElement(tag_spatialrefsys, u'srid') elem.text = u'{}'.format(srid) elem = ET.SubElement(tag_spatialrefsys, u'authid') elem.text = u'EPSG: {}'.format(srid) elem = ET.SubElement(tag_spatialrefsys, u'description') elem.text = description elem = ET.SubElement(tag_spatialrefsys, u'projectionacronym') elem.text = projectionacronym if ellipsoidacronym is not None: elem = ET.SubElement(tag_spatialrefsys, u'ellipsoidacronym') elem.text = ellipsoidacronym # Pfad zur QKan-Datenbank anpassen for tag_datasource in root.findall( u".//projectlayers/maplayer/datasource"): text = tag_datasource.text tag_datasource.text = u"dbname='" + datasource + u"' " + text[ text.find(u'table='):] qgsxml.write(projectFile) # writing modified project file logger.debug(u'Projektdatei: {}'.format(projectFile)) # logger.debug(u'encoded string: {}'.format(tex)) # ------------------------------------------------------------------------------ # Abschluss: Ggfs. Protokoll schreiben und Datenbankverbindungen schliessen iface.mainWindow().statusBar().clearMessage() iface.messageBar().pushMessage( "Information", "Projektdatei ist angepasst und muss neu geladen werden!", level=QgsMessageBar.INFO)