Changeset View
Changeset View
Standalone View
Standalone View
src/lib/marble/geodata/data/GeoDataTrack.cpp
Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Line(s) | 29 | public: | |||
---|---|---|---|---|---|
43 | { | 43 | { | ||
44 | m_when.reserve(m_coordinates.size()); | 44 | m_when.reserve(m_coordinates.size()); | ||
45 | while ( m_when.size() < m_coordinates.size() ) { | 45 | while ( m_when.size() < m_coordinates.size() ) { | ||
46 | //fill coordinates without time information with null QDateTime | 46 | //fill coordinates without time information with null QDateTime | ||
47 | m_when.append( QDateTime() ); | 47 | m_when.append( QDateTime() ); | ||
48 | } | 48 | } | ||
49 | } | 49 | } | ||
50 | 50 | | |||
51 | GeoDataLineString m_lineString; | 51 | mutable GeoDataLineString m_lineString; | ||
52 | bool m_lineStringNeedsUpdate; | 52 | mutable bool m_lineStringNeedsUpdate; | ||
53 | 53 | | |||
54 | bool m_interpolate; | 54 | bool m_interpolate; | ||
55 | 55 | | |||
56 | QVector<QDateTime> m_when; | 56 | QVector<QDateTime> m_when; | ||
57 | QVector<GeoDataCoordinates> m_coordinates; | 57 | QVector<GeoDataCoordinates> m_coordinates; | ||
58 | 58 | | |||
59 | GeoDataExtendedData m_extendedData; | 59 | GeoDataExtendedData m_extendedData; | ||
60 | }; | 60 | }; | ||
Show All 15 Lines | 75 | { | |||
76 | GeoDataGeometry::operator=( other ); | 76 | GeoDataGeometry::operator=( other ); | ||
77 | 77 | | |||
78 | return *this; | 78 | return *this; | ||
79 | } | 79 | } | ||
80 | 80 | | |||
81 | 81 | | |||
82 | bool GeoDataTrack::operator==( const GeoDataTrack& other ) const | 82 | bool GeoDataTrack::operator==( const GeoDataTrack& other ) const | ||
83 | { | 83 | { | ||
84 | Q_D(const GeoDataTrack); | ||||
85 | const GeoDataTrackPrivate * const otherD = other.d_func(); | ||||
86 | | ||||
84 | return equals(other) && | 87 | return equals(other) && | ||
85 | p()->m_when == other.p()->m_when && | 88 | d->m_when == otherD->m_when && | ||
86 | p()->m_coordinates == other.p()->m_coordinates && | 89 | d->m_coordinates == otherD->m_coordinates && | ||
87 | p()->m_extendedData == other.p()->m_extendedData && | 90 | d->m_extendedData == otherD->m_extendedData && | ||
88 | p()->m_interpolate == other.p()->m_interpolate; | 91 | d->m_interpolate == otherD->m_interpolate; | ||
89 | } | 92 | } | ||
90 | 93 | | |||
91 | bool GeoDataTrack::operator!=( const GeoDataTrack& other ) const | 94 | bool GeoDataTrack::operator!=( const GeoDataTrack& other ) const | ||
92 | { | 95 | { | ||
93 | return !this->operator==( other ); | 96 | return !this->operator==( other ); | ||
94 | } | 97 | } | ||
95 | 98 | | |||
96 | int GeoDataTrack::size() const | 99 | int GeoDataTrack::size() const | ||
97 | { | 100 | { | ||
98 | return p()->m_coordinates.size(); | 101 | Q_D(const GeoDataTrack); | ||
102 | return d->m_coordinates.size(); | ||||
99 | } | 103 | } | ||
100 | 104 | | |||
101 | bool GeoDataTrack::interpolate() const | 105 | bool GeoDataTrack::interpolate() const | ||
102 | { | 106 | { | ||
103 | return p()->m_interpolate; | 107 | Q_D(const GeoDataTrack); | ||
108 | return d->m_interpolate; | ||||
104 | } | 109 | } | ||
105 | 110 | | |||
106 | void GeoDataTrack::setInterpolate(bool on) | 111 | void GeoDataTrack::setInterpolate(bool on) | ||
107 | { | 112 | { | ||
108 | detach(); | 113 | detach(); | ||
109 | 114 | | |||
110 | p()->m_interpolate = on; | 115 | Q_D(GeoDataTrack); | ||
116 | d->m_interpolate = on; | ||||
111 | } | 117 | } | ||
112 | 118 | | |||
113 | QDateTime GeoDataTrack::firstWhen() const | 119 | QDateTime GeoDataTrack::firstWhen() const | ||
114 | { | 120 | { | ||
115 | if ( p()->m_when.isEmpty() ) { | 121 | Q_D(const GeoDataTrack); | ||
122 | | ||||
123 | if (d->m_when.isEmpty()) { | ||||
116 | return QDateTime(); | 124 | return QDateTime(); | ||
117 | } | 125 | } | ||
118 | 126 | | |||
119 | return p()->m_when.first(); | 127 | return d->m_when.first(); | ||
120 | } | 128 | } | ||
121 | 129 | | |||
122 | QDateTime GeoDataTrack::lastWhen() const | 130 | QDateTime GeoDataTrack::lastWhen() const | ||
123 | { | 131 | { | ||
124 | if ( p()->m_when.isEmpty() ) { | 132 | Q_D(const GeoDataTrack); | ||
133 | | ||||
134 | if (d->m_when.isEmpty()) { | ||||
125 | return QDateTime(); | 135 | return QDateTime(); | ||
126 | } | 136 | } | ||
127 | 137 | | |||
128 | return p()->m_when.last(); | 138 | return d->m_when.last(); | ||
129 | } | 139 | } | ||
130 | 140 | | |||
131 | QVector<GeoDataCoordinates> GeoDataTrack::coordinatesList() const | 141 | QVector<GeoDataCoordinates> GeoDataTrack::coordinatesList() const | ||
132 | { | 142 | { | ||
133 | return p()->m_coordinates; | 143 | Q_D(const GeoDataTrack); | ||
144 | return d->m_coordinates; | ||||
134 | } | 145 | } | ||
135 | 146 | | |||
136 | QVector<QDateTime> GeoDataTrack::whenList() const | 147 | QVector<QDateTime> GeoDataTrack::whenList() const | ||
137 | { | 148 | { | ||
138 | return p()->m_when; | 149 | Q_D(const GeoDataTrack); | ||
150 | return d->m_when; | ||||
139 | } | 151 | } | ||
140 | 152 | | |||
141 | GeoDataCoordinates GeoDataTrack::coordinatesAt( const QDateTime &when ) const | 153 | GeoDataCoordinates GeoDataTrack::coordinatesAt( const QDateTime &when ) const | ||
142 | { | 154 | { | ||
143 | if ( p()->m_when.isEmpty() ) { | 155 | Q_D(const GeoDataTrack); | ||
156 | | ||||
157 | if (d->m_when.isEmpty()) { | ||||
144 | return GeoDataCoordinates(); | 158 | return GeoDataCoordinates(); | ||
145 | } | 159 | } | ||
146 | 160 | | |||
147 | if ( p()->m_when.contains( when ) ) { | 161 | if (d->m_when.contains(when)) { | ||
148 | //exact match found | 162 | //exact match found | ||
149 | int index = p()->m_when.indexOf( when ); | 163 | const int index = d->m_when.indexOf(when); | ||
150 | if ( index < p()->m_coordinates.size() ) { | 164 | if (index < d->m_coordinates.size()) { | ||
151 | return p()->m_coordinates.at( index ); | 165 | return d->m_coordinates.at(index); | ||
152 | } | 166 | } | ||
153 | } | 167 | } | ||
154 | 168 | | |||
155 | if ( !interpolate() ) { | 169 | if ( !interpolate() ) { | ||
156 | return GeoDataCoordinates(); | 170 | return GeoDataCoordinates(); | ||
157 | } | 171 | } | ||
158 | 172 | | |||
159 | typedef QMap<QDateTime, GeoDataCoordinates> PointMap; | 173 | typedef QMap<QDateTime, GeoDataCoordinates> PointMap; | ||
160 | PointMap pointMap; | 174 | PointMap pointMap; | ||
161 | for ( int i = 0; i < qMin( p()->m_when.size(), p()->m_coordinates.size() ); ++i) { | 175 | for (int i = 0; i < qMin(d->m_when.size(), d->m_coordinates.size()); ++i) { | ||
162 | if ( p()->m_when.at( i ).isValid() ) { | 176 | if (d->m_when.at(i).isValid()) { | ||
163 | pointMap[ p()->m_when.at( i ) ] = p()->m_coordinates.at( i ); | 177 | pointMap[d->m_when.at(i)] = d->m_coordinates.at(i); | ||
164 | } | 178 | } | ||
165 | } | 179 | } | ||
166 | 180 | | |||
167 | QMap<QDateTime, GeoDataCoordinates>::const_iterator nextEntry = const_cast<const PointMap&>(pointMap).upperBound( when ); | 181 | QMap<QDateTime, GeoDataCoordinates>::const_iterator nextEntry = const_cast<const PointMap&>(pointMap).upperBound( when ); | ||
168 | 182 | | |||
169 | // No tracked point happened before "when" | 183 | // No tracked point happened before "when" | ||
170 | if ( nextEntry == pointMap.constBegin() ) { | 184 | if ( nextEntry == pointMap.constBegin() ) { | ||
171 | mDebug() << "No tracked point before " << when; | 185 | mDebug() << "No tracked point before " << when; | ||
Show All 22 Lines | |||||
194 | 208 | | |||
195 | qreal alt = previousCoord.altitude() + ( nextCoord.altitude() - previousCoord.altitude() ) * t; | 209 | qreal alt = previousCoord.altitude() + ( nextCoord.altitude() - previousCoord.altitude() ) * t; | ||
196 | 210 | | |||
197 | return GeoDataCoordinates( lon, lat, alt ); | 211 | return GeoDataCoordinates( lon, lat, alt ); | ||
198 | } | 212 | } | ||
199 | 213 | | |||
200 | GeoDataCoordinates GeoDataTrack::coordinatesAt( int index ) const | 214 | GeoDataCoordinates GeoDataTrack::coordinatesAt( int index ) const | ||
201 | { | 215 | { | ||
202 | return p()->m_coordinates.at( index ); | 216 | Q_D(const GeoDataTrack); | ||
217 | return d->m_coordinates.at(index); | ||||
203 | } | 218 | } | ||
204 | 219 | | |||
205 | void GeoDataTrack::addPoint( const QDateTime &when, const GeoDataCoordinates &coord ) | 220 | void GeoDataTrack::addPoint( const QDateTime &when, const GeoDataCoordinates &coord ) | ||
206 | { | 221 | { | ||
207 | detach(); | 222 | detach(); | ||
208 | 223 | | |||
209 | p()->equalizeWhenSize(); | 224 | Q_D(GeoDataTrack); | ||
210 | p()->m_lineStringNeedsUpdate = true; | 225 | d->equalizeWhenSize(); | ||
226 | d->m_lineStringNeedsUpdate = true; | ||||
211 | int i=0; | 227 | int i=0; | ||
212 | while ( i < p()->m_when.size() ) { | 228 | while (i < d->m_when.size()) { | ||
213 | if ( p()->m_when.at( i ) > when ) { | 229 | if (d->m_when.at(i) > when) { | ||
214 | break; | 230 | break; | ||
215 | } | 231 | } | ||
216 | ++i; | 232 | ++i; | ||
217 | } | 233 | } | ||
218 | p()->m_when.insert(i, when ); | 234 | d->m_when.insert(i, when ); | ||
219 | p()->m_coordinates.insert(i, coord ); | 235 | d->m_coordinates.insert(i, coord ); | ||
220 | } | 236 | } | ||
221 | 237 | | |||
222 | void GeoDataTrack::appendCoordinates( const GeoDataCoordinates &coord ) | 238 | void GeoDataTrack::appendCoordinates( const GeoDataCoordinates &coord ) | ||
223 | { | 239 | { | ||
224 | detach(); | 240 | detach(); | ||
225 | 241 | | |||
226 | p()->equalizeWhenSize(); | 242 | Q_D(GeoDataTrack); | ||
227 | p()->m_lineStringNeedsUpdate = true; | 243 | d->equalizeWhenSize(); | ||
228 | p()->m_coordinates.append( coord ); | 244 | d->m_lineStringNeedsUpdate = true; | ||
245 | d->m_coordinates.append(coord); | ||||
229 | } | 246 | } | ||
230 | 247 | | |||
231 | void GeoDataTrack::appendAltitude( qreal altitude ) | 248 | void GeoDataTrack::appendAltitude( qreal altitude ) | ||
232 | { | 249 | { | ||
233 | detach(); | 250 | detach(); | ||
234 | 251 | | |||
235 | p()->m_lineStringNeedsUpdate = true; | 252 | Q_D(GeoDataTrack); | ||
236 | Q_ASSERT( !p()->m_coordinates.isEmpty() ); | 253 | d->m_lineStringNeedsUpdate = true; | ||
237 | if ( p()->m_coordinates.isEmpty() ) return; | 254 | Q_ASSERT(!d->m_coordinates.isEmpty()); | ||
238 | GeoDataCoordinates coordinates = p()->m_coordinates.takeLast(); | 255 | if (d->m_coordinates.isEmpty()) { | ||
256 | return; | ||||
257 | } | ||||
258 | GeoDataCoordinates coordinates = d->m_coordinates.takeLast(); | ||||
239 | coordinates.setAltitude( altitude ); | 259 | coordinates.setAltitude( altitude ); | ||
240 | p()->m_coordinates.append( coordinates ); | 260 | d->m_coordinates.append(coordinates); | ||
241 | } | 261 | } | ||
242 | 262 | | |||
243 | void GeoDataTrack::appendWhen( const QDateTime &when ) | 263 | void GeoDataTrack::appendWhen( const QDateTime &when ) | ||
244 | { | 264 | { | ||
245 | detach(); | 265 | detach(); | ||
246 | 266 | | |||
247 | p()->m_when.append( when ); | 267 | Q_D(GeoDataTrack); | ||
268 | d->m_when.append(when); | ||||
248 | } | 269 | } | ||
249 | 270 | | |||
250 | void GeoDataTrack::clear() | 271 | void GeoDataTrack::clear() | ||
251 | { | 272 | { | ||
252 | detach(); | 273 | detach(); | ||
253 | 274 | | |||
254 | p()->m_when.clear(); | 275 | Q_D(GeoDataTrack); | ||
255 | p()->m_coordinates.clear(); | 276 | d->m_when.clear(); | ||
256 | p()->m_lineStringNeedsUpdate = true; | 277 | d->m_coordinates.clear(); | ||
278 | d->m_lineStringNeedsUpdate = true; | ||||
257 | } | 279 | } | ||
258 | 280 | | |||
259 | void GeoDataTrack::removeBefore( const QDateTime &when ) | 281 | void GeoDataTrack::removeBefore( const QDateTime &when ) | ||
260 | { | 282 | { | ||
261 | detach(); | 283 | detach(); | ||
262 | 284 | | |||
263 | Q_ASSERT( p()->m_coordinates.size() == p()->m_when.size() ); | 285 | Q_D(GeoDataTrack); | ||
264 | if ( p()->m_when.isEmpty() ) { | 286 | Q_ASSERT( d->m_coordinates.size() == d->m_when.size()); | ||
287 | if (d->m_when.isEmpty()) { | ||||
265 | return; | 288 | return; | ||
266 | } | 289 | } | ||
267 | p()->equalizeWhenSize(); | 290 | d->equalizeWhenSize(); | ||
268 | 291 | | |||
269 | while ( !p()->m_when.isEmpty() && p()->m_when.first() < when ) { | 292 | while (!d->m_when.isEmpty() && d->m_when.first() < when) { | ||
270 | p()->m_when.takeFirst(); | 293 | d->m_when.takeFirst(); | ||
271 | p()->m_coordinates.takeFirst(); | 294 | d->m_coordinates.takeFirst(); | ||
272 | } | 295 | } | ||
273 | } | 296 | } | ||
274 | 297 | | |||
275 | void GeoDataTrack::removeAfter( const QDateTime &when ) | 298 | void GeoDataTrack::removeAfter( const QDateTime &when ) | ||
276 | { | 299 | { | ||
277 | detach(); | 300 | detach(); | ||
278 | 301 | | |||
279 | Q_ASSERT( p()->m_coordinates.size() == p()->m_when.size() ); | 302 | Q_D(GeoDataTrack); | ||
280 | if ( p()->m_when.isEmpty() ) { | 303 | Q_ASSERT(d->m_coordinates.size() == d->m_when.size()); | ||
304 | if (d->m_when.isEmpty()) { | ||||
281 | return; | 305 | return; | ||
282 | } | 306 | } | ||
283 | p()->equalizeWhenSize(); | 307 | d->equalizeWhenSize(); | ||
284 | while ( !p()->m_when.isEmpty() && p()->m_when.last() > when ) { | 308 | while (!d->m_when.isEmpty() && d->m_when.last() > when) { | ||
285 | p()->m_when.takeLast(); | 309 | d->m_when.takeLast(); | ||
286 | p()->m_coordinates.takeLast(); | 310 | d->m_coordinates.takeLast(); | ||
287 | | ||||
288 | } | 311 | } | ||
289 | } | 312 | } | ||
290 | 313 | | |||
291 | const GeoDataLineString *GeoDataTrack::lineString() const | 314 | const GeoDataLineString *GeoDataTrack::lineString() const | ||
292 | { | 315 | { | ||
293 | if ( p()->m_lineStringNeedsUpdate ) { | 316 | Q_D(const GeoDataTrack); | ||
294 | p()->m_lineString = GeoDataLineString(); | 317 | if (d->m_lineStringNeedsUpdate) { | ||
295 | p()->m_lineString.append( coordinatesList() ); | 318 | d->m_lineString = GeoDataLineString(); | ||
296 | p()->m_lineStringNeedsUpdate = false; | 319 | d->m_lineString.append( coordinatesList() ); | ||
320 | d->m_lineStringNeedsUpdate = false; | ||||
297 | } | 321 | } | ||
298 | return &p()->m_lineString; | 322 | return &d->m_lineString; | ||
299 | } | 323 | } | ||
300 | 324 | | |||
301 | GeoDataExtendedData& GeoDataTrack::extendedData() const | 325 | GeoDataExtendedData& GeoDataTrack::extendedData() | ||
302 | { | 326 | { | ||
303 | return p()->m_extendedData; | 327 | detach(); | ||
328 | | ||||
329 | Q_D(GeoDataTrack); | ||||
330 | return d->m_extendedData; | ||||
331 | } | ||||
332 | | ||||
333 | const GeoDataExtendedData& GeoDataTrack::extendedData() const | ||||
334 | { | ||||
335 | Q_D(const GeoDataTrack); | ||||
336 | return d->m_extendedData; | ||||
304 | } | 337 | } | ||
305 | 338 | | |||
306 | void GeoDataTrack::setExtendedData( const GeoDataExtendedData& extendedData ) | 339 | void GeoDataTrack::setExtendedData( const GeoDataExtendedData& extendedData ) | ||
307 | { | 340 | { | ||
308 | detach(); | 341 | detach(); | ||
309 | 342 | | |||
310 | p()->m_extendedData = extendedData; | 343 | Q_D(GeoDataTrack); | ||
344 | d->m_extendedData = extendedData; | ||||
311 | } | 345 | } | ||
312 | 346 | | |||
313 | const GeoDataLatLonAltBox& GeoDataTrack::latLonAltBox() const | 347 | const GeoDataLatLonAltBox& GeoDataTrack::latLonAltBox() const | ||
314 | { | 348 | { | ||
315 | return lineString()->latLonAltBox(); | 349 | return lineString()->latLonAltBox(); | ||
316 | } | 350 | } | ||
317 | 351 | | |||
318 | //TODO | 352 | //TODO | ||
319 | void GeoDataTrack::pack( QDataStream& stream ) const | 353 | void GeoDataTrack::pack( QDataStream& stream ) const | ||
320 | { | 354 | { | ||
321 | GeoDataGeometry::pack( stream ); | 355 | GeoDataGeometry::pack( stream ); | ||
322 | } | 356 | } | ||
323 | //TODO | 357 | //TODO | ||
324 | void GeoDataTrack::unpack( QDataStream& stream ) | 358 | void GeoDataTrack::unpack( QDataStream& stream ) | ||
325 | { | 359 | { | ||
326 | GeoDataGeometry::unpack( stream ); | 360 | GeoDataGeometry::unpack( stream ); | ||
327 | } | 361 | } | ||
328 | 362 | | |||
329 | GeoDataTrackPrivate *GeoDataTrack::p() const | | |||
330 | { | | |||
331 | return static_cast<GeoDataTrackPrivate *>( d ); | | |||
332 | } | | |||
333 | | ||||
334 | } | 363 | } |