Skip to content

Commit

Permalink
[Geometry checker] Use symDifference for all geometry types to detect…
Browse files Browse the repository at this point in the history
… duplicates
  • Loading branch information
manisandro committed Oct 23, 2017
1 parent 816273e commit 183671f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 40 deletions.
56 changes: 17 additions & 39 deletions src/analysis/vector/geometry_checker/qgsgeometryduplicatecheck.cpp
Expand Up @@ -48,6 +48,11 @@ void QgsGeometryDuplicateCheck::collectErrors( QList<QgsGeometryCheckError *> &e


QgsRectangle bboxA = layerFeatureA.geometry()->boundingBox(); QgsRectangle bboxA = layerFeatureA.geometry()->boundingBox();
QSharedPointer<QgsGeometryEngine> geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureA.geometry(), mContext->tolerance ); QSharedPointer<QgsGeometryEngine> geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureA.geometry(), mContext->tolerance );
if ( !geomEngineA->isValid() )
{
messages.append( tr( "Duplicate check failed for %1: the geometry is invalid" ).arg( layerFeatureA.id() ) );
continue;
}
QMap<QString, QList<QgsFeatureId>> duplicates; QMap<QString, QList<QgsFeatureId>> duplicates;


QgsWkbTypes::GeometryType geomType = layerFeatureA.feature().geometry().type(); QgsWkbTypes::GeometryType geomType = layerFeatureA.feature().geometry().type();
Expand All @@ -59,29 +64,17 @@ void QgsGeometryDuplicateCheck::collectErrors( QList<QgsGeometryCheckError *> &e
{ {
continue; continue;
} }
if ( geomType == QgsWkbTypes::PointGeometry ) QString errMsg;
QgsAbstractGeometry *diffGeom = geomEngineA->symDifference( layerFeatureB.geometry(), &errMsg );
if ( errMsg.isEmpty() && diffGeom && diffGeom->isEmpty() )
{ {
const QgsPoint *p = dynamic_cast<const QgsPoint *>( layerFeatureA.geometry() ); duplicates[layerFeatureB.layer().id()].append( layerFeatureB.feature().id() );
const QgsPoint *q = dynamic_cast<const QgsPoint *>( layerFeatureB.geometry() );
if ( p && q && p->distanceSquared( *q ) < mContext->tolerance * mContext->tolerance )
{
duplicates[layerFeatureB.layer().id()].append( layerFeatureB.feature().id() );
}
} }
else if ( geomType == QgsWkbTypes::PolygonGeometry ) else if ( !errMsg.isEmpty() )
{ {
QString errMsg; messages.append( tr( "Duplicate check failed for %1, %2: %3" ).arg( layerFeatureA.id() ).arg( layerFeatureB.id() ).arg( errMsg ) );
QgsAbstractGeometry *diffGeom = geomEngineA->symDifference( layerFeatureB.geometry(), &errMsg );
if ( diffGeom && diffGeom->area() < mContext->tolerance )
{
duplicates[layerFeatureB.layer().id()].append( layerFeatureB.feature().id() );
}
else if ( !diffGeom )
{
messages.append( tr( "Duplicate check between features %1 and %2: %3" ).arg( layerFeatureA.id() ).arg( layerFeatureB.id() ).arg( errMsg ) );
}
delete diffGeom;
} }
delete diffGeom;
} }
if ( !duplicates.isEmpty() ) if ( !duplicates.isEmpty() )
{ {
Expand All @@ -106,8 +99,6 @@ void QgsGeometryDuplicateCheck::fixError( QgsGeometryCheckError *error, int meth
} }
else if ( method == RemoveDuplicates ) else if ( method == RemoveDuplicates )
{ {
QgsWkbTypes::GeometryType geomType = featureA.geometry().type();

QgsGeometryCheckerUtils::LayerFeature layerFeatureA( featurePoolA, featureA, true ); QgsGeometryCheckerUtils::LayerFeature layerFeatureA( featurePoolA, featureA, true );
QSharedPointer<QgsGeometryEngine> geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureA.geometry(), mContext->tolerance ); QSharedPointer<QgsGeometryEngine> geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureA.geometry(), mContext->tolerance );


Expand All @@ -123,27 +114,14 @@ void QgsGeometryDuplicateCheck::fixError( QgsGeometryCheckError *error, int meth
continue; continue;
} }
QgsGeometryCheckerUtils::LayerFeature layerFeatureB( featurePoolB, featureB, true ); QgsGeometryCheckerUtils::LayerFeature layerFeatureB( featurePoolB, featureB, true );
if ( geomType == QgsWkbTypes::PointGeometry ) QgsAbstractGeometry *diffGeom = geomEngineA->symDifference( layerFeatureB.geometry() );
if ( diffGeom && diffGeom->isEmpty() )
{ {
const QgsPoint *p = dynamic_cast<const QgsPoint *>( layerFeatureA.geometry() ); featurePoolB->deleteFeature( featureB );
const QgsPoint *q = dynamic_cast<const QgsPoint *>( layerFeatureB.geometry() ); changes[layerIdB][idB].append( Change( ChangeFeature, ChangeRemoved ) );
if ( p && q && p->distanceSquared( *q ) < mContext->tolerance * mContext->tolerance )
{
featurePoolB->deleteFeature( featureB );
changes[layerIdB][idB].append( Change( ChangeFeature, ChangeRemoved ) );
}
} }
else if ( geomType == QgsWkbTypes::PolygonGeometry )
{
QgsAbstractGeometry *diffGeom = geomEngineA->symDifference( layerFeatureB.geometry() );
if ( diffGeom && diffGeom->area() < mContext->tolerance )
{
featurePoolB->deleteFeature( featureB );
changes[layerIdB][idB].append( Change( ChangeFeature, ChangeRemoved ) );
}


delete diffGeom; delete diffGeom;
}
} }
} }
error->setFixed( method ); error->setFixed( method );
Expand Down
Expand Up @@ -51,7 +51,7 @@ class ANALYSIS_EXPORT QgsGeometryDuplicateCheck : public QgsGeometryCheck


public: public:
explicit QgsGeometryDuplicateCheck( QgsGeometryCheckerContext *context ) explicit QgsGeometryDuplicateCheck( QgsGeometryCheckerContext *context )
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PointGeometry, QgsWkbTypes::PolygonGeometry}, 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 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; void fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
QStringList getResolutionMethods() const override; QStringList getResolutionMethods() const override;
Expand Down

0 comments on commit 183671f

Please sign in to comment.