17 #include <QtConcurrentMap>
18 #include <QFutureWatcher>
21 #include <QTextStream>
36 , mFeaturePools( featurePools )
38 for (
auto it =
featurePools.constBegin(); it != mFeaturePools.constEnd(); ++it )
40 if ( it.value()->layer() )
42 it.value()->layer()->setReadOnly(
true );
44 it.value()->layer()->dataProvider()->enterUpdateMode();
51 qDeleteAll( mCheckErrors );
52 qDeleteAll( mChecks );
53 for (
auto it = mFeaturePools.constBegin(); it != mFeaturePools.constEnd(); ++it )
55 if ( it.value()->layer() )
57 it.value()->layer()->dataProvider()->leaveUpdateMode();
58 it.value()->layer()->setReadOnly(
false );
72 for (
auto it = mFeaturePools.constBegin(); it != mFeaturePools.constEnd(); ++it )
76 *totalSteps += check->isCompatible( it.value()->layer() ) ? it.value()->allFeatureIds().size() : 0;
85 QTimer *timer =
new QTimer();
86 connect( timer, &QTimer::timeout,
this, &QgsGeometryChecker::emitProgressValue );
87 QFutureWatcher<void> *watcher =
new QFutureWatcher<void>();
88 connect( watcher, &QFutureWatcherBase::finished, timer, &QObject::deleteLater );
89 connect( watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater );
91 QFuture<void> future = QtConcurrent::map( mChecks, RunCheckWrapper(
this ) );
92 watcher->setFuture( future );
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();
154 for (
auto layerChangeIt = layerChanges.constBegin(); layerChangeIt != layerChanges.constEnd(); ++layerChangeIt )
156 bool removed =
false;
168 if ( featurePool->
getFeature( layerChangeIt.key(), f ) )
170 recheckFeatures[it.key()].insert( layerChangeIt.key() );
181 if ( err->affectedAreaBBox().intersects( recheckArea ) )
188 QMap<QString, QgsFeatureIds> recheckAreaFeatures;
189 for (
const QString &layerId : mFeaturePools.keys() )
197 QList<QgsGeometryCheckError *> recheckErrors;
202 if ( !recheckAreaFeatures.isEmpty() )
204 check->collectErrors( mFeaturePools, recheckErrors, mMessages,
nullptr, recheckAreaFeatures );
209 if ( !recheckFeatures.isEmpty() )
211 check->collectErrors( mFeaturePools, recheckErrors, mMessages,
nullptr, recheckFeatures );
226 bool handled = err->handleChanges( changes );
233 if ( recheckErr->isEqual( err ) || recheckErr->closeMatch( err ) )
236 matchErr = recheckErr;
240 if ( nMatch == 1 && matchErr )
244 recheckErrors.removeAll( matchErr );
270 mCheckErrors.append( recheckErr );
273 if ( triggerRepaint )
275 for (
const QString &layerId : changes.keys() )
277 mFeaturePools[layerId]->layer()->triggerRepaint();
284 void QgsGeometryChecker::runCheck(
const QMap<QString, QgsFeaturePool *> &featurePools,
const QgsGeometryCheck *check )
287 QList<QgsGeometryCheckError *> errors;
288 QStringList messages;
290 mErrorListMutex.lock();
291 mCheckErrors.append( errors );
292 mMessages.append( messages );
293 mErrorListMutex.unlock();
301 : mInstance( instance )
305 void QgsGeometryChecker::RunCheckWrapper::operator()(
const QgsGeometryCheck *check )
307 mInstance->runCheck( mInstance->mFeaturePools, check );