Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qgeoroutereplyohosmapkit.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtCore/qjsondocument.h>
5#include <QtCore/qjsonobject.h>
6#include <QtCore/qjsonarray.h>
7#include <QtCore/qmetaobject.h>
8#include <QtLocation/private/qgeorouteparser_p.h>
9#include <QtLocation/private/qgeoroute_p.h>
10#include <QtLocation/qgeoroutesegment.h>
11#include <QtLocation/qgeomaneuver.h>
12#include <qgeoroutereplyohosmapkit.h>
13#include <qgeoroutingmanagerengineohosmapkit.h>
14#include <qohosmapkitcommon.h>
15
17
18namespace {
19
21 {"turn-slight-left", QGeoManeuver::DirectionLightLeft},
22 {"turn-sharp-left", QGeoManeuver::DirectionHardLeft},
23 {"uturn-left", QGeoManeuver::DirectionUTurnLeft},
24 {"turn-left", QGeoManeuver::DirectionLeft},
25 {"turn-slight-right", QGeoManeuver::DirectionLightRight},
26 {"turn-sharp-right", QGeoManeuver::DirectionHardRight},
27 {"uturn-right", QGeoManeuver::DirectionUTurnRight},
28 {"turn-right", QGeoManeuver::DirectionRight},
29 {"straight", QGeoManeuver::DirectionForward},
30 {"ramp-left", QGeoManeuver::DirectionBearLeft},
31 {"ramp-right", QGeoManeuver::DirectionBearRight},
32 {"fork-left", QGeoManeuver::DirectionBearLeft},
33 {"fork-right", QGeoManeuver::DirectionBearRight},
34 {"roundabout-left", QGeoManeuver::DirectionLeft},
35 {"roundabout-right", QGeoManeuver::DirectionRight},
36};
37
38QList<QGeoCoordinate> parsePolyline(const QJsonArray &polyArray)
39{
40 QList<QGeoCoordinate> coords;
41
42 coords.reserve(polyArray.size());
43 for (const auto &coordVal : polyArray)
44 coords.append(OhosMapKit::CoordinateJson::tryConvertToQGeoCoordinate(coordVal.toObject()));
45
46 return coords;
47}
48
49QGeoManeuver parseManeuver(const QJsonObject &stepObj)
50{
51 QGeoManeuver maneuver;
52
53 maneuver.setInstructionText(stepObj.value("instruction").toString());
54 maneuver.setPosition(
55 OhosMapKit::CoordinateJson::tryConvertToQGeoCoordinate(stepObj.value("startLocation").toObject()));
56 maneuver.setDistanceToNextInstruction(stepObj.value("distance").toDouble());
57 maneuver.setTimeToNextInstruction(stepObj.value("duration").toDouble());
58
59 auto action = stepObj.value("action").toString();
60 maneuver.setDirection(actionsToDirectionsMap.value(action, QGeoManeuver::NoDirection));
61
62 return maneuver;
63}
64
65QGeoRouteSegment parseStep(const QJsonObject &stepObj)
66{
67 QGeoRouteSegment segment;
68
69 segment.setDistance(stepObj.value("distance").toDouble());
70 segment.setTravelTime(stepObj.value("duration").toDouble());
71 segment.setPath(parsePolyline(stepObj.value("polyline").toArray()));
72 segment.setManeuver(parseManeuver(stepObj));
73
74 return segment;
75}
76
77QGeoRoute parseRoute(const QJsonObject &routeObj)
78{
79 QGeoRoute route;
80
81 route.setBounds(
82 OhosMapKit::CoordinateBoundsJson::tryConvertToQGeoRectangle(routeObj.value("bounds").toObject()));
83
84 double totalDistance = 0.0;
85 double totalTimeSeconds = 0.0;
86 QList<QGeoCoordinate> fullRoutePath;
87 QList<QGeoRouteSegment> routeSegments;
88
89 auto pathsArray = routeObj.value("paths").toArray();
90 for (const auto &pathVal : pathsArray) {
91 auto pathObj = pathVal.toObject();
92 totalDistance += pathObj.value("distance").toDouble();
93 totalTimeSeconds += pathObj.value("duration").toDouble();
94
95 auto stepsArray = pathObj.value("steps").toArray();
96 for (const auto &stepVal : stepsArray) {
97 routeSegments.push_back(parseStep(stepVal.toObject()));
98
99 auto segmentPath = routeSegments.last().path();
100 if (!segmentPath.isEmpty()) {
101 if (!fullRoutePath.isEmpty() && fullRoutePath.last() == segmentPath.first())
102 segmentPath.pop_front();
103
104 fullRoutePath += segmentPath;
105 }
106 }
107 }
108
109 route.setDistance(totalDistance);
110 route.setTravelTime(totalTimeSeconds);
111 route.setPath(fullRoutePath);
112 if (!routeSegments.isEmpty()) {
113 auto currentRouteSegment = routeSegments.last();
114 for (int i = routeSegments.size() - 2; i >= 0; --i) {
115 auto tmpRouteSegment = routeSegments[i];
116 tmpRouteSegment.setNextRouteSegment(currentRouteSegment);
117 currentRouteSegment = tmpRouteSegment;
118 }
119 route.setFirstRouteSegment(currentRouteSegment);
120 }
121
122 return route;
123}
124
125QList<QGeoRoute> parseRouteResponse(const QJsonObject &responseBodyJsonObj)
126{
127 QList<QGeoRoute> routes;
128
129 auto routesArray = responseBodyJsonObj.value("routes").toArray();
130 for (const auto &routeVal : routesArray)
131 routes.append(parseRoute(routeVal.toObject()));
132
133 return routes;
134}
135
137{
138public:
140 QNetworkReply *reply, const QGeoRouteRequest &request, QObject *parent);
141
142private:
143 void networkReplyFinished();
144 void networkReplyError(QNetworkReply::NetworkError error);
145};
146
148 QNetworkReply *reply, const QGeoRouteRequest &request, QObject *parent)
150{
151 if (reply == nullptr) {
152 setError(QGeoRouteReply::UnknownError, QStringLiteral("Null reply"));
153 return;
154 }
155
156 connect(reply, &QNetworkReply::finished, this, &QGeoRouteReplyOhosMapKit::networkReplyFinished);
157 connect(reply, &QNetworkReply::errorOccurred, this, &QGeoRouteReplyOhosMapKit::networkReplyError);
158 connect(this, &QGeoRouteReply::aborted, reply, &QNetworkReply::abort);
159 connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
160}
161
162void QGeoRouteReplyOhosMapKit::networkReplyFinished()
163{
164 auto *reply = static_cast<QNetworkReply *>(sender());
165 reply->deleteLater();
166
167 if (reply->error() != QNetworkReply::NoError) {
168 setError(
169 QGeoRouteReply::UnknownError,
170 tr("Network reply error: %1")
171 .arg(QMetaEnum::fromType<QNetworkReply::NetworkError>().valueToKey(reply->error())));
172 return;
173 }
174
175 auto responseBodyJsonDoc = QJsonDocument::fromJson(reply->readAll());
176 if (!responseBodyJsonDoc.isObject()) {
177 setError(QGeoRouteReply::ParseError, tr("Response parse error"));
178 return;
179 }
180
181 setRoutes(parseRouteResponse(responseBodyJsonDoc.object()));
182
183 setFinished(true);
184}
185
186void QGeoRouteReplyOhosMapKit::networkReplyError(QNetworkReply::NetworkError error)
187{
188 Q_UNUSED(error)
189 auto *reply = static_cast<QNetworkReply *>(sender());
190 reply->deleteLater();
191 setError(QGeoRouteReply::CommunicationError, reply->errorString());
192}
193
194}
195
197 QNetworkReply *reply, const QGeoRouteRequest &request, QObject *parent)
198{
199 return new QGeoRouteReplyOhosMapKit(reply, request, parent);
200}
201
202QT_END_NAMESPACE
QGeoRouteReplyOhosMapKit(QNetworkReply *reply, const QGeoRouteRequest &request, QObject *parent)
Combined button and popup list for selecting options.
QList< QGeoRoute > parseRouteResponse(const QJsonObject &responseBodyJsonObj)
QGeoManeuver parseManeuver(const QJsonObject &stepObj)
QList< QGeoCoordinate > parsePolyline(const QJsonArray &polyArray)
QHash< QString, QGeoManeuver::InstructionDirection > actionsToDirectionsMap
QGeoRoute parseRoute(const QJsonObject &routeObj)
QGeoRouteSegment parseStep(const QJsonObject &stepObj)
QGeoRouteReply * makeQGeoRouteReplyOhosMapKit(QNetworkReply *reply, const QGeoRouteRequest &request, QObject *parent)