6#include <QXmlStreamReader>
9#include <QtCore/QThreadPool>
12#include <QtPositioning/QGeoRectangle>
13#include <QtPositioning/QGeoPath>
14#include <QtLocation/QGeoRoute>
15#include <QtLocation/private/qgeoroutesegment_p.h>
47 m_reader =
new QXmlStreamReader(m_data);
49 if (!parseRootElement())
58bool QGeoRouteXmlParser::parseRootElement()
60 if (!m_reader->readNextStartElement()) {
61 m_reader->raiseError(
QStringLiteral(
"Expected a root element named \"CalculateRoute\" "
62 "(no root element found)."));
73 bool updateroute =
false;
76 m_reader->raiseError(
QStringLiteral(
"The root element is expected to have the name "
77 "\"CalculateRoute\" or \"GetRoute\" (root element "
78 "was named \"%1\").").
arg(m_reader->name().toString()));
84 if (m_reader->readNextStartElement()) {
86 m_reader->raiseError(
QStringLiteral(
"Expected a element named \"Response\" (element "
87 "was named \"%1\").").
arg(m_reader->name().toString()));
92 while (m_reader->readNextStartElement() && !m_reader->hasError()) {
98 if (!parseRoute(&route))
103 m_reader->skipCurrentElement();
105 m_reader->skipCurrentElement();
109 return !m_reader->hasError();
112bool QGeoRouteXmlParser::parseRoute(
QGeoRoute *route)
119 m_reader->readNext();
120 while (!(m_reader->tokenType() == QXmlStreamReader::EndElement
121 && m_reader->name() ==
QLatin1String(
"Route")) && !m_reader->hasError()) {
122 if (m_reader->tokenType() == QXmlStreamReader::StartElement) {
124 route->
setRouteId(m_reader->readElementText());
130 if (!parseMode(route))
133 QString elementName = m_reader->name().toString();
135 if (!parseGeoPoints(m_reader->readElementText(), &
path, elementName))
138 }
else if (m_reader->name() ==
QLatin1String(
"BoundingBox")) {
140 if (!parseBoundingBox(bounds))
144 if (!parseLeg(legIndex++))
147 if (!parseSummary(route))
150 m_reader->skipCurrentElement();
153 m_reader->readNext();
156 if (m_reader->hasError())
159 return postProcessRoute(route);
162bool QGeoRouteXmlParser::parseLeg(
int legIndex)
167 m_reader->readNext();
170 while (!(m_reader->tokenType() == QXmlStreamReader::EndElement
172 !m_reader->hasError()) {
173 if (m_reader->tokenType() == QXmlStreamReader::StartElement) {
175 if (!parseManeuver(maneuvers))
187 leg.
setDistance(m_reader->readElementText().toDouble());
189 m_reader->skipCurrentElement();
192 m_reader->readNext();
195 if (m_reader->hasError())
200 m_maneuvers << maneuvers;
209bool QGeoRouteXmlParser::postProcessRoute(
QGeoRoute *route)
217 legSegments << QList<QGeoRouteSegment>();
225 extendedAttributes[
"first"] = maneuver.
first;
226 extendedAttributes[
"last"] = maneuver.
last;
227 extendedAttributes[
"legIndex"] =
i;
228 extendedAttributes[
"id"] = maneuver.
id;
229 extendedAttributes[
"toLink"] = maneuver.
toLink;
230 extendedAttributes[
"index"] =
j;
254 sp->setLegLastSegment(
true);
264 auto &leg = m_legs[
i];
275 while (
s.isValid()) {
276 path.append(
s.path());
277 if (
s.isLegLastSegment())
317bool QGeoRouteXmlParser::parseMode(
QGeoRoute *route)
320 m_reader->readNext();
322 while (!(m_reader->tokenType() == QXmlStreamReader::EndElement
323 && m_reader->name() ==
QLatin1String(
"Mode")) && !m_reader->hasError()) {
324 if (m_reader->tokenType() == QXmlStreamReader::StartElement) {
329 else if (
value ==
"pedestrian")
331 else if (
value ==
"publicTransport")
333 else if (
value ==
"bicycle")
335 else if (
value ==
"truck")
339 m_reader->raiseError(
QString(
"Unsupported travel mode '\"%1\"'").
arg(
value));
343 m_reader->skipCurrentElement();
346 m_reader->readNext();
348 return !m_reader->hasError();
351bool QGeoRouteXmlParser::parseSummary(
QGeoRoute *route)
355 m_reader->readNext();
357 double baseTime = -1, trafficTime = -1;
359 while (!(m_reader->tokenType() == QXmlStreamReader::EndElement
360 && m_reader->name() ==
QLatin1String(
"Summary")) && !m_reader->hasError()) {
361 if (m_reader->tokenType() == QXmlStreamReader::StartElement) {
363 route->
setDistance(m_reader->readElementText().toDouble());
364 }
else if (m_reader->name() ==
QLatin1String(
"TrafficTime")) {
365 trafficTime = m_reader->readElementText().toDouble();
367 baseTime = m_reader->readElementText().toDouble();
369 m_reader->skipCurrentElement();
372 m_reader->readNext();
375 if (m_reader->hasError())
378 if (trafficTime >= 0)
388 QString currentElement = m_reader->name().toString();
389 m_reader->readNext();
391 while (!(m_reader->tokenType() == QXmlStreamReader::EndElement
392 && m_reader->name() == currentElement) && !m_reader->hasError()) {
393 if (m_reader->tokenType() == QXmlStreamReader::StartElement) {
396 if (
name ==
"Latitude")
398 else if (
name ==
"Longitude")
401 m_reader->readNext();
404 return !m_reader->hasError();
411 if (!m_reader->attributes().hasAttribute(
"id")) {
412 m_reader->raiseError(
"The element \"Maneuver\" did not have the required attribute \"id\".");
416 maneuverContainter.
id = m_reader->attributes().value(
"id").toString();
418 m_reader->readNext();
419 while (!(m_reader->tokenType() == QXmlStreamReader::EndElement
420 && m_reader->name() ==
QLatin1String(
"Maneuver")) && !m_reader->hasError()) {
421 if (m_reader->tokenType() == QXmlStreamReader::StartElement) {
424 if (parseCoordinates(coordinates))
426 }
else if (m_reader->name() ==
QLatin1String(
"Instruction")) {
429 QString elementName = m_reader->name().toString();
431 if (!parseGeoPoints(m_reader->readElementText(), &
path, elementName))
435 maneuverContainter.
toLink = m_reader->readElementText();
436 }
else if (m_reader->name() ==
QLatin1String(
"TravelTime")) {
442 if (
value ==
"forward")
444 else if (
value ==
"bearRight")
446 else if (
value ==
"lightRight")
448 else if (
value ==
"right")
450 else if (
value ==
"hardRight")
452 else if (
value ==
"uTurnRight")
454 else if (
value ==
"uTurnLeft")
456 else if (
value ==
"hardLeft")
458 else if (
value ==
"left")
460 else if (
value ==
"lightLeft")
462 else if (
value ==
"bearLeft")
467 m_reader->skipCurrentElement();
470 m_reader->readNext();
473 if (m_reader->hasError())
476 maneuvers.
append(maneuverContainter);
483 m_reader->readNext();
487 while (!(m_reader->tokenType() == QXmlStreamReader::EndElement
488 && m_reader->name() ==
QStringLiteral(
"Link")) && !m_reader->hasError()) {
489 if (m_reader->tokenType() == QXmlStreamReader::StartElement) {
491 segmentContainer.
id = m_reader->readElementText();
493 QString elementName = m_reader->name().toString();
495 parseGeoPoints(m_reader->readElementText(), &
path, elementName);
500 segmentContainer.
maneuverId = m_reader->readElementText();
501 }
else if (m_reader->name() ==
QStringLiteral(
"DynamicSpeedInfo")) {
503 if (!parseDynamicSpeedInfo(speedInfo))
510 m_reader->skipCurrentElement();
513 m_reader->readNext();
516 if (m_reader->hasError())
518 links.
append(segmentContainer);
527 for (
const auto &rawPoint : rawPoints) {
530 if (
coords.length() != 2) {
531 m_reader->raiseError(
QStringLiteral(
"Each of the space separated values of \"%1\" "
532 "is expected to be a comma separated pair of "
533 "coordinates (value was \"%2\")")
534 .
arg(elementName).
arg(rawPoint));
543 m_reader->raiseError(
QStringLiteral(
"The latitude portions of \"%1\" are expected to "
544 "have a value convertable to a double (value was "
545 "\"%2\")").
arg(elementName).
arg(latString));
553 m_reader->raiseError(
QStringLiteral(
"The longitude portions of \"%1\" are expected to "
554 "have a value convertable to a double (value was "
555 "\"%2\")").
arg(elementName).
arg(lngString));
560 geoPoints->
append(geoPoint);
566bool QGeoRouteXmlParser::parseBoundingBox(
QGeoRectangle &bounds)
573 m_reader->readNext();
574 while (!(m_reader->tokenType() == QXmlStreamReader::EndElement
575 && m_reader->name() ==
QLatin1String(
"BoundingBox")) && !m_reader->hasError()) {
576 if (m_reader->tokenType() == QXmlStreamReader::StartElement) {
579 if (parseCoordinates(coordinates))
581 }
else if (m_reader->name() ==
QLatin1String(
"BottomRight")) {
583 if (parseCoordinates(coordinates))
586 m_reader->skipCurrentElement();
589 m_reader->readNext();
592 if (m_reader->hasError())
607 m_reader->readNext();
608 while (!(m_reader->tokenType() == QXmlStreamReader::EndElement && m_reader->name() ==
QStringLiteral(
"DynamicSpeedInfo")) &&
609 !m_reader->hasError()) {
610 if (m_reader->tokenType() == QXmlStreamReader::StartElement) {
612 speedInfo.
trafficSpeed = m_reader->readElementText().toDouble();
616 speedInfo.
baseSpeed = m_reader->readElementText().toDouble();
618 speedInfo.
baseTime =
qRound(m_reader->readElementText().toDouble());
620 m_reader->skipCurrentElement();
623 m_reader->readNext();
626 return !m_reader->hasError();
bool isValid
This property holds the validity of this geo coordinate.
QGeoDynamicSpeedInfoContainer()
QList< QGeoCoordinate > path
void setInstructionText(const QString &instructionText)
qreal distanceToNextInstruction
\qmlproperty real routeManeuver::distanceToNextInstruction
void setTimeToNextInstruction(int secs)
void setDirection(InstructionDirection direction)
void setDistanceToNextInstruction(qreal distance)
void setPosition(const QGeoCoordinate &position)
int timeToNextInstruction
\qmlproperty int routeManeuver::timeToNextInstruction
void setExtendedAttributes(const QVariantMap &extendedAttributes)
TravelModes travelModes() const
Returns the travel modes which this request specifies should be considered during the planning of the...
TravelMode
Defines modes of travel to be used for a route.
static QGeoRouteSegmentPrivate * get(QGeoRouteSegment &segment)
void setNextRouteSegment(const QGeoRouteSegment &routeSegment)
Sets the next route segment in the route to routeSegment.
QGeoRouteSegment nextRouteSegment() const
Returns the next route segment in the route.
void setDistance(qreal distance)
bool isValid() const
Returns whether this route segment is valid or not.
void setTravelTime(int secs)
void setPath(const QList< QGeoCoordinate > &path)
QGeoRouteXmlParser(const QGeoRouteRequest &request)
void parse(const QByteArray &data)
void results(const QList< QGeoRoute > &routes)
void errorOccurred(const QString &errorString)
void run() override
Implement this pure virtual function in your subclass.
void setOverallRoute(const QGeoRoute &route)
void setRouteId(const QString &id)
void setLegIndex(int idx)
QGeoRouteRequest request() const
the route request which describes the criteria used in the calculation of this route
void setRequest(const QGeoRouteRequest &request)
QGeoRouteSegment firstRouteSegment() const
Returns the first route segment in the route.
void setFirstRouteSegment(const QGeoRouteSegment &routeSegment)
Sets the first route segment in the route to routeSegment.
void setDistance(qreal distance)
void setTravelTime(int secs)
void setTravelMode(QGeoRouteRequest::TravelMode mode)
Sets the travel mode for this route to mode.
void setPath(const QList< QGeoCoordinate > &path)
QGeoRouteRequest::TravelMode travelMode() const
Returns the travel mode for the this route.
void setRouteLegs(const QList< QGeoRoute > &legs)
void setBounds(const QGeoRectangle &bounds)
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
void append(parameter_type t)
\macro QT_RESTRICTED_CAST_FROM_ASCII
double toDouble(bool *ok=nullptr) const
Returns the string converted to a double value.
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
void start(QRunnable *runnable, int priority=0)
Reserves a thread and uses it to run runnable, unless this thread will make the current thread count ...
static QThreadPool * globalInstance()
Returns the global QThreadPool instance.
Q_CORE_EXPORT QStringView value(QAnyStringView namespaceUri, QAnyStringView name) const noexcept
Combined button and popup list for selecting options.
std::optional< qint64 > baseTime
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
int qRound(qfloat16 d) noexcept
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei const GLubyte GLsizei GLenum const void * coords
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei const GLchar *const * path
QLatin1StringView QLatin1String
#define QStringLiteral(str)
QNetworkRequest request(url)