17 #include <QtConcurrentMap>    18 #include <QFutureWatcher>    35   , mFeaturePools( featurePools )
    37   for ( 
auto it = featurePools.constBegin(); it != mFeaturePools.constEnd(); ++it )
    39     if ( it.value()->layer() )
    41       it.value()->layer()->setReadOnly( 
true );
    43       it.value()->layer()->dataProvider()->enterUpdateMode();
    50   qDeleteAll( mCheckErrors );
    51   qDeleteAll( mChecks );
    52   for ( 
auto it = mFeaturePools.constBegin(); it != mFeaturePools.constEnd(); ++it )
    54     if ( it.value()->layer() )
    56       it.value()->layer()->dataProvider()->leaveUpdateMode();
    57       it.value()->layer()->setReadOnly( 
false );
    71       for ( 
auto it = mFeaturePools.constBegin(); it != mFeaturePools.constEnd(); ++it )
    75           *totalSteps += check->isCompatible( it.value()->layer() ) ? it.value()->allFeatureIds().size() : 0;
    85   QFuture<void> future = QtConcurrent::map( mChecks, RunCheckWrapper( 
this ) );
    87   QFutureWatcher<void> *watcher = 
new QFutureWatcher<void>();
    88   watcher->setFuture( future );
    89   QTimer *timer = 
new QTimer();
    90   connect( timer, &QTimer::timeout, 
this, &QgsGeometryChecker::emitProgressValue );
    91   connect( watcher, &QFutureWatcherBase::finished, timer, &QObject::deleteLater );
    92   connect( watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater );
    98 void QgsGeometryChecker::emitProgressValue()
   117   error->
check()->
fixError( mFeaturePools, error, method, mMergeAttributeIndices, changes );
   120   static QVector<QString> strChangeWhat = { 
"ChangeFeature", 
"ChangePart", 
"ChangeRing", 
"ChangeNode" };
   121   static QVector<QString> strChangeType = { 
"ChangeAdded", 
"ChangeRemoved", 
"ChangeChanged" };
   122   for ( 
const QString &layerId : changes.keys() )
   124     for ( 
const QgsFeatureId &fid : changes[layerId].keys() )
   128         QTextStream( stdout ) << 
" * Change: " << layerId << 
":" << fid << 
" :: " << strChangeWhat[change.what] << 
":" << strChangeType[change.type] << 
":(" << change.vidx.part << 
"," << change.vidx.ring << 
"," << change.vidx.vertex << 
")" << endl;
   140   if ( changes.isEmpty() )
   147   QMap<QString, QSet<QgsFeatureId>> recheckFeatures;
   148   for ( 
auto it = changes.constBegin(); it != changes.constEnd(); ++it )
   150     const QMap<QgsFeatureId, QList<QgsGeometryCheck::Change>> &layerChanges = it.value();
   153     for ( 
auto layerChangeIt = layerChanges.constBegin(); layerChangeIt != layerChanges.constEnd(); ++layerChangeIt )
   155       bool removed = 
false;
   167         if ( featurePool->
getFeature( layerChangeIt.key(), f ) )
   169           recheckFeatures[it.key()].insert( layerChangeIt.key() );
   180       if ( err->affectedAreaBBox().intersects( recheckArea ) )
   187   QMap<QString, QgsFeatureIds> recheckAreaFeatures;
   188   for ( 
const QString &layerId : mFeaturePools.keys() )
   192     recheckAreaFeatures[layerId] = featurePool->
