[Marble-commits] KDE/kdeedu/marble/src/plugins/runner/monav
Dennis Nienhüser
earthwings at gentoo.org
Fri Oct 8 23:20:38 CEST 2010
SVN commit 1183964 by nienhueser:
Support multiple, non-overlapping maps. Maps can be placed in any subdirectory of ../maps/earth/monav/ now and will be recognized automatically if they contain the plugins.ini required by monavd. Optionally (recommended) a $dirname/$dirname.poly file in osmosis polygon filter file format (in the tiling scheme from cloudmade; might switch to kml instead) can be provided to determine if the map is applicable for a route request (i.e. all via points in the route request are inside the map polygon). The .poly files can be downloaded directly from cloudmade (CC-BY-SA, distributed with the country osm.bz2 files). They correspond to simplified country borders.
M +151 -7 MonavPlugin.cpp
M +2 -0 MonavPlugin.h
M +14 -8 MonavRunner.cpp
M +2 -1 MonavRunner.h
--- trunk/KDE/kdeedu/marble/src/plugins/runner/monav/MonavPlugin.cpp #1183963:1183964
@@ -13,23 +13,43 @@
#include "MonavRunner.h"
#include "MarbleDirs.h"
#include "MarbleDebug.h"
+#include "GeoDataLatLonBox.h"
#include <QtCore/QProcess>
#include <QtCore/QDir>
+#include <QtCore/QDirIterator>
#include <QtCore/QTimer>
#include <QtNetwork/QLocalSocket>
+
#include <unistd.h>
-
-
namespace Marble
{
+class MonavMap
+{
+public:
+ QDir m_directory;
+
+ GeoDataLatLonBox m_boundingBox;
+
+ QVector<GeoDataLatLonBox> m_tiles;
+
+ void setDirectory( const QDir &dir );
+
+ bool containsPoint( const GeoDataCoordinates &point ) const;
+
+private:
+ void parseBoundingBox( const QFileInfo &file );
+};
+
class MonavPluginPrivate
{
public:
QDir m_mapDir;
+ QVector<MonavMap> m_maps;
+
bool m_ownsServer;
MonavPluginPrivate();
@@ -41,8 +61,75 @@
void stopDaemon();
bool isDaemonRunning() const;
+
+ void loadMaps();
+
+ static bool bordersFirst( const MonavMap &first, const MonavMap &second );
+
+private:
+ void loadMap( const QString &path );
};
+void MonavMap::setDirectory( const QDir &dir )
+{
+ m_directory = dir;
+ QFileInfo boundingBox( dir, dir.dirName() + ".poly" );
+ if ( boundingBox.exists() ) {
+ parseBoundingBox( boundingBox );
+ } else {
+ mDebug() << "No monav bounding box given for " << boundingBox.absoluteFilePath();
+ }
+}
+
+void MonavMap::parseBoundingBox( const QFileInfo &file )
+{
+ QFile input( file.absoluteFilePath() );
+ if ( input.open( QFile::ReadOnly ) ) {
+ GeoDataLineString boundingBox;
+ QTextStream stream( &input );
+ stream.readLine();
+ qreal lat( 0.0 ), lon( 0.0 );
+ while ( !stream.atEnd() ) {
+ if ( stream.readLine() == "END" ) {
+ continue;
+ }
+ GeoDataLineString box;
+ for ( int i = 0; i < 5; ++i ) {
+ stream >> lon;
+ stream >> lat;
+ GeoDataCoordinates point( lon, lat, 0.0, GeoDataCoordinates::Degree );
+ box << point;
+ boundingBox << point;
+ }
+ m_tiles.append( box.latLonAltBox() );
+ stream.readLine();
+ }
+ stream.readLine();
+ m_boundingBox = boundingBox.latLonAltBox();
+ }
+}
+
+bool MonavMap::containsPoint( const GeoDataCoordinates &point ) const
+{
+ // If we do not have a bounding box at all, we err on the safe side
+ if ( m_tiles.isEmpty() ) {
+ return true;
+ }
+
+ // Quick check for performance reasons
+ if ( !m_boundingBox.contains( point ) ) {
+ return false;
+ }
+
+ foreach( const GeoDataLatLonBox &box, m_tiles ) {
+ if ( box.contains( point ) ) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
MonavPluginPrivate::MonavPluginPrivate() : m_ownsServer( false )
{
// nothing to do
@@ -69,8 +156,7 @@
// Give MoNavD up to one second to set up its server
// Without that, the first route request would fail
- for ( int i=0; i<10; ++i )
- {
+ for ( int i = 0; i < 10; ++i ) {
if ( isDaemonRunning() ) {
break;
}
@@ -95,6 +181,44 @@
}
}
+void MonavPluginPrivate::loadMaps()
+{
+ QString base = MarbleDirs::localPath() + "/maps/earth/monav/";
+ loadMap( base );
+ QDir::Filters filters = QDir::AllDirs | QDir::Readable | QDir::NoDotAndDotDot;
+ QDirIterator iter( base, filters, QDirIterator::Subdirectories );
+ while ( iter.hasNext() ) {
+ iter.next();
+ loadMap( iter.filePath() );
+ }
+ // Prefer maps where bounding boxes are known
+ qSort( m_maps.begin(), m_maps.end(), MonavPluginPrivate::bordersFirst );
+}
+
+void MonavPluginPrivate::loadMap( const QString &path )
+{
+ QDir mapDir( path );
+ QFileInfo pluginsFile( mapDir, "plugins.ini" );
+ if ( pluginsFile.exists() ) {
+ MonavMap map;
+ map.setDirectory( mapDir );
+ m_maps.append( map );
+ }
+}
+
+bool MonavPluginPrivate::bordersFirst( const MonavMap &first, const MonavMap &second )
+{
+ if ( !first.m_tiles.isEmpty() && second.m_tiles.isEmpty() ) {
+ return true;
+ }
+
+ if ( first.m_tiles.isEmpty() && !second.m_tiles.isEmpty() ) {
+ return false;
+ }
+
+ return first.m_directory.absolutePath() < second.m_directory.absolutePath();
+}
+
MonavPlugin::MonavPlugin( QObject *parent ) : RunnerPlugin( parent ), d( new MonavPluginPrivate )
{
setSupportedCelestialBodies( QStringList() << "earth" );
@@ -105,8 +229,8 @@
setGuiString( tr( "Monav Routing" ) );
// Check installation
- d->m_mapDir = QDir( MarbleDirs::localPath() + "/maps/earth/monav/" );
- bool haveMap = QFileInfo( d->m_mapDir, "plugins.ini" ).exists();
+ d->loadMaps();
+ bool const haveMap = !d->m_maps.isEmpty();
setCapabilities( haveMap ? Routing /*| ReverseGeocoding */ : None );
}
@@ -121,11 +245,31 @@
mDebug() << "Failed to connect to MoNavD daemon";
}
- return new MonavRunner;
+ return new MonavRunner( this );
}
+QString MonavPlugin::mapDirectoryForRequest( RouteRequest* request ) const
+{
+ foreach( const MonavMap &map, d->m_maps ) {
+ bool containsAllPoints = true;
+ for ( int i = 0; i < request->size(); ++i ) {
+ GeoDataCoordinates via = request->at( i );
+ if ( !map.containsPoint( via ) ) {
+ containsAllPoints = false;
+ break;
}
+ }
+ if ( containsAllPoints ) {
+ return map.m_directory.absolutePath();
+ }
+ }
+
+ return QString();
+}
+
+}
+
Q_EXPORT_PLUGIN2( MonavPlugin, Marble::MonavPlugin )
#include "MonavPlugin.moc"
--- trunk/KDE/kdeedu/marble/src/plugins/runner/monav/MonavPlugin.h #1183963:1183964
@@ -30,6 +30,8 @@
virtual MarbleAbstractRunner* newRunner() const;
+ QString mapDirectoryForRequest( RouteRequest* request ) const;
+
private:
MonavPluginPrivate* const d;
};
--- trunk/KDE/kdeedu/marble/src/plugins/runner/monav/MonavRunner.cpp #1183963:1183964
@@ -9,6 +9,7 @@
//
#include "MonavRunner.h"
+#include "MonavPlugin.h"
#include "signals.h"
#include "MarbleDebug.h"
@@ -29,9 +30,9 @@
class MonavRunnerPrivate
{
public:
- QDir m_mapDir;
+ const MonavPlugin* m_plugin;
- MonavRunnerPrivate();
+ MonavRunnerPrivate( const MonavPlugin* plugin );
bool retrieveData( RouteRequest *route, RoutingDaemonResult* result ) const;
@@ -40,14 +41,19 @@
GeoDataDocument* createDocument( GeoDataLineString* geometry, const QVector<GeoDataPlacemark*> &instructions ) const;
};
-MonavRunnerPrivate::MonavRunnerPrivate() :
- m_mapDir( MarbleDirs::localPath() + "/maps/earth/monav/" )
+MonavRunnerPrivate::MonavRunnerPrivate( const MonavPlugin* plugin ) :
+ m_plugin( plugin )
{
// nothing to do
}
bool MonavRunnerPrivate::retrieveData( RouteRequest *route, RoutingDaemonResult* reply ) const
{
+ QString mapDir = m_plugin->mapDirectoryForRequest( route );
+ if ( mapDir.isEmpty() ) {
+ return false;
+ }
+
QLocalSocket socket;
socket.connectToServer( "MoNavD" );
if ( socket.waitForConnected() ) {
@@ -61,7 +67,7 @@
waypoints << coordinate;
}
- command.dataDirectory = m_mapDir.absolutePath();
+ command.dataDirectory = mapDir;
command.lookupRadius = 1500;
command.waypoints = waypoints;
command.lookupStrings = true;
@@ -72,7 +78,7 @@
if ( reply->read( &socket ) ) {
switch ( reply->type ) {
case RoutingDaemonResult::LoadFailed:
- mDebug() << "failed to load monav map from " << m_mapDir.absolutePath();
+ mDebug() << "failed to load monav map from " << mapDir;
return false;
break;
case RoutingDaemonResult::RouteFailed:
@@ -180,9 +186,9 @@
return result;
}
-MonavRunner::MonavRunner( QObject *parent ) :
+MonavRunner::MonavRunner( const MonavPlugin* plugin, QObject *parent ) :
MarbleAbstractRunner( parent ),
- d( new MonavRunnerPrivate )
+ d( new MonavRunnerPrivate( plugin ) )
{
// nothing to do
}
--- trunk/KDE/kdeedu/marble/src/plugins/runner/monav/MonavRunner.h #1183963:1183964
@@ -20,12 +20,13 @@
{
class MonavRunnerPrivate;
+class MonavPlugin;
class MonavRunner : public MarbleAbstractRunner
{
Q_OBJECT
public:
- explicit MonavRunner( QObject *parent = 0 );
+ explicit MonavRunner( const MonavPlugin* plugin, QObject *parent = 0 );
~MonavRunner();
More information about the Marble-commits
mailing list