mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-28 00:04:04 -04:00
[Geometry checker] Introduce QgsGeometryCheckerContext
This commit is contained in:
parent
31cc65df49
commit
2a92bfb2c9
@ -22,7 +22,8 @@ void QgsGeometryAngleCheck::collectErrors( QList<QgsGeometryCheckError *> &error
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -30,7 +31,7 @@ void QgsGeometryAngleCheck::collectErrors( QList<QgsGeometryCheckError *> &error
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -77,8 +78,9 @@ void QgsGeometryAngleCheck::collectErrors( QList<QgsGeometryCheckError *> &error
|
||||
|
||||
void QgsGeometryAngleCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -140,14 +142,14 @@ void QgsGeometryAngleCheck::fixError( QgsGeometryCheckError *error, int method,
|
||||
else
|
||||
{
|
||||
changes[error->layerId()][error->featureId()].append( Change( ChangeNode, ChangeRemoved, vidx ) );
|
||||
if ( QgsGeometryUtils::sqrDistance2D( p1, p3 ) < QgsGeometryCheckPrecision::tolerance() * QgsGeometryCheckPrecision::tolerance()
|
||||
&& QgsGeometryCheckerUtils::canDeleteVertex( geometry, vidx.part, vidx.ring ) &&
|
||||
if ( QgsGeometryUtils::sqrDistance2D( p1, p3 ) < mContext->tolerance &&
|
||||
QgsGeometryCheckerUtils::canDeleteVertex( geometry, vidx.part, vidx.ring ) &&
|
||||
geometry->deleteVertex( error->vidx() ) ) // error->vidx points to p3 after removing p2
|
||||
{
|
||||
changes[error->layerId()][error->featureId()].append( Change( ChangeNode, ChangeRemoved, QgsVertexId( vidx.part, vidx.ring, ( vidx.vertex + 1 ) % n ) ) );
|
||||
}
|
||||
feature.setGeometry( g );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
error->setFixed( method );
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ class QgsGeometryAngleCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsGeometryAngleCheck( const QMap<QString, QgsFeaturePool *> &featurePools, double minAngle )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, featurePools )
|
||||
QgsGeometryAngleCheck( QgsGeometryCheckerContext *context, double minAngle )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, context )
|
||||
, mMinAngle( minAngle )
|
||||
{}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
|
@ -23,7 +23,8 @@ void QgsGeometryAreaCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -31,7 +32,7 @@ void QgsGeometryAreaCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -44,7 +45,7 @@ void QgsGeometryAreaCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
for ( int i = 0, n = multiGeom->numGeometries(); i < n; ++i )
|
||||
{
|
||||
double value;
|
||||
if ( checkThreshold( layerId, multiGeom->geometryN( i ), value ) )
|
||||
if ( checkThreshold( featurePool->getMapToLayerUnits(), multiGeom->geometryN( i ), value ) )
|
||||
{
|
||||
errors.append( new QgsGeometryCheckError( this, layerId, featureid, multiGeom->geometryN( i )->centroid(), QgsVertexId( i ), value, QgsGeometryCheckError::ValueArea ) );
|
||||
}
|
||||
@ -53,7 +54,7 @@ void QgsGeometryAreaCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
else
|
||||
{
|
||||
double value;
|
||||
if ( checkThreshold( layerId, geom, value ) )
|
||||
if ( checkThreshold( featurePool->getMapToLayerUnits(), geom, value ) )
|
||||
{
|
||||
errors.append( new QgsGeometryCheckError( this, layerId, featureid, geom->centroid(), QgsVertexId( 0 ), value, QgsGeometryCheckError::ValueArea ) );
|
||||
}
|
||||
@ -64,12 +65,14 @@ void QgsGeometryAreaCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
|
||||
void QgsGeometryAreaCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
}
|
||||
double mapToLayerUnits = featurePool->getMapToLayerUnits();
|
||||
QgsGeometry g = feature.geometry();
|
||||
QgsAbstractGeometry *geom = g.geometry();
|
||||
QgsVertexId vidx = error->vidx();
|
||||
@ -85,7 +88,7 @@ void QgsGeometryAreaCheck::fixError( QgsGeometryCheckError *error, int method, c
|
||||
if ( dynamic_cast<QgsGeometryCollection *>( geom ) )
|
||||
{
|
||||
double value;
|
||||
if ( !checkThreshold( error->layerId(), static_cast<QgsGeometryCollection *>( geom )->geometryN( vidx.part ), value ) )
|
||||
if ( !checkThreshold( mapToLayerUnits, static_cast<QgsGeometryCollection *>( geom )->geometryN( vidx.part ), value ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -94,7 +97,7 @@ void QgsGeometryAreaCheck::fixError( QgsGeometryCheckError *error, int method, c
|
||||
else
|
||||
{
|
||||
double value;
|
||||
if ( !checkThreshold( error->layerId(), geom, value ) )
|
||||
if ( !checkThreshold( mapToLayerUnits, geom, value ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -129,16 +132,17 @@ void QgsGeometryAreaCheck::fixError( QgsGeometryCheckError *error, int method, c
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsGeometryAreaCheck::checkThreshold( const QString &layerId, const QgsAbstractGeometry *geom, double &value ) const
|
||||
bool QgsGeometryAreaCheck::checkThreshold( double mapToLayerUnits, const QgsAbstractGeometry *geom, double &value ) const
|
||||
{
|
||||
value = geom->area();
|
||||
double mapToLayerUnits = getFeaturePool( layerId )->getMapToLayerUnits();
|
||||
double threshold = mThresholdMapUnits * mapToLayerUnits * mapToLayerUnits;
|
||||
return value < threshold;
|
||||
}
|
||||
|
||||
bool QgsGeometryAreaCheck::mergeWithNeighbor( const QString &layerId, QgsFeature &feature, int partIdx, int method, int mergeAttributeIndex, Changes &changes, QString &errMsg ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
|
||||
double maxVal = 0.;
|
||||
QgsFeature mergeFeature;
|
||||
int mergePartIdx = -1;
|
||||
@ -147,10 +151,10 @@ bool QgsGeometryAreaCheck::mergeWithNeighbor( const QString &layerId, QgsFeature
|
||||
QgsAbstractGeometry *geom = g.geometry();
|
||||
|
||||
// Search for touching neighboring geometries
|
||||
for ( QgsFeatureId testId : getFeaturePool( layerId )->getIntersects( g.boundingBox() ) )
|
||||
for ( QgsFeatureId testId : featurePool->getIntersects( g.boundingBox() ) )
|
||||
{
|
||||
QgsFeature testFeature;
|
||||
if ( !getFeaturePool( layerId )->get( testId, testFeature ) )
|
||||
if ( !featurePool->get( testId, testFeature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -162,7 +166,7 @@ bool QgsGeometryAreaCheck::mergeWithNeighbor( const QString &layerId, QgsFeature
|
||||
{
|
||||
continue;
|
||||
}
|
||||
double len = QgsGeometryCheckerUtils::sharedEdgeLength( QgsGeometryCheckerUtils::getGeomPart( geom, partIdx ), QgsGeometryCheckerUtils::getGeomPart( testGeom, testPartIdx ), QgsGeometryCheckPrecision::reducedTolerance() );
|
||||
double len = QgsGeometryCheckerUtils::sharedEdgeLength( QgsGeometryCheckerUtils::getGeomPart( geom, partIdx ), QgsGeometryCheckerUtils::getGeomPart( testGeom, testPartIdx ), mContext->reducedTolerance );
|
||||
if ( len > 0. )
|
||||
{
|
||||
if ( method == MergeLongestEdge || method == MergeLargestArea )
|
||||
@ -212,8 +216,8 @@ bool QgsGeometryAreaCheck::mergeWithNeighbor( const QString &layerId, QgsFeature
|
||||
// Merge geometries
|
||||
QgsGeometry mergeFeatureGeom = mergeFeature.geometry();
|
||||
QgsAbstractGeometry *mergeGeom = mergeFeatureGeom.geometry();
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( QgsGeometryCheckerUtils::getGeomPart( mergeGeom, mergePartIdx ), QgsGeometryCheckPrecision::tolerance() );
|
||||
QgsAbstractGeometry *combinedGeom = geomEngine->combine( QgsGeometryCheckerUtils::getGeomPart( geom, partIdx ), &errMsg );
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( QgsGeometryCheckerUtils::getGeomPart( mergeGeom, mergePartIdx ), mContext->tolerance );
|
||||
QgsAbstractGeometry *combinedGeom = geomEngine->combine( *QgsGeometryCheckerUtils::getGeomPart( geom, partIdx ), &errMsg );
|
||||
delete geomEngine;
|
||||
if ( !combinedGeom || combinedGeom->isEmpty() )
|
||||
{
|
||||
|
@ -25,8 +25,8 @@ class QgsGeometryAreaCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsGeometryAreaCheck( const QMap<QString, QgsFeaturePool *> &featurePools, double thresholdMapUnits )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PolygonGeometry}, featurePools )
|
||||
QgsGeometryAreaCheck( QgsGeometryCheckerContext *context, double thresholdMapUnits )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PolygonGeometry}, context )
|
||||
, mThresholdMapUnits( thresholdMapUnits )
|
||||
{}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
@ -37,7 +37,7 @@ class QgsGeometryAreaCheck : public QgsGeometryCheck
|
||||
private:
|
||||
enum ResolutionMethod { MergeLongestEdge, MergeLargestArea, MergeIdenticalAttribute, Delete, NoChange };
|
||||
|
||||
virtual bool checkThreshold( const QString &layerId, const QgsAbstractGeometry *geom, double &value ) const;
|
||||
virtual bool checkThreshold( double mapToLayerUnits, const QgsAbstractGeometry *geom, double &value ) const;
|
||||
bool mergeWithNeighbor( const QString &layerId, QgsFeature &feature, int partIdx, int method, int mergeAttributeIndex, Changes &changes, QString &errMsg ) const;
|
||||
|
||||
protected:
|
||||
|
@ -18,43 +18,13 @@
|
||||
#include "qgsgeometrycheck.h"
|
||||
#include "../utils/qgsfeaturepool.h"
|
||||
|
||||
QgsGeometryCheckPrecision::QgsGeometryCheckPrecision()
|
||||
{
|
||||
mPrecision = 10;
|
||||
mReducedPrecision = 6;
|
||||
}
|
||||
|
||||
QgsGeometryCheckPrecision *QgsGeometryCheckPrecision::get()
|
||||
{
|
||||
static QgsGeometryCheckPrecision sInstance;
|
||||
return &sInstance;
|
||||
}
|
||||
|
||||
void QgsGeometryCheckPrecision::setPrecision( int tolerance )
|
||||
{
|
||||
get()->mPrecision = tolerance;
|
||||
get()->mReducedPrecision = tolerance / 2;
|
||||
}
|
||||
|
||||
int QgsGeometryCheckPrecision::precision()
|
||||
{
|
||||
return get()->mPrecision;
|
||||
}
|
||||
|
||||
int QgsGeometryCheckPrecision::reducedPrecision()
|
||||
{
|
||||
return get()->mReducedPrecision;
|
||||
}
|
||||
|
||||
double QgsGeometryCheckPrecision::tolerance()
|
||||
{
|
||||
return std::pow( 10, -get()->mPrecision );
|
||||
}
|
||||
|
||||
double QgsGeometryCheckPrecision::reducedTolerance()
|
||||
{
|
||||
return std::pow( 10, -get()->mReducedPrecision );
|
||||
}
|
||||
QgsGeometryCheckerContext::QgsGeometryCheckerContext( int _precision, const QString &_crs, const QMap<QString, QgsFeaturePool *> &_featurePools )
|
||||
: tolerance( qPow( 10, -_precision ) )
|
||||
, reducedTolerance( qPow( 10, -_precision / 2 ) )
|
||||
, crs( _crs )
|
||||
, featurePools( _featurePools )
|
||||
{}
|
||||
|
||||
QgsGeometryCheckError::QgsGeometryCheckError( const QgsGeometryCheck *check, const QString &layerId,
|
||||
QgsFeatureId featureId,
|
||||
@ -74,7 +44,7 @@ QgsGeometryCheckError::QgsGeometryCheckError( const QgsGeometryCheck *check, con
|
||||
QgsAbstractGeometry *QgsGeometryCheckError::geometry()
|
||||
{
|
||||
QgsFeature f;
|
||||
if ( mCheck->getFeaturePool( layerId() )->get( featureId(), f ) && f.hasGeometry() )
|
||||
if ( mCheck->getContext()->featurePools[ layerId() ]->get( featureId(), f ) && f.hasGeometry() )
|
||||
{
|
||||
QgsGeometry featureGeom = f.geometry();
|
||||
QgsAbstractGeometry *geom = featureGeom.geometry();
|
||||
@ -152,7 +122,7 @@ bool QgsGeometryCheckError::handleChanges( const QgsGeometryCheck::Changes &chan
|
||||
QMap<QString, QgsFeatureIds> QgsGeometryCheck::allLayerFeatureIds() const
|
||||
{
|
||||
QMap<QString, QgsFeatureIds> featureIds;
|
||||
for ( QgsFeaturePool *pool : mFeaturePools )
|
||||
for ( QgsFeaturePool *pool : mContext->featurePools )
|
||||
{
|
||||
featureIds.insert( pool->getLayer()->id(), pool->getFeatureIds() );
|
||||
}
|
||||
@ -161,6 +131,7 @@ QMap<QString, QgsFeatureIds> QgsGeometryCheck::allLayerFeatureIds() const
|
||||
|
||||
void QgsGeometryCheck::replaceFeatureGeometryPart( const QString &layerId, QgsFeature &feature, int partIdx, QgsAbstractGeometry *newPartGeom, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[layerId];
|
||||
QgsGeometry featureGeom = feature.geometry();
|
||||
QgsAbstractGeometry *geom = featureGeom.geometry();
|
||||
if ( dynamic_cast<QgsGeometryCollection *>( geom ) )
|
||||
@ -177,11 +148,12 @@ void QgsGeometryCheck::replaceFeatureGeometryPart( const QString &layerId, QgsFe
|
||||
feature.setGeometry( QgsGeometry( newPartGeom ) );
|
||||
changes[layerId][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
|
||||
}
|
||||
mFeaturePools[layerId]->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
}
|
||||
|
||||
void QgsGeometryCheck::deleteFeatureGeometryPart( const QString &layerId, QgsFeature &feature, int partIdx, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[layerId];
|
||||
QgsGeometry featureGeom = feature.geometry();
|
||||
QgsAbstractGeometry *geom = featureGeom.geometry();
|
||||
if ( dynamic_cast<QgsGeometryCollection *>( geom ) )
|
||||
@ -189,25 +161,26 @@ void QgsGeometryCheck::deleteFeatureGeometryPart( const QString &layerId, QgsFea
|
||||
static_cast<QgsGeometryCollection *>( geom )->removeGeometry( partIdx );
|
||||
if ( static_cast<QgsGeometryCollection *>( geom )->numGeometries() == 0 )
|
||||
{
|
||||
mFeaturePools[layerId]->deleteFeature( feature );
|
||||
featurePool->deleteFeature( feature );
|
||||
changes[layerId][feature.id()].append( Change( ChangeFeature, ChangeRemoved ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
feature.setGeometry( featureGeom );
|
||||
mFeaturePools[layerId]->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
changes[layerId][feature.id()].append( Change( ChangePart, ChangeRemoved, QgsVertexId( partIdx ) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mFeaturePools[layerId]->deleteFeature( feature );
|
||||
featurePool->deleteFeature( feature );
|
||||
changes[layerId][feature.id()].append( Change( ChangeFeature, ChangeRemoved ) );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGeometryCheck::deleteFeatureGeometryRing( const QString &layerId, QgsFeature &feature, int partIdx, int ringIdx, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[layerId];
|
||||
QgsGeometry featureGeom = feature.geometry();
|
||||
QgsAbstractGeometry *partGeom = QgsGeometryCheckerUtils::getGeomPart( featureGeom.geometry(), partIdx );
|
||||
if ( dynamic_cast<QgsCurvePolygon *>( partGeom ) )
|
||||
@ -221,7 +194,7 @@ void QgsGeometryCheck::deleteFeatureGeometryRing( const QString &layerId, QgsFea
|
||||
{
|
||||
static_cast<QgsCurvePolygon *>( partGeom )->removeInteriorRing( ringIdx - 1 );
|
||||
feature.setGeometry( featureGeom );
|
||||
mFeaturePools[layerId]->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
changes[layerId][feature.id()].append( Change( ChangeRing, ChangeRemoved, QgsVertexId( partIdx, ringIdx ) ) );
|
||||
}
|
||||
}
|
||||
|
@ -30,21 +30,13 @@ class QgsFeaturePool;
|
||||
|
||||
#define FEATUREID_NULL std::numeric_limits<QgsFeatureId>::min()
|
||||
|
||||
class QgsGeometryCheckPrecision
|
||||
struct QgsGeometryCheckerContext
|
||||
{
|
||||
public:
|
||||
static void setPrecision( int precision );
|
||||
static int precision();
|
||||
static int reducedPrecision();
|
||||
static double tolerance();
|
||||
static double reducedTolerance();
|
||||
|
||||
private:
|
||||
QgsGeometryCheckPrecision();
|
||||
static QgsGeometryCheckPrecision *get();
|
||||
|
||||
int mPrecision;
|
||||
int mReducedPrecision;
|
||||
QgsGeometryCheckerContext( int _precision, const QString &_crs, const QMap<QString, QgsFeaturePool *> &_featurePools );
|
||||
const double tolerance;
|
||||
const double reducedTolerance;
|
||||
const QString crs;
|
||||
const QMap<QString, QgsFeaturePool *> featurePools;
|
||||
};
|
||||
|
||||
class QgsGeometryCheck : public QObject
|
||||
@ -71,10 +63,10 @@ class QgsGeometryCheck : public QObject
|
||||
|
||||
typedef QMap<QString, QMap<QgsFeatureId, QList<Change>>> Changes;
|
||||
|
||||
QgsGeometryCheck( CheckType checkType, const QList<QgsWkbTypes::GeometryType> &compatibleGeometryTypes, const QMap<QString, QgsFeaturePool *> &featurePools )
|
||||
QgsGeometryCheck( CheckType checkType, const QList<QgsWkbTypes::GeometryType> &compatibleGeometryTypes, QgsGeometryCheckerContext *context )
|
||||
: mCheckType( checkType )
|
||||
, mCompatibleGeometryTypes( compatibleGeometryTypes )
|
||||
, mFeaturePools( featurePools )
|
||||
, mContext( context )
|
||||
{}
|
||||
virtual void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const = 0;
|
||||
virtual void fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const = 0;
|
||||
@ -83,8 +75,7 @@ class QgsGeometryCheck : public QObject
|
||||
virtual QString errorName() const = 0;
|
||||
CheckType getCheckType() const { return mCheckType; }
|
||||
bool getCompatibility( QgsWkbTypes::GeometryType type ) const { return mCompatibleGeometryTypes.contains( type ); }
|
||||
const QMap<QString, QgsFeaturePool *> &getFeaturePools() const { return mFeaturePools; }
|
||||
QgsFeaturePool *getFeaturePool( const QString &layerId ) const { return mFeaturePools.value( layerId, nullptr ); }
|
||||
QgsGeometryCheckerContext *getContext() const { return mContext; }
|
||||
|
||||
protected:
|
||||
QMap<QString, QgsFeatureIds> allLayerFeatureIds() const;
|
||||
@ -95,7 +86,9 @@ class QgsGeometryCheck : public QObject
|
||||
private:
|
||||
const CheckType mCheckType;
|
||||
QList<QgsWkbTypes::GeometryType> mCompatibleGeometryTypes;
|
||||
QMap<QString, QgsFeaturePool *> mFeaturePools;
|
||||
|
||||
protected:
|
||||
QgsGeometryCheckerContext *mContext;
|
||||
};
|
||||
|
||||
|
||||
|
@ -22,7 +22,8 @@ void QgsGeometryContainedCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -30,15 +31,15 @@ void QgsGeometryContainedCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QgsGeometry featureGeom = feature.geometry();
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( featureGeom.geometry(), QgsGeometryCheckPrecision::tolerance() );
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( featureGeom.geometry(), mContext->tolerance );
|
||||
|
||||
QgsFeatureIds ids = getFeaturePool( layerId )->getIntersects( featureGeom.geometry()->boundingBox() );
|
||||
QgsFeatureIds ids = featurePool->getIntersects( featureGeom.geometry()->boundingBox() );
|
||||
for ( QgsFeatureId otherid : ids )
|
||||
{
|
||||
if ( otherid == featureid )
|
||||
@ -46,7 +47,7 @@ void QgsGeometryContainedCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
continue;
|
||||
}
|
||||
QgsFeature otherFeature;
|
||||
if ( !getFeaturePool( layerId )->get( otherid, otherFeature ) )
|
||||
if ( !featurePool->get( otherid, otherFeature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -68,12 +69,13 @@ void QgsGeometryContainedCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
|
||||
void QgsGeometryContainedCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
|
||||
{
|
||||
QgsGeometryContainedCheckError *coverError = static_cast<QgsGeometryContainedCheckError *>( error );
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsGeometryContainedCheckError *containerError = static_cast<QgsGeometryContainedCheckError *>( error );
|
||||
|
||||
QgsFeature feature;
|
||||
QgsFeature otherFeature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) ||
|
||||
!getFeaturePool( error->layerId() )->get( coverError->otherId(), otherFeature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) ||
|
||||
!featurePool->get( containerError->otherId(), otherFeature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -81,7 +83,7 @@ void QgsGeometryContainedCheck::fixError( QgsGeometryCheckError *error, int meth
|
||||
|
||||
// Check if error still applies
|
||||
QgsGeometry featureGeom = feature.geometry();
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( featureGeom.geometry(), QgsGeometryCheckPrecision::tolerance() );
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( featureGeom.geometry(), mContext->tolerance );
|
||||
|
||||
if ( !geomEngine->within( otherFeature.geometry().geometry() ) )
|
||||
{
|
||||
@ -99,7 +101,7 @@ void QgsGeometryContainedCheck::fixError( QgsGeometryCheckError *error, int meth
|
||||
else if ( method == Delete )
|
||||
{
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeRemoved ) );
|
||||
getFeaturePool( error->layerId() )->deleteFeature( feature );
|
||||
featurePool->deleteFeature( feature );
|
||||
error->setFixed( method );
|
||||
}
|
||||
else
|
||||
|
@ -50,8 +50,8 @@ class QgsGeometryContainedCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsGeometryContainedCheck( const QMap<QString, QgsFeaturePool *> &featurePools )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PolygonGeometry}, featurePools ) {}
|
||||
explicit QgsGeometryContainedCheck( QgsGeometryCheckerContext *context )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PolygonGeometry}, context ) {}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
void fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
|
||||
QStringList getResolutionMethods() const override;
|
||||
|
@ -21,7 +21,8 @@ void QgsGeometryDegeneratePolygonCheck::collectErrors( QList<QgsGeometryCheckErr
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -29,7 +30,7 @@ void QgsGeometryDegeneratePolygonCheck::collectErrors( QList<QgsGeometryCheckErr
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -51,8 +52,9 @@ void QgsGeometryDegeneratePolygonCheck::collectErrors( QList<QgsGeometryCheckErr
|
||||
|
||||
void QgsGeometryDegeneratePolygonCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
|
@ -23,8 +23,8 @@ class QgsGeometryDegeneratePolygonCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsGeometryDegeneratePolygonCheck( const QMap<QString, QgsFeaturePool *> &featurePools )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::PolygonGeometry}, featurePools ) {}
|
||||
explicit QgsGeometryDegeneratePolygonCheck( QgsGeometryCheckerContext *context )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::PolygonGeometry}, context ) {}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
void fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
|
||||
QStringList getResolutionMethods() const override;
|
||||
|
@ -24,7 +24,8 @@ void QgsGeometryDuplicateCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -32,15 +33,15 @@ void QgsGeometryDuplicateCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QgsGeometry featureGeom = feature.geometry();
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( featureGeom.geometry(), QgsGeometryCheckPrecision::tolerance() );
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( featureGeom.geometry(), mContext->tolerance );
|
||||
|
||||
QList<QgsFeatureId> duplicates;
|
||||
QgsFeatureIds ids = getFeaturePool( layerId )->getIntersects( featureGeom.geometry()->boundingBox() );
|
||||
QgsFeatureIds ids = featurePool->getIntersects( featureGeom.geometry()->boundingBox() );
|
||||
for ( QgsFeatureId id : ids )
|
||||
{
|
||||
// > : only report overlaps once
|
||||
@ -49,13 +50,13 @@ void QgsGeometryDuplicateCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
continue;
|
||||
}
|
||||
QgsFeature testFeature;
|
||||
if ( !getFeaturePool( layerId )->get( id, testFeature ) )
|
||||
if ( !featurePool->get( id, testFeature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QString errMsg;
|
||||
QgsAbstractGeometry *diffGeom = geomEngine->symDifference( *testFeature.geometry().geometry(), &errMsg );
|
||||
if ( diffGeom && diffGeom->area() < QgsGeometryCheckPrecision::tolerance() )
|
||||
if ( diffGeom && diffGeom->area() < mContext->tolerance )
|
||||
{
|
||||
duplicates.append( id );
|
||||
}
|
||||
@ -77,8 +78,9 @@ void QgsGeometryDuplicateCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
|
||||
void QgsGeometryDuplicateCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -91,20 +93,20 @@ void QgsGeometryDuplicateCheck::fixError( QgsGeometryCheckError *error, int meth
|
||||
else if ( method == RemoveDuplicates )
|
||||
{
|
||||
QgsGeometry featureGeom = feature.geometry();
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( featureGeom.geometry(), QgsGeometryCheckPrecision::tolerance() );
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( featureGeom.geometry(), mContext->tolerance );
|
||||
|
||||
QgsGeometryDuplicateCheckError *duplicateError = static_cast<QgsGeometryDuplicateCheckError *>( error );
|
||||
for ( QgsFeatureId id : duplicateError->duplicates() )
|
||||
{
|
||||
QgsFeature testFeature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( id, testFeature ) )
|
||||
if ( !featurePool->get( id, testFeature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QgsAbstractGeometry *diffGeom = geomEngine->symDifference( testFeature.geometry().geometry() );
|
||||
if ( diffGeom && diffGeom->area() < QgsGeometryCheckPrecision::tolerance() )
|
||||
QgsAbstractGeometry *diffGeom = geomEngine->symDifference( *testFeature.geometry().geometry() );
|
||||
if ( diffGeom && diffGeom->area() < mContext->tolerance )
|
||||
{
|
||||
getFeaturePool( error->layerId() )->deleteFeature( testFeature );
|
||||
featurePool->deleteFeature( testFeature );
|
||||
changes[error->layerId()][id].append( Change( ChangeFeature, ChangeRemoved ) );
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,8 @@ class QgsGeometryDuplicateCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsGeometryDuplicateCheck( const QMap<QString, QgsFeaturePool *> &featurePools )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PolygonGeometry}, featurePools ) {}
|
||||
explicit QgsGeometryDuplicateCheck( QgsGeometryCheckerContext *context )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PolygonGeometry}, context ) {}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
void fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
|
||||
QStringList getResolutionMethods() const override;
|
||||
|
@ -22,7 +22,8 @@ void QgsGeometryDuplicateNodesCheck::collectErrors( QList<QgsGeometryCheckError
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -30,7 +31,7 @@ void QgsGeometryDuplicateNodesCheck::collectErrors( QList<QgsGeometryCheckError
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -48,7 +49,7 @@ void QgsGeometryDuplicateNodesCheck::collectErrors( QList<QgsGeometryCheckError
|
||||
{
|
||||
QgsPoint pi = geom->vertexAt( QgsVertexId( iPart, iRing, iVert ) );
|
||||
QgsPoint pj = geom->vertexAt( QgsVertexId( iPart, iRing, jVert ) );
|
||||
if ( QgsGeometryUtils::sqrDistance2D( pi, pj ) < QgsGeometryCheckPrecision::tolerance() * QgsGeometryCheckPrecision::tolerance() )
|
||||
if ( QgsGeometryUtils::sqrDistance2D( pi, pj ) < mContext->tolerance )
|
||||
{
|
||||
errors.append( new QgsGeometryCheckError( this, layerId, featureid, pj, QgsVertexId( iPart, iRing, jVert ) ) );
|
||||
}
|
||||
@ -61,8 +62,9 @@ void QgsGeometryDuplicateNodesCheck::collectErrors( QList<QgsGeometryCheckError
|
||||
|
||||
void QgsGeometryDuplicateNodesCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -80,14 +82,9 @@ void QgsGeometryDuplicateNodesCheck::fixError( QgsGeometryCheckError *error, int
|
||||
|
||||
// Check if error still applies
|
||||
int nVerts = QgsGeometryCheckerUtils::polyLineSize( geom, vidx.part, vidx.ring );
|
||||
if ( nVerts == 0 )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
}
|
||||
QgsPoint pi = geom->vertexAt( QgsVertexId( vidx.part, vidx.ring, ( vidx.vertex + nVerts - 1 ) % nVerts ) );
|
||||
QgsPoint pj = geom->vertexAt( error->vidx() );
|
||||
if ( QgsGeometryUtils::sqrDistance2D( pi, pj ) >= QgsGeometryCheckPrecision::tolerance() * QgsGeometryCheckPrecision::tolerance() )
|
||||
if ( QgsGeometryUtils::sqrDistance2D( pi, pj ) >= mContext->tolerance )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -111,7 +108,7 @@ void QgsGeometryDuplicateNodesCheck::fixError( QgsGeometryCheckError *error, int
|
||||
else
|
||||
{
|
||||
feature.setGeometry( featureGeom );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
error->setFixed( method );
|
||||
changes[error->layerId()][error->featureId()].append( Change( ChangeNode, ChangeRemoved, error->vidx() ) );
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ class QgsGeometryDuplicateNodesCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsGeometryDuplicateNodesCheck( const QMap<QString, QgsFeaturePool *> &featurePools )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, featurePools ) {}
|
||||
explicit QgsGeometryDuplicateNodesCheck( QgsGeometryCheckerContext *context )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, context ) {}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
void fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
|
||||
QStringList getResolutionMethods() const override;
|
||||
|
@ -27,17 +27,18 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,
|
||||
// Collect geometries, build spatial index
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
double mapToLayerUnits = getFeaturePool( layerId )->getMapToLayerUnits();
|
||||
double mapToLayerUnits = featurePool->getMapToLayerUnits();
|
||||
double gapAreaThreshold = mThresholdMapUnits * mapToLayerUnits * mapToLayerUnits;
|
||||
QList<QgsAbstractGeometry *> geomList;
|
||||
for ( QgsFeatureId id : featureIds[layerId] )
|
||||
{
|
||||
QgsFeature feature;
|
||||
if ( getFeaturePool( layerId )->get( id, feature ) )
|
||||
if ( featurePool->get( id, feature ) )
|
||||
{
|
||||
geomList.append( feature.geometry().geometry()->clone() );
|
||||
}
|
||||
@ -48,7 +49,7 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,
|
||||
return;
|
||||
}
|
||||
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( nullptr, QgsGeometryCheckPrecision::tolerance() );
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( nullptr, mContext->tolerance );
|
||||
|
||||
// Create union of geometry
|
||||
QString errMsg;
|
||||
@ -62,7 +63,7 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,
|
||||
}
|
||||
|
||||
// Get envelope of union
|
||||
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( unionGeom, QgsGeometryCheckPrecision::tolerance() );
|
||||
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( unionGeom, mContext->tolerance );
|
||||
QgsAbstractGeometry *envelope = geomEngine->envelope( &errMsg );
|
||||
delete geomEngine;
|
||||
if ( !envelope )
|
||||
@ -73,14 +74,14 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,
|
||||
}
|
||||
|
||||
// Buffer envelope
|
||||
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope, QgsGeometryCheckPrecision::tolerance() );
|
||||
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope, mContext->tolerance );
|
||||
QgsAbstractGeometry *bufEnvelope = geomEngine->buffer( 2, 0, GEOSBUF_CAP_SQUARE, GEOSBUF_JOIN_MITRE, 4. );
|
||||
delete geomEngine;
|
||||
delete envelope;
|
||||
envelope = bufEnvelope;
|
||||
|
||||
// Compute difference between envelope and union to obtain gap polygons
|
||||
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope, QgsGeometryCheckPrecision::tolerance() );
|
||||
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope, mContext->tolerance );
|
||||
QgsAbstractGeometry *diffGeom = geomEngine->difference( *unionGeom, &errMsg );
|
||||
delete geomEngine;
|
||||
if ( !diffGeom )
|
||||
@ -102,7 +103,7 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,
|
||||
}
|
||||
|
||||
// Skip gaps above threshold
|
||||
if ( geom->area() > gapAreaThreshold || geom->area() < QgsGeometryCheckPrecision::reducedTolerance() )
|
||||
if ( geom->area() > gapAreaThreshold || geom->area() < mContext->reducedTolerance )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -110,18 +111,18 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,
|
||||
// Get neighboring polygons
|
||||
QgsFeatureIds neighboringIds;
|
||||
QgsRectangle gapAreaBBox = geom->boundingBox();
|
||||
QgsFeatureIds intersectIds = getFeaturePool( layerId )->getIntersects( geom->boundingBox() );
|
||||
QgsFeatureIds intersectIds = featurePool->getIntersects( geom->boundingBox() );
|
||||
|
||||
for ( QgsFeatureId id : intersectIds )
|
||||
{
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( id, feature ) )
|
||||
if ( !featurePool->get( id, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QgsGeometry featureGeom = feature.geometry();
|
||||
QgsAbstractGeometry *geom2 = featureGeom.geometry();
|
||||
if ( QgsGeometryCheckerUtils::sharedEdgeLength( geom, geom2, QgsGeometryCheckPrecision::reducedTolerance() ) > 0 )
|
||||
if ( QgsGeometryCheckerUtils::sharedEdgeLength( geom, geom2, mContext->reducedTolerance ) > 0 )
|
||||
{
|
||||
neighboringIds.insert( feature.id() );
|
||||
gapAreaBBox.unionRect( geom2->boundingBox() );
|
||||
@ -169,6 +170,7 @@ void QgsGeometryGapCheck::fixError( QgsGeometryCheckError *error, int method, co
|
||||
|
||||
bool QgsGeometryGapCheck::mergeWithNeighbor( QgsGeometryGapCheckError *err, Changes &changes, QString &errMsg ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ err->layerId() ];
|
||||
double maxVal = 0.;
|
||||
QgsFeature mergeFeature;
|
||||
int mergePartIdx = -1;
|
||||
@ -179,7 +181,7 @@ bool QgsGeometryGapCheck::mergeWithNeighbor( QgsGeometryGapCheckError *err, Chan
|
||||
for ( QgsFeatureId testId : err->neighbors() )
|
||||
{
|
||||
QgsFeature testFeature;
|
||||
if ( !getFeaturePool( err->layerId() )->get( testId, testFeature ) )
|
||||
if ( !featurePool->get( testId, testFeature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -187,7 +189,7 @@ bool QgsGeometryGapCheck::mergeWithNeighbor( QgsGeometryGapCheckError *err, Chan
|
||||
QgsAbstractGeometry *testGeom = featureGeom.geometry();
|
||||
for ( int iPart = 0, nParts = testGeom->partCount(); iPart < nParts; ++iPart )
|
||||
{
|
||||
double len = QgsGeometryCheckerUtils::sharedEdgeLength( errGeometry, QgsGeometryCheckerUtils::getGeomPart( testGeom, iPart ), QgsGeometryCheckPrecision::reducedTolerance() );
|
||||
double len = QgsGeometryCheckerUtils::sharedEdgeLength( errGeometry, QgsGeometryCheckerUtils::getGeomPart( testGeom, iPart ), mContext->reducedTolerance );
|
||||
if ( len > maxVal )
|
||||
{
|
||||
maxVal = len;
|
||||
@ -205,8 +207,8 @@ bool QgsGeometryGapCheck::mergeWithNeighbor( QgsGeometryGapCheckError *err, Chan
|
||||
// Merge geometries
|
||||
QgsGeometry mergeFeatureGeom = mergeFeature.geometry();
|
||||
QgsAbstractGeometry *mergeGeom = mergeFeatureGeom.geometry();
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( errGeometry, QgsGeometryCheckPrecision::tolerance() );
|
||||
QgsAbstractGeometry *combinedGeom = geomEngine->combine( QgsGeometryCheckerUtils::getGeomPart( mergeGeom, mergePartIdx ), &errMsg );
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( errGeometry, mContext->tolerance );
|
||||
QgsAbstractGeometry *combinedGeom = geomEngine->combine( *QgsGeometryCheckerUtils::getGeomPart( mergeGeom, mergePartIdx ), &errMsg );
|
||||
delete geomEngine;
|
||||
if ( !combinedGeom || combinedGeom->isEmpty() )
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ class QgsGeometryGapCheckError : public QgsGeometryCheckError
|
||||
bool isEqual( QgsGeometryCheckError *other ) const override
|
||||
{
|
||||
QgsGeometryGapCheckError *err = dynamic_cast<QgsGeometryGapCheckError *>( other );
|
||||
return err && QgsGeometryCheckerUtils::pointsFuzzyEqual( err->location(), location(), QgsGeometryCheckPrecision::reducedTolerance() ) && err->neighbors() == neighbors();
|
||||
return err && QgsGeometryCheckerUtils::pointsFuzzyEqual( err->location(), location(), mCheck->getContext()->reducedTolerance ) && err->neighbors() == neighbors();
|
||||
}
|
||||
|
||||
bool closeMatch( QgsGeometryCheckError *other ) const override
|
||||
@ -86,8 +86,8 @@ class QgsGeometryGapCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsGeometryGapCheck( const QMap<QString, QgsFeaturePool *> &featurePools, double thresholdMapUnits )
|
||||
: QgsGeometryCheck( LayerCheck, {QgsWkbTypes::PolygonGeometry}, featurePools )
|
||||
QgsGeometryGapCheck( QgsGeometryCheckerContext *context, double thresholdMapUnits )
|
||||
: QgsGeometryCheck( LayerCheck, {QgsWkbTypes::PolygonGeometry}, context )
|
||||
, mThresholdMapUnits( thresholdMapUnits )
|
||||
{}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
|
@ -21,7 +21,8 @@ void QgsGeometryHoleCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -29,7 +30,7 @@ void QgsGeometryHoleCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -50,8 +51,9 @@ void QgsGeometryHoleCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
|
||||
void QgsGeometryHoleCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
|
@ -23,8 +23,8 @@ class QgsGeometryHoleCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsGeometryHoleCheck( const QMap<QString, QgsFeaturePool *> &featurePools )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PolygonGeometry}, featurePools ) {}
|
||||
explicit QgsGeometryHoleCheck( QgsGeometryCheckerContext *context )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PolygonGeometry}, context ) {}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
void fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
|
||||
QStringList getResolutionMethods() const override;
|
||||
|
@ -21,7 +21,8 @@ void QgsGeometryMultipartCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -29,7 +30,7 @@ void QgsGeometryMultipartCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -47,8 +48,9 @@ void QgsGeometryMultipartCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
|
||||
void QgsGeometryMultipartCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -71,13 +73,13 @@ void QgsGeometryMultipartCheck::fixError( QgsGeometryCheckError *error, int meth
|
||||
else if ( method == ConvertToSingle )
|
||||
{
|
||||
feature.setGeometry( QgsGeometry( QgsGeometryCheckerUtils::getGeomPart( geom, 0 )->clone() ) );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
error->setFixed( method );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
|
||||
}
|
||||
else if ( method == RemoveObject )
|
||||
{
|
||||
getFeaturePool( error->layerId() )->deleteFeature( feature );
|
||||
featurePool->deleteFeature( feature );
|
||||
error->setFixed( method );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeRemoved ) );
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ class QgsGeometryMultipartCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsGeometryMultipartCheck( const QMap<QString, QgsFeaturePool *> &featurePools )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PointGeometry, QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, featurePools ) {}
|
||||
explicit QgsGeometryMultipartCheck( QgsGeometryCheckerContext *context )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PointGeometry, QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, context ) {}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
void fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
|
||||
QStringList getResolutionMethods() const override;
|
||||
|
@ -22,25 +22,26 @@ void QgsGeometryOverlapCheck::collectErrors( QList<QgsGeometryCheckError *> &err
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
double mapToLayerUnits = getFeaturePool( layerId )->getMapToLayerUnits();
|
||||
double mapToLayerUnits = featurePool->getMapToLayerUnits();
|
||||
double overlapThreshold = mThresholdMapUnits * mapToLayerUnits * mapToLayerUnits;
|
||||
for ( QgsFeatureId featureid : featureIds[layerId] )
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QgsGeometry featureGeom = feature.geometry();
|
||||
QgsAbstractGeometry *geom = featureGeom.geometry();
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( geom, QgsGeometryCheckPrecision::tolerance() );
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( geom, mContext->tolerance );
|
||||
|
||||
QgsFeatureIds ids = getFeaturePool( layerId )->getIntersects( feature.geometry().boundingBox() );
|
||||
QgsFeatureIds ids = featurePool->getIntersects( feature.geometry().boundingBox() );
|
||||
for ( QgsFeatureId otherid : ids )
|
||||
{
|
||||
// >= : only report overlaps once
|
||||
@ -50,7 +51,7 @@ void QgsGeometryOverlapCheck::collectErrors( QList<QgsGeometryCheckError *> &err
|
||||
}
|
||||
|
||||
QgsFeature otherFeature;
|
||||
if ( !getFeaturePool( layerId )->get( otherid, otherFeature ) )
|
||||
if ( !featurePool->get( otherid, otherFeature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -65,7 +66,7 @@ void QgsGeometryOverlapCheck::collectErrors( QList<QgsGeometryCheckError *> &err
|
||||
for ( int iPart = 0, nParts = interGeom->partCount(); iPart < nParts; ++iPart )
|
||||
{
|
||||
double area = QgsGeometryCheckerUtils::getGeomPart( interGeom, iPart )->area();
|
||||
if ( area > QgsGeometryCheckPrecision::reducedTolerance() && area < overlapThreshold )
|
||||
if ( area > mContext->reducedTolerance && area < overlapThreshold )
|
||||
{
|
||||
errors.append( new QgsGeometryOverlapCheckError( this, layerId, featureid, QgsGeometryCheckerUtils::getGeomPart( interGeom, iPart )->centroid(), area, otherid ) );
|
||||
}
|
||||
@ -88,17 +89,18 @@ void QgsGeometryOverlapCheck::fixError( QgsGeometryCheckError *error, int method
|
||||
QString errMsg;
|
||||
QgsGeometryOverlapCheckError *overlapError = static_cast<QgsGeometryOverlapCheckError *>( error );
|
||||
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsFeature feature;
|
||||
QgsFeature otherFeature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) ||
|
||||
!getFeaturePool( error->layerId() )->get( overlapError->otherId(), otherFeature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) ||
|
||||
!featurePool->get( overlapError->otherId(), otherFeature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
}
|
||||
QgsGeometry featureGeom = feature.geometry();
|
||||
QgsAbstractGeometry *geom = featureGeom.geometry();
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( geom, QgsGeometryCheckPrecision::tolerance() );
|
||||
QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( geom, mContext->tolerance );
|
||||
|
||||
// Check if error still applies
|
||||
if ( !geomEngine->overlaps( otherFeature.geometry().geometry() ) )
|
||||
@ -120,8 +122,8 @@ void QgsGeometryOverlapCheck::fixError( QgsGeometryCheckError *error, int method
|
||||
for ( int iPart = 0, nParts = interGeom->partCount(); iPart < nParts; ++iPart )
|
||||
{
|
||||
QgsAbstractGeometry *part = QgsGeometryCheckerUtils::getGeomPart( interGeom, iPart );
|
||||
if ( std::fabs( part->area() - overlapError->value().toDouble() ) < QgsGeometryCheckPrecision::reducedTolerance() &&
|
||||
QgsGeometryCheckerUtils::pointsFuzzyEqual( part->centroid(), overlapError->location(), QgsGeometryCheckPrecision::reducedTolerance() ) )
|
||||
if ( qAbs( part->area() - overlapError->value().toDouble() ) < mContext->reducedTolerance &&
|
||||
QgsGeometryCheckerUtils::pointsFuzzyEqual( part->centroid(), overlapError->location(), mContext->reducedTolerance ) )
|
||||
{
|
||||
interPart = part;
|
||||
break;
|
||||
@ -141,8 +143,8 @@ void QgsGeometryOverlapCheck::fixError( QgsGeometryCheckError *error, int method
|
||||
}
|
||||
else if ( method == Subtract )
|
||||
{
|
||||
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( geom, QgsGeometryCheckPrecision::reducedTolerance() );
|
||||
QgsAbstractGeometry *diff1 = geomEngine->difference( interPart, &errMsg );
|
||||
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( geom, mContext->reducedTolerance );
|
||||
QgsAbstractGeometry *diff1 = geomEngine->difference( *interPart, &errMsg );
|
||||
delete geomEngine;
|
||||
if ( !diff1 || diff1->isEmpty() )
|
||||
{
|
||||
@ -154,8 +156,8 @@ void QgsGeometryOverlapCheck::fixError( QgsGeometryCheckError *error, int method
|
||||
QgsGeometryCheckerUtils::filter1DTypes( diff1 );
|
||||
}
|
||||
QgsGeometry otherFeatureGeom = otherFeature.geometry();
|
||||
QgsGeometryEngine *otherGeomEngine = QgsGeometryCheckerUtils::createGeomEngine( otherFeatureGeom.geometry(), QgsGeometryCheckPrecision::reducedTolerance() );
|
||||
QgsAbstractGeometry *diff2 = otherGeomEngine->difference( interPart, &errMsg );
|
||||
QgsGeometryEngine *otherGeomEngine = QgsGeometryCheckerUtils::createGeomEngine( otherFeatureGeom.geometry(), mContext->reducedTolerance );
|
||||
QgsAbstractGeometry *diff2 = otherGeomEngine->difference( *interPart, &errMsg );
|
||||
delete otherGeomEngine;
|
||||
if ( !diff2 || diff2->isEmpty() )
|
||||
{
|
||||
@ -166,8 +168,8 @@ void QgsGeometryOverlapCheck::fixError( QgsGeometryCheckError *error, int method
|
||||
{
|
||||
QgsGeometryCheckerUtils::filter1DTypes( diff2 );
|
||||
}
|
||||
double shared1 = diff1 ? QgsGeometryCheckerUtils::sharedEdgeLength( diff1, interPart, QgsGeometryCheckPrecision::reducedPrecision() ) : 0;
|
||||
double shared2 = diff2 ? QgsGeometryCheckerUtils::sharedEdgeLength( diff2, interPart, QgsGeometryCheckPrecision::reducedPrecision() ) : 0;
|
||||
double shared1 = diff1 ? QgsGeometryCheckerUtils::sharedEdgeLength( diff1, interPart, mContext->reducedTolerance ) : 0;
|
||||
double shared2 = diff2 ? QgsGeometryCheckerUtils::sharedEdgeLength( diff2, interPart, mContext->reducedTolerance ) : 0;
|
||||
if ( shared1 == 0. || shared2 == 0. )
|
||||
{
|
||||
error->setFixFailed( tr( "Could not find shared edges between intersection and overlapping features" ) );
|
||||
@ -179,7 +181,7 @@ void QgsGeometryOverlapCheck::fixError( QgsGeometryCheckError *error, int method
|
||||
feature.setGeometry( QgsGeometry( diff1 ) );
|
||||
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
|
||||
delete diff2;
|
||||
}
|
||||
@ -188,7 +190,7 @@ void QgsGeometryOverlapCheck::fixError( QgsGeometryCheckError *error, int method
|
||||
otherFeature.setGeometry( QgsGeometry( diff2 ) );
|
||||
|
||||
changes[error->layerId()][otherFeature.id()].append( Change( ChangeFeature, ChangeChanged ) );
|
||||
getFeaturePool( error->layerId() )->updateFeature( otherFeature );
|
||||
featurePool->updateFeature( otherFeature );
|
||||
|
||||
delete diff1;
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ class QgsGeometryOverlapCheckError : public QgsGeometryCheckError
|
||||
other->layerId() == layerId() &&
|
||||
other->featureId() == featureId() &&
|
||||
err->otherId() == otherId() &&
|
||||
QgsGeometryCheckerUtils::pointsFuzzyEqual( location(), other->location(), QgsGeometryCheckPrecision::reducedTolerance() ) &&
|
||||
std::fabs( value().toDouble() - other->value().toDouble() ) < QgsGeometryCheckPrecision::reducedTolerance();
|
||||
QgsGeometryCheckerUtils::pointsFuzzyEqual( location(), other->location(), mCheck->getContext()->reducedTolerance ) &&
|
||||
qAbs( value().toDouble() - other->value().toDouble() ) < mCheck->getContext()->reducedTolerance;
|
||||
}
|
||||
|
||||
bool closeMatch( QgsGeometryCheckError *other ) const override
|
||||
@ -60,8 +60,8 @@ class QgsGeometryOverlapCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsGeometryOverlapCheck( const QMap<QString, QgsFeaturePool *> &featurePools, double thresholdMapUnits )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PolygonGeometry}, featurePools )
|
||||
QgsGeometryOverlapCheck( QgsGeometryCheckerContext *context, double thresholdMapUnits )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PolygonGeometry}, context )
|
||||
, mThresholdMapUnits( thresholdMapUnits )
|
||||
{}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
|
@ -22,17 +22,18 @@ void QgsGeometrySegmentLengthCheck::collectErrors( QList<QgsGeometryCheckError *
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
double mapToLayerUnits = getFeaturePool( layerId )->getMapToLayerUnits();
|
||||
double mapToLayerUnits = featurePool->getMapToLayerUnits();
|
||||
double minLength = mMinLengthMapUnits * mapToLayerUnits;
|
||||
for ( QgsFeatureId featureid : featureIds[layerId] )
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -66,8 +67,9 @@ void QgsGeometrySegmentLengthCheck::collectErrors( QList<QgsGeometryCheckError *
|
||||
|
||||
void QgsGeometrySegmentLengthCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &/*changes*/ ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -95,7 +97,7 @@ void QgsGeometrySegmentLengthCheck::fixError( QgsGeometryCheckError *error, int
|
||||
QgsPoint pi = geom->vertexAt( error->vidx() );
|
||||
QgsPoint pj = geom->vertexAt( QgsVertexId( vidx.part, vidx.ring, ( vidx.vertex - 1 + nVerts ) % nVerts ) );
|
||||
double dist = qSqrt( QgsGeometryUtils::sqrDistance2D( pi, pj ) );
|
||||
double mapToLayerUnits = getFeaturePool( error->layerId() )->getMapToLayerUnits();
|
||||
double mapToLayerUnits = featurePool->getMapToLayerUnits();
|
||||
double minLength = mMinLengthMapUnits * mapToLayerUnits;
|
||||
if ( dist >= minLength )
|
||||
{
|
||||
|
@ -23,8 +23,8 @@ class QgsGeometrySegmentLengthCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsGeometrySegmentLengthCheck( const QMap<QString, QgsFeaturePool *> &featurePools, double minLengthMapUnits )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, featurePools )
|
||||
QgsGeometrySegmentLengthCheck( QgsGeometryCheckerContext *context, double minLengthMapUnits )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, context )
|
||||
, mMinLengthMapUnits( minLengthMapUnits )
|
||||
{}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
|
@ -12,10 +12,10 @@
|
||||
void QgsGeometrySelfContactCheck::collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &/*messages*/, QAtomicInt *progressCounter, const QMap<QString, QgsFeatureIds> &ids ) const
|
||||
{
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
double tolerance = QgsGeometryCheckPrecision::tolerance();
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -23,7 +23,7 @@ void QgsGeometrySelfContactCheck::collectErrors( QList<QgsGeometryCheckError *>
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -44,14 +44,19 @@ void QgsGeometrySelfContactCheck::collectErrors( QList<QgsGeometryCheckError *>
|
||||
ring.append( geom->vertexAt( QgsVertexId( iPart, iRing, 0 ) ) );
|
||||
for ( int i = 1; i < n; ++i )
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
QgsPoint p = geom->vertexAt( QgsVertexId( iPart, iRing, i ) );
|
||||
if ( QgsGeometryUtils::sqrDistance2D( p, ring.last() ) > tolerance * tolerance )
|
||||
=======
|
||||
QgsPoint p = geom->vertexAt( QgsVertexId( iPart, iRing, i ) );
|
||||
if ( QgsGeometryUtils::sqrDistance2D( p, ring.last() ) > mContext->tolerance * mContext->tolerance )
|
||||
>>>>>>> [GeometryChecker] Introduce QgsGeometryCheckerContext
|
||||
{
|
||||
vtxMap.append( i );
|
||||
ring.append( p );
|
||||
}
|
||||
}
|
||||
while ( QgsGeometryUtils::sqrDistance2D( ring.front(), ring.back() ) < tolerance * tolerance )
|
||||
while ( QgsGeometryUtils::sqrDistance2D( ring.front(), ring.back() ) < mContext->tolerance * mContext->tolerance )
|
||||
{
|
||||
vtxMap.pop_back();
|
||||
ring.pop_back();
|
||||
@ -76,7 +81,7 @@ void QgsGeometrySelfContactCheck::collectErrors( QList<QgsGeometryCheckError *>
|
||||
const QgsPoint &si = ring[i];
|
||||
const QgsPoint &sj = ring[j];
|
||||
QgsPoint q = QgsGeometryUtils::projPointOnSegment( p, si, sj );
|
||||
if ( QgsGeometryUtils::sqrDistance2D( p, q ) < tolerance * tolerance )
|
||||
if ( QgsGeometryUtils::sqrDistance2D( p, q ) < mContext->tolerance * mContext->tolerance )
|
||||
{
|
||||
errors.append( new QgsGeometryCheckError( this, layerId, featureid, p, QgsVertexId( iPart, iRing, vtxMap[iVert] ) ) );
|
||||
break; // No need to report same contact on different segments multiple times
|
||||
|
@ -15,8 +15,8 @@ class QgsGeometrySelfContactCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsGeometrySelfContactCheck( const QMap<QString, QgsFeaturePool *> &featurePools )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, featurePools ) {}
|
||||
QgsGeometrySelfContactCheck( QgsGeometryCheckerContext *context )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, context ) {}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = 0, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const;
|
||||
void fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes & ) const;
|
||||
QStringList getResolutionMethods() const;
|
||||
|
@ -65,7 +65,8 @@ void QgsGeometrySelfIntersectionCheck::collectErrors( QList<QgsGeometryCheckErro
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -73,7 +74,7 @@ void QgsGeometrySelfIntersectionCheck::collectErrors( QList<QgsGeometryCheckErro
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -84,7 +85,7 @@ void QgsGeometrySelfIntersectionCheck::collectErrors( QList<QgsGeometryCheckErro
|
||||
{
|
||||
for ( int iRing = 0, nRings = geom->ringCount( iPart ); iRing < nRings; ++iRing )
|
||||
{
|
||||
for ( const QgsGeometryUtils::SelfIntersection &inter : QgsGeometryUtils::getSelfIntersections( geom, iPart, iRing, QgsGeometryCheckPrecision::tolerance() ) )
|
||||
for ( const QgsGeometryUtils::SelfIntersection &inter : QgsGeometryUtils::getSelfIntersections( geom, iPart, iRing, mContext->tolerance ) )
|
||||
{
|
||||
errors.append( new QgsGeometrySelfIntersectionCheckError( this, layerId, featureid, inter.point, QgsVertexId( iPart, iRing ), inter ) );
|
||||
}
|
||||
@ -96,8 +97,9 @@ void QgsGeometrySelfIntersectionCheck::collectErrors( QList<QgsGeometryCheckErro
|
||||
|
||||
void QgsGeometrySelfIntersectionCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -127,7 +129,7 @@ void QgsGeometrySelfIntersectionCheck::fixError( QgsGeometryCheckError *error, i
|
||||
QgsPoint p2 = geom->vertexAt( QgsVertexId( vidx.part, vidx.ring, ( inter.segment1 + 1 ) % nVerts ) );
|
||||
QgsPoint q2 = geom->vertexAt( QgsVertexId( vidx.part, vidx.ring, ( inter.segment2 + 1 ) % nVerts ) );
|
||||
QgsPoint s;
|
||||
if ( !QgsGeometryUtils::segmentIntersection( p1, p2, q1, q2, s, QgsGeometryCheckPrecision::tolerance() ) )
|
||||
if ( !QgsGeometryUtils::segmentIntersection( p1, p2, q1, q2, s, mContext->tolerance ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -202,7 +204,7 @@ void QgsGeometrySelfIntersectionCheck::fixError( QgsGeometryCheckError *error, i
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeRing, ChangeAdded, QgsVertexId( vidx.part, poly->ringCount() - 2 ) ) );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeRing, ChangeAdded, QgsVertexId( vidx.part, poly->ringCount() - 1 ) ) );
|
||||
feature.setGeometry( featureGeom );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -214,8 +216,8 @@ void QgsGeometrySelfIntersectionCheck::fixError( QgsGeometryCheckError *error, i
|
||||
poly2->setExteriorRing( ringGeom2 );
|
||||
|
||||
// Reassing interiors as necessary
|
||||
QgsGeometryEngine *geomEnginePoly1 = QgsGeometryCheckerUtils::createGeomEngine( poly, QgsGeometryCheckPrecision::tolerance() );
|
||||
QgsGeometryEngine *geomEnginePoly2 = QgsGeometryCheckerUtils::createGeomEngine( poly2, QgsGeometryCheckPrecision::tolerance() );
|
||||
QgsGeometryEngine *geomEnginePoly1 = QgsGeometryCheckerUtils::createGeomEngine( poly, mContext->tolerance );
|
||||
QgsGeometryEngine *geomEnginePoly2 = QgsGeometryCheckerUtils::createGeomEngine( poly2, mContext->tolerance );
|
||||
for ( int n = poly->numInteriorRings(), i = n - 1; i >= 0; --i )
|
||||
{
|
||||
if ( !geomEnginePoly1->contains( poly->interiorRing( i ) ) )
|
||||
@ -241,7 +243,7 @@ void QgsGeometrySelfIntersectionCheck::fixError( QgsGeometryCheckError *error, i
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeRing, ChangeChanged, QgsVertexId( vidx.part, vidx.ring ) ) );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangePart, ChangeAdded, QgsVertexId( geom->partCount() - 1 ) ) );
|
||||
feature.setGeometry( featureGeom );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
}
|
||||
// Otherwise, create multipolygon
|
||||
else
|
||||
@ -250,7 +252,7 @@ void QgsGeometrySelfIntersectionCheck::fixError( QgsGeometryCheckError *error, i
|
||||
multiPoly->addGeometry( poly->clone() );
|
||||
multiPoly->addGeometry( poly2 );
|
||||
feature.setGeometry( QgsGeometry( multiPoly ) );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
|
||||
}
|
||||
}
|
||||
@ -259,8 +261,8 @@ void QgsGeometrySelfIntersectionCheck::fixError( QgsGeometryCheckError *error, i
|
||||
QgsFeature newFeature;
|
||||
newFeature.setAttributes( feature.attributes() );
|
||||
newFeature.setGeometry( QgsGeometry( poly2 ) );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
getFeaturePool( error->layerId() )->addFeature( newFeature );
|
||||
featurePool->updateFeature( feature );
|
||||
featurePool->addFeature( newFeature );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeRing, ChangeChanged, QgsVertexId( vidx.part, vidx.ring ) ) );
|
||||
changes[error->layerId()][newFeature.id()].append( Change( ChangeFeature, ChangeAdded ) );
|
||||
}
|
||||
@ -276,7 +278,7 @@ void QgsGeometrySelfIntersectionCheck::fixError( QgsGeometryCheckError *error, i
|
||||
geomCollection->removeGeometry( vidx.part );
|
||||
geomCollection->addGeometry( ringGeom1 );
|
||||
geomCollection->addGeometry( ringGeom2 );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangePart, ChangeRemoved, QgsVertexId( vidx.part ) ) );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangePart, ChangeAdded, QgsVertexId( geomCollection->partCount() - 2 ) ) );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangePart, ChangeAdded, QgsVertexId( geomCollection->partCount() - 1 ) ) );
|
||||
@ -287,7 +289,7 @@ void QgsGeometrySelfIntersectionCheck::fixError( QgsGeometryCheckError *error, i
|
||||
geomCollection->addGeometry( ringGeom1 );
|
||||
geomCollection->addGeometry( ringGeom2 );
|
||||
feature.setGeometry( QgsGeometry( geomCollection ) );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
|
||||
}
|
||||
}
|
||||
@ -299,20 +301,20 @@ void QgsGeometrySelfIntersectionCheck::fixError( QgsGeometryCheckError *error, i
|
||||
geomCollection->removeGeometry( vidx.part );
|
||||
geomCollection->addGeometry( ringGeom1 );
|
||||
feature.setGeometry( featureGeom );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangePart, ChangeRemoved, QgsVertexId( vidx.part ) ) );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangePart, ChangeAdded, QgsVertexId( geomCollection->partCount() - 1 ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
feature.setGeometry( QgsGeometry( ringGeom1 ) );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged, QgsVertexId( vidx.part ) ) );
|
||||
}
|
||||
QgsFeature newFeature;
|
||||
newFeature.setAttributes( feature.attributes() );
|
||||
newFeature.setGeometry( QgsGeometry( ringGeom2 ) );
|
||||
getFeaturePool( error->layerId() )->addFeature( newFeature );
|
||||
featurePool->addFeature( newFeature );
|
||||
changes[error->layerId()][newFeature.id()].append( Change( ChangeFeature, ChangeAdded ) );
|
||||
}
|
||||
}
|
||||
|
@ -51,8 +51,8 @@ class QgsGeometrySelfIntersectionCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsGeometrySelfIntersectionCheck( const QMap<QString, QgsFeaturePool *> &featurePools )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, featurePools ) {}
|
||||
explicit QgsGeometrySelfIntersectionCheck( QgsGeometryCheckerContext *context )
|
||||
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, context ) {}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
void fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
|
||||
QStringList getResolutionMethods() const override;
|
||||
|
@ -16,9 +16,8 @@
|
||||
#include "qgsgeometrysliverpolygoncheck.h"
|
||||
#include "../utils/qgsfeaturepool.h"
|
||||
|
||||
bool QgsGeometrySliverPolygonCheck::checkThreshold( const QString &layerId, const QgsAbstractGeometry *geom, double &value ) const
|
||||
bool QgsGeometrySliverPolygonCheck::checkThreshold( double mapToLayerUnits, const QgsAbstractGeometry *geom, double &value ) const
|
||||
{
|
||||
double mapToLayerUnits = getFeaturePool( layerId )->getMapToLayerUnits();
|
||||
double maxArea = mMaxAreaMapUnits * mapToLayerUnits * mapToLayerUnits;
|
||||
QgsRectangle bb = geom->boundingBox();
|
||||
double maxDim = qMax( bb.width(), bb.height() );
|
||||
|
@ -23,8 +23,8 @@ class QgsGeometrySliverPolygonCheck : public QgsGeometryAreaCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsGeometrySliverPolygonCheck( const QMap<QString, QgsFeaturePool *> &featurePools, double threshold, double maxAreaMapUnits )
|
||||
: QgsGeometryAreaCheck( featurePools, threshold )
|
||||
QgsGeometrySliverPolygonCheck( QgsGeometryCheckerContext *context, double threshold, double maxAreaMapUnits )
|
||||
: QgsGeometryAreaCheck( context, threshold )
|
||||
, mMaxAreaMapUnits( maxAreaMapUnits )
|
||||
{}
|
||||
QString errorDescription() const override { return tr( "Sliver polygon" ); }
|
||||
@ -33,7 +33,7 @@ class QgsGeometrySliverPolygonCheck : public QgsGeometryAreaCheck
|
||||
private:
|
||||
double mMaxAreaMapUnits;
|
||||
|
||||
bool checkThreshold( const QString &layerId, const QgsAbstractGeometry *geom, double &value ) const override;
|
||||
bool checkThreshold( double mapToLayerUnits, const QgsAbstractGeometry *geom, double &value ) const override;
|
||||
};
|
||||
|
||||
#endif // QGS_GEOMETRY_SLIVERPOLYGON_CHECK_H
|
||||
|
@ -28,7 +28,8 @@ void QgsGeometryTypeCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
if ( !getCompatibility( getFeaturePool( layerId )->getLayer()->geometryType() ) )
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
if ( !getCompatibility( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -36,7 +37,7 @@ void QgsGeometryTypeCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
{
|
||||
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( layerId )->get( featureid, feature ) )
|
||||
if ( !featurePool->get( featureid, feature ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -54,8 +55,9 @@ void QgsGeometryTypeCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
|
||||
void QgsGeometryTypeCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ error->layerId() ];
|
||||
QgsFeature feature;
|
||||
if ( !getFeaturePool( error->layerId() )->get( error->featureId(), feature ) )
|
||||
if ( !featurePool->get( error->featureId(), feature ) )
|
||||
{
|
||||
error->setObsolete();
|
||||
return;
|
||||
@ -87,12 +89,12 @@ void QgsGeometryTypeCheck::fixError( QgsGeometryCheckError *error, int method, c
|
||||
QgsFeature newFeature;
|
||||
newFeature.setAttributes( feature.attributes() );
|
||||
newFeature.setGeometry( QgsGeometry( QgsGeometryCheckerUtils::getGeomPart( geom, iPart )->clone() ) );
|
||||
getFeaturePool( error->layerId() )->addFeature( newFeature );
|
||||
featurePool->addFeature( newFeature );
|
||||
changes[error->layerId()][newFeature.id()].append( Change( ChangeFeature, ChangeAdded ) );
|
||||
}
|
||||
// Recycle feature for part 0
|
||||
feature.setGeometry( QgsGeometry( QgsGeometryCheckerUtils::getGeomPart( geom, 0 )->clone() ) );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
|
||||
}
|
||||
// Check if corresponding multi type is allowed
|
||||
@ -138,21 +140,21 @@ void QgsGeometryTypeCheck::fixError( QgsGeometryCheckError *error, int method, c
|
||||
geomCollection->addGeometry( geom->clone() );
|
||||
|
||||
feature.setGeometry( QgsGeometry( geomCollection ) );
|
||||
getFeaturePool( error->layerId() )->updateFeature( feature );
|
||||
featurePool->updateFeature( feature );
|
||||
changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
|
||||
}
|
||||
}
|
||||
// Delete feature
|
||||
else
|
||||
{
|
||||
getFeaturePool( error->layerId() )->deleteFeature( feature );
|
||||
featurePool->deleteFeature( feature );
|
||||
changes[error->layerId()][error->featureId()].append( Change( ChangeFeature, ChangeRemoved ) );
|
||||
}
|
||||
error->setFixed( method );
|
||||
}
|
||||
else if ( method == Delete )
|
||||
{
|
||||
getFeaturePool( error->layerId() )->deleteFeature( feature );
|
||||
featurePool->deleteFeature( feature );
|
||||
error->setFixed( method );
|
||||
changes[error->layerId()][error->featureId()].append( Change( ChangeFeature, ChangeRemoved ) );
|
||||
}
|
||||
|
@ -48,8 +48,8 @@ class QgsGeometryTypeCheck : public QgsGeometryCheck
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsGeometryTypeCheck( const QMap<QString, QgsFeaturePool *> &featurePools, int allowedTypes )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PointGeometry, QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, featurePools )
|
||||
QgsGeometryTypeCheck( QgsGeometryCheckerContext *context, int allowedTypes )
|
||||
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PointGeometry, QgsWkbTypes::LineGeometry, QgsWkbTypes::PolygonGeometry}, context )
|
||||
, mAllowedTypes( allowedTypes )
|
||||
{}
|
||||
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
|
||||
|
@ -24,9 +24,9 @@
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
QgsGeometryChecker::QgsGeometryChecker( const QList<QgsGeometryCheck *> &checks, const QMap<QString, QgsFeaturePool *> &featurePools )
|
||||
QgsGeometryChecker::QgsGeometryChecker( const QList<QgsGeometryCheck *> &checks, QgsGeometryCheckerContext *context )
|
||||
: mChecks( checks )
|
||||
, mFeaturePools( featurePools )
|
||||
, mContext( context )
|
||||
{
|
||||
}
|
||||
|
||||
@ -34,6 +34,13 @@ QgsGeometryChecker::~QgsGeometryChecker()
|
||||
{
|
||||
qDeleteAll( mCheckErrors );
|
||||
qDeleteAll( mChecks );
|
||||
for ( const QgsFeaturePool *featurePool : mContext->featurePools.values() )
|
||||
{
|
||||
if ( featurePool->getLayer() )
|
||||
featurePool->getLayer()->setReadOnly( false );
|
||||
delete featurePool;
|
||||
}
|
||||
delete mContext;
|
||||
}
|
||||
|
||||
QFuture<void> QgsGeometryChecker::execute( int *totalSteps )
|
||||
@ -43,7 +50,7 @@ QFuture<void> QgsGeometryChecker::execute( int *totalSteps )
|
||||
*totalSteps = 0;
|
||||
for ( QgsGeometryCheck *check : mChecks )
|
||||
{
|
||||
for ( const QgsFeaturePool *featurePool : mFeaturePools.values() )
|
||||
for ( const QgsFeaturePool *featurePool : mContext->featurePools.values() )
|
||||
{
|
||||
if ( check->getCheckType() <= QgsGeometryCheck::FeatureCheck )
|
||||
{
|
||||
@ -118,7 +125,7 @@ bool QgsGeometryChecker::fixError( QgsGeometryCheckError *error, int method, boo
|
||||
if ( !removed )
|
||||
{
|
||||
QgsFeature f;
|
||||
if ( mFeaturePools[layerId]->get( id, f ) )
|
||||
if ( mContext->featurePools[layerId]->get( id, f ) )
|
||||
{
|
||||
recheckFeatures[layerId].insert( id );
|
||||
recheckArea.combineExtentWith( f.geometry().boundingBox() );
|
||||
@ -137,15 +144,16 @@ bool QgsGeometryChecker::fixError( QgsGeometryCheckError *error, int method, boo
|
||||
}
|
||||
}
|
||||
}
|
||||
recheckArea.grow( 10 * QgsGeometryCheckPrecision::tolerance() );
|
||||
recheckArea.grow( 10 * mContext->tolerance );
|
||||
QMap<QString, QgsFeatureIds> recheckAreaFeatures;
|
||||
for ( const QString &layerId : mFeaturePools.keys() )
|
||||
for ( const QString &layerId : mContext->featurePools.keys() )
|
||||
{
|
||||
recheckAreaFeatures[layerId] = mFeaturePools[layerId]->getIntersects( recheckArea );
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[layerId];
|
||||
recheckAreaFeatures[layerId] = featurePool->getIntersects( recheckArea );
|
||||
// If only selected features were checked, confine the recheck areas to the selected features
|
||||
if ( mFeaturePools[layerId]->getSelectedOnly() )
|
||||
if ( featurePool->getSelectedOnly() )
|
||||
{
|
||||
recheckAreaFeatures[layerId] = recheckAreaFeatures[layerId].intersect( mFeaturePools[layerId]->getLayer()->selectedFeatureIds() );
|
||||
recheckAreaFeatures[layerId] = recheckAreaFeatures[layerId].intersect( featurePool->getLayer()->selectedFeatureIds() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,7 +257,7 @@ bool QgsGeometryChecker::fixError( QgsGeometryCheckError *error, int method, boo
|
||||
{
|
||||
for ( const QString &layerId : changes.keys() )
|
||||
{
|
||||
mFeaturePools[layerId]->getLayer()->triggerRepaint();
|
||||
mContext->featurePools[layerId]->getLayer()->triggerRepaint();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
typedef qint64 QgsFeatureId;
|
||||
typedef QSet<QgsFeatureId> QgsFeatureIds;
|
||||
class QgsFeaturePool;
|
||||
struct QgsGeometryCheckerContext;
|
||||
class QgsGeometryCheck;
|
||||
class QgsGeometryCheckError;
|
||||
class QgsMapLayer;
|
||||
@ -35,13 +35,14 @@ class QgsGeometryChecker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsGeometryChecker( const QList<QgsGeometryCheck *> &checks, const QMap<QString, QgsFeaturePool *> &featurePools );
|
||||
QgsGeometryChecker( const QList<QgsGeometryCheck *> &checks, QgsGeometryCheckerContext *context );
|
||||
~QgsGeometryChecker();
|
||||
QFuture<void> execute( int *totalSteps = nullptr );
|
||||
bool fixError( QgsGeometryCheckError *error, int method, bool triggerRepaint = false );
|
||||
const QList<QgsGeometryCheck *> getChecks() const { return mChecks; }
|
||||
QStringList getMessages() const { return mMessages; }
|
||||
void setMergeAttributeIndices( const QMap<QString, int> &mergeAttributeIndices ) { mMergeAttributeIndices = mergeAttributeIndices; }
|
||||
QgsGeometryCheckerContext *getContext() const { return mContext; }
|
||||
|
||||
signals:
|
||||
void errorAdded( QgsGeometryCheckError *error );
|
||||
@ -59,7 +60,7 @@ class QgsGeometryChecker : public QObject
|
||||
};
|
||||
|
||||
QList<QgsGeometryCheck *> mChecks;
|
||||
QMap<QString, QgsFeaturePool *> mFeaturePools;
|
||||
QgsGeometryCheckerContext *mContext;
|
||||
QList<QgsGeometryCheckError *> mCheckErrors;
|
||||
QStringList mMessages;
|
||||
QMutex mErrorListMutex;
|
||||
|
@ -50,13 +50,13 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometryAngleCheck>::checkApplicabil
|
||||
return ui.checkBoxAngle->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryAngleCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryAngleCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkAngle", ui.checkBoxAngle->isChecked() );
|
||||
QgsSettings().setValue( sSettingsGroup + "minimalAngle", ui.doubleSpinBoxAngle->value() );
|
||||
if ( ui.checkBoxAngle->isEnabled() && ui.checkBoxAngle->isChecked() )
|
||||
{
|
||||
return new QgsGeometryAngleCheck( featurePools, ui.doubleSpinBoxAngle->value() );
|
||||
return new QgsGeometryAngleCheck( context, ui.doubleSpinBoxAngle->value() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -80,13 +80,13 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometryAreaCheck>::checkApplicabili
|
||||
return ui.checkBoxArea->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryAreaCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryAreaCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkArea", ui.checkBoxArea->isChecked() );
|
||||
QgsSettings().setValue( sSettingsGroup + "minimalArea", ui.doubleSpinBoxArea->value() );
|
||||
if ( ui.checkBoxArea->isEnabled() && ui.checkBoxArea->isChecked() )
|
||||
{
|
||||
return new QgsGeometryAreaCheck( featurePools, ui.doubleSpinBoxArea->value() );
|
||||
return new QgsGeometryAreaCheck( context, ui.doubleSpinBoxArea->value() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -109,12 +109,12 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometryContainedCheck>::checkApplic
|
||||
return ui.checkBoxCovered->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryContainedCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryContainedCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkCovers", ui.checkBoxCovered->isChecked() );
|
||||
if ( ui.checkBoxCovered->isEnabled() && ui.checkBoxCovered->isChecked() )
|
||||
{
|
||||
return new QgsGeometryContainedCheck( featurePools );
|
||||
return new QgsGeometryContainedCheck( context );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -137,12 +137,12 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometryDegeneratePolygonCheck>::che
|
||||
return ui.checkBoxDegeneratePolygon->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryDegeneratePolygonCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryDegeneratePolygonCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkDegeneratePolygon", ui.checkBoxDegeneratePolygon->isChecked() );
|
||||
if ( ui.checkBoxDegeneratePolygon->isEnabled() && ui.checkBoxDegeneratePolygon->isChecked() )
|
||||
{
|
||||
return new QgsGeometryDegeneratePolygonCheck( featurePools );
|
||||
return new QgsGeometryDegeneratePolygonCheck( context );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -165,12 +165,12 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometryDuplicateCheck>::checkApplic
|
||||
return ui.checkBoxDuplicates->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryDuplicateCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryDuplicateCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkDuplicates", ui.checkBoxDuplicates->isChecked() );
|
||||
if ( ui.checkBoxDuplicates->isEnabled() && ui.checkBoxDuplicates->isChecked() )
|
||||
{
|
||||
return new QgsGeometryDuplicateCheck( featurePools );
|
||||
return new QgsGeometryDuplicateCheck( context );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -193,12 +193,12 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometryDuplicateNodesCheck>::checkA
|
||||
return ui.checkBoxDuplicateNodes->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryDuplicateNodesCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryDuplicateNodesCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkDuplicateNodes", ui.checkBoxDuplicateNodes->isChecked() );
|
||||
if ( ui.checkBoxDuplicateNodes->isEnabled() && ui.checkBoxDuplicateNodes->isChecked() )
|
||||
{
|
||||
return new QgsGeometryDuplicateNodesCheck( featurePools );
|
||||
return new QgsGeometryDuplicateNodesCheck( context );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -223,13 +223,13 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometryGapCheck>::checkApplicabilit
|
||||
return ui.checkBoxGaps->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryGapCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryGapCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkGaps", ui.checkBoxGaps->isChecked() );
|
||||
QgsSettings().setValue( sSettingsGroup + "maxGapArea", ui.doubleSpinBoxGapArea->value() );
|
||||
if ( ui.checkBoxGaps->isEnabled() && ui.checkBoxGaps->isChecked() )
|
||||
{
|
||||
return new QgsGeometryGapCheck( featurePools, ui.doubleSpinBoxGapArea->value() );
|
||||
return new QgsGeometryGapCheck( context, ui.doubleSpinBoxGapArea->value() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -252,12 +252,12 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometryHoleCheck>::checkApplicabili
|
||||
return ui.checkBoxNoHoles->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryHoleCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryHoleCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkHoles", ui.checkBoxNoHoles->isChecked() );
|
||||
if ( ui.checkBoxNoHoles->isEnabled() && ui.checkBoxNoHoles->isChecked() )
|
||||
{
|
||||
return new QgsGeometryHoleCheck( featurePools );
|
||||
return new QgsGeometryHoleCheck( context );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -279,12 +279,12 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometryMultipartCheck>::checkApplic
|
||||
return true;
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryMultipartCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryMultipartCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkMultipart", ui.checkBoxMultipart->isChecked() );
|
||||
if ( ui.checkBoxMultipart->isEnabled() && ui.checkBoxMultipart->isChecked() )
|
||||
{
|
||||
return new QgsGeometryMultipartCheck( featurePools );
|
||||
return new QgsGeometryMultipartCheck( context );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -309,13 +309,13 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometryOverlapCheck>::checkApplicab
|
||||
return ui.checkBoxOverlaps->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryOverlapCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryOverlapCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkOverlaps", ui.checkBoxOverlaps->isChecked() );
|
||||
QgsSettings().setValue( sSettingsGroup + "maxOverlapArea", ui.doubleSpinBoxOverlapArea->value() );
|
||||
if ( ui.checkBoxOverlaps->isEnabled() && ui.checkBoxOverlaps->isChecked() )
|
||||
{
|
||||
return new QgsGeometryOverlapCheck( featurePools, ui.doubleSpinBoxOverlapArea->value() );
|
||||
return new QgsGeometryOverlapCheck( context, ui.doubleSpinBoxOverlapArea->value() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -340,13 +340,13 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometrySegmentLengthCheck>::checkAp
|
||||
return ui.checkBoxSegmentLength->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometrySegmentLengthCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometrySegmentLengthCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkSegmentLength", ui.checkBoxSegmentLength->isChecked() );
|
||||
QgsSettings().setValue( sSettingsGroup + "minSegmentLength", ui.doubleSpinBoxSegmentLength->value() );
|
||||
if ( ui.checkBoxSegmentLength->isEnabled() && ui.checkBoxSegmentLength->isChecked() )
|
||||
{
|
||||
return new QgsGeometrySegmentLengthCheck( featurePools, ui.doubleSpinBoxSegmentLength->value() );
|
||||
return new QgsGeometrySegmentLengthCheck( context, ui.doubleSpinBoxSegmentLength->value() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -369,12 +369,12 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometrySelfContactCheck>::checkAppl
|
||||
return ui.checkBoxSelfContacts->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometrySelfContactCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometrySelfContactCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkSelfContacts", ui.checkBoxSelfContacts->isChecked() );
|
||||
if ( ui.checkBoxSelfContacts->isEnabled() && ui.checkBoxSelfContacts->isChecked() )
|
||||
{
|
||||
return new QgsGeometrySelfContactCheck( featurePools );
|
||||
return new QgsGeometrySelfContactCheck( context );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -397,12 +397,12 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometrySelfIntersectionCheck>::chec
|
||||
return ui.checkBoxSelfIntersections->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometrySelfIntersectionCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometrySelfIntersectionCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkSelfIntersections", ui.checkBoxSelfIntersections->isChecked() );
|
||||
if ( ui.checkBoxSelfIntersections->isEnabled() && ui.checkBoxSelfIntersections->isChecked() )
|
||||
{
|
||||
return new QgsGeometrySelfIntersectionCheck( featurePools );
|
||||
return new QgsGeometrySelfIntersectionCheck( context );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -429,7 +429,7 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometrySliverPolygonCheck>::checkAp
|
||||
return ui.checkBoxSliverPolygons->isEnabled();
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometrySliverPolygonCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometrySliverPolygonCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
double threshold = ui.doubleSpinBoxSliverThinness->value();
|
||||
double maxArea = ui.checkBoxSliverArea->isChecked() ? ui.doubleSpinBoxSliverArea->value() : 0.;
|
||||
@ -439,7 +439,7 @@ template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometrySliverPolygonCh
|
||||
QgsSettings().setValue( sSettingsGroup + "checkSliverPolygons", ui.checkBoxSliverPolygons->isChecked() );
|
||||
if ( ui.checkBoxSliverPolygons->isEnabled() && ui.checkBoxSliverPolygons->isChecked() )
|
||||
{
|
||||
return new QgsGeometrySliverPolygonCheck( featurePools, threshold, maxArea );
|
||||
return new QgsGeometrySliverPolygonCheck( context, threshold, maxArea );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -466,7 +466,7 @@ template<> bool QgsGeometryCheckFactoryT<QgsGeometryTypeCheck>::checkApplicabili
|
||||
return true;
|
||||
}
|
||||
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryTypeCheck>::createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryTypeCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
|
||||
{
|
||||
QgsSettings().setValue( sSettingsGroup + "checkTypePoint", ui.checkBoxPoint->isChecked() );
|
||||
QgsSettings().setValue( sSettingsGroup + "checkTypeMultipoint", ui.checkBoxMultipoint->isChecked() );
|
||||
@ -502,7 +502,7 @@ template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryTypeCheck>::cre
|
||||
}
|
||||
if ( allowedTypes != 0 )
|
||||
{
|
||||
return new QgsGeometryTypeCheck( featurePools, allowedTypes );
|
||||
return new QgsGeometryTypeCheck( context, allowedTypes );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "qgis.h"
|
||||
#include "ui_qgsgeometrycheckersetuptab.h"
|
||||
|
||||
class QgsFeaturePool;
|
||||
struct QgsGeometryCheckerContext;
|
||||
class QgsGeometryCheck;
|
||||
|
||||
class QgsGeometryCheckFactory
|
||||
@ -27,7 +27,7 @@ class QgsGeometryCheckFactory
|
||||
virtual ~QgsGeometryCheckFactory() = default;
|
||||
virtual void restorePrevious( Ui::QgsGeometryCheckerSetupTab & /*ui*/ ) const = 0;
|
||||
virtual bool checkApplicability( Ui::QgsGeometryCheckerSetupTab & /*ui*/, int /*nPoint*/, int /*nLineString*/, int /*nPolygon*/ ) const = 0;
|
||||
virtual QgsGeometryCheck *createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const = 0;
|
||||
virtual QgsGeometryCheck *createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const = 0;
|
||||
|
||||
protected:
|
||||
static QString sSettingsGroup;
|
||||
@ -38,7 +38,7 @@ class QgsGeometryCheckFactoryT : public QgsGeometryCheckFactory
|
||||
{
|
||||
void restorePrevious( Ui::QgsGeometryCheckerSetupTab & /*ui*/ ) const override;
|
||||
bool checkApplicability( Ui::QgsGeometryCheckerSetupTab &ui, int nPoint, int nLineString, int nPolygon ) const override;
|
||||
QgsGeometryCheck *createInstance( const QMap<QString, QgsFeaturePool *> &featurePools, const Ui::QgsGeometryCheckerSetupTab &ui ) const override;
|
||||
QgsGeometryCheck *createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const override;
|
||||
};
|
||||
|
||||
class QgsGeometryCheckFactoryRegistry
|
||||
|
@ -57,11 +57,11 @@ QgsGeometryCheckerDialog::~QgsGeometryCheckerDialog()
|
||||
s.setValue( QStringLiteral( "/Plugin-GeometryChecker/Window/geometry" ), saveGeometry() );
|
||||
}
|
||||
|
||||
void QgsGeometryCheckerDialog::onCheckerStarted( QgsGeometryChecker *checker, QMap<QString, QgsFeaturePool *> featurePools )
|
||||
void QgsGeometryCheckerDialog::onCheckerStarted( QgsGeometryChecker *checker )
|
||||
{
|
||||
delete mTabWidget->widget( 1 );
|
||||
mTabWidget->removeTab( 1 );
|
||||
mTabWidget->addTab( new QgsGeometryCheckerResultTab( mIface, checker, featurePools, mTabWidget ), tr( "Result" ) );
|
||||
mTabWidget->addTab( new QgsGeometryCheckerResultTab( mIface, checker, mTabWidget ), tr( "Result" ) );
|
||||
mTabWidget->setTabEnabled( 1, false );
|
||||
mButtonBox->button( QDialogButtonBox::Close )->setEnabled( false );
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ class QgsGeometryCheckerDialog : public QDialog
|
||||
void closeEvent( QCloseEvent *ev ) override;
|
||||
|
||||
private slots:
|
||||
void onCheckerStarted( QgsGeometryChecker *checker, QMap<QString, QgsFeaturePool *> featurePools );
|
||||
void onCheckerStarted( QgsGeometryChecker *checker );
|
||||
void onCheckerFinished( bool successful );
|
||||
void showHelp();
|
||||
};
|
||||
|
@ -15,14 +15,15 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsgeometrycheckerfixsummarydialog.h"
|
||||
#include "../qgsgeometrychecker.h"
|
||||
#include "../checks/qgsgeometrycheck.h"
|
||||
#include "../utils/qgsfeaturepool.h"
|
||||
#include "qgisinterface.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
|
||||
QgsGeometryCheckerFixSummaryDialog::QgsGeometryCheckerFixSummaryDialog( const QMap<QString, QgsFeaturePool *> &featurePools, const Statistics &stats, const QStringList &messages, QWidget *parent )
|
||||
QgsGeometryCheckerFixSummaryDialog::QgsGeometryCheckerFixSummaryDialog( const Statistics &stats, QgsGeometryChecker *checker, QWidget *parent )
|
||||
: QDialog( parent )
|
||||
, mFeaturePools( featurePools )
|
||||
, mChecker( checker )
|
||||
{
|
||||
ui.setupUi( this );
|
||||
|
||||
@ -53,20 +54,20 @@ QgsGeometryCheckerFixSummaryDialog::QgsGeometryCheckerFixSummaryDialog( const QM
|
||||
setupTable( ui.tableWidgetNotFixed );
|
||||
setupTable( ui.tableWidgetObsoleteErrors );
|
||||
|
||||
ui.plainTextEditMessages->setPlainText( messages.join( QStringLiteral( "\n" ) ) );
|
||||
ui.plainTextEditMessages->setPlainText( checker->getMessages().join( QStringLiteral( "\n" ) ) );
|
||||
|
||||
ui.groupBoxFixedErrors->setVisible( !stats.fixedErrors.isEmpty() );
|
||||
ui.groupBoxNewErrors->setVisible( !stats.newErrors.isEmpty() );
|
||||
ui.groupBoxNotFixed->setVisible( !stats.failedErrors.isEmpty() );
|
||||
ui.groupBoxObsoleteErrors->setVisible( !stats.obsoleteErrors.isEmpty() );
|
||||
ui.groupBoxMessages->setVisible( !messages.isEmpty() );
|
||||
ui.groupBoxMessages->setVisible( !checker->getMessages().isEmpty() );
|
||||
}
|
||||
|
||||
void QgsGeometryCheckerFixSummaryDialog::addError( QTableWidget *table, QgsGeometryCheckError *error )
|
||||
{
|
||||
int prec = 7 - std::floor( std::max( 0., std::log10( std::max( error->location().x(), error->location().y() ) ) ) );
|
||||
QString posStr = QStringLiteral( "%1, %2" ).arg( error->location().x(), 0, 'f', prec ).arg( error->location().y(), 0, 'f', prec );
|
||||
double layerToMap = 1. / mFeaturePools[error->layerId()]->getMapToLayerUnits();
|
||||
double layerToMap = 1. / mChecker->getContext()->featurePools[error->layerId()]->getMapToLayerUnits();
|
||||
QVariant value;
|
||||
if ( error->valueType() == QgsGeometryCheckError::ValueLength )
|
||||
{
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
class QgisInterface;
|
||||
class QgsGeometryCheckError;
|
||||
class QgsFeaturePool;
|
||||
class QgsGeometryChecker;
|
||||
|
||||
class QgsGeometryCheckerFixSummaryDialog : public QDialog
|
||||
{
|
||||
@ -41,14 +41,14 @@ class QgsGeometryCheckerFixSummaryDialog : public QDialog
|
||||
}
|
||||
};
|
||||
|
||||
QgsGeometryCheckerFixSummaryDialog( const QMap<QString, QgsFeaturePool *> &featurePools, const Statistics &stats, const QStringList &messages, QWidget *parent = nullptr );
|
||||
QgsGeometryCheckerFixSummaryDialog( const Statistics &stats, QgsGeometryChecker *checker, QWidget *parent = nullptr );
|
||||
|
||||
signals:
|
||||
void errorSelected( QgsGeometryCheckError *error );
|
||||
|
||||
private:
|
||||
Ui::QgsGeometryCheckerFixSummaryDialog ui;
|
||||
QMap<QString, QgsFeaturePool *> mFeaturePools;
|
||||
QgsGeometryChecker *mChecker;
|
||||
|
||||
void addError( QTableWidget *table, QgsGeometryCheckError *error );
|
||||
void setupTable( QTableWidget *table );
|
||||
|
@ -43,23 +43,22 @@
|
||||
|
||||
QString QgsGeometryCheckerResultTab::sSettingsGroup = QStringLiteral( "/geometry_checker/default_fix_methods/" );
|
||||
|
||||
QgsGeometryCheckerResultTab::QgsGeometryCheckerResultTab( QgisInterface *iface, QgsGeometryChecker *checker, const QMap<QString, QgsFeaturePool *> &featurePools, QTabWidget *tabWidget, QWidget *parent )
|
||||
QgsGeometryCheckerResultTab::QgsGeometryCheckerResultTab( QgisInterface *iface, QgsGeometryChecker *checker, QTabWidget *tabWidget, QWidget *parent )
|
||||
: QWidget( parent )
|
||||
, mTabWidget( tabWidget )
|
||||
, mIface( iface )
|
||||
, mChecker( checker )
|
||||
, mFeaturePools( featurePools )
|
||||
{
|
||||
ui.setupUi( this );
|
||||
mErrorCount = 0;
|
||||
mFixedCount = 0;
|
||||
mCloseable = true;
|
||||
|
||||
for ( const QString &layerId : mFeaturePools.keys() )
|
||||
for ( const QString &layerId : mChecker->getContext()->featurePools.keys() )
|
||||
{
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem( ui.treeWidgetMergeAttribute, QStringList() << layerId << "" );
|
||||
QComboBox *attribCombo = new QComboBox();
|
||||
QgsVectorLayer *layer = mFeaturePools[layerId]->getLayer();
|
||||
QgsVectorLayer *layer = mChecker->getContext()->featurePools[layerId]->getLayer();
|
||||
for ( int i = 0, n = layer->fields().count(); i < n; ++i )
|
||||
{
|
||||
attribCombo->addItem( layer->fields().at( i ).name() );
|
||||
@ -83,7 +82,7 @@ QgsGeometryCheckerResultTab::QgsGeometryCheckerResultTab( QgisInterface *iface,
|
||||
connect( ui.pushButtonExport, &QAbstractButton::clicked, this, &QgsGeometryCheckerResultTab::exportErrors );
|
||||
|
||||
bool allLayersEditable = true;
|
||||
for ( const QgsFeaturePool *featurePool : mFeaturePools.values() )
|
||||
for ( const QgsFeaturePool *featurePool : mChecker->getContext()->featurePools.values() )
|
||||
{
|
||||
if ( ( featurePool->getLayer()->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeGeometries ) == 0 )
|
||||
{
|
||||
@ -106,12 +105,7 @@ QgsGeometryCheckerResultTab::QgsGeometryCheckerResultTab( QgisInterface *iface,
|
||||
|
||||
QgsGeometryCheckerResultTab::~QgsGeometryCheckerResultTab()
|
||||
{
|
||||
for ( const QgsFeaturePool *featurePool : mFeaturePools.values() )
|
||||
{
|
||||
if ( featurePool->getLayer() )
|
||||
featurePool->getLayer()->setReadOnly( false );
|
||||
delete featurePool;
|
||||
}
|
||||
|
||||
delete mChecker;
|
||||
qDeleteAll( mCurrentRubberBands );
|
||||
}
|
||||
@ -143,7 +137,7 @@ void QgsGeometryCheckerResultTab::addError( QgsGeometryCheckError *error )
|
||||
int row = ui.tableWidgetErrors->rowCount();
|
||||
int prec = 7 - std::floor( std::max( 0., std::log10( std::max( error->location().x(), error->location().y() ) ) ) );
|
||||
QString posStr = QStringLiteral( "%1, %2" ).arg( error->location().x(), 0, 'f', prec ).arg( error->location().y(), 0, 'f', prec );
|
||||
double layerToMap = 1. / mFeaturePools[error->layerId()]->getMapToLayerUnits();
|
||||
double layerToMap = 1. / mChecker->getContext()->featurePools[error->layerId()]->getMapToLayerUnits();
|
||||
QVariant value;
|
||||
if ( error->valueType() == QgsGeometryCheckError::ValueLength )
|
||||
{
|
||||
@ -191,7 +185,7 @@ void QgsGeometryCheckerResultTab::updateError( QgsGeometryCheckError *error, boo
|
||||
int row = mErrorMap.value( error ).row();
|
||||
int prec = 7 - std::floor( std::max( 0., std::log10( std::max( error->location().x(), error->location().y() ) ) ) );
|
||||
QString posStr = QStringLiteral( "%1, %2" ).arg( error->location().x(), 0, 'f', prec ).arg( error->location().y(), 0, 'f', prec );
|
||||
double layerToMap = 1. / mFeaturePools[error->layerId()]->getMapToLayerUnits();
|
||||
double layerToMap = 1. / mChecker->getContext()->featurePools[error->layerId()]->getMapToLayerUnits();
|
||||
QVariant value;
|
||||
if ( error->valueType() == QgsGeometryCheckError::ValueLength )
|
||||
{
|
||||
@ -243,7 +237,7 @@ void QgsGeometryCheckerResultTab::updateError( QgsGeometryCheckError *error, boo
|
||||
void QgsGeometryCheckerResultTab::exportErrors()
|
||||
{
|
||||
QString initialdir;
|
||||
QDir dir = QFileInfo( mFeaturePools.first()->getLayer()->dataProvider()->dataSourceUri() ).dir();
|
||||
QDir dir = QFileInfo( mChecker->getContext()->featurePools.first()->getLayer()->dataProvider()->dataSourceUri() ).dir();
|
||||
if ( dir.exists() )
|
||||
{
|
||||
initialdir = dir.absolutePath();
|
||||
@ -295,7 +289,7 @@ bool QgsGeometryCheckerResultTab::exportErrorsDo( const QString &file )
|
||||
for ( int row = 0, nRows = ui.tableWidgetErrors->rowCount(); row < nRows; ++row )
|
||||
{
|
||||
QgsGeometryCheckError *error = ui.tableWidgetErrors->item( row, 0 )->data( Qt::UserRole ).value<QgsGeometryCheckError *>();
|
||||
QgsVectorLayer *srcLayer = mFeaturePools[error->layerId()]->getLayer();
|
||||
QgsVectorLayer *srcLayer = mChecker->getContext()->featurePools[error->layerId()]->getLayer();
|
||||
QgsFeature f( layer->fields() );
|
||||
f.setAttribute( fieldLayer, srcLayer->name() );
|
||||
f.setAttribute( fieldFeatureId, error->featureId() );
|
||||
@ -356,7 +350,7 @@ void QgsGeometryCheckerResultTab::highlightErrors( bool current )
|
||||
for ( QTableWidgetItem *item : items )
|
||||
{
|
||||
QgsGeometryCheckError *error = ui.tableWidgetErrors->item( item->row(), 0 )->data( Qt::UserRole ).value<QgsGeometryCheckError *>();
|
||||
QgsVectorLayer *layer = mFeaturePools[error->layerId()]->getLayer();
|
||||
QgsVectorLayer *layer = mChecker->getContext()->featurePools[error->layerId()]->getLayer();
|
||||
|
||||
QgsAbstractGeometry *geometry = error->geometry();
|
||||
if ( ui.checkBoxHighlight->isChecked() && geometry )
|
||||
@ -475,7 +469,7 @@ void QgsGeometryCheckerResultTab::openAttributeTable()
|
||||
{
|
||||
mAttribTableDialogs[layerId]->close();
|
||||
}
|
||||
mAttribTableDialogs[layerId] = mIface->showAttributeTable( mFeaturePools[layerId]->getLayer(), expr.join( QStringLiteral( " or " ) ) );
|
||||
mAttribTableDialogs[layerId] = mIface->showAttributeTable( mChecker->getContext()->featurePools[layerId]->getLayer(), expr.join( QStringLiteral( " or " ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -543,14 +537,14 @@ void QgsGeometryCheckerResultTab::fixErrors( bool prompt )
|
||||
ui.progressBarFixErrors->setVisible( false );
|
||||
unsetCursor();
|
||||
}
|
||||
for ( const QString &layerId : mFeaturePools.keys() )
|
||||
for ( const QString &layerId : mChecker->getContext()->featurePools.keys() )
|
||||
{
|
||||
mFeaturePools[layerId]->getLayer()->triggerRepaint();
|
||||
mChecker->getContext()->featurePools[layerId]->getLayer()->triggerRepaint();
|
||||
}
|
||||
|
||||
if ( mStatistics.itemCount() > 0 )
|
||||
{
|
||||
QgsGeometryCheckerFixSummaryDialog summarydialog( mFeaturePools, mStatistics, mChecker->getMessages(), mIface->mainWindow() );
|
||||
QgsGeometryCheckerFixSummaryDialog summarydialog( mStatistics, mChecker, mIface->mainWindow() );
|
||||
QEventLoop loop;
|
||||
connect( &summarydialog, &QgsGeometryCheckerFixSummaryDialog::errorSelected, this, &QgsGeometryCheckerResultTab::highlightError );
|
||||
connect( &summarydialog, &QDialog::finished, &loop, &QEventLoop::quit );
|
||||
@ -632,11 +626,11 @@ void QgsGeometryCheckerResultTab::storeDefaultResolutionMethod( int id ) const
|
||||
void QgsGeometryCheckerResultTab::checkRemovedLayer( const QStringList &ids )
|
||||
{
|
||||
bool requiredLayersRemoved = false;
|
||||
for ( const QString &id : mFeaturePools.keys() )
|
||||
for ( const QString &layerId : mChecker->getContext()->featurePools.keys() )
|
||||
{
|
||||
if ( ids.contains( id ) && isEnabled() )
|
||||
if ( ids.contains( layerId ) && isEnabled() )
|
||||
{
|
||||
mFeaturePools[id]->clearLayer();
|
||||
mChecker->getContext()->featurePools[layerId]->clearLayer();
|
||||
requiredLayersRemoved = true;
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class QgsGeometryCheckerResultTab : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsGeometryCheckerResultTab( QgisInterface *iface, QgsGeometryChecker *checker, const QMap<QString, QgsFeaturePool *> &featurePools, QTabWidget *tabWidget, QWidget *parent = nullptr );
|
||||
QgsGeometryCheckerResultTab( QgisInterface *iface, QgsGeometryChecker *checker, QTabWidget *tabWidget, QWidget *parent = nullptr );
|
||||
~QgsGeometryCheckerResultTab();
|
||||
void finalize();
|
||||
bool isCloseable() const { return mCloseable; }
|
||||
@ -44,7 +44,6 @@ class QgsGeometryCheckerResultTab : public QWidget
|
||||
Ui::QgsGeometryCheckerResultTab ui;
|
||||
QgisInterface *mIface = nullptr;
|
||||
QgsGeometryChecker *mChecker = nullptr;
|
||||
QMap<QString, QgsFeaturePool *> mFeaturePools;
|
||||
QList<QgsRubberBand *> mCurrentRubberBands;
|
||||
QMap<QgsGeometryCheckError *, QPersistentModelIndex> mErrorMap;
|
||||
QMap<QString, QPointer<QDialog>> mAttribTableDialogs;
|
||||
|
@ -69,8 +69,8 @@ QgsGeometryCheckerSetupTab::QgsGeometryCheckerSetupTab( QgisInterface *iface, QW
|
||||
connect( QgsProject::instance(), static_cast<void ( QgsProject::* )( const QStringList & )>( &QgsProject::layersWillBeRemoved ), this, &QgsGeometryCheckerSetupTab::updateLayers );
|
||||
connect( ui.radioButtonOutputNew, &QAbstractButton::toggled, ui.frameOutput, &QWidget::setEnabled );
|
||||
connect( ui.buttonGroupOutput, static_cast<void ( QButtonGroup::* )( int )>( &QButtonGroup::buttonClicked ), this, &QgsGeometryCheckerSetupTab::validateInput );
|
||||
connect( ui.pushButtonOutputBrowse, &QAbstractButton::clicked, this, &QgsGeometryCheckerSetupTab::selectOutputFile );
|
||||
connect( ui.lineEditOutput, &QLineEdit::textChanged, this, &QgsGeometryCheckerSetupTab::validateInput );
|
||||
connect( ui.pushButtonOutputDirectory, &QAbstractButton::clicked, this, &QgsGeometryCheckerSetupTab::selectOutputDirectory );
|
||||
connect( ui.lineEditOutputDirectory, &QLineEdit::textChanged, this, &QgsGeometryCheckerSetupTab::validateInput );
|
||||
connect( ui.checkBoxSliverPolygons, &QAbstractButton::toggled, ui.widgetSliverThreshold, &QWidget::setEnabled );
|
||||
connect( ui.checkBoxSliverArea, &QAbstractButton::toggled, ui.doubleSpinBoxSliverArea, &QWidget::setEnabled );
|
||||
|
||||
@ -153,6 +153,7 @@ QList<QgsVectorLayer *> QgsGeometryCheckerSetupTab::getSelectedLayers()
|
||||
|
||||
void QgsGeometryCheckerSetupTab::validateInput()
|
||||
{
|
||||
QStringList layerCrs = QStringList() << mIface->mapCanvas()->mapSettings().destinationCrs().authid();
|
||||
QList<QgsVectorLayer *> layers = getSelectedLayers();
|
||||
int nApplicable = 0;
|
||||
if ( !layers.isEmpty() )
|
||||
@ -175,17 +176,27 @@ void QgsGeometryCheckerSetupTab::validateInput()
|
||||
{
|
||||
++nPolygon;
|
||||
}
|
||||
layerCrs.append( layer->crs().authid() );
|
||||
}
|
||||
for ( const QgsGeometryCheckFactory *factory : QgsGeometryCheckFactoryRegistry::getCheckFactories() )
|
||||
{
|
||||
nApplicable += factory->checkApplicability( ui, nPoint, nLineString, nPolygon );
|
||||
}
|
||||
}
|
||||
QString prevCrs = ui.comboBoxTopologyCrs->currentText();
|
||||
ui.comboBoxTopologyCrs->clear();
|
||||
ui.comboBoxTopologyCrs->addItems( layerCrs );
|
||||
ui.comboBoxTopologyCrs->setCurrentIndex( ui.comboBoxTopologyCrs->findText( prevCrs ) );
|
||||
if ( ui.comboBoxTopologyCrs->currentIndex() == -1 )
|
||||
{
|
||||
ui.comboBoxTopologyCrs->setCurrentIndex( 0 );
|
||||
}
|
||||
|
||||
bool outputOk = ui.radioButtonOutputModifyInput->isChecked() || !ui.lineEditOutputDirectory->text().isEmpty();
|
||||
mRunButton->setEnabled( !layers.isEmpty() && nApplicable > 0 && outputOk );
|
||||
}
|
||||
|
||||
void QgsGeometryCheckerSetupTab::selectOutputFile()
|
||||
void QgsGeometryCheckerSetupTab::selectOutputDirectory()
|
||||
{
|
||||
QString filterString = QgsVectorFileWriter::filterForDriver( QStringLiteral( "GPKG" ) );
|
||||
QMap<QString, QString> filterFormatMap = QgsVectorFileWriter::supportedFiltersAndFormats();
|
||||
@ -397,19 +408,20 @@ void QgsGeometryCheckerSetupTab::runChecks()
|
||||
featurePools.insert( layer->id(), new QgsFeaturePool( layer, mapToLayerUnits, selectedOnly ) );
|
||||
}
|
||||
|
||||
QgsGeometryCheckerContext *context = new QgsGeometryCheckerContext( ui.spinBoxTolerance->value(), ui.comboBoxTopologyCrs->currentText(), featurePools );
|
||||
|
||||
QList<QgsGeometryCheck *> checks;
|
||||
for ( const QgsGeometryCheckFactory *factory : QgsGeometryCheckFactoryRegistry::getCheckFactories() )
|
||||
{
|
||||
QgsGeometryCheck *check = factory->createInstance( featurePools, ui );
|
||||
QgsGeometryCheck *check = factory->createInstance( context, ui );
|
||||
if ( check )
|
||||
{
|
||||
checks.append( check );
|
||||
}
|
||||
}
|
||||
QgsGeometryCheckPrecision::setPrecision( ui.spinBoxTolerance->value() );
|
||||
QgsGeometryChecker *checker = new QgsGeometryChecker( checks, featurePools );
|
||||
QgsGeometryChecker *checker = new QgsGeometryChecker( checks, context );
|
||||
|
||||
emit checkerStarted( checker, featurePools );
|
||||
emit checkerStarted( checker );
|
||||
|
||||
// Add result layer (do this after checkerStarted, otherwise warning about removing of result layer may appear)
|
||||
for ( QgsVectorLayer *layer : processLayers )
|
||||
|
@ -35,7 +35,7 @@ class QgsGeometryCheckerSetupTab : public QWidget
|
||||
~QgsGeometryCheckerSetupTab();
|
||||
|
||||
signals:
|
||||
void checkerStarted( QgsGeometryChecker *checker, QMap<QString, QgsFeaturePool *> featurePools );
|
||||
void checkerStarted( QgsGeometryChecker *checker );
|
||||
void checkerFinished( bool );
|
||||
|
||||
private:
|
||||
@ -51,7 +51,7 @@ class QgsGeometryCheckerSetupTab : public QWidget
|
||||
void runChecks();
|
||||
void updateLayers();
|
||||
void validateInput();
|
||||
void selectOutputFile();
|
||||
void selectOutputDirectory();
|
||||
void showCancelFeedback();
|
||||
};
|
||||
|
||||
|
@ -41,9 +41,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-46</y>
|
||||
<y>-106</y>
|
||||
<width>626</width>
|
||||
<height>804</height>
|
||||
<height>832</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
@ -549,10 +549,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_10">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
@ -565,14 +562,7 @@
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelTolerance">
|
||||
<property name="text">
|
||||
<string>Tolerance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxTolerance">
|
||||
<property name="prefix">
|
||||
<string notr="true">1E-</string>
|
||||
@ -588,6 +578,23 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelTolerance">
|
||||
<property name="text">
|
||||
<string>Tolerance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelTopologyCrs">
|
||||
<property name="text">
|
||||
<string>CRS for topology checks:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboBoxTopologyCrs"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
Loading…
x
Reference in New Issue
Block a user