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() )
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();
283 void QgsGeometryChecker::runCheck(
const QMap<QString, QgsFeaturePool *> &featurePools,
const QgsGeometryCheck *check )
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 );