24 QString QgsDeleteDuplicateGeometriesAlgorithm::name()
const
26 return QStringLiteral(
"deleteduplicategeometries" );
29 QString QgsDeleteDuplicateGeometriesAlgorithm::displayName()
const
31 return QObject::tr(
"Delete duplicate geometries" );
34 QStringList QgsDeleteDuplicateGeometriesAlgorithm::tags()
const
36 return QObject::tr(
"drop,remove,same,points,coincident,overlapping,filter" ).split(
',' );
39 QString QgsDeleteDuplicateGeometriesAlgorithm::group()
const
41 return QObject::tr(
"Vector general" );
44 QString QgsDeleteDuplicateGeometriesAlgorithm::groupId()
const
46 return QStringLiteral(
"vectorgeneral" );
49 void QgsDeleteDuplicateGeometriesAlgorithm::initAlgorithm(
const QVariantMap & )
53 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"RETAINED_COUNT" ), QObject::tr(
"Count of retained records" ) ) );
54 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"DUPLICATE_COUNT" ), QObject::tr(
"Count of discarded duplicate records" ) ) );
57 QString QgsDeleteDuplicateGeometriesAlgorithm::shortHelpString()
const
59 return QObject::tr(
"This algorithm finds duplicated geometries and removes them.\n\nAttributes are not checked, "
60 "so in case two features have identical geometries but different attributes, only one of "
61 "them will be added to the result layer." );
64 QString QgsDeleteDuplicateGeometriesAlgorithm::shortDescription()
const
66 return QObject::tr(
"Finds duplicated geometries in a layer and removes them." );
69 QgsDeleteDuplicateGeometriesAlgorithm *QgsDeleteDuplicateGeometriesAlgorithm::createInstance()
const
71 return new QgsDeleteDuplicateGeometriesAlgorithm();
76 mSource.reset( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
86 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, destId, mSource->fields(),
87 mSource->wkbType(), mSource->sourceCrs() ) );
93 double step = mSource->featureCount() > 0 ? 100.0 / mSource->featureCount() : 0;
94 QHash< QgsFeatureId, QgsGeometry > geometries;
95 QSet< QgsFeatureId > nullGeometryFeatures;
104 nullGeometryFeatures.insert( f.id() );
108 geometries.insert( f.id(), f.geometry() );
120 QHash< QgsFeatureId, QgsGeometry > uniqueFeatures = geometries;
124 for (
auto it = geometries.constBegin(); it != geometries.constEnd(); ++it )
132 if ( !uniqueFeatures.contains( featureId ) )
138 const QList<QgsFeatureId> candidates = index.intersects( geometry.
boundingBox() );
142 if ( candidateId == featureId )
145 if ( !uniqueFeatures.contains( candidateId ) )
152 else if ( geometry.
isGeosEqual( geometries.value( candidateId ) ) )
155 uniqueFeatures.remove( candidateId );
162 feedback->
setProgress( 0.80 * current * step + 10 );
167 QSet< QgsFeatureId > outputFeatureIds = qgis::listToSet( uniqueFeatures.keys() );
168 outputFeatureIds.unite( nullGeometryFeatures );
169 step = outputFeatureIds.empty() ? 1 : 100.0 / outputFeatureIds.size();
172 it = mSource->getFeatures( request );
180 if ( !nullGeometryFeatures.contains( f.id() ) )
182 f.setGeometry( uniqueFeatures.value( f.id() ) );
188 feedback->
setProgress( 0.10 * current * step + 90 );
191 feedback->
pushInfo( QObject::tr(
"%n duplicate feature(s) removed",
nullptr, removed ) );
194 outputs.insert( QStringLiteral(
"OUTPUT" ), destId );
195 outputs.insert( QStringLiteral(
"DUPLICATE_COUNT" ),
static_cast< long long >( removed ) );
196 outputs.insert( QStringLiteral(
"RETAINED_COUNT" ), outputFeatureIds.size() );