diff --git a/src/plugins/runner/yours/CMakeLists.txt b/src/plugins/runner/yours/CMakeLists.txt
index 437269deb..95b86a8a5 100644
--- a/src/plugins/runner/yours/CMakeLists.txt
+++ b/src/plugins/runner/yours/CMakeLists.txt
@@ -1,10 +1,14 @@
PROJECT( YoursPlugin )
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
set( yours_SRCS YoursRunner.cpp YoursPlugin.cpp )
+set( yours_UI YoursConfigWidget.ui )
+
+qt_wrap_ui( yours_SRCS ${yours_UI} )
+
marble_add_plugin( YoursPlugin ${yours_SRCS} )
diff --git a/src/plugins/runner/yours/YoursConfigWidget.ui b/src/plugins/runner/yours/YoursConfigWidget.ui
new file mode 100644
index 000000000..3ef4ad976
--- /dev/null
+++ b/src/plugins/runner/yours/YoursConfigWidget.ui
@@ -0,0 +1,51 @@
+
+
+ YoursConfigWidget
+
+
+
+ 0
+ 0
+ 273
+ 196
+
+
+
+ -
+
+
+ Transport:
+
+
+
+ -
+
+
+ -
+
+
+ Method
+
+
+
-
+
+
+ Fastest
+
+
+
+ -
+
+
+ Shortest
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/runner/yours/YoursPlugin.cpp b/src/plugins/runner/yours/YoursPlugin.cpp
index bddd07066..d6ade0b33 100644
--- a/src/plugins/runner/yours/YoursPlugin.cpp
+++ b/src/plugins/runner/yours/YoursPlugin.cpp
@@ -1,73 +1,167 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser
+// Copyright 2016 Piotr Wójcik
//
#include "YoursPlugin.h"
#include "YoursRunner.h"
+#include "ui_YoursConfigWidget.h"
+
namespace Marble
{
YoursPlugin::YoursPlugin( QObject *parent ) :
RoutingRunnerPlugin( parent )
{
setSupportedCelestialBodies(QStringList(QStringLiteral("earth")));
setCanWorkOffline( false );
setStatusMessage( tr ( "This service requires an Internet connection." ) );
}
QString YoursPlugin::name() const
{
return tr( "Yours Routing" );
}
QString YoursPlugin::guiString() const
{
return tr( "Yours" );
}
QString YoursPlugin::nameId() const
{
return QStringLiteral("yours");
}
QString YoursPlugin::version() const
{
- return QStringLiteral("1.0");
+ return QStringLiteral("1.1");
}
QString YoursPlugin::description() const
{
return tr( "Worldwide routing using a YOURS server" );
}
QString YoursPlugin::copyrightYears() const
{
- return QStringLiteral("2010");
+ return QStringLiteral("2010, 2016");
}
QVector YoursPlugin::pluginAuthors() const
{
return QVector()
- << PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"));
+ << PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"))
+ << PluginAuthor(QStringLiteral("Piotr Wójcik"), QStringLiteral("chocimier@tlen.pl"));
}
RoutingRunner *YoursPlugin::newRunner() const
{
return new YoursRunner;
}
+class YoursConfigWidget : public RoutingRunnerPlugin::ConfigWidget
+{
+public:
+ YoursConfigWidget()
+ : RoutingRunnerPlugin::ConfigWidget()
+ {
+ ui_configWidget = new Ui::YoursConfigWidget;
+ ui_configWidget->setupUi( this );
+ //TODO: read from profiles.xml
+ ui_configWidget->transport->addItem( tr( "Foot" ), "foot" );
+ ui_configWidget->transport->addItem( tr( "Bicycle" ), "bicycle" );
+ ui_configWidget->transport->addItem( tr( "Motorcar" ), "motorcar" );
+ }
+ virtual ~YoursConfigWidget()
+ {
+ delete ui_configWidget;
+ }
+ virtual void loadSettings( const QHash &settings_ )
+ {
+ QHash settings = settings_;
+
+ // Check if all fields are filled and fill them with default values.
+ if (!settings.contains(QStringLiteral("transport"))) {
+ settings.insert(QStringLiteral("transport"), QStringLiteral("motorcar"));
+ }
+ ui_configWidget->transport->setCurrentIndex(
+ ui_configWidget->transport->findData(settings.value(QStringLiteral("transport")).toString()));
+ if (settings.value(QStringLiteral("method")).toString() == QLatin1String("shortest")) {
+ ui_configWidget->shortest->setChecked( true );
+ } else {
+ ui_configWidget->fastest->setChecked( true );
+ }
+ }
+
+ virtual QHash settings() const
+ {
+ QHash settings;
+ settings.insert(QStringLiteral("transport"),
+ ui_configWidget->transport->itemData( ui_configWidget->transport->currentIndex() ) );
+
+ if ( ui_configWidget->shortest->isChecked() ) {
+ settings.insert(QStringLiteral("method"), QStringLiteral("shortest"));
+ } else {
+ settings.insert(QStringLiteral("method"), QStringLiteral("fastest"));
+ }
+ return settings;
+ }
+private:
+ Ui::YoursConfigWidget *ui_configWidget;
+};
+
+RoutingRunnerPlugin::ConfigWidget *YoursPlugin::configWidget()
+{
+ return new YoursConfigWidget();
+}
+
bool YoursPlugin::supportsTemplate( RoutingProfilesModel::ProfileTemplate profileTemplate ) const
{
- return profileTemplate == RoutingProfilesModel::CarFastestTemplate;
+ QSet availableTemplates;
+ availableTemplates.insert( RoutingProfilesModel::CarFastestTemplate );
+ availableTemplates.insert( RoutingProfilesModel::CarShortestTemplate );
+ availableTemplates.insert( RoutingProfilesModel::BicycleTemplate );
+ availableTemplates.insert( RoutingProfilesModel::PedestrianTemplate );
+ return availableTemplates.contains( profileTemplate );
+}
+
+QHash< QString, QVariant > YoursPlugin::templateSettings(RoutingProfilesModel::ProfileTemplate profileTemplate) const
+{
+ QHash result;
+ switch ( profileTemplate ) {
+ case RoutingProfilesModel::CarFastestTemplate:
+ result.insert(QStringLiteral("transport"), QStringLiteral("motorcar"));
+ result.insert(QStringLiteral("method"), QStringLiteral("fastest"));
+ break;
+ case RoutingProfilesModel::CarShortestTemplate:
+ result.insert(QStringLiteral("transport"), QStringLiteral("motorcar"));
+ result.insert(QStringLiteral("method"), QStringLiteral("shortest"));
+ break;
+ case RoutingProfilesModel::CarEcologicalTemplate:
+ break;
+ case RoutingProfilesModel::BicycleTemplate:
+ result.insert(QStringLiteral("transport"), QStringLiteral("bicycle"));
+ result.insert(QStringLiteral("method"), QStringLiteral("shortest"));
+ break;
+ case RoutingProfilesModel::PedestrianTemplate:
+ result.insert(QStringLiteral("transport"), QStringLiteral("foot"));
+ result.insert(QStringLiteral("method"), QStringLiteral("shortest"));
+ break;
+ case RoutingProfilesModel::LastTemplate:
+ Q_ASSERT( false );
+ break;
+ }
+ return result;
}
}
#include "moc_YoursPlugin.cpp"
diff --git a/src/plugins/runner/yours/YoursPlugin.h b/src/plugins/runner/yours/YoursPlugin.h
index 348cf8e56..31f0669ca 100644
--- a/src/plugins/runner/yours/YoursPlugin.h
+++ b/src/plugins/runner/yours/YoursPlugin.h
@@ -1,50 +1,55 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser
+// Copyright 2016 Piotr Wójcik
//
#ifndef MARBLE_YOURSPLUGIN_H
#define MARBLE_YOURSPLUGIN_H
#include "RoutingRunnerPlugin.h"
namespace Marble
{
class YoursPlugin : public RoutingRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.YoursPlugin")
Q_INTERFACES( Marble::RoutingRunnerPlugin )
public:
explicit YoursPlugin( QObject *parent = 0 );
QString name() const;
QString guiString() const;
QString nameId() const;
QString version() const;
QString description() const;
QString copyrightYears() const;
QVector pluginAuthors() const override;
virtual RoutingRunner *newRunner() const;
+ ConfigWidget* configWidget();
+
virtual bool supportsTemplate(RoutingProfilesModel::ProfileTemplate profileTemplate) const;
+
+ QHash< QString, QVariant > templateSettings(RoutingProfilesModel::ProfileTemplate profileTemplate) const;
};
}
#endif
diff --git a/src/plugins/runner/yours/YoursRunner.cpp b/src/plugins/runner/yours/YoursRunner.cpp
index 0b5d5ce02..0cce29b4c 100644
--- a/src/plugins/runner/yours/YoursRunner.cpp
+++ b/src/plugins/runner/yours/YoursRunner.cpp
@@ -1,162 +1,176 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser
+// Copyright 2016 Piotr Wójcik
//
#include "YoursRunner.h"
#include "MarbleDebug.h"
#include "MarbleLocale.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataParser.h"
#include "GeoDataFolder.h"
#include "GeoDataLineString.h"
#include "routing/RouteRequest.h"
#include
#include
#include
#include
#include
#include
namespace Marble
{
YoursRunner::YoursRunner( QObject *parent ) :
RoutingRunner( parent ),
m_networkAccessManager()
{
connect( &m_networkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(retrieveData(QNetworkReply*)) );
}
YoursRunner::~YoursRunner()
{
// nothing to do
}
void YoursRunner::retrieveRoute( const RouteRequest *route )
{
if ( route->size() != 2 ) {
return;
}
GeoDataCoordinates source = route->source();
GeoDataCoordinates destination = route->destination();
double fLon = source.longitude( GeoDataCoordinates::Degree );
double fLat = source.latitude( GeoDataCoordinates::Degree );
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://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";
+
+ QHash settings = route->routingProfile().pluginSettings()[QStringLiteral("yours")];
+ QString transport = settings[QStringLiteral("transport")].toString();
+ QString fast;
+
+ if (settings[QStringLiteral("method")] == QLatin1String("shortest")) {
+ fast = "0";
+ } else {
+ fast = "1";
+ }
+
+ QString preferences = "&v=%1&fast=%2&layer=mapnik;";
+ preferences = preferences.arg(transport).arg(fast);
QString request = base + args + preferences;
// mDebug() << "GET: " << request;
m_request = QNetworkRequest( QUrl( request ) );
+ m_request.setRawHeader( "X-Yours-client", "Marble" );
QEventLoop eventLoop;
QTimer timer;
timer.setSingleShot( true );
timer.setInterval( 15000 );
connect( &timer, SIGNAL(timeout()),
&eventLoop, SLOT(quit()));
connect( this, SIGNAL(routeCalculated(GeoDataDocument*)),
&eventLoop, SLOT(quit()) );
// @todo FIXME Must currently be done in the main thread, see bug 257376
QTimer::singleShot( 0, this, SLOT(get()) );
timer.start();
eventLoop.exec();
}
void YoursRunner::get()
{
QNetworkReply *reply = m_networkAccessManager.get( m_request );
connect( reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(handleError(QNetworkReply::NetworkError)) );
}
void YoursRunner::retrieveData( QNetworkReply *reply )
{
if ( reply->isFinished() ) {
QByteArray data = reply->readAll();
reply->deleteLater();
//mDebug() << "Download completed: " << data;
GeoDataDocument* result = parse( data );
if ( result ) {
QString name = "%1 %2 (Yours)";
QString unit = QLatin1String( "m" );
qreal length = distance( result );
if ( length == 0.0 ) {
delete result;
emit routeCalculated( 0 );
return;
} else if ( length >= 1000 ) {
length /= 1000.0;
unit = "km";
}
result->setName( name.arg( length, 0, 'f', 1 ).arg( unit ) );
}
emit routeCalculated( result );
}
}
void YoursRunner::handleError( QNetworkReply::NetworkError error )
{
mDebug() << " Error when retrieving yournavigation.org route: " << error;
emit routeCalculated( 0 );
}
GeoDataDocument* YoursRunner::parse( const QByteArray &content )
{
GeoDataParser parser( GeoData_UNKNOWN );
// Open file in right mode
QBuffer buffer;
buffer.setData( content );
buffer.open( QIODevice::ReadOnly );
if ( !parser.read( &buffer ) ) {
mDebug() << "Cannot parse kml data! Input is " << content ;
return 0;
}
GeoDataDocument* document = static_cast( parser.releaseDocument() );
return document;
}
qreal YoursRunner::distance( const GeoDataDocument* document )
{
QVector folders = document->folderList();
foreach( const GeoDataFolder *folder, folders ) {
foreach( const GeoDataPlacemark *placemark, folder->placemarkList() ) {
const GeoDataGeometry* geometry = placemark->geometry();
if ( geometry->geometryId() == GeoDataLineStringId ) {
const GeoDataLineString* lineString = dynamic_cast( geometry );
Q_ASSERT( lineString && "Internal error: geometry ID does not match class type" );
return lineString->length( EARTH_RADIUS );
}
}
}
return 0.0;
}
} // namespace Marble
#include "moc_YoursRunner.cpp"
diff --git a/src/plugins/runner/yours/YoursRunner.h b/src/plugins/runner/yours/YoursRunner.h
index 847fa77c6..35fda2fce 100644
--- a/src/plugins/runner/yours/YoursRunner.h
+++ b/src/plugins/runner/yours/YoursRunner.h
@@ -1,56 +1,57 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser
+// Copyright 2016 Piotr Wójcik
//
#ifndef MARBLE_YOURSRUNNER_H
#define MARBLE_YOURSRUNNER_H
#include "RoutingRunner.h"
#include
#include
namespace Marble
{
class YoursRunner : public RoutingRunner
{
Q_OBJECT
public:
explicit YoursRunner( QObject *parent = 0 );
~YoursRunner();
// Overriding MarbleAbstractRunner
virtual void retrieveRoute( const RouteRequest *request );
private Q_SLOTS:
/** Route data was retrieved via http */
void retrieveData( QNetworkReply *reply );
/** A network error occurred */
void handleError( QNetworkReply::NetworkError );
void get();
private:
static GeoDataDocument* parse( const QByteArray &input );
static qreal distance( const GeoDataDocument* document );
QNetworkAccessManager m_networkAccessManager;
QNetworkRequest m_request;
};
}
#endif