QGISの式を使用して特定のテキスト文字列を含むフィーチャを選択する方法


15

ポリゴンがミネラルクレームであるかどうかに基づいて、調査区画ポリゴンシェープファイルのスタイルを設定する必要があります。残念ながら、ポリゴンがミネラルクレームであるかどうかに関する唯一の情報は、属性テーブルの「TITLE」フィールドに含まれており、調査対象パーセルの正式な名前を示しています。たとえば、「DISTRICT LOT 5639、BEING AWARD NO。2ミネラルクレーム、KDYD '。「TITLE」フィールドに「MINERAL CLAIM」というテキストを含む機能を選択する式が必要です。

回答:


24

LIKE演算子を使用する必要があります。

例えば、 "TITLE" LIKE '%MINERAL CLAIM%'

%シンボルは、ワイルドカードのように動作します。

LIKE大文字と小文字が区別されますが、区別されILIKEません。


また、これは低速の操作であるため、常に式として使用するのではなく、一度使用して新しい列を生成することをお勧めします。
bugmenot123

大きなシェイプでは遅いため、選択範囲を新しいベクターレイヤーとして単純にコピー/貼り付けします。
クリス

@chris QGISの他の部分で同じクエリを定義クエリとして使用したり、ルールベースのレンダリングを使用してスタイル設定したりできます-クエリを適用する必要がある理由(分析、視覚化、エクスポートなど)によって異なります。選択は少々集中的ですが、定義クエリとして適用された場合、キャンバス上のクエリ内のそれらの機能のみを表示するか、処理できるようにします。基本的に、選択範囲を新しいベクターレイヤーとしてコピー/貼り付けするときに行ったこと。
-SaultDon

LIKEでインデックスを使用することはできません。そのため、インデックスを何度も使用しないようにしています。しかし、はい、それは無関係であるかもしれません、確かに小さなデータセットでは、スピードのための他の低いハングフルーツがあります。
bugmenot123

1
@ bugmenot123私が学んだのは、データがpostgresqlにあるときにインデックスがある場合、LIKEは特定の条件(クエリ内の%など)でインデックスを使用し、シーケンシャルスキャンを実行しないことです!blog.cleverelephant.ca/2016/08/pgsql-text-pattern-ops.html
SaultDon 16

3

私はこの正確な問題を抱えており、Pythonコンソールから正規表現で解決しました。正規表現は難しい場合がありますが、非常に強力です。そして、より難しいマッチケースで使用できるツールが残されます。 こちらがドキュメントです。また、正規表現文字列をテストするための素晴らしいオンラインマシンがあります。

まず、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"

正規表現の一致に満足したら、それを関数でラップして、一致するすべての機能の選択を提供できます。以下は、まさにそれを行う関数です。

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)

これをファイルに保存し、qgis python ideから実行する必要があります。

(テストされていないが、かなり自信がある)


1
正規表現を学ぶための素晴らしいアドバイスですが、目前の問題はやり過ぎです。
alphabetasoup

@ alpha-beta-soup true。この場合。しかし、非常に似たような問題は確かにそれが不可欠であるとわかります。ロット番号<6000?または最初の2つのミネラルクレーム?それはもう1つの(はるかに複雑/強力ではあるが)答えです。おそらく他の誰かを助けるでしょう。
パープル氏

3
また、QGISには正規表現一致関数が組み込まれていることに注意してください-regexp_match。
ndawson

確かに、より詳細な答えです。私が必要なものは少しやり過ぎですが、それでも感謝しています。将来的に他の人を確実に助けるでしょう。
クリス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.