From 1e24cec7e3ebf5f62f5440d848caf6cd9db1e456 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Tue, 11 Dec 2018 15:21:35 +0900 Subject: Introduce a map plugin parameter to decide U-Turn direction When "uturn" comes from OSRM, Qt returns UTurnLeft since Right Hand Traffic is in use in most countries. This commit allows qml to set traffic side to return correct u-turn direction. Task-number: QTBUG-72462 Change-Id: Ifaa002b063159b4e4ee563d007721ba7a4a587a4 Reviewed-by: Paolo Angelelli --- src/location/maps/qgeorouteparser.cpp | 16 +++++++++++++++- src/location/maps/qgeorouteparser_p.h | 15 ++++++++++++++- src/location/maps/qgeorouteparser_p_p.h | 2 ++ src/location/maps/qgeorouteparserosrmv4.cpp | 21 ++++++++++++++------- src/location/maps/qgeorouteparserosrmv5.cpp | 16 +++++++++++----- .../mapbox/qgeoroutingmanagerenginemapbox.cpp | 8 +++++++- .../geoservices/osm/qgeoroutingmanagerengineosm.cpp | 7 +++++++ 7 files changed, 70 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/location/maps/qgeorouteparser.cpp b/src/location/maps/qgeorouteparser.cpp index 646902e0..51b839dd 100644 --- a/src/location/maps/qgeorouteparser.cpp +++ b/src/location/maps/qgeorouteparser.cpp @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE Private class implementations */ -QGeoRouteParserPrivate::QGeoRouteParserPrivate() : QObjectPrivate() +QGeoRouteParserPrivate::QGeoRouteParserPrivate() : QObjectPrivate(), trafficSide(QGeoRouteParser::RightHandTraffic) { } @@ -85,6 +85,20 @@ QUrl QGeoRouteParser::requestUrl(const QGeoRouteRequest &request, const QString return d->requestUrl(request, prefix); } +QGeoRouteParser::TrafficSide QGeoRouteParser::trafficSide() const +{ + Q_D(const QGeoRouteParser); + return d->trafficSide; +} + +void QGeoRouteParser::setTrafficSide(QGeoRouteParser::TrafficSide trafficSide) +{ + Q_D(QGeoRouteParser); + if (d->trafficSide == trafficSide) return; + d->trafficSide = trafficSide; + Q_EMIT trafficSideChanged(trafficSide); +} + QT_END_NAMESPACE diff --git a/src/location/maps/qgeorouteparser_p.h b/src/location/maps/qgeorouteparser_p.h index 33c3a4db..053dadb1 100644 --- a/src/location/maps/qgeorouteparser_p.h +++ b/src/location/maps/qgeorouteparser_p.h @@ -61,12 +61,25 @@ class Q_LOCATION_PRIVATE_EXPORT QGeoRouteParser : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QGeoRouteParser) - + Q_PROPERTY(TrafficSide trafficSide READ trafficSide WRITE setTrafficSide NOTIFY trafficSideChanged) + Q_ENUMS(TrafficSide) public: + enum TrafficSide { + RightHandTraffic, + LeftHandTraffic + }; virtual ~QGeoRouteParser(); QGeoRouteReply::Error parseReply(QList &routes, QString &errorString, const QByteArray &reply) const; QUrl requestUrl(const QGeoRouteRequest &request, const QString &prefix) const; + TrafficSide trafficSide() const; + +public Q_SLOTS: + void setTrafficSide(TrafficSide trafficSide); + +Q_SIGNALS: + void trafficSideChanged(TrafficSide trafficSide); + protected: QGeoRouteParser(QGeoRouteParserPrivate &dd, QObject *parent = nullptr); diff --git a/src/location/maps/qgeorouteparser_p_p.h b/src/location/maps/qgeorouteparser_p_p.h index 63c773eb..c0080437 100644 --- a/src/location/maps/qgeorouteparser_p_p.h +++ b/src/location/maps/qgeorouteparser_p_p.h @@ -64,6 +64,8 @@ public: virtual QGeoRouteReply::Error parseReply(QList &routes, QString &errorString, const QByteArray &reply) const = 0; virtual QUrl requestUrl(const QGeoRouteRequest &request, const QString &prefix) const = 0; + + QGeoRouteParser::TrafficSide trafficSide; }; QT_END_NAMESPACE diff --git a/src/location/maps/qgeorouteparserosrmv4.cpp b/src/location/maps/qgeorouteparserosrmv4.cpp index bd36e7f3..24c920b0 100644 --- a/src/location/maps/qgeorouteparserosrmv4.cpp +++ b/src/location/maps/qgeorouteparserosrmv4.cpp @@ -86,7 +86,7 @@ static QList parsePolyline(const QByteArray &data) return path; } -static QGeoManeuver::InstructionDirection osrmInstructionDirection(const QString &instructionCode) +static QGeoManeuver::InstructionDirection osrmInstructionDirection(const QString &instructionCode, QGeoRouteParser::TrafficSide trafficSide) { if (instructionCode == QLatin1String("0")) return QGeoManeuver::NoDirection; @@ -98,9 +98,15 @@ static QGeoManeuver::InstructionDirection osrmInstructionDirection(const QString return QGeoManeuver::DirectionRight; else if (instructionCode == QLatin1String("4")) return QGeoManeuver::DirectionHardRight; - else if (instructionCode == QLatin1String("5")) + else if (instructionCode == QLatin1String("5")) { + switch (trafficSide) { + case QGeoRouteParser::RightHandTraffic: + return QGeoManeuver::DirectionUTurnLeft; + case QGeoRouteParser::LeftHandTraffic: + return QGeoManeuver::DirectionUTurnRight; + } return QGeoManeuver::DirectionUTurnLeft; - else if (instructionCode == QLatin1String("6")) + } else if (instructionCode == QLatin1String("6")) return QGeoManeuver::DirectionHardLeft; else if (instructionCode == QLatin1String("7")) return QGeoManeuver::DirectionLeft; @@ -240,7 +246,7 @@ static QString osrmInstructionText(const QString &instructionCode, const QString } static QGeoRoute constructRoute(const QByteArray &geometry, const QJsonArray &instructions, - const QJsonObject &summary) + const QJsonObject &summary, QGeoRouteParser::TrafficSide trafficSide) { QGeoRoute route; @@ -272,7 +278,7 @@ static QGeoRoute constructRoute(const QByteArray &geometry, const QJsonArray &in segment.setDistance(segmentLength); QGeoManeuver maneuver; - maneuver.setDirection(osrmInstructionDirection(instructionCode)); + maneuver.setDirection(osrmInstructionDirection(instructionCode, trafficSide)); maneuver.setDistanceToNextInstruction(segmentLength); maneuver.setInstructionText(osrmInstructionText(instructionCode, wayname)); maneuver.setPosition(path.at(position)); @@ -349,7 +355,7 @@ QGeoRouteReply::Error QGeoRouteParserOsrmV4Private::parseReply(QList QJsonArray routeInstructions = object.value(QStringLiteral("route_instructions")).toArray(); - QGeoRoute route = constructRoute(routeGeometry, routeInstructions, routeSummary); + QGeoRoute route = constructRoute(routeGeometry, routeInstructions, routeSummary, trafficSide); routes.append(route); @@ -365,7 +371,8 @@ QGeoRouteReply::Error QGeoRouteParserOsrmV4Private::parseReply(QList for (int i = 0; i < alternativeSummaries.count(); ++i) { route = constructRoute(alternativeGeometries.at(i).toString().toLatin1(), alternativeInstructions.at(i).toArray(), - alternativeSummaries.at(i).toObject()); + alternativeSummaries.at(i).toObject(), + trafficSide); //routes.append(route); } } diff --git a/src/location/maps/qgeorouteparserosrmv5.cpp b/src/location/maps/qgeorouteparserosrmv5.cpp index 39910229..cc39158f 100644 --- a/src/location/maps/qgeorouteparserosrmv5.cpp +++ b/src/location/maps/qgeorouteparserosrmv5.cpp @@ -769,7 +769,7 @@ static QString instructionText(const QJsonObject &step, const QJsonObject &maneu return maneuverType + QLatin1String(" to/onto ") + wayName; } -static QGeoManeuver::InstructionDirection instructionDirection(const QJsonObject &maneuver) +static QGeoManeuver::InstructionDirection instructionDirection(const QJsonObject &maneuver, QGeoRouteParser::TrafficSide trafficSide) { QString modifier; if (maneuver.value(QLatin1String("modifier")).isString()) @@ -785,9 +785,15 @@ static QGeoManeuver::InstructionDirection instructionDirection(const QJsonObject return QGeoManeuver::DirectionHardRight; else if (modifier == QLatin1String("slight right")) return QGeoManeuver::DirectionLightRight; - else if (modifier == QLatin1String("uturn")) - return QGeoManeuver::DirectionUTurnLeft; // This should rather be country-specific. In UK, f.ex. one should rather UTurn Right - else if (modifier == QLatin1String("left")) + else if (modifier == QLatin1String("uturn")) { + switch (trafficSide) { + case QGeoRouteParser::RightHandTraffic: + return QGeoManeuver::DirectionUTurnLeft; + case QGeoRouteParser::LeftHandTraffic: + return QGeoManeuver::DirectionUTurnRight; + } + return QGeoManeuver::DirectionUTurnLeft; + } else if (modifier == QLatin1String("left")) return QGeoManeuver::DirectionLeft; else if (modifier == QLatin1String("sharp left")) return QGeoManeuver::DirectionHardLeft; @@ -855,7 +861,7 @@ QGeoRouteSegment QGeoRouteParserOsrmV5Private::parseStep(const QJsonObject &step QString geometry = step.value(QLatin1String("geometry")).toString(); QList path = decodePolyline(geometry); - QGeoManeuver::InstructionDirection maneuverInstructionDirection = instructionDirection(maneuver); + QGeoManeuver::InstructionDirection maneuverInstructionDirection = instructionDirection(maneuver, trafficSide); QString maneuverInstructionText = instructionText(step, maneuver, maneuverInstructionDirection); diff --git a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp index e8db635f..29cf0167 100644 --- a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp +++ b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp @@ -238,7 +238,13 @@ QGeoRoutingManagerEngineMapbox::QGeoRoutingManagerEngineMapbox(const QVariantMap QGeoRouteParserOsrmV5 *parser = new QGeoRouteParserOsrmV5(this); parser->setExtension(new QGeoRouteParserOsrmV5ExtensionMapbox(m_accessToken, use_mapbox_text_instructions)); - + if (parameters.contains(QStringLiteral("mapbox.routing.traffic_side"))) { + QString trafficSide = parameters.value(QStringLiteral("mapbox.routing.traffic_side")).toString(); + if (trafficSide == QStringLiteral("right")) + parser->setTrafficSide(QGeoRouteParser::RightHandTraffic); + else if (trafficSide == QStringLiteral("left")) + parser->setTrafficSide(QGeoRouteParser::LeftHandTraffic); + } m_routeParser = parser; *error = QGeoServiceProvider::NoError; diff --git a/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.cpp b/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.cpp index 12db22a9..29a35aaa 100644 --- a/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.cpp +++ b/src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.cpp @@ -67,6 +67,13 @@ QGeoRoutingManagerEngineOsm::QGeoRoutingManagerEngineOsm(const QVariantMap ¶ m_routeParser = new QGeoRouteParserOsrmV4(this); else m_routeParser = new QGeoRouteParserOsrmV5(this); + if (parameters.contains(QStringLiteral("osm.routing.traffic_side"))) { + QString trafficSide = parameters.value(QStringLiteral("mapbox.routing.traffic_side")).toString(); + if (trafficSide == QStringLiteral("right")) + m_routeParser->setTrafficSide(QGeoRouteParser::RightHandTraffic); + else if (trafficSide == QStringLiteral("left")) + m_routeParser->setTrafficSide(QGeoRouteParser::LeftHandTraffic); + } *error = QGeoServiceProvider::NoError; errorString->clear(); -- cgit v1.2.1