From 1dcd175a3cb1dd9f90349e3d486096875da1e45e Mon Sep 17 00:00:00 2001 From: Jean Felder Date: Fri, 25 Oct 2024 13:34:28 +0200 Subject: [PATCH] qgsvectorlayerprofilegenerator: Add support for custom tolerance --- .../vector/qgsvectorlayerprofilegenerator.cpp | 23 ++++++++++++------- .../vector/qgsvectorlayerprofilegenerator.h | 4 ++++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/core/vector/qgsvectorlayerprofilegenerator.cpp b/src/core/vector/qgsvectorlayerprofilegenerator.cpp index d7971b0205ce5..2c7aac503a5f9 100644 --- a/src/core/vector/qgsvectorlayerprofilegenerator.cpp +++ b/src/core/vector/qgsvectorlayerprofilegenerator.cpp @@ -687,6 +687,8 @@ QgsVectorLayerProfileGenerator::QgsVectorLayerProfileGenerator( QgsVectorLayer * , mBinding( qgis::down_cast< QgsVectorLayerElevationProperties * >( layer->elevationProperties() )->binding() ) , mExtrusionEnabled( qgis::down_cast< QgsVectorLayerElevationProperties * >( layer->elevationProperties() )->extrusionEnabled() ) , mExtrusionHeight( qgis::down_cast< QgsVectorLayerElevationProperties * >( layer->elevationProperties() )->extrusionHeight() ) + , mCustomToleranceEnabled( qgis::down_cast< QgsVectorLayerElevationProperties * >( layer->elevationProperties() )->customToleranceEnabled() ) + , mCustomTolerance( qgis::down_cast< QgsVectorLayerElevationProperties * >( layer->elevationProperties() )->customTolerance() ) , mExpressionContext( request.expressionContext() ) , mFields( layer->fields() ) , mDataDefinedProperties( layer->elevationProperties()->dataDefinedProperties() ) @@ -818,13 +820,13 @@ bool QgsVectorLayerProfileGenerator::generateProfileInner( const QgsProfileGener mProfileCurveEngine.reset( new QgsGeos( mProfileCurve.get() ) ); mProfileCurveEngine->prepareGeometry(); - if ( mTolerance == 0.0 ) // geos does not handle very well buffer with 0 size + if ( tolerance() == 0.0 ) // geos does not handle very well buffer with 0 size { mProfileBufferedCurve = std::unique_ptr( mProfileCurve->clone() ); } else { - mProfileBufferedCurve = std::unique_ptr( mProfileCurveEngine->buffer( mTolerance, 8, Qgis::EndCapStyle::Flat, Qgis::JoinStyle::Round, 2 ) ); + mProfileBufferedCurve = std::unique_ptr( mProfileCurveEngine->buffer( tolerance(), 8, Qgis::EndCapStyle::Flat, Qgis::JoinStyle::Round, 2 ) ); } mProfileBufferedCurveEngine.reset( new QgsGeos( mProfileBufferedCurve.get() ) ); @@ -875,7 +877,7 @@ bool QgsVectorLayerProfileGenerator::generateProfileForPoints() // get features from layer QgsFeatureRequest request; request.setCoordinateTransform( QgsCoordinateTransform( mSourceCrs, mTargetCrs, mTransformContext ) ); - request.setDistanceWithin( QgsGeometry( mProfileCurve->clone() ), mTolerance ); + request.setDistanceWithin( QgsGeometry( mProfileCurve->clone() ), tolerance() ); request.setSubsetOfAttributes( mDataDefinedProperties.referencedFields( mExpressionContext ), mFields ); request.setFeedback( mFeedback.get() ); @@ -1038,9 +1040,9 @@ bool QgsVectorLayerProfileGenerator::generateProfileForLines() // get features from layer QgsFeatureRequest request; request.setDestinationCrs( mTargetCrs, mTransformContext ); - if ( mTolerance > 0 ) + if ( tolerance() > 0 ) { - request.setDistanceWithin( QgsGeometry( mProfileCurve->clone() ), mTolerance ); + request.setDistanceWithin( QgsGeometry( mProfileCurve->clone() ), tolerance() ); } else { @@ -1330,9 +1332,9 @@ bool QgsVectorLayerProfileGenerator::generateProfileForPolygons() // get features from layer QgsFeatureRequest request; request.setDestinationCrs( mTargetCrs, mTransformContext ); - if ( mTolerance > 0 ) + if ( tolerance() > 0 ) { - request.setDistanceWithin( QgsGeometry( mProfileCurve->clone() ), mTolerance ); + request.setDistanceWithin( QgsGeometry( mProfileCurve->clone() ), tolerance() ); } else { @@ -1403,7 +1405,7 @@ bool QgsVectorLayerProfileGenerator::generateProfileForPolygons() if ( mFeedback->isCanceled() ) return; - if ( mTolerance > 0.0 ) // if the tolerance is not 0.0 we will have a polygon / polygon intersection, we do not need tessellation + if ( tolerance() > 0.0 ) // if the tolerance is not 0.0 we will have a polygon / polygon intersection, we do not need tessellation { QString error; if ( mProfileBufferedCurveEngine->intersects( clampedPolygon.get(), &error ) ) @@ -1621,6 +1623,11 @@ bool QgsVectorLayerProfileGenerator::generateProfileForPolygons() return true; } +double QgsVectorLayerProfileGenerator::tolerance() const +{ + return mCustomToleranceEnabled ? mCustomTolerance : mTolerance; +} + double QgsVectorLayerProfileGenerator::terrainHeight( double x, double y ) const { if ( !mTerrainProvider ) diff --git a/src/core/vector/qgsvectorlayerprofilegenerator.h b/src/core/vector/qgsvectorlayerprofilegenerator.h index 021f210e154e7..e971038937f52 100644 --- a/src/core/vector/qgsvectorlayerprofilegenerator.h +++ b/src/core/vector/qgsvectorlayerprofilegenerator.h @@ -136,6 +136,8 @@ class CORE_EXPORT QgsVectorLayerProfileGenerator : public QgsAbstractProfileSurf void processTriangleIntersectForLine( const QgsPolygon *triangle, const QgsLineString *intersect, QVector< QgsGeometry > &transformedParts, QVector< QgsGeometry > &crossSectionParts ); void processTriangleIntersectForPolygon( const QgsPolygon *triangle, const QgsPolygon *intersectionPolygon, QVector< QgsGeometry > &transformedParts, QVector< QgsGeometry > &crossSectionParts ); + double tolerance() const; + double terrainHeight( double x, double y ) const; double featureZToHeight( double x, double y, double z, double offset ) const; @@ -171,6 +173,8 @@ class CORE_EXPORT QgsVectorLayerProfileGenerator : public QgsAbstractProfileSurf Qgis::AltitudeBinding mBinding = Qgis::AltitudeBinding::Centroid; bool mExtrusionEnabled = false; double mExtrusionHeight = 0; + bool mCustomToleranceEnabled = false; + double mCustomTolerance = 0; QgsExpressionContext mExpressionContext; QgsFields mFields;