diff options
-rw-r--r-- | src/positioning/qgeocircle.cpp | 125 | ||||
-rw-r--r-- | src/positioning/qgeocircle.h | 4 | ||||
-rw-r--r-- | src/positioning/qgeocircle_p.h | 11 | ||||
-rw-r--r-- | src/positioning/qgeorectangle.cpp | 12 | ||||
-rw-r--r-- | src/positioning/qgeorectangle.h | 86 | ||||
-rw-r--r-- | src/positioning/qgeorectangle_p.h | 2 | ||||
-rw-r--r-- | src/positioning/qgeoshape.cpp | 16 | ||||
-rw-r--r-- | src/positioning/qgeoshape.h | 89 | ||||
-rw-r--r-- | src/positioning/qgeoshape_p.h | 3 | ||||
-rw-r--r-- | src/positioning/qlocationutils_p.h | 49 | ||||
-rw-r--r-- | tests/auto/qgeocircle/tst_qgeocircle.cpp | 38 | ||||
-rw-r--r-- | tests/auto/qgeorectangle/tst_qgeorectangle.cpp | 25 |
12 files changed, 350 insertions, 110 deletions
diff --git a/src/positioning/qgeocircle.cpp b/src/positioning/qgeocircle.cpp index 3f2707a4..9552ac37 100644 --- a/src/positioning/qgeocircle.cpp +++ b/src/positioning/qgeocircle.cpp @@ -42,9 +42,11 @@ #include "qgeocoordinate.h" #include "qnumeric.h" +#include "qlocationutils_p.h" #include "qdoublevector2d_p.h" #include "qdoublevector3d_p.h" +#include <cmath> QT_BEGIN_NAMESPACE /*! @@ -191,12 +193,12 @@ bool QGeoCircle::operator!=(const QGeoCircle &other) const bool QGeoCirclePrivate::isValid() const { - return m_center.isValid() && !qIsNaN(radius) && radius >= -1e-7; + return m_center.isValid() && !qIsNaN(m_radius) && m_radius >= -1e-7; } bool QGeoCirclePrivate::isEmpty() const { - return !isValid() || radius <= 1e-7; + return !isValid() || m_radius <= 1e-7; } /*! @@ -206,7 +208,7 @@ void QGeoCircle::setCenter(const QGeoCoordinate ¢er) { Q_D(QGeoCircle); - d->m_center = center; + d->setCenter(center); } /*! @@ -226,7 +228,7 @@ void QGeoCircle::setRadius(qreal radius) { Q_D(QGeoCircle); - d->radius = radius; + d->setRadius(radius); } /*! @@ -236,7 +238,7 @@ qreal QGeoCircle::radius() const { Q_D(const QGeoCircle); - return d->radius; + return d->m_radius; } bool QGeoCirclePrivate::contains(const QGeoCoordinate &coordinate) const @@ -246,7 +248,7 @@ bool QGeoCirclePrivate::contains(const QGeoCoordinate &coordinate) const // see QTBUG-41447 for details qreal distance = m_center.distanceTo(coordinate); - if (qFuzzyCompare(distance, radius) || distance <= radius) + if (qFuzzyCompare(distance, m_radius) || distance <= m_radius) return true; return false; @@ -257,6 +259,103 @@ QGeoCoordinate QGeoCirclePrivate::center() const return m_center; } +QGeoRectangle QGeoCirclePrivate::boundingGeoRectangle() const +{ + return m_bbox; +} + +void QGeoCirclePrivate::updateBoundingBox() +{ + if (isEmpty()) { + if (m_center.isValid()) { + m_bbox.setTopLeft(m_center); + m_bbox.setBottomRight(m_center); + } + return; + } + + bool crossNorth = crossNorthPole(); + bool crossSouth = crossSouthPole(); + + if (crossNorth && crossSouth) { + // Circle crossing both poles fills the whole map + m_bbox = QGeoRectangle(QGeoCoordinate(90.0, -180.0), QGeoCoordinate(-90.0, 180.0)); + } else if (crossNorth) { + // Circle crossing one pole fills the map in the longitudinal direction + m_bbox = QGeoRectangle(QGeoCoordinate(90.0, -180.0), QGeoCoordinate(m_center.atDistanceAndAzimuth(m_radius, 180.0).latitude(), 180.0)); + } else if (crossSouth) { + m_bbox = QGeoRectangle(QGeoCoordinate(m_center.atDistanceAndAzimuth(m_radius, 0.0).latitude(), -180.0), QGeoCoordinate(-90, 180.0)); + } else { + // Regular circle not crossing anything + + // Calculate geo bounding box of the circle + // + // A circle tangential point with a meridian, together with pole and + // the circle center create a spherical triangle. + // Finding the tangential point with the spherical law of sines: + // + // * lon_delta_in_rad : delta between the circle center and a tangential + // point (absolute value). + // * r_in_rad : angular radius of the circle + // * lat_in_rad : latitude of the circle center + // * alpha_in_rad : angle between meridian and radius of the circle. + // At the tangential point, sin(alpha_in_rad) == 1. + // * lat_delta_in_rad - absolute delta of latitudes between the circle center and + // any of the two points where the great circle going through the circle + // center and the pole crosses the circle. In other words, the points + // on the circle with azimuth 0 or 180. + // + // Using: + // sin(lon_delta_in_rad)/sin(r_in_rad) = sin(alpha_in_rad)/sin(pi/2 - lat_in_rad) + + double r_in_rad = m_radius / QLocationUtils::earthMeanRadius(); // angular r + double lat_delta_in_deg = QLocationUtils::degrees(r_in_rad); + double lon_delta_in_deg = QLocationUtils::degrees(std::asin( + std::sin(r_in_rad) / + std::cos(QLocationUtils::radians(m_center.latitude())) + )); + + QGeoCoordinate topLeft; + topLeft.setLatitude(m_center.latitude() + lat_delta_in_deg); + topLeft.setLongitude(m_center.longitude() - lon_delta_in_deg); + QGeoCoordinate bottomRight; + bottomRight.setLatitude(m_center.latitude() - lat_delta_in_deg); + bottomRight.setLongitude(m_center.longitude() + lon_delta_in_deg); + + m_bbox = QGeoRectangle(topLeft, bottomRight); + } +} + +void QGeoCirclePrivate::setCenter(const QGeoCoordinate &c) +{ + m_center = c; + updateBoundingBox(); +} + +void QGeoCirclePrivate::setRadius(const qreal r) +{ + m_radius = r; + updateBoundingBox(); +} + +bool QGeoCirclePrivate::crossNorthPole() const +{ + const QGeoCoordinate northPole(90.0, m_center.longitude()); + qreal distanceToPole = m_center.distanceTo(northPole); + if (distanceToPole < m_radius) + return true; + return false; +} + +bool QGeoCirclePrivate::crossSouthPole() const +{ + const QGeoCoordinate southPole(-90.0, m_center.longitude()); + qreal distanceToPole = m_center.distanceTo(southPole); + if (distanceToPole < m_radius) + return true; + return false; +} + /*! Extends the circle to include \a coordinate */ @@ -265,7 +364,7 @@ void QGeoCirclePrivate::extendShape(const QGeoCoordinate &coordinate) if (!isValid() || !coordinate.isValid() || contains(coordinate)) return; - radius = m_center.distanceTo(coordinate); + setRadius(m_center.distanceTo(coordinate)); } /*! @@ -307,7 +406,7 @@ void QGeoCircle::translate(double degreesLatitude, double degreesLongitude) lon -= 180; } - d->m_center = QGeoCoordinate(lat, lon); + d->setCenter(QGeoCoordinate(lat, lon)); } /*! @@ -349,18 +448,19 @@ QString QGeoCircle::toString() const *******************************************************************************/ QGeoCirclePrivate::QGeoCirclePrivate() -: QGeoShapePrivate(QGeoShape::CircleType), radius(-1.0) +: QGeoShapePrivate(QGeoShape::CircleType), m_radius(-1.0) { } QGeoCirclePrivate::QGeoCirclePrivate(const QGeoCoordinate ¢er, qreal radius) -: QGeoShapePrivate(QGeoShape::CircleType), m_center(center), radius(radius) +: QGeoShapePrivate(QGeoShape::CircleType), m_center(center), m_radius(radius) { + updateBoundingBox(); } QGeoCirclePrivate::QGeoCirclePrivate(const QGeoCirclePrivate &other) : QGeoShapePrivate(QGeoShape::CircleType), m_center(other.m_center), - radius(other.radius) + m_radius(other.m_radius), m_bbox(other.m_bbox) { } @@ -378,8 +478,7 @@ bool QGeoCirclePrivate::operator==(const QGeoShapePrivate &other) const const QGeoCirclePrivate &otherCircle = static_cast<const QGeoCirclePrivate &>(other); - return radius == otherCircle.radius && m_center == otherCircle.m_center; + return m_radius == otherCircle.m_radius && m_center == otherCircle.m_center; } QT_END_NAMESPACE - diff --git a/src/positioning/qgeocircle.h b/src/positioning/qgeocircle.h index b4b6c45e..e8632fe9 100644 --- a/src/positioning/qgeocircle.h +++ b/src/positioning/qgeocircle.h @@ -75,8 +75,8 @@ public: void setRadius(qreal radius); qreal radius() const; - void translate(double degreesLatitude, double degreesLongitude); - QGeoCircle translated(double degreesLatitude, double degreesLongitude) const; + Q_INVOKABLE void translate(double degreesLatitude, double degreesLongitude); + Q_INVOKABLE QGeoCircle translated(double degreesLatitude, double degreesLongitude) const; Q_INVOKABLE QString toString() const; diff --git a/src/positioning/qgeocircle_p.h b/src/positioning/qgeocircle_p.h index 311aba8b..07d79db4 100644 --- a/src/positioning/qgeocircle_p.h +++ b/src/positioning/qgeocircle_p.h @@ -70,6 +70,14 @@ public: QGeoCoordinate center() const Q_DECL_OVERRIDE; + QGeoRectangle boundingGeoRectangle() const Q_DECL_OVERRIDE; + + bool crossNorthPole() const; + bool crossSouthPole() const; + void updateBoundingBox(); + void setCenter(const QGeoCoordinate &c); + void setRadius(const qreal r); + void extendShape(const QGeoCoordinate &coordinate) Q_DECL_OVERRIDE; QGeoShapePrivate *clone() const Q_DECL_OVERRIDE; @@ -77,7 +85,8 @@ public: bool operator==(const QGeoShapePrivate &other) const Q_DECL_OVERRIDE; QGeoCoordinate m_center; - qreal radius; + qreal m_radius; + QGeoRectangle m_bbox; }; QT_END_NAMESPACE diff --git a/src/positioning/qgeorectangle.cpp b/src/positioning/qgeorectangle.cpp index bbcafd6b..a8d74414 100644 --- a/src/positioning/qgeorectangle.cpp +++ b/src/positioning/qgeorectangle.cpp @@ -40,6 +40,8 @@ #include "qgeorectangle.h" #include "qgeorectangle_p.h" +#include "qgeoprojection_p.h" +#include "qdoublevector2d_p.h" #include "qgeocoordinate.h" #include "qnumeric.h" #include <QList> @@ -614,10 +616,7 @@ double QGeoRectangle::height() const Q_D(const QGeoRectangle); - double result = d->topLeft.latitude() - d->bottomRight.latitude(); - if (result < 0.0) - result = qQNaN(); - return result; + return d->topLeft.latitude() - d->bottomRight.latitude(); } bool QGeoRectanglePrivate::contains(const QGeoCoordinate &coordinate) const @@ -674,6 +673,11 @@ QGeoCoordinate QGeoRectanglePrivate::center() const return QGeoCoordinate(cLat, cLon); } +QGeoRectangle QGeoRectanglePrivate::boundingGeoRectangle() const +{ + return QGeoRectangle(topLeft, bottomRight); +} + /*! Returns whether the geo rectangle \a rectangle is contained within this geo rectangle. diff --git a/src/positioning/qgeorectangle.h b/src/positioning/qgeorectangle.h index 7e921730..9e9acf91 100644 --- a/src/positioning/qgeorectangle.h +++ b/src/positioning/qgeorectangle.h @@ -42,89 +42,7 @@ #include <QtPositioning/QGeoShape> -QT_BEGIN_NAMESPACE - -class QGeoCoordinate; -class QGeoRectanglePrivate; - -class Q_POSITIONING_EXPORT QGeoRectangle : public QGeoShape -{ - Q_GADGET - Q_PROPERTY(QGeoCoordinate bottomLeft READ bottomLeft WRITE setBottomLeft) - Q_PROPERTY(QGeoCoordinate bottomRight READ bottomRight WRITE setBottomRight) - Q_PROPERTY(QGeoCoordinate topLeft READ topLeft WRITE setTopLeft) - Q_PROPERTY(QGeoCoordinate topRight READ topRight WRITE setTopRight) - Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter) - Q_PROPERTY(double height READ height WRITE setHeight) - Q_PROPERTY(double width READ width WRITE setWidth) - -public: - QGeoRectangle(); - QGeoRectangle(const QGeoCoordinate ¢er, double degreesWidth, double degreesHeight); - QGeoRectangle(const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight); - QGeoRectangle(const QList<QGeoCoordinate> &coordinates); - QGeoRectangle(const QGeoRectangle &other); - QGeoRectangle(const QGeoShape &other); - - ~QGeoRectangle(); - - QGeoRectangle &operator=(const QGeoRectangle &other); - - using QGeoShape::operator==; - bool operator==(const QGeoRectangle &other) const; - - using QGeoShape::operator!=; - bool operator!=(const QGeoRectangle &other) const; - - void setTopLeft(const QGeoCoordinate &topLeft); - QGeoCoordinate topLeft() const; - - void setTopRight(const QGeoCoordinate &topRight); - QGeoCoordinate topRight() const; - - void setBottomLeft(const QGeoCoordinate &bottomLeft); - QGeoCoordinate bottomLeft() const; - - void setBottomRight(const QGeoCoordinate &bottomRight); - QGeoCoordinate bottomRight() const; - - void setCenter(const QGeoCoordinate ¢er); - QGeoCoordinate center() const; - - void setWidth(double degreesWidth); - double width() const; - - void setHeight(double degreesHeight); - double height() const; - - using QGeoShape::contains; - bool contains(const QGeoRectangle &rectangle) const; - bool intersects(const QGeoRectangle &rectangle) const; - - void translate(double degreesLatitude, double degreesLongitude); - QGeoRectangle translated(double degreesLatitude, double degreesLongitude) const; - - QGeoRectangle united(const QGeoRectangle &rectangle) const; - QGeoRectangle operator|(const QGeoRectangle &rectangle) const; - QGeoRectangle &operator|=(const QGeoRectangle &rectangle); - - Q_INVOKABLE QString toString() const; - -private: - inline QGeoRectanglePrivate *d_func(); - inline const QGeoRectanglePrivate *d_func() const; -}; - -Q_DECLARE_TYPEINFO(QGeoRectangle, Q_MOVABLE_TYPE); - -inline QGeoRectangle QGeoRectangle::operator|(const QGeoRectangle &rectangle) const -{ - return united(rectangle); -} - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QGeoRectangle) +// QGeoRectangle declaration now in qgeoshape.h. +// This file remains for compatibility. #endif - diff --git a/src/positioning/qgeorectangle_p.h b/src/positioning/qgeorectangle_p.h index 188e5548..ee1b1732 100644 --- a/src/positioning/qgeorectangle_p.h +++ b/src/positioning/qgeorectangle_p.h @@ -70,6 +70,8 @@ public: QGeoCoordinate center() const Q_DECL_OVERRIDE; + QGeoRectangle boundingGeoRectangle() const Q_DECL_OVERRIDE; + void extendShape(const QGeoCoordinate &coordinate) Q_DECL_OVERRIDE; QGeoShapePrivate *clone() const Q_DECL_OVERRIDE; diff --git a/src/positioning/qgeoshape.cpp b/src/positioning/qgeoshape.cpp index bac37605..dd358fb5 100644 --- a/src/positioning/qgeoshape.cpp +++ b/src/positioning/qgeoshape.cpp @@ -227,6 +227,22 @@ bool QGeoShape::contains(const QGeoCoordinate &coordinate) const } /*! + Returns a \a QGeoRectangle representing the geographical bounding rectangle of the + geo shape, that defines the latitudinal/longitudinal bounds of the geo shape. + + \since 5.9 +*/ +QGeoRectangle QGeoShape::boundingGeoRectangle() const +{ + Q_D(const QGeoShape); + + if (d) + return d->boundingGeoRectangle(); + else + return QGeoRectangle(); +} + +/*! Returns the coordinate located at the geometric center of the geo shape. \since 5.5 diff --git a/src/positioning/qgeoshape.h b/src/positioning/qgeoshape.h index f8a30358..58e17c7d 100644 --- a/src/positioning/qgeoshape.h +++ b/src/positioning/qgeoshape.h @@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE class QDebug; class QGeoShapePrivate; +class QGeoRectangle; class Q_POSITIONING_EXPORT QGeoShape { @@ -72,10 +73,10 @@ public: bool isValid() const; bool isEmpty() const; Q_INVOKABLE bool contains(const QGeoCoordinate &coordinate) const; + Q_INVOKABLE QGeoRectangle boundingGeoRectangle() const; + Q_INVOKABLE QGeoCoordinate center() const; - QGeoCoordinate center() const; - - void extendShape(const QGeoCoordinate &coordinate); + Q_INVOKABLE void extendShape(const QGeoCoordinate &coordinate); bool operator==(const QGeoShape &other) const; bool operator!=(const QGeoShape &other) const; @@ -104,9 +105,89 @@ Q_POSITIONING_EXPORT QDataStream &operator<<(QDataStream &stream, const QGeoShap Q_POSITIONING_EXPORT QDataStream &operator>>(QDataStream &stream, QGeoShape &shape); #endif + + +// QGeoRectangle is declared here because of QGeoShape::boundingGeoRectangle +class QGeoRectanglePrivate; + +class Q_POSITIONING_EXPORT QGeoRectangle : public QGeoShape +{ + Q_GADGET + Q_PROPERTY(QGeoCoordinate bottomLeft READ bottomLeft WRITE setBottomLeft) + Q_PROPERTY(QGeoCoordinate bottomRight READ bottomRight WRITE setBottomRight) + Q_PROPERTY(QGeoCoordinate topLeft READ topLeft WRITE setTopLeft) + Q_PROPERTY(QGeoCoordinate topRight READ topRight WRITE setTopRight) + Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter) + Q_PROPERTY(double height READ height WRITE setHeight) + Q_PROPERTY(double width READ width WRITE setWidth) + +public: + QGeoRectangle(); + QGeoRectangle(const QGeoCoordinate ¢er, double degreesWidth, double degreesHeight); + QGeoRectangle(const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight); + QGeoRectangle(const QList<QGeoCoordinate> &coordinates); + QGeoRectangle(const QGeoRectangle &other); + QGeoRectangle(const QGeoShape &other); + + ~QGeoRectangle(); + + QGeoRectangle &operator=(const QGeoRectangle &other); + + using QGeoShape::operator==; + bool operator==(const QGeoRectangle &other) const; + + using QGeoShape::operator!=; + bool operator!=(const QGeoRectangle &other) const; + + void setTopLeft(const QGeoCoordinate &topLeft); + QGeoCoordinate topLeft() const; + + void setTopRight(const QGeoCoordinate &topRight); + QGeoCoordinate topRight() const; + + void setBottomLeft(const QGeoCoordinate &bottomLeft); + QGeoCoordinate bottomLeft() const; + + void setBottomRight(const QGeoCoordinate &bottomRight); + QGeoCoordinate bottomRight() const; + + void setCenter(const QGeoCoordinate ¢er); + QGeoCoordinate center() const; + + void setWidth(double degreesWidth); + double width() const; + + void setHeight(double degreesHeight); + double height() const; + + using QGeoShape::contains; + bool contains(const QGeoRectangle &rectangle) const; + Q_INVOKABLE bool intersects(const QGeoRectangle &rectangle) const; + + Q_INVOKABLE void translate(double degreesLatitude, double degreesLongitude); + Q_INVOKABLE QGeoRectangle translated(double degreesLatitude, double degreesLongitude) const; + + Q_INVOKABLE QGeoRectangle united(const QGeoRectangle &rectangle) const; + QGeoRectangle operator|(const QGeoRectangle &rectangle) const; + QGeoRectangle &operator|=(const QGeoRectangle &rectangle); + + Q_INVOKABLE QString toString() const; + +private: + inline QGeoRectanglePrivate *d_func(); + inline const QGeoRectanglePrivate *d_func() const; +}; + +Q_DECLARE_TYPEINFO(QGeoRectangle, Q_MOVABLE_TYPE); + +inline QGeoRectangle QGeoRectangle::operator|(const QGeoRectangle &rectangle) const +{ + return united(rectangle); +} + QT_END_NAMESPACE Q_DECLARE_METATYPE(QGeoShape) +Q_DECLARE_METATYPE(QGeoRectangle) #endif - diff --git a/src/positioning/qgeoshape_p.h b/src/positioning/qgeoshape_p.h index 275886ff..251e872c 100644 --- a/src/positioning/qgeoshape_p.h +++ b/src/positioning/qgeoshape_p.h @@ -69,6 +69,8 @@ public: virtual QGeoCoordinate center() const = 0; + virtual QGeoRectangle boundingGeoRectangle() const = 0; + virtual void extendShape(const QGeoCoordinate &coordinate) = 0; virtual QGeoShapePrivate *clone() const = 0; @@ -89,4 +91,3 @@ Q_INLINE_TEMPLATE QGeoShapePrivate *QSharedDataPointer<QGeoShapePrivate>::clone( QT_END_NAMESPACE #endif - diff --git a/src/positioning/qlocationutils_p.h b/src/positioning/qlocationutils_p.h index 00c4d3e3..32addb63 100644 --- a/src/positioning/qlocationutils_p.h +++ b/src/positioning/qlocationutils_p.h @@ -53,6 +53,14 @@ #include <QtCore/QtGlobal> #include <math.h> +#ifndef M_1_180 +#define M_1_180 0.0055555555555555555555555555555555555555556 +#endif + +#ifndef M_1_PI +#define M_1_PI 0.31830988618379067154 +#endif + QT_BEGIN_NAMESPACE class QTime; class QByteArray; @@ -176,6 +184,47 @@ public: return CardinalNNW; } + // For values exceeding +- 720.0 + inline static double wrapLongExt(double lng) { + double remainder = fmod(lng + 180.0, 360.0); + return fmod(remainder + 360.0, 360.0) - 180.0; + } + + // Mirrors the azimuth against the X axis. Azimuth assumed to be in [0,360[ + inline static double mirrorAzimuthX(double azimuth) { + if (azimuth <= 90.0) + return 180.0 - azimuth; + else + return 180.0 + (360.0 - azimuth); + } + + // Mirrors the azimuth against the Y axis. Azimuth assumed to be in [0,360[ + inline static double mirrorAzimuthY(double azimuth) { + if (azimuth == 0.0) + return 0.0; + return 360.0 - azimuth; + } + + inline static double radians(double degrees) + { + return degrees * M_PI * M_1_180; + } + + inline static double degrees(double radians) + { + return radians * 180.0 * M_1_PI; + } + + inline static double earthMeanRadius() + { + return 6371007.2; + } + + inline static double mercatorMaxLatitude() + { + return 85.05113; + } + /* Creates a QGeoPositionInfo from a GGA, GLL, RMC, VTG or ZDA sentence. diff --git a/tests/auto/qgeocircle/tst_qgeocircle.cpp b/tests/auto/qgeocircle/tst_qgeocircle.cpp index 01fbed6b..6422a8aa 100644 --- a/tests/auto/qgeocircle/tst_qgeocircle.cpp +++ b/tests/auto/qgeocircle/tst_qgeocircle.cpp @@ -60,6 +60,9 @@ private slots: void contains_data(); void contains(); + void boundingGeoRectangle_data(); + void boundingGeoRectangle(); + void extendShape(); void extendShape_data(); @@ -281,7 +284,7 @@ void tst_QGeoCircle::contains_data() QTest::addColumn<QGeoCoordinate>("probe"); QTest::addColumn<bool>("result"); - QTest::newRow("own centre") << QGeoCoordinate(1,1) << qreal(100.0) << + QTest::newRow("own center") << QGeoCoordinate(1,1) << qreal(100.0) << QGeoCoordinate(1,1) << true; QTest::newRow("over the hills") << QGeoCoordinate(1,1) << qreal(100.0) << QGeoCoordinate(30, 40) << false; @@ -291,6 +294,7 @@ void tst_QGeoCircle::contains_data() QGeoCoordinate(1.00077538, 0.99955527) << true; QTest::newRow("at 1.01*radius") << QGeoCoordinate(1,1) << qreal(100.0) << QGeoCoordinate(1.00071413, 0.99943423) << false; + // TODO: add tests for edge circle cases: cross 1 pole, cross both poles } void tst_QGeoCircle::contains() @@ -307,6 +311,38 @@ void tst_QGeoCircle::contains() QCOMPARE(area.contains(probe), result); } +void tst_QGeoCircle::boundingGeoRectangle_data() +{ + QTest::addColumn<QGeoCoordinate>("center"); + QTest::addColumn<qreal>("radius"); + QTest::addColumn<QGeoCoordinate>("probe"); + QTest::addColumn<bool>("result"); + + QTest::newRow("own center") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1,1) << true; + QTest::newRow("over the hills") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(30, 40) << false; + QTest::newRow("at 0.5*radius") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1.00015374,1.00015274) << true; + QTest::newRow("at 0.99*radius") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1.00077538, 0.99955527) << true; + QTest::newRow("Outside the box") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1.00071413, 0.99903423) << false; + // TODO: add tests for edge circle cases: cross 1 pole, cross both poles +} + +void tst_QGeoCircle::boundingGeoRectangle() +{ + QFETCH(QGeoCoordinate, center); + QFETCH(qreal, radius); + QFETCH(QGeoCoordinate, probe); + QFETCH(bool, result); + + QGeoCircle c(center, radius); + QGeoRectangle box = c.boundingGeoRectangle(); + QCOMPARE(box.contains(probe), result); +} + void tst_QGeoCircle::extendShape() { QFETCH(QGeoCircle, circle); diff --git a/tests/auto/qgeorectangle/tst_qgeorectangle.cpp b/tests/auto/qgeorectangle/tst_qgeorectangle.cpp index 71a3765a..59dc38be 100644 --- a/tests/auto/qgeorectangle/tst_qgeorectangle.cpp +++ b/tests/auto/qgeorectangle/tst_qgeorectangle.cpp @@ -71,6 +71,9 @@ private slots: void center(); void center_data(); + void boundingGeoRectangle(); + void boundingGeoRectangle_data(); + void containsCoord(); void containsCoord_data(); @@ -957,6 +960,28 @@ void tst_QGeoRectangle::center_data() QGeoCoordinate(-90.0, -170.0)); } +void tst_QGeoRectangle::boundingGeoRectangle_data() +{ + QTest::addColumn<QGeoRectangle>("rectangle"); + + QGeoRectangle b1(QGeoCoordinate(70, 30), QGeoCoordinate(30, 70)); + QGeoRectangle b2(QGeoCoordinate(70, 150), QGeoCoordinate(30, -170)); + QGeoRectangle b3(QGeoCoordinate(90, 30), QGeoCoordinate(50, 70)); + QGeoRectangle b4(QGeoCoordinate(-50, 30), QGeoCoordinate(-90, 70)); + + QTest::newRow("Box 1") << b1; + QTest::newRow("Box 2") << b2; + QTest::newRow("Box 3") << b3; + QTest::newRow("Box 4") << b4; +} + +void tst_QGeoRectangle::boundingGeoRectangle() +{ + QFETCH(QGeoRectangle, rectangle); + + QGeoRectangle box = rectangle.boundingGeoRectangle(); + QCOMPARE(box, rectangle); +} void tst_QGeoRectangle::containsCoord() { |