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 const QStringList fields = parameterAsFields( parameters, QStringLiteral(
"FIELD" ), context );
41 const long count = source->featureCount();
46 const 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 const QgsGeometry tempOutputGeometry = collector( geomQueue );
78 geomQueue << tempOutputGeometry;
86 outputFeature.
setGeometry( collector( geomQueue ) );
92 QList< int > fieldIndexes;
93 const auto constFields = fields;
94 for (
const QString &
field : constFields )
96 const int index = source->fields().lookupField(
field );
98 fieldIndexes << index;
101 QHash< QVariant, QgsAttributes > attributeHash;
102 QHash< QVariant, QVector< QgsGeometry > > geometryHash;
111 QVariantList indexAttributes;
112 const auto constFieldIndexes = fieldIndexes;
113 for (
const int index : constFieldIndexes )
118 if ( !attributeHash.contains( indexAttributes ) )
121 attributeHash.insert( indexAttributes, f.
attributes() );
126 geometryHash[ indexAttributes ].append( f.
geometry() );
130 const int numberFeatures = attributeHash.count();
131 QHash< QVariant, QgsAttributes >::const_iterator attrIt = attributeHash.constBegin();
132 for ( ; attrIt != attributeHash.constEnd(); ++attrIt )
140 if ( geometryHash.contains( attrIt.key() ) )
142 QgsGeometry geom = collector( geometryHash.value( attrIt.key() ) );
153 feedback->
setProgress( current * 100.0 / numberFeatures );
159 outputs.insert( QStringLiteral(
"OUTPUT" ), dest );
168 QString QgsDissolveAlgorithm::name()
const
170 return QStringLiteral(
"dissolve" );
173 QString QgsDissolveAlgorithm::displayName()
const
175 return QObject::tr(
"Dissolve" );
178 QStringList QgsDissolveAlgorithm::tags()
const
180 return QObject::tr(
"dissolve,union,combine,collect" ).split(
',' );
183 QString QgsDissolveAlgorithm::group()
const
185 return QObject::tr(
"Vector geometry" );
188 QString QgsDissolveAlgorithm::groupId()
const
190 return QStringLiteral(
"vectorgeometry" );
194 void QgsDissolveAlgorithm::initAlgorithm(
const QVariantMap & )
203 QString QgsDissolveAlgorithm::shortHelpString()
const
205 return QObject::tr(
"This algorithm takes a vector layer and combines their features into new features. One or more attributes can "
206 "be specified to dissolve features belonging to the same class (having the same value for the specified attributes), alternatively "
207 "all features can be dissolved in a single one.\n\n"
208 "All output geometries will be converted to multi geometries. "
209 "In case the input is a polygon layer, common boundaries of adjacent polygons being dissolved will get erased." );
212 QgsDissolveAlgorithm *QgsDissolveAlgorithm::createInstance()
const
214 return new QgsDissolveAlgorithm();
219 return processCollection( parameters, context, feedback, [ & ](
const QVector< QgsGeometry > &parts )->
QgsGeometry
223 result = result.mergeLines();
226 if ( ! result.lastError().isEmpty() && parts.count() > 2 )
231 feedback->
pushDebugInfo( QObject::tr(
"GEOS exception: taking the slower route ..." ) );
233 for (
const auto &p : parts )
237 result = result.mergeLines();
242 if ( ! result.lastError().isEmpty() )
245 if ( result.isEmpty() )
256 QString QgsCollectAlgorithm::name()
const
258 return QStringLiteral(
"collect" );
261 QString QgsCollectAlgorithm::displayName()
const
263 return QObject::tr(
"Collect geometries" );
266 QStringList QgsCollectAlgorithm::tags()
const
268 return QObject::tr(
"union,combine,collect,multipart,parts,single" ).split(
',' );
271 QString QgsCollectAlgorithm::group()
const
273 return QObject::tr(
"Vector geometry" );
276 QString QgsCollectAlgorithm::groupId()
const
278 return QStringLiteral(
"vectorgeometry" );
283 return processCollection( parameters, context, feedback, [](
const QVector< QgsGeometry > &parts )->
QgsGeometry
290 void QgsCollectAlgorithm::initAlgorithm(
const QVariantMap & )
299 QString QgsCollectAlgorithm::shortHelpString()
const
301 return QObject::tr(
"This algorithm takes a vector layer and collects its geometries into new multipart geometries. One or more attributes can "
302 "be specified to collect only geometries belonging to the same class (having the same value for the specified attributes), alternatively "
303 "all geometries can be collected." ) +
304 QStringLiteral(
"\n\n" ) +
305 QObject::tr(
"All output geometries will be converted to multi geometries, even those with just a single part. "
306 "This algorithm does not dissolve overlapping geometries - they will be collected together without modifying the shape of each geometry part." ) +
307 QStringLiteral(
"\n\n" ) +
308 QObject::tr(
"See the 'Promote to multipart' or 'Aggregate' algorithms for alternative options." );
311 QgsCollectAlgorithm *QgsCollectAlgorithm::createInstance()
const
313 return new QgsCollectAlgorithm();
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
A geometry is the spatial representation of a feature.
static QgsGeometry collectGeometry(const QVector< QgsGeometry > &geometries)
Creates a new multipart geometry from a list of QgsGeometry objects.
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries)
Compute the unary union on a list of geometries.
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
@ FlagSkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Base class for providing feedback from a processing algorithm.
virtual void pushDebugInfo(const QString &info)
Pushes an informational message containing debugging helpers from the algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A vector layer or feature source field parameter for processing algorithms.
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
static Type multiType(Type type) SIP_HOLDGIL
Returns the multi type for a WKB type.