mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Add QgsGeometry::isSimple() - useful for self-intersection checks
This commit is contained in:
parent
09975cec07
commit
e001d5c70a
@ -188,6 +188,19 @@ Returns true if WKB of the geometry is of WKBMulti* type
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool isSimple() const;
|
||||
%Docstring
|
||||
Determines whether the geometry is simple (according to OGC definition),
|
||||
i.e. it has no anomalous geometric points, such as self-intersection or self-tangency.
|
||||
Uses GEOS library for the test.
|
||||
.. note::
|
||||
|
||||
This is useful mainly for linestrings and linear rings. Polygons are simple by definition,
|
||||
for checking anomalies in polygon geometries one can use isGeosValid().
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
double area() const;
|
||||
%Docstring
|
||||
Returns the area of the geometry using GEOS
|
||||
|
@ -155,6 +155,13 @@ class QgsGeometryEngine
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
virtual bool isSimple( QString *errorMsg = 0 ) const = 0;
|
||||
%Docstring
|
||||
Determines whether the geometry is simple (according to OGC definition).
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
virtual int splitGeometry( const QgsLineString &splitLine,
|
||||
QList<QgsAbstractGeometry *> &newGeometries,
|
||||
bool topological,
|
||||
|
@ -1980,6 +1980,15 @@ bool QgsGeometry::isGeosValid() const
|
||||
return geos.isValid();
|
||||
}
|
||||
|
||||
bool QgsGeometry::isSimple() const
|
||||
{
|
||||
if ( !d->geometry )
|
||||
return false;
|
||||
|
||||
QgsGeos geos( d->geometry );
|
||||
return geos.isSimple();
|
||||
}
|
||||
|
||||
bool QgsGeometry::isGeosEqual( const QgsGeometry &g ) const
|
||||
{
|
||||
if ( !d->geometry || !g.d->geometry )
|
||||
|
@ -213,6 +213,15 @@ class CORE_EXPORT QgsGeometry
|
||||
*/
|
||||
bool isGeosValid() const;
|
||||
|
||||
/** Determines whether the geometry is simple (according to OGC definition),
|
||||
* i.e. it has no anomalous geometric points, such as self-intersection or self-tangency.
|
||||
* Uses GEOS library for the test.
|
||||
* \note This is useful mainly for linestrings and linear rings. Polygons are simple by definition,
|
||||
* for checking anomalies in polygon geometries one can use isGeosValid().
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool isSimple() const;
|
||||
|
||||
/** Returns the area of the geometry using GEOS
|
||||
\since QGIS 1.5
|
||||
*/
|
||||
|
@ -83,6 +83,11 @@ class CORE_EXPORT QgsGeometryEngine
|
||||
virtual bool isEqual( const QgsAbstractGeometry &geom, QString *errorMsg = nullptr ) const = 0;
|
||||
virtual bool isEmpty( QString *errorMsg ) const = 0;
|
||||
|
||||
/** Determines whether the geometry is simple (according to OGC definition).
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual bool isSimple( QString *errorMsg = nullptr ) const = 0;
|
||||
|
||||
virtual int splitGeometry( const QgsLineString &splitLine,
|
||||
QList<QgsAbstractGeometry *> &newGeometries,
|
||||
bool topological,
|
||||
|
@ -1494,6 +1494,20 @@ bool QgsGeos::isEmpty( QString *errorMsg ) const
|
||||
CATCH_GEOS_WITH_ERRMSG( false );
|
||||
}
|
||||
|
||||
bool QgsGeos::isSimple( QString *errorMsg ) const
|
||||
{
|
||||
if ( !mGeos )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return GEOSisSimple_r( geosinit.ctxt, mGeos );
|
||||
}
|
||||
CATCH_GEOS_WITH_ERRMSG( false );
|
||||
}
|
||||
|
||||
GEOSCoordSequence *QgsGeos::createCoordinateSequence( const QgsCurve *curve, double precision, bool forceClose )
|
||||
{
|
||||
bool segmentize = false;
|
||||
|
@ -71,6 +71,7 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
|
||||
bool isValid( QString *errorMsg = nullptr ) const override;
|
||||
bool isEqual( const QgsAbstractGeometry &geom, QString *errorMsg = nullptr ) const override;
|
||||
bool isEmpty( QString *errorMsg = nullptr ) const override;
|
||||
bool isSimple( QString *errorMsg = nullptr ) const override;
|
||||
|
||||
/** Splits this geometry according to a given line.
|
||||
\param splitLine the line that splits the geometry
|
||||
|
@ -124,6 +124,8 @@ class TestQgsGeometry : public QObject
|
||||
|
||||
void makeValid();
|
||||
|
||||
void isSimple();
|
||||
|
||||
private:
|
||||
//! A helper method to do a render check to see if the geometry op is as expected
|
||||
bool renderCheck( const QString &testName, const QString &comment = QLatin1String( QLatin1String( "" ) ), int mismatchCount = 0 );
|
||||
@ -5423,5 +5425,32 @@ void TestQgsGeometry::makeValid()
|
||||
}
|
||||
}
|
||||
|
||||
void TestQgsGeometry::isSimple()
|
||||
{
|
||||
typedef QPair<QString, bool> InputWktAndExpectedResult;
|
||||
QList<InputWktAndExpectedResult> geoms;
|
||||
geoms << qMakePair( QString( "LINESTRING(0 0, 1 0, 1 1)" ), true );
|
||||
geoms << qMakePair( QString( "LINESTRING(0 0, 1 0, 1 1, 0 0)" ), true ); // may be closed (linear ring)
|
||||
geoms << qMakePair( QString( "LINESTRING(0 0, 1 0, 1 1, 0 -1)" ), false ); // self-intersection
|
||||
geoms << qMakePair( QString( "LINESTRING(0 0, 1 0, 1 1, 0.5 0, 0 1)" ), false ); // self-tangency
|
||||
geoms << qMakePair( QString( "POINT(1 1)" ), true ); // points are simple
|
||||
geoms << qMakePair( QString( "POLYGON((0 0, 1 1, 1 1, 0 0))" ), true ); // polygons are always simple, even if they are invalid
|
||||
geoms << qMakePair( QString( "MULTIPOINT((1 1), (2 2))" ), true );
|
||||
geoms << qMakePair( QString( "MULTIPOINT((1 1), (1 1))" ), false ); // must not contain the same point twice
|
||||
geoms << qMakePair( QString( "MULTILINESTRING((0 0, 1 0), (0 1, 1 1))" ), true );
|
||||
geoms << qMakePair( QString( "MULTILINESTRING((0 0, 1 0), (0 0, 1 0))" ), true ); // may be touching at endpoints
|
||||
geoms << qMakePair( QString( "MULTILINESTRING((0 0, 1 1), (0 1, 1 0))" ), false ); // must not intersect each other
|
||||
geoms << qMakePair( QString( "MULTIPOLYGON(((0 0, 1 1, 1 1, 0 0)),((0 0, 1 1, 1 1, 0 0)))" ), true ); // multi-polygons are always simple
|
||||
|
||||
Q_FOREACH ( const InputWktAndExpectedResult &pair, geoms )
|
||||
{
|
||||
QgsGeometry gInput = QgsGeometry::fromWkt( pair.first );
|
||||
QVERIFY( !gInput.isNull() );
|
||||
|
||||
bool res = gInput.isSimple();
|
||||
QCOMPARE( res, pair.second );
|
||||
}
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsGeometry )
|
||||
#include "testqgsgeometry.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user