[geometry fixer] fix overlap check tolerance error

We were not using the same tolerance when collecting
the error than when fixing the error.
This commit is contained in:
olivierdalang 2020-10-15 14:47:38 +02:00
parent 279b0510d5
commit 4d730eb845
7 changed files with 52 additions and 1 deletions

View File

@ -112,7 +112,7 @@ void QgsGeometryOverlapCheck::fixError( const QMap<QString, QgsFeaturePool *> &f
QgsGeometryCheckerUtils::LayerFeature layerFeatureA( featurePoolA, featureA, mContext, true );
QgsGeometryCheckerUtils::LayerFeature layerFeatureB( featurePoolB, featureB, mContext, true );
const QgsGeometry geometryA = layerFeatureA.geometry();
std::unique_ptr< QgsGeometryEngine > geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( geometryA.constGet(), mContext->reducedTolerance );
std::unique_ptr< QgsGeometryEngine > geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( geometryA.constGet(), mContext->tolerance );
geomEngineA->prepareGeometry();
const QgsGeometry geometryB = layerFeatureB.geometry();

View File

@ -99,6 +99,7 @@ class TestQgsGeometryChecks: public QObject
void testSelfIntersectionCheck();
void testSliverPolygonCheck();
void testGapCheckPointInPoly();
void testOverlapCheckToleranceBug();
};
void TestQgsGeometryChecks::initTestCase()
@ -1207,6 +1208,54 @@ void TestQgsGeometryChecks::testGapCheckPointInPoly()
cleanupTestContext( testContext );
}
void TestQgsGeometryChecks::testOverlapCheckToleranceBug()
{
// The overlap (intersection) was computed with a different tolerance when collecting errors
// than when fixing them, leading to failures to fix the issue esp. with big coordinates.
QTemporaryDir dir;
QMap<QString, QString> layers;
layers.insert( "overlap_layer_tolerance_bug.shp", "" );
auto testContext = createTestContext( dir, layers );
// Test detection
QList<QgsGeometryCheckError *> checkErrors;
QStringList messages;
QVariantMap configuration;
configuration.insert( "gapThreshold", 1000.0 );
QgsProject::instance()->setCrs( QgsCoordinateReferenceSystem::fromEpsgId( 2056 ) );
QgsGeometryOverlapCheck check( testContext.first, configuration );
QgsFeedback feedback;
check.collectErrors( testContext.second, checkErrors, messages, &feedback );
listErrors( checkErrors, messages );
QCOMPARE( checkErrors.size(), 1 );
QgsGeometryCheckError *error = checkErrors.first();
// Test fixes
QgsFeature f;
testContext.second[layers["overlap_layer_tolerance_bug.shp"]]->getFeature( 0, f );
double areaOld = f.geometry().area();
QCOMPARE( areaOld, 10442.710061549426 );
QgsGeometryCheck::Changes changes;
QMap<QString, int> mergeAttrs;
error->check()->fixError( testContext.second, error, QgsGeometryOverlapCheck::Subtract, mergeAttrs, changes );
// Ensure it worked
QCOMPARE( error->status(), QgsGeometryCheckError::StatusFixed );
// Ensure it actually worked
testContext.second[layers["overlap_layer_tolerance_bug.shp"]]->getFeature( 0, f );
QVERIFY( f.geometry().area() < areaOld );
cleanupTestContext( testContext );
}
///////////////////////////////////////////////////////////////////////////////
double TestQgsGeometryChecks::layerToMapUnits( const QgsMapLayer *layer, const QgsCoordinateReferenceSystem &mapCrs ) const

View File

@ -0,0 +1 @@
UTF-8

Binary file not shown.

View File

@ -0,0 +1 @@
PROJCS["CH1903+_LV95",GEOGCS["GCS_CH1903+",DATUM["D_CH1903+",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],PARAMETER["False_Easting",2600000.0],PARAMETER["False_Northing",1200000.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Azimuth",90.0],PARAMETER["Longitude_Of_Center",7.43958333333333],PARAMETER["Latitude_Of_Center",46.9524055555556],UNIT["Meter",1.0]]

Binary file not shown.

Binary file not shown.