Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Move curve orientation enum (Clockwise/CounterClockwise) to Qgis and
generalise the name

These values are useful for more than just curve orientations
  • Loading branch information
nyalldawson committed Nov 10, 2021
1 parent 5b8d164 commit aaca87c
Show file tree
Hide file tree
Showing 12 changed files with 49 additions and 31 deletions.
11 changes: 11 additions & 0 deletions python/core/auto_additions/qgis.py
Expand Up @@ -1161,3 +1161,14 @@
Qgis.Capitalization.__doc__ = 'String capitalization options.\n\n.. note::\n\n Prior to QGIS 3.24 this was available as :py:class:`QgsStringUtils`.Capitalization\n\n.. versionadded:: 3.24\n\n' + '* ``MixedCase``: ' + Qgis.Capitalization.MixedCase.__doc__ + '\n' + '* ``AllUppercase``: ' + Qgis.Capitalization.AllUppercase.__doc__ + '\n' + '* ``AllLowercase``: ' + Qgis.Capitalization.AllLowercase.__doc__ + '\n' + '* ``ForceFirstLetterToCapital``: ' + Qgis.Capitalization.ForceFirstLetterToCapital.__doc__ + '\n' + '* ``SmallCaps``: ' + Qgis.Capitalization.SmallCaps.__doc__ + '\n' + '* ``TitleCase``: ' + Qgis.Capitalization.TitleCase.__doc__ + '\n' + '* ``UpperCamelCase``: ' + Qgis.Capitalization.UpperCamelCase.__doc__ + '\n' + '* ``AllSmallCaps``: ' + Qgis.Capitalization.AllSmallCaps.__doc__
# --
Qgis.Capitalization.baseClass = Qgis
QgsCurve.Orientation = Qgis.AngularDirection
# monkey patching scoped based enum
QgsCurve.Clockwise = Qgis.AngularDirection.Clockwise
QgsCurve.Clockwise.is_monkey_patched = True
QgsCurve.Clockwise.__doc__ = "Clockwise direction"
QgsCurve.CounterClockwise = Qgis.AngularDirection.CounterClockwise
QgsCurve.CounterClockwise.is_monkey_patched = True
QgsCurve.CounterClockwise.__doc__ = "Counter-clockwise direction"
Qgis.AngularDirection.__doc__ = 'Angular directions.\n\n.. versionadded:: 3.24\n\n' + '* ``Clockwise``: ' + Qgis.AngularDirection.Clockwise.__doc__ + '\n' + '* ``CounterClockwise``: ' + Qgis.AngularDirection.CounterClockwise.__doc__
# --
Qgis.AngularDirection.baseClass = Qgis
8 changes: 1 addition & 7 deletions python/core/auto_generated/geometry/qgscurve.sip.in
Expand Up @@ -281,13 +281,7 @@ If a curve :py:func:`~QgsCurve.isClosed`, it has infinite sinuosity and will ret
.. versionadded:: 3.2
%End

enum Orientation
{
Clockwise,
CounterClockwise,
};

Orientation orientation() const;
Qgis::AngularDirection orientation() const;
%Docstring
Returns the curve's orientation, e.g. clockwise or counter-clockwise.

Expand Down
7 changes: 7 additions & 0 deletions python/core/auto_generated/qgis.sip.in
Expand Up @@ -746,6 +746,13 @@ The development version
AllSmallCaps,
};


enum class AngularDirection
{
Clockwise,
CounterClockwise,
};

static const double DEFAULT_SEARCH_RADIUS_MM;

static const float DEFAULT_MAPTOPIXEL_THRESHOLD;
Expand Down
4 changes: 2 additions & 2 deletions src/core/geometry/qgscurve.cpp
Expand Up @@ -283,11 +283,11 @@ double QgsCurve::sinuosity() const
return length() / d;
}

QgsCurve::Orientation QgsCurve::orientation() const
Qgis::AngularDirection QgsCurve::orientation() const
{
double a = 0;
sumUpArea( a );
return a < 0 ? Clockwise : CounterClockwise;
return a < 0 ? Qgis::AngularDirection::Clockwise : Qgis::AngularDirection::CounterClockwise;
}

