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() ) );
 
  187     feedback->
setProgress( 0.10 * current * step + 90 ); 
 
  190   feedback->
pushInfo( QObject::tr( 
"%1 duplicate features removed" ).arg( removed ) );
 
  193   outputs.insert( QStringLiteral( 
"OUTPUT" ), destId );
 
  194   outputs.insert( QStringLiteral( 
"DUPLICATE_COUNT" ), 
static_cast< long long >( removed ) );
 
  195   outputs.insert( QStringLiteral( 
"RETAINED_COUNT" ), outputFeatureIds.size() );
 
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).
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets feature IDs that should be fetched.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ 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 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.
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