From 1279c76b8bc86e8cec65cd5d815b3e5a26e3bb31 Mon Sep 17 00:00:00 2001 From: Marco Hugentobler Date: Thu, 3 Dec 2020 11:25:22 +0100 Subject: [PATCH] Handle geometrycollections also in difference results --- src/analysis/processing/qgsoverlayutils.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/analysis/processing/qgsoverlayutils.cpp b/src/analysis/processing/qgsoverlayutils.cpp index 4a9667368f3a..c829aeb08508 100644 --- a/src/analysis/processing/qgsoverlayutils.cpp +++ b/src/analysis/processing/qgsoverlayutils.cpp @@ -54,7 +54,7 @@ bool QgsOverlayUtils::sanitizeIntersectionResult( QgsGeometry &geom, QgsWkbTypes //! Makes sure that what came out from difference of two geometries is good to be used in the output -static bool sanitizeDifferenceResult( QgsGeometry &geom ) +static bool sanitizeDifferenceResult( QgsGeometry &geom, QgsWkbTypes::GeometryType geometryType ) { if ( geom.isNull() ) { @@ -62,6 +62,13 @@ static bool sanitizeDifferenceResult( QgsGeometry &geom ) throw QgsProcessingException( QStringLiteral( "%1\n\n%2" ).arg( QObject::tr( "GEOS geoprocessing error: difference failed." ), geom.lastError() ) ); } + //fix geometry collections + if ( QgsWkbTypes::flatType( geom.wkbType() ) == QgsWkbTypes::GeometryCollection ) + { + // try to filter out irrelevant parts with different geometry type than what we want + geom.convertGeometryCollectionToSubclass( geometryType ); + } + // if geomB covers the whole source geometry, we get an empty geometry collection if ( geom.isEmpty() ) return false; @@ -76,6 +83,7 @@ static bool sanitizeDifferenceResult( QgsGeometry &geom ) void QgsOverlayUtils::difference( const QgsFeatureSource &sourceA, const QgsFeatureSource &sourceB, QgsFeatureSink &sink, QgsProcessingContext &context, QgsProcessingFeedback *feedback, int &count, int totalCount, QgsOverlayUtils::DifferenceOutput outputAttrs ) { + QgsWkbTypes::GeometryType geometryType = QgsWkbTypes::geometryType( QgsWkbTypes::multiType( sourceA.wkbType() ) ); QgsFeatureRequest requestB; requestB.setNoAttributes(); if ( outputAttrs != OutputBA ) @@ -147,7 +155,7 @@ void QgsOverlayUtils::difference( const QgsFeatureSource &sourceA, const QgsFeat geom = geom.difference( geomB ); } - if ( !sanitizeDifferenceResult( geom ) ) + if ( !sanitizeDifferenceResult( geom, geometryType ) ) continue; const QgsAttributes attrsA( featA.attributes() ); @@ -369,7 +377,7 @@ void QgsOverlayUtils::resolveOverlaps( const QgsFeatureSource &source, QgsFeatur index.deleteFeature( f ); geometries.remove( fid1 ); - if ( sanitizeDifferenceResult( g12 ) ) + if ( sanitizeDifferenceResult( g12, geometryType ) ) { geometries.insert( fid1, g12 ); @@ -390,7 +398,7 @@ void QgsOverlayUtils::resolveOverlaps( const QgsFeatureSource &source, QgsFeatur geometries.remove( fid2 ); - if ( sanitizeDifferenceResult( g21 ) ) + if ( sanitizeDifferenceResult( g21, geometryType ) ) { geometries.insert( fid2, g21 );