summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron McCarthy <aaron.mccarthy@jollamobile.com>2014-02-04 13:56:17 +1000
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-10 00:42:29 +0100
commit20ee891ec034783b09c698916fbfc2127f92c803 (patch)
tree5fe8516cca36ec317ae5e63594293bddcb433d8b
parent930de8867937b5a61786e5dc6723b229bf27e529 (diff)
downloadqtlocation-20ee891ec034783b09c698916fbfc2127f92c803.tar.gz
Add direction and vertical speed properties to QML Position type.
The QML and C++ position types now provide the same functionality. Position attributes are always set/reset on every position update. This ensures that old values of speed, accuracy, direction, and vertical speed are not indefinitely reported in QML. Values are set to NaN and if appropriate the associated is valid property is set. [ChangeLog][QtPositioning][Position] Added direction and vertical speed properities. Change-Id: Ia02da8a5bc1cd68489eb58180986df512c24aa2f Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
-rw-r--r--src/imports/positioning/positioning.cpp3
-rw-r--r--src/imports/positioning/qdeclarativeposition.cpp115
-rw-r--r--src/imports/positioning/qdeclarativeposition_p.h28
-rw-r--r--src/imports/positioning/qdeclarativepositionsource.cpp12
-rw-r--r--tests/auto/declarative_core/tst_position.qml10
-rw-r--r--tests/auto/declarative_core/tst_positionsource.qml20
-rw-r--r--tests/auto/positionplugin/plugin.cpp14
7 files changed, 183 insertions, 19 deletions
diff --git a/src/imports/positioning/positioning.cpp b/src/imports/positioning/positioning.cpp
index 669a2624..4314582d 100644
--- a/src/imports/positioning/positioning.cpp
+++ b/src/imports/positioning/positioning.cpp
@@ -55,6 +55,8 @@
#include "locationsingleton.h"
+#include <QtCore/QVariantAnimation>
+
#include <QtQml/qqmlextensionplugin.h>
#include <QtQml/qqml.h>
#include <QtQml/private/qqmlvaluetype_p.h>
@@ -131,6 +133,7 @@ public:
// Introduction of 5.3 version; existing 5.2 exports automatically become availabe under 5.3 as well
minor = 3;
qmlRegisterType<QDeclarativeGeoCoordinateAnimation >(uri, major, minor, "CoordinateAnimation");
+ qmlRegisterType<QDeclarativePosition, 1 >(uri, major, minor, "Position");
} else {
qDebug() << "Unsupported URI given to load positioning QML plugin: " << QLatin1String(uri);
}
diff --git a/src/imports/positioning/qdeclarativeposition.cpp b/src/imports/positioning/qdeclarativeposition.cpp
index fa2bd943..e52c4c2c 100644
--- a/src/imports/positioning/qdeclarativeposition.cpp
+++ b/src/imports/positioning/qdeclarativeposition.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include <QtCore/QtNumeric>
#include "qdeclarativeposition_p.h"
#include <QtQml/qqml.h>
#include <qnmeapositioninfosource.h>
@@ -83,9 +84,10 @@ QT_BEGIN_NAMESPACE
*/
QDeclarativePosition::QDeclarativePosition(QObject *parent)
- : QObject(parent), m_latitudeValid(false), m_longitudeValid(false),
- m_altitudeValid(false), m_speed(-1), m_speedValid(false), m_horizontalAccuracyValid(false),
- m_verticalAccuracyValid(false), m_horizontalAccuracy(-1), m_verticalAccuracy(-1)
+: QObject(parent), m_latitudeValid(false), m_longitudeValid(false), m_altitudeValid(false),
+ m_speed(-1), m_speedValid(false), m_direction(qQNaN()), m_verticalSpeed(qQNaN()),
+ m_horizontalAccuracyValid(false), m_verticalAccuracyValid(false), m_horizontalAccuracy(-1),
+ m_verticalAccuracy(-1)
{
}
@@ -225,9 +227,12 @@ void QDeclarativePosition::setSpeed(double speed)
if (speed == m_speed)
return;
m_speed = speed;
- if (!m_speedValid) {
+ if (!m_speedValid && !qIsNaN(speed)) {
m_speedValid = true;
emit speedValidChanged();
+ } else if (m_speedValid && qIsNaN(speed)) {
+ m_speedValid = false;
+ emit speedValidChanged();
}
emit speedChanged();
}
@@ -250,9 +255,12 @@ void QDeclarativePosition::setHorizontalAccuracy(qreal horizontalAccuracy)
if (horizontalAccuracy == m_horizontalAccuracy)
return;
m_horizontalAccuracy = horizontalAccuracy;
- if (!m_horizontalAccuracyValid) {
+ if (!m_horizontalAccuracyValid && !qIsNaN(horizontalAccuracy)) {
m_horizontalAccuracyValid = true;
emit horizontalAccuracyValidChanged();
+ } else if (m_horizontalAccuracyValid && qIsNaN(horizontalAccuracy)) {
+ m_horizontalAccuracyValid = false;
+ emit horizontalAccuracyValidChanged();
}
emit horizontalAccuracyChanged();
}
@@ -291,9 +299,12 @@ void QDeclarativePosition::setVerticalAccuracy(qreal verticalAccuracy)
if (verticalAccuracy == m_verticalAccuracy)
return;
m_verticalAccuracy = verticalAccuracy;
- if (!m_verticalAccuracyValid) {
+ if (!m_verticalAccuracyValid && !qIsNaN(verticalAccuracy)) {
m_verticalAccuracyValid = true;
emit verticalAccuracyValidChanged();
+ } else if (m_verticalAccuracyValid && qIsNaN(verticalAccuracy)) {
+ m_verticalAccuracyValid = false;
+ emit verticalAccuracyValidChanged();
}
emit verticalAccuracyChanged();
}
@@ -341,6 +352,90 @@ QDateTime QDeclarativePosition::timestamp() const
return m_timestamp;
}
+/*!
+ \qmlproperty bool Position::directionValid
+ \since Qt Positioning 5.3
+
+ This property is true if \l direction has been set (to indicate whether that data has been
+ received or not, as every update does not necessarily contain all data).
+
+ \sa direction
+*/
+bool QDeclarativePosition::isDirectionValid() const
+{
+ return !qIsNaN(m_direction);
+}
+
+/*!
+ \qmlproperty double Position::direction
+ \since Qt Positioning 5.3
+
+ This property holds the value of the direction of travel in degrees from true north.
+
+ It is a read-only property.
+
+ \sa directionValid
+*/
+double QDeclarativePosition::direction() const
+{
+ return m_direction;
+}
+
+void QDeclarativePosition::setDirection(double direction)
+{
+ if (m_direction == direction || (qIsNaN(m_direction) && qIsNaN(direction)))
+ return;
+
+ bool validChanged = qIsNaN(m_direction) || qIsNaN(direction);
+
+ m_direction = direction;
+ emit directionChanged();
+ if (validChanged)
+ emit directionValidChanged();
+}
+
+/*!
+ \qmlproperty bool Position::verticalSpeedValid
+ \since Qt Positioning 5.3
+
+ This property is true if \l verticalSpeed has been set (to indicate whether that data has been
+ received or not, as every update does not necessarily contain all data).
+
+ \sa verticalSpeed
+*/
+bool QDeclarativePosition::isVerticalSpeedValid() const
+{
+ return !qIsNaN(m_verticalSpeed);
+}
+
+/*!
+ \qmlproperty double Position::verticalSpeed
+ \since Qt Positioning 5.3
+
+ This property holds the value of the vertical speed in meters per second.
+
+ It is a read-only property.
+
+ \sa verticalSpeedValid
+*/
+double QDeclarativePosition::verticalSpeed() const
+{
+ return m_verticalSpeed;
+}
+
+void QDeclarativePosition::setVerticalSpeed(double speed)
+{
+ if (m_verticalSpeed == speed || (qIsNaN(m_verticalSpeed) && qIsNaN(speed)))
+ return;
+
+ bool validChanged = qIsNaN(m_verticalSpeed) || qIsNaN(speed);
+
+ m_verticalSpeed = speed;
+ emit verticalSpeedChanged();
+ if (validChanged)
+ emit verticalSpeedValidChanged();
+}
+
void QDeclarativePosition::invalidate()
{
// Invalidate all data
@@ -368,6 +463,14 @@ void QDeclarativePosition::invalidate()
m_verticalAccuracyValid = false;
emit verticalAccuracyValidChanged();
}
+ if (!qIsNaN(m_direction)) {
+ m_direction = qQNaN();
+ emit directionValidChanged();
+ }
+ if (!qIsNaN(m_verticalSpeed)) {
+ m_verticalSpeed = qQNaN();
+ emit verticalSpeedValidChanged();
+ }
}
#include "moc_qdeclarativeposition_p.cpp"
diff --git a/src/imports/positioning/qdeclarativeposition_p.h b/src/imports/positioning/qdeclarativeposition_p.h
index 99c2d8fc..f109b7a7 100644
--- a/src/imports/positioning/qdeclarativeposition_p.h
+++ b/src/imports/positioning/qdeclarativeposition_p.h
@@ -42,12 +42,10 @@
#ifndef QDECLARATIVEPOSITION_H
#define QDECLARATIVEPOSITION_H
-#include <QtCore>
-#include <QDateTime>
-#include <qgeopositioninfosource.h>
-#include <qgeopositioninfo.h>
-#include "qdeclarativecoordinate_p.h"
+#include <QtCore/QObject>
+#include <QtCore/QDateTime>
#include <QtQml/qqml.h>
+#include <QtPositioning/QGeoPositionInfo>
// Define this to get qDebug messages
// #define QDECLARATIVE_POSITION_DEBUG
@@ -73,6 +71,11 @@ class QDeclarativePosition : public QObject
Q_PROPERTY(bool horizontalAccuracyValid READ isHorizontalAccuracyValid NOTIFY horizontalAccuracyValidChanged)
Q_PROPERTY(bool verticalAccuracyValid READ isVerticalAccuracyValid NOTIFY verticalAccuracyValidChanged)
+ Q_PROPERTY(bool directionValid READ isDirectionValid NOTIFY directionValidChanged REVISION 1)
+ Q_PROPERTY(double direction READ direction NOTIFY directionChanged REVISION 1)
+ Q_PROPERTY(bool verticalSpeedValid READ isVerticalSpeedValid NOTIFY verticalSpeedValidChanged REVISION 1)
+ Q_PROPERTY(double verticalSpeed READ verticalSpeed NOTIFY verticalSpeedChanged REVISION 1)
+
public:
explicit QDeclarativePosition(QObject *parent = 0);
@@ -94,6 +97,14 @@ public:
qreal verticalAccuracy() const;
void setVerticalAccuracy(qreal verticalAccuracy);
+ bool isDirectionValid() const;
+ double direction() const;
+ void setDirection(double direction);
+
+ bool isVerticalSpeedValid() const;
+ double verticalSpeed() const;
+ void setVerticalSpeed(double speed);
+
// C++
void setCoordinate(const QGeoCoordinate &coordinate);
void invalidate();
@@ -111,6 +122,11 @@ Q_SIGNALS:
void verticalAccuracyChanged();
void verticalAccuracyValidChanged();
+ Q_REVISION(1) void directionValidChanged();
+ Q_REVISION(1) void directionChanged();
+ Q_REVISION(1) void verticalSpeedValidChanged();
+ Q_REVISION(1) void verticalSpeedChanged();
+
private:
bool m_latitudeValid;
bool m_longitudeValid;
@@ -118,6 +134,8 @@ private:
QDateTime m_timestamp;
double m_speed;
bool m_speedValid;
+ double m_direction;
+ double m_verticalSpeed;
bool m_horizontalAccuracyValid;
bool m_verticalAccuracyValid;
qreal m_horizontalAccuracy;
diff --git a/src/imports/positioning/qdeclarativepositionsource.cpp b/src/imports/positioning/qdeclarativepositionsource.cpp
index a13092fc..317f03c7 100644
--- a/src/imports/positioning/qdeclarativepositionsource.cpp
+++ b/src/imports/positioning/qdeclarativepositionsource.cpp
@@ -43,6 +43,7 @@
#include "qdeclarativeposition_p.h"
#include "error_messages.h"
+#include <QtCore/QCoreApplication>
#include <QtQml/qqmlinfo.h>
#include <QtQml/qqml.h>
#include <qnmeapositioninfosource.h>
@@ -373,12 +374,11 @@ void QDeclarativePositionSource::setPosition(const QGeoPositionInfo &pi)
if (pi.isValid()) {
m_position.setTimestamp(pi.timestamp());
m_position.setCoordinate(pi.coordinate());
- if (pi.hasAttribute(QGeoPositionInfo::GroundSpeed))
- m_position.setSpeed(pi.attribute(QGeoPositionInfo::GroundSpeed));
- if (pi.hasAttribute(QGeoPositionInfo::HorizontalAccuracy))
- m_position.setHorizontalAccuracy(pi.attribute(QGeoPositionInfo::HorizontalAccuracy));
- if (pi.hasAttribute(QGeoPositionInfo::VerticalAccuracy))
- m_position.setVerticalAccuracy(pi.attribute(QGeoPositionInfo::VerticalAccuracy));
+ m_position.setSpeed(pi.attribute(QGeoPositionInfo::GroundSpeed));
+ m_position.setDirection(pi.attribute(QGeoPositionInfo::Direction));
+ m_position.setVerticalSpeed(pi.attribute(QGeoPositionInfo::VerticalSpeed));
+ m_position.setHorizontalAccuracy(pi.attribute(QGeoPositionInfo::HorizontalAccuracy));
+ m_position.setVerticalAccuracy(pi.attribute(QGeoPositionInfo::VerticalAccuracy));
} else {
m_position.invalidate();
}
diff --git a/tests/auto/declarative_core/tst_position.qml b/tests/auto/declarative_core/tst_position.qml
index 8bb42960..07d92328 100644
--- a/tests/auto/declarative_core/tst_position.qml
+++ b/tests/auto/declarative_core/tst_position.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtPositioning 5.2
+import QtPositioning 5.3
TestCase {
id: testCase
@@ -61,6 +61,8 @@ TestCase {
SignalSpy { id: horizontalAccuracyValidSpy; target: defaultPosition; signalName: "horizontalAccuracyValidChanged" }
SignalSpy { id: verticalAccuracySpy; target: defaultPosition; signalName: "verticalAccuracyChanged" }
SignalSpy { id: verticalAccuracyValidSpy; target: defaultPosition; signalName: "verticalAccuracyValidChanged" }
+ SignalSpy { id: directionSpy; target: defaultPosition; signalName: "directionChanged" }
+ SignalSpy { id: verticalSpeedSpy; target: defaultPosition; signalName: "verticalSpeedChanged" }
function test_defaults() {
compare(defaultPosition.latitudeValid, false);
@@ -69,6 +71,10 @@ TestCase {
compare(defaultPosition.speedValid, false);
compare(defaultPosition.horizontalAccuracyValid, false);
compare(defaultPosition.verticalAccuracyValid, false);
+ verify(!defaultPosition.directionValid);
+ verify(isNaN(defaultPosition.direction));
+ verify(!defaultPosition.verticalSpeedValid);
+ verify(isNaN(defaultPosition.verticalSpeed));
}
function test_modifiers() {
@@ -83,6 +89,8 @@ TestCase {
horizontalAccuracyValidSpy.clear();
verticalAccuracySpy.clear();
verticalAccuracyValidSpy.clear();
+ directionSpy.clear();
+ verticalSpeedSpy.clear();
defaultPosition.horizontalAccuracy = 10;
compare(horizontalAccuracySpy.count, 1);
diff --git a/tests/auto/declarative_core/tst_positionsource.qml b/tests/auto/declarative_core/tst_positionsource.qml
index 6cf99d04..405c46ae 100644
--- a/tests/auto/declarative_core/tst_positionsource.qml
+++ b/tests/auto/declarative_core/tst_positionsource.qml
@@ -117,6 +117,8 @@ TestCase {
PositionSource { id: testingSource; name: "test.source"; updateInterval: 1000 }
SignalSpy { id: updateSpy; target: testingSource; signalName: "positionChanged" }
+ SignalSpy { id: directionValidSpy; target: testingSource.position; signalName: "directionValidChanged" }
+ SignalSpy { id: directionSpy; target: testingSource.position; signalName: "directionChanged" }
function test_updateInterval() {
testingSource.updateInterval = 1000;
@@ -139,20 +141,38 @@ TestCase {
function test_updates() {
updateSpy.clear();
+ compare(directionValidSpy.count, 0)
+ compare(directionSpy.count, 0)
+
testingSource.active = true;
tryCompare(updateSpy, "count", 1, 1500);
compare(testingSource.position.coordinate.longitude, 0.1);
compare(testingSource.position.coordinate.latitude, 0.1);
+ compare(directionValidSpy.count, 1)
+ compare(directionSpy.count, 1)
+ fuzzyCompare(testingSource.position.direction, 45, 0.1)
+ verify(!testingSource.position.speedValid)
+ verify(isNaN(testingSource.position.speed))
tryCompare(updateSpy, "count", 2, 1500);
compare(testingSource.position.coordinate.longitude, 0.2);
compare(testingSource.position.coordinate.latitude, 0.2);
+ compare(directionValidSpy.count, 1)
+ compare(directionSpy.count, 2)
+ fuzzyCompare(testingSource.position.direction, 45, 0.1)
+ verify(testingSource.position.speedValid)
+ verify(testingSource.position.speed > 15000)
testingSource.active = false;
wait(2500);
compare(updateSpy.count, 2);
compare(testingSource.position.coordinate.longitude, 0.2);
compare(testingSource.position.coordinate.latitude, 0.2);
+ compare(directionValidSpy.count, 1)
+ compare(directionSpy.count, 2)
+ fuzzyCompare(testingSource.position.direction, 45, 0.1)
+ verify(testingSource.position.speedValid)
+ verify(testingSource.position.speed > 15000)
}
}
diff --git a/tests/auto/positionplugin/plugin.cpp b/tests/auto/positionplugin/plugin.cpp
index a213bbb1..3d6f23ed 100644
--- a/tests/auto/positionplugin/plugin.cpp
+++ b/tests/auto/positionplugin/plugin.cpp
@@ -71,6 +71,7 @@ private:
QTimer *timeoutTimer;
QTimer *singleTimer;
QGeoPositionInfo lastPosition;
+ QDateTime lastUpdateTime;
private slots:
void updatePosition();
@@ -165,9 +166,20 @@ void DummySource::updatePosition()
{
timeoutTimer->stop();
singleTimer->stop();
+
+ const QDateTime now = QDateTime::currentDateTime();
+
QGeoCoordinate coord(lastPosition.coordinate().latitude() + 0.1,
lastPosition.coordinate().longitude() + 0.1);
- QGeoPositionInfo info(coord, QDateTime::currentDateTime());
+
+ QGeoPositionInfo info(coord, now);
+ info.setAttribute(QGeoPositionInfo::Direction, lastPosition.coordinate().azimuthTo(coord));
+ if (lastUpdateTime.isValid()) {
+ double speed = lastPosition.coordinate().distanceTo(coord) / lastUpdateTime.msecsTo(now);
+ info.setAttribute(QGeoPositionInfo::GroundSpeed, 1000 * speed);
+ }
+
+ lastUpdateTime = now;
lastPosition = info;
emit positionUpdated(info);
}