6#include "GeoDataTrack.h"
7#include "GeoDataGeometry_p.h"
9#include "GeoDataLatLonAltBox.h"
10#include "GeoDataTypes.h"
11#include "MarbleDebug.h"
13#include "GeoDataExtendedData.h"
14#include "GeoDataLineString.h"
22class GeoDataTrackPrivate :
public GeoDataGeometryPrivate
26 : m_lineStringNeedsUpdate(false)
27 , m_interpolate(false)
31 GeoDataGeometryPrivate *copy()
const override
33 return new GeoDataTrackPrivate(*
this);
36 void equalizeWhenSize()
38 m_when.
reserve(m_coordinates.size());
39 while (m_when.
size() < m_coordinates.size()) {
45 mutable GeoDataLineString m_lineString;
46 mutable bool m_lineStringNeedsUpdate;
53 GeoDataExtendedData m_extendedData;
56GeoDataTrack::GeoDataTrack()
57 : GeoDataGeometry(new GeoDataTrackPrivate())
61GeoDataTrack::GeoDataTrack(
const GeoDataTrack &other)
65GeoDataTrack &GeoDataTrack::operator=(
const GeoDataTrack &other) =
default;
67const char *GeoDataTrack::nodeType()
const
69 return GeoDataTypes::GeoDataTrackType;
72EnumGeometryId GeoDataTrack::geometryId()
const
74 return GeoDataTrackId;
77GeoDataGeometry *GeoDataTrack::copy()
const
79 return new GeoDataTrack(*
this);
85 const GeoDataTrackPrivate *
const otherD = other.d_func();
87 return equals(other) && d->m_when == otherD->m_when && d->m_coordinates == otherD->m_coordinates && d->m_extendedData == otherD->m_extendedData
88 && d->m_interpolate == otherD->m_interpolate;
91bool GeoDataTrack::operator!=(
const GeoDataTrack &other)
const
93 return !this->operator==(other);
96int GeoDataTrack::size()
const
99 return d->m_coordinates.size();
102bool GeoDataTrack::interpolate()
const
105 return d->m_interpolate;
108void GeoDataTrack::setInterpolate(
bool on)
113 d->m_interpolate = on;
120 if (d->m_when.isEmpty()) {
124 return d->m_when.first();
131 if (d->m_when.isEmpty()) {
135 return d->m_when.last();
141 return d->m_coordinates;
154 if (d->m_when.isEmpty()) {
158 if (d->m_when.contains(when)) {
160 const int index = d->m_when.indexOf(when);
161 if (index < d->m_coordinates.size()) {
162 return d->m_coordinates.at(index);
166 if (!interpolate()) {
172 for (
int i = 0; i < qMin(d->m_when.size(), d->m_coordinates.size()); ++i) {
173 if (d->m_when.at(i).isValid()) {
174 pointMap[d->m_when.at(i)] = d->m_coordinates.at(i);
181 if (nextEntry == pointMap.constBegin()) {
182 mDebug() <<
"No tracked point before " << when;
186 if (nextEntry == pointMap.constEnd()) {
187 mDebug() <<
"No track point after" << when;
194 QDateTime previousWhen = previousEntry.key();
198 int interval = previousWhen.
msecsTo(nextWhen);
199 int position = previousWhen.
msecsTo(when);
200 qreal t = (qreal)position / (qreal)interval;
208 return d->m_coordinates.at(index);
216 d->equalizeWhenSize();
217 d->m_lineStringNeedsUpdate =
true;
219 while (i < d->m_when.size()) {
220 if (d->m_when.at(i) > when) {
225 d->m_when.insert(i, when);
226 d->m_coordinates.insert(i, coord);
234 d->equalizeWhenSize();
235 d->m_lineStringNeedsUpdate =
true;
236 d->m_coordinates.append(coord);
239void GeoDataTrack::appendAltitude(qreal altitude)
244 d->m_lineStringNeedsUpdate =
true;
245 Q_ASSERT(!d->m_coordinates.isEmpty());
246 if (d->m_coordinates.isEmpty()) {
251 d->m_coordinates.append(coordinates);
259 d->m_when.append(when);
262void GeoDataTrack::clear()
268 d->m_coordinates.clear();
269 d->m_lineStringNeedsUpdate =
true;
277 Q_ASSERT(d->m_coordinates.size() == d->m_when.size());
278 if (d->m_when.isEmpty()) {
281 d->equalizeWhenSize();
283 while (!d->m_when.isEmpty() && d->m_when.first() < when) {
284 d->m_when.takeFirst();
285 d->m_coordinates.takeFirst();
294 Q_ASSERT(d->m_coordinates.size() == d->m_when.size());
295 if (d->m_when.isEmpty()) {
298 d->equalizeWhenSize();
299 while (!d->m_when.isEmpty() && d->m_when.last() > when) {
300 d->m_when.takeLast();
301 d->m_coordinates.takeLast();
308 if (d->m_lineStringNeedsUpdate) {
310 d->m_lineString.append(coordinatesList());
311 d->m_lineStringNeedsUpdate =
false;
313 return &d->m_lineString;
321 return d->m_extendedData;
327 return d->m_extendedData;
335 d->m_extendedData = extendedData;
340 return lineString()->latLonAltBox();
346 GeoDataGeometry::pack(stream);
351 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
void append(QList< T > &&value)
void reserve(qsizetype size)
qsizetype size() const const