1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtPositioning module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39#include "qgeopositioninfo.h"
40#include "qgeopositioninfo_p.h"
41#include <QHash>
42#include <QDebug>
43#include <QDataStream>
44#include <QtCore/QtNumeric>
45
46#include <algorithm>
47
48QT_BEGIN_NAMESPACE
49
50/*!
51 \class QGeoPositionInfo
52 \inmodule QtPositioning
53 \ingroup QtPositioning-positioning
54 \since 5.2
55
56 \brief The QGeoPositionInfo class contains information gathered on a global position, direction and velocity at a particular point in time.
57
58 A QGeoPositionInfo contains, at a minimum, a geographical coordinate and
59 a timestamp. It may also have heading and speed measurements as well as
60 estimates of the accuracy of the provided data.
61
62 \sa QGeoPositionInfoSource
63*/
64
65/*!
66 \enum QGeoPositionInfo::Attribute
67 Defines the attributes for positional information.
68
69 \value Direction The bearing measured in degrees clockwise from true north to the direction of travel.
70 \value GroundSpeed The ground speed, in meters/sec.
71 \value VerticalSpeed The vertical speed, in meters/sec.
72 \value MagneticVariation The angle between the horizontal component of the magnetic field and true north, in degrees. Also known as magnetic declination. A positive value indicates a clockwise direction from true north and a negative value indicates a counter-clockwise direction.
73 \value HorizontalAccuracy The accuracy of the provided latitude-longitude value, in meters.
74 \value VerticalAccuracy The accuracy of the provided altitude value, in meters.
75*/
76
77/*!
78 Creates an invalid QGeoPositionInfo object.
79
80 \sa isValid()
81*/
82QGeoPositionInfo::QGeoPositionInfo()
83 : d(new QGeoPositionInfoPrivate)
84{
85}
86
87/*!
88 Creates a QGeoPositionInfo for the given \a coordinate and \a timestamp.
89*/
90QGeoPositionInfo::QGeoPositionInfo(const QGeoCoordinate &coordinate, const QDateTime &timestamp)
91 : d(new QGeoPositionInfoPrivate)
92{
93 d->timestamp = timestamp;
94 d->coord = coordinate;
95}
96
97/*!
98 Creates a QGeoPositionInfo with the values of \a other.
99*/
100QGeoPositionInfo::QGeoPositionInfo(const QGeoPositionInfo &other)
101 : d(other.d->clone())
102{
103}
104
105QGeoPositionInfo::QGeoPositionInfo(QGeoPositionInfoPrivate &dd) : d(&dd)
106{
107}
108
109/*!
110 Destroys a QGeoPositionInfo object.
111*/
112QGeoPositionInfo::~QGeoPositionInfo()
113{
114 delete d;
115}
116
117/*!
118 Assigns the values from \a other to this QGeoPositionInfo.
119*/
120QGeoPositionInfo &QGeoPositionInfo::operator=(const QGeoPositionInfo & other)
121{
122 if (this == &other)
123 return *this;
124
125 delete d;
126 d = other.d->clone();
127
128// d->timestamp = other.d->timestamp;
129// d->coord = other.d->coord;
130// d->doubleAttribs = other.d->doubleAttribs;
131
132 return *this;
133}
134
135/*!
136 Returns true if all of this object's values are the same as those of
137 \a other.
138*/
139bool QGeoPositionInfo::operator==(const QGeoPositionInfo &other) const
140{
141 return *d == *other.d;
142}
143
144/*!
145 \fn bool QGeoPositionInfo::operator!=(const QGeoPositionInfo &other) const
146
147 Returns true if any of this object's values are not the same as those of
148 \a other.
149*/
150
151/*!
152 Returns true if the timestamp() and coordinate() values are both valid.
153
154 \sa QGeoCoordinate::isValid(), QDateTime::isValid()
155*/
156bool QGeoPositionInfo::isValid() const
157{
158 return d->timestamp.isValid() && d->coord.isValid();
159}
160
161/*!
162 Sets the date and time at which this position was reported to \a timestamp.
163
164 The \a timestamp must be in UTC time.
165
166 \sa timestamp()
167*/
168void QGeoPositionInfo::setTimestamp(const QDateTime &timestamp)
169{
170 d->timestamp = timestamp;
171}
172
173/*!
174 Returns the date and time at which this position was reported, in UTC time.
175
176 Returns an invalid QDateTime if no date/time value has been set.
177
178 \sa setTimestamp()
179*/
180QDateTime QGeoPositionInfo::timestamp() const
181{
182 return d->timestamp;
183}
184
185/*!
186 Sets the coordinate for this position to \a coordinate.
187
188 \sa coordinate()
189*/
190void QGeoPositionInfo::setCoordinate(const QGeoCoordinate &coordinate)
191{
192 d->coord = coordinate;
193}
194
195/*!
196 Returns the coordinate for this position.
197
198 Returns an invalid coordinate if no coordinate has been set.
199
200 \sa setCoordinate()
201*/
202QGeoCoordinate QGeoPositionInfo::coordinate() const
203{
204 return d->coord;
205}
206
207/*!
208 Sets the value for \a attribute to \a value.
209
210 \sa attribute()
211*/
212void QGeoPositionInfo::setAttribute(Attribute attribute, qreal value)
213{
214 d->doubleAttribs[attribute] = value;
215}
216
217/*!
218 Returns the value of the specified \a attribute as a qreal value.
219
220 Returns NaN if the value has not been set.
221
222 The function hasAttribute() should be used to determine whether or
223 not a value has been set for an attribute.
224
225 \sa hasAttribute(), setAttribute()
226*/
227qreal QGeoPositionInfo::attribute(Attribute attribute) const
228{
229 if (d->doubleAttribs.contains(akey: attribute))
230 return d->doubleAttribs[attribute];
231 return qQNaN();
232}
233
234/*!
235 Removes the specified \a attribute and its value.
236*/
237void QGeoPositionInfo::removeAttribute(Attribute attribute)
238{
239 d->doubleAttribs.remove(akey: attribute);
240}
241
242/*!
243 Returns true if the specified \a attribute is present for this
244 QGeoPositionInfo object.
245*/
246bool QGeoPositionInfo::hasAttribute(Attribute attribute) const
247{
248 return d->doubleAttribs.contains(akey: attribute);
249}
250
251#ifndef QT_NO_DEBUG_STREAM
252QDebug operator<<(QDebug dbg, const QGeoPositionInfo &info)
253{
254 QDebugStateSaver saver(dbg);
255 dbg.nospace() << "QGeoPositionInfo(" << info.d->timestamp;
256 dbg.nospace() << ", "; // timestamp force dbg.space() -> reverting here
257 dbg << info.d->coord;
258
259 QList<QGeoPositionInfo::Attribute> attribs = info.d->doubleAttribs.keys();
260 std::stable_sort(first: attribs.begin(), last: attribs.end()); // Output a sorted list from an unsorted hash.
261 for (int i = 0; i < attribs.count(); ++i) {
262 dbg << ", ";
263 switch (attribs[i]) {
264 case QGeoPositionInfo::Direction:
265 dbg << "Direction=";
266 break;
267 case QGeoPositionInfo::GroundSpeed:
268 dbg << "GroundSpeed=";
269 break;
270 case QGeoPositionInfo::VerticalSpeed:
271 dbg << "VerticalSpeed=";
272 break;
273 case QGeoPositionInfo::MagneticVariation:
274 dbg << "MagneticVariation=";
275 break;
276 case QGeoPositionInfo::HorizontalAccuracy:
277 dbg << "HorizontalAccuracy=";
278 break;
279 case QGeoPositionInfo::VerticalAccuracy:
280 dbg << "VerticalAccuracy=";
281 break;
282 }
283 dbg << info.d->doubleAttribs[attribs[i]];
284 }
285 dbg << ')';
286 return dbg;
287}
288#endif
289
290
291#ifndef QT_NO_DATASTREAM
292/*!
293 \relates QGeoPositionInfo
294
295 Writes the given \a attr enumeration to the specified \a stream.
296
297 \sa {Serializing Qt Data Types}
298*/
299QDataStream &operator<<(QDataStream &stream, QGeoPositionInfo::Attribute attr)
300{
301 return stream << int(attr);
302}
303
304/*!
305 \relates QGeoPositionInfo
306
307 Reads an attribute enumeration from the specified \a stream info the given \a attr.
308
309 \sa {Serializing Qt Data Types}
310*/
311QDataStream &operator>>(QDataStream &stream, QGeoPositionInfo::Attribute &attr)
312{
313 int a;
314 stream >> a;
315 attr = static_cast<QGeoPositionInfo::Attribute>(a);
316 return stream;
317}
318
319/*!
320 \fn QDataStream &operator<<(QDataStream &stream, const QGeoPositionInfo &info)
321 \relates QGeoPositionInfo
322
323 Writes the given \a info to the specified \a stream.
324
325 \sa {Serializing Qt Data Types}
326*/
327
328QDataStream &operator<<(QDataStream &stream, const QGeoPositionInfo &info)
329{
330 stream << info.d->timestamp;
331 stream << info.d->coord;
332 stream << info.d->doubleAttribs;
333 return stream;
334}
335
336/*!
337 \fn QDataStream &operator>>(QDataStream &stream, QGeoPositionInfo &info)
338 \relates QGeoPositionInfo
339
340 Reads a coordinate from the specified \a stream into the given
341 \a info.
342
343 \sa {Serializing Qt Data Types}
344*/
345
346QDataStream &operator>>(QDataStream &stream, QGeoPositionInfo &info)
347{
348 stream >> info.d->timestamp;
349 stream >> info.d->coord;
350 stream >> info.d->doubleAttribs;
351 return stream;
352}
353#endif
354
355QGeoPositionInfoPrivate::~QGeoPositionInfoPrivate()
356{
357
358}
359
360QGeoPositionInfoPrivate *QGeoPositionInfoPrivate::clone() const
361{
362 return new QGeoPositionInfoPrivate(*this);
363}
364
365bool QGeoPositionInfoPrivate::operator==(const QGeoPositionInfoPrivate &other) const
366{
367 return timestamp == other.timestamp
368 && coord == other.coord
369 && doubleAttribs == other.doubleAttribs;
370}
371
372QGeoPositionInfoPrivate *QGeoPositionInfoPrivate::get(const QGeoPositionInfo &info)
373{
374 return info.d;
375}
376
377QT_END_NAMESPACE
378
379

source code of qtlocation/src/positioning/qgeopositioninfo.cpp