summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2018-06-28 10:45:16 +0200
committerPaolo Angelelli <paolo.angelelli@qt.io>2018-08-24 11:54:22 +0000
commit0a6315b7a2a00d56a101c4a2ea165242d356e024 (patch)
treec7b9a313f4e001d243d7b796129894b026a53be2
parent34ee76720ee09ac692ea149ce44413cb5c0c7b99 (diff)
downloadqtlocation-0a6315b7a2a00d56a101c4a2ea165242d356e024.tar.gz
Add support for route legs
This patch adds support for route legs, that are the portions of a route between one waypoint and the next. QGeoRouteLeg in particular can be seen as an API addition to QGeoRoute in that it uses and exposes additional methods added to QGeoRoutePrivate but not used in QGeoRoute. Currently the request for legs is set to be the same as the request for the entire route. Finding the related bounding waypoints has to be done programmatically using the legIndex property. Change-Id: If462b1dc6348be16dc96b167db5500f079fe0a64 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/imports/location/location.cpp2
-rw-r--r--src/location/declarativemaps/qdeclarativegeoroute.cpp91
-rw-r--r--src/location/declarativemaps/qdeclarativegeoroute_p.h24
-rw-r--r--src/location/maps/qgeoroute.cpp175
-rw-r--r--src/location/maps/qgeoroute.h28
-rw-r--r--src/location/maps/qgeoroute_p.h24
-rw-r--r--src/location/maps/qgeorouteparserosrmv5.cpp58
-rw-r--r--src/location/maps/qgeoroutesegment.cpp44
-rw-r--r--src/location/maps/qgeoroutesegment.h3
-rw-r--r--src/location/maps/qgeoroutesegment_p.h8
10 files changed, 432 insertions, 25 deletions
diff --git a/src/imports/location/location.cpp b/src/imports/location/location.cpp
index 62debb1d..2c2331bf 100644
--- a/src/imports/location/location.cpp
+++ b/src/imports/location/location.cpp
@@ -191,6 +191,8 @@ public:
qmlRegisterType<QDeclarativeGeoMapItemView, 12>(uri, major, minor, "MapItemView");
qmlRegisterType<QDeclarativeSearchResultModel, 12>(uri, major, minor, "PlaceSearchModel");
qmlRegisterType<QDeclarativeGeoMap, 12>(uri, major, minor, "Map");
+ qmlRegisterType<QDeclarativeGeoRoute, 12>(uri, major, minor, "Route");
+ qmlRegisterType<QDeclarativeGeoRouteLeg, 12>(uri, major, minor, "RouteLeg");
// Register the latest Qt version as QML type version
qmlRegisterModule(uri, QT_VERSION_MAJOR, QT_VERSION_MINOR);
diff --git a/src/location/declarativemaps/qdeclarativegeoroute.cpp b/src/location/declarativemaps/qdeclarativegeoroute.cpp
index 8eeb549a..09ed46ab 100644
--- a/src/location/declarativemaps/qdeclarativegeoroute.cpp
+++ b/src/location/declarativemaps/qdeclarativegeoroute.cpp
@@ -79,12 +79,12 @@ QT_BEGIN_NAMESPACE
*/
QDeclarativeGeoRoute::QDeclarativeGeoRoute(QObject *parent)
- : QObject(parent), segmentsDirty_(true)
+ : QObject(parent)
{
}
QDeclarativeGeoRoute::QDeclarativeGeoRoute(const QGeoRoute &route, QObject *parent)
- : QObject(parent), route_(route), segmentsDirty_(true)
+ : QObject(parent), route_(route)
{
}
@@ -95,6 +95,7 @@ void QDeclarativeGeoRoute::initSegments(unsigned int lastIndex) // -1 turns it
if (!segmentsDirty_)
return;
+ const bool isLeg = qobject_cast<QDeclarativeGeoRoute *>(parent());
QGeoRouteSegment segment = route_.firstRouteSegment();
unsigned int idx = 0;
unsigned int initialListSize = static_cast<unsigned int>(segments_.size());
@@ -104,6 +105,10 @@ void QDeclarativeGeoRoute::initSegments(unsigned int lastIndex) // -1 turns it
QQmlEngine::setContextForObject(routeSegment, QQmlEngine::contextForObject(this));
segments_.append(routeSegment);
}
+ if (isLeg && segment.isLegLastSegment()) {
+ segmentsDirty_ = false;
+ return;
+ }
++idx;
segment = segment.nextRouteSegment();
if (idx > lastIndex && segment.isValid()) // Do not clean segmentsDirty_ if there are still segments to initialize
@@ -322,6 +327,31 @@ QDeclarativeGeoRouteQuery *QDeclarativeGeoRoute::routeQuery()
}
/*!
+ \qmlproperty list<Route> QtLocation::Route::legs
+
+ Returns the route legs associated with this route.
+ Route legs are the sub-routes between each two adjacent waypoints.
+ The result may be empty, if this level of detail is not supported by the
+ backend.
+
+ \since QtLocation 5.12
+*/
+QList<QObject *> QDeclarativeGeoRoute::legs()
+{
+ // route_.routeLegs() is expected not to change.
+ // The following if condition is expected to be run only once.
+ if (route_.routeLegs().size() != legs_.size()) {
+ legs_.clear();
+ QList<QGeoRouteLeg> rlegs = route_.routeLegs();
+ for (const QGeoRouteLeg &r: rlegs) {
+ QDeclarativeGeoRouteLeg *dr = new QDeclarativeGeoRouteLeg(r, this);
+ legs_.append(dr);
+ }
+ }
+ return legs_;
+}
+
+/*!
\qmlmethod bool QtLocation::Route::equals(Route other)
This method performs deep comparison.
@@ -333,4 +363,61 @@ bool QDeclarativeGeoRoute::equals(QDeclarativeGeoRoute *other) const
return route_ == other->route_;
}
+/*!
+ \qmltype RouteLeg
+ \instantiates QDeclarativeGeoRouteLeg
+ \inqmlmodule QtLocation
+ \ingroup qml-QtLocation5-routing
+ \since QtLocation 5.12
+
+ \brief The RouteLeg type represents a leg of a Route, that is the portion
+ of a route between one waypoint and the next.
+
+ \note Since RouteLeg is a subclass of Route, QtLocation::Route::legs will
+ return an empty list if accessed on a route leg.
+*/
+
+/*!
+ \qmlproperty int QtLocation::RouteLeg::legIndex
+
+ Read-only property which holds the index of the leg within the containing Route's list of QtLocation::Route::legs .
+*/
+
+/*!
+ \qmlproperty Route QtLocation::RouteLeg::overallRoute
+
+ Read-only property which holds the Route that contains this leg.
+*/
+
+
+QDeclarativeGeoRouteLeg::QDeclarativeGeoRouteLeg(QObject *parent)
+ : QDeclarativeGeoRoute(parent)
+{
+
+}
+
+QDeclarativeGeoRouteLeg::QDeclarativeGeoRouteLeg(const QGeoRouteLeg &routeLeg, QObject *parent)
+ : QDeclarativeGeoRoute(routeLeg, parent), m_routeLeg(routeLeg)
+{
+
+}
+
+QDeclarativeGeoRouteLeg::~QDeclarativeGeoRouteLeg()
+{
+
+}
+
+int QDeclarativeGeoRouteLeg::legIndex() const
+{
+ return m_routeLeg.legIndex();
+}
+
+QObject *QDeclarativeGeoRouteLeg::overallRoute() const
+{
+ QDeclarativeGeoRoute *containingRoute = qobject_cast<QDeclarativeGeoRoute *>(parent());
+ if (Q_UNLIKELY(!containingRoute))
+ return new QDeclarativeGeoRoute(m_routeLeg.overallRoute(), parent());
+ return containingRoute;
+}
+
QT_END_NAMESPACE
diff --git a/src/location/declarativemaps/qdeclarativegeoroute_p.h b/src/location/declarativemaps/qdeclarativegeoroute_p.h
index fa9025d8..98d08e98 100644
--- a/src/location/declarativemaps/qdeclarativegeoroute_p.h
+++ b/src/location/declarativemaps/qdeclarativegeoroute_p.h
@@ -68,6 +68,7 @@ class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoRoute : public QObject
Q_PROPERTY(QJSValue path READ path WRITE setPath NOTIFY pathChanged)
Q_PROPERTY(QQmlListProperty<QDeclarativeGeoRouteSegment> segments READ segments CONSTANT)
Q_PROPERTY(QDeclarativeGeoRouteQuery *routeQuery READ routeQuery REVISION 11)
+ Q_PROPERTY(QList<QObject *> legs READ legs CONSTANT REVISION 12)
public:
explicit QDeclarativeGeoRoute(QObject *parent = 0);
@@ -89,6 +90,7 @@ public:
int segmentsCount() const;
const QGeoRoute &route() const;
QDeclarativeGeoRouteQuery *routeQuery();
+ QList<QObject *> legs();
Q_INVOKABLE bool equals(QDeclarativeGeoRoute *other) const;
@@ -107,10 +109,30 @@ private:
QGeoRoute route_;
QDeclarativeGeoRouteQuery *routeQuery_ = nullptr;
QList<QDeclarativeGeoRouteSegment *> segments_;
- bool segmentsDirty_;
+ QList<QObject *> legs_;
+ bool segmentsDirty_ = true;
friend class QDeclarativeRouteMapItem;
};
+class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoRouteLeg : public QDeclarativeGeoRoute
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int legIndex READ legIndex CONSTANT)
+ Q_PROPERTY(QObject * overallRoute READ overallRoute CONSTANT)
+
+public:
+ explicit QDeclarativeGeoRouteLeg(QObject *parent = nullptr);
+ QDeclarativeGeoRouteLeg(const QGeoRouteLeg &routeLeg, QObject *parent = nullptr);
+ ~QDeclarativeGeoRouteLeg() override;
+
+ int legIndex() const;
+ QObject *overallRoute() const;
+
+private:
+ QGeoRouteLeg m_routeLeg;
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/location/maps/qgeoroute.cpp b/src/location/maps/qgeoroute.cpp
index 8d62dceb..799fe7f1 100644
--- a/src/location/maps/qgeoroute.cpp
+++ b/src/location/maps/qgeoroute.cpp
@@ -95,6 +95,11 @@ QExplicitlySharedDataPointer<QGeoRoutePrivate> &QGeoRoute::d()
return d_ptr;
}
+const QExplicitlySharedDataPointer<QGeoRoutePrivate> &QGeoRoute::const_d() const
+{
+ return d_ptr;
+}
+
/*!
Constructs a route object from the contents of \a other.
*/
@@ -294,6 +299,28 @@ QList<QGeoCoordinate> QGeoRoute::path() const
return d_ptr->path();
}
+/*!
+ Sets the route legs for a multi-waypoint route.
+
+ \sa QGeoRouteLeg
+ \since 5.12
+*/
+void QGeoRoute::setRouteLegs(const QList<QGeoRouteLeg> &legs)
+{
+ d_ptr->setRouteLegs(legs);
+}
+
+/*!
+ Returns the legs for the route.
+
+ \sa QGeoRouteLeg
+ \since 5.12
+*/
+QList<QGeoRouteLeg> QGeoRoute::routeLegs() const
+{
+ return d_ptr->routeLegs();
+}
+
/*******************************************************************************
*******************************************************************************/
@@ -341,7 +368,8 @@ bool QGeoRoutePrivate::equals(const QGeoRoutePrivate &other) const
&& (distance() == other.distance())
&& (travelMode() == other.travelMode())
&& (path() == other.path())
- && (metadata() == other.metadata()));
+ && (metadata() == other.metadata())
+ && (routeLegs() == other.routeLegs()));
}
void QGeoRoutePrivate::setId(const QString &id)
@@ -434,6 +462,36 @@ QVariantMap QGeoRoutePrivate::metadata() const
return QVariantMap();
}
+void QGeoRoutePrivate::setRouteLegs(const QList<QGeoRouteLeg> &/*legs*/)
+{
+
+}
+
+QList<QGeoRouteLeg> QGeoRoutePrivate::routeLegs() const
+{
+ return QList<QGeoRouteLeg>();
+}
+
+void QGeoRoutePrivate::setLegIndex(int /*idx*/)
+{
+
+}
+
+int QGeoRoutePrivate::legIndex() const
+{
+ return 0;
+}
+
+void QGeoRoutePrivate::setContainingRoute(const QGeoRoute &/*route*/)
+{
+
+}
+
+QGeoRoute QGeoRoutePrivate::containingRoute() const
+{
+ return QGeoRoute();
+}
+
/*******************************************************************************
*******************************************************************************/
@@ -454,6 +512,7 @@ QGeoRoutePrivateDefault::QGeoRoutePrivateDefault(const QGeoRoutePrivateDefault &
m_distance(other.m_distance),
m_travelMode(other.m_travelMode),
m_path(other.m_path),
+ m_legs(other.m_legs),
m_firstSegment(other.m_firstSegment),
m_numSegments(other.m_numSegments){}
@@ -559,10 +618,124 @@ int QGeoRoutePrivateDefault::segmentsCount() const
QGeoRouteSegment segment = m_firstSegment;
while (segment.isValid()) {
++count;
+ if (segment.isLegLastSegment() && m_containingRoute.data()) // if containing route, this is a leg
+ break;
segment = segment.nextRouteSegment();
}
m_numSegments = count;
return count;
}
+void QGeoRoutePrivateDefault::setRouteLegs(const QList<QGeoRouteLeg> &legs)
+{
+ m_legs = legs;
+}
+
+QList<QGeoRouteLeg> QGeoRoutePrivateDefault::routeLegs() const
+{
+ return m_legs;
+}
+
+void QGeoRoutePrivateDefault::setLegIndex(int idx)
+{
+ if (idx >= 0)
+ m_legIndex = idx;
+}
+
+int QGeoRoutePrivateDefault::legIndex() const
+{
+ return m_legIndex;
+}
+
+void QGeoRoutePrivateDefault::setContainingRoute(const QGeoRoute &route)
+{
+ QScopedPointer<QGeoRoute> containingRoute(new QGeoRoute(route));
+ m_containingRoute.swap(containingRoute);
+}
+
+QGeoRoute QGeoRoutePrivateDefault::containingRoute() const
+{
+ if (m_containingRoute)
+ return *m_containingRoute;
+ return QGeoRoute();
+}
+
+/*!
+ \class QGeoRouteLeg
+ \inmodule QtLocation
+ \ingroup QtLocation-routing
+ \since 5.12
+
+ \brief The QGeoRouteLeg class represents a leg of a route, that is the portion
+ of a route between one waypoint and the next.
+ This is a subclass of QGeoRoute, exposing route leg specific API.
+
+ \note QGeoRoute::routeLegs will return an empty list if called on a route leg.
+
+ \sa QGeoRoute
+*/
+
+/*!
+ Constructs a route leg object.
+*/
+
+QGeoRouteLeg::QGeoRouteLeg() : QGeoRoute()
+{
+
+}
+
+/*!
+ Constructs a route leg object from the contents of \a other.
+*/
+QGeoRouteLeg::QGeoRouteLeg(const QGeoRouteLeg &other) : QGeoRoute(other)
+{
+
+}
+
+/*!
+ Destroys this route object.
+*/
+QGeoRouteLeg::~QGeoRouteLeg()
+{
+
+}
+
+/*!
+ Sets the route leg index to \a idx.
+*/
+void QGeoRouteLeg::setLegIndex(int idx)
+{
+ d()->setLegIndex(idx);
+}
+
+/*!
+ Returns the index of this route leg inside the containing QGeoRoute::routeLegs list.
+ Can be used to find the next legs.
+*/
+int QGeoRouteLeg::legIndex() const
+{
+ return const_d()->legIndex();
+}
+
+/*!
+ Sets the \a route that contains this route leg.
+*/
+void QGeoRouteLeg::setOverallRoute(const QGeoRoute &route)
+{
+ d()->setContainingRoute(route);
+}
+
+/*!
+ Returns the \a route that contains this route leg.
+*/
+QGeoRoute QGeoRouteLeg::overallRoute() const
+{
+ return const_d()->containingRoute();
+}
+
+QGeoRouteLeg::QGeoRouteLeg(const QExplicitlySharedDataPointer<QGeoRoutePrivate> &dd) : QGeoRoute(dd)
+{
+
+}
+
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeoroute.h b/src/location/maps/qgeoroute.h
index ef1f7566..381152e3 100644
--- a/src/location/maps/qgeoroute.h
+++ b/src/location/maps/qgeoroute.h
@@ -50,13 +50,13 @@ class QGeoRectangle;
class QGeoRouteSegment;
class QGeoRoutePrivate;
-
+class QGeoRouteLeg;
class Q_LOCATION_EXPORT QGeoRoute
{
public:
QGeoRoute();
QGeoRoute(const QGeoRoute &other);
- ~QGeoRoute();
+ ~QGeoRoute(); // ### Qt6: make this virtual
QGeoRoute &operator = (const QGeoRoute &other);
@@ -87,9 +87,13 @@ public:
void setPath(const QList<QGeoCoordinate> &path);
QList<QGeoCoordinate> path() const;
+ void setRouteLegs(const QList<QGeoRouteLeg> &legs);
+ QList<QGeoRouteLeg> routeLegs() const;
+
protected:
QGeoRoute(const QExplicitlySharedDataPointer<QGeoRoutePrivate> &dd);
QExplicitlySharedDataPointer<QGeoRoutePrivate> &d();
+ const QExplicitlySharedDataPointer<QGeoRoutePrivate> &const_d() const;
private:
QExplicitlySharedDataPointer<QGeoRoutePrivate> d_ptr;
@@ -97,6 +101,26 @@ private:
friend class QGeoRoutePrivate;
};
+class Q_LOCATION_EXPORT QGeoRouteLeg: public QGeoRoute
+{
+public:
+ QGeoRouteLeg();
+ QGeoRouteLeg(const QGeoRouteLeg &other);
+ ~QGeoRouteLeg();
+
+ void setLegIndex(int idx);
+ int legIndex() const;
+
+ void setOverallRoute(const QGeoRoute &route);
+ QGeoRoute overallRoute() const;
+
+protected:
+ QGeoRouteLeg(const QExplicitlySharedDataPointer<QGeoRoutePrivate> &dd);
+
+ friend class QDeclarativeGeoRoute;
+ friend class QGeoRoutePrivate;
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/location/maps/qgeoroute_p.h b/src/location/maps/qgeoroute_p.h
index 384802ee..39f96c48 100644
--- a/src/location/maps/qgeoroute_p.h
+++ b/src/location/maps/qgeoroute_p.h
@@ -55,6 +55,7 @@
#include "qgeoroutesegment.h"
#include <QSharedData>
+#include <QScopedPointer>
QT_BEGIN_NAMESPACE
@@ -96,9 +97,18 @@ public:
virtual QVariantMap metadata() const;
+ virtual void setRouteLegs(const QList<QGeoRouteLeg> &legs);
+ virtual QList<QGeoRouteLeg> routeLegs() const;
+
virtual QString engineName() const = 0;
virtual int segmentsCount() const = 0;
+ // QGeoRouteLeg API
+ virtual void setLegIndex(int idx);
+ virtual int legIndex() const;
+ virtual void setContainingRoute(const QGeoRoute &route);
+ virtual QGeoRoute containingRoute() const;
+
static const QGeoRoutePrivate *routePrivateData(const QGeoRoute &route);
protected:
@@ -110,7 +120,7 @@ class Q_LOCATION_PRIVATE_EXPORT QGeoRoutePrivateDefault : public QGeoRoutePriva
public:
QGeoRoutePrivateDefault();
QGeoRoutePrivateDefault(const QGeoRoutePrivateDefault &other);
- ~QGeoRoutePrivateDefault();
+ ~QGeoRoutePrivateDefault() override;
virtual QGeoRoutePrivate *clone() override;
virtual void setId(const QString &id) override;
@@ -140,6 +150,14 @@ public:
virtual QString engineName() const override;
virtual int segmentsCount() const override;
+ virtual void setRouteLegs(const QList<QGeoRouteLeg> &legs) override;
+ virtual QList<QGeoRouteLeg> routeLegs() const override;
+
+ // QGeoRouteLeg API
+ virtual void setLegIndex(int idx) override;
+ virtual int legIndex() const override;
+ virtual void setContainingRoute(const QGeoRoute &route) override;
+ virtual QGeoRoute containingRoute() const override;
QString m_id;
QGeoRouteRequest m_request;
@@ -153,9 +171,11 @@ public:
QGeoRouteRequest::TravelMode m_travelMode;
QList<QGeoCoordinate> m_path;
-
+ QList<QGeoRouteLeg> m_legs;
QGeoRouteSegment m_firstSegment;
mutable int m_numSegments;
+ QScopedPointer<QGeoRoute> m_containingRoute;
+ int m_legIndex = 0;
};
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeorouteparserosrmv5.cpp b/src/location/maps/qgeorouteparserosrmv5.cpp
index 58299d09..275da2c3 100644
--- a/src/location/maps/qgeorouteparserosrmv5.cpp
+++ b/src/location/maps/qgeorouteparserosrmv5.cpp
@@ -35,8 +35,11 @@
****************************************************************************/
#include "qgeorouteparserosrmv5_p.h"
+#include "qgeoroute.h"
+#include "qgeoroute_p.h"
#include "qgeorouteparser_p_p.h"
#include "qgeoroutesegment.h"
+#include "qgeoroutesegment_p.h"
#include "qgeomaneuver.h"
#include <QtCore/private/qobject_p.h>
@@ -912,22 +915,26 @@ QGeoRouteReply::Error QGeoRouteParserOsrmV5Private::parseReply(QList<QGeoRoute>
foreach (const QJsonValue &r, osrmRoutes) {
if (!r.isObject())
continue;
- QJsonObject route = r.toObject();
- if (!route.value(QLatin1String("legs")).isArray())
+ QJsonObject routeObject = r.toObject();
+ if (!routeObject.value(QLatin1String("legs")).isArray())
continue;
- if (!route.value(QLatin1String("duration")).isDouble())
+ if (!routeObject.value(QLatin1String("duration")).isDouble())
continue;
- if (!route.value(QLatin1String("distance")).isDouble())
+ if (!routeObject.value(QLatin1String("distance")).isDouble())
continue;
- double distance = route.value(QLatin1String("distance")).toDouble();
- double travelTime = route.value(QLatin1String("duration")).toDouble();
+ double distance = routeObject.value(QLatin1String("distance")).toDouble();
+ double travelTime = routeObject.value(QLatin1String("duration")).toDouble();
bool error = false;
QList<QGeoRouteSegment> segments;
- QJsonArray legs = route.value(QLatin1String("legs")).toArray();
+ QJsonArray legs = routeObject.value(QLatin1String("legs")).toArray();
+ QList<QGeoRouteLeg> routeLegs;
+ QGeoRoute route;
for (int legIndex = 0; legIndex < legs.size(); ++legIndex) {
const QJsonValue &l = legs.at(legIndex);
+ QGeoRouteLeg routeLeg;
+ QList<QGeoRouteSegment> legSegments;
if (!l.isObject()) { // invalid leg record
error = true;
break;
@@ -937,16 +944,20 @@ QGeoRouteReply::Error QGeoRouteParserOsrmV5Private::parseReply(QList<QGeoRoute>
error = true;
break;
}
+ const double legDistance = leg.value(QLatin1String("distance")).toDouble();
+ const double legTravelTime = leg.value(QLatin1String("duration")).toDouble();
QJsonArray steps = leg.value(QLatin1String("steps")).toArray();
+ QGeoRouteSegment segment;
for (int stepIndex = 0; stepIndex < steps.size(); ++stepIndex) {
const QJsonValue &s = steps.at(stepIndex);
if (!s.isObject()) {
error = true;
break;
}
- QGeoRouteSegment segment = parseStep(s.toObject(), legIndex, stepIndex);
+ segment = parseStep(s.toObject(), legIndex, stepIndex);
if (segment.isValid()) {
- segments.append(segment);
+ // setNextRouteSegment done below for all segments in the route.
+ legSegments.append(segment);
} else {
error = true;
break;
@@ -954,6 +965,23 @@ QGeoRouteReply::Error QGeoRouteParserOsrmV5Private::parseReply(QList<QGeoRoute>
}
if (error)
break;
+
+ QGeoRouteSegmentPrivate *segmentPrivate = QGeoRouteSegmentPrivate::get(segment);
+ segmentPrivate->setLegLastSegment(true);
+ QList<QGeoCoordinate> path;
+ for (const QGeoRouteSegment &s: qAsConst(legSegments))
+ path.append(s.path());
+ routeLeg.setLegIndex(legIndex);
+ routeLeg.setOverallRoute(route); // QGeoRoute::d_ptr is explicitlySharedDataPointer. Modifiers below won't detach it.
+ routeLeg.setDistance(legDistance);
+ routeLeg.setTravelTime(legTravelTime);
+ if (!path.isEmpty()) {
+ routeLeg.setPath(path);
+ routeLeg.setFirstRouteSegment(legSegments.first());
+ }
+ routeLegs << routeLeg;
+
+ segments.append(legSegments);
}
if (!error) {
@@ -964,15 +992,15 @@ QGeoRouteReply::Error QGeoRouteParserOsrmV5Private::parseReply(QList<QGeoRoute>
for (int i = segments.size() - 1; i > 0; --i)
segments[i-1].setNextRouteSegment(segments[i]);
- QGeoRoute r;
- r.setDistance(distance);
- r.setTravelTime(travelTime);
+ route.setDistance(distance);
+ route.setTravelTime(travelTime);
if (!path.isEmpty()) {
- r.setPath(path);
- r.setFirstRouteSegment(segments.first());
+ route.setPath(path);
+ route.setFirstRouteSegment(segments.first());
}
+ route.setRouteLegs(routeLegs);
//r.setTravelMode(QGeoRouteRequest::CarTravel); // The only one supported by OSRM demo service, but other OSRM servers might do cycle or pedestrian too
- routes.append(r);
+ routes.append(route);
}
}
diff --git a/src/location/maps/qgeoroutesegment.cpp b/src/location/maps/qgeoroutesegment.cpp
index 5bfb4f65..b02285bc 100644
--- a/src/location/maps/qgeoroutesegment.cpp
+++ b/src/location/maps/qgeoroutesegment.cpp
@@ -147,6 +147,21 @@ bool QGeoRouteSegment::isValid() const
}
/*!
+ Returns whether this route segment is the last segment of a route leg.
+
+ \since 5.12
+*/
+bool QGeoRouteSegment::isLegLastSegment() const
+{
+ if (!d_ptr->valid())
+ return false;
+
+ if (!d_ptr->nextRouteSegment())
+ return true;
+ return d_ptr->isLegLastSegment();
+}
+
+/*!
Sets the next route segment in the route to \a routeSegment.
*/
void QGeoRouteSegment::setNextRouteSegment(const QGeoRouteSegment &routeSegment)
@@ -163,8 +178,8 @@ void QGeoRouteSegment::setNextRouteSegment(const QGeoRouteSegment &routeSegment)
*/
QGeoRouteSegment QGeoRouteSegment::nextRouteSegment() const
{
- if (d_ptr->valid() && d_ptr->m_nextSegment)
- return QGeoRouteSegment(d_ptr->m_nextSegment);
+ if (d_ptr->valid() && d_ptr->nextRouteSegment())
+ return QGeoRouteSegment(d_ptr->nextRouteSegment());
return QGeoRouteSegment();
}
@@ -286,6 +301,16 @@ void QGeoRouteSegmentPrivate::setValid(bool valid)
Q_UNUSED(valid)
}
+bool QGeoRouteSegmentPrivate::isLegLastSegment() const
+{
+ return false;
+}
+
+void QGeoRouteSegmentPrivate::setLegLastSegment(bool lastSegment)
+{
+ Q_UNUSED(lastSegment)
+}
+
int QGeoRouteSegmentPrivate::travelTime() const
{
return 0;
@@ -336,6 +361,11 @@ void QGeoRouteSegmentPrivate::setNextRouteSegment(const QExplicitlySharedDataPoi
m_nextSegment = next;
}
+QGeoRouteSegmentPrivate *QGeoRouteSegmentPrivate::get(QGeoRouteSegment &segment)
+{
+ return segment.d_ptr.data();
+}
+
/*******************************************************************************
*******************************************************************************/
@@ -383,6 +413,16 @@ void QGeoRouteSegmentPrivateDefault::setValid(bool valid)
m_valid = valid;
}
+bool QGeoRouteSegmentPrivateDefault::isLegLastSegment() const
+{
+ return m_legLastSegment;
+}
+
+void QGeoRouteSegmentPrivateDefault::setLegLastSegment(bool lastSegment)
+{
+ m_legLastSegment = lastSegment;
+}
+
int QGeoRouteSegmentPrivateDefault::travelTime() const
{
return m_travelTime;
diff --git a/src/location/maps/qgeoroutesegment.h b/src/location/maps/qgeoroutesegment.h
index 3ce01151..1767e33f 100644
--- a/src/location/maps/qgeoroutesegment.h
+++ b/src/location/maps/qgeoroutesegment.h
@@ -61,6 +61,7 @@ public:
bool operator !=(const QGeoRouteSegment &other) const;
bool isValid() const;
+ bool isLegLastSegment() const;
void setNextRouteSegment(const QGeoRouteSegment &routeSegment);
QGeoRouteSegment nextRouteSegment() const;
@@ -83,6 +84,8 @@ protected:
private:
QExplicitlySharedDataPointer<QGeoRouteSegmentPrivate> d_ptr;
+
+ friend class QGeoRouteSegmentPrivate;
};
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeoroutesegment_p.h b/src/location/maps/qgeoroutesegment_p.h
index f0b180da..d72f8b22 100644
--- a/src/location/maps/qgeoroutesegment_p.h
+++ b/src/location/maps/qgeoroutesegment_p.h
@@ -74,6 +74,9 @@ public:
virtual bool valid() const;
virtual void setValid(bool valid);
+ virtual bool isLegLastSegment() const;
+ virtual void setLegLastSegment(bool lastSegment);
+
virtual int travelTime() const;
virtual void setTravelTime(int travelTime);
@@ -90,6 +93,7 @@ public:
virtual void setNextRouteSegment(const QExplicitlySharedDataPointer<QGeoRouteSegmentPrivate> &next);
QExplicitlySharedDataPointer<QGeoRouteSegmentPrivate> m_nextSegment;
+ static QGeoRouteSegmentPrivate *get(QGeoRouteSegment &segment);
protected:
virtual bool equals(const QGeoRouteSegmentPrivate &other) const;
@@ -110,6 +114,9 @@ public:
virtual bool valid() const override;
virtual void setValid(bool valid) override;
+ virtual bool isLegLastSegment() const override;
+ virtual void setLegLastSegment(bool lastSegment) override;
+
virtual int travelTime() const override;
virtual void setTravelTime(int travelTime) override;
@@ -124,6 +131,7 @@ public:
bool m_valid;
+ bool m_legLastSegment = false;
int m_travelTime;
qreal m_distance;
QList<QGeoCoordinate> m_path;