Skip to content

Commit

Permalink
Add methods to convert between QgsRectangle and QgsBox3d
Browse files Browse the repository at this point in the history
Also add volume calculation to QgsBox3d
  • Loading branch information
nyalldawson committed Apr 12, 2017
1 parent 6632fd6 commit 36ca6d2
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 1 deletion.
12 changes: 12 additions & 0 deletions python/core/qgsbox3d.sip
Expand Up @@ -156,6 +156,12 @@ class QgsBox3d
:rtype: float
%End

double volume() const;
%Docstring
Returns the volume of the box.
:rtype: float
%End

QgsBox3d intersect( const QgsBox3d &other ) const;
%Docstring
Returns the intersection of this box and another 3D box.
Expand Down Expand Up @@ -183,6 +189,12 @@ class QgsBox3d
:rtype: bool
%End

QgsRectangle toRectangle() const;
%Docstring
Converts the box to a 2D rectangle.
:rtype: QgsRectangle
%End

};

/************************************************************************
Expand Down
8 changes: 8 additions & 0 deletions python/core/qgsrectangle.sip
Expand Up @@ -290,6 +290,14 @@ Copy constructor
Swap x/y coordinates in the rectangle.
%End

QgsBox3d toBox3d( double zMin, double zMax ) const;
%Docstring
Converts the rectangle to a 3D box, with the specified
zMin and zMax z values.
.. versionadded:: 3.0
:rtype: QgsBox3d
%End

};


Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsbox3d.h
Expand Up @@ -156,6 +156,11 @@ class CORE_EXPORT QgsBox3d
*/
double depth() const { return mZmax - mZmin; }

/**
* Returns the volume of the box.
*/
double volume() const { return mBounds2d.area() * ( mZmax - mZmin ); }

/**
* Returns the intersection of this box and another 3D box.
*/
Expand All @@ -179,6 +184,11 @@ class CORE_EXPORT QgsBox3d
*/
bool contains( const QgsPointV2 &point ) const;

/**
* Converts the box to a 2D rectangle.
*/
QgsRectangle toRectangle() const { return mBounds2d; }

private:

QgsRectangle mBounds2d;
Expand Down
6 changes: 6 additions & 0 deletions src/core/qgsrectangle.cpp
Expand Up @@ -28,6 +28,7 @@
#include "qgspoint.h"
#include "qgsrectangle.h"
#include "qgslogger.h"
#include "qgsbox3d.h"

QgsRectangle::QgsRectangle( double xMin, double yMin, double xMax, double yMax )
: mXmin( xMin )
Expand Down Expand Up @@ -377,6 +378,11 @@ void QgsRectangle::invert()
mYmax = tmp;
}

QgsBox3d QgsRectangle::toBox3d( double zMin, double zMax ) const
{
return QgsBox3d( mXmin, mYmin, zMin, mXmax, mYmax, zMax );
}

QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle )
{
out << rectangle.xMinimum() << rectangle.yMinimum() << rectangle.xMaximum() << rectangle.yMaximum();
Expand Down
8 changes: 8 additions & 0 deletions src/core/qgsrectangle.h
Expand Up @@ -24,6 +24,7 @@

class QString;
class QRectF;
class QgsBox3d;
#include "qgspoint.h"


Expand Down Expand Up @@ -274,6 +275,13 @@ class CORE_EXPORT QgsRectangle
*/
void invert();

/**
* Converts the rectangle to a 3D box, with the specified
* \a zMin and \a zMax z values.
* \since QGIS 3.0
*/
QgsBox3d toBox3d( double zMin, double zMax ) const;

private:

double mXmin;
Expand Down
12 changes: 11 additions & 1 deletion tests/src/python/test_qgsbox3d.py
Expand Up @@ -17,7 +17,8 @@
from qgis.core import (QgsBox3d,
QgsPoint,
QgsPointV2,
QgsWkbTypes)
QgsWkbTypes,
QgsRectangle)

from qgis.testing import unittest

Expand Down Expand Up @@ -145,6 +146,15 @@ def testContainsPoint(self):
self.assertFalse(box.contains(QgsPointV2(QgsWkbTypes.Point, 16, 7)))
self.assertFalse(box.contains(QgsPointV2(QgsWkbTypes.Point, 6, 17)))

def testVolume(self):
box = QgsBox3d(5.0, 6.0, 7.0, 11.0, 13.0, 15.0)
self.assertEqual(box.volume(), 336.0)

def testToRectangle(self):
box = QgsBox3d(5.0, 6.0, 7.0, 11.0, 13.0, 15.0)
rect = box.toRectangle()
self.assertEqual(rect, QgsRectangle(5, 6, 11, 13))


if __name__ == '__main__':
unittest.main()
10 changes: 10 additions & 0 deletions tests/src/python/test_qgsrectangle.py
Expand Up @@ -242,6 +242,16 @@ def testToString(self):
(myExpectedString, myString))
assert myString == myExpectedString, myMessage

def testToBox3d(self):
rect = QgsRectangle(0, 0.1, 0.2, 0.3)
box = rect.toBox3d(0.4, 0.5)
self.assertEqual(box.xMinimum(), 0.0)
self.assertEqual(box.yMinimum(), 0.1)
self.assertEqual(box.zMinimum(), 0.4)
self.assertEqual(box.xMaximum(), 0.2)
self.assertEqual(box.yMaximum(), 0.3)
self.assertEqual(box.zMaximum(), 0.5)


if __name__ == '__main__':
unittest.main()

0 comments on commit 36ca6d2

Please sign in to comment.