Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[API] Improve isValid method for curve type
  • Loading branch information
lbartoletti committed Dec 1, 2020
1 parent 8486312 commit 0f292cf
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 1 deletion.
2 changes: 2 additions & 0 deletions python/core/auto_generated/geometry/qgscircularstring.sip.in
Expand Up @@ -83,6 +83,8 @@ to ``p2`` will be used (i.e. winding the other way around the circle).

virtual bool isEmpty() const /HoldGIL/;

virtual bool isValid( QString &error /Out/, int flags = 0 ) const;

virtual int numPoints() const /HoldGIL/;


Expand Down
2 changes: 2 additions & 0 deletions python/core/auto_generated/geometry/qgscompoundcurve.sip.in
Expand Up @@ -65,6 +65,8 @@ Compound curve geometry type

virtual bool isEmpty() const /HoldGIL/;

virtual bool isValid( QString &error /Out/, int flags = 0 ) const;


virtual QgsLineString *curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const /Factory/;

Expand Down
2 changes: 2 additions & 0 deletions python/core/auto_generated/geometry/qgslinestring.sip.in
Expand Up @@ -416,6 +416,8 @@ segment in the line.

virtual bool isEmpty() const /HoldGIL/;

virtual bool isValid( QString &error /Out/, int flags = 0 ) const;

virtual QgsLineString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;

virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );
Expand Down
10 changes: 10 additions & 0 deletions src/core/geometry/qgscircularstring.cpp
Expand Up @@ -403,6 +403,16 @@ bool QgsCircularString::isEmpty() const
return mX.isEmpty();
}

bool QgsCircularString::isValid( QString &error, int flags ) const
{
if ( !isEmpty() && ( numPoints() < 3 ) )
{
error = QObject::tr( "CircularString has less than 3 points and is not empty." );
return false;
}
return QgsCurve::isValid( error, flags );
}

//curve interface
double QgsCircularString::length() const
{
Expand Down
1 change: 1 addition & 0 deletions src/core/geometry/qgscircularstring.h
Expand Up @@ -82,6 +82,7 @@ class CORE_EXPORT QgsCircularString: public QgsCurve
QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
json asJsonObject( int precision = 17 ) const override SIP_SKIP;
bool isEmpty() const override SIP_HOLDGIL;
bool isValid( QString &error SIP_OUT, int flags = 0 ) const override;
int numPoints() const override SIP_HOLDGIL;

/**
Expand Down
17 changes: 16 additions & 1 deletion src/core/geometry/qgscompoundcurve.cpp
Expand Up @@ -388,6 +388,22 @@ bool QgsCompoundCurve::isEmpty() const
return true;
}

bool QgsCompoundCurve::isValid( QString &error, int flags ) const
{
if ( mCurves.isEmpty() )
return true;

for ( int i = 0; i < mCurves.size() ; ++i )
{
if ( !mCurves[i]->isValid( error, flags ) )
{
error = QObject::tr( "Curve[%1]: %2" ).arg( i + 1 ).arg( error );
return false;
}
}
return QgsCurve::isValid( error, flags );
}

QgsLineString *QgsCompoundCurve::curveToLine( double tolerance, SegmentationToleranceType toleranceType ) const
{
QgsLineString *line = new QgsLineString();
Expand Down Expand Up @@ -1011,4 +1027,3 @@ void QgsCompoundCurve::swapXy()
}
clearCache();
}

1 change: 1 addition & 0 deletions src/core/geometry/qgscompoundcurve.h
Expand Up @@ -60,6 +60,7 @@ class CORE_EXPORT QgsCompoundCurve: public QgsCurve
void points( QgsPointSequence &pts SIP_OUT ) const override;
int numPoints() const override SIP_HOLDGIL;
bool isEmpty() const override SIP_HOLDGIL;
bool isValid( QString &error SIP_OUT, int flags = 0 ) const override;

/**
* Returns a new line string geometry corresponding to a segmentized approximation
Expand Down
10 changes: 10 additions & 0 deletions src/core/geometry/qgslinestring.cpp
Expand Up @@ -310,6 +310,16 @@ bool QgsLineString::isEmpty() const
return mX.isEmpty();
}

bool QgsLineString::isValid( QString &error, int flags ) const
{
if ( !isEmpty() && ( numPoints() < 2 ) )
{
error = QObject::tr( "LineString has less than 2 points and is not empty." );
return false;
}
return QgsCurve::isValid( error, flags );
}

QgsLineString *QgsLineString::snappedToGrid( double hSpacing, double vSpacing, double dSpacing, double mSpacing ) const
{
// prepare result
Expand Down
1 change: 1 addition & 0 deletions src/core/geometry/qgslinestring.h
Expand Up @@ -586,6 +586,7 @@ class CORE_EXPORT QgsLineString: public QgsCurve
QgsLineString *clone() const override SIP_FACTORY;
void clear() override;
bool isEmpty() const override SIP_HOLDGIL;
bool isValid( QString &error SIP_OUT, int flags = 0 ) const override;
QgsLineString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;

Expand Down
38 changes: 38 additions & 0 deletions tests/src/core/testqgsgeometry.cpp
Expand Up @@ -83,6 +83,7 @@ class TestQgsGeometry : public QObject
void asVariant(); //test conversion to and from a QVariant
void referenced();
void isEmpty();
void isValid();
void equality();
void vertexIterator();
void partIterator();
Expand Down Expand Up @@ -469,6 +470,43 @@ void TestQgsGeometry::isEmpty()
QVERIFY( collection.isEmpty() );
}

void TestQgsGeometry::isValid()
{
QString error;
// LineString
QgsLineString line;
QVERIFY( line.isValid( error ) );
line.addVertex( QgsPoint( 0, 0 ) );
QVERIFY( !line.isValid( error ) );
QCOMPARE( error, QStringLiteral( "LineString has less than 2 points and is not empty." ) );
line.addVertex( QgsPoint( 1, 1 ) );
QVERIFY( line.isValid( error ) );

// CircularString
QgsCircularString circ;
QVERIFY( circ.isValid( error ) );
QgsPointSequence pts = QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 2.5, 2.3 );
circ.setPoints( pts );
QVERIFY( !circ.isValid( error ) );
QCOMPARE( error, QStringLiteral( "CircularString has less than 3 points and is not empty." ) );
pts.append( QgsPoint( 5, 5 ) );
circ.setPoints( pts );
QVERIFY( circ.isValid( error ) );

// CompoundCurve
QgsCompoundCurve curve;
QVERIFY( curve.isValid( error ) );
curve.addCurve( line.clone() );
QVERIFY( curve.isValid( error ) );
curve.addCurve( circ.clone() );
QVERIFY( curve.isValid( error ) );
QgsLineString invalidLine;
invalidLine.addVertex( QgsPoint( 0, 0 ) );
curve.addCurve( invalidLine.clone() );
QVERIFY( !curve.isValid( error ) );
QCOMPARE( error, QStringLiteral( "Curve[3]: LineString has less than 2 points and is not empty." ) );
}

void TestQgsGeometry::equality()
{
// null geometries
Expand Down

0 comments on commit 0f292cf

Please sign in to comment.