Cómo seleccionar características que contienen cadenas de texto específicas usando una expresión en QGIS

15

Necesito diseñar un archivo de forma de polígono de parcela topográfica, en función de si el polígono es un reclamo mineral o no. Desafortunadamente, la única información sobre si un polígono es un reclamo mineral o no está contenida en el campo "TÍTULO" de la tabla de atributos, que proporciona el nombre legal completo de la parcela encuestada. Por ejemplo, 'DISTRITO LOTE 5639, PREMIO NO. 2 RECLAMACIÓN MINERAL, KDYD '. Necesito una expresión que seleccione cualquier característica que contenga el texto 'RECLAMACIÓN MINERAL' en el campo "TÍTULO".

Chris
fuente

Respuestas:

24

Solo tienes que usar el LIKEoperador.

Por ejemplo, "TITLE" LIKE '%MINERAL CLAIM%'

El %símbolo actúa como un comodín.

LIKEes sensible a mayúsculas y minúsculas, mientras ILIKEque no lo es.

SaultDon
fuente
Y tenga en cuenta que esta es una operación lenta, es posible que desee usarla una vez para generar una nueva columna en lugar de tenerla como expresión todo el tiempo.
bugmenot123
Es lento para una forma grande, así que simplemente copié / pegué la selección como una nueva capa vectorial.
Chris
@chris Puede usar esa misma consulta en otras partes de QGIS, como una consulta de definición o un estilo usando la representación basada en reglas, realmente depende de la razón por la que necesita aplicar la consulta (es decir, análisis, visualización, exportación, etc.). Las selecciones son un poco intensivas, pero si se aplican como una consulta de definición, solo muestra esas características en la consulta en el lienzo o las pone a disposición para su procesamiento. Esencialmente, lo que hizo al copiar / pegar la selección como una nueva capa vectorial.
SaultDon
Los índices no se pueden usar con LIKE, por lo que siempre trato de evitar hacerlo una y otra vez. Pero sí, puede ser irrelevante, definitivamente con pequeños conjuntos de datos hay otros frutos bajos para la velocidad.
bugmenot123
1
@ bugmenot123 Acabo de enterarme de que si tiene un índice cuando sus datos están en postgresql, LIKE lo usará en condiciones específicas (como donde está el% en la consulta) y no realizará un análisis secuencial. blog.cleverelephant.ca/2016/08/pgsql-text-pattern-ops.html
SaultDon
3

Tuve este problema exacto y lo resolví desde la consola de Python con regex. Si bien la expresión regular puede ser complicada, es muy poderosa. Y te quedarás con una herramienta que puedes usar con casos de coincidencias más difíciles. Aquí están los documentos . y aquí hay una buena máquina en línea para probar sus cadenas de expresiones regulares.

En primer lugar, aquí está el script rápido que ejecuto para verificar mis cadenas de expresiones regulares en 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"

Una vez que esté satisfecho con su coincidencia de expresiones regulares, puede envolverla en una función para proporcionar una selección de todas las características que coinciden. A continuación hay una función para hacer precisamente eso.

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)

Deberá guardar esto en un archivo y ejecutarlo desde qgis python ide.

(no probado pero bastante confiado)

Señor púrpura
fuente
1
Un gran consejo para aprender expresiones regulares, pero exagerado para el problema en cuestión.
alphabetasoup
@ alpha-beta-soup cierto. En este caso. Sin embargo, problemas MUY similares ciertamente lo encontrarían indispensable. números de lote <6000? o las primeras 2 reclamaciones minerales? Es solo otra respuesta (aunque mucho más compleja / poderosa). Quizás ayude a alguien más.
Mr Purple
33
También tenga en cuenta que QGIS tiene una función integrada de coincidencia de expresiones regulares: regexp_match.
ndawson
Ciertamente, la respuesta más "en profundidad". Un poco exagerado para lo que necesito, pero de todos modos lo aprecio. Seguramente ayudará a otros en el futuro.
Chris