diff --git a/python/analysis/vector/qgstransectsample.sip b/python/analysis/vector/qgstransectsample.sip index c2274919ae0..874a603fca7 100644 --- a/python/analysis/vector/qgstransectsample.sip +++ b/python/analysis/vector/qgstransectsample.sip @@ -18,7 +18,8 @@ class QgsTransectSample QgsTransectSample( QgsVectorLayer* strataLayer, QString strataIdAttribute, QString minDistanceAttribute, QString nPointsAttribute, DistanceUnits minDistUnits, QgsVectorLayer* baselineLayer, bool shareBaseline, - QString baselineStrataId, const QString& outputPointLayer, const QString& outputLineLayer, const QString& usedBaselineLayer, double minTransectLength = 0.0 ); + QString baselineStrataId, const QString& outputPointLayer, const QString& outputLineLayer, const QString& usedBaselineLayer, + double minTransectLength = 0.0, double baselineBufferDistance = -1.0, double baselineSimplificationTolerance = -1.0 ); ~QgsTransectSample(); int createSample( QProgressDialog* pd ); diff --git a/src/analysis/vector/qgstransectsample.cpp b/src/analysis/vector/qgstransectsample.cpp index bb729cf8525..24693991444 100644 --- a/src/analysis/vector/qgstransectsample.cpp +++ b/src/analysis/vector/qgstransectsample.cpp @@ -14,10 +14,11 @@ QgsTransectSample::QgsTransectSample( QgsVectorLayer* strataLayer, QString strataIdAttribute, QString minDistanceAttribute, QString nPointsAttribute, DistanceUnits minDistUnits, QgsVectorLayer* baselineLayer, bool shareBaseline, QString baselineStrataId, const QString& outputPointLayer, - const QString& outputLineLayer, const QString& usedBaselineLayer, double minTransectLength ): mStrataLayer( strataLayer ), + const QString& outputLineLayer, const QString& usedBaselineLayer, double minTransectLength, + double baselineBufferDistance, double baselineSimplificationTolerance ): mStrataLayer( strataLayer ), mStrataIdAttribute( strataIdAttribute ), mMinDistanceAttribute( minDistanceAttribute ), mNPointsAttribute( nPointsAttribute ), mBaselineLayer( baselineLayer ), mShareBaseline( shareBaseline ), mBaselineStrataId( baselineStrataId ), mOutputPointLayer( outputPointLayer ), mOutputLineLayer( outputLineLayer ), mUsedBaselineLayer( usedBaselineLayer ), - mMinDistanceUnits( minDistUnits ), mMinTransectLength( minTransectLength ) + mMinDistanceUnits( minDistUnits ), mMinTransectLength( minTransectLength ), mBaselineBufferDistance( baselineBufferDistance ), mBaselineSimplificationTolerance( baselineSimplificationTolerance ) { } @@ -155,11 +156,10 @@ int QgsTransectSample::createSample( QProgressDialog* pd ) double minDistance = fet.attribute( mMinDistanceAttribute ).toDouble(); double minDistanceLayerUnits = minDistance; //if minDistance is in meters and the data in degrees, we need to apply a rough conversion for the buffer distance - double bufferDist = minDistance; + double bufferDist = bufferDistance( minDistance ); if ( mMinDistanceUnits == Meters && mStrataLayer->crs().mapUnits() == QGis::DecimalDegrees ) { - bufferDist = minDistance / 111319.9; - minDistanceLayerUnits = bufferDist; + minDistanceLayerUnits = minDistance / 111319.9; } QgsGeometry* clippedBaseline = strataGeom->intersection( baselineGeom ); @@ -549,13 +549,30 @@ QgsGeometry* QgsTransectSample::clipBufferLine( const QgsGeometry* stratumGeom, return 0; } + QgsGeometry* usedBaseline = clippedBaseline; + if ( mBaselineSimplificationTolerance >= 0 ) + { + //int verticesBefore = usedBaseline->asMultiPolyline().count(); + usedBaseline = clippedBaseline->simplify( mBaselineSimplificationTolerance ); + if ( !usedBaseline ) + { + return 0; + } + //int verticesAfter = usedBaseline->asMultiPolyline().count(); + + //debug: write to file + /*QgsVectorFileWriter debugWriter( "/tmp/debug.shp", "utf-8", QgsFields(), QGis::WKBLineString, &( mStrataLayer->crs() ) ); + QgsFeature debugFeature; debugFeature.setGeometry( usedBaseline ); + debugWriter.addFeature( debugFeature );*/ + } + double currentBufferDist = tolerance; int maxLoops = 10; for ( int i = 0; i < maxLoops; ++i ) { //loop with tolerance: create buffer, convert buffer to line, clip line by stratum, test if result is (single) line - QgsGeometry* clipBaselineBuffer = clippedBaseline->buffer( currentBufferDist, 8 ); + QgsGeometry* clipBaselineBuffer = usedBaseline->buffer( currentBufferDist, 8 ); if ( !clipBaselineBuffer ) { delete clipBaselineBuffer; @@ -628,6 +645,10 @@ QgsGeometry* QgsTransectSample::clipBufferLine( const QgsGeometry* stratumGeom, if ( bufferLineClippedIntersectsStratum ) { delete clipBaselineBuffer; + if ( mBaselineSimplificationTolerance >= 0 ) + { + delete usedBaseline; + } return bufferLineClipped; } } @@ -637,5 +658,25 @@ QgsGeometry* QgsTransectSample::clipBufferLine( const QgsGeometry* stratumGeom, currentBufferDist /= 2; } + if ( mBaselineSimplificationTolerance >= 0 ) + { + delete usedBaseline; + } return 0; //no solution found even with reduced tolerances } + +double QgsTransectSample::bufferDistance( double minDistanceFromAttribute ) const +{ + double bufferDist = minDistanceFromAttribute; + if ( mBaselineBufferDistance >= 0 ) + { + bufferDist = mBaselineBufferDistance; + } + + if ( mMinDistanceUnits == Meters && mStrataLayer->crs().mapUnits() == QGis::DecimalDegrees ) + { + bufferDist /= 111319.9; + } + + return bufferDist; +} diff --git a/src/analysis/vector/qgstransectsample.h b/src/analysis/vector/qgstransectsample.h index b49a7f33afa..ffacc4602ee 100644 --- a/src/analysis/vector/qgstransectsample.h +++ b/src/analysis/vector/qgstransectsample.h @@ -25,7 +25,8 @@ class ANALYSIS_EXPORT QgsTransectSample QgsTransectSample( QgsVectorLayer* strataLayer, QString strataIdAttribute, QString minDistanceAttribute, QString nPointsAttribute, DistanceUnits minDistUnits, QgsVectorLayer* baselineLayer, bool shareBaseline, - QString baselineStrataId, const QString& outputPointLayer, const QString& outputLineLayer, const QString& usedBaselineLayer, double minTransectLength = 0.0 ); + QString baselineStrataId, const QString& outputPointLayer, const QString& outputLineLayer, const QString& usedBaselineLayer, double minTransectLength = 0.0, + double baselineBufferDistance = -1.0, double baselineSimplificationTolerance = -1.0 ); ~QgsTransectSample(); int createSample( QProgressDialog* pd ); @@ -56,6 +57,11 @@ class ANALYSIS_EXPORT QgsTransectSample double mMinTransectLength; + /**If value is negative, the buffer distance ist set to the same value as the minimum distance*/ + double mBaselineBufferDistance; + /**If value is negative, no simplification is done to the baseline prior to create the buffer*/ + double mBaselineSimplificationTolerance; + /**Finds the closest points between two line segments @param g1 first input geometry. Must be a linestring with two vertices @param g2 second input geometry. Must be a linestring with two vertices @@ -71,7 +77,10 @@ class ANALYSIS_EXPORT QgsTransectSample @param clippedBaseline base line geometry clipped to the stratum @param tolerance buffer distance (in layer units) @return clipped buffer line or 0 in case of error*/ - static QgsGeometry* clipBufferLine( const QgsGeometry* stratumGeom, QgsGeometry* clippedBaseline, double tolerance ); + QgsGeometry* clipBufferLine( const QgsGeometry* stratumGeom, QgsGeometry* clippedBaseline, double tolerance ); + + /**Returns distance to buffer the baseline (takes care of units and buffer settings*/ + double bufferDistance( double minDistanceFromAttribute ) const; }; #endif // QGSTRANSECTSAMPLE_H