6#include "GeoDataTrack.h"
7#include "GeoDataGeometry_p.h"
9#include "GeoDataLatLonAltBox.h"
10#include "GeoDataTypes.h"
11#include "MarbleDebug.h"
13#include "GeoDataLineString.h"
14#include "GeoDataExtendedData.h"
21class GeoDataTrackPrivate :
public GeoDataGeometryPrivate
25 : m_lineStringNeedsUpdate( false ),
26 m_interpolate( false )
30 GeoDataGeometryPrivate *copy()
const override {
return new GeoDataTrackPrivate( *
this ); }
32 void equalizeWhenSize()
34 m_when.reserve(m_coordinates.size());
35 while ( m_when.size() < m_coordinates.size() ) {
41 mutable GeoDataLineString m_lineString;
42 mutable bool m_lineStringNeedsUpdate;
49 GeoDataExtendedData m_extendedData;
52GeoDataTrack::GeoDataTrack() :
53 GeoDataGeometry( new GeoDataTrackPrivate() )
58GeoDataTrack::GeoDataTrack(
const GeoDataTrack &other )
59 : GeoDataGeometry( other )
64GeoDataTrack &GeoDataTrack::operator=(
const GeoDataTrack &other )
66 GeoDataGeometry::operator=( other );
71const char *GeoDataTrack::nodeType()
const
73 return GeoDataTypes::GeoDataTrackType;
76EnumGeometryId GeoDataTrack::geometryId()
const
78 return GeoDataTrackId;
81GeoDataGeometry *GeoDataTrack::copy()
const
83 return new GeoDataTrack(*
this);
90 const GeoDataTrackPrivate *
const otherD = other.d_func();
92 return equals(other) &&
93 d->m_when == otherD->m_when &&
94 d->m_coordinates == otherD->m_coordinates &&
95 d->m_extendedData == otherD->m_extendedData &&
96 d->m_interpolate == otherD->m_interpolate;
99bool GeoDataTrack::operator!=(
const GeoDataTrack& other )
const
101 return !this->operator==( other );
104int GeoDataTrack::size()
const
107 return d->m_coordinates.size();
110bool GeoDataTrack::interpolate()
const
113 return d->m_interpolate;
116void GeoDataTrack::setInterpolate(
bool on)
121 d->m_interpolate = on;
128 if (d->m_when.isEmpty()) {
132 return d->m_when.first();
139 if (d->m_when.isEmpty()) {
143 return d->m_when.last();
149 return d->m_coordinates;
162 if (d->m_when.isEmpty()) {
166 if (d->m_when.contains(when)) {
168 const int index = d->m_when.indexOf(when);
169 if (index < d->m_coordinates.size()) {
170 return d->m_coordinates.at(index);
174 if ( !interpolate() ) {
180 for (
int i = 0; i < qMin(d->m_when.size(), d->m_coordinates.size()); ++i) {
181 if (d->m_when.at(i).isValid()) {
182 pointMap[d->m_when.at(i)] = d->m_coordinates.at(i);
189 if ( nextEntry == pointMap.constBegin() ) {
190 mDebug() <<
"No tracked point before " << when;
194 if ( nextEntry == pointMap.constEnd() ) {
195 mDebug() <<
"No track point after" << when;
202 QDateTime previousWhen = previousEntry.key();
206 int interval = previousWhen.
msecsTo( nextWhen );
207 int position = previousWhen.
msecsTo( when );
208 qreal t = (qreal)position / (qreal)interval;
216 return d->m_coordinates.at(index);
224 d->equalizeWhenSize();
225 d->m_lineStringNeedsUpdate =
true;
227 while (i < d->m_when.size()) {
228 if (d->m_when.at(i) > when) {
233 d->m_when.insert(i, when );
234 d->m_coordinates.insert(i, coord );
242 d->equalizeWhenSize();
243 d->m_lineStringNeedsUpdate =
true;
244 d->m_coordinates.append(coord);
247void GeoDataTrack::appendAltitude( qreal altitude )
252 d->m_lineStringNeedsUpdate =
true;
253 Q_ASSERT(!d->m_coordinates.isEmpty());
254 if (d->m_coordinates.isEmpty()) {
259 d->m_coordinates.append(coordinates);
267 d->m_when.append(when);
270void GeoDataTrack::clear()
276 d->m_coordinates.clear();
277 d->m_lineStringNeedsUpdate =
true;
285 Q_ASSERT( d->m_coordinates.size() == d->m_when.size());
286 if (d->m_when.isEmpty()) {
289 d->equalizeWhenSize();
291 while (!d->m_when.isEmpty() && d->m_when.first() < when) {
292 d->m_when.takeFirst();
293 d->m_coordinates.takeFirst();
302 Q_ASSERT(d->m_coordinates.size() == d->m_when.size());
303 if (d->m_when.isEmpty()) {
306 d->equalizeWhenSize();
307 while (!d->m_when.isEmpty() && d->m_when.last() > when) {
308 d->m_when.takeLast();
309 d->m_coordinates.takeLast();
316 if (d->m_lineStringNeedsUpdate) {
318 d->m_lineString.append( coordinatesList() );
319 d->m_lineStringNeedsUpdate =
false;
321 return &d->m_lineString;
329 return d->m_extendedData;
335 return d->m_extendedData;
343 d->m_extendedData = extendedData;
348 return lineString()->latLonAltBox();
352void GeoDataTrack::pack(
QDataStream& stream )
const
354 GeoDataGeometry::pack( stream );
359 GeoDataGeometry::unpack( stream );
A 3d point representation.
void setAltitude(const qreal altitude)
set the altitude of the Point in meters
GeoDataCoordinates interpolate(const GeoDataCoordinates &target, double t) const
slerp (spherical linear) interpolation between this coordinate and the given target coordinate
a class which allows to add custom data to KML Feature.
A class that defines a 3D bounding box for geographic data.
A LineString that allows to store a contiguous set of line segments.
A geometry for tracking objects made of (time, coordinates) pairs.
Binds a QML item to a specific geodetic location in screen coordinates.
qint64 msecsTo(const QDateTime &other) const const