Skip to content
Permalink
Browse files

[Geometry checker] Extend duplicate check to also handle points

  • Loading branch information
manisandro committed Jun 27, 2017
1 parent ee47d42 commit b9966aa362359635d218d5773e94156cb23326da
@@ -26,37 +26,49 @@ void QgsGeometryDuplicateCheck::collectErrors( QList<QgsGeometryCheckError *> &e
QList<QString> layerIds = featureIds.keys();
for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeatureA : layerFeaturesA )
{
// Don't check already checked layers
layerIds.removeOne( layerFeatureA.layer().id() );

QgsRectangle bboxA = layerFeatureA.geometry()->boundingBox();
QSharedPointer<QgsGeometryEngine> geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureA.geometry(), mContext->tolerance );
QMap<QString, QList<QgsFeatureId>> duplicates;

QgsGeometryCheckerUtils::LayerFeatures layerFeaturesB( mContext->featurePools, QList<QString>() << layerFeatureA.layer().id() << layerIds, bboxA, mCompatibleGeometryTypes );
QgsWkbTypes::GeometryType geomType = layerFeatureA.feature().geometry().type();
QgsGeometryCheckerUtils::LayerFeatures layerFeaturesB( mContext->featurePools, layerIds, bboxA, {geomType} );
for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeatureB : layerFeaturesB )
{
// > : only report overlaps within same layer once
if ( layerFeatureA.layer().id() == layerFeatureB.layer().id() && layerFeatureB.feature().id() >= layerFeatureA.feature().id() )
{
continue;
}
QString errMsg;
QgsAbstractGeometry *diffGeom = geomEngineA->symDifference( *layerFeatureB.geometry(), &errMsg );
if ( diffGeom && diffGeom->area() < mContext->tolerance )
if ( geomType == QgsWkbTypes::PointGeometry )
{
duplicates[layerFeatureB.layer().id()].append( layerFeatureB.feature().id() );
const QgsPoint *p = dynamic_cast<const QgsPoint *>( layerFeatureA.geometry() );
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 ( !diffGeom )
else if ( geomType == QgsWkbTypes::PolygonGeometry )
{
messages.append( tr( "Duplicate check between features %1 and %2: %3" ).arg( layerFeatureA.id() ).arg( layerFeatureB.id() ).arg( errMsg ) );
QString 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() )
{
errors.append( new QgsGeometryDuplicateCheckError( this, layerFeatureA, layerFeatureA.geometry()->centroid(), duplicates ) );
}
// Don't check already checked layers
layerIds.removeOne( layerFeatureA.layer().id() );
}
}

@@ -76,6 +88,8 @@ void QgsGeometryDuplicateCheck::fixError( QgsGeometryCheckError *error, int meth
}
else if ( method == RemoveDuplicates )
{
QgsWkbTypes::GeometryType geomType = featureA.geometry().type();

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

@@ -91,14 +105,27 @@ void QgsGeometryDuplicateCheck::fixError( QgsGeometryCheckError *error, int meth
continue;
}
QgsGeometryCheckerUtils::LayerFeature layerFeatureB( featurePoolB, featureB, true );
QgsAbstractGeometry *diffGeom = geomEngineA->symDifference( *layerFeatureB.geometry() );
if ( diffGeom && diffGeom->area() < mContext->tolerance )
if ( geomType == QgsWkbTypes::PointGeometry )
{
featurePoolB->deleteFeature( featureB );
changes[layerIdB][idB].append( Change( ChangeFeature, ChangeRemoved ) );
const QgsPoint *p = dynamic_cast<const QgsPoint *>( layerFeatureA.geometry() );
const QgsPoint *q = dynamic_cast<const QgsPoint *>( layerFeatureB.geometry() );
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 );
@@ -65,7 +65,7 @@ class QgsGeometryDuplicateCheck : public QgsGeometryCheck

public:
explicit QgsGeometryDuplicateCheck( QgsGeometryCheckerContext *context )
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PolygonGeometry}, context ) {}
: QgsGeometryCheck( FeatureCheck, {QgsWkbTypes::PointGeometry, 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;
@@ -189,9 +189,9 @@ template<> void QgsGeometryCheckFactoryT<QgsGeometryDuplicateCheck>::restorePrev
ui.checkBoxDuplicates->setChecked( QgsSettings().value( sSettingsGroup + "checkDuplicates" ).toBool() );
}

template<> bool QgsGeometryCheckFactoryT<QgsGeometryDuplicateCheck>::checkApplicability( Ui::QgsGeometryCheckerSetupTab &ui, int /*nPoint*/, int /*nLineString*/, int nPolygon ) const
template<> bool QgsGeometryCheckFactoryT<QgsGeometryDuplicateCheck>::checkApplicability( Ui::QgsGeometryCheckerSetupTab &ui, int nPoint, int /*nLineString*/, int nPolygon ) const
{
ui.checkBoxDuplicates->setEnabled( nPolygon > 0 );
ui.checkBoxDuplicates->setEnabled( nPoint > 0 || nPolygon > 0 );
return ui.checkBoxDuplicates->isEnabled();
}

0 comments on commit b9966aa

Please sign in to comment.
You can’t perform that action at this time.