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

marble

  • sources
  • kde-4.14
  • 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_currentTrack( 0 ),
48  m_positionProvider( 0 ),
49  m_length( 0.0 )
50  {
51  }
52 
53  void updatePosition();
54 
55  void updateStatus();
56 
57  static QString statusFile();
58 
59  PositionTracking *const q;
60 
61  GeoDataTreeModel *const m_treeModel;
62 
63  GeoDataPlacemark *const m_currentPositionPlacemark;
64  GeoDataPlacemark *m_currentTrackPlacemark;
65  GeoDataMultiTrack *m_trackSegments;
66  GeoDataDocument m_document;
67 
68  GeoDataCoordinates m_gpsPreviousPosition;
69  GeoDataTrack *m_currentTrack;
70 
71  PositionProviderPlugin* m_positionProvider;
72 
73  qreal m_length;
74 };
75 
76 void PositionTrackingPrivate::updatePosition()
77 {
78  Q_ASSERT( m_positionProvider != 0 );
79 
80  const GeoDataAccuracy accuracy = m_positionProvider->accuracy();
81  const GeoDataCoordinates position = m_positionProvider->position();
82  const QDateTime timestamp = m_positionProvider->timestamp();
83 
84  if ( m_positionProvider->status() == PositionProviderStatusAvailable ) {
85  if ( accuracy.horizontal < 250 ) {
86  if ( m_currentTrack->size() ) {
87  m_length += distanceSphere( m_currentTrack->coordinatesAt( m_currentTrack->size() - 1 ), position );
88  }
89  m_currentTrack->addPoint( timestamp, position );
90  }
91 
92  //if the position has moved then update the current position
93  if ( m_gpsPreviousPosition != position ) {
94  m_currentPositionPlacemark->setCoordinate( position );
95 
96  qreal speed = m_positionProvider->speed();
97  emit q->gpsLocation( position, speed );
98  }
99  }
100 }
101 
102 
103 void PositionTrackingPrivate::updateStatus()
104 {
105  Q_ASSERT( m_positionProvider != 0 );
106 
107  const PositionProviderStatus status = m_positionProvider->status();
108 
109  if (status == PositionProviderStatusAvailable) {
110  m_currentTrack = new GeoDataTrack;
111  m_treeModel->removeFeature( m_currentTrackPlacemark );
112  m_trackSegments->append( m_currentTrack );
113  m_treeModel->addFeature( &m_document, m_currentTrackPlacemark );
114  }
115 
116  emit q->statusChanged( status );
117 }
118 
119 QString PositionTrackingPrivate::statusFile()
120 {
121  QString const subdir = "tracking";
122  QDir dir( MarbleDirs::localPath() );
123  if ( !dir.exists( subdir ) ) {
124  if ( !dir.mkdir( subdir ) ) {
125  mDebug() << "Unable to create dir " << dir.absoluteFilePath( subdir );
126  return dir.absolutePath();
127  }
128  }
129 
130  if ( !dir.cd( subdir ) ) {
131  mDebug() << "Cannot change into " << dir.absoluteFilePath( subdir );
132  }
133 
134  return dir.absoluteFilePath( "track.kml" );
135 }
136 
137 PositionTracking::PositionTracking( GeoDataTreeModel *model )
138  : QObject( model ),
139  d( new PositionTrackingPrivate( model, this ) )
140 {
141  d->m_document.setDocumentRole( TrackingDocument );
142  d->m_document.setName("Position Tracking");
143 
144  // First point is current position
145  d->m_currentPositionPlacemark->setName("Current Position");
146  d->m_currentPositionPlacemark->setVisible(false);
147  d->m_document.append( d->m_currentPositionPlacemark );
148 
149  // Second point is position track
150  d->m_currentTrack = new GeoDataTrack;
151  d->m_trackSegments->append(d->m_currentTrack);
152 
153  d->m_currentTrackPlacemark->setGeometry(d->m_trackSegments);
154  d->m_currentTrackPlacemark->setName("Current Track");
155 
156  GeoDataStyle style;
157  GeoDataLineStyle lineStyle;
158  QColor transparentRed = Oxygen::brickRed4;
159  transparentRed.setAlpha( 200 );
160  lineStyle.setColor( transparentRed );
161  lineStyle.setWidth( 4 );
162  style.setLineStyle(lineStyle);
163  style.setId("track");
164 
165  GeoDataStyleMap styleMap;
166  styleMap.setId("map-track");
167  styleMap.insert("normal", QString("#").append(style.id()));
168  d->m_document.addStyleMap(styleMap);
169  d->m_document.addStyle(style);
170  d->m_document.append( d->m_currentTrackPlacemark );
171 
172  d->m_currentTrackPlacemark->setStyleUrl(QString("#").append(styleMap.id()));
173 
174  d->m_treeModel->addDocument( &d->m_document );
175 }
176 
177 
178 PositionTracking::~PositionTracking()
179 {
180  d->m_treeModel->removeDocument( &d->m_document );
181  delete d;
182 }
183 
184 void PositionTracking::setPositionProviderPlugin( PositionProviderPlugin* plugin )
185 {
186  const PositionProviderStatus oldStatus = status();
187 
188  if ( d->m_positionProvider ) {
189  delete d->m_positionProvider;
190  }
191 
192  d->m_positionProvider = plugin;
193 
194  if ( d->m_positionProvider ) {
195  d->m_positionProvider->setParent( this );
196  mDebug() << "Initializing position provider:" << d->m_positionProvider->name();
197  connect( d->m_positionProvider, SIGNAL(statusChanged(PositionProviderStatus)),
198  this, SLOT(updateStatus()) );
199  connect( d->m_positionProvider, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)),
200  this, SLOT(updatePosition()) );
201 
202  d->m_positionProvider->initialize();
203  }
204 
205  emit positionProviderPluginChanged( plugin );
206 
207  if ( oldStatus != status() ) {
208  emit statusChanged( status() );
209  }
210 
211  if ( status() == PositionProviderStatusAvailable ) {
212  emit gpsLocation( d->m_positionProvider->position(), d->m_positionProvider->speed() );
213  }
214 }
215 
216 PositionProviderPlugin* PositionTracking::positionProviderPlugin()
217 {
218  return d->m_positionProvider;
219 }
220 
221 QString PositionTracking::error() const
222 {
223  return d->m_positionProvider ? d->m_positionProvider->error() : QString();
224 }
225 
226 
227 //get speed from provider
228 qreal PositionTracking::speed() const
229 {
230  return d->m_positionProvider ? d->m_positionProvider->speed() : 0 ;
231 }
232 
233 //get direction from provider
234 qreal PositionTracking::direction() const
235 {
236  return d->m_positionProvider ? d->m_positionProvider->direction() : 0 ;
237 }
238 
239 QDateTime PositionTracking::timestamp() const
240 {
241  return d->m_positionProvider ? d->m_positionProvider->timestamp() : QDateTime();
242 }
243 
244 bool PositionTracking::trackVisible() const
245 {
246  return d->m_currentTrackPlacemark->isVisible();
247 }
248 
249 void PositionTracking::setTrackVisible( bool visible )
250 {
251  d->m_currentTrackPlacemark->setVisible( visible );
252  d->m_treeModel->updateFeature( d->m_currentTrackPlacemark );
253 }
254 
255 bool PositionTracking::saveTrack( const QString& fileName )
256 {
257 
258  if ( fileName.isEmpty() ) {
259  return false;
260  }
261 
262  GeoWriter writer;
263  //FIXME: a better way to do this?
264  writer.setDocumentType( kml::kmlTag_nameSpaceOgc22 );
265 
266  GeoDataDocument *document = new GeoDataDocument;
267  QFileInfo fileInfo( fileName );
268  QString name = fileInfo.baseName();
269  document->setName( name );
270  foreach( const GeoDataStyle &style, d->m_document.styles() ) {
271  document->addStyle( style );
272  }
273  foreach( const GeoDataStyleMap &map, d->m_document.styleMaps() ) {
274  document->addStyleMap( map );
275  }
276  GeoDataPlacemark *track = new GeoDataPlacemark( *d->m_currentTrackPlacemark );
277  track->setName( "Track " + name );
278  document->append( track );
279 
280  QFile file( fileName );
281  file.open( QIODevice::WriteOnly );
282  bool const result = writer.write( &file, document );
283  file.close();
284  delete document;
285  return result;
286 }
287 
288 void PositionTracking::clearTrack()
289 {
290  d->m_treeModel->removeFeature( d->m_currentTrackPlacemark );
291  d->m_currentTrack = new GeoDataTrack;
292  d->m_trackSegments->clear();
293  d->m_trackSegments->append( d->m_currentTrack );
294  d->m_treeModel->addFeature( &d->m_document, d->m_currentTrackPlacemark );
295  d->m_length = 0.0;
296 }
297 
298 void PositionTracking::readSettings()
299 {
300  QFile file( d->statusFile() );
301  if ( !file.open( QIODevice::ReadOnly ) ) {
302  mDebug() << "Can not read track from " << file.fileName();
303  return;
304  }
305 
306  GeoDataParser parser( GeoData_KML );
307  if ( !parser.read( &file ) ) {
308  mDebug() << "Could not parse tracking file: " << parser.errorString();
309  return;
310  }
311 
312  GeoDataDocument *doc = dynamic_cast<GeoDataDocument*>( parser.releaseDocument() );
313  file.close();
314 
315  if( !doc ){
316  mDebug() << "tracking document not available";
317  return;
318  }
319 
320  GeoDataPlacemark *track = dynamic_cast<GeoDataPlacemark*>( doc->child( 0 ) );
321  if( !track ) {
322  mDebug() << "tracking document doesn't have a placemark";
323  delete doc;
324  return;
325  }
326 
327  d->m_trackSegments = dynamic_cast<GeoDataMultiTrack*>( track->geometry() );
328  if( !d->m_trackSegments ) {
329  mDebug() << "tracking document doesn't have a multitrack";
330  delete doc;
331  return;
332  }
333  if( d->m_trackSegments->size() < 1 ) {
334  mDebug() << "tracking document doesn't have a track";
335  delete doc;
336  return;
337  }
338 
339  d->m_currentTrack = dynamic_cast<GeoDataTrack*>( d->m_trackSegments->child( d->m_trackSegments->size() - 1 ) );
340  if( !d->m_currentTrack ) {
341  mDebug() << "tracking document doesn't have a last track";
342  delete doc;
343  return;
344  }
345 
346  doc->remove( 0 );
347  delete doc;
348 
349  d->m_treeModel->removeDocument( &d->m_document );
350  d->m_document.remove( 1 );
351  delete d->m_currentTrackPlacemark;
352  d->m_currentTrackPlacemark = track;
353  d->m_currentTrackPlacemark->setName("Current Track");
354  d->m_document.append( d->m_currentTrackPlacemark );
355  d->m_currentTrackPlacemark->setStyleUrl( d->m_currentTrackPlacemark->styleUrl() );
356 
357  d->m_treeModel->addDocument( &d->m_document );
358  d->m_length = 0.0;
359 }
360 
361 void PositionTracking::writeSettings()
362 {
363  saveTrack( d->statusFile() );
364 }
365 
366 bool PositionTracking::isTrackEmpty() const
367 {
368  if ( d->m_trackSegments->size() < 1 ) {
369  return true;
370  }
371 
372  if ( d->m_trackSegments->size() == 1 ) {
373  return ( d->m_currentTrack->size() == 0 );
374  }
375 
376  return false;
377 }
378 
379 qreal PositionTracking::length( qreal planetRadius ) const
380 {
381  return d->m_length * planetRadius;
382 }
383 
384 GeoDataAccuracy PositionTracking::accuracy() const
385 {
386  return d->m_positionProvider ? d->m_positionProvider->accuracy() : GeoDataAccuracy();
387 }
388 
389 GeoDataCoordinates PositionTracking::currentLocation() const
390 {
391  return d->m_positionProvider ? d->m_positionProvider->position() : GeoDataCoordinates();
392 }
393 
394 PositionProviderStatus PositionTracking::status() const
395 {
396  return d->m_positionProvider ? d->m_positionProvider->status() : PositionProviderStatusUnavailable;
397 }
398 
399 }
400 
401 #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:234
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
QXmlStreamReader::errorString
QString errorString() const
Marble::GeoDataMultiTrack
Definition: GeoDataMultiTrack.h:25
Marble::GeoDataDocument::addStyleMap
void addStyleMap(const GeoDataStyleMap &map)
Add a stylemap to the stylemap storage.
Definition: GeoDataDocument.cpp:166
FileManager.h
Marble::GeoDataTrack
A geometry for tracking objects made of (time, coordinates) pairs.
Definition: GeoDataTrack.h:54
Marble::PositionTracking::trackVisible
bool trackVisible() const
provides the visibility of the Position Tracking document
Definition: PositionTracking.cpp:244
Marble::GeoDataDocument
A container for Features, Styles and in the future Schemas.
Definition: GeoDataDocument.h:65
Marble::GeoDataContainer::child
GeoDataFeature * child(int)
returns the requested child item
Definition: GeoDataContainer.cpp:239
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:137
Marble::GeoDataColorStyle::setColor
void setColor(const QColor &value)
Set a new color.
Definition: GeoDataColorStyle.cpp:84
GeoDataStyle.h
QColor::setAlpha
void setAlpha(int alpha)
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:223
Marble::PositionTracking::gpsLocation
void gpsLocation(GeoDataCoordinates, qreal)
Marble::GeoDataStyleMap
a class to map different styles to one style
Definition: GeoDataStyleMap.h:38
MarbleDebug.h
Marble::PositionProviderStatusUnavailable
Definition: PositionProviderPluginInterface.h:27
GeoDataTrack.h
QFile
GeoWriter.h
Marble::PositionTracking::accuracy
GeoDataAccuracy accuracy() const
Returns the estimated accuracy of the current position.
Definition: PositionTracking.cpp:384
Marble::GeoDataPlacemark::geometry
GeoDataGeometry * geometry()
The geometry of the GeoDataPlacemark is to be rendered to the marble map along with the icon at the c...
Definition: GeoDataPlacemark.cpp:152
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:221
Marble::PositionTracking::~PositionTracking
~PositionTracking()
Definition: PositionTracking.cpp:178
QObject::name
const char * name() const
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:366
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:549
Marble::TrackingDocument
Definition: GeoDataDocument.h:43
KmlElementDictionary.h
QObject
MarbleDirs.h
QString::isEmpty
bool isEmpty() const
Marble::GeoDataLineStyle::setWidth
void setWidth(const float &width)
Set the width of the line.
Definition: GeoDataLineStyle.cpp:95
Marble::GeoWriter
Standard Marble way of writing XML This class is intended to be a standardised way of writing XML for...
Definition: GeoWriter.h:29
Marble::GeoDataDocument::addStyle
void addStyle(const GeoDataStyle &style)
Add a style to the style storage.
Definition: GeoDataDocument.cpp:134
QString
QColor
GeoDataPlacemark.h
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
GeoDataTreeModel.h
GeoDataMultiTrack.h
GeoDataStyleMap.h
Marble::GeoDataContainer::append
void append(GeoDataFeature *other)
add an element
Definition: GeoDataContainer.cpp:272
Marble::PositionProviderStatus
PositionProviderStatus
Definition: PositionProviderPluginInterface.h:25
QFileInfo
Marble::kml::kmlTag_nameSpaceOgc22
const char * kmlTag_nameSpaceOgc22
Definition: KmlElementDictionary.cpp:34
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:239
QFile::close
virtual void close()
Marble::PositionTracking::clearTrack
void clearTrack()
Removes all track segments which were recorded.
Definition: PositionTracking.cpp:288
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.
QDir
Marble::GeoDataStyle::setLineStyle
void setLineStyle(const GeoDataLineStyle &style)
set the line style
Definition: GeoDataStyle.cpp:107
Marble::Oxygen::brickRed4
QColor const brickRed4
Definition: MarbleColors.h:32
Marble::GeoDataObject::id
QString id() const
Get the id of the object.
Definition: GeoDataObject.cpp:75
Marble::PositionTracking::setTrackVisible
void setTrackVisible(bool visible)
Toggles the visibility of the Position Tracking document.
Definition: PositionTracking.cpp:249
Marble::PositionTracking::writeSettings
void writeSettings()
Definition: PositionTracking.cpp:361
Marble::GeoDataObject::setId
void setId(const QString &value)
Set the id of the object.
Definition: GeoDataObject.cpp:80
Marble::PositionTracking::statusChanged
void statusChanged(PositionProviderStatus status)
Marble::GeoDataContainer::remove
void remove(int index)
Definition: GeoDataContainer.cpp:280
Marble::PositionTracking::saveTrack
bool saveTrack(const QString &fileName)
Saves the track document to file.
Definition: PositionTracking.cpp:255
Marble::PositionTracking::readSettings
void readSettings()
Definition: PositionTracking.cpp:298
Marble::PositionTracking::status
PositionProviderStatus status() const
Returns the status of the current position provider plugin, if any.
Definition: PositionTracking.cpp:394
Marble::PositionProviderStatusAvailable
Definition: PositionProviderPluginInterface.h:29
QMap::insert
iterator insert(const Key &key, const T &value)
Marble::PositionTracking::setPositionProviderPlugin
void setPositionProviderPlugin(PositionProviderPlugin *plugin)
Change the position provider to use.
Definition: PositionTracking.cpp:184
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:389
Marble::PositionTracking::speed
qreal speed() const
provides speed of the gps device
Definition: PositionTracking.cpp:228
GeoDataTypes.h
PositionTracking.h
Marble::GeoDataAccuracy
Definition: GeoDataAccuracy.h:22
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
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:36
QFileInfo::baseName
QString baseName() const
Marble::PositionTracking::length
qreal length(qreal planetRadius) const
Returns the total track length.
Definition: PositionTracking.cpp:379
QDateTime
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-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:41 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
  • 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