Skip to content

Commit

Permalink
add helper to build a QgsRectangle from a WKT string
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustry authored and nyalldawson committed Oct 11, 2017
1 parent 5515d68 commit 098611c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 0 deletions.
8 changes: 8 additions & 0 deletions python/core/geometry/qgsrectangle.sip
Expand Up @@ -44,6 +44,14 @@ Copy constructor

~QgsRectangle();

static QgsRectangle fromWkt( const QString &wkt );
%Docstring
Creates a new rectangle from a WKT string.
The WKT must contain only 5 vertices, representing a rectangle aligned with X and Y axes.
.. versionadded:: 3.0
:rtype: QgsRectangle
%End

void set( const QgsPointXY &p1, const QgsPointXY &p2 );
%Docstring
Sets the rectangle from two QgsPoints. The rectangle is
Expand Down
19 changes: 19 additions & 0 deletions src/core/geometry/qgsrectangle.cpp
Expand Up @@ -24,6 +24,7 @@
#include <QTransform>
#include <QRegExp>

#include "qgsgeometry.h"
#include "qgspointxy.h"
#include "qgsrectangle.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -59,6 +60,24 @@ QgsRectangle::QgsRectangle( const QgsRectangle &r )
mYmax = r.yMaximum();
}

QgsRectangle QgsRectangle::fromWkt( const QString &wkt )
{
QgsGeometry geom = QgsGeometry::fromWkt( wkt );
if ( geom.isMultipart() )
return QgsRectangle();

QgsPolygon poly = geom.asPolygon();

if ( poly.size() != 1 )
return QgsRectangle();

QgsPolyline polyline = geom.asPolygon().at( 0 );
if ( polyline.size() == 5 && polyline.at( 0 ) == polyline.at( 4 ) && geom.isGeosValid() )
return QgsRectangle( polyline.at( 0 ).x(), polyline.at( 0 ).y(), polyline.at( 2 ).x(), polyline.at( 2 ).y() );
else
return QgsRectangle();
}

void QgsRectangle::set( const QgsPointXY &p1, const QgsPointXY &p2 )
{
mXmin = p1.x();
Expand Down
7 changes: 7 additions & 0 deletions src/core/geometry/qgsrectangle.h
Expand Up @@ -53,6 +53,13 @@ class CORE_EXPORT QgsRectangle
// see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
~QgsRectangle() = default;

/**
* Creates a new rectangle from a WKT string.
* The WKT must contain only 5 vertices, representing a rectangle aligned with X and Y axes.
* \since QGIS 3.0
*/
static QgsRectangle fromWkt( const QString &wkt );

/**
* Sets the rectangle from two QgsPoints. The rectangle is
* normalised after construction.
Expand Down
20 changes: 20 additions & 0 deletions tests/src/core/testqgsrectangle.cpp
Expand Up @@ -26,6 +26,7 @@ class TestQgsRectangle: public QObject
Q_OBJECT
private slots:
void isEmpty();
void fromWkt();
void manipulate();
void regression6194();
void operators();
Expand Down Expand Up @@ -56,6 +57,25 @@ void TestQgsRectangle::isEmpty()
QVERIFY( r.isEmpty() );
}

void TestQgsRectangle::fromWkt()
{
QgsRectangle rect = QgsRectangle::fromWkt( QStringLiteral( "POLYGON((0 0,1 0,1 1,0 1,0 0))" ) );
QVERIFY( ! rect.isEmpty() );
QCOMPARE( rect.xMinimum(), 0.0 );
QCOMPARE( rect.yMinimum(), 0.0 );
QCOMPARE( rect.xMaximum(), 1.0 );
QCOMPARE( rect.yMaximum(), 1.0 );

QVERIFY( rect == QgsRectangle::fromWkt( rect.asWktPolygon() ) );

QVERIFY( QgsRectangle::fromWkt( QStringLiteral( "LINESTRING (0 0,1 0,1 1,0 1,0 0)" ) ).isEmpty() );
QVERIFY( QgsRectangle::fromWkt( QStringLiteral( "MULTIPOLYGON(((0 0,3 0,3 3,0 3,0 0)),((1 1, 1 2, 2 2, 2 1)))" ) ).isEmpty() );
QVERIFY( QgsRectangle::fromWkt( QStringLiteral( "MULTIPOLYGON(((0 0,3 0,3 3,0 3,0 0), (10 10,13 10,13 13,10 13,10 10)))" ) ).isEmpty() );
QVERIFY( QgsRectangle::fromWkt( QStringLiteral( "POLYGON((0 0,1 0,1 1,0 1,0 1))" ) ).isEmpty() );
QVERIFY( QgsRectangle::fromWkt( QStringLiteral( "POLYGON((0 0,1 0,1 1,0 1,0 1))" ) ).isEmpty() );
QVERIFY( QgsRectangle::fromWkt( QStringLiteral( "POLYGON((0 0,1 0,1 1,0 1))" ) ).isEmpty() );
}

void TestQgsRectangle::manipulate()
{
// Set up two intersecting rectangles and normalize
Expand Down

0 comments on commit 098611c

Please sign in to comment.