void QgsCurve::clearCache() const
Expand Down
9 changes: 1 addition & 8 deletions src/core/geometry/qgscurve.h
Expand Up @@ -260,21 +260,14 @@ class CORE_EXPORT QgsCurve: public QgsAbstractGeometry SIP_ABSTRACT
*/
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;
Qgis::AngularDirection orientation() const;

/**
* Scrolls the curve vertices so that they start with the vertex at the given index.
Expand Down
8 changes: 4 additions & 4 deletions src/core/geometry/qgscurvepolygon.cpp
Expand Up @@ -817,7 +817,7 @@ void QgsCurvePolygon::forceRHR()

void QgsCurvePolygon::forceClockwise()
{
if ( mExteriorRing && mExteriorRing->orientation() != QgsCurve::Clockwise )
if ( mExteriorRing && mExteriorRing->orientation() != Qgis::AngularDirection::Clockwise )
{
// flip exterior ring orientation
std::unique_ptr< QgsCurve > flipped( mExteriorRing->reversed() );
Expand All @@ -827,7 +827,7 @@ void QgsCurvePolygon::forceClockwise()
QVector<QgsCurve *> validRings;
for ( QgsCurve *curve : std::as_const( mInteriorRings ) )
{
if ( curve && curve->orientation() != QgsCurve::CounterClockwise )
if ( curve && curve->orientation() != Qgis::AngularDirection::CounterClockwise )
{
// flip interior ring orientation
QgsCurve *flipped = curve->reversed();
Expand All @@ -844,7 +844,7 @@ void QgsCurvePolygon::forceClockwise()

void QgsCurvePolygon::forceCounterClockwise()
{
if ( mExteriorRing && mExteriorRing->orientation() != QgsCurve::CounterClockwise )
if ( mExteriorRing && mExteriorRing->orientation() != Qgis::AngularDirection::CounterClockwise )
{
// flip exterior ring orientation
mExteriorRing.reset( mExteriorRing->reversed() );
Expand All @@ -853,7 +853,7 @@ void QgsCurvePolygon::forceCounterClockwise()
QVector<QgsCurve *> validRings;
for ( QgsCurve *curve : std::as_const( mInteriorRings ) )
{
if ( curve && curve->orientation() != QgsCurve::Clockwise )
if ( curve && curve->orientation() != Qgis::AngularDirection::Clockwise )
{
// flip interior ring orientation
QgsCurve *flipped = curve->reversed();
Expand Down
4 changes: 2 additions & 2 deletions src/core/geometry/qgsgeometry.cpp
Expand Up @@ -2125,7 +2125,7 @@ QgsGeometry QgsGeometry::offsetCurve( double distance, int segments, Qgis::JoinS
mLastError.clear();

// GEOS can flip the curve orientation in some circumstances. So record previous orientation and correct if required
const QgsCurve::Orientation prevOrientation = qgsgeometry_cast< const QgsCurve * >( d->geometry.get() )->orientation();
const Qgis::AngularDirection prevOrientation = qgsgeometry_cast< const QgsCurve * >( d->geometry.get() )->orientation();

std::unique_ptr< QgsAbstractGeometry > offsetGeom( geos.offsetCurve( distance, segments, joinStyle, miterLimit, &mLastError ) );
if ( !offsetGeom )
Expand All @@ -2137,7 +2137,7 @@ QgsGeometry QgsGeometry::offsetCurve( double distance, int segments, Qgis::JoinS

if ( const QgsCurve *offsetCurve = qgsgeometry_cast< const QgsCurve * >( offsetGeom.get() ) )
{
const QgsCurve::Orientation newOrientation = offsetCurve->orientation();
const Qgis::AngularDirection newOrientation = offsetCurve->orientation();
if ( newOrientation != prevOrientation )
{
// GEOS has flipped line orientation, flip it back
Expand Down
13 changes: 13 additions & 0 deletions src/core/qgis.h
Expand Up @@ -1219,6 +1219,19 @@ class CORE_EXPORT Qgis
};
Q_ENUM( Capitalization )


/**
* Angular directions.
*
* \since QGIS 3.24
*/
enum class AngularDirection SIP_MONKEYPATCH_SCOPEENUM_UNNEST( QgsCurve, Orientation ) : int
{
Clockwise, //!< Clockwise direction
CounterClockwise, //!< Counter-clockwise direction
};
Q_ENUM( AngularDirection )

