summaryrefslogtreecommitdiff
path: root/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2017-11-06 16:21:58 +0100
committerPaolo Angelelli <paolo.angelelli@qt.io>2017-11-30 16:20:12 +0000
commit74e0f7b414432688858ce9d82a05384b4f883688 (patch)
tree8829ceb8bca000db8383f991240832e5c1e72835 /src/location/declarativemaps/qdeclarativegeoroutemodel.cpp
parent3e107c6d2933b4b924100d1aab18f52f7ca40edc (diff)
downloadqtlocation-74e0f7b414432688858ce9d82a05384b4f883688.tar.gz
Introduce Waypoint
This patch replaces QGeoCoordinate with Waypoint as mean to specify waypoints in a RouteQuery. This patch also adds a new invokable to RouteQuery, waypointObjects, to return QDeclarativeGeoWaypoints instead of QGeoCooordinates. NOTE: If, by 5.11, support to perform implicit conversions in method invocations based on converters registered in the metatype system will be added, this method could/should be removed, and QDeclarativeGeoWaypoint objects should be return as QVariants from the waypoints() getter, as they could be used in place of QGeoCoordinate when passing them as arguments. Task-number: QTBUG-64066 Change-Id: I77747f53cdcbabe6430580b60fa59d4afe8c650a Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/location/declarativemaps/qdeclarativegeoroutemodel.cpp')
-rw-r--r--src/location/declarativemaps/qdeclarativegeoroutemodel.cpp589
1 files changed, 528 insertions, 61 deletions
diff --git a/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp b/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp
index 488e28ca..8066d917 100644
--- a/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp
+++ b/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp
@@ -49,6 +49,59 @@
QT_BEGIN_NAMESPACE
+static bool compareFloats(qreal a, qreal b)
+{
+ return (qIsNaN(a) && qIsNaN(b))
+ || a == b;
+}
+
+static bool compareParameterList(const QList<QDeclarativeGeoMapParameter *> &a, const QList<QDeclarativeGeoMapParameter *> &b)
+{
+ if (a.size() != b.size())
+ return false;
+ if (a != b) {
+ for (int i = 0; i < a.size(); ++i) {
+ if (! (*a.at(i) == *b.at(i)))
+ return false;
+ }
+ }
+ return true;
+}
+
+static int findWaypoint(const QList<QDeclarativeGeoWaypoint *> &waypoints, const QDeclarativeGeoWaypoint *w)
+{
+ for (int i = waypoints.size() - 1; i >= 0; --i) {
+ if (waypoints.at(i) == w || *waypoints.at(i) == *w)
+ return i;
+ }
+ return -1;
+}
+
+static int findWaypoint(const QList<QDeclarativeGeoWaypoint *> &waypoints, const QGeoCoordinate &c)
+{
+ for (int i = waypoints.size() - 1; i >= 0; --i) {
+ if (waypoints.at(i)->coordinate() == c)
+ return i;
+ }
+ return -1;
+}
+
+static QList<QGeoCoordinate> waypointCoordinates(const QList<QDeclarativeGeoWaypoint *> &waypoints)
+{
+ QList<QGeoCoordinate> res;
+ for (const QDeclarativeGeoWaypoint *w: waypoints)
+ res << w->coordinate();
+ return res;
+}
+
+static QList<QVariantMap> waypointMetadata(const QList<QDeclarativeGeoWaypoint *> &waypoints)
+{
+ QList<QVariantMap> res;
+ for (QDeclarativeGeoWaypoint *w: waypoints)
+ res << w->metadata();
+ return res;
+}
+
/*!
\qmltype RouteModel
\instantiates QDeclarativeGeoRouteModel
@@ -773,60 +826,93 @@ void QDeclarativeGeoRouteQuery::setNumberAlternativeRoutes(int numberAlternative
\qmlproperty list<coordinate> RouteQuery::waypoints
- The waypoint coordinates of the desired route.
+ The coordinates of the waypoints for the desired route.
The waypoints should be given in order from origin to destination.
Two or more coordinates are needed.
Waypoints can be set as part of the RouteQuery type declaration or
dynamically with the functions provided.
- \sa addWaypoint, removeWaypoint, clearWaypoints
+ When setting this property to a list of waypoints, each waypoint
+ can be either a \l coordinate or a \l Waypoint, interchangeably.
+ If a \l coordinate is passed, it will be internally converted to a
+ \l Waypoint.
+
+ This property, however, always contains a list of coordinates.
+
+ \sa waypointObjects, addWaypoint, removeWaypoint, clearWaypoints
*/
-QJSValue QDeclarativeGeoRouteQuery::waypoints()
+QVariantList QDeclarativeGeoRouteQuery::waypoints()
{
- QQmlContext *context = QQmlEngine::contextForObject(parent());
- QQmlEngine *engine = context->engine();
- QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine);
+ QVariantList res;
- QV4::Scope scope(v4);
- QV4::Scoped<QV4::ArrayObject> waypointArray(scope, v4->newArrayObject(request_.waypoints().length()));
- for (int i = 0; i < request_.waypoints().length(); ++i) {
- const QGeoCoordinate &c = request_.waypoints().at(i);
+ for (const auto &w : m_waypoints)
+ res << QVariant::fromValue(w->coordinate());
- QV4::ScopedValue cv(scope, v4->fromVariant(QVariant::fromValue(c)));
- waypointArray->putIndexed(i, cv);
- }
+ return res;
+}
+
+/*!
+ \qmlmethod list<Waypoint> QtLocation::RouteQuery::waypointObjects()
- return QJSValue(v4, waypointArray.asReturnedValue());
+ This method can be used to retrieve the list of Waypoint objects
+ relative to RouteQuery::waypoints.
+
+ \sa waypointObjects, addWaypoint, removeWaypoint, clearWaypoints
+*/
+QVariantList QDeclarativeGeoRouteQuery::waypointObjects()
+{
+ QVariantList res;
+
+ for (const auto &w : m_waypoints)
+ res << QVariant::fromValue(w);
+
+ return res;
}
-void QDeclarativeGeoRouteQuery::setWaypoints(const QJSValue &value)
+void QDeclarativeGeoRouteQuery::setWaypoints(const QVariantList &value)
{
- if (!value.isArray())
- return;
+ QList<QDeclarativeGeoWaypoint *> waypointList;
+ bool allWaypoints = true;
- QList<QGeoCoordinate> waypointList;
- quint32 length = value.property(QStringLiteral("length")).toUInt();
- for (quint32 i = 0; i < length; ++i) {
- bool ok;
- QGeoCoordinate c = parseCoordinate(value.property(i), &ok);
+ for (const auto &w: value) {
+ // First, test if this is already a QDeclarativeGeoWaypoint
+ // From QVariant to QObject *
+ QDeclarativeGeoWaypoint *waypoint = nullptr;
+ QObject *obj = qvariant_cast<QObject *>(w);
+ waypoint = qobject_cast<QDeclarativeGeoWaypoint *>(obj);
+
+ if (waypoint) {
+ waypointList << waypoint;
+ continue;
+ }
- if (!ok || !c.isValid()) {
- qmlWarning(this) << "Unsupported waypoint type";
+ // if here, w is not a Waypoint, so either a QGeoCoordinate or a variant map, so a waypoint has to be instantiated.
+ allWaypoints = false;
+
+ QGeoCoordinate c = parseCoordinate(w);
+ if (!c.isValid()) {
+ qmlWarning(this) << QStringLiteral("Invalid waypoint");
+ flushWaypoints(waypointList);
return;
}
- waypointList.append(c);
+ waypoint = new QDeclarativeGeoWaypoint(this);
+ waypoint->setCoordinate(c);
+ waypointList << waypoint;
+
}
- if (request_.waypoints() == waypointList)
+ if (allWaypoints && m_waypoints == waypointList)
return;
- request_.setWaypoints(waypointList);
+ flushWaypoints(m_waypoints);
+ m_waypoints = waypointList;
+ for (const QDeclarativeGeoWaypoint *w: qAsConst(m_waypoints))
+ connect(w, &QDeclarativeGeoWaypoint::waypointDetailsChanged, this, &QDeclarativeGeoRouteQuery::waypointChanged);
- emit waypointsChanged();
- emit queryDetailsChanged();
+ waypointChanged();
}
/*!
@@ -869,7 +955,7 @@ void QDeclarativeGeoRouteQuery::setExcludedAreas(const QJSValue &value)
QGeoRectangle r = parseRectangle(value.property(i), &ok);
if (!ok || !r.isValid()) {
- qmlWarning(this) << "Unsupported area type";
+ qmlWarning(this) << QStringLiteral("Unsupported area type");
return;
}
@@ -881,8 +967,10 @@ void QDeclarativeGeoRouteQuery::setExcludedAreas(const QJSValue &value)
request_.setExcludeAreas(excludedAreasList);
- emit excludedAreasChanged();
- emit queryDetailsChanged();
+ if (complete_) {
+ emit excludedAreasChanged();
+ emit queryDetailsChanged();
+ }
}
/*!
@@ -938,8 +1026,10 @@ void QDeclarativeGeoRouteQuery::removeExcludedArea(const QGeoRectangle &area)
excludedAreas.removeAt(index);
request_.setExcludeAreas(excludedAreas);
- emit excludedAreasChanged();
- emit queryDetailsChanged();
+ if (complete_) {
+ emit excludedAreasChanged();
+ emit queryDetailsChanged();
+ }
}
/*!
@@ -957,8 +1047,10 @@ void QDeclarativeGeoRouteQuery::clearExcludedAreas()
request_.setExcludeAreas(QList<QGeoRectangle>());
- emit excludedAreasChanged();
- emit queryDetailsChanged();
+ if (complete_) {
+ emit excludedAreasChanged();
+ emit queryDetailsChanged();
+ }
}
/*!
@@ -966,24 +1058,43 @@ void QDeclarativeGeoRouteQuery::clearExcludedAreas()
Appends a coordinate to the list of waypoints. Same coordinate
can be set multiple times.
+ The \a coordinate argument can be a \l coordinate or a \l Waypoint.
+ If a \l coordinate is used, it will be internally converted to a
+ \l Waypoint.
\sa removeWaypoint, clearWaypoints
*/
-void QDeclarativeGeoRouteQuery::addWaypoint(const QGeoCoordinate &waypoint)
+void QDeclarativeGeoRouteQuery::addWaypoint(const QVariant &waypoint)
{
- if (!waypoint.isValid()) {
- qmlWarning(this) << QStringLiteral("Not adding invalid waypoint.");
+ QDeclarativeGeoWaypoint *w = nullptr;
+ QObject *obj = qvariant_cast<QObject *>(waypoint);
+ w = qobject_cast<QDeclarativeGeoWaypoint *>(obj);
+
+ if (w) {
+ if (! w->isValid()) {
+ qmlWarning(this) << QStringLiteral("Invalid waypoint");
+ return;
+ }
+
+ m_waypoints << w;
+ connect(w, &QDeclarativeGeoWaypoint::waypointDetailsChanged, this, &QDeclarativeGeoRouteQuery::waypointChanged);
+ waypointChanged();
return;
}
- QList<QGeoCoordinate> waypoints = request_.waypoints();
- waypoints.append(waypoint);
- request_.setWaypoints(waypoints);
+ // if here, waypoint is not a Waypoint, so either a QGeoCoordinate or a variant map, so a waypoint has to be instantiated.
- if (complete_) {
- emit waypointsChanged();
- emit queryDetailsChanged();
+ QGeoCoordinate c = parseCoordinate(waypoint);
+ if (!c.isValid()) {
+ qmlWarning(this) << QStringLiteral("Invalid coordinate as waypoint");
+ return;
}
+
+ w = new QDeclarativeGeoWaypoint(this);
+ w->setCoordinate(c);
+ m_waypoints << w;
+ connect(w, &QDeclarativeGeoWaypoint::waypointDetailsChanged, this, &QDeclarativeGeoRouteQuery::waypointChanged);
+ waypointChanged();
}
/*!
@@ -995,22 +1106,49 @@ void QDeclarativeGeoRouteQuery::addWaypoint(const QGeoCoordinate &waypoint)
\sa addWaypoint, clearWaypoints
*/
-void QDeclarativeGeoRouteQuery::removeWaypoint(const QGeoCoordinate &waypoint)
+void QDeclarativeGeoRouteQuery::removeWaypoint(const QVariant &waypoint)
{
- QList<QGeoCoordinate> waypoints = request_.waypoints();
+ QDeclarativeGeoWaypoint *w = nullptr;
+ QObject *obj = qvariant_cast<QObject *>(waypoint);
+ w = qobject_cast<QDeclarativeGeoWaypoint *>(obj);
- int index = waypoints.lastIndexOf(waypoint);
- if (index == -1) {
- qmlWarning(this) << QStringLiteral("Cannot remove nonexistent waypoint.");
+ if (w) {
+ if (!w->isValid()) {
+ qmlWarning(this) << QStringLiteral("Invalid waypoint");
+ return;
+ }
+
+ int idx = findWaypoint(m_waypoints, w);
+ if (idx >= 0) {
+ QDeclarativeGeoWaypoint *toRemove = m_waypoints.takeAt(idx);
+ toRemove->disconnect(this);
+ if (toRemove->parent() == this)
+ delete toRemove;
+
+ waypointChanged();
+ } else {
+ qmlWarning(this) << QStringLiteral("Cannot remove nonexistent waypoint.");
+ }
return;
}
- waypoints.removeAt(index);
+ QGeoCoordinate c = parseCoordinate(waypoint);
+ if (!c.isValid()) {
+ qmlWarning(this) << QStringLiteral("Invalid coordinate as waypoint");
+ return;
+ }
- request_.setWaypoints(waypoints);
+ int idx = findWaypoint(m_waypoints, c);
+ if (idx >= 0) {
+ QDeclarativeGeoWaypoint *toRemove = m_waypoints.takeAt(idx);
+ toRemove->disconnect(this);
+ if (toRemove->parent() == this)
+ delete toRemove;
- emit waypointsChanged();
- emit queryDetailsChanged();
+ waypointChanged();
+ } else {
+ qmlWarning(this) << QStringLiteral("Cannot remove nonexistent waypoint.");
+ }
}
/*!
@@ -1022,13 +1160,21 @@ void QDeclarativeGeoRouteQuery::removeWaypoint(const QGeoCoordinate &waypoint)
*/
void QDeclarativeGeoRouteQuery::clearWaypoints()
{
- if (request_.waypoints().isEmpty())
+ if (m_waypoints.isEmpty())
return;
- request_.setWaypoints(QList<QGeoCoordinate>());
+ flushWaypoints(m_waypoints);
+ waypointChanged();
+}
- emit waypointsChanged();
- emit queryDetailsChanged();
+void QDeclarativeGeoRouteQuery::flushWaypoints(QList<QDeclarativeGeoWaypoint *> &waypoints)
+{
+ for (const QDeclarativeGeoWaypoint *w : qAsConst(waypoints)) {
+ w->disconnect(this);
+ if (w->parent() == this) // w has been created internally as a result of adding a QGeoCoordinate
+ delete w;
+ }
+ waypoints.clear();
}
/*!
@@ -1301,6 +1447,12 @@ QGeoRouteRequest QDeclarativeGeoRouteQuery::routeRequest()
extraParameters[p->type()] = p->toVariantMap();
request_.setExtraParameters(extraParameters);
}
+ if (m_waypointsChanged) {
+ m_waypointsChanged = false;
+ // Update waypoints and metadata into request
+ request_.setWaypoints(waypointCoordinates(m_waypoints));
+ request_.setWaypointsMetadata(waypointMetadata(m_waypoints));
+ }
return request_;
}
@@ -1321,6 +1473,15 @@ void QDeclarativeGeoRouteQuery::extraParameterChanged()
}
}
+void QDeclarativeGeoRouteQuery::waypointChanged()
+{
+ m_waypointsChanged = true;
+ if (complete_) {
+ emit waypointsChanged();
+ emit queryDetailsChanged();
+ }
+}
+
void QDeclarativeGeoRouteQuery::append(QQmlListProperty<QObject> *p, QObject *v)
{
QDeclarativeGeoRouteQuery *query = static_cast<QDeclarativeGeoRouteQuery*>(p->object);
@@ -1331,8 +1492,10 @@ void QDeclarativeGeoRouteQuery::append(QQmlListProperty<QObject> *p, QObject *v)
query->m_extraParametersChanged = true;
query->connect(param, &QGeoMapParameter::propertyUpdated,
query, &QDeclarativeGeoRouteQuery::extraParameterChanged);
- emit query->extraParametersChanged();
- emit query->queryDetailsChanged();
+ if (query->complete_) {
+ emit query->extraParametersChanged();
+ emit query->queryDetailsChanged();
+ }
}
}
@@ -1375,7 +1538,311 @@ QQmlListProperty<QObject> QDeclarativeGeoRouteQuery::declarativeChildren()
void QDeclarativeGeoRouteQuery::doCoordinateChanged()
{
m_excludedAreaCoordinateChanged = false;
- emit queryDetailsChanged();
+ if (complete_)
+ emit queryDetailsChanged();
+}
+
+/*!
+ \qmltype Waypoint
+ \instantiates QDeclarativeGeoWaypoint
+ \inqmlmodule QtLocation
+ \ingroup qml-QtLocation5-routing
+ \since Qt Location 5.11
+
+ \brief The Waypoint type provides a mean to specify a waypoint in a \l RouteQuery
+ in a more detailed way than by using a simple \l coordinate.
+
+ A Waypoint is a type that allows to specify properties of a waypoint in a \l RouteQuery,
+ such as the waypoint coordinate, or the angle of approach to the waypoint.
+
+ Additional information that are backend-specific can be specified by nesting \l MapParameter
+ elements.
+
+ Changing properties of the waypoint or of its nested MapParameteters will cause the containing
+ \l RouteQuery to emit the queryDetailsChanged signal.
+
+ \section2 Example Usage
+
+ The following snippet is two-part, showing firstly the declaration of
+ objects, and secondly a short piece of procedural code using it. We set
+ the routeModel's \l{autoUpdate} property to false, and call \l{update} once
+ the query is set up, to avoid useless extra requests halfway through the
+ set up of the query.
+
+ \code
+ Plugin {
+ id: aPlugin
+ name: "osm"
+ }
+
+ Waypoint {
+ id: waypointStart
+ coordinate: ...
+ bearing: ...
+ }
+ Waypoint {
+ id: waypointFinish
+ coordinate: ...
+ bearing: ...
+ }
+
+ RouteQuery {
+ id: aQuery
+ Component.onCompleted: {
+ travelModes = RouteQuery.CarTravel
+ addWaypoint(waypointStart)
+ var aWaypoint = Qt.createQmlObject ('import QtLocation 5.11; Waypoint { ... }', ...)
+ addWaypoint(aWaypoint)
+ addWaypoint(waypointFinish)
+ }
+ }
+
+ RouteModel {
+ id: routeModel
+ plugin: aPlugin
+ query: aQuery
+ autoUpdate: true
+ }
+ \endcode
+
+ \sa RouteQuery
+*/
+
+
+/*
+ *
+ At the time of adding this class (2017.11), 3 routing services are natively supported in Qt: Esri, Here and OSRM.
+ Waypoint documentation for each of these:
+ Esri: http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000 , called "stop"
+ HERE: https://developer.here.com/documentation/routing/topics/resource-param-type-waypoint.html
+ OSRM: https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md , under Request Options
+ *
+ */
+
+
+static QGeoCoordinate convertWaypointToCoordinate(const QDeclarativeGeoWaypoint *value)
+{
+ return QGeoCoordinate(value);
+}
+
+struct WaypointVariantConversions
+{
+ WaypointVariantConversions()
+ {
+ QMetaType::registerConverter<QDeclarativeGeoWaypoint *, QGeoCoordinate>(convertWaypointToCoordinate);
+ }
+};
+
+Q_GLOBAL_STATIC(WaypointVariantConversions, initWaypointConversions)
+
+
+QDeclarativeGeoWaypoint::QDeclarativeGeoWaypoint(QObject *parent) : QGeoCoordinateObject(parent)
+{
+ initWaypointConversions();
+ connect(this, &QGeoCoordinateObject::coordinateChanged,
+ this, &QDeclarativeGeoWaypoint::waypointDetailsChanged);
+}
+
+QDeclarativeGeoWaypoint::~QDeclarativeGeoWaypoint()
+{
+
+}
+
+bool QDeclarativeGeoWaypoint::operator==(const QDeclarativeGeoWaypoint &other) const
+{
+ const QList<QDeclarativeGeoMapParameter *> params = quickChildren<QDeclarativeGeoMapParameter>();
+ const QList<QDeclarativeGeoMapParameter *> otherParams = other.quickChildren<QDeclarativeGeoMapParameter>();
+
+ return coordinate() == other.coordinate() &&
+ compareFloats(m_bearing, other.bearing()) &&
+ compareParameterList(params, otherParams);
+}
+
+/*!
+ \qmlproperty coordinate Waypoint::coordinate
+
+ The waypoint's coordinate. The default value is undefined.
+*/
+
+
+/*!
+ \qmlproperty real Waypoint::latitude
+
+ The latitude of the waypoint's coordinate. The default value is NaN.
+ Changing this property will affect the \l Waypoint::coordinate property as well.
+*/
+qreal QDeclarativeGeoWaypoint::latitude() const
+{
+ return m_coordinate.latitude();
+}
+
+void QDeclarativeGeoWaypoint::setLatitude(qreal latitude)
+{
+ if (compareFloats(latitude, m_coordinate.latitude()))
+ return;
+
+ m_coordinate.setLatitude(latitude);
+ if (m_complete) {
+ emit coordinateChanged();
+ emit waypointDetailsChanged();
+ }
+}
+
+/*!
+ \qmlproperty real Waypoint::longitude
+
+ The longitude of the waypoint's coordinate. The default value is NaN.
+ Changing this property will affect the \l Waypoint::coordinate property as well.
+*/
+qreal QDeclarativeGeoWaypoint::longitude() const
+{
+ return m_coordinate.longitude();
+}
+
+void QDeclarativeGeoWaypoint::setLongitude(qreal longitude)
+{
+ if (compareFloats(longitude, m_coordinate.longitude()))
+ return;
+
+ m_coordinate.setLongitude(longitude);
+ if (m_complete) {
+ emit coordinateChanged();
+ emit waypointDetailsChanged();
+ }
+}
+
+/*!
+ \qmlproperty real Waypoint::altitude
+
+ The altitude of the waypoint's coordinate. The default value is NaN.
+ Changing this property will affect the \l Waypoint::coordinate property as well.
+*/
+qreal QDeclarativeGeoWaypoint::altitude() const
+{
+ return m_coordinate.altitude();
+}
+
+void QDeclarativeGeoWaypoint::setAltitude(qreal altitude)
+{
+ if (compareFloats(altitude, m_coordinate.altitude()))
+ return;
+
+ m_coordinate.setAltitude(altitude);
+ if (m_complete) {
+ emit coordinateChanged();
+ emit waypointDetailsChanged();
+ }
+}
+
+bool QDeclarativeGeoWaypoint::isValid() const
+{
+ return m_coordinate.isValid();
+}
+
+/*!
+ \qmlproperty real Waypoint::bearing
+
+ The bearing specifying the angle of approach of the waypoint, that is the bearing with which the waypoint is to be approached.
+ This information may be used by the provider to filter the road segment the waypoint will be placed on, and,
+ depending on the provider and the \l {QGeoRouteRequest::TravelMode} {travel mode} used, to restrict the maneuvers
+ allowed at the waypoint, potentially making the provider calculating and returning a different route.
+
+ If set to NaN, this value will not be considered.
+
+ The default value is NaN.
+*/
+qreal QDeclarativeGeoWaypoint::bearing() const
+{
+ return m_bearing;
+}
+
+void QDeclarativeGeoWaypoint::setBearing(qreal bearing)
+{
+ if (compareFloats(bearing, m_bearing))
+ return;
+
+ m_bearing = bearing;
+
+ // Bearing is actually packed into QGeoRouteRequest::waypointMetadata() together with the extra parameters
+ m_metadataChanged = true;
+ if (m_complete) {
+ emit bearingChanged();
+ emit waypointDetailsChanged();
+ }
+}
+
+QVariantMap QDeclarativeGeoWaypoint::metadata()
+{
+ if (m_metadataChanged) {
+ m_metadataChanged = false;
+ m_metadata.clear();
+ // Update metadata
+ const QList<QDeclarativeGeoMapParameter *> params = quickChildren<QDeclarativeGeoMapParameter>();
+ QVariantMap extraParameters;
+ for (const QDeclarativeGeoMapParameter *p: params)
+ extraParameters[p->type()] = p->toVariantMap();
+ m_metadata[QStringLiteral("extra")] = extraParameters;
+ m_metadata[QStringLiteral("bearing")] = m_bearing;
+ }
+ return m_metadata;
+}
+
+void QDeclarativeGeoWaypoint::extraParameterChanged()
+{
+ m_metadataChanged = true;
+ if (m_complete) {
+ emit extraParametersChanged();
+ emit waypointDetailsChanged();
+ }
+}
+
+void QDeclarativeGeoWaypoint::append(QQmlListProperty<QObject> *p, QObject *v)
+{
+ QDeclarativeGeoWaypoint *waypoint = static_cast<QDeclarativeGeoWaypoint*>(p->object);
+ waypoint->m_children.append(v);
+
+ QDeclarativeGeoMapParameter *param = qobject_cast<QDeclarativeGeoMapParameter *>(v);
+ if (param) {
+ waypoint->connect(param, &QGeoMapParameter::propertyUpdated,
+ waypoint, &QDeclarativeGeoWaypoint::extraParameterChanged);
+ waypoint->extraParameterChanged();
+ }
+}
+
+int QDeclarativeGeoWaypoint::count(QQmlListProperty<QObject> *p)
+{
+ return static_cast<QDeclarativeGeoWaypoint*>(p->object)->m_children.count();
+}
+
+QObject *QDeclarativeGeoWaypoint::at(QQmlListProperty<QObject> *p, int idx)
+{
+ return static_cast<QDeclarativeGeoWaypoint*>(p->object)->m_children.at(idx);
+}
+
+void QDeclarativeGeoWaypoint::clear(QQmlListProperty<QObject> *p)
+{
+ QDeclarativeGeoWaypoint *waypoint = static_cast<QDeclarativeGeoWaypoint*>(p->object);
+ for (auto kid : qAsConst(waypoint->m_children)) {
+ auto val = qobject_cast<QDeclarativeGeoMapParameter *>(kid);
+ if (val) {
+ val->disconnect(waypoint);
+ waypoint->m_metadataChanged = true;
+ }
+ }
+ waypoint->m_children.clear();
+ if (waypoint->m_metadataChanged && waypoint->m_complete) {
+ emit waypoint->extraParametersChanged();
+ emit waypoint->waypointDetailsChanged();
+ }
+}
+
+QQmlListProperty<QObject> QDeclarativeGeoWaypoint::declarativeChildren()
+{
+ return QQmlListProperty<QObject>(this, nullptr,
+ &QDeclarativeGeoWaypoint::append,
+ &QDeclarativeGeoWaypoint::count,
+ &QDeclarativeGeoWaypoint::at,
+ &QDeclarativeGeoWaypoint::clear);
}
QT_END_NAMESPACE