summaryrefslogtreecommitdiff
path: root/src/plugins/geoservices/mapbox
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2017-11-28 16:53:54 +0100
committerPaolo Angelelli <paolo.angelelli@qt.io>2017-11-29 23:02:27 +0000
commitfe821df2179d496a3ffc853076e9c62f96abde2a (patch)
tree649ce88bd270af2a74b47ae6e529fc0ecd6122e0 /src/plugins/geoservices/mapbox
parent057fe199941b8783312abeedde315118b59ccb8e (diff)
downloadqtlocation-fe821df2179d496a3ffc853076e9c62f96abde2a.tar.gz
Unify OSRM backends for OSM and Mapbox plugins
This patch unifies the OSRM backend in both the OSM and Mapbox plugins, adding some extra functionalities to QGeoRouteParserOsrmV5 to handle the extra osrm-text-instructions information coming from the Mapbox servers. It also adds a plugin parameter to let the user choose whether to use the server's text instructions or the plugin-generated ones. Change-Id: Id7ce73f4285e2e7db6872f40d72c0610847fce91 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/plugins/geoservices/mapbox')
-rw-r--r--src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp129
-rw-r--r--src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp35
-rw-r--r--src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.h4
3 files changed, 33 insertions, 135 deletions
diff --git a/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp
index 8fc3386a..43b18454 100644
--- a/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp
+++ b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp
@@ -39,7 +39,8 @@
****************************************************************************/
#include "qgeoroutereplymapbox.h"
-
+#include "qgeoroutingmanagerenginemapbox.h"
+#include <QtLocation/private/qgeorouteparser_p.h>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>
@@ -48,40 +49,6 @@
QT_BEGIN_NAMESPACE
-static QList<QGeoCoordinate> parsePolyline(const QString &line)
-{
- QList<QGeoCoordinate> path;
- QByteArray data(line.toLocal8Bit());
-
- int mode = 0, shift = 0, value = 0, coord[2] = {0, 0};
- for (int i = 0; i < data.length(); ++i) {
- int c = data.at(i) - 63;
- value |= (c & 0x1f) << shift;
- shift += 5;
- if (c & 0x20) continue;
- coord[mode] += (value & 1) ? ~(value >> 1) : (value >> 1);
- if (mode) path.append(QGeoCoordinate((double)coord[0]/1e5, (double)coord[1]/1e5));
- mode = 1 - mode;
- value = shift = 0;
- }
- return path;
-}
-
-static QList<QGeoCoordinate> parseGeometry(const QJsonValue &geometry)
-{
- QList<QGeoCoordinate> path;
- if (geometry.isString()) path = parsePolyline(geometry.toString());
- if (geometry.isObject()) {
- QJsonArray coords = geometry.toObject().value(QStringLiteral("coordinates")).toArray();
- for (int i = 0; i < coords.count(); i++) {
- QJsonArray coord = coords.at(i).toArray();
- if (coord.count() != 2) continue;
- path.append(QGeoCoordinate(coord.at(1).toDouble(), coord.at(0).toDouble()));
- }
- }
- return path;
-}
-
QGeoRouteReplyMapbox::QGeoRouteReplyMapbox(QNetworkReply *reply, const QGeoRouteRequest &request,
QObject *parent)
: QGeoRouteReply(request, parent)
@@ -101,73 +68,6 @@ QGeoRouteReplyMapbox::~QGeoRouteReplyMapbox()
{
}
-static QGeoRoute constructRoute(const QJsonObject &obj)
-{
- QGeoRoute route;
- route.setDistance(obj.value(QStringLiteral("distance")).toDouble());
- route.setTravelTime(obj.value(QStringLiteral("duration")).toDouble());
-
- QList<QGeoCoordinate> path = parseGeometry(obj.value(QStringLiteral("geometry")));
- route.setPath(path);
-
- QGeoRouteSegment firstSegment, lastSegment;
- QJsonArray legs = obj.value(QStringLiteral("legs")).toArray();
-
- for (int i = 0; i < legs.count(); i++) {
- QJsonObject leg = legs.at(i).toObject();
- QJsonArray steps = leg.value("steps").toArray();
-
- for (int j = 0; j < steps.count(); j++) {
- QJsonObject step = steps.at(j).toObject();
- QJsonObject stepManeuver = step.value("maneuver").toObject();
-
- QGeoRouteSegment segment;
- segment.setDistance(step.value("distance").toDouble());
- segment.setTravelTime(step.value(QStringLiteral("duration")).toDouble());
-
- QGeoManeuver maneuver;
- maneuver.setDistanceToNextInstruction(step.value("distance").toDouble());
- maneuver.setInstructionText(stepManeuver.value("instruction").toString());
- maneuver.setTimeToNextInstruction(step.value(QStringLiteral("duration")).toDouble());
- QJsonArray location = stepManeuver.value(QStringLiteral("location")).toArray();
- if (location.count() > 1)
- maneuver.setPosition(QGeoCoordinate(location.at(0).toDouble(), location.at(1).toDouble()));
-
- QString modifier = stepManeuver.value("modifier").toString();
- int bearing1 = stepManeuver.value("bearing_before").toInt();
- int bearing2 = stepManeuver.value("bearing_after").toInt();
-
- if (modifier == "straight")
- maneuver.setDirection(QGeoManeuver::DirectionForward);
- else if (modifier == "slight right")
- maneuver.setDirection(QGeoManeuver::DirectionLightRight);
- else if (modifier == "right")
- maneuver.setDirection(QGeoManeuver::DirectionRight);
- else if (modifier == "sharp right")
- maneuver.setDirection(QGeoManeuver::DirectionHardRight);
- else if (modifier == "uturn")
- maneuver.setDirection(bearing2 - bearing1 > 180 ? QGeoManeuver::DirectionUTurnLeft : QGeoManeuver::DirectionUTurnRight);
- else if (modifier == "sharp left")
- maneuver.setDirection(QGeoManeuver::DirectionHardLeft);
- else if (modifier == "left")
- maneuver.setDirection(QGeoManeuver::DirectionLeft);
- else if (modifier == "slight left")
- maneuver.setDirection(QGeoManeuver::DirectionLightLeft);
- else
- maneuver.setDirection(QGeoManeuver::NoDirection);
-
- segment.setManeuver(maneuver);
- segment.setPath(parseGeometry(step.value(QStringLiteral("geometry"))));
-
- if (!firstSegment.isValid()) firstSegment = segment;
- if (lastSegment.isValid()) lastSegment.setNextRouteSegment(segment);
- lastSegment = segment;
- }
- }
- route.setFirstRouteSegment(firstSegment);
- return route;
-}
-
void QGeoRouteReplyMapbox::networkReplyFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
@@ -176,26 +76,19 @@ void QGeoRouteReplyMapbox::networkReplyFinished()
if (reply->error() != QNetworkReply::NoError)
return;
- QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
- if (document.isObject()) {
- QJsonObject object = document.object();
+ QGeoRoutingManagerEngineMapbox *engine = qobject_cast<QGeoRoutingManagerEngineMapbox *>(parent());
+ const QGeoRouteParser *parser = engine->routeParser();
- QString status = object.value(QStringLiteral("code")).toString();
- if (status != QStringLiteral("Ok")) {
- setError(QGeoRouteReply::UnknownError, object.value(QStringLiteral("message")).toString());
- return;
- }
+ QList<QGeoRoute> routes;
+ QString errorString;
+ QGeoRouteReply::Error error = parser->parseReply(routes, errorString, reply->readAll());
- QList<QGeoRoute> list;
- QJsonArray routes = object.value(QStringLiteral("routes")).toArray();
- for (int i = 0; i < routes.count(); i++) {
- QGeoRoute route = constructRoute(routes.at(i).toObject());
- list.append(route);
- }
- setRoutes(list);
+ if (error == QGeoRouteReply::NoError) {
+ setRoutes(routes.mid(0, request().numberAlternativeRoutes() + 1));
+ // 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);
}
}
diff --git a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp
index 1b7cc1b3..2697114d 100644
--- a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp
+++ b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp
@@ -41,6 +41,7 @@
#include "qgeoroutingmanagerenginemapbox.h"
#include "qgeoroutereplymapbox.h"
#include "qmapboxcommon.h"
+#include "QtLocation/private/qgeorouteparserosrmv5_p.h"
#include <QtCore/QUrlQuery>
#include <QtCore/QDebug>
@@ -62,6 +63,15 @@ QGeoRoutingManagerEngineMapbox::QGeoRoutingManagerEngineMapbox(const QVariantMap
m_accessToken = parameters.value(QStringLiteral("mapbox.access_token")).toString();
}
+ bool use_mapbox_text_instructions = true;
+ if (parameters.contains(QStringLiteral("mapbox.routing.use_mapbox_text_instructions"))) {
+ use_mapbox_text_instructions = parameters.value(QStringLiteral("mapbox.use_mapbox_text_instructions")).toBool();
+ }
+
+ QGeoRouteParserOsrmV5 *parser = new QGeoRouteParserOsrmV5(this, use_mapbox_text_instructions);
+ parser->setAccessToken(m_accessToken);
+ m_routeParser = parser;
+
*error = QGeoServiceProvider::NoError;
errorString->clear();
}
@@ -73,7 +83,7 @@ QGeoRoutingManagerEngineMapbox::~QGeoRoutingManagerEngineMapbox()
QGeoRouteReply* QGeoRoutingManagerEngineMapbox::calculateRoute(const QGeoRouteRequest &request)
{
QNetworkRequest networkRequest;
- networkRequest.setRawHeader("User-Agent", m_userAgent);
+ networkRequest.setHeader(QNetworkRequest::UserAgentHeader, m_userAgent);
QString url = mapboxDirectionsApiPath;
@@ -94,24 +104,10 @@ QGeoRouteReply* QGeoRoutingManagerEngineMapbox::calculateRoute(const QGeoRouteRe
}
}
- foreach (const QGeoCoordinate &c, request.waypoints()) {
- url += QString("%1,%2;").arg(c.longitude()).arg(c.latitude());
- }
- if (url.right(1) == QLatin1Char(';'))
- url.chop(1);
-
- QUrlQuery query;
- query.addQueryItem(QStringLiteral("steps"), QStringLiteral("true"));
- query.addQueryItem(QStringLiteral("alternatives"), QStringLiteral("true"));
- query.addQueryItem(QStringLiteral("overview"), QStringLiteral("full"));
- query.addQueryItem(QStringLiteral("geometries"), QStringLiteral("geojson"));
- query.addQueryItem(QStringLiteral("access_token"), m_accessToken);
-
- QUrl u(url);
- u.setQuery(query);
- networkRequest.setUrl(u);
+ networkRequest.setUrl(m_routeParser->requestUrl(request, url));
QNetworkReply *reply = m_networkManager->get(networkRequest);
+
QGeoRouteReplyMapbox *routeReply = new QGeoRouteReplyMapbox(reply, request, this);
connect(routeReply, SIGNAL(finished()), this, SLOT(replyFinished()));
@@ -121,6 +117,11 @@ QGeoRouteReply* QGeoRoutingManagerEngineMapbox::calculateRoute(const QGeoRouteRe
return routeReply;
}
+const QGeoRouteParser *QGeoRoutingManagerEngineMapbox::routeParser() const
+{
+ return m_routeParser;
+}
+
void QGeoRoutingManagerEngineMapbox::replyFinished()
{
QGeoRouteReply *reply = qobject_cast<QGeoRouteReply *>(sender());
diff --git a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.h b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.h
index 5b440147..61ab9a4a 100644
--- a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.h
+++ b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.h
@@ -47,6 +47,7 @@
QT_BEGIN_NAMESPACE
class QNetworkAccessManager;
+class QGeoRouteParser;
class QGeoRoutingManagerEngineMapbox : public QGeoRoutingManagerEngine
{
@@ -59,6 +60,7 @@ public:
~QGeoRoutingManagerEngineMapbox();
QGeoRouteReply *calculateRoute(const QGeoRouteRequest &request);
+ const QGeoRouteParser *routeParser() const;
private Q_SLOTS:
void replyFinished();
@@ -68,6 +70,8 @@ private:
QNetworkAccessManager *m_networkManager;
QByteArray m_userAgent;
QString m_accessToken;
+ bool m_useMapboxText = false;
+ QGeoRouteParser *m_routeParser = nullptr;
};
QT_END_NAMESPACE