Ist es möglich, dynamische Ebenennamen in QGIS-Projekten zu haben?

9

Ich habe ein QGIS-Projekt mit Ebenen, die auf PostGIS-SQL-Abfragen basieren, die das aktuelle Datum verwenden. Da sich die Daten in der Datenbank ändern, geben diese Abfragen jeden neuen Tag andere Daten zurück.

Ist es möglich, den Namen der Ebene im Ebenenbaumbedienfeld dynamisch zu ändern, sodass er das aktuelle Datum darstellt? (dh Layername wie Traffic on 24.01.2015, der sich jeden neuen Tag ändert). Die Daten für die Beschriftung sollten dem Attribut eines Features in einer Ebene entnommen werden - sie haben alle den gleichen Wert für das Feld traffic_date.

Mofoyoda
quelle
Was genau würden Sie aus Ihrer Datenbanktabelle "Verkehr" oder dem aktuellen Datum extrahieren?
Germán Carrillo
Ich extrahiere Daten für das aktuelle Datum in eine Ebene und prognostiziere Daten in andere Ebenen. "24.01.2015" ist also eigentlich ein Feldwert, der aus der Datenbank stammt. Ich brauche den Ebenennamen im Projekt, um ihn automatisch entsprechend dem Datum zu ändern.
Mofoyoda
Wäre es in Ordnung, den Namen jedes Mal zu ändern, wenn das Projekt geladen wird?
Nathan W

Antworten:

13

Wenn ich Sie richtig verstanden habe, lautet die Antwort: Ja, QGIS unterstützt dynamische Ebenennamen.

Sie müssten ein Python-Makro schreiben, das bei jedem Öffnen des Projekts ausgeführt wird. Dies wäre der Workflow:

  1. Gehen Sie zu QGIS->Project->Project Propertiesund ersetzen Sie openProject()durch den folgenden Python-Code:

    def openProject():
        import re, qgis     
        iface = qgis.utils.iface
        layers = iface.mapCanvas().layers()
        for lyr in layers:
            # Get date from layer
            it=lyr.getFeatures()
            feat = next(it)
            idx = lyr.fieldNameIndex('traffic_da')
            currDate = feat.attributes()[idx]
    
            # Set new layer name
            name = lyr.name()
            if re.search(' on \d{2,2}.\d{2,2}.\d{4,4}$', name):
                 name = name[:-14]
            name = name + " on " + currDate
            lyr.setLayerName( name )
    

    Geben Sie hier die Bildbeschreibung ein

    Hinweis 1: Ich habe es an Shapefiles getestet. Das Feld, aus dem ich Daten nehme, ist daher, traffic_dadass Shapefiles keine weiteren Buchstaben in Feldnamen unterstützen. Passen Sie dies im Code an, um auf Ihren Ebenen zu arbeiten.

    Hinweis 2: Abhängig von Ihrer Projektkonfiguration sollten Sie Validierungscode hinzufügen, um nur auf die gewünschten Ebenen zu reagieren. Wenn Sie den Code beispielsweise auf Rasterebenen ausführen, werden mit Sicherheit Fehler angezeigt. Wenn Sie dabei Hilfe benötigen, öffnen Sie eine neue Frage, ich kann Ihnen helfen.

  2. Stellen Sie sicher, dass Sie Makros in Ihrem Projekt folgendermaßen aktivieren: Settings->Options->General->Enable macros: Always

  3. Laden Sie Ihre Ebenen in das Projekt.

  4. Speichern Sie Ihr Projekt.

Jedes Mal, wenn Sie Ihr Projekt von diesem Punkt aus öffnen, sind Ihre Ebenennamen dynamisch. Das Datum wird aus dem Feld traffic_datein der Attributtabelle der einzelnen Ebenen entnommen .

Nach dem ersten Öffnen des Projekts wurden meine Ebenennamen auf diese Weise dynamisch generiert:

Geben Sie hier die Bildbeschreibung ein

Ich denke, das kann Ihnen helfen, loszulegen. Sagen Sie mir, wenn Sie mit nicht offensichtlichen Problemen konfrontiert sind.

Germán Carrillo
quelle
Ich habe es herausgefunden, indem ich Ihren Kommentar gelesen und 1s gepostet habe, bevor ich die Antwort eingereicht habe. Einige Anpassungen sollten im Code vorgenommen werden, um der spezifischen Anordnung der Ebenen zu entsprechen, aber ich hoffe, @mofoyoda kann damit umgehen.
Germán Carrillo
1
Ja, es ist ein guter erster Schritt. Sie können auch einfach den Index von onund den Streifen von dort bis zum Ende finden, um bei der Verwendung von Regex zu sparen.
Nathan W
1
@gcarrillo intensiv! Aber großartig!
DPSSpatial
1
@gcarrillo Sehr cool, danke! Ich versuche immer noch herauszufinden, wie man nur auf bestimmte Schichten aufträgt, ich hoffe, ich werde es schaffen. Danke für eine tolle Antwort!
Mofoyoda