From 883dcab1fedb0f3f4838ccc165909aac93b66225 Mon Sep 17 00:00:00 2001 From: Magnus Homann Date: Sun, 16 Sep 2012 04:55:51 +0200 Subject: [PATCH 1/2] Added conversion between QgsRectangle and QRectF. And tests. --- python/core/qgsrectangle.sip | 8 +++++++- src/core/qgsrectangle.cpp | 16 ++++++++++++++++ src/core/qgsrectangle.h | 10 ++++++++-- tests/src/core/testqgsrectangle.cpp | 9 +++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/python/core/qgsrectangle.sip b/python/core/qgsrectangle.sip index 0a08aeda3c7..69462ed2d81 100644 --- a/python/core/qgsrectangle.sip +++ b/python/core/qgsrectangle.sip @@ -16,6 +16,9 @@ class QgsRectangle QgsRectangle(double xmin=0, double ymin=0, double xmax=0, double ymax=0); //! Construct a rectangle from two points. The rectangle is normalized after construction. QgsRectangle(const QgsPoint & p1, const QgsPoint & p2); + //! Construct a rectangle from a QRectF. The rectangle is normalized after construction. + //@note added in 2.0 + QgsRectangle(const QRectF & qRectF ); //! Copy constructor QgsRectangle(const QgsRectangle &other); //! Destructor @@ -77,8 +80,11 @@ class QgsRectangle //! returns string representation in Wkt form QString asWktCoordinates() const; //! returns string representation as WKT Polygon - //@note added om 2.0 + //@note added in 2.0 QString asWktPolygon() const; + //! returns a QRectF with same coordinates. + //@note added in 2.0 + QRectF QgsRectangle::toRectF() const; //! returns string representation of form xmin,ymin xmax,ymax QString toString(bool automaticPrecision = false) const; //! overloaded toString that allows precision of numbers to be set diff --git a/src/core/qgsrectangle.cpp b/src/core/qgsrectangle.cpp index 72316f7f1a3..53d49271adf 100644 --- a/src/core/qgsrectangle.cpp +++ b/src/core/qgsrectangle.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,14 @@ QgsRectangle::QgsRectangle( QgsPoint const & p1, QgsPoint const & p2 ) set( p1, p2 ); } +QgsRectangle::QgsRectangle( QRectF const & qRectF ) +{ + xmin = qRectF.topLeft().x(); + ymin = qRectF.topLeft().y(); + xmax = qRectF.bottomRight().x(); + ymax = qRectF.bottomRight().y(); +} + QgsRectangle::QgsRectangle( const QgsRectangle &r ) { xmin = r.xMinimum(); @@ -203,6 +212,13 @@ QString QgsRectangle::asWktPolygon() const return rep; } +//! returns a QRectF with same coordinates. +//@note added in 2.0 +QRectF QgsRectangle::toRectF() const +{ + return QRectF( (qreal)xmin, (qreal)ymin, (qreal)xmax - xmin, (qreal)ymax - ymin ); +} + // Return a string representation of the rectangle with automatic or high precision QString QgsRectangle::toString( bool automaticPrecision ) const { diff --git a/src/core/qgsrectangle.h b/src/core/qgsrectangle.h index ce5b5605182..26fc4813901 100644 --- a/src/core/qgsrectangle.h +++ b/src/core/qgsrectangle.h @@ -21,7 +21,7 @@ #include class QString; - +class QRectF; #include "qgspoint.h" @@ -38,6 +38,9 @@ class CORE_EXPORT QgsRectangle QgsRectangle( double xmin = 0, double ymin = 0, double xmax = 0, double ymax = 0 ); //! Construct a rectangle from two points. The rectangle is normalized after construction. QgsRectangle( QgsPoint const & p1, QgsPoint const & p2 ); + //! Construct a rectangle from a QRectF. The rectangle is normalized after construction. + //@note added in 2.0 + QgsRectangle( const QRectF & qRectF ); //! Copy constructor QgsRectangle( const QgsRectangle &other ); //! Destructor @@ -98,8 +101,11 @@ class CORE_EXPORT QgsRectangle //! returns string representation in Wkt form QString asWktCoordinates() const; //! returns string representation as WKT Polygon - //@note added om 2.0 + //@note added in 2.0 QString asWktPolygon() const; + //! returns a QRectF with same coordinates. + //@note added in 2.0 + QRectF toRectF() const; //! returns string representation of form xmin,ymin xmax,ymax QString toString( bool automaticPrecision = false ) const; //! overloaded toString that allows precision of numbers to be set diff --git a/tests/src/core/testqgsrectangle.cpp b/tests/src/core/testqgsrectangle.cpp index 60ce9720cbb..b7d8a0f828c 100644 --- a/tests/src/core/testqgsrectangle.cpp +++ b/tests/src/core/testqgsrectangle.cpp @@ -59,6 +59,15 @@ void TestQgsRectangle::regression6194() // 100 wide, 200 high QgsRectangle rect1 = QgsRectangle( 10.0, 20.0, 110.0, 220.0 ); + // Test conversion to QRectF and back + QRectF qRectF = rect1.toRectF(); + QCOMPARE( qRectF.width(), 100.0 ); + QCOMPARE( qRectF.height(), 200.0 ); + QCOMPARE( qRectF.x(), 10.0 ); + QCOMPARE( qRectF.y(), 20.0 ); + QgsRectangle rect4 = QgsRectangle( qRectF ); + QCOMPARE( rect4.toString( 2 ), QString( "10.00,20.00 : 110.00,220.00" ) ); + // 250 wide, 500 high QgsRectangle rect2; rect2.setXMinimum( 10.0 ); From 96295010d39aba072b097c7c3a8830fa91ee07f9 Mon Sep 17 00:00:00 2001 From: Magnus Homann Date: Sun, 16 Sep 2012 12:07:26 +0200 Subject: [PATCH 2/2] Improved QgsClipper test, and ran prepare-commit --- python/core/qgsrectangle.sip | 2 +- src/core/qgsrectangle.cpp | 6 ++-- tests/src/core/testqgsclipper.cpp | 56 +++++++++++++++++++++---------- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/python/core/qgsrectangle.sip b/python/core/qgsrectangle.sip index 69462ed2d81..13bcbb79416 100644 --- a/python/core/qgsrectangle.sip +++ b/python/core/qgsrectangle.sip @@ -10,7 +10,7 @@ class QgsRectangle %TypeHeaderCode #include %End - + public: //! Constructor QgsRectangle(double xmin=0, double ymin=0, double xmax=0, double ymax=0); diff --git a/src/core/qgsrectangle.cpp b/src/core/qgsrectangle.cpp index 53d49271adf..3b0dbc811c7 100644 --- a/src/core/qgsrectangle.cpp +++ b/src/core/qgsrectangle.cpp @@ -196,7 +196,7 @@ QString QgsRectangle::asWktCoordinates() const QString QgsRectangle::asWktPolygon() const { QString rep = - QString("POLYGON((") + + QString( "POLYGON((" ) + QString::number( xmin, 'f', 16 ) + " " + QString::number( ymin, 'f', 16 ) + ", " + QString::number( xmax, 'f', 16 ) + " " + @@ -207,7 +207,7 @@ QString QgsRectangle::asWktPolygon() const QString::number( ymax, 'f', 16 ) + ", " + QString::number( xmin, 'f', 16 ) + " " + QString::number( ymin, 'f', 16 ) + - QString("))"); + QString( "))" ); return rep; } @@ -216,7 +216,7 @@ QString QgsRectangle::asWktPolygon() const //@note added in 2.0 QRectF QgsRectangle::toRectF() const { - return QRectF( (qreal)xmin, (qreal)ymin, (qreal)xmax - xmin, (qreal)ymax - ymin ); + return QRectF(( qreal )xmin, ( qreal )ymin, ( qreal )xmax - xmin, ( qreal )ymax - ymin ); } // Return a string representation of the rectangle with automatic or high precision diff --git a/tests/src/core/testqgsclipper.cpp b/tests/src/core/testqgsclipper.cpp index 2b6fb247808..31ed704ecc1 100644 --- a/tests/src/core/testqgsclipper.cpp +++ b/tests/src/core/testqgsclipper.cpp @@ -34,36 +34,56 @@ class TestQgsClipper: public QObject void init() {};// will be called before each testfunction is executed. void cleanup() {};// will be called after every testfunction. void basic(); + private: + bool TestQgsClipper::checkBoundingBox( QPolygonF polygon, QgsRectangle clipRect ); }; void TestQgsClipper::initTestCase() { - // - // Runs once before any tests are run - // - // init QGIS's paths - true means that all path will be inited from prefix - // QgsApplication::init(); - // QgsApplication::initQgis(); - // QgsApplication::showSettings(); + } void TestQgsClipper::basic() { - // CQgsClipper is static only - //QgsClipper snipsnip; + // QgsClipper is static only QPolygonF polygon; - polygon << QPointF(10.4, 20.5) << QPointF(20.2, 30.2); - - QgsRectangle clipRect(10, 10, 25, 30 ); - - QgsClipper::trimPolygon( polygon, clipRect ); - - QRectF bBox( polygon.boundingRect() ); - QgsRectangle boundingRect( bBox.bottomLeft().x(), bBox.bottomLeft().y(), bBox.topRight().x(), bBox.topRight().y() ); + polygon << QPointF( 10.4, 20.5 ) << QPointF( 20.2, 30.2 ); - QVERIFY( clipRect.contains( boundingRect ) ); + QgsRectangle clipRect( 10, 10, 25, 30 ); + + QgsClipper::trimPolygon( polygon, clipRect ); + + // Check nothing sticks out. + QVERIFY( checkBoundingBox( polygon , clipRect ) ); + // Check that it didn't clip too much + QgsRectangle clipRectInner( clipRect ); + clipRectInner.scale( 0.999 ); + QVERIFY( ! checkBoundingBox( polygon , clipRectInner ) ); + + // A more complex example + polygon.clear(); + polygon << QPointF( 1.0, 9.0 ) << QPointF( 11.0, 11.0 ) << QPointF( 9.0, 1.0 ); + clipRect.set( 0.0, 0.0, 10.0, 10.0 ); + + QgsClipper::trimPolygon( polygon, clipRect ); + + // We should have 5 vertices now? + QCOMPARE( polygon.size(), 5 ); + // Check nothing sticks out. + QVERIFY( checkBoundingBox( polygon , clipRect ) ); + // Check that it didn't clip too much + clipRectInner = clipRect; + clipRectInner.scale( 0.999 ); + QVERIFY( ! checkBoundingBox( polygon , clipRectInner ) ); }; +bool TestQgsClipper::checkBoundingBox( QPolygonF polygon, QgsRectangle clipRect ) +{ + QgsRectangle bBox( polygon.boundingRect() ); + + return clipRect.contains( bBox ); +} + QTEST_MAIN( TestQgsClipper ) #include "moc_testqgsclipper.cxx"