Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Algoritmo utils ExportFeaturesByAttribute #813

Merged
merged 4 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<body>

<div>
<p>Help versão 1.0</p>
<hr/>
<h2>Descrição:</h2>
<h4 style="text-align: center; padding: 6px;">
Exporta feições de uma camada com base em um atributo específico e um operador. Permite selecionar e exportar feições filtradas, como aquelas que contêm, começam com ou não contêm um valor específico.
</h4>
<hr />
</div>

<div>
<h2>Parâmetros:</h2>
<p>
<span style="margin-bottom: 10px;">
&#8226; Camada de entrada &rarr; Camada vetorial que será processada para identificar feições com base em um atributo específico.
</span>

<span style="margin-bottom: 10px;">
&#8226; Atributo de seleção &rarr; Nome do atributo que será utilizado para a filtragem.
</span>

<span style="margin-bottom: 10px;">
&#8226; Operador &rarr; Operador de comparação a ser utilizado para selecionar feições (ex.: igual, diferente, contém, não contém, etc.).
</span>

<span style="margin-bottom: 10px;">
&#8226; Valor &rarr; Valor a ser comparado com o atributo selecionado.
</span>

<span style="margin-bottom: 10px;">
&#8226; Camada de saída &rarr; Nova camada onde as feições filtradas serão exportadas.
</span>

<span style="color:#ff0000; font-weight: bold;"><u>Atenção</u>: certifique-se de usar o operador correto para garantir que as feições desejadas sejam exportadas corretamente. Caso utilize a opção "Contém" ou "Não contém", o valor deve ser ajustado para a string apropriada.</span>

</p>
<hr />
</div>

<div>
<h2>Exemplo de uso: </h2>
<h4>Filtrando feições em uma camada de pontos de interesse na modelagem EDGV3.0 (EPSG:4674)</h4>

<span style="margin-bottom: 10px;">&#8226; Camada de entrada &rarr; cobter_massa_dagua_a</span><br>
<span style="margin-bottom: 10px;">&#8226; Atributo de seleção &rarr; tipo</span><br>
<span style="margin-bottom: 10px;">&#8226; Operador &rarr; igual '='</span><br>
<span style="margin-bottom: 10px;">&#8226; Valor &rarr; 7</span><br>
<span style="margin-bottom: 10px;">&#8226; Camada de saída &rarr; Output layer</span>

<hr />
</div>


<div>
<h2>Nota sobre o uso em models:</h2>
<p style="text-align: justify;">
Este algoritmo também pode ser utilizado em models quando houver necessidade de filtrar feições com base em seus atributos.
No entanto, deve ser usado <strong>restritamente</strong> quando a camada é opcional para o processamento.
isso evita que o modelo aplique o filtro em camadas essenciais ou obrigatórias sem supervisão.
</p>
<hr />
</div>

</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# -*- coding: utf-8 -*-
"""
/***************************************************************************
DsgTools
A QGIS plugin
Brazilian Army Cartographic Production Tools
-------------------
begin : 2024-11-06
git sha : $Format:%H$
copyright : (C) 2024 by Jean Michael Estevez Alvarez - Brazilian Army
email : jeanalvarez@id.uff.br
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
"""

from qgis.PyQt.QtCore import QCoreApplication, QVariant
from qgis.core import (QgsProcessing,
QgsProcessingException,
QgsProcessingAlgorithm,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterField,
QgsProcessingParameterEnum,
QgsProcessingParameterString,
QgsProcessingParameterFeatureSink,
QgsExpression,
QgsFeatureSink,
QgsVectorLayer,
QgsFeatureRequest)
from qgis import processing

from ..Help.algorithmHelpCreator import HTMLHelpCreator as help


class ExportFeaturesByAttributeAlgorithm(QgsProcessingAlgorithm):
"""Algorithm to export features based on attribute filtering."""

INPUT = 'INPUT'
FIELD = 'FIELD'
OPERATOR = 'OPERATOR'
VALUE = 'VALUE'
OUTPUT = 'OUTPUT'

