• 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
  • plugins
  • runner
  • monav
MonavPlugin.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 2010 Dennis Nienhüser <earthwings@gentoo.org>
9 //
10 
11 #include "MonavPlugin.h"
12 
13 #include "signals.h"
14 #include "MonavRunner.h"
15 #include "MonavConfigWidget.h"
16 #include "MonavMap.h"
17 #include "MonavMapsModel.h"
18 
19 #include "MarbleDirs.h"
20 #include "MarbleDebug.h"
21 #include "GeoDataLatLonBox.h"
22 #include "GeoDataDocument.h"
23 #include "GeoDataData.h"
24 #include "GeoDataExtendedData.h"
25 #include "routing/RouteRequest.h"
26 
27 #include <QProcess>
28 #include <QDirIterator>
29 #include <QTimer>
30 #include <QLocalSocket>
31 #include <QThread>
32 #include <QTextStream>
33 
34 namespace Marble
35 {
36 
38 class MonavWaiter : private QThread
39 {
40 public:
41  static void msleep( unsigned long milliSeconds ) {
42  QThread::msleep( milliSeconds );
43  }
44 
45 private:
46  MonavWaiter();
47  Q_DISABLE_COPY( MonavWaiter )
48 };
49 
50 class MonavPluginPrivate
51 {
52 public:
53  QDir m_mapDir;
54 
55  QVector<MonavMap> m_maps;
56 
57  bool m_ownsServer;
58 
59  QString m_monavDaemonProcess;
60 
61  MonavPlugin::MonavRoutingDaemonVersion m_monavVersion;
62 
63  MonavPluginPrivate();
64 
65  ~MonavPluginPrivate();
66 
67  bool startDaemon();
68 
69  void stopDaemon();
70 
71  static bool isDaemonRunning();
72 
73  static bool isDaemonInstalled();
74 
75  void loadMaps();
76 
77  void initialize();
78 
79  static bool areaLessThan( const MonavMap &first, const MonavMap &second );
80 
81 private:
82  void loadMap( const QString &path );
83 
84  bool m_initialized;
85 };
86 
87 MonavPluginPrivate::MonavPluginPrivate() : m_ownsServer( false ),
88  m_monavDaemonProcess("monav-daemon"), m_monavVersion( MonavPlugin::Monav_0_3 ),
89  m_initialized( false )
90 {
91  // nothing to do
92 }
93 
94 MonavPluginPrivate::~MonavPluginPrivate()
95 {
96  stopDaemon();
97 }
98 
99 bool MonavPluginPrivate::isDaemonRunning()
100 {
101  QLocalSocket socket;
102  socket.connectToServer( "MoNavD" );
103  return socket.waitForConnected();
104 }
105 
106 bool MonavPluginPrivate::isDaemonInstalled()
107 {
108  QString path = QProcessEnvironment::systemEnvironment().value( "PATH", "/usr/local/bin:/usr/bin:/bin" );
109  foreach( const QString &application, QStringList() << "monav-daemon" << "MoNavD" ) {
110  foreach( const QString &dir, path.split( QLatin1Char( ':' ) ) ) {
111  QFileInfo executable( QDir( dir ), application );
112  if ( executable.exists() ) {
113  return true;
114  }
115  }
116  }
117 
118  return false;
119 }
120 
121 bool MonavPluginPrivate::startDaemon()
122 {
123  if ( !isDaemonRunning() ) {
124  QProcess process;
125  if ( process.startDetached( m_monavDaemonProcess ) ) {
126  m_ownsServer = true;
127  } else {
128  if ( process.startDetached( "MoNavD" ) ) {
129  m_ownsServer = true;
130  m_monavDaemonProcess = "MoNavD";
131  m_monavVersion = MonavPlugin::Monav_0_2;
132  } else {
133  return false;
134  }
135  }
136 
137  // Give monav-daemon up to one second to set up its server
138  // Without that, the first route request would fail
139  for ( int i = 0; i < 10; ++i ) {
140  if ( isDaemonRunning() ) {
141  break;
142  }
143  MonavWaiter::msleep( 100 );
144  }
145 
146  return true;
147  }
148 
149  return true;
150 }
151 
152 void MonavPluginPrivate::stopDaemon()
153 {
154  // So far Marble is the only application using monav-routingdaemon on Maemo.
155  // Always shut down the monav server there, since monav-routingdaemon will
156  // survive a crash of Marble and later block mounting a N900 via USB because
157  // it has loaded some data from it. This way if Marble crashed and monav blocks
158  // USB mounting (which the user will not be aware of), another start and shutdown
159  // of Marble will at least fix the USB mount block.
160  bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
161  if ( smallScreen || m_ownsServer ) {
162  m_ownsServer = false;
163  QProcess process;
164  process.startDetached( m_monavDaemonProcess, QStringList() << "-t" );
165  }
166 }
167 
168 void MonavPluginPrivate::loadMaps()
169 {
170  if ( m_maps.isEmpty() ) {
171  QStringList const baseDirs = QStringList() << MarbleDirs::systemPath() << MarbleDirs::localPath();
172  foreach ( const QString &baseDir, baseDirs ) {
173  QString base = baseDir + "/maps/earth/monav/";
174  loadMap( base );
175  QDir::Filters filters = QDir::AllDirs | QDir::Readable | QDir::NoDotAndDotDot;
176  QDirIterator::IteratorFlags flags = QDirIterator::Subdirectories | QDirIterator::FollowSymlinks;
177  QDirIterator iter( base, filters, flags );
178  while ( iter.hasNext() ) {
179  iter.next();
180  loadMap( iter.filePath() );
181  }
182  }
183  // Prefer maps where bounding boxes are known
184  qSort( m_maps.begin(), m_maps.end(), MonavMap::areaLessThan );
185  }
186 }
187 
188 void MonavPluginPrivate::loadMap( const QString &path )
189 {
190  QDir mapDir( path );
191  QFileInfo pluginsFile( mapDir, "plugins.ini" );
192  QFileInfo moduleFile( mapDir, "Module.ini" );
193  if ( pluginsFile.exists() && !moduleFile.exists() ) {
194  qDebug() << "Migrating" << mapDir.dirName() << "from monav-0.2";
195  QFile file( moduleFile.absoluteFilePath() );
196  file.open( QIODevice::WriteOnly );
197  QTextStream stream( &file );
198  stream << "[General]\nconfigVersion=2\n";
199  stream << "router=Contraction Hierarchies\ngpsLookup=GPS Grid\n";
200  stream << "routerFileFormatVersion=1\ngpsLookupFileFormatVersion=1\n";
201  stream.flush();
202  file.close();
203  moduleFile.refresh();
204  }
205 
206  if ( moduleFile.exists() ) {
207  MonavMap map;
208  map.setDirectory( mapDir );
209  m_maps.append( map );
210  }
211 }
212 
213 void MonavPluginPrivate::initialize()
214 {
215  if ( !m_initialized ) {
216  m_initialized = true;
217  loadMaps();
218  }
219 }
220 
221 MonavPlugin::MonavPlugin( QObject *parent ) :
222  RoutingRunnerPlugin( parent ),
223  d( new MonavPluginPrivate )
224 {
225  setSupportedCelestialBodies( QStringList() << "earth" );
226  setCanWorkOffline( true );
227 
228  if ( d->isDaemonInstalled() ) {
229  d->initialize();
230  if ( d->m_maps.isEmpty() ) {
231  setStatusMessage( tr ( "No offline maps installed yet." ) );
232  }
233  } else {
234  setStatusMessage( tr ( "The monav routing daemon does not seem to be installed on your system." ) );
235  }
236 
237  connect( qApp, SIGNAL(aboutToQuit()), this, SLOT(stopDaemon()) );
238 }
239 
240 MonavPlugin::~MonavPlugin()
241 {
242  delete d;
243 }
244 
245 QString MonavPlugin::name() const
246 {
247  return tr( "Monav Routing" );
248 }
249 
250 QString MonavPlugin::guiString() const
251 {
252  return tr( "Monav" );
253 }
254 
255 QString MonavPlugin::nameId() const
256 {
257  return "monav";
258 }
259 
260 QString MonavPlugin::version() const
261 {
262  return "1.0";
263 }
264 
265 QString MonavPlugin::description() const
266 {
267  return tr( "Offline routing using the monav daemon" );
268 }
269 
270 QString MonavPlugin::copyrightYears() const
271 {
272  return "2010";
273 }
274 
275 QList<PluginAuthor> MonavPlugin::pluginAuthors() const
276 {
277  return QList<PluginAuthor>()
278  << PluginAuthor( QString::fromUtf8( "Dennis Nienhüser" ), "earthwings@gentoo.org" );
279 }
280 
281 RoutingRunner *MonavPlugin::newRunner() const
282 {
283  d->initialize();
284  if ( !d->startDaemon() ) {
285  mDebug() << "Failed to start the monav routing daemon";
286  }
287 
288  return new MonavRunner( this );
289 }
290 
291 QString MonavPlugin::mapDirectoryForRequest( const RouteRequest* request ) const
292 {
293  d->initialize();
294 
295  QHash<QString, QVariant> settings = request->routingProfile().pluginSettings()[nameId()];
296  QString transport = settings["transport"].toString();
297 
298  for ( int j=0; j<d->m_maps.size(); ++j ) {
299  bool valid = true;
300  if ( transport.isEmpty() || transport == d->m_maps[j].transport() ) {
301  for ( int i = 0; i < request->size(); ++i ) {
302  GeoDataCoordinates via = request->at( i );
303  if ( !d->m_maps[j].containsPoint( via ) ) {
304  valid = false;
305  break;
306  }
307  }
308  } else {
309  valid = false;
310  }
311 
312  if ( valid ) {
313  if ( j ) {
314  // Subsequent route requests will likely be in the same country
315  qSwap( d->m_maps[0], d->m_maps[j] );
316  }
317  // mDebug() << "Using " << d->m_maps.first().m_directory.dirName() << " as monav map";
318  return d->m_maps.first().directory().absolutePath();
319  }
320  }
321 
322  return QString();
323 }
324 
325 QStringList MonavPlugin::mapDirectoriesForRequest( const RouteRequest* request ) const
326 {
327  QStringList result;
328  d->initialize();
329  QHash<QString, QVariant> settings = request->routingProfile().pluginSettings()[nameId()];
330  QString transport = settings["transport"].toString();
331 
332  for ( int j=0; j<d->m_maps.size(); ++j ) {
333  bool valid = true;
334  if ( transport.isEmpty() || transport == d->m_maps[j].transport() ) {
335  for ( int i = 0; i < request->size(); ++i ) {
336  GeoDataCoordinates via = request->at( i );
337  if ( !d->m_maps[j].containsPoint( via ) ) {
338  valid = false;
339  break;
340  }
341  }
342  } else {
343  valid = false;
344  }
345 
346  if ( valid ) {
347  result << d->m_maps[j].directory().absolutePath();
348  }
349  }
350 
351  return result;
352 }
353 
354 RoutingRunnerPlugin::ConfigWidget *MonavPlugin::configWidget()
355 {
356  return new MonavConfigWidget( this );
357 }
358 
359 MonavMapsModel* MonavPlugin::installedMapsModel()
360 {
361  d->initialize();
362  return new MonavMapsModel( d->m_maps );
363 }
364 
365 void MonavPlugin::reloadMaps()
366 {
367  d->m_maps.clear();
368  d->loadMaps();
369 }
370 
371 bool MonavPlugin::canWork() const
372 {
373  d->initialize();
374  return !d->m_maps.isEmpty();
375 }
376 
377 bool MonavPlugin::supportsTemplate( RoutingProfilesModel::ProfileTemplate profileTemplate ) const
378 {
379  // Since we support multiple maps, pretty much anything can be installed, but ecological is
380  // not supported by monav
381  return profileTemplate != RoutingProfilesModel::CarEcologicalTemplate;
382 }
383 
384 QHash< QString, QVariant > MonavPlugin::templateSettings( RoutingProfilesModel::ProfileTemplate profileTemplate ) const
385 {
386  QHash<QString, QVariant> result;
387  switch ( profileTemplate ) {
388  case RoutingProfilesModel::CarFastestTemplate:
389  result["transport"] = "Motorcar";
390  break;
391  case RoutingProfilesModel::CarShortestTemplate:
392  result["transport"] = "Motorcar";
393  break;
394  case RoutingProfilesModel::CarEcologicalTemplate:
395  break;
396  case RoutingProfilesModel::BicycleTemplate:
397  result["transport"] = "Bicycle";
398  break;
399  case RoutingProfilesModel::PedestrianTemplate:
400  result["transport"] = "Pedestrian";
401  break;
402  case RoutingProfilesModel::LastTemplate:
403  Q_ASSERT( false );
404  break;
405  }
406  return result;
407 }
408 
409 MonavPlugin::MonavRoutingDaemonVersion MonavPlugin::monavVersion() const
410 {
411  return d->m_monavVersion;
412 }
413 
414 }
415 
416 Q_EXPORT_PLUGIN2( MonavPlugin, Marble::MonavPlugin )
417 
418 #include "MonavPlugin.moc"
GeoDataDocument.h
Marble::RouteRequest::size
int size() const
Number of points in the route.
Definition: RouteRequest.cpp:126
Marble::MonavPlugin::pluginAuthors
QList< PluginAuthor > pluginAuthors() const
Definition: MonavPlugin.cpp:275
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
MonavMap.h
Marble::RoutingProfilesModel::CarEcologicalTemplate
Definition: RoutingProfilesModel.h:38
Marble::MonavPlugin::templateSettings
virtual QHash< QString, QVariant > templateSettings(RoutingProfilesModel::ProfileTemplate profileTemplate) const
Settings for the given routing profile template.
Definition: MonavPlugin.cpp:384
Marble::MonavPlugin::MonavPlugin
MonavPlugin(QObject *parent=0)
Definition: MonavPlugin.cpp:221
Marble::MonavPlugin::~MonavPlugin
~MonavPlugin()
Definition: MonavPlugin.cpp:240
Marble::MonavPlugin::monavVersion
MonavRoutingDaemonVersion monavVersion() const
Definition: MonavPlugin.cpp:409
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
Marble::MonavPlugin
Definition: MonavPlugin.h:23
QProcess::startDetached
bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
Marble::PluginAuthor
Definition: PluginInterface.h:28
Marble::MarbleDirs::localPath
static QString localPath()
Definition: MarbleDirs.cpp:223
GeoDataExtendedData.h
Marble::MonavPlugin::supportsTemplate
virtual bool supportsTemplate(RoutingProfilesModel::ProfileTemplate profileTemplate) const
True if the plugin supports the given routing profile template.
Definition: MonavPlugin.cpp:377
MonavPlugin.h
MarbleDebug.h
QObject::tr
QString tr(const char *sourceText, const char *disambiguation, int n)
Marble::MonavPlugin::reloadMaps
void reloadMaps()
Definition: MonavPlugin.cpp:365
QFile
QProcessEnvironment::value
QString value(const QString &name, const QString &defaultValue) const
QTextStream
Marble::RoutingRunnerPlugin::ConfigWidget
Definition: RoutingRunnerPlugin.h:77
MonavMapsModel.h
Marble::RouteRequest
Points to be included in a route.
Definition: RouteRequest.h:31
Marble::MonavPlugin::description
QString description() const
Returns a user description of the plugin.
Definition: MonavPlugin.cpp:265
Marble::MonavMap::areaLessThan
static bool areaLessThan(const MonavMap &first, const MonavMap &second)
Definition: MonavMap.cpp:160
Marble::RouteRequest::routingProfile
RoutingProfile routingProfile() const
Definition: RouteRequest.cpp:321
Marble::MonavPlugin::name
QString name() const
Returns the user-visible name of the plugin.
Definition: MonavPlugin.cpp:245
QString::fromUtf8
QString fromUtf8(const char *str, int size)
QHash< QString, QVariant >
QProcess
QObject
QDir::Filters
typedef Filters
MarbleDirs.h
QString::isEmpty
bool isEmpty() const
Marble::MonavPlugin::nameId
QString nameId() const
Returns the unique name of the plugin.
Definition: MonavPlugin.cpp:255
Marble::RoutingProfilesModel::CarShortestTemplate
Definition: RoutingProfilesModel.h:37
Marble::MonavPlugin::mapDirectoryForRequest
QString mapDirectoryForRequest(const RouteRequest *request) const
Definition: MonavPlugin.cpp:291
Marble::MonavPlugin::guiString
QString guiString() const
Returns the string that should appear in the user interface.
Definition: MonavPlugin.cpp:250
QString
QList
QtConcurrent::map
QFuture< void > map(Sequence &sequence, MapFunction function)
Marble::MonavPlugin::mapDirectoriesForRequest
QStringList mapDirectoriesForRequest(const RouteRequest *request) const
Definition: MonavPlugin.cpp:325
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QStringList
Q_EXPORT_PLUGIN2
#define Q_EXPORT_PLUGIN2(a, b)
Definition: marble_export.h:34
QFileInfo
QDirIterator
Marble::RoutingProfilesModel::CarFastestTemplate
Definition: RoutingProfilesModel.h:36
QLatin1Char
Marble::MarbleGlobal::SmallScreen
Definition: MarbleGlobal.h:287
Marble::MonavPlugin::configWidget
virtual ConfigWidget * configWidget()
Method for getting a pointer to the configuration widget of the plugin.
Definition: MonavPlugin.cpp:354
Marble::MarbleGlobal::getInstance
static MarbleGlobal * getInstance()
Definition: MarbleGlobal.cpp:37
Marble::MonavPlugin::version
QString version() const
Definition: MonavPlugin.cpp:260
QDirIterator::IteratorFlags
typedef IteratorFlags
Marble::RoutingProfile::pluginSettings
const QHash< QString, QHash< QString, QVariant > > & pluginSettings() const
Definition: RoutingProfile.cpp:33
Marble::RoutingProfilesModel::LastTemplate
Definition: RoutingProfilesModel.h:42
QDir
Marble::MonavRunner
Definition: MonavRunner.h:22
GeoDataLatLonBox.h
Marble::MonavPlugin::copyrightYears
QString copyrightYears() const
Definition: MonavPlugin.cpp:270
Marble::RoutingProfilesModel::ProfileTemplate
ProfileTemplate
Definition: RoutingProfilesModel.h:35
Marble::RoutingRunnerPlugin::setSupportedCelestialBodies
void setSupportedCelestialBodies(const QStringList &celestialBodies)
Definition: RoutingRunnerPlugin.cpp:61
Marble::RoutingRunnerPlugin::setCanWorkOffline
void setCanWorkOffline(bool canWorkOffline)
Definition: RoutingRunnerPlugin.cpp:66
GeoDataData.h
Marble::RoutingProfilesModel::BicycleTemplate
Definition: RoutingProfilesModel.h:39
QVector
Marble::RoutingRunner
Definition: RoutingRunner.h:28
Marble::MonavPlugin::newRunner
virtual RoutingRunner * newRunner() const
Plugin factory method to create a new runner instance.
Definition: MonavPlugin.cpp:281
signals.h
Marble::MonavPlugin::Monav_0_2
Definition: MonavPlugin.h:32
Marble::RoutingRunnerPlugin
A plugin for Marble to execute a routing task.
Definition: RoutingRunnerPlugin.h:33
Marble::RoutingRunnerPlugin::setStatusMessage
void setStatusMessage(const QString &message)
Definition: RoutingRunnerPlugin.cpp:101
process
int process(const QDir &input, const QDir &output, const QString &xml)
Definition: tools/speaker-files/main.cpp:242
Marble::MarbleGlobal::profiles
Profiles profiles() const
Definition: MarbleGlobal.cpp:48
Marble::MonavPlugin::MonavRoutingDaemonVersion
MonavRoutingDaemonVersion
Definition: MonavPlugin.h:30
QLocalSocket::connectToServer
void connectToServer(const QString &name, QFlags< QIODevice::OpenModeFlag > openMode)
Marble::MonavPlugin::installedMapsModel
MonavMapsModel * installedMapsModel()
Definition: MonavPlugin.cpp:359
Marble::MarbleDirs::systemPath
static QString systemPath()
Definition: MarbleDirs.cpp:125
RouteRequest.h
QLocalSocket::waitForConnected
bool waitForConnected(int msecs)
QProcessEnvironment::systemEnvironment
QProcessEnvironment systemEnvironment()
MonavConfigWidget.h
Marble::MonavConfigWidget
Definition: MonavConfigWidget.h:27
QThread
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Marble::RoutingProfilesModel::PedestrianTemplate
Definition: RoutingProfilesModel.h:40
MonavRunner.h
Marble::MonavPlugin::canWork
virtual bool canWork() const
Returns.
Definition: MonavPlugin.cpp:371
QLocalSocket
Marble::MonavMapsModel
Definition: MonavMapsModel.h:21
Marble::mDebug
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:36
QThread::msleep
void msleep(unsigned long msecs)
Marble::RouteRequest::at
GeoDataCoordinates at(int index) const
Accessor for the n-th position.
Definition: RouteRequest.cpp:149
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