[Geometry checker] Make contained check work with all geometry types

This commit is contained in:
Sandro Mani 2017-09-27 18:18:23 +02:00
parent 44ce916656
commit 54019e1111
2 changed files with 19 additions and 6 deletions

View File

@ -26,6 +26,11 @@ void QgsGeometryContainedCheck::collectErrors( QList<QgsGeometryCheckError *> &e
{
QgsRectangle bboxA = layerFeatureA.geometry()->boundingBox();
QSharedPointer<QgsGeometryEngine> geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureA.geometry(), mContext->tolerance );
if ( !geomEngineA->isValid() )
{
messages.append( tr( "Contained check failed for (%1): the geometry is invalid" ).arg( layerFeatureA.id() ) );
continue;
}
QgsGeometryCheckerUtils::LayerFeatures layerFeaturesB( mContext->featurePools, featureIds.keys(), bboxA, mCompatibleGeometryTypes );
for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeatureB : layerFeaturesB )
{
@ -33,14 +38,21 @@ void QgsGeometryContainedCheck::collectErrors( QList<QgsGeometryCheckError *> &e
{
continue;
}
QString errMsg;
if ( geomEngineA->within( layerFeatureB.geometry(), &errMsg ) )
QSharedPointer<QgsGeometryEngine> geomEngineB = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureB.geometry(), mContext->tolerance );
if ( !geomEngineB->isValid() )
{
errors.append( new QgsGeometryContainedCheckError( this, layerFeatureA, layerFeatureA.geometry()->centroid(), layerFeatureB ) );
messages.append( tr( "Contained check failed for (%1): the geometry is invalid" ).arg( layerFeatureB.id() ) );
continue;
}
QString errMsg;
// If A contains B and B contains A, it would mean that the geometries are identical, which is covered by the duplicate check
if ( geomEngineA->contains( layerFeatureB.geometry(), &errMsg ) && !geomEngineB->contains( layerFeatureA.geometry(), &errMsg ) && errMsg.isEmpty() )
{
errors.append( new QgsGeometryContainedCheckError( this, layerFeatureB, layerFeatureB.geometry()->centroid(), layerFeatureA ) );
}
else if ( !errMsg.isEmpty() )
{
messages.append( tr( "Feature %1 within feature %2: %3" ).arg( layerFeatureA.id() ).arg( layerFeatureB.id() ).arg( errMsg ) );
messages.append( tr( "Contained check failed for (%1, %2): %3" ).arg( layerFeatureB.id() ).arg( layerFeatureA.id() ).arg( errMsg ) );
}
}
}
@ -66,8 +78,9 @@ void QgsGeometryContainedCheck::fixError( QgsGeometryCheckError *error, int meth
QgsGeometryCheckerUtils::LayerFeature layerFeatureB( featurePoolB, featureB, true );
QSharedPointer<QgsGeometryEngine> geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureA.geometry(), mContext->tolerance );
QSharedPointer<QgsGeometryEngine> geomEngineB = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureB.geometry(), mContext->tolerance );
if ( !geomEngineA->within( layerFeatureB.geometry() ) )
if ( !( geomEngineA->contains( layerFeatureB.geometry() ) && !geomEngineB->contains( layerFeatureA.geometry() ) ) )
{
error->setObsolete();
return;

View File

@ -50,7 +50,7 @@ class ANALYSIS_EXPORT QgsGeometryContainedCheck : public QgsGeometryCheck
public:
explicit QgsGeometryContainedCheck( QgsGeometryCheckerContext *context )
: QgsGeometryCheck( FeatureCheck, {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 fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
QStringList getResolutionMethods() const override;