getIntersects( t.transform( recheckArea ) );
   196   QList<QgsGeometryCheckError *> recheckErrors;
   201       if ( !recheckAreaFeatures.isEmpty() )
   203         check->collectErrors( mFeaturePools, recheckErrors, mMessages, 
nullptr, recheckAreaFeatures );
   208       if ( !recheckFeatures.isEmpty() )
   210         check->collectErrors( mFeaturePools, recheckErrors, mMessages, 
nullptr, recheckFeatures );
   225     bool handled = err->handleChanges( changes );
   232       if ( recheckErr->isEqual( err ) || recheckErr->closeMatch( err ) )
   235         matchErr = recheckErr;
   239     if ( nMatch == 1 && matchErr )
   243       recheckErrors.removeAll( matchErr );
   269     mCheckErrors.append( recheckErr );
   272   if ( triggerRepaint )
   274     for ( 
const QString &layerId : changes.keys() )
   276       mFeaturePools[layerId]->layer()->triggerRepaint();
   286   QList<QgsGeometryCheckError *> errors;
   287   QStringList messages;
   289   mErrorListMutex.lock();
   290   mCheckErrors.append( errors );
   291   mMessages.append( messages );
   292   mErrorListMutex.unlock();
   300   : mInstance( instance )
   304 void QgsGeometryChecker::RunCheckWrapper::operator()( 
const QgsGeometryCheck *check )
   306   mInstance->runCheck( mInstance->mFeaturePools, check );
 bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle. 
The error is obsolete because of other modifications. 
A rectangle specified with double values. 
QgsFeatureIds getIntersects(const QgsRectangle &rect) const
Gets all feature ids in the bounding box rect. 
virtual void update(const QgsGeometryCheckError *other)
Update this error with the information from other. 
double progress() const
Returns the current progress reported by the feedback object. 
const QgsCoordinateReferenceSystem mapCrs
The coordinate system in which calculations should be done. 
Status
The status of an error. 
const QgsPointXY & location() const
The location of the error in map units. 
QgsGeometryChecker(const QList< QgsGeometryCheck *> &checks, QgsGeometryCheckContext *context, const QMap< QString, QgsFeaturePool *> &featurePools)
const QMap< QString, QgsFeaturePool * > featurePools() const
void setObsolete()
Set the error status to obsolete. 
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Base configuration for geometry checks. 
QgsVectorLayer * layer() const
Gets a pointer to the underlying layer. 
Manages and runs a set of geometry checks. 
The check controls geometries as a whole. 
Something has been removed. 
const QgsGeometryCheck * check() const
The geometry check that created this error. 
void grow(double delta)
Grows the rectangle in place by the specified amount. 
bool getFeature(QgsFeatureId id, QgsFeature &feature)
Retrieves the feature with the specified id into feature. 
This class implements a geometry check. 
QString resolutionMessage() const
A message with details, how the error has been resolved. 
const QString & layerId() const
The id of the layer on which this error has been detected. 
~QgsGeometryChecker() override
const double tolerance
The tolerance to allow for in geometry checks. 
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle...
Status status() const
The status of the error. 
QMap< QString, QMap< QgsFeatureId, QList< QgsGeometryCheck::Change > > > Changes
A collection of changes. 
A feature pool is based on a vector layer and caches features. 
QFuture< void > execute(int *totalSteps=nullptr)
virtual QgsRectangle affectedAreaBBox() const
The bounding box of the affected area of the error. 
virtual void fixError(const QMap< QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap< QString, int > &mergeAttributeIndices, Changes &changes) const
Fix the error error with the specified method. 
Descripts a change to fix a geometry. 
static QgsProject * instance()
Returns the QgsProject singleton instance. 
QgsRectangle boundingBox() const
Returns the bounding box of the geometry. 
bool fixError(QgsGeometryCheckError *error, int method, bool triggerRepaint=false)
virtual QString description() const
The error description. 
QgsFeatureId featureId() const
The id of the feature on which this error has been detected. 
This represents an error reported by a geometry check. 
virtual void collectErrors(const QMap< QString, QgsFeaturePool *> &featurePools, QList< QgsGeometryCheckError *> &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids=QgsGeometryCheck::LayerFeatureIds()) const =0
The main worker method. 
QVariant value() const
An additional value for the error. 
void progressValue(int value)
const QgsVertexId & vidx() const
The id of the affected vertex. 
void errorUpdated(QgsGeometryCheckError *error, bool statusChanged)
This change happens on feature level. 
QgsCoordinateReferenceSystem crs
The check controls a whole layer (topology checks) 
void errorAdded(QgsGeometryCheckError *error)