Auswählen von Features, die eine bestimmte Textzeichenfolge enthalten, mithilfe eines Ausdrucks in QGIS

15

Ich muss ein Umfragepaket-Polygon-Shapefile basierend darauf gestalten, ob das Polygon eine mineralische Behauptung ist oder nicht. Leider enthält das Feld "TITLE" der Attributtabelle die einzigen Informationen darüber, ob es sich bei einem Polygon um eine mineralische Angabe handelt oder nicht, in der der vollständige rechtliche Name des vermessenen Flurstücks angegeben ist. Zum Beispiel 'DISTRICT LOT 5639, BEING AWARD NO. 2 MINERALANSPRUCH, KDYD '. Ich benötige einen Ausdruck, der ein beliebiges Feature auswählt, das den Text 'MINERAL CLAIM' im Feld "TITLE" enthält.

Chris
quelle

Antworten:

24

Sie müssen nur den LIKEOperator verwenden.

Beispielsweise, "TITLE" LIKE '%MINERAL CLAIM%'

Das %Symbol fungiert als Platzhalter.

LIKEist case-sensitive, während ILIKEnicht.

SaultDon
quelle
Beachten Sie, dass dies eine langsame Operation ist. Möglicherweise möchten Sie sie einmal verwenden, um eine neue Spalte zu generieren, anstatt sie ständig als Ausdruck zu verwenden.
Bugmenot123
Für eine große Form ist es langsam, daher habe ich die Auswahl einfach als neue Vektorebene kopiert / eingefügt.
Chris
@chris Sie können dieselbe Abfrage in anderen Teilen von QGIS verwenden, z. B. als Definitionsabfrage oder mit regelbasiertem Rendering - hängt davon ab, warum Sie die Abfrage anwenden müssen (z. B. Analyse, Visualisierung, Export usw.). Die Auswahl ist etwas umfangreich, wird jedoch als Definitionsabfrage angewendet, werden nur diese Features in der Abfrage im Erstellungsbereich angezeigt oder für die Verarbeitung verfügbar gemacht. Im Wesentlichen, was Sie beim Kopieren / Einfügen der Auswahl als neue Vektorebene getan haben.
SaultDon
Indizes können nicht mit LIKE verwendet werden, daher versuche ich immer, sie nicht immer wieder zu verwenden. Aber ja, es könnte irrelevant sein, auf jeden Fall gibt es bei kleinen Datensätzen andere niedrig hängende Früchte für die Geschwindigkeit.
Bugmenot123
1
@ bugmenot123 Ich habe gerade erfahren, dass, wenn Sie einen Index haben, wenn sich Ihre Daten in postgresql befinden, LIKE ihn unter bestimmten Bedingungen verwendet (wie z. B. wo sich das% in der Abfrage befindet) und keinen sequentiellen Scan durchführt! blog.cleverelephant.ca/2016/08/pgsql-text-pattern-ops.html
SaultDon
3

Ich hatte genau dieses Problem und löste es von der Python-Konsole mit Regex. Während Regex schwierig sein kann, ist es sehr mächtig. Und Sie werden mit einem Werkzeug zurückbleiben, das Sie für schwierigere Streichholzschachteln verwenden können. Hier sind die Dokumente . und hier ist eine nette Online-Maschine zum Testen Ihrer Regex-Strings.

Erstens ist hier das schnelle Skript, mit dem ich meine Regex-Zeichenfolgen in qgis überprüfe

import re
RES_STRING='MINERAL CLAIM'
REGEX_HAYSTACK='DISTRICT LOT 5639, BEING AWARD NO. 2 MINERAL CLAIM, KDYD'

REGEX_STRING=re.compile(RES_STRING)
print "searching for "+RES_STRING+" in "+REGEX_HAYSTACK
REGEX_MATCH = REGEX_STRING.search(REGEX_HAYSTACK)
if REGEX_MATCH:
    print "found '"+REGEX_MATCH.group()+"'"
else:
    print "No match found"

Wenn Sie mit Ihrer Regex-Übereinstimmung zufrieden sind, können Sie sie in eine Funktion einschließen, um eine Auswahl für alle übereinstimmenden Funktionen bereitzustellen. Unten finden Sie eine Funktion, um genau das zu tun.

def select_by_regex(input_layer,attribute_name,regex_string):
    import re
    RES_STRING=regex_string
    attribute_name_idx = input_layer.fieldNameIndex(attribute_name)
    if attribute_name_idx<0:
        raise valueError("cannot find attribute"+attribute_name)
    else:
        fids=[]
        for feature in input_layer.getFeatures():
            REGEX_HAYSTACK=feature[attribute_name_idx]
            REGEX_STRING=re.compile(RES_STRING)
            REGEX_MATCH = REGEX_STRING.search(REGEX_HAYSTACK)
            if REGEX_MATCH:
                fids.append(feature.id())
            else:
                pass
        input_layer.setSelectedFeatures(fids)


#USAGE BIT
input_layer = QgsVectorLayer('path/to/shape/file.shp','layer name', 'ogr')
QgsMapLayerRegistry.instance().addMapLayer(input_layer)   
regex_string='MINERAL CLAIM'
attribute_name='TITLE'
select_by_regex(input_layer,attribute_name,regex_string)

Sie müssen dies in einer Datei speichern und von der QGIS-Python-Ide ausführen.

(ungetestet aber ziemlich zuversichtlich)

Mr Purple
quelle
1
Toller Rat, um Regex zu lernen, aber übertrieben für das anstehende Problem.
Buchstabensuppe
@ alpha-beta-suppe stimmt. In diesem Fall. SEHR ähnliche Probleme wären jedoch sicherlich unabdingbar. Chargennummern <6000? oder die ersten 2 mineralischen Claims? Es ist nur eine andere (wenn auch viel komplexere / mächtigere) Antwort. Vielleicht hilft es jemand anderem.
Mr Purple
3
Beachten Sie auch, dass QGIS eine integrierte Match-Funktion für reguläre Ausdrücke hat - regexp_match.
ndawson
Sicherlich die tiefer gehende Antwort. Ein wenig übertrieben für das, was ich brauche, aber ich weiß es trotzdem zu schätzen. Es wird sicherlich anderen in Zukunft helfen.
Chris