Cara memilih fitur yang berisi string teks tertentu menggunakan ekspresi di QGIS

15

Saya perlu mendesain bentuk paket survei poligon, berdasarkan apakah poligon tersebut merupakan klaim mineral atau tidak. Sayangnya, satu-satunya informasi tentang apakah poligon adalah klaim mineral atau tidak terdapat di bidang "TITLE" pada tabel atribut, yang memberikan nama lengkap hukum dari paket yang disurvei. Misalnya, 'BANYAK DISTRIK 5639, MENJADI PENGHARGAAN NO. 2 KLAIM MINERAL, KDYD '. Saya membutuhkan ekspresi yang memilih fitur apa pun yang mengandung teks 'KLAIM MINERAL' di bidang "TITLE".

Chris
sumber

Jawaban:

24

Anda hanya harus menggunakan LIKEoperator.

Sebagai contoh, "TITLE" LIKE '%MINERAL CLAIM%'

The %simbol bertindak seperti wildcard.

LIKEcase-sensitive, sedangkan ILIKEtidak.

SaultDon
sumber
Perlu diketahui bahwa ini adalah operasi yang lambat, Anda mungkin ingin menggunakannya sekali untuk menghasilkan kolom baru alih-alih memilikinya sebagai ekspresi sepanjang waktu.
bugmenot123
Ini lambat untuk bentuk besar, jadi saya salin / tempel seleksi sebagai layer vektor baru.
Chris
@chris Anda dapat menggunakan kueri yang sama di bagian QGIS lainnya seperti sebagai kueri definisi atau ditata menggunakan rendering berbasis aturan - sangat tergantung pada alasan mengapa Anda perlu menerapkan kueri (yaitu, analisis, visualisasi, ekspor, dll). Pilihan agak intensif tetapi jika diterapkan sebagai kueri definisi maka hanya menampilkan fitur-fitur tersebut dalam kueri pada kanvas atau membuatnya tersedia untuk diproses. Pada dasarnya apa yang Anda lakukan ketika menyalin / menempelkan seleksi sebagai layer vektor baru.
SaultDon
Indeks tidak dapat digunakan dengan LIKE jadi saya selalu mencoba untuk menghindari melakukannya lagi dan lagi. Tapi ya, itu mungkin tidak relevan, pasti dengan dataset kecil ada buah lain yang menggantung rendah untuk kecepatan.
bugmenot123
1
@ bugmenot123 Saya baru belajar, bahwa jika Anda memiliki indeks ketika data Anda di postgresql, LIKE akan menggunakannya dalam kondisi tertentu (seperti di mana% berada dalam kueri) dan tidak melakukan pemindaian berurutan! blog.cleverelephant.ca/2016/08/pgsql-text-pattern-ops.html
SaultDon
3

Saya punya masalah persis ini dan menyelesaikannya dari konsol python dengan regex. Meskipun regex bisa rumit, sangat kuat. Dan Anda akan dibiarkan dengan alat yang dapat Anda gunakan dengan kasing yang lebih sulit. Ini dokumennya . dan di sini adalah mesin online yang bagus untuk menguji string regex Anda.

Pertama di sini adalah skrip cepat yang saya jalankan untuk memeriksa string regex saya di 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"

Setelah Anda puas dengan pencocokan regex Anda, Anda bisa membungkusnya dalam suatu fungsi untuk menyediakan pilihan untuk semua fitur yang cocok. Di bawah ini adalah fungsi untuk melakukan hal itu.

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)

Anda harus menyimpan ini ke dalam file dan menjalankannya dari ide python qgis.

(Belum diuji tetapi cukup percaya diri)

Tuan Ungu
sumber
1
Nasihat yang bagus untuk mempelajari regex, tetapi terlalu banyak mengatasi masalah yang ada.
alphabetasoup
@ alpha-beta-soup benar. Pada kasus ini. Namun, masalah SANGAT mirip pasti akan merasa sangat diperlukan. nomor lot <6000? atau 2 klaim mineral pertama? Ini hanyalah jawaban (walaupun jauh lebih kompleks / kuat). Mungkin itu akan membantu orang lain.
Tuan Ungu
3
Perhatikan juga bahwa QGIS memiliki fungsi pencocokan ekspresi reguler bawaan - regexp_match.
ndawson
Tentu saja semakin banyak jawaban "mendalam". Sedikit berlebihan untuk apa yang saya butuhkan, tetapi tetap menghargainya. Ini pasti akan membantu orang lain di masa depan.
Chris