[Marble-commits] KDE/kdeedu/marble/src/lib/routing
Dennis Nienhüser
earthwings at gentoo.org
Sat Jul 10 20:29:33 CEST 2010
SVN commit 1148459 by nienhueser:
When openrouteservice.org fails to calculate a route (e.g. requests outside of Europe or no streets nearby), use nroets.dev.openstreetmap.org as a fallback. This server is a variant of yours with worldwide data and much better hardware than yournavigation.org. For now only basic routing; route summary, via point support and directions to be done.
CCMAIL: nroets at gmail.com
M +50 -27 RoutingManager.cpp
M +1 -0 RoutingManager.h
M +53 -2 RoutingModel.cpp
M +9 -1 RoutingModel.h
M +3 -2 YoursRoutingProvider.cpp
--- trunk/KDE/kdeedu/marble/src/lib/routing/RoutingManager.cpp #1148458:1148459
@@ -13,6 +13,7 @@
#include "MarbleDebug.h"
#include "MarbleWidget.h"
#include "OrsRoutingProvider.h"
+#include "YoursRoutingProvider.h"
#include "RouteSkeleton.h"
#include "RoutingModel.h"
@@ -24,32 +25,62 @@
class RoutingManagerPrivate
{
public:
+ RoutingManager* q;
+
RoutingModel *m_routingModel;
- AbstractRoutingProvider *m_routingProvider;
+ AbstractRoutingProvider *m_orsProvider;
+ AbstractRoutingProvider *m_yoursProvider;
+
MarbleWidget *m_marbleWidget;
- RoutingManagerPrivate( MarbleWidget *widget, QObject *parent );
-
RouteSkeleton *m_route;
bool m_workOffline;
+
+ RoutingManagerPrivate( MarbleWidget *widget, RoutingManager* manager, QObject *parent );
+
+ void updateRoute( AbstractRoutingProvider* provider );
};
-RoutingManagerPrivate::RoutingManagerPrivate( MarbleWidget *widget, QObject *parent ) :
- m_routingModel( new RoutingModel( parent ) ),
- m_routingProvider( new OrsRoutingProvider( parent ) ),
+RoutingManagerPrivate::RoutingManagerPrivate( MarbleWidget *widget, RoutingManager* manager, QObject *parent ) :
+ q( manager ), m_routingModel( new RoutingModel( parent ) ),
+ m_orsProvider( new OrsRoutingProvider( parent ) ),
+ m_yoursProvider( new YoursRoutingProvider( parent ) ),
m_marbleWidget( widget ), m_route( 0 ), m_workOffline( false )
{
// nothing to do
}
+void RoutingManagerPrivate::updateRoute( AbstractRoutingProvider* provider )
+{
+ if ( !m_workOffline && m_route && m_route->size() > 1 ) {
+ int realSize = 0;
+ for ( int i = 0; i < m_route->size(); ++i ) {
+ // Sort out dummy targets
+ if ( m_route->at( i ).longitude() != 0.0 && m_route->at( i ).latitude() != 0.0 ) {
+ ++realSize;
+ }
+ }
+
+ if ( realSize > 1 ) {
+ emit q->stateChanged( RoutingManager::Downloading, m_route );
+ provider->retrieveDirections( m_route );
+ } else {
+ m_routingModel->clear();
+ emit q->stateChanged( RoutingManager::Retrieved, m_route );
+ }
+ }
+}
+
RoutingManager::RoutingManager( MarbleWidget *widget, QObject *parent ) : QObject( parent ),
- d( new RoutingManagerPrivate( widget, this ) )
+ d( new RoutingManagerPrivate( widget, this, this ) )
{
- connect( d->m_routingProvider, SIGNAL( routeRetrieved( AbstractRoutingProvider::Format, QByteArray ) ),
+ connect( d->m_orsProvider, SIGNAL( routeRetrieved( AbstractRoutingProvider::Format, QByteArray ) ),
this, SLOT( setRouteData( AbstractRoutingProvider::Format, QByteArray ) ) );
+ connect( d->m_yoursProvider, SIGNAL( routeRetrieved( AbstractRoutingProvider::Format, QByteArray ) ),
+ this, SLOT( setRouteData( AbstractRoutingProvider::Format, QByteArray ) ) );
}
RoutingManager::~RoutingManager()
@@ -71,10 +102,18 @@
void RoutingManager::setRouteData( AbstractRoutingProvider::Format format, const QByteArray &data )
{
/** @todo: switch to using GeoDataDocument* */
- Q_UNUSED( format );
if ( data.size() ) {
- d->m_routingModel->importOpenGis( data );
+ if ( format == AbstractRoutingProvider::OpenGIS ) {
+ if ( !d->m_routingModel->importOpenGis( data ) ) {
+ mDebug() << " Invalid ORS route, trying YOURS instead";
+ d->updateRoute( d->m_yoursProvider );
+ }
+ } else if ( format == AbstractRoutingProvider::KML ) {
+ d->m_routingModel->importKml( data );
+ } else {
+ mDebug() << "Gpx format import for routing is not implemented yet";
+ }
d->m_marbleWidget->repaint();
} else {
mDebug() << "Got an empty result instead of route data";
@@ -87,25 +126,9 @@
void RoutingManager::updateRoute()
{
- if ( !d->m_workOffline && d->m_route && d->m_route->size() > 1 ) {
- int realSize = 0;
- for ( int i = 0; i < d->m_route->size(); ++i ) {
- // Sort out dummy targets
- if ( d->m_route->at( i ).longitude() != 0.0 && d->m_route->at( i ).latitude() != 0.0 ) {
- ++realSize;
+ d->updateRoute( d->m_orsProvider );
}
- }
- if ( realSize > 1 ) {
- emit stateChanged( Downloading, d->m_route );
- d->m_routingProvider->retrieveDirections( d->m_route );
- } else {
- d->m_routingModel->clear();
- emit stateChanged( Retrieved, d->m_route );
- }
- }
-}
-
void RoutingManager::setWorkOffline( bool offline )
{
d->m_workOffline = offline;
--- trunk/KDE/kdeedu/marble/src/lib/routing/RoutingManager.h #1148458:1148459
@@ -83,6 +83,7 @@
void setRouteData( AbstractRoutingProvider::Format format, const QByteArray &data );
private:
+ friend class RoutingManagerPrivate;
RoutingManagerPrivate *const d;
};
--- trunk/KDE/kdeedu/marble/src/lib/routing/RoutingModel.cpp #1148458:1148459
@@ -15,6 +15,8 @@
#include "MarbleMath.h"
#include "GeoDataCoordinates.h"
#include "GeoDataDocument.h"
+#include "GeoDataGeometry.h"
+#include "GeoDataFolder.h"
#include "GeoDataParser.h"
#include "GeoDataPlacemark.h"
#include "RouteSkeleton.h"
@@ -129,20 +131,27 @@
return QVariant();
}
-void RoutingModel::importOpenGis( const QByteArray &content )
+bool RoutingModel::importOpenGis( const QByteArray &content )
{
d->m_route.clear();
QDomDocument xml;
if ( !xml.setContent( content ) ) {
mDebug() << "Cannot parse xml file with routing instructions.";
- return;
+ reset();
+ return false;
}
QDomElement root = xml.documentElement();
QDomNodeList errors = root.elementsByTagName( "xls:Error" );
if ( errors.size() > 0 ) {
+ reset();
+ return false;
+ // Returning early because fallback routing providers are used now
+ // The code below can be used to parse OpenGis errors reported by ORS
+ // and may be useful in the future
+
for ( unsigned int i = 0; i < errors.length(); ++i ) {
QDomNode node = errors.item( i );
QString errorMessage = node.attributes().namedItem( "message" ).nodeValue();
@@ -244,8 +253,50 @@
}
reset();
+ return true;
}
+bool RoutingModel::importKml( const QByteArray &content )
+{
+ d->m_route.clear();
+ GeoDataParser parser( GeoData_UNKNOWN );
+
+ // Open file in right mode
+ QBuffer buffer;
+ buffer.setData( content );
+ buffer.open( QIODevice::ReadOnly );
+
+ if ( !parser.read( &buffer ) ) {
+ qDebug() << "Cannot parse kml data! Input is " << content ;
+ reset();
+ return false;
+ }
+ GeoDataDocument* document = static_cast<GeoDataDocument*>( parser.releaseDocument() );
+ Q_ASSERT( document );
+
+ QVector<GeoDataFolder> folders = document->folders();
+ foreach( const GeoDataFolder &folder, folders ) {
+ foreach( const GeoDataPlacemark &placemark, folder.placemarks() ) {
+ GeoDataGeometry* geometry = placemark.geometry();
+ if ( geometry->geometryId() == GeoDataLineStringId ) {
+ GeoDataLineString* lineString = dynamic_cast<GeoDataLineString*>( geometry );
+ Q_ASSERT( lineString && "Internal error: geometry ID does not match class type" );
+ if ( lineString ) {
+ for ( int i=0; i<lineString->size(); ++i ) {
+ RouteElement element;
+ element.type = WayPoint;
+ element.position = lineString->at( i );
+ d->m_route.push_back( element );
+ }
+ }
+ }
+ }
+ }
+
+ reset();
+ return true;
+}
+
RoutingModel::Duration RoutingModel::duration() const
{
return d->m_totalDuration;
--- trunk/KDE/kdeedu/marble/src/lib/routing/RoutingModel.h #1148458:1148459
@@ -91,9 +91,17 @@
* @todo: Add geodata/handlers/opengis, use it in the route provider and use a
* parsed GeoDocument here
*/
- void importOpenGis( const QByteArray &xmlData );
+ bool importOpenGis( const QByteArray &xmlData );
/**
+ * @brief Parse the provided data in kml format.
+ *
+ * Old data in the model is discarded, the parsed content of the provided xml data
+ * in kml format is used as the new model data and a model reset is done
+ */
+ bool importKml( const QByteArray &content );
+
+ /**
* Returns the total (estimated) time it takes to travel from
- * source to destination
*/
--- trunk/KDE/kdeedu/marble/src/lib/routing/YoursRoutingProvider.cpp #1148458:1148459
@@ -43,10 +43,11 @@
double tLon = destination.longitude( GeoDataCoordinates::Degree );
double tLat = destination.latitude( GeoDataCoordinates::Degree );
- QString base = "http://www.yournavigation.org/api/1.0/gosmore.php";
+ //QString base = "http://www.yournavigation.org/api/1.0/gosmore.php";
+ QString base = "http://nroets.dev.openstreetmap.org/demo/gosmore.php";
QString args = "?flat=%1&flon=%2&tlat=%3&tlon=%4";
args = args.arg( fLat, 0, 'f', 6 ).arg( fLon, 0, 'f', 6 ).arg( tLat, 0, 'f', 6 ).arg( tLon, 0, 'f', 6 );
- QString preferences = "&v=motorcar&fast=1&layer=mapnik&format=kml";
+ QString preferences = "&v=motorcar&fast=1&layer=mapnik";
QString request = base + args + preferences;
// mDebug() << "GET: " << request;
More information about the Marble-commits
mailing list