Add method to determine orientation of closed curves

This commit is contained in:
Nyall Dawson 2018-11-06 10:40:43 +10:00
parent 6e16651d96
commit c22364d45e
4 changed files with 62 additions and 0 deletions

View File

@ -229,6 +229,23 @@ If a curve isClosed(), it has infinite sinuosity and will return NaN.
.. versionadded:: 3.2
%End
enum Orientation
{
Clockwise,
CounterClockwise,
};
Orientation orientation() const;
%Docstring
Returns the curve's orientation, e.g. clockwise or counter-clockwise.
.. warning::
The result is not predictable for non-closed curves.
.. versionadded:: 3.6
%End
protected:

View File

@ -214,6 +214,13 @@ double QgsCurve::sinuosity() const
return length() / d;
}
QgsCurve::Orientation QgsCurve::orientation() const
{
double a = 0;
sumUpArea( a );
return a < 0 ? Clockwise : CounterClockwise;
}
void QgsCurve::clearCache() const
{
mBoundingBox = QgsRectangle();

View File

@ -213,6 +213,22 @@ class CORE_EXPORT QgsCurve: public QgsAbstractGeometry
*/
double sinuosity() const;
//! Curve orientation
enum Orientation
{
Clockwise, //!< Clockwise orientation
CounterClockwise, //!< Counter-clockwise orientation
};
/**
* Returns the curve's orientation, e.g. clockwise or counter-clockwise.
*
* \warning The result is not predictable for non-closed curves.
*
* \since QGIS 3.6
*/
Orientation orientation() const;
#ifndef SIP_RUN
/**

View File

@ -2760,6 +2760,13 @@ void TestQgsGeometry::circularString()
interpolateResult.reset( interpolate.interpolatePoint( 1 ) );
QCOMPARE( interpolateResult->asWkt( 2 ), QStringLiteral( "Point (10.46 0.84)" ) );
// orientation
QgsCircularString orientation;
( void )orientation.orientation(); // no crash
orientation.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 1 ) << QgsPoint( 1, 1 ) << QgsPoint( 1, 0 ) << QgsPoint( 0, 0 ) );
QCOMPARE( orientation.orientation(), QgsCurve::Clockwise );
orientation.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 1 ) << QgsPoint( 0, 0 ) );
QCOMPARE( orientation.orientation(), QgsCurve::CounterClockwise );
}
@ -4767,6 +4774,14 @@ void TestQgsGeometry::lineString()
interpolate.setPoints( QgsPointSequence() << QgsPoint( 11, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 111, 12 ) );
interpolateResult.reset( interpolate.interpolatePoint( 1 ) );
QCOMPARE( interpolateResult->asWkt( 2 ), QStringLiteral( "Point (11 3)" ) );
// orientation
QgsLineString orientation;
( void )orientation.orientation(); // no crash
orientation.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 1 ) << QgsPoint( 1, 1 ) << QgsPoint( 1, 0 ) << QgsPoint( 0, 0 ) );
QCOMPARE( orientation.orientation(), QgsCurve::Clockwise );
orientation.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 1 ) << QgsPoint( 0, 0 ) );
QCOMPARE( orientation.orientation(), QgsCurve::CounterClockwise );
}
void TestQgsGeometry::polygon()
@ -11449,6 +11464,13 @@ void TestQgsGeometry::compoundCurve()
interpolateResult.reset( interpolate.interpolatePoint( 1 ) );
QCOMPARE( interpolateResult->asWkt( 2 ), QStringLiteral( "Point (6 0)" ) );
// orientation
QgsCompoundCurve orientation;
( void )orientation.orientation(); // no crash
orientation.fromWkt( QStringLiteral( "CompoundCurve( ( 0 0, 0 1), CircularString (0 1, 1 1, 1 0), (1 0, 0 0))" ) );
QCOMPARE( orientation.orientation(), QgsCurve::Clockwise );
orientation.fromWkt( QStringLiteral( "CompoundCurve( ( 0 0, 1 0), CircularString (1 0, 1 1, 0 1), (0 1, 0 0))" ) );
QCOMPARE( orientation.orientation(), QgsCurve::CounterClockwise );
}
void TestQgsGeometry::multiPoint()