• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • src
  • lib
  • marble
PositionTracking.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2007 Andrew Manson <g.real.ate@gmail.com>
9 // Copyright 2009 Eckhart Wörner <ewoerner@kde.org>
10 // Copyright 2010 Thibaut Gridel <tgridel@free.fr>
11 //
12 
13 #include "PositionTracking.h"
14 
15 #include "GeoDataDocument.h"
16 #include "GeoDataMultiTrack.h"
17 #include "GeoDataPlacemark.h"
18 #include "GeoDataParser.h"
19 #include "GeoDataStyle.h"
20 #include "GeoDataStyleMap.h"
21 #include "GeoDataTrack.h"
22 #include "GeoDataTreeModel.h"
23 #include "GeoDataTypes.h"
24 #include "GeoWriter.h"
25 #include "KmlElementDictionary.h"
26 #include "FileManager.h"
27 #include "MarbleMath.h"
28 #include "MarbleDebug.h"
29 #include "MarbleDirs.h"
30 #include "PositionProviderPlugin.h"
31 
32 #include <QFile>
33 
34 namespace Marble
35 {
36 
37 class PositionTrackingPrivate
38 {
39  public:
40  PositionTrackingPrivate( GeoDataTreeModel *model, PositionTracking *parent ) :
41  q( parent ),
42  m_treeModel( model ),
43  m_currentPositionPlacemark( new GeoDataPlacemark ),
44  m_currentTrackPlacemark( new GeoDataPlacemark ),
45  m_trackSegments( new GeoDataMultiTrack ),
46  m_document(),
47  m_positionProvider( 0 ),
48  m_length( 0.0 )
49  {
50  }
51 
52  void updatePosition();
53 
54  void updateStatus();
55 
56  QString statusFile();
57 
58  PositionTracking *const q;
59 
60  GeoDataTreeModel *const m_treeModel;
61 
62  GeoDataPlacemark *const m_currentPositionPlacemark;
63  GeoDataPlacemark *m_currentTrackPlacemark;
64  GeoDataMultiTrack *m_trackSegments;
65  GeoDataDocument m_document;
66 
67  GeoDataCoordinates m_gpsPreviousPosition;
68  GeoDataTrack *m_currentTrack;
69 
70  PositionProviderPlugin* m_positionProvider;
71 
72  qreal m_length;
73 };
74 
75 void PositionTrackingPrivate::updatePosition()
76 {
77  Q_ASSERT( m_positionProvider != 0 );
78 
79  const GeoDataAccuracy accuracy = m_positionProvider->accuracy();
80  const GeoDataCoordinates position = m_positionProvider->position();
81  const QDateTime timestamp = m_positionProvider->timestamp();
82 
83  if ( m_positionProvider->status() == PositionProviderStatusAvailable ) {
84  if ( accuracy.horizontal < 250 ) {
85  if ( m_currentTrack->size() ) {
86  m_length += distanceSphere( m_currentTrack->coordinatesAt( m_currentTrack->size() - 1 ), position );
87  }
88  m_currentTrack->addPoint( timestamp, position );
89  }
90 
91  //if the position has moved then update the current position
92  if ( m_gpsPreviousPosition != position ) {
93  m_currentPositionPlacemark->setCoordinate( position );
94 
95  qreal speed = m_positionProvider->speed();
96  emit q->gpsLocation( position, speed );
97  }
98  }
99 }
100 
101 
102 void PositionTrackingPrivate::updateStatus()
103 {
104  Q_ASSERT( m_positionProvider != 0 );
105 
106  const PositionProviderStatus status = m_positionProvider->status();
107 
108  if (status == PositionProviderStatusAvailable) {
109  m_currentTrack = new GeoDataTrack;
110  m_treeModel->removeFeature( m_currentTrackPlacemark );
111  m_trackSegments->append( m_currentTrack );
112  m_treeModel->addFeature( &m_document, m_currentTrackPlacemark );
113  }
114 
115  emit q->statusChanged( status );
116 }
117 
118 QString PositionTrackingPrivate::statusFile()
119 {
120  QString const subdir = "tracking";
121  QDir dir( MarbleDirs::localPath() );
122  if ( !dir.exists( subdir ) ) {
123  if ( !dir.mkdir( subdir ) ) {
124  mDebug() << "Unable to create dir " << dir.absoluteFilePath( subdir );
125  return dir.absolutePath();
126  }
127  }
128 
129  if ( !dir.cd( subdir ) ) {
130  mDebug() << "Cannot change into " << dir.absoluteFilePath( subdir );
131  }
132 
133  return dir.absoluteFilePath( "track.kml" );
134 }
135 
136 PositionTracking::PositionTracking( GeoDataTreeModel *model )
137  : QObject( model ),
138  d( new PositionTrackingPrivate( model, this ) )
139 {
140  d->m_document.setDocumentRole( TrackingDocument );
141  d->m_document.setName("Position Tracking");
142 
143  // First point is current position
144  d->m_currentPositionPlacemark->setName("Current Position");
145  d->m_currentPositionPlacemark->setVisible(false);
146  d->m_document.append( d->m_currentPositionPlacemark );
147 
148  // Second point is position track
149  d->m_currentTrack = new GeoDataTrack;
150  d->m_trackSegments->append(d->m_currentTrack);
151 
152  d->m_currentTrackPlacemark->setGeometry(d->m_trackSegments);
153  d->m_currentTrackPlacemark->setName("Current Track");
154 
155  GeoDataStyle style;
156  GeoDataLineStyle lineStyle;
157  QColor transparentRed = Oxygen::brickRed4;
158  transparentRed.setAlpha( 200 );
159  lineStyle.setColor( transparentRed );
160  lineStyle.setWidth( 4 );
161  style.setLineStyle(lineStyle);
162  style.setStyleId("track");
163 
164  GeoDataStyleMap styleMap;
165  styleMap.setStyleId("map-track");
166  styleMap.insert("normal", QString("#").append(style.styleId()));
167  d->m_document.addStyleMap(styleMap);
168  d->m_document.addStyle(style);
169  d->m_document.append( d->m_currentTrackPlacemark );
170 
171  d->m_currentTrackPlacemark->setStyleUrl(QString("#").append(styleMap.styleId()));
172 
173  d->m_treeModel->addDocument( &d->m_document );
174 }
175 
176 
177 PositionTracking::~PositionTracking()
178 {
179  d->m_treeModel->removeDocument( &d->m_document );
180  delete d;
181 }
182 
183 void PositionTracking::setPositionProviderPlugin( PositionProviderPlugin* plugin )
184 {
185  const PositionProviderStatus oldStatus = status();
186 
187  if ( d->m_positionProvider ) {
188  delete d->m_positionProvider;
189  }
190 
191  d->m_positionProvider = plugin;
192 
193  if ( d->m_positionProvider ) {
194  d->m_positionProvider->setParent( this );
195  mDebug() << "Initializing position provider:" << d->m_positionProvider->name();
196  connect( d->m_positionProvider, SIGNAL(statusChanged(PositionProviderStatus)),
197  this, SLOT(updateStatus()) );
198  connect( d->m_positionProvider, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)),
199  this, SLOT(updatePosition()) );
200 
201  d->m_positionProvider->initialize();
202  }
203 
204  emit positionProviderPluginChanged( plugin );
205 
206  if ( oldStatus != status() ) {
207  emit statusChanged( status() );
208  }
209 
210  if ( status() == PositionProviderStatusAvailable ) {
211  emit gpsLocation( d->m_positionProvider->position(), d->m_positionProvider->speed() );
212  }
213 }
214 
215 PositionProviderPlugin* PositionTracking::positionProviderPlugin()
216 {
217  return d->m_positionProvider;
218 }
219 
220 QString PositionTracking::error() const
221 {
222  return d->m_positionProvider ? d->m_positionProvider->error() : QString();
223 }
224 
225 
226 //get speed from provider
227 qreal PositionTracking::speed() const
228 {
229  return d->m_positionProvider ? d->m_positionProvider->speed() : 0 ;
230 }
231 
232 //get direction from provider
233 qreal PositionTracking::direction() const
234 {
235  return d->m_positionProvider ? d->m_positionProvider->direction() : 0 ;
236 }
237 
238 QDateTime PositionTracking::timestamp() const
239 {
240  return d->m_positionProvider ? d->m_positionProvider->timestamp() : QDateTime();
241 }
242 
243 bool PositionTracking::trackVisible() const
244 {
245  return d->m_currentTrackPlacemark->isVisible();
246 }
247 
248 void PositionTracking::setTrackVisible( bool visible )
249 {
250  d->m_currentTrackPlacemark->setVisible( visible );
251  d->m_treeModel->updateFeature( d->m_currentTrackPlacemark );
252 }
253 
254 bool PositionTracking::saveTrack( const QString& fileName )
255 {
256 
257  if ( fileName.isEmpty() ) {
258  return false;
259  }
260 
261  GeoWriter writer;
262  //FIXME: a better way to do this?
263  writer.setDocumentType( kml::kmlTag_nameSpace22 );
264 
265  GeoDataDocument *document = new GeoDataDocument;
266  QFileInfo fileInfo( fileName );
267  QString name = fileInfo.baseName();
268  document->setName( name );
269  foreach( const GeoDataStyle &style, d->m_document.styles() ) {
270  document->addStyle( style );
271  }
272  foreach( const GeoDataStyleMap &map, d->m_document.styleMaps() ) {
273  document->addStyleMap( map );
274  }
275  GeoDataPlacemark *track = new GeoDataPlacemark( *d->m_currentTrackPlacemark );
276  track->setName( "Track " + name );
277  document->append( track );
278 
279  QFile file( fileName );
280  file.open( QIODevice::WriteOnly );
281  bool const result = writer.write( &file, document );
282  file.close();
283  delete document;
284  return result;
285 }
286 
287 void PositionTracking::clearTrack()
288 {
289  d->m_treeModel->removeFeature( d->m_currentTrackPlacemark );
290  d->m_currentTrack = new GeoDataTrack;
291  d->m_trackSegments->clear();
292  d->m_trackSegments->append( d->m_currentTrack );
293  d->m_treeModel->addFeature( &d->m_document, d->m_currentTrackPlacemark );
294  d->m_length = 0.0;
295 }
296 
297 void PositionTracking::readSettings()
298 {
299  QFile file( d->statusFile() );
300  if ( !file.open( QIODevice::ReadOnly ) ) {
301  mDebug() << "Can not read track from " << file.fileName();
302  return;
303  }
304 
305  GeoDataParser parser( GeoData_KML );
306  if ( !parser.read( &file ) ) {
307  mDebug() << "Could not parse tracking file: " << parser.errorString();
308  return;
309  }
310 
311  GeoDataDocument *doc = dynamic_cast<GeoDataDocument*>( parser.releaseDocument() );
312  file.close();
313 
314  if( !doc ){
315  mDebug() << "tracking document not available";
316  return;
317  }
318 
319  GeoDataPlacemark *track = dynamic_cast<GeoDataPlacemark*>( doc->child( 0 ) );
320  if( !track ) {
321  mDebug() << "tracking document doesn't have a placemark";
322  delete doc;
323  return;
324  }
325 
326  d->m_trackSegments = dynamic_cast<GeoDataMultiTrack*>( track->geometry() );
327  if( !d->m_trackSegments ) {
328  mDebug() << "tracking document doesn't have a multitrack";
329  delete doc;
330  return;
331  }
332  if( d->m_trackSegments->size() < 1 ) {
333  mDebug() << "tracking document doesn't have a track";
334  delete doc;
335  return;
336  }
337 
338  d->m_currentTrack = dynamic_cast<GeoDataTrack*>( d->m_trackSegments->child( d->m_trackSegments->size() - 1 ) );
339  if( !d->m_currentTrack ) {
340  mDebug() << "tracking document doesn't have a last track";
341  delete doc;
342  return;
343  }
344 
345  doc->remove( 0 );
346  delete doc;
347 
348  d->m_treeModel->removeDocument( &d->m_document );
349  d->m_document.remove( 1 );
350  delete d->m_currentTrackPlacemark;
351  d->m_currentTrackPlacemark = track;
352  d->m_currentTrackPlacemark->setName("Current Track");
353  d->m_document.append( d->m_currentTrackPlacemark );
354  d->m_currentTrackPlacemark->setStyleUrl( d->m_currentTrackPlacemark->styleUrl() );
355 
356  d->m_treeModel->addDocument( &d->m_document );
357  d->m_length = 0.0;
358 }
359 
360 void PositionTracking::writeSettings()
361 {
362  saveTrack( d->statusFile() );
363 }
364 
365 bool PositionTracking::isTrackEmpty() const
366 {
367  if ( d->m_trackSegments->size() < 1 ) {
368  return true;
369  }
370 
371  if ( d->m_trackSegments->size() == 1 ) {
372  return ( d->m_currentTrack->size() == 0 );
373  }
374 
375  return false;
376 }
377 
378 qreal PositionTracking::length( qreal planetRadius ) const
379 {
380  return d->m_length * planetRadius;
381 }
382 
383 GeoDataAccuracy PositionTracking::accuracy() const
384 {
385  return d->m_positionProvider ? d->m_positionProvider->accuracy() : GeoDataAccuracy();
386 }
387 
388 GeoDataCoordinates PositionTracking::currentLocation() const
389 {
390  return d->m_positionProvider ? d->m_positionProvider->position() : GeoDataCoordinates();
391 }
392 
393 PositionProviderStatus PositionTracking::status() const
394 {
395  return d->m_positionProvider ? d->m_positionProvider->status() : PositionProviderStatusUnavailable;
396 }
397 
398 }
399 
400 #include "PositionTracking.moc"
GeoDataDocument.h
Marble::GeoDataLineStyle
specifies the style how lines are drawn
Definition: GeoDataLineStyle.h:36
Marble::PositionTracking::direction
qreal direction() const
provides direction of the gps device in degrees with geographical north
Definition: PositionTracking.cpp:233
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
Marble::GeoDataMultiTrack
Definition: GeoDataMultiTrack.h:25
Marble::GeoDataDocument::addStyleMap
void addStyleMap(const GeoDataStyleMap &map)
Add a stylemap to the stylemap storage.
Definition: GeoDataDocument.cpp:137
FileManager.h
Marble::GeoDataTrack
A geometry for tracking objects made of (time, coordinates) pairs.
Definition: GeoDataTrack.h:54
Marble::GeoDataStyleSelector::setStyleId
void setStyleId(const QString &value)
Set a new style id.
Definition: GeoDataStyleSelector.cpp:60
Marble::PositionTracking::trackVisible
bool trackVisible() const
provides the visibility of the Position Tracking document
Definition: PositionTracking.cpp:243
Marble::GeoDataDocument
A container for Features, Styles and in the future Schemas.
Definition: GeoDataDocument.h:64
Marble::GeoDataContainer::child
GeoDataFeature * child(int)
returns the requested child item
Definition: GeoDataContainer.cpp:132
Marble::GeoDataParser
Definition: GeoDataParser.h:40
Marble::GeoDataTreeModel
The representation of GeoData in a model This class represents all available data given by kml-data f...
Definition: GeoDataTreeModel.h:32
PositionProviderPlugin.h
MarbleMath.h
Marble::PositionTracking::PositionTracking
PositionTracking(GeoDataTreeModel *model)
Definition: PositionTracking.cpp:136
Marble::GeoDataColorStyle::setColor
void setColor(const QColor &value)
Set a new color.
Definition: GeoDataColorStyle.cpp:73
GeoDataStyle.h
GeoDataParser.h
Marble::distanceSphere
qreal distanceSphere(qreal lon1, qreal lat1, qreal lon2, qreal lat2)
This method calculates the shortest distance between two points on a sphere.
Definition: MarbleMath.h:52
Marble::MarbleDirs::localPath
static QString localPath()
Definition: MarbleDirs.cpp:217
Marble::PositionTracking::gpsLocation
void gpsLocation(GeoDataCoordinates, qreal)
Marble::GeoDataStyleMap
a class to map different styles to one style
Definition: GeoDataStyleMap.h:38
Marble::kml::kmlTag_nameSpace22
const char * kmlTag_nameSpace22
Definition: KmlElementDictionary.cpp:33
QObject
Marble::GeoDataPlacemark::geometry
GeoDataGeometry * geometry() const
The geometry of the GeoDataPlacemark is to be rendered to the marble map along with the icon at the c...
Definition: GeoDataPlacemark.cpp:63
MarbleDebug.h
Marble::PositionProviderStatusUnavailable
Definition: PositionProviderPluginInterface.h:27
GeoDataTrack.h
GeoWriter.h
Marble::PositionTracking::accuracy
GeoDataAccuracy accuracy() const
Returns the estimated accuracy of the current position.
Definition: PositionTracking.cpp:383
Marble::PositionProviderPlugin
The abstract class that provides position information.
Definition: PositionProviderPlugin.h:26
Marble::GeoData_KML
Definition: GeoDataParser.h:36
Marble::PositionTracking::error
QString error() const
gives the error message from the current position provider
Definition: PositionTracking.cpp:220
Marble::PositionTracking::~PositionTracking
~PositionTracking()
Definition: PositionTracking.cpp:177
Marble::GeoDataStyle
an addressable style group
Definition: GeoDataStyle.h:55
Marble::PositionTracking::isTrackEmpty
bool isTrackEmpty() const
Returns true if there is no position in the track.
Definition: PositionTracking.cpp:365
Marble::GeoParser::read
bool read(QIODevice *)
Main API for reading the XML document.
Definition: GeoParser.cpp:74
Marble::GeoDataFeature::setName
void setName(const QString &value)
Set a new name for this feature.
Definition: GeoDataFeature.cpp:485
Marble::TrackingDocument
Definition: GeoDataDocument.h:43
KmlElementDictionary.h
MarbleDirs.h
Marble::GeoDataLineStyle::setWidth
void setWidth(const float &width)
Set the width of the line.
Definition: GeoDataLineStyle.cpp:76
Marble::GeoWriter
Standard Marble way of writing XML This class is intended to be a standardised way of writing XML for...
Definition: GeoWriter.h:28
Marble::GeoDataDocument::addStyle
void addStyle(const GeoDataStyle &style)
Add a style to the style storage.
Definition: GeoDataDocument.cpp:110
GeoDataPlacemark.h
GeoDataTreeModel.h
GeoDataMultiTrack.h
GeoDataStyleMap.h
Marble::GeoDataContainer::append
void append(GeoDataFeature *other)
add an element
Definition: GeoDataContainer.cpp:165
Marble::PositionProviderStatus
PositionProviderStatus
Definition: PositionProviderPluginInterface.h:25
Marble::GeoWriter::setDocumentType
void setDocumentType(const QString &documentType)
Set the current document type.
Definition: GeoWriter.cpp:79
Marble::PositionTracking::timestamp
QDateTime timestamp() const
Returns the timestamp of last recent tracking point.
Definition: PositionTracking.cpp:238
Marble::PositionTracking::clearTrack
void clearTrack()
Removes all track segments which were recorded.
Definition: PositionTracking.cpp:287
Marble::PositionTracking::positionProviderPluginChanged
void positionProviderPluginChanged(PositionProviderPlugin *activePlugin)
emits positionProviderPluginChanged(0) when provider is disabled
Marble::PositionTracking::positionProviderPlugin
PositionProviderPlugin * positionProviderPlugin()
Returns the current position provider plugin, or 0 if none is in use.
Marble::GeoDataStyle::setLineStyle
void setLineStyle(const GeoDataLineStyle &style)
set the line style
Definition: GeoDataStyle.cpp:88
Marble::Oxygen::brickRed4
QColor const brickRed4
Definition: MarbleColors.h:32
Marble::PositionTracking::setTrackVisible
void setTrackVisible(bool visible)
Toggles the visibility of the Position Tracking document.
Definition: PositionTracking.cpp:248
Marble::PositionTracking::writeSettings
void writeSettings()
Definition: PositionTracking.cpp:360
Marble::PositionTracking::statusChanged
void statusChanged(PositionProviderStatus status)
Marble::GeoDataContainer::remove
void remove(int index)
Definition: GeoDataContainer.cpp:173
Marble::PositionTracking::saveTrack
bool saveTrack(const QString &fileName)
Saves the track document to file.
Definition: PositionTracking.cpp:254
Marble::PositionTracking::readSettings
void readSettings()
Definition: PositionTracking.cpp:297
Marble::PositionTracking::status
PositionProviderStatus status() const
Returns the status of the current position provider plugin, if any.
Definition: PositionTracking.cpp:393
Marble::GeoDataStyleSelector::styleId
QString styleId() const
Return the style id.
Definition: GeoDataStyleSelector.cpp:65
Marble::PositionProviderStatusAvailable
Definition: PositionProviderPluginInterface.h:29
Marble::PositionTracking::setPositionProviderPlugin
void setPositionProviderPlugin(PositionProviderPlugin *plugin)
Change the position provider to use.
Definition: PositionTracking.cpp:183
Marble::GeoWriter::write
bool write(QIODevice *device, const GeoNode *feature)
The main API call to use the XML writer.
Definition: GeoWriter.cpp:28
Marble::PositionTracking::currentLocation
GeoDataCoordinates currentLocation() const
Returns the current position, if any.
Definition: PositionTracking.cpp:388
Marble::PositionTracking::speed
qreal speed() const
provides speed of the gps device
Definition: PositionTracking.cpp:227
GeoDataTypes.h
PositionTracking.h
Marble::GeoDataAccuracy
Definition: GeoDataAccuracy.h:22
Marble::GeoDataPlacemark
a class representing a point of interest on the map
Definition: GeoDataPlacemark.h:54
Marble::mDebug
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
Marble::PositionTracking::length
qreal length(qreal planetRadius) const
Returns the total track length.
Definition: PositionTracking.cpp:378
Marble::GeoParser::releaseDocument
GeoDocument * releaseDocument()
retrieve the parsed document and reset the parser If parsing was successful, retrieve the resulting d...
Definition: GeoParser.cpp:205
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:52 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal