Jak wybrać funkcje zawierające określony ciąg tekstowy za pomocą wyrażenia w QGIS

16

Muszę stylizować plik kształtu wielokąta działki ankiety na podstawie tego, czy wielokąt jest roszczeniem mineralnym, czy nie. Niestety jedyne informacje o tym, czy wielokąt jest roszczeniem mineralnym, czy nie, znajdują się w polu „TITLE” tabeli atrybutów, która podaje pełną prawną nazwę badanej działki. Na przykład „DISTRICT LOT 5639, BEING AWARD NO. 2 ROSZCZENIE MINERALNE, KDYD ”. Potrzebuję wyrażenia, które wybiera dowolną cechę zawierającą tekst „ROSZCZENIE MINERALNE” w polu „TYTUŁ”.

Chris
źródło

Odpowiedzi:

25

Musisz tylko użyć LIKEoperatora.

Na przykład, "TITLE" LIKE '%MINERAL CLAIM%'

%Symbol działa jak zamiennika.

LIKErozróżnia małe i wielkie litery, podczas gdy ILIKEnie.

SaultDon
źródło
I pamiętaj, że jest to powolna operacja, możesz użyć jej raz, aby wygenerować nową kolumnę zamiast mieć ją cały czas jako wyrażenie.
bugmenot123
Duży kształt jest wolny, więc po prostu skopiowałem / wkleiłem zaznaczenie jako nową warstwę wektorową.
Chris
@chris Możesz użyć tego samego zapytania w innych częściach QGIS, takich jak zapytanie definicji lub styl z wykorzystaniem renderowania opartego na regułach - naprawdę zależy od powodu, dla którego musisz zastosować zapytanie (tj. analiza, wizualizacja, eksport itp.). Wybory są nieco intensywne, ale jeśli zostaną zastosowane jako zapytanie definicji, wówczas wyświetla tylko te funkcje w zapytaniu na kanwie lub udostępnia je do przetworzenia. Zasadniczo to, co zrobiłeś podczas kopiowania / wklejania zaznaczenia jako nowej warstwy wektorowej.
SaultDon
Indeksów nie można używać z LIKE, dlatego zawsze staram się unikać ich powtarzania. Ale tak, może to być nieistotne, na pewno przy małych zestawach danych są inne nisko wiszące owoce dla szybkości.
bugmenot123
1
@ bugmenot123 Właśnie dowiedziałem się, że jeśli masz indeks, gdy twoje dane są w postgresql, LIKE użyje go w określonych warunkach (np. gdzie% znajduje się w zapytaniu) i nie wykona skanowania sekwencyjnego! blog.cleverelephant.ca/2016/08/pgsql-text-pattern-ops.html
SaultDon
3

Miałem dokładnie ten problem i rozwiązałem go z konsoli Pythona za pomocą wyrażenia regularnego. Wyrażenia regularne mogą być trudne, ale są bardzo potężne. I pozostanie Ci narzędzie, którego możesz użyć w trudniejszych przypadkach. Oto dokumenty . a tutaj jest fajna maszyna online do testowania łańcuchów wyrażeń regularnych.

Najpierw jest szybki skrypt, który uruchamiam, aby sprawdzić ciągi regularne w qgis

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"

Gdy będziesz zadowolony z dopasowania wyrażenia regularnego, możesz zawinąć go w funkcję zapewniającą wybór wszystkich pasujących funkcji. Poniżej znajduje się funkcja, która właśnie to robi.

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)

Będziesz musiał zapisać to do pliku i uruchomić go z qgis python ide.

(nieprzetestowane, ale dość pewne siebie)

Mr Purple
źródło
1
Świetna rada, aby nauczyć się wyrażenia regularnego, ale przesadzenie z danym problemem.
alphabetasoup
1
@ Zupa alfa-beta prawdziwa. W tym przypadku. Jednak BARDZO podobne problemy z pewnością byłyby niezbędne. numery partii <6000? lub pierwsze 2 roszczenia mineralne? To tylko kolejna (choć znacznie bardziej złożona / mocna) odpowiedź. Być może pomoże to komuś innemu.
Mr Purple
3
Zauważ też, że QGIS ma wbudowaną funkcję dopasowania wyrażeń regularnych - regexp_match.
ndawson
Z pewnością tym bardziej „dogłębna” odpowiedź. Trochę przesady w stosunku do tego, czego potrzebuję, ale mimo to doceń to. Z pewnością pomoże innym w przyszłości.
Chris