Beispiel #1
0
    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
Beispiel #2
0
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)
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
    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)
Beispiel #7
0
    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)
Beispiel #9
0
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
Beispiel #10
0
    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
Beispiel #11
0
    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
Beispiel #12
0
    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
Beispiel #13
0
    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
Beispiel #14
0
    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')
Beispiel #15
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)
Beispiel #16
0
    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)
Beispiel #17
0
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)