diff options
author | Alex Blasche <alexander.blasche@qt.io> | 2016-11-02 10:53:45 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@qt.io> | 2016-11-02 10:53:56 +0100 |
commit | 16423f84f970d7dac644a4b041e3ebe2ac0f6e22 (patch) | |
tree | 40e88861e7987c5286012185303205113aa4ca3c /src/plugins/geoservices | |
parent | 3f813d1c8c24e5da67d3f096eb3f5c73e760e641 (diff) | |
parent | 09868ace97177fbeb7198a844113f47065102b1b (diff) | |
download | qtlocation-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')
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 ¶ 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; }; |