22 QString QgsJoinByAttributeAlgorithm::name()
const 24 return QStringLiteral(
"joinattributestable" );
27 QString QgsJoinByAttributeAlgorithm::displayName()
const 29 return QObject::tr(
"Join attributes by field value" );
32 QStringList QgsJoinByAttributeAlgorithm::tags()
const 34 return QObject::tr(
"join,connect,attributes,values,fields,tables" ).split(
',' );
37 QString QgsJoinByAttributeAlgorithm::group()
const 39 return QObject::tr(
"Vector general" );
42 QString QgsJoinByAttributeAlgorithm::groupId()
const 44 return QStringLiteral(
"vectorgeneral" );
47 void QgsJoinByAttributeAlgorithm::initAlgorithm(
const QVariantMap & )
50 methods << QObject::tr(
"Create separate feature for each matching feature (one-to-many)" )
51 << QObject::tr(
"Take attributes of the first matching feature only (one-to-one)" );
56 QObject::tr(
"Table field" ), QVariant(), QStringLiteral(
"INPUT" ) ) );
61 QObject::tr(
"Table field 2" ), QVariant(), QStringLiteral(
"INPUT_2" ) ) );
64 QObject::tr(
"Layer 2 fields to copy (leave empty to copy all fields)" ),
69 QObject::tr(
"Join type" ),
70 methods,
false, 1 ) );
72 QObject::tr(
"Discard records which could not be joined" ),
76 QObject::tr(
"Joined field prefix" ), QVariant(),
false,
true ) );
81 QString QgsJoinByAttributeAlgorithm::shortHelpString()
const 83 return QObject::tr(
"This algorithm takes an input vector layer and creates a new vector layer that is an extended version of the " 84 "input one, with additional attributes in its attribute table.\n\n" 85 "The additional attributes and their values are taken from a second vector layer. An attribute is selected " 86 "in each of them to define the join criteria." );
89 QgsJoinByAttributeAlgorithm *QgsJoinByAttributeAlgorithm::createInstance()
const 91 return new QgsJoinByAttributeAlgorithm();
96 int joinMethod = parameterAsEnum( parameters, QStringLiteral(
"METHOD" ), context );
97 bool discardNonMatching = parameterAsBool( parameters, QStringLiteral(
"DISCARD_NONMATCHING" ), context );
99 std::unique_ptr< QgsProcessingFeatureSource > input( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
103 std::unique_ptr< QgsProcessingFeatureSource > input2( parameterAsSource( parameters, QStringLiteral(
"INPUT_2" ), context ) );
107 QString prefix = parameterAsString( parameters, QStringLiteral(
"PREFIX" ), context );
109 QString field1Name = parameterAsString( parameters, QStringLiteral(
"FIELD" ), context );
110 QString field2Name = parameterAsString( parameters, QStringLiteral(
"FIELD_2" ), context );
111 const QStringList fieldsToCopy = parameterAsFields( parameters, QStringLiteral(
"FIELDS_TO_COPY" ), context );
113 int joinField1Index = input->fields().lookupField( field1Name );
114 int joinField2Index = input2->fields().lookupField( field2Name );
115 if ( joinField1Index < 0 || joinField2Index < 0 )
120 if ( fieldsToCopy.empty() )
122 outFields2 = input2->fields();
123 for (
int i = 0; i < outFields2.
count(); ++i )
130 for (
const QString &field : fieldsToCopy )
135 fields2Indices << index;
136 outFields2.
append( input2->fields().at( index ) );
141 if ( !prefix.isEmpty() )
143 for (
int i = 0; i < outFields2.
count(); ++i )
145 outFields2[ i ].setName( prefix + outFields2[ i ].name() );
150 fields2Fetch << joinField2Index;
155 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, dest, outFields,
156 input->wkbType(), input->sourceCrs() ) );
162 QMultiHash< QVariant, QgsAttributes > input2AttributeCache;
164 double step = input2->featureCount() > 0 ? 50.0 / input2->featureCount() : 1;
177 if ( joinMethod == 1 && input2AttributeCache.contains( feat.
attribute( joinField2Index ) ) )
182 for (
int j = 0; j < feat.
attributes().count(); ++j )
184 if ( ! fields2Indices.contains( j ) )
189 input2AttributeCache.insert( feat.
attribute( joinField2Index ), attributes );
193 step = input->featureCount() > 0 ? 50.0 / input->featureCount() : 1;
206 if ( input2AttributeCache.count( feat.
attribute( joinField1Index ) ) > 0 )
210 QList< QgsAttributes > attributes = input2AttributeCache.values( feat.
attribute( joinField1Index ) );
211 QList< QgsAttributes >::iterator attrsIt = attributes.begin();
212 for ( ; attrsIt != attributes.end(); ++attrsIt )
215 newAttrs.append( *attrsIt );
220 else if ( !discardNonMatching )
227 outputs.insert( QStringLiteral(
"OUTPUT" ), dest );
int lookupField(const QString &fieldName) const
Look up field's index from the field name.
A boolean parameter for processing algorithms.
Wrapper for iterator of features from vector data provider or vector layer.
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
Base class for providing feedback from a processing algorithm.
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
A vector layer or feature source field parameter for processing algorithms.
void setProgress(double progress)
Sets the current progress for the feedback object.
Container of fields for a vector layer.
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
int count() const
Returns number of items.
A feature sink output for processing algorithms.
An enum based parameter for processing algorithms, allowing for selection from predefined values...
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB)
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).
This class wraps a request for features to a vector layer (or directly its vector data provider)...
Custom exception class for processing related exceptions.
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Append a field. The field must have unique name, otherwise it is rejected (returns false) ...
bool isCanceled() const
Tells whether the operation has been canceled already.
An input feature source (such as vector layers) parameter for processing algorithms.
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
QList< int > QgsAttributeList
bool nextFeature(QgsFeature &f)
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Contains information about the context in which a processing algorithm is executed.
A string parameter for processing algorithms.