/**
* Identify search radius in mm
* \since QGIS 2.3
Expand Down
4 changes: 2 additions & 2 deletions src/core/symbology/qgssymbol.cpp
Expand Up @@ -154,9 +154,9 @@ QPolygonF QgsSymbol::_getPolygonRing( QgsRenderContext &context, const QgsCurve
if ( correctRingOrientation )
{
// ensure consistent polygon ring orientation
if ( isExteriorRing && curve.orientation() != QgsCurve::Clockwise )
if ( isExteriorRing && curve.orientation() != Qgis::AngularDirection::Clockwise )
std::reverse( poly.begin(), poly.end() );
else if ( !isExteriorRing && curve.orientation() != QgsCurve::CounterClockwise )
else if ( !isExteriorRing && curve.orientation() != Qgis::AngularDirection::CounterClockwise )
std::reverse( poly.begin(), poly.end() );
}

Expand Down
4 changes: 2 additions & 2 deletions tests/src/core/geometry/testqgscircularstring.cpp
Expand Up @@ -2253,11 +2253,11 @@ void TestQgsCircularString::orientation()

cs.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 1 )
<< QgsPoint( 1, 1 ) << QgsPoint( 1, 0 ) << QgsPoint( 0, 0 ) );
QCOMPARE( cs.orientation(), QgsCurve::Clockwise );
QCOMPARE( cs.orientation(), Qgis::AngularDirection::Clockwise );

cs.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 )
<< QgsPoint( 1, 1 ) << QgsPoint( 0, 1 ) << QgsPoint( 0, 0 ) );
QCOMPARE( cs.orientation(), QgsCurve::CounterClockwise );
QCOMPARE( cs.orientation(), Qgis::AngularDirection::CounterClockwise );
}

void TestQgsCircularString::constructorFromArray()
Expand Down
4 changes: 2 additions & 2 deletions tests/src/core/geometry/testqgscompoundcurve.cpp
Expand Up @@ -1919,10 +1919,10 @@ void TestQgsCompoundCurve::orientation()
( void )cc.orientation(); // no crash

cc.fromWkt( QStringLiteral( "CompoundCurve( ( 0 0, 0 1), CircularString (0 1, 1 1, 1 0), (1 0, 0 0))" ) );
QCOMPARE( cc.orientation(), QgsCurve::Clockwise );
QCOMPARE( cc.orientation(), Qgis::AngularDirection::Clockwise );

cc.fromWkt( QStringLiteral( "CompoundCurve( ( 0 0, 1 0), CircularString (1 0, 1 1, 0 1), (0 1, 0 0))" ) );
QCOMPARE( cc.orientation(), QgsCurve::CounterClockwise );
QCOMPARE( cc.orientation(), Qgis::AngularDirection::CounterClockwise );
}

void TestQgsCompoundCurve::length()
Expand Down
4 changes: 2 additions & 2 deletions tests/src/core/geometry/testqgslinestring.cpp
Expand Up @@ -2916,13 +2916,13 @@ void TestQgsLineString::orientation()
<< QgsPoint( 0, 1 ) << QgsPoint( 1, 1 )
<< QgsPoint( 1, 0 ) << QgsPoint( 0, 0 ) );

QCOMPARE( ls.orientation(), QgsCurve::Clockwise );
QCOMPARE( ls.orientation(), Qgis::AngularDirection::Clockwise );

ls.setPoints( QgsPointSequence() << QgsPoint( 0, 0 )
<< QgsPoint( 1, 0 ) << QgsPoint( 1, 1 )
<< QgsPoint( 0, 1 ) << QgsPoint( 0, 0 ) );

QCOMPARE( ls.orientation(), QgsCurve::CounterClockwise );
QCOMPARE( ls.orientation(), Qgis::AngularDirection::CounterClockwise );
}

void TestQgsLineString::boundingBoxIntersects()
Expand Down

0 comments on commit aaca87c

Please sign in to comment.