diff options
Diffstat (limited to 'src/plugins/geoservices/osm/qgeoroutereplyosm.cpp')
-rw-r--r-- | src/plugins/geoservices/osm/qgeoroutereplyosm.cpp | 326 |
1 files changed, 16 insertions, 310 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(); |