OPERATORS = ['=',
'<>',
'>',
'>=',
'<',
'<=',
'begins with',
'contains',
'is null',
'is not null',
'does not contain']
STRING_OPERATORS = ['begins with', 'contains', 'does not contain']


def initAlgorithm(self, config=None):
"""Initializes algorithm parameters."""
self.addParameter(
QgsProcessingParameterVectorLayer(
self.INPUT,
self.tr('Input layer'),
[QgsProcessing.TypeVector]
)
)

self.addParameter(
QgsProcessingParameterField(
self.FIELD,
self.tr('Selection attribute'),
parentLayerParameterName=self.INPUT
)
)

self.addParameter(
QgsProcessingParameterEnum(
self.OPERATOR,
self.tr('Operator'),
options=self.OPERATORS,
defaultValue=0
)
)

self.addParameter(
QgsProcessingParameterString(
self.VALUE,
self.tr('Value'),
optional=True
)
)

self.addParameter(
QgsProcessingParameterFeatureSink(
self.OUTPUT,
self.tr('Output layer')
)
)

def processAlgorithm(self, parameters, context, feedback):
"""Processes the algorithm."""
layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
fieldName = self.parameterAsString(parameters, self.FIELD, context)
operator = self.OPERATORS[self.parameterAsEnum(parameters, self.OPERATOR, context)]
value = self.parameterAsString(parameters, self.VALUE, context)

fields = layer.fields() if layer else QgsFields()
(sink, dest_id) = self.parameterAsSink(
parameters,
self.OUTPUT,
context,
fields,
layer.wkbType() if layer else QgsWkbTypes.NoGeometry,
layer.sourceCrs() if layer else None
)

if sink is None:
raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))


if layer is None:
raise QgsProcessingException("Camada inválida ou não encontrada.")


if fieldName not in layer.fields().names():
feedback.pushInfo(f"O atributo '{fieldName}' não foi encontrado na camada. Nenhuma exportação realizada.")
return {self.OUTPUT: dest_id}


field_ref = QgsExpression.quotedColumnRef(fieldName)
if operator == 'is null':
expression_string = f"{field_ref} IS NULL"
elif operator == 'is not null':
expression_string = f"{field_ref} IS NOT NULL"
elif operator == 'begins with':
expression_string = f"{field_ref} LIKE '{value}%'"
elif operator == 'contains':
expression_string = f"{field_ref} LIKE '%{value}%'"
elif operator == 'does not contain':
expression_string = f"{field_ref} NOT LIKE '%{value}%'"
else:
quoted_val = QgsExpression.quotedValue(value)
expression_string = f"{field_ref} {operator} {quoted_val}"

expression = QgsExpression(expression_string)
if expression.hasParserError():
raise QgsProcessingException(f"Erro na expressão: {expression.parserErrorString()}")


features = layer.getFeatures(QgsFeatureRequest(expression))
matched_features = [f for f in features]


nFeatures = len(matched_features)
if nFeatures == 0:
feedback.pushInfo("Nenhum recurso encontrado com o valor especificado.")
return {self.OUTPUT: dest_id}

stepSize = 100 / nFeatures


for current, feature in enumerate(matched_features):
if feedback.isCanceled():
break
sink.addFeature(feature, QgsFeatureSink.FastInsert)
phborba marked this conversation as resolved.
Show resolved Hide resolved
feedback.setProgress(int((current / nFeatures) * 100))

feedback.pushInfo("Exportação concluída com sucesso.")
return {self.OUTPUT: dest_id}

def name(self):
return 'exportfeaturesbyattribute'

def displayName(self):
return self.tr('Export Features by Attribute')

def group(self):
return self.tr("Utils")

def groupId(self):
return "DSGTools - Utils"

def tr(self, string):
return QCoreApplication.translate("ExportFeaturesByAttribute", string)

def shortHelpString(self):
return help().shortHelpString(self.name())

def createInstance(self):
return ExportFeaturesByAttributeAlgorithm()

Empty file.
Loading
Loading