diff options
-rw-r--r-- | src/imports/positioning/locationsingleton.cpp | 18 | ||||
-rw-r--r-- | src/imports/positioning/locationsingleton.h | 2 | ||||
-rw-r--r-- | src/positioning/qgeocircle.cpp | 11 | ||||
-rw-r--r-- | src/positioning/qgeocircle_p.h | 2 | ||||
-rw-r--r-- | src/positioning/qgeorectangle.cpp | 68 | ||||
-rw-r--r-- | src/positioning/qgeorectangle.h | 1 | ||||
-rw-r--r-- | src/positioning/qgeorectangle_p.h | 2 | ||||
-rw-r--r-- | src/positioning/qgeoshape.cpp | 11 | ||||
-rw-r--r-- | src/positioning/qgeoshape.h | 2 | ||||
-rw-r--r-- | src/positioning/qgeoshape_p.h | 2 | ||||
-rw-r--r-- | tests/auto/auto.pro | 3 | ||||
-rw-r--r-- | tests/auto/declarative_geoshape/declarative_geoshape.pro | 14 | ||||
-rw-r--r-- | tests/auto/declarative_geoshape/main.cpp | 43 | ||||
-rw-r--r-- | tests/auto/declarative_geoshape/tst_locationsingleton.qml (renamed from tests/auto/declarative_core/tst_geoshape.qml) | 26 | ||||
-rw-r--r-- | tests/auto/qgeocircle/tst_qgeocircle.cpp | 52 | ||||
-rw-r--r-- | tests/auto/qgeorectangle/tst_qgeorectangle.cpp | 110 |
16 files changed, 365 insertions, 2 deletions
diff --git a/src/imports/positioning/locationsingleton.cpp b/src/imports/positioning/locationsingleton.cpp index c44db946..0b1a5d6d 100644 --- a/src/imports/positioning/locationsingleton.cpp +++ b/src/imports/positioning/locationsingleton.cpp @@ -140,6 +140,24 @@ QGeoRectangle LocationSingleton::rectangle(const QGeoCoordinate &topLeft, } /*! + \qmlmethod georectangle QtLocation5::QtLocation::rectangle(list<coordinate> coordinates) const + + Constructs a georectangle from the list of coordinates, the returned list is the smallest possible + containing all the coordinates. + + \sa {georectangle} +*/ +QGeoRectangle LocationSingleton::rectangle(const QVariantList &coordinates) const +{ + QList<QGeoCoordinate> internalCoordinates; + for (int i = 0; i < coordinates.size(); i++) { + if (coordinates.at(i).canConvert<QGeoCoordinate>()) + internalCoordinates << coordinates.at(i).value<QGeoCoordinate>(); + } + return QGeoRectangle(internalCoordinates); +} + +/*! \qmlmethod geocircle QtPositioning::circle() const Constructs an invalid geocircle. diff --git a/src/imports/positioning/locationsingleton.h b/src/imports/positioning/locationsingleton.h index b5e6476e..6c8d4496 100644 --- a/src/imports/positioning/locationsingleton.h +++ b/src/imports/positioning/locationsingleton.h @@ -48,6 +48,7 @@ #include <QtPositioning/QGeoShape> #include <QtPositioning/QGeoRectangle> #include <QtPositioning/QGeoCircle> +#include <QVariant> class LocationSingleton : public QObject { @@ -67,6 +68,7 @@ public: double width, double height) const; Q_INVOKABLE QGeoRectangle rectangle(const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight) const; + Q_INVOKABLE QGeoRectangle rectangle(const QVariantList &coordinates) const; Q_INVOKABLE QGeoCircle circle() const; Q_INVOKABLE QGeoCircle circle(const QGeoCoordinate ¢er, qreal radius = -1.0) const; diff --git a/src/positioning/qgeocircle.cpp b/src/positioning/qgeocircle.cpp index f9c43c1c..4a4f67aa 100644 --- a/src/positioning/qgeocircle.cpp +++ b/src/positioning/qgeocircle.cpp @@ -214,6 +214,17 @@ bool QGeoCirclePrivate::contains(const QGeoCoordinate &coordinate) const } /*! + Extends the circle to include \a coordinate +*/ +void QGeoCirclePrivate::extendShape(const QGeoCoordinate &coordinate) +{ + if (!isValid() || !coordinate.isValid() || contains(coordinate)) + return; + + radius = center.distanceTo(coordinate); +} + +/*! Translates this geo circle by \a degreesLatitude northwards and \a degreesLongitude eastwards. Negative values of \a degreesLatitude and \a degreesLongitude correspond to diff --git a/src/positioning/qgeocircle_p.h b/src/positioning/qgeocircle_p.h index e8e4a2c0..2043fdc4 100644 --- a/src/positioning/qgeocircle_p.h +++ b/src/positioning/qgeocircle_p.h @@ -70,6 +70,8 @@ public: bool isEmpty() const; bool contains(const QGeoCoordinate &coordinate) const; + void extendShape(const QGeoCoordinate &coordinate); + QGeoShapePrivate *clone() const; bool operator==(const QGeoShapePrivate &other) const; diff --git a/src/positioning/qgeorectangle.cpp b/src/positioning/qgeorectangle.cpp index 354bdb1c..3c2c0ff8 100644 --- a/src/positioning/qgeorectangle.cpp +++ b/src/positioning/qgeorectangle.cpp @@ -44,7 +44,7 @@ #include "qgeocoordinate.h" #include "qnumeric.h" - +#include <QList> QT_BEGIN_NAMESPACE /*! @@ -140,6 +140,24 @@ QGeoRectangle::QGeoRectangle(const QGeoCoordinate &topLeft, const QGeoCoordinate } /*! + Constructs a georectangle from the list of coordinates, the returned rectangle is the smallest possible + containing all the coordinates. + */ +QGeoRectangle::QGeoRectangle(const QList<QGeoCoordinate> &coordinates) +{ + if (coordinates.isEmpty()) { + d_ptr = new QGeoRectanglePrivate; + } else { + const QGeoCoordinate &startCoordinate = coordinates.first(); + d_ptr = new QGeoRectanglePrivate(startCoordinate, startCoordinate); + + foreach (const QGeoCoordinate &coordinate, coordinates) { + d_ptr->extendShape(coordinate); + } + } +} + +/*! Constructs a geo rectangle from the contents of \a other. */ QGeoRectangle::QGeoRectangle(const QGeoRectangle &other) @@ -735,6 +753,54 @@ QGeoRectangle QGeoRectangle::united(const QGeoRectangle &rectangle) const } /*! + Extends the rectangle in the smallest possible way to include \a coordinate in + the shape. + + Both the rectangle and coordinate needs to be valid. If the rectangle already covers + the coordinate noting happens. + +*/ +void QGeoRectanglePrivate::extendShape(const QGeoCoordinate &coordinate) +{ + if (!isValid() || !coordinate.isValid() || contains(coordinate)) + return; + + double left = topLeft.longitude(); + double right = bottomRight.longitude(); + double top = topLeft.latitude(); + double bottom = bottomRight.latitude(); + + double inputLat = coordinate.latitude(); + double inputLon = coordinate.longitude(); + + top = qMax(top, inputLat); + bottom = qMin(bottom, inputLat); + + bool wrap = left > right; + + if (wrap && inputLon > right && inputLon < left) { + if (qAbs(left - inputLon) < qAbs(right - inputLon)) + left = inputLon; + else + right = inputLon; + } else if (!wrap) { + if (inputLon < left) { + if (360 - (right - inputLon) < left - inputLon) + right = inputLon; + else + left = inputLon; + } else if (inputLon > right) { + if (360 - (inputLon - left) < inputLon - right) + left = inputLon; + else + right = inputLon; + } + } + topLeft = QGeoCoordinate(top, left); + bottomRight = QGeoCoordinate(bottom, right); +} + +/*! \fn QGeoRectangle QGeoRectangle::operator|(const QGeoRectangle &rectangle) const Returns the smallest geo rectangle which contains both this geo rectangle and \a rectangle. diff --git a/src/positioning/qgeorectangle.h b/src/positioning/qgeorectangle.h index cd91c1d7..babbe621 100644 --- a/src/positioning/qgeorectangle.h +++ b/src/positioning/qgeorectangle.h @@ -55,6 +55,7 @@ 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); diff --git a/src/positioning/qgeorectangle_p.h b/src/positioning/qgeorectangle_p.h index 136d4be4..2ce0250e 100644 --- a/src/positioning/qgeorectangle_p.h +++ b/src/positioning/qgeorectangle_p.h @@ -70,6 +70,8 @@ public: bool isEmpty() const; bool contains(const QGeoCoordinate &coordinate) const; + void extendShape(const QGeoCoordinate &coordinate); + QGeoShapePrivate *clone() const; bool operator==(const QGeoShapePrivate &other) const; diff --git a/src/positioning/qgeoshape.cpp b/src/positioning/qgeoshape.cpp index 53799738..46f50c3b 100644 --- a/src/positioning/qgeoshape.cpp +++ b/src/positioning/qgeoshape.cpp @@ -192,6 +192,17 @@ bool QGeoShape::contains(const QGeoCoordinate &coordinate) const return false; } +/*! + Extends the geo shape to also cover the coordinate \a coordinate +*/ +void QGeoShape::extendShape(const QGeoCoordinate &coordinate) +{ + Q_D(QGeoShape); + + if (d) + d->extendShape(coordinate); +} + /*! Returns true if the \a other geo shape is equivalent to this geo shape, otherwise returns diff --git a/src/positioning/qgeoshape.h b/src/positioning/qgeoshape.h index f1cb4cf2..56dbc028 100644 --- a/src/positioning/qgeoshape.h +++ b/src/positioning/qgeoshape.h @@ -69,6 +69,8 @@ public: bool isEmpty() const; bool contains(const QGeoCoordinate &coordinate) const; + void extendShape(const QGeoCoordinate &coordinate); + bool operator==(const QGeoShape &other) const; bool operator!=(const QGeoShape &other) const; diff --git a/src/positioning/qgeoshape_p.h b/src/positioning/qgeoshape_p.h index ec0b8283..f58fe1e8 100644 --- a/src/positioning/qgeoshape_p.h +++ b/src/positioning/qgeoshape_p.h @@ -69,6 +69,8 @@ public: virtual bool isEmpty() const = 0; virtual bool contains(const QGeoCoordinate &coordinate) const = 0; + virtual void extendShape(const QGeoCoordinate &coordinate) = 0; + virtual QGeoShapePrivate *clone() const = 0; virtual bool operator==(const QGeoShapePrivate &other) const; diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index d9517add..ffbd9b84 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -57,7 +57,8 @@ qtHaveModule(location) { qgeocameratiles qtHaveModule(quick) { - SUBDIRS += declarative_core + SUBDIRS += declarative_core \ + declarative_geoshape !mac: SUBDIRS += declarative_ui } diff --git a/tests/auto/declarative_geoshape/declarative_geoshape.pro b/tests/auto/declarative_geoshape/declarative_geoshape.pro new file mode 100644 index 00000000..54331c57 --- /dev/null +++ b/tests/auto/declarative_geoshape/declarative_geoshape.pro @@ -0,0 +1,14 @@ +# QML tests in this directory must not depend on an OpenGL context. + +TEMPLATE = app +TARGET = tst_declarative_geoshape +CONFIG += qmltestcase +SOURCES += main.cpp + +QT += positioning quick + +OTHER_FILES = *.qml +TESTDATA = $$OTHER_FILES +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +CONFIG+=insignificant_test # QTBUG-31798 diff --git a/tests/auto/declarative_geoshape/main.cpp b/tests/auto/declarative_geoshape/main.cpp new file mode 100644 index 00000000..efc51279 --- /dev/null +++ b/tests/auto/declarative_geoshape/main.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +QUICK_TEST_MAIN(declarative_geoshape) diff --git a/tests/auto/declarative_core/tst_geoshape.qml b/tests/auto/declarative_geoshape/tst_locationsingleton.qml index df03125f..58682721 100644 --- a/tests/auto/declarative_core/tst_geoshape.qml +++ b/tests/auto/declarative_geoshape/tst_locationsingleton.qml @@ -90,11 +90,26 @@ Item { property variant br: QtPositioning.coordinate(0, 1) property variant ntr: QtPositioning.coordinate(3, 3) + property variant invalid: QtPositioning.coordinate(100, 190) property variant inside: QtPositioning.coordinate(0.5, 0.5) property variant outside: QtPositioning.coordinate(2, 2) property variant box: QtPositioning.rectangle(tl, br) + property variant coordinates: [bl, tl, tr, br] + property variant coordinates2: [bl, tl, tr, br, ntr] + property variant coordinates3: [tr] + property variant coordinates4: [invalid] + property variant coordinates5: [] + + property variant listBox: QtPositioning.rectangle(coordinates) + property variant listBox2: QtPositioning.rectangle(coordinates2) + property variant listBox3: QtPositioning.rectangle(coordinates3) + property variant listBox4: QtPositioning.rectangle(coordinates4) + property variant listBox5: QtPositioning.rectangle(coordinates5) + + property variant widthBox: QtPositioning.rectangle(inside, 1, 1); + // C++ auto test exists for basics of bounding box, testing here // only added functionality TestCase { @@ -106,6 +121,17 @@ Item { compare (box.contains(outside), false) box.topRight = ntr compare (box.contains(outside), true) + + compare (listBox.isValid, true) + compare (listBox.contains(outside), false) + compare (listBox2.contains(outside), true) + compare (listBox3.isValid, true) + compare (listBox3.isEmpty, true) + compare (listBox4.isValid, false) + compare (listBox5.isValid, false) + + compare (widthBox.contains(inside), true) + compare (widthBox.contains(outside), false) } } } diff --git a/tests/auto/qgeocircle/tst_qgeocircle.cpp b/tests/auto/qgeocircle/tst_qgeocircle.cpp index dde256bd..db8cde66 100644 --- a/tests/auto/qgeocircle/tst_qgeocircle.cpp +++ b/tests/auto/qgeocircle/tst_qgeocircle.cpp @@ -73,6 +73,9 @@ private slots: void contains_data(); void contains(); + void extendShape(); + void extendShape_data(); + void areaComparison(); void areaComparison_data(); @@ -313,6 +316,55 @@ void tst_QGeoCircle::contains() QCOMPARE(area.contains(probe), result); } +void tst_QGeoCircle::extendShape() +{ + QFETCH(QGeoCircle, circle); + QFETCH(QGeoCoordinate, coord); + QFETCH(bool, containsFirst); + QFETCH(bool, containsExtended); + + QCOMPARE(circle.contains(coord), containsFirst); + circle.extendShape(coord); + QCOMPARE(circle.contains(coord), containsExtended); + +} + +void tst_QGeoCircle::extendShape_data() +{ + QTest::addColumn<QGeoCircle>("circle"); + QTest::addColumn<QGeoCoordinate>("coord"); + QTest::addColumn<bool>("containsFirst"); + QTest::addColumn<bool>("containsExtended"); + + QGeoCoordinate co1(20.0, 20.0); + + QTest::newRow("own center") + << QGeoCircle(co1, 100) + << QGeoCoordinate(20.0, 20.0) + << true + << true; + QTest::newRow("inside") + << QGeoCircle(co1, 100) + << QGeoCoordinate(20.0001, 20.0001) + << true + << true; + QTest::newRow("far away") + << QGeoCircle(co1, 100) + << QGeoCoordinate(50.0001, 50.0001) + << false + << true; + QTest::newRow("invalid circle") + << QGeoCircle() + << QGeoCoordinate(20.0, 20.0) + << false + << false; + QTest::newRow("invalid coordinate") + << QGeoCircle(co1, 100) + << QGeoCoordinate(99.0, 190.0) + << false + << false; +} + void tst_QGeoCircle::areaComparison_data() { QTest::addColumn<QGeoShape>("area"); diff --git a/tests/auto/qgeorectangle/tst_qgeorectangle.cpp b/tests/auto/qgeorectangle/tst_qgeorectangle.cpp index d0c9672d..7abc6c4c 100644 --- a/tests/auto/qgeorectangle/tst_qgeorectangle.cpp +++ b/tests/auto/qgeorectangle/tst_qgeorectangle.cpp @@ -56,6 +56,7 @@ private slots: void default_constructor(); void center_constructor(); void corner_constructor(); + void list_constructor(); void copy_constructor(); void assignment(); void destructor(); @@ -95,6 +96,9 @@ private slots: void unite(); void unite_data(); + void extendShape(); + void extendShape_data(); + void areaComparison(); void areaComparison_data(); @@ -126,6 +130,23 @@ void tst_QGeoRectangle::corner_constructor() QCOMPARE(b1.bottomRight(), QGeoCoordinate(0.0, 10.0)); } +void tst_QGeoRectangle::list_constructor() +{ + QList<QGeoCoordinate> coordinates; + QGeoRectangle b1 = QGeoRectangle(coordinates); + QCOMPARE(b1.isValid(), false); + + coordinates << QGeoCoordinate(10.0, 0.0); + b1 = QGeoRectangle(coordinates); + QCOMPARE(b1.isValid(), true); + QCOMPARE(b1.isEmpty(), true); + + coordinates << QGeoCoordinate(0.0, 10.0) << QGeoCoordinate(0.0, 5.0); + b1 = QGeoRectangle(coordinates); + QCOMPARE(b1.topLeft(), QGeoCoordinate(10.0,0.0)); + QCOMPARE(b1.bottomRight(), QGeoCoordinate(0.0, 10.0)); +} + void tst_QGeoRectangle::copy_constructor() { QGeoRectangle b1 = QGeoRectangle(QGeoCoordinate(10.0, 0.0), @@ -2190,6 +2211,95 @@ void tst_QGeoRectangle::unite_data() QGeoCoordinate(-30.0, 180.0)); } + +void tst_QGeoRectangle::extendShape() +{ + QFETCH(QGeoRectangle, box); + QFETCH(QGeoCoordinate, coord); + QFETCH(QGeoRectangle, out); + + box.extendShape(coord); + QCOMPARE(box, out); +} + +void tst_QGeoRectangle::extendShape_data() +{ + QTest::addColumn<QGeoRectangle>("box"); + QTest::addColumn<QGeoCoordinate>("coord"); + QTest::addColumn<QGeoRectangle>("out"); + + QTest::newRow("valid rect - invalid coordinate") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoCoordinate(100.0, 190.0) + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20)); + QTest::newRow("invalid rect - valid coordinate") + << QGeoRectangle() + << QGeoCoordinate(10.0, 10.0) + << QGeoRectangle(); + QTest::newRow("inside rect - not wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoCoordinate(10.0, 10.0) + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20)); + QTest::newRow("lat outside rect - not wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoCoordinate(40.0, 10.0) + << QGeoRectangle(QGeoCoordinate(40.0, -20.0), + QGeoCoordinate(-30.0, 20)); + QTest::newRow("positive lon outside rect - not wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoCoordinate(10.0, 40.0) + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 40)); + QTest::newRow("negative lon outside rect - not wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoCoordinate(10.0, -40.0) + << QGeoRectangle(QGeoCoordinate(30.0, -40.0), + QGeoCoordinate(-30.0, 20.0)); + QTest::newRow("inside rect - wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -160.0)) + << QGeoCoordinate(10.0, -170.0) + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -160.0)); + QTest::newRow("lat outside rect - wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -160.0)) + << QGeoCoordinate(-40.0, -170.0) + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-40.0, -160.0)); + QTest::newRow("positive lon outside rect - wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -160.0)) + << QGeoCoordinate(10.0, 140.0) + << QGeoRectangle(QGeoCoordinate(30.0, 140.0), + QGeoCoordinate(-30.0, -160.0)); + QTest::newRow("negative lon outside rect - wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -160.0)) + << QGeoCoordinate(10.0, -140.0) + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -140.0)); + QTest::newRow("extending over 180 degree line eastward") + << QGeoRectangle(QGeoCoordinate(30.0, 130.0), + QGeoCoordinate(-30.0, 160.0)) + << QGeoCoordinate(10.0, -170.0) + << QGeoRectangle(QGeoCoordinate(30.0, 130.0), + QGeoCoordinate(-30.0, -170)); + QTest::newRow("extending over -180 degree line westward") + << QGeoRectangle(QGeoCoordinate(30.0, -160.0), + QGeoCoordinate(-30.0, -130.0)) + << QGeoCoordinate(10.0, 170.0) + << QGeoRectangle(QGeoCoordinate(30.0, 170.0), + QGeoCoordinate(-30.0, -130)); +} + void tst_QGeoRectangle::areaComparison_data() { QTest::addColumn<QGeoShape>("area"); |