mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Add methods for comparison of QgsPoint, QgsPolyline and QgsPolygon
These methods allow for fuzzy comparison of coordinates with a specified tolerance.
This commit is contained in:
parent
54a58b984c
commit
7882fe2f25
@ -475,5 +475,27 @@ class QgsGeometry
|
||||
@returns the new computed QgsGeometry, or null
|
||||
*/
|
||||
static QgsGeometry *unaryUnion( const QList<QgsGeometry*>& geometryList ) /Factory/;
|
||||
|
||||
/** Compares two polylines for equality within a specified tolerance.
|
||||
* @param p1 first polyline
|
||||
* @param p2 second polyline
|
||||
* @param epsilon maximum difference for coordinates between the polylines
|
||||
* @returns true if polylines have the same number of points and all
|
||||
* points are equal within the specified tolerance
|
||||
* @note added in QGIS 2.9
|
||||
*/
|
||||
static bool compare( const QgsPolyline& p1, const QgsPolyline& p2, double epsilon = 4 * DBL_EPSILON );
|
||||
|
||||
/** Compares two polygons for equality within a specified tolerance.
|
||||
* @param p1 first polygon
|
||||
* @param p2 second polygon
|
||||
* @param epsilon maximum difference for coordinates between the polygons
|
||||
* @returns true if polygons have the same number of rings, and each ring has the same
|
||||
* number of points and all points are equal within the specified tolerance
|
||||
* @note added in QGIS 2.9
|
||||
*/
|
||||
static bool compare( const QgsPolygon& p1, const QgsPolygon& p2, double epsilon = 4 * DBL_EPSILON );
|
||||
|
||||
|
||||
}; // class QgsGeometry
|
||||
|
||||
|
@ -113,6 +113,14 @@ class QgsPoint
|
||||
/**Calculates azimuth between this point and other one (clockwise in degree, starting from north) */
|
||||
double azimuth( const QgsPoint& other );
|
||||
|
||||
/** Compares this point with another point with a fuzzy tolerance
|
||||
* @param other point to compare with
|
||||
* @param epsilon maximum difference for coordinates between the points
|
||||
* @returns true if points are equal within specified tolerance
|
||||
* @note added in QGIS 2.9
|
||||
*/
|
||||
bool compare( const QgsPoint &other, double epsilon = 4 * DBL_EPSILON ) const;
|
||||
|
||||
//! equality operator
|
||||
bool operator==( const QgsPoint &other );
|
||||
|
||||
|
@ -6632,3 +6632,29 @@ QgsGeometry *QgsGeometry::unaryUnion( const QList<QgsGeometry*> &geometryList )
|
||||
ret->fromGeos( geomUnion );
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool QgsGeometry::compare( const QgsPolyline &p1, const QgsPolyline &p2, double epsilon )
|
||||
{
|
||||
if ( p1.count() != p2.count() )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < p1.count(); ++i )
|
||||
{
|
||||
if ( !p1.at( i ).compare( p2.at( i ), epsilon ) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsGeometry::compare( const QgsPolygon &p1, const QgsPolygon &p2, double epsilon )
|
||||
{
|
||||
if ( p1.count() != p2.count() )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < p1.count(); ++i )
|
||||
{
|
||||
if ( !QgsGeometry::compare( p1.at( i ), p2.at( i ), epsilon ) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -521,6 +521,26 @@ class CORE_EXPORT QgsGeometry
|
||||
*/
|
||||
static QgsGeometry *unaryUnion( const QList<QgsGeometry*>& geometryList );
|
||||
|
||||
/** Compares two polylines for equality within a specified tolerance.
|
||||
* @param p1 first polyline
|
||||
* @param p2 second polyline
|
||||
* @param epsilon maximum difference for coordinates between the polylines
|
||||
* @returns true if polylines have the same number of points and all
|
||||
* points are equal within the specified tolerance
|
||||
* @note added in QGIS 2.9
|
||||
*/
|
||||
static bool compare( const QgsPolyline& p1, const QgsPolyline& p2, double epsilon = 4 * DBL_EPSILON );
|
||||
|
||||
/** Compares two polygons for equality within a specified tolerance.
|
||||
* @param p1 first polygon
|
||||
* @param p2 second polygon
|
||||
* @param epsilon maximum difference for coordinates between the polygons
|
||||
* @returns true if polygons have the same number of rings, and each ring has the same
|
||||
* number of points and all points are equal within the specified tolerance
|
||||
* @note added in QGIS 2.9
|
||||
*/
|
||||
static bool compare( const QgsPolygon& p1, const QgsPolygon& p2, double epsilon = 4 * DBL_EPSILON );
|
||||
|
||||
private:
|
||||
// Private variables
|
||||
|
||||
@ -687,7 +707,7 @@ class CORE_EXPORT QgsWkbPtr
|
||||
inline const QgsWkbPtr &operator>>( char &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline const QgsWkbPtr &operator>>( QGis::WkbType &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
#ifdef QT_ARCH_ARM
|
||||
inline const QgsWkbPtr &operator>>( qreal &v ) const { double d; memcpy( &d, mP, sizeof( d ) ); mP += sizeof( d ); v=d; return *this; }
|
||||
inline const QgsWkbPtr &operator>>( qreal &v ) const { double d; memcpy( &d, mP, sizeof( d ) ); mP += sizeof( d ); v = d; return *this; }
|
||||
#endif
|
||||
|
||||
inline QgsWkbPtr &operator<<( const double &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
@ -717,7 +737,7 @@ class CORE_EXPORT QgsConstWkbPtr
|
||||
inline const QgsConstWkbPtr &operator>>( char &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline const QgsConstWkbPtr &operator>>( QGis::WkbType &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
#ifdef QT_ARCH_ARM
|
||||
inline const QgsConstWkbPtr &operator>>( qreal &v ) const { double d; memcpy( &d, mP, sizeof( d ) ); mP += sizeof( d ); v=d; return *this; }
|
||||
inline const QgsConstWkbPtr &operator>>( qreal &v ) const { double d; memcpy( &d, mP, sizeof( d ) ); mP += sizeof( d ); v = d; return *this; }
|
||||
#endif
|
||||
|
||||
inline void operator+=( int n ) { mP += n; }
|
||||
|
@ -347,6 +347,11 @@ double QgsPoint::azimuth( const QgsPoint& other )
|
||||
return ( atan2( dx, dy ) * 180.0 / M_PI );
|
||||
}
|
||||
|
||||
bool QgsPoint::compare( const QgsPoint &other, double epsilon ) const
|
||||
{
|
||||
return ( qgsDoubleNear( m_x, other.x(), epsilon ) && qgsDoubleNear( m_y, other.y(), epsilon ) );
|
||||
}
|
||||
|
||||
// operators
|
||||
bool QgsPoint::operator==( const QgsPoint & other )
|
||||
{
|
||||
|
@ -189,6 +189,14 @@ class CORE_EXPORT QgsPoint
|
||||
/**Calculates azimuth between this point and other one (clockwise in degree, starting from north) */
|
||||
double azimuth( const QgsPoint& other );
|
||||
|
||||
/** Compares this point with another point with a fuzzy tolerance
|
||||
* @param other point to compare with
|
||||
* @param epsilon maximum difference for coordinates between the points
|
||||
* @returns true if points are equal within specified tolerance
|
||||
* @note added in QGIS 2.9
|
||||
*/
|
||||
bool compare( const QgsPoint &other, double epsilon = 4 * DBL_EPSILON ) const;
|
||||
|
||||
//! equality operator
|
||||
bool operator==( const QgsPoint &other );
|
||||
|
||||
|
@ -57,6 +57,9 @@ class TestQgsGeometry : public QObject
|
||||
void asQPointF();
|
||||
void asQPolygonF();
|
||||
|
||||
void comparePolylines();
|
||||
void comparePolygons();
|
||||
|
||||
// MK, Disabled 14.11.2014
|
||||
// Too unclear what exactly should be tested and which variations are allowed for the line
|
||||
#if 0
|
||||
@ -300,6 +303,48 @@ void TestQgsGeometry::asQPolygonF()
|
||||
QVERIFY( fromBad.isEmpty() );
|
||||
}
|
||||
|
||||
void TestQgsGeometry::comparePolylines()
|
||||
{
|
||||
QgsPolyline line1;
|
||||
line1 << mPoint1 << mPoint2 << mPoint3;
|
||||
QgsPolyline line2;
|
||||
line2 << mPoint1 << mPoint2 << mPoint3;
|
||||
QVERIFY( QgsGeometry::compare( line1, line2 ) );
|
||||
|
||||
//different number of nodes
|
||||
QgsPolyline line3;
|
||||
line3 << mPoint1 << mPoint2 << mPoint3 << mPoint4;
|
||||
QVERIFY( !QgsGeometry::compare( line1, line3 ) );
|
||||
|
||||
//different nodes
|
||||
QgsPolyline line4;
|
||||
line3 << mPoint1 << mPointA << mPoint3 << mPoint4;
|
||||
QVERIFY( !QgsGeometry::compare( line3, line4 ) );
|
||||
}
|
||||
|
||||
void TestQgsGeometry::comparePolygons()
|
||||
{
|
||||
QgsPolyline ring1;
|
||||
ring1 << mPoint1 << mPoint2 << mPoint3 << mPoint1;
|
||||
QgsPolyline ring2;
|
||||
ring2 << mPoint4 << mPointA << mPointB << mPoint4;
|
||||
QgsPolygon poly1;
|
||||
poly1 << ring1 << ring2;
|
||||
QgsPolygon poly2;
|
||||
poly2 << ring1 << ring2;
|
||||
QVERIFY( QgsGeometry::compare( poly1, poly2 ) );
|
||||
|
||||
//different number of rings
|
||||
QgsPolygon poly3;
|
||||
poly3 << ring1;
|
||||
QVERIFY( !QgsGeometry::compare( poly1, poly3 ) );
|
||||
|
||||
//different rings
|
||||
QgsPolygon poly4;
|
||||
poly4 << ring2;
|
||||
QVERIFY( !QgsGeometry::compare( poly3, poly4 ) );
|
||||
}
|
||||
|
||||
void TestQgsGeometry::initTestCase()
|
||||
{
|
||||
//
|
||||
|
@ -51,6 +51,8 @@ class TestQgsPoint: public QObject
|
||||
void sqrDist();
|
||||
void multiply();
|
||||
void onSegment();
|
||||
void compare();
|
||||
|
||||
private:
|
||||
QgsPoint mPoint1;
|
||||
QgsPoint mPoint2;
|
||||
@ -591,5 +593,16 @@ void TestQgsPoint::onSegment()
|
||||
|
||||
}
|
||||
|
||||
void TestQgsPoint::compare()
|
||||
{
|
||||
QgsPoint point1( 5.000000000001, 9.0 );
|
||||
QgsPoint point2( 5.0, 8.999999999999999 );
|
||||
QVERIFY( point1.compare( point2, 0.00000001 ) );
|
||||
QgsPoint point3( 5.0, 6.0 );
|
||||
QVERIFY( !( point3.compare( point1 ) ) );
|
||||
QgsPoint point4( 10 / 3.0, 12 / 7.0 );
|
||||
QVERIFY( point4.compare( QgsPoint( 10 / 3.0, 12 / 7.0 ) ) );
|
||||
}
|
||||
|
||||
QTEST_MAIN( TestQgsPoint )
|
||||
#include "testqgspoint.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user