summaryrefslogtreecommitdiff
path: root/src/plugins/geoservices/osm
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@qt.io>2016-11-02 10:53:45 +0100
committerAlex Blasche <alexander.blasche@qt.io>2016-11-02 10:53:56 +0100
commit16423f84f970d7dac644a4b041e3ebe2ac0f6e22 (patch)
tree40e88861e7987c5286012185303205113aa4ca3c /src/plugins/geoservices/osm
parent3f813d1c8c24e5da67d3f096eb3f5c73e760e641 (diff)
parent09868ace97177fbeb7198a844113f47065102b1b (diff)
downloadqtlocation-16423f84f970d7dac644a4b041e3ebe2ac0f6e22.tar.gz
Merge remote-tracking branch 'gerrit/5.6' into 5.7
Conflicts: src/imports/location/qdeclarativegeomap.cpp src/location/maps/maps.pri Change-Id: I346d7351e98f4a1aa67c9c0401d41b6da9099f48
Diffstat (limited to 'src/plugins/geoservices/osm')
-rw-r--r--src/plugins/geoservices/osm/qgeoroutereplyosm.cpp326
-rw-r--r--src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.cpp31
-rw-r--r--src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.h3
3 files changed, 36 insertions, 324 deletions
diff --git a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp
index a104df54..da28317f 100644
--- a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp
+++ b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp
@@ -38,207 +38,10 @@
****************************************************************************/
#include "qgeoroutereplyosm.h"
-
-#include <QtCore/QJsonDocument>
-#include <QtCore/QJsonObject>
-#include <QtCore/QJsonArray>
-#include <QtLocation/QGeoRouteSegment>
-#include <QtLocation/QGeoManeuver>
+#include "qgeoroutingmanagerengineosm.h"
QT_BEGIN_NAMESPACE
-static QList<QGeoCoordinate> parsePolyline(const QByteArray &data)
-{
- QList<QGeoCoordinate> path;
-
- bool parsingLatitude = true;
-
- int shift = 0;
- int value = 0;
-
- QGeoCoordinate coord(0, 0);
-
- for (int i = 0; i < data.length(); ++i) {
- unsigned char c = data.at(i) - 63;
-
- value |= (c & 0x1f) << shift;
- shift += 5;
-
- // another chunk
- if (c & 0x20)
- continue;
-
- int diff = (value & 1) ? ~(value >> 1) : (value >> 1);
-
- if (parsingLatitude) {
- coord.setLatitude(coord.latitude() + (double)diff/1e6);
- } else {
- coord.setLongitude(coord.longitude() + (double)diff/1e6);
- path.append(coord);
- }
-
- parsingLatitude = !parsingLatitude;
-
- value = 0;
- shift = 0;
- }
-
- return path;
-}
-
-static QGeoManeuver::InstructionDirection osrmInstructionDirection(const QString &instructionCode)
-{
- if (instructionCode == QLatin1String("0"))
- return QGeoManeuver::NoDirection;
- else if (instructionCode == QLatin1String("1"))
- return QGeoManeuver::DirectionForward;
- else if (instructionCode == QLatin1String("2"))
- return QGeoManeuver::DirectionBearRight;
- else if (instructionCode == QLatin1String("3"))
- return QGeoManeuver::DirectionRight;
- else if (instructionCode == QLatin1String("4"))
- return QGeoManeuver::DirectionHardRight;
- else if (instructionCode == QLatin1String("5"))
- return QGeoManeuver::DirectionUTurnLeft;
- else if (instructionCode == QLatin1String("6"))
- return QGeoManeuver::DirectionHardLeft;
- else if (instructionCode == QLatin1String("7"))
- return QGeoManeuver::DirectionLeft;
- else if (instructionCode == QLatin1String("8"))
- return QGeoManeuver::DirectionBearLeft;
- else if (instructionCode == QLatin1String("9"))
- return QGeoManeuver::NoDirection;
- else if (instructionCode == QLatin1String("10"))
- return QGeoManeuver::DirectionForward;
- else if (instructionCode == QLatin1String("11"))
- return QGeoManeuver::NoDirection;
- else if (instructionCode == QLatin1String("12"))
- return QGeoManeuver::NoDirection;
- else if (instructionCode == QLatin1String("13"))
- return QGeoManeuver::NoDirection;
- else if (instructionCode == QLatin1String("14"))
- return QGeoManeuver::NoDirection;
- else if (instructionCode == QLatin1String("15"))
- return QGeoManeuver::NoDirection;
- else
- return QGeoManeuver::NoDirection;
-}
-
-const QString osrmInstructionText(const QString &instructionCode, const QString &wayname)
-{
- if (instructionCode == QLatin1String("0")) {
- return QString();
- } else if (instructionCode == QLatin1String("1")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("Go straight.");
- else
- return QGeoRouteReplyOsm::tr("Go straight onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("2")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("Turn slightly right.");
- else
- return QGeoRouteReplyOsm::tr("Turn slightly right onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("3")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("Turn right.");
- else
- return QGeoRouteReplyOsm::tr("Turn right onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("4")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("Make a sharp right.");
- else
- return QGeoRouteReplyOsm::tr("Make a sharp right onto %1.").arg(wayname);
- }
- else if (instructionCode == QLatin1String("5")) {
- return QGeoRouteReplyOsm::tr("When it is safe to do so, perform a U-turn.");
- } else if (instructionCode == QLatin1String("6")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("Make a sharp left.");
- else
- return QGeoRouteReplyOsm::tr("Make a sharp left onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("7")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("Turn left.");
- else
- return QGeoRouteReplyOsm::tr("Turn left onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("8")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("Turn slightly left.");
- else
- return QGeoRouteReplyOsm::tr("Turn slightly left onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("9")) {
- return QGeoRouteReplyOsm::tr("Reached waypoint.");
- } else if (instructionCode == QLatin1String("10")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("Head on.");
- else
- return QGeoRouteReplyOsm::tr("Head onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("11")) {
- return QGeoRouteReplyOsm::tr("Enter the roundabout.");
- } else if (instructionCode == QLatin1String("11-1")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("At the roundabout take the first exit.");
- else
- return QGeoRouteReplyOsm::tr("At the roundabout take the first exit onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("11-2")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("At the roundabout take the second exit.");
- else
- return QGeoRouteReplyOsm::tr("At the roundabout take the second exit onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("11-3")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("At the roundabout take the third exit.");
- else
- return QGeoRouteReplyOsm::tr("At the roundabout take the third exit onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("11-4")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("At the roundabout take the fourth exit.");
- else
- return QGeoRouteReplyOsm::tr("At the roundabout take the fourth exit onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("11-5")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("At the roundabout take the fifth exit.");
- else
- return QGeoRouteReplyOsm::tr("At the roundabout take the fifth exit onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("11-6")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("At the roundabout take the sixth exit.");
- else
- return QGeoRouteReplyOsm::tr("At the roundabout take the sixth exit onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("11-7")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("At the roundabout take the seventh exit.");
- else
- return QGeoRouteReplyOsm::tr("At the roundabout take the seventh exit onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("11-8")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("At the roundabout take the eighth exit.");
- else
- return QGeoRouteReplyOsm::tr("At the roundabout take the eighth exit onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("11-9")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("At the roundabout take the ninth exit.");
- else
- return QGeoRouteReplyOsm::tr("At the roundabout take the ninth exit onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("12")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("Leave the roundabout.");
- else
- return QGeoRouteReplyOsm::tr("Leave the roundabout onto %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("13")) {
- return QGeoRouteReplyOsm::tr("Stay on the roundabout.");
- } else if (instructionCode == QLatin1String("14")) {
- if (wayname.isEmpty())
- return QGeoRouteReplyOsm::tr("Start at the end of the street.");
- else
- return QGeoRouteReplyOsm::tr("Start at the end of %1.").arg(wayname);
- } else if (instructionCode == QLatin1String("15")) {
- return QGeoRouteReplyOsm::tr("You have reached your destination.");
- } else {
- return QGeoRouteReplyOsm::tr("Don't know what to say for '%1'").arg(instructionCode);
- }
-}
-
QGeoRouteReplyOsm::QGeoRouteReplyOsm(QNetworkReply *reply, const QGeoRouteRequest &request,
QObject *parent)
: QGeoRouteReply(request, parent), m_reply(reply)
@@ -265,70 +68,6 @@ void QGeoRouteReplyOsm::abort()
m_reply = 0;
}
-static QGeoRoute constructRoute(const QByteArray &geometry, const QJsonArray &instructions,
- const QJsonObject &summary)
-{
- QGeoRoute route;
-
- QList<QGeoCoordinate> path = parsePolyline(geometry);
-
- QGeoRouteSegment firstSegment;
- int firstPosition = -1;
-
- int segmentPathLengthCount = 0;
-
- for (int i = instructions.count() - 1; i >= 0; --i) {
- QJsonArray instruction = instructions.at(i).toArray();
-
- if (instruction.count() < 8) {
- qWarning("Instruction does not contain enough fields.");
- continue;
- }
-
- const QString instructionCode = instruction.at(0).toString();
- const QString wayname = instruction.at(1).toString();
- double segmentLength = instruction.at(2).toDouble();
- int position = instruction.at(3).toDouble();
- int time = instruction.at(4).toDouble();
- //const QString segmentLengthString = instruction.at(5).toString();
- //const QString direction = instruction.at(6).toString();
- //double azimuth = instruction.at(7).toDouble();
-
- QGeoRouteSegment segment;
- segment.setDistance(segmentLength);
-
- QGeoManeuver maneuver;
- maneuver.setDirection(osrmInstructionDirection(instructionCode));
- maneuver.setDistanceToNextInstruction(segmentLength);
- maneuver.setInstructionText(osrmInstructionText(instructionCode, wayname));
- maneuver.setPosition(path.at(position));
- maneuver.setTimeToNextInstruction(time);
-
- segment.setManeuver(maneuver);
-
- if (firstPosition == -1)
- segment.setPath(path.mid(position));
- else
- segment.setPath(path.mid(position, firstPosition - position));
-
- segmentPathLengthCount += segment.path().length();
-
- segment.setTravelTime(time);
-
- segment.setNextRouteSegment(firstSegment);
-
- firstSegment = segment;
- firstPosition = position;
- }
-
- route.setDistance(summary.value(QStringLiteral("total_distance")).toDouble());
- route.setTravelTime(summary.value(QStringLiteral("total_time")).toDouble());
- route.setFirstRouteSegment(firstSegment);
- route.setPath(path);
-
- return route;
-}
-
void QGeoRouteReplyOsm::networkReplyFinished()
{
if (!m_reply)
@@ -341,59 +80,26 @@ void QGeoRouteReplyOsm::networkReplyFinished()
return;
}
- QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
-
- if (document.isObject()) {
- QJsonObject object = document.object();
-
- //double version = object.value(QStringLiteral("version")).toDouble();
- int status = object.value(QStringLiteral("status")).toDouble();
- QString statusMessage = object.value(QStringLiteral("status_message")).toString();
-
- // status code 0 or 200 are case of success
- // status code is 207 if no route was found
- // an error occurred when trying to find a route
- if (0 != status && 200 != status) {
- setError(QGeoRouteReply::UnknownError, statusMessage);
- m_reply->deleteLater();
- m_reply = 0;
- return;
- }
-
- QJsonObject routeSummary = object.value(QStringLiteral("route_summary")).toObject();
-
- QByteArray routeGeometry =
- object.value(QStringLiteral("route_geometry")).toString().toLatin1();
-
- QJsonArray routeInstructions = object.value(QStringLiteral("route_instructions")).toArray();
-
- QGeoRoute route = constructRoute(routeGeometry, routeInstructions, routeSummary);
-
- QList<QGeoRoute> routes;
- routes.append(route);
-
- QJsonArray alternativeSummaries =
- object.value(QStringLiteral("alternative_summaries")).toArray();
- QJsonArray alternativeGeometries =
- object.value(QStringLiteral("alternative_geometries")).toArray();
- QJsonArray alternativeInstructions =
- object.value(QStringLiteral("alternative_instructions")).toArray();
+ if (m_reply->error() != QNetworkReply::NoError) {
+ setError(QGeoRouteReply::CommunicationError, m_reply->errorString());
+ m_reply->deleteLater();
+ m_reply = 0;
+ return;
+ }
- if (alternativeSummaries.count() == alternativeGeometries.count() &&
- alternativeSummaries.count() == alternativeInstructions.count()) {
- for (int i = 0; i < alternativeSummaries.count(); ++i) {
- route = constructRoute(alternativeGeometries.at(i).toString().toLatin1(),
- alternativeInstructions.at(i).toArray(),
- alternativeSummaries.at(i).toObject());
- //routes.append(route);
- }
- }
+ QGeoRoutingManagerEngineOsm *engine = qobject_cast<QGeoRoutingManagerEngineOsm *>(parent());
+ const QGeoRouteParser *parser = engine->routeParser();
- setRoutes(routes);
+ QList<QGeoRoute> routes;
+ QString errorString;
+ QGeoRouteReply::Error error = parser->parseReply(routes, errorString, m_reply->readAll());
+ if (error == QGeoRouteReply::NoError) {
+ setRoutes(routes.mid(0,1)); // TODO QTBUG-56426
+ // setError(QGeoRouteReply::NoError, status); // can't do this, or NoError is emitted and does damages
setFinished(true);
} else {
- setError(QGeoRouteReply::ParseError, QStringLiteral("Couldn't parse json."));
+ setError(error, errorString);
}
m_reply->deleteLater();
diff --git a/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.cpp b/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.cpp
index 0d7277a5..12db22a9 100644
--- a/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.cpp
+++ b/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.cpp
@@ -39,6 +39,8 @@
#include "qgeoroutingmanagerengineosm.h"
#include "qgeoroutereplyosm.h"
+#include "QtLocation/private/qgeorouteparserosrmv4_p.h"
+#include "QtLocation/private/qgeorouteparserosrmv5_p.h"
#include <QtCore/QUrlQuery>
@@ -57,7 +59,14 @@ QGeoRoutingManagerEngineOsm::QGeoRoutingManagerEngineOsm(const QVariantMap &para
if (parameters.contains(QStringLiteral("osm.routing.host")))
m_urlPrefix = parameters.value(QStringLiteral("osm.routing.host")).toString().toLatin1();
else
- m_urlPrefix = QStringLiteral("http://router.project-osrm.org/viaroute");
+ m_urlPrefix = QStringLiteral("http://router.project-osrm.org/route/v1/driving/");
+ // for v4 it was "http://router.project-osrm.org/viaroute"
+
+ if (parameters.contains(QStringLiteral("osm.routing.apiversion"))
+ && (parameters.value(QStringLiteral("osm.routing.apiversion")).toString().toLatin1() == QByteArray("v4")))
+ m_routeParser = new QGeoRouteParserOsrmV4(this);
+ else
+ m_routeParser = new QGeoRouteParserOsrmV5(this);
*error = QGeoServiceProvider::NoError;
errorString->clear();
@@ -70,20 +79,9 @@ QGeoRoutingManagerEngineOsm::~QGeoRoutingManagerEngineOsm()
QGeoRouteReply* QGeoRoutingManagerEngineOsm::calculateRoute(const QGeoRouteRequest &request)
{
QNetworkRequest networkRequest;
- networkRequest.setRawHeader("User-Agent", m_userAgent);
-
- QUrl url(m_urlPrefix);
- QUrlQuery query;
-
- query.addQueryItem(QStringLiteral("instructions"), QStringLiteral("true"));
+ networkRequest.setHeader(QNetworkRequest::UserAgentHeader, m_userAgent);
- foreach (const QGeoCoordinate &c, request.waypoints()) {
- query.addQueryItem(QStringLiteral("loc"), QString::number(c.latitude()) + QLatin1Char(',') +
- QString::number(c.longitude()));
- }
-
- url.setQuery(query);
- networkRequest.setUrl(url);
+ networkRequest.setUrl(routeParser()->requestUrl(request, m_urlPrefix));
QNetworkReply *reply = m_networkManager->get(networkRequest);
@@ -96,6 +94,11 @@ QGeoRouteReply* QGeoRoutingManagerEngineOsm::calculateRoute(const QGeoRouteReque
return routeReply;
}
+const QGeoRouteParser *QGeoRoutingManagerEngineOsm::routeParser() const
+{
+ return m_routeParser;
+}
+
void QGeoRoutingManagerEngineOsm::replyFinished()
{
QGeoRouteReply *reply = qobject_cast<QGeoRouteReply *>(sender());
diff --git a/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.h b/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.h
index 0dac897a..8e2d7f50 100644
--- a/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.h
+++ b/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.h
@@ -42,6 +42,7 @@
#include <QtLocation/QGeoServiceProvider>
#include <QtLocation/QGeoRoutingManagerEngine>
+#include <QtLocation/private/qgeorouteparser_p.h>
QT_BEGIN_NAMESPACE
@@ -58,6 +59,7 @@ public:
~QGeoRoutingManagerEngineOsm();
QGeoRouteReply *calculateRoute(const QGeoRouteRequest &request);
+ const QGeoRouteParser *routeParser() const;
private Q_SLOTS:
void replyFinished();
@@ -65,6 +67,7 @@ private Q_SLOTS:
private:
QNetworkAccessManager *m_networkManager;
+ QGeoRouteParser *m_routeParser;
QByteArray m_userAgent;
QString m_urlPrefix;
};