22 QString QgsExtractByAttributeAlgorithm::name()
const
24 return QStringLiteral(
"extractbyattribute" );
27 QString QgsExtractByAttributeAlgorithm::displayName()
const
29 return QObject::tr(
"Extract by attribute" );
32 QStringList QgsExtractByAttributeAlgorithm::tags()
const
34 return QObject::tr(
"extract,filter,attribute,value,contains,null,field" ).split(
',' );
37 QString QgsExtractByAttributeAlgorithm::group()
const
39 return QObject::tr(
"Vector selection" );
42 QString QgsExtractByAttributeAlgorithm::groupId()
const
44 return QStringLiteral(
"vectorselection" );
47 void QgsExtractByAttributeAlgorithm::initAlgorithm(
const QVariantMap & )
51 addParameter(
new QgsProcessingParameterField( QStringLiteral(
"FIELD" ), QObject::tr(
"Selection attribute" ), QVariant(), QStringLiteral(
"INPUT" ) ) );
59 << QObject::tr(
"begins with" )
60 << QObject::tr(
"contains" )
61 << QObject::tr(
"is null" )
62 << QObject::tr(
"is not null" )
63 << QObject::tr(
"does not contain" ),
false, 0 ) );
70 addParameter( failOutput );
73 QString QgsExtractByAttributeAlgorithm::shortHelpString()
const
75 return QObject::tr(
"This algorithm creates a new vector layer that only contains matching features from an input layer. "
76 "The criteria for adding features to the resulting layer is defined based on the values "
77 "of an attribute from the input layer." );
80 QgsExtractByAttributeAlgorithm *QgsExtractByAttributeAlgorithm::createInstance()
const
82 return new QgsExtractByAttributeAlgorithm();
87 std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
91 const QString fieldName = parameterAsString( parameters, QStringLiteral(
"FIELD" ), context );
92 const Operation op =
static_cast< Operation
>( parameterAsEnum( parameters, QStringLiteral(
"OPERATOR" ), context ) );
93 const QString value = parameterAsString( parameters, QStringLiteral(
"VALUE" ), context );
95 QString matchingSinkId;
96 std::unique_ptr< QgsFeatureSink > matchingSink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, matchingSinkId, source->fields(),
97 source->wkbType(), source->sourceCrs() ) );
101 QString nonMatchingSinkId;
102 std::unique_ptr< QgsFeatureSink > nonMatchingSink( parameterAsSink( parameters, QStringLiteral(
"FAIL_OUTPUT" ), context, nonMatchingSinkId, source->fields(),
103 source->wkbType(), source->sourceCrs() ) );
105 const int idx = source->fields().lookupField( fieldName );
107 throw QgsProcessingException( QObject::tr(
"Field '%1' was not found in INPUT source" ).arg( fieldName ) );
109 const QVariant::Type fieldType = source->fields().at( idx ).type();
111 if ( fieldType != QVariant::String && ( op == BeginsWith || op == Contains || op == DoesNotContain ) )
117 method = QObject::tr(
"begins with" );
120 method = QObject::tr(
"contains" );
123 method = QObject::tr(
"does not contain" );
130 throw QgsProcessingException( QObject::tr(
"Operator '%1' can be used only with string fields." ).arg( method ) );
139 expr = QStringLiteral(
"%1 = %3" ).arg( fieldRef, quotedVal );
142 expr = QStringLiteral(
"%1 != %3" ).arg( fieldRef, quotedVal );
145 expr = QStringLiteral(
"%1 > %3" ).arg( fieldRef, quotedVal );
147 case GreaterThanEqualTo:
148 expr = QStringLiteral(
"%1 >= %3" ).arg( fieldRef, quotedVal );
151 expr = QStringLiteral(
"%1 < %3" ).arg( fieldRef, quotedVal );
153 case LessThanEqualTo:
154 expr = QStringLiteral(
"%1 <= %3" ).arg( fieldRef, quotedVal );
157 expr = QStringLiteral(
"%1 LIKE '%2%'" ).arg( fieldRef, value );
160 expr = QStringLiteral(
"%1 LIKE '%%2%'" ).arg( fieldRef, value );
163 expr = QStringLiteral(
"%1 IS NULL" ).arg( fieldRef );
166 expr = QStringLiteral(
"%1 IS NOT NULL" ).arg( fieldRef );
169 expr = QStringLiteral(
"%1 NOT LIKE '%%2%'" ).arg( fieldRef, value );
174 if ( expression.hasParserError() )
179 QgsExpressionContext expressionContext = createExpressionContext( parameters, context, source.get() );
181 const long count = source->featureCount();
183 const double step = count > 0 ? 100.0 / count : 1;
186 if ( !nonMatchingSink )
203 throw QgsProcessingException( writeFeatureError( matchingSink.get(), parameters, QStringLiteral(
"OUTPUT" ) ) );
212 expressionContext.
setFields( source->fields() );
213 expression.prepare( &expressionContext );
225 if ( expression.evaluate( &expressionContext ).toBool() )
228 throw QgsProcessingException( writeFeatureError( matchingSink.get(), parameters, QStringLiteral(
"OUTPUT" ) ) );
233 throw QgsProcessingException( writeFeatureError( nonMatchingSink.get(), parameters, QStringLiteral(
"FAIL_OUTPUT" ) ) );
243 outputs.insert( QStringLiteral(
"OUTPUT" ), matchingSinkId );
244 if ( nonMatchingSink )
245 outputs.insert( QStringLiteral(
"FAIL_OUTPUT" ), nonMatchingSinkId );