Copyright (C) 2010 Ixonos Plc. Authors:
Henri Lampela - henri.lampela@ixonos.com
+ Sami Rämö - sami.ramo@ixonos.com
Situare is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
USA.
*/
-#include <QFile>
+#include "parser.h"
+
+#include <QCryptographicHash>
#include <QDebug>
-#include <QtGlobal>
-#include <QStringList>
#include <QNetworkReply>
-#include <QPointF>
+#include <QStringList>
+#include <QtGlobal>
-#include "common.h"
-#include "parser.h"
+#if defined(Q_WS_MAEMO_5) & defined(ARMEL)
+#include <QDBusInterface>
+#include <QDBusMessage>
+#endif
+
+#include "coordinates/geocoordinate.h"
+#include "error.h"
+#include "location.h"
#include "network/networkaccessmanager.h"
+#include "route.h"
+#include "routesegment.h"
+
#include "routingservice.h"
+// defines for IMEI retrieval via dbus
+#define SIM_DBUS_SERVICE "com.nokia.phone.SIM"
+#define SIM_DBUS_PATH "/com/nokia/phone/SIM/security"
+#define SIM_DBUS_IFACE "Phone.Sim.Security"
+#define SIM_IMEI_REQ "get_imei"
+
const int NO_ERROR = 0;
+// cloudmade
+const QString CLOUDMADE_AUTH_PART = "http://auth.cloudmade.com/token/";
+const QString CLOUDMADE_API_KEY = "0cea0072adbf42ce823f4c78b974f12d";
+
RoutingService::RoutingService(QObject *parent)
: QObject(parent)
{
qDebug() << __PRETTY_FUNCTION__;
- m_networkManager = NetworkAccessManager::instance();
+ m_pendingRequest.clear();
+ m_token.clear();
+
+ m_networkManager = new NetworkAccessManager(this);
connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(requestFinished(QNetworkReply*)), Qt::QueuedConnection);
- QByteArray tmp; // remove
- parseRouteData(tmp); // remove
-}
-
-RoutingService::~RoutingService()
-{
- qDebug() << __PRETTY_FUNCTION__;
}
void RoutingService::parseRouteData(const QByteArray &jsonReply)
QJson::Parser parser;
bool ok;
- // remove when you need real data ->
- QVariantMap result;
- QByteArray jsonDummy;
- QFile temp("route_from_Lehtokertunkuja_to_Jukolankuja.js");
- if(temp.open(QIODevice::ReadOnly)) {
- qDebug() << "File found";
- jsonDummy = temp.readAll();
- temp.close();
- result = parser.parse (jsonDummy, &ok).toMap();
- } else
- result = parser.parse (jsonReply, &ok).toMap();
- // <- remove when you need real data
-
- //QVariantMap result = parser.parse (jsonReply, &ok).toMap();
+ QVariantMap result = parser.parse (jsonReply, &ok).toMap();
if (!ok) {
emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
return;
QVariant routeSummary = result.value("route_summary");
QMap<QString, QVariant> routeSummaryMap = routeSummary.toMap();
- QString totalDistance = routeSummaryMap["total_distance"].toString();
- QString totalTime = routeSummaryMap["total_time"].toString();
- QString startPoint = routeSummaryMap["start_point"].toString();
- QString endPoint = routeSummaryMap["end_point"].toString();
+ Route route;
+ route.setEndPointName(routeSummaryMap["end_point"].toString());
+ route.setStartPointName(routeSummaryMap["start_point"].toString());
+ route.setTotalDistance(routeSummaryMap["total_distance"].toInt());
+ route.setTotalTime(routeSummaryMap["total_time"].toInt());
- qDebug() << totalDistance;
- qDebug() << totalTime;
- qDebug() << startPoint;
- qDebug() << endPoint;
-
- QList<QPointF> geometryList;
foreach(QVariant routeGeometry, result["route_geometry"].toList()) {
QStringList list = routeGeometry.toStringList();
- geometryList.append(QPointF(list.at(0).toDouble(), list.at(1).toDouble()));
+ route.appendGeometryPoint(GeoCoordinate(list.at(0).toDouble(),
+ list.at(1).toDouble()));
}
- qDebug() << geometryList;
foreach(QVariant routeInstructions, result["route_instructions"].toList()) {
QStringList list = routeInstructions.toStringList();
- qDebug() << list.join(",");
+ RouteSegment segment;
+ segment.setInstruction(list.at(0));
+ segment.setLength(list.at(1).toDouble());
+ segment.setPositionIndex(list.at(2).toInt());
+ segment.setTime(list.at(3).toInt());
+ segment.setLengthCaption(list.at(4));
+ segment.setEarthDirection(list.at(5));
+ segment.setAzimuth(list.at(6).toDouble());
+ if (list.count() == 9) {
+ segment.setTurnType(list.at(7));
+ segment.setTurnAngle(list.at(8).toDouble());
+ }
+ route.appendSegment(segment);
}
+
+ emit routeParsed(route);
}
}
}
+void RoutingService::requestAuthorizationToken()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ // create token request of format: http://auth.cloudmade.com/token/APIKEY?userid=UserID
+ // where APIKEY is our application specific key and userID is md5 hashed value of IMEI code
+ QString url = CLOUDMADE_AUTH_PART;
+ url.append(CLOUDMADE_API_KEY);
+ QString uidPart = "?userid=";
+ QByteArray rawData;
+
+#if defined(Q_WS_MAEMO_5) & defined(ARMEL)
+ // get the device IMEI code
+ QDBusInterface interface(SIM_DBUS_SERVICE, SIM_DBUS_PATH, SIM_DBUS_IFACE,
+ QDBusConnection::systemBus());
+
+ QDBusMessage reply = interface.call(SIM_IMEI_REQ);
+ if (reply.type() == QDBusMessage::ErrorMessage)
+ qDebug() << reply.errorMessage();
+ else {
+ QList<QVariant> args = reply.arguments();
+ qDebug() << QString("Phone's IMEI: %1").arg(args.at(0).toString());
+ rawData = args.at(0).toByteArray();
+ }
+#else
+ // for desktop we need to use login name
+ rawData.append(system("whoami"));
+#endif
+
+ QCryptographicHash crypto(QCryptographicHash::Md5);
+ crypto.addData(rawData);
+ uidPart.append(crypto.result().toHex());
+
+ url.append(uidPart);
+ sendRequest(url);
+}
+
void RoutingService::requestFinished(QNetworkReply *reply)
{
qDebug() << __PRETTY_FUNCTION__;
- if (m_currentRequests.contains(reply)) {
+ QByteArray replyArray = reply->readAll();
+
+ if (reply->error()) {
+ emit error(ErrorContext::NETWORK, reply->error());
+ } else if(reply->url().toString().contains(CLOUDMADE_AUTH_PART)) {
+ m_token = replyArray;
+ m_pendingRequest.append(m_token);
+ sendRequest(m_pendingRequest);
+ m_pendingRequest.clear();
+ } else {
+ parseRouteData(replyArray);
+ }
- if (reply->error())
- emit error(ErrorContext::NETWORK, reply->error());
- else
- parseRouteData(reply->readAll());
+ reply->deleteLater();
+}
- m_currentRequests.removeAll(reply);
- reply->deleteLater();
+void RoutingService::requestRoute(const GeoCoordinate &from, const GeoCoordinate &to)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ QString url = "http://routes.cloudmade.com/";
+ url.append(CLOUDMADE_API_KEY);
+ url.append("/api/0.3/");
+ url.append(QString::number(from.latitude()) + "," + QString::number(from.longitude()) + ",");
+ url.append(QString::number(to.latitude()) + "," + QString::number(to.longitude()));
+ url.append("/car/fastest.js?lang=en&units=km&token=");
+
+ if(m_token.isEmpty()) {
+ m_pendingRequest.append(url);
+ requestAuthorizationToken();
+ } else {
+ url.append(m_token);
+ sendRequest(QUrl(url));
}
}
request.setUrl(url);
request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
- QNetworkReply *reply = m_networkManager->get(request, true);
-
- m_currentRequests.append(reply);
+ QByteArray ba;
+ m_networkManager->post(request, ba, false);
}