27 const std::function<
QgsGeometry(
const QVector< QgsGeometry >& )> &collector,
int maxQueueLength, QgsProcessingFeatureSource::Flags sourceFlags )
29 std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
34 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, dest, source->fields(),
QgsWkbTypes::multiType( source->wkbType() ), source->sourceCrs() ) );
39 QStringList fields = parameterAsFields( parameters, QStringLiteral(
"FIELD" ), context );
41 long count = source->featureCount();
46 double step = count > 0 ? 100.0 / count : 1;
49 if ( fields.isEmpty() )
52 bool firstFeature =
true;
54 QVector< QgsGeometry > geomQueue;
73 if ( maxQueueLength > 0 && geomQueue.length() > maxQueueLength )
76 QgsGeometry tempOutputGeometry = collector( geomQueue );
78 geomQueue << tempOutputGeometry;
86 outputFeature.
setGeometry( collector( geomQueue ) );
91 QList< int > fieldIndexes;
92 const auto constFields = fields;
93 for (
const QString &
field : constFields )
95 int index = source->fields().lookupField(
field );
97 fieldIndexes << index;
100 QHash< QVariant, QgsAttributes > attributeHash;
101 QHash< QVariant, QVector< QgsGeometry > > geometryHash;
110 QVariantList indexAttributes;
111 const auto constFieldIndexes = fieldIndexes;
112 for (
int index : constFieldIndexes )
117 if ( !attributeHash.contains( indexAttributes ) )
120 attributeHash.insert( indexAttributes, f.
attributes() );
125 geometryHash[ indexAttributes ].append( f.
geometry() );
129 int numberFeatures = attributeHash.count();
130 QHash< QVariant, QgsAttributes >::const_iterator attrIt = attributeHash.constBegin();
131 for ( ; attrIt != attributeHash.constEnd(); ++attrIt )
139 if ( geometryHash.contains( attrIt.key() ) )
141 QgsGeometry geom = collector( geometryHash.value( attrIt.key() ) );
151 feedback->
setProgress( current * 100.0 / numberFeatures );
157 outputs.insert( QStringLiteral(
"OUTPUT" ), dest );
166 QString QgsDissolveAlgorithm::name()
const
168 return QStringLiteral(
"dissolve" );
171 QString QgsDissolveAlgorithm::displayName()
const
173 return QObject::tr(
"Dissolve" );
176 QStringList QgsDissolveAlgorithm::tags()
const
178 return QObject::tr(
"dissolve,union,combine,collect" ).split(
',' );
181 QString QgsDissolveAlgorithm::group()
const
183 return QObject::tr(
"Vector geometry" );
186 QString QgsDissolveAlgorithm::groupId()
const
188 return QStringLiteral(
"vectorgeometry" );
192 void QgsDissolveAlgorithm::initAlgorithm(
const QVariantMap & )
201 QString QgsDissolveAlgorithm::shortHelpString()
const
203 return QObject::tr(
"This algorithm takes a vector layer and combines their features into new features. One or more attributes can "
204 "be specified to dissolve features belonging to the same class (having the same value for the specified attributes), alternatively "
205 "all features can be dissolved in a single one.\n\n"
206 "All output geometries will be converted to multi geometries. "
207 "In case the input is a polygon layer, common boundaries of adjacent polygons being dissolved will get erased." );
210 QgsDissolveAlgorithm *QgsDissolveAlgorithm::createInstance()
const
212 return new QgsDissolveAlgorithm();
217 return processCollection( parameters, context, feedback, [ & ](
const QVector< QgsGeometry > &parts )->
QgsGeometry
221 result = result.mergeLines();
224 if ( ! result.lastError().isEmpty() && parts.count() > 2 )
229 feedback->
pushDebugInfo( QObject::tr(
"GEOS exception: taking the slower route ..." ) );
231 for (
const auto &p : parts )
235 result = result.mergeLines();
240 if ( ! result.lastError().isEmpty() )
243 if ( result.isEmpty() )
254 QString QgsCollectAlgorithm::name()
const
256 return QStringLiteral(
"collect" );
259 QString QgsCollectAlgorithm::displayName()
const
261 return QObject::tr(
"Collect geometries" );
264 QStringList QgsCollectAlgorithm::tags()
const
266 return QObject::tr(
"union,combine,collect,multipart,parts,single" ).split(
',' );
269 QString QgsCollectAlgorithm::group()
const
271 return QObject::tr(
"Vector geometry" );
274 QString QgsCollectAlgorithm::groupId()
const
276 return QStringLiteral(
"vectorgeometry" );
281 return processCollection( parameters, context, feedback, [](
const QVector< QgsGeometry > &parts )->
QgsGeometry
288 void QgsCollectAlgorithm::initAlgorithm(
const QVariantMap & )
297 QString QgsCollectAlgorithm::shortHelpString()
const
299 return QObject::tr(
"This algorithm takes a vector layer and collects its geometries into new multipart geometries. One or more attributes can "
300 "be specified to collect only geometries belonging to the same class (having the same value for the specified attributes), alternatively "
301 "all geometries can be collected." ) +
302 QStringLiteral(
"\n\n" ) +
303 QObject::tr(
"All output geometries will be converted to multi geometries, even those with just a single part. "
304 "This algorithm does not dissolve overlapping geometries - they will be collected together without modifying the shape of each geometry part." ) +
305 QStringLiteral(
"\n\n" ) +
306 QObject::tr(
"See the 'Promote to multipart' or 'Aggregate' algorithms for alternative options." );
309 QgsCollectAlgorithm *QgsCollectAlgorithm::createInstance()
const
311 return new QgsCollectAlgorithm();