25QString QgsDeleteDuplicateGeometriesAlgorithm::name()
const
27 return QStringLiteral(
"deleteduplicategeometries" );
30QString QgsDeleteDuplicateGeometriesAlgorithm::displayName()
const
32 return QObject::tr(
"Delete duplicate geometries" );
35QStringList QgsDeleteDuplicateGeometriesAlgorithm::tags()
const
37 return QObject::tr(
"drop,remove,same,points,coincident,overlapping,filter" ).split(
',' );
40QString QgsDeleteDuplicateGeometriesAlgorithm::group()
const
42 return QObject::tr(
"Vector general" );
45QString QgsDeleteDuplicateGeometriesAlgorithm::groupId()
const
47 return QStringLiteral(
"vectorgeneral" );
50void QgsDeleteDuplicateGeometriesAlgorithm::initAlgorithm(
const QVariantMap & )
54 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"RETAINED_COUNT" ), QObject::tr(
"Count of retained records" ) ) );
55 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"DUPLICATE_COUNT" ), QObject::tr(
"Count of discarded duplicate records" ) ) );
58QString QgsDeleteDuplicateGeometriesAlgorithm::shortHelpString()
const
60 return QObject::tr(
"This algorithm finds duplicated geometries and removes them.\n\nAttributes are not checked, "
61 "so in case two features have identical geometries but different attributes, only one of "
62 "them will be added to the result layer." );
65QString QgsDeleteDuplicateGeometriesAlgorithm::shortDescription()
const
67 return QObject::tr(
"Finds duplicated geometries in a layer and removes them." );
70QgsDeleteDuplicateGeometriesAlgorithm *QgsDeleteDuplicateGeometriesAlgorithm::createInstance()
const
72 return new QgsDeleteDuplicateGeometriesAlgorithm();
77 mSource.reset( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
87 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, destId, mSource->fields(),
88 mSource->wkbType(), mSource->sourceCrs() ) );
94 double step = mSource->featureCount() > 0 ? 100.0 / mSource->featureCount() : 0;
95 QHash< QgsFeatureId, QgsGeometry > geometries;
96 QSet< QgsFeatureId > nullGeometryFeatures;
105 nullGeometryFeatures.insert( f.
id() );
121 QHash< QgsFeatureId, QgsGeometry > uniqueFeatures = geometries;
125 for (
auto it = geometries.constBegin(); it != geometries.constEnd(); ++it )
133 if ( !uniqueFeatures.contains( featureId ) )
139 const QList<QgsFeatureId> candidates = index.intersects( geometry.
boundingBox() );
143 if ( candidateId == featureId )
146 if ( !uniqueFeatures.contains( candidateId ) )
153 else if ( geometry.
isGeosEqual( geometries.value( candidateId ) ) )
156 uniqueFeatures.remove( candidateId );
163 feedback->
setProgress( 0.80 * current * step + 10 );
168 QSet< QgsFeatureId > outputFeatureIds = qgis::listToSet( uniqueFeatures.keys() );
169 outputFeatureIds.unite( nullGeometryFeatures );
170 step = outputFeatureIds.empty() ? 1 : 100.0 / outputFeatureIds.size();
173 it = mSource->getFeatures( request );
181 if ( !nullGeometryFeatures.contains( f.id() ) )
183 f.setGeometry( uniqueFeatures.value( f.id() ) );
189 feedback->
setProgress( 0.10 * current * step + 90 );
192 feedback->
pushInfo( QObject::tr(
"%n duplicate feature(s) removed",
nullptr, removed ) );
195 outputs.insert( QStringLiteral(
"OUTPUT" ), destId );
196 outputs.insert( QStringLiteral(
"DUPLICATE_COUNT" ),
static_cast< long long >( removed ) );
197 outputs.insert( QStringLiteral(
"RETAINED_COUNT" ), outputFeatureIds.size() );
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
@ 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...
bool hasGeometry() const
Returns true if the feature has an associated geometry.
bool isCanceled() const
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.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
bool isGeosEqual(const QgsGeometry &) const
Compares the geometry with another geometry using GEOS.
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
A numeric output for processing algorithms.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A spatial index for QgsFeature objects.
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QList< int > QgsAttributeList