diff options
3 files changed, 37 insertions, 446 deletions
diff --git a/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp b/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp index 6a622a72..53b791fe 100644 --- a/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp +++ b/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp @@ -48,38 +48,6 @@ QT_BEGIN_NAMESPACE -static bool compareFloats(qreal a, qreal b) -{ - return (qIsNaN(a) && qIsNaN(b)) - || a == b; -} - -static int findWaypoint(const QList<QDeclarativeGeoWaypoint *> &waypoints, const QDeclarativeGeoWaypoint *w) -{ - for (qsizetype 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 (qsizetype 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; -} - /*! \qmltype RouteModel \instantiates QDeclarativeGeoRouteModel @@ -717,12 +685,7 @@ QDeclarativeGeoRouteQuery::QDeclarativeGeoRouteQuery(const QGeoRouteRequest &req { // Extra params assumed to be already set in the request. // Init waypoints - const QList<QGeoCoordinate> wpts = request_.waypoints(); - for (int i = 0; i < wpts.size(); ++i) { - QDeclarativeGeoWaypoint *w = new QDeclarativeGeoWaypoint(this); - w->setCoordinate(wpts.at(i)); - m_waypoints << w; - } + m_waypoints = request_.waypoints(); } QDeclarativeGeoRouteQuery::~QDeclarativeGeoRouteQuery() @@ -813,78 +776,20 @@ void QDeclarativeGeoRouteQuery::setNumberAlternativeRoutes(int numberAlternative This property, however, always contains a list of coordinates. - \sa waypointObjects, addWaypoint, removeWaypoint, clearWaypoints + \sa addWaypoint, removeWaypoint, clearWaypoints */ -QVariantList QDeclarativeGeoRouteQuery::waypoints() const +QList<QGeoCoordinate> QDeclarativeGeoRouteQuery::waypoints() const { - QVariantList res; - - for (const auto &w : m_waypoints) - res << QVariant::fromValue(w->coordinate()); - - return res; + return m_waypoints; } -/*! - \qmlmethod list<Waypoint> QtLocation::RouteQuery::waypointObjects() - - This method can be used to retrieve the list of Waypoint objects - relative to RouteQuery::waypoints. - - \sa waypointObjects, addWaypoint, removeWaypoint, clearWaypoints -*/ -QVariantList QDeclarativeGeoRouteQuery::waypointObjects() const +void QDeclarativeGeoRouteQuery::setWaypoints(const QList<QGeoCoordinate> &value) { - QVariantList res; - - for (const auto &w : m_waypoints) - res << QVariant::fromValue(w); - - return res; -} - -void QDeclarativeGeoRouteQuery::setWaypoints(const QVariantList &value) -{ - QList<QDeclarativeGeoWaypoint *> waypointList; - bool allWaypoints = true; - - 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 here, w is not a Waypoint, so either a QGeoCoordinate or a variant map, so a waypoint has to be instantiated. - allWaypoints = false; - - const QGeoCoordinate c = w.value<QGeoCoordinate>(); - if (!c.isValid()) { - qmlWarning(this) << QStringLiteral("Invalid waypoint"); - flushWaypoints(waypointList); - return; - } - - waypoint = new QDeclarativeGeoWaypoint(this); - waypoint->setCoordinate(c); - waypointList << waypoint; - - } - - if (allWaypoints && m_waypoints == waypointList) + if (m_waypoints == value) return; - flushWaypoints(m_waypoints); - m_waypoints = waypointList; - for (const QDeclarativeGeoWaypoint *w: qAsConst(m_waypoints)) - connect(w, &QDeclarativeGeoWaypoint::waypointDetailsChanged, this, &QDeclarativeGeoRouteQuery::waypointChanged); - + m_waypoints = value; waypointChanged(); } @@ -1008,36 +913,14 @@ void QDeclarativeGeoRouteQuery::clearExcludedAreas() \sa removeWaypoint, clearWaypoints */ -void QDeclarativeGeoRouteQuery::addWaypoint(const QVariant &waypoint) +void QDeclarativeGeoRouteQuery::addWaypoint(const QGeoCoordinate &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; - } - - // if here, waypoint is not a Waypoint, so either a QGeoCoordinate or a variant map, so a waypoint has to be instantiated. - - const QGeoCoordinate c = waypoint.value<QGeoCoordinate>(); - if (!c.isValid()) { + if (!waypoint.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); + m_waypoints << waypoint; waypointChanged(); } @@ -1050,45 +933,15 @@ void QDeclarativeGeoRouteQuery::addWaypoint(const QVariant &waypoint) \sa addWaypoint, clearWaypoints */ -void QDeclarativeGeoRouteQuery::removeWaypoint(const QVariant &waypoint) +void QDeclarativeGeoRouteQuery::removeWaypoint(const QGeoCoordinate &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; - } - - 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; - } - - const QGeoCoordinate c = waypoint.value<QGeoCoordinate>(); - if (!c.isValid()) { + if (!waypoint.isValid()) { qmlWarning(this) << QStringLiteral("Invalid coordinate as waypoint"); return; } - int idx = findWaypoint(m_waypoints, c); - if (idx >= 0) { - QDeclarativeGeoWaypoint *toRemove = m_waypoints.takeAt(idx); - toRemove->disconnect(this); - if (toRemove->parent() == this) - delete toRemove; - + if (qsizetype idx = m_waypoints.lastIndexOf(waypoint); idx >= 0) { + m_waypoints.remove(idx); waypointChanged(); } else { qmlWarning(this) << QStringLiteral("Cannot remove nonexistent waypoint."); @@ -1107,20 +960,10 @@ void QDeclarativeGeoRouteQuery::clearWaypoints() if (m_waypoints.isEmpty()) return; - flushWaypoints(m_waypoints); + m_waypoints.clear(); waypointChanged(); } -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(); -} - /*! \qmlmethod void QtLocation::RouteQuery::setFeatureWeight(FeatureType feature, FeatureWeight weight) @@ -1435,7 +1278,7 @@ QGeoRouteRequest QDeclarativeGeoRouteQuery::routeRequest() const if (m_waypointsChanged) { m_waypointsChanged = false; // Update waypoints and metadata into request - request_.setWaypoints(waypointCoordinates(m_waypoints)); + request_.setWaypoints(m_waypoints); } return request_; } @@ -1538,170 +1381,4 @@ void QDeclarativeGeoRouteQuery::doCoordinateChanged() */ -/* - * - 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 value->coordinate(); -} - -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 -{ - return coordinate() == other.coordinate() && - compareFloats(m_bearing, other.bearing()); -} - -/*! - \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.value().latitude(); -} - -void QDeclarativeGeoWaypoint::setLatitude(qreal latitude) -{ - if (compareFloats(latitude, m_coordinate.value().latitude())) - return; - - auto coord = m_coordinate.value(); - coord.setLatitude(latitude); - m_coordinate.setValueBypassingBindings(coord); // set the value without notifying, yet - - if (m_complete) { - m_coordinate.notify(); // it will also 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.value().longitude(); -} - -void QDeclarativeGeoWaypoint::setLongitude(qreal longitude) -{ - if (compareFloats(longitude, m_coordinate.value().longitude())) - return; - - auto coord = m_coordinate.value(); - coord.setLongitude(longitude); - m_coordinate.setValueBypassingBindings(coord); // set the value without notifying, yet - - if (m_complete) { - m_coordinate.notify(); // it will also 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.value().altitude(); -} - -void QDeclarativeGeoWaypoint::setAltitude(qreal altitude) -{ - if (compareFloats(altitude, m_coordinate.value().altitude())) - return; - - auto coord = m_coordinate.value(); - coord.setAltitude(altitude); - m_coordinate.setValueBypassingBindings(coord); // set the value without notifying, yet - - if (m_complete) { - m_coordinate.notify(); // it will also emit coordinateChanged() - emit waypointDetailsChanged(); - } -} - -bool QDeclarativeGeoWaypoint::isValid() const -{ - return m_coordinate.value().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 - if (m_complete) { - emit bearingChanged(); - emit waypointDetailsChanged(); - } -} - QT_END_NAMESPACE diff --git a/src/location/declarativemaps/qdeclarativegeoroutemodel_p.h b/src/location/declarativemaps/qdeclarativegeoroutemodel_p.h index 3c0900ff..1e753217 100644 --- a/src/location/declarativemaps/qdeclarativegeoroutemodel_p.h +++ b/src/location/declarativemaps/qdeclarativegeoroutemodel_p.h @@ -187,63 +187,6 @@ private: RouteError error_ = QDeclarativeGeoRouteModel::NoError; }; - - -// purpose of this class is to be convertible to a QGeoCoordinate (through QGeoWaypoint), but also -// to behave like it, so that in QML source compatibility would be preserved. This is, however, not possible to achieve at the present. -class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoWaypoint : public QGeoCoordinateObject, public QQmlParserStatus -{ - Q_OBJECT - QML_NAMED_ELEMENT(Waypoint) - QML_ADDED_IN_VERSION(5, 11) - - Q_PROPERTY(double latitude READ latitude WRITE setLatitude STORED false) - Q_PROPERTY(double longitude READ longitude WRITE setLongitude STORED false) - Q_PROPERTY(double altitude READ altitude WRITE setAltitude STORED false) - Q_PROPERTY(bool isValid READ isValid STORED false) - - Q_PROPERTY(qreal bearing READ bearing WRITE setBearing NOTIFY bearingChanged) - Q_INTERFACES(QQmlParserStatus) - -public: - QDeclarativeGeoWaypoint(QObject *parent = nullptr); - virtual ~QDeclarativeGeoWaypoint(); - - bool operator==(const QDeclarativeGeoWaypoint &other) const; - - qreal latitude() const; - void setLatitude(qreal latitude); - - qreal longitude() const; - void setLongitude(qreal longitude); - - qreal altitude() const; - void setAltitude(qreal altitude); - - bool isValid() const; - - qreal bearing() const; - void setBearing(qreal bearing); - -Q_SIGNALS: - void completed(); - void waypointDetailsChanged(); - void bearingChanged(); - -protected: - // From QQmlParserStatus - void classBegin() override {} - void componentComplete() override { m_complete = true; emit completed(); } - - // other data members - bool m_complete = false; - - qreal m_bearing = Q_QNAN; -}; - - - - class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoRouteQuery : public QObject, public QQmlParserStatus { Q_OBJECT @@ -265,7 +208,7 @@ class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoRouteQuery : public QObject, publ Q_PROPERTY(RouteOptimizations routeOptimizations READ routeOptimizations WRITE setRouteOptimizations NOTIFY routeOptimizationsChanged) Q_PROPERTY(SegmentDetail segmentDetail READ segmentDetail WRITE setSegmentDetail NOTIFY segmentDetailChanged) Q_PROPERTY(ManeuverDetail maneuverDetail READ maneuverDetail WRITE setManeuverDetail NOTIFY maneuverDetailChanged) - Q_PROPERTY(QVariantList waypoints READ waypoints WRITE setWaypoints NOTIFY waypointsChanged) + Q_PROPERTY(QList<QGeoCoordinate> waypoints READ waypoints WRITE setWaypoints NOTIFY waypointsChanged) Q_PROPERTY(QList<QGeoRectangle> excludedAreas READ excludedAreas WRITE setExcludedAreas NOTIFY excludedAreasChanged) Q_PROPERTY(QList<int> featureTypes READ featureTypes NOTIFY featureTypesChanged) Q_PROPERTY(QVariantMap extraParameters READ extraParameters REVISION(5, 11)) @@ -344,17 +287,15 @@ public: QList<int> featureTypes() const; - QVariantList waypoints() const; - Q_INVOKABLE QVariantList waypointObjects() const; - void setWaypoints(const QVariantList &value); + QList<QGeoCoordinate> waypoints() const; + void setWaypoints(const QList<QGeoCoordinate> &value); QList<QGeoRectangle> excludedAreas() const; void setExcludedAreas(const QList<QGeoRectangle> &value); - Q_INVOKABLE void addWaypoint(const QVariant &w); - Q_INVOKABLE void removeWaypoint(const QVariant &waypoint); + Q_INVOKABLE void addWaypoint(const QGeoCoordinate &w); + Q_INVOKABLE void removeWaypoint(const QGeoCoordinate &waypoint); Q_INVOKABLE void clearWaypoints(); - void flushWaypoints(QList<QDeclarativeGeoWaypoint *> &waypoints); Q_INVOKABLE void addExcludedArea(const QGeoRectangle &area); Q_INVOKABLE void removeExcludedArea(const QGeoRectangle &area); @@ -410,11 +351,9 @@ private: bool complete_ = false; bool m_excludedAreaCoordinateChanged = false; mutable bool m_waypointsChanged = false; - QList<QDeclarativeGeoWaypoint *> m_waypoints; + QList<QGeoCoordinate> m_waypoints; }; QT_END_NAMESPACE -Q_DECLARE_METATYPE(QDeclarativeGeoWaypoint*) - #endif diff --git a/tests/auto/declarative_location_core/tst_routing.qml b/tests/auto/declarative_location_core/tst_routing.qml index 6b1778f8..aeed51dc 100644 --- a/tests/auto/declarative_location_core/tst_routing.qml +++ b/tests/auto/declarative_location_core/tst_routing.qml @@ -273,6 +273,7 @@ Item { compare(emptyQuery.waypoints[2], coordinate1) compare(emptyQuery.waypoints[3], coordinate2) emptyQuery.removeWaypoint(coordinate1) // remove one from the middle, check that one added last is removed + compare(emptyQuery.waypoints.length, 3) compare(emptyQuery.waypoints[0], coordinate1) compare(emptyQuery.waypoints[1], coordinate2) compare(emptyQuery.waypoints[2], coordinate2) @@ -562,17 +563,8 @@ Item { property variant f2coordinate2: QtPositioning.coordinate(61, 62) property variant f2coordinate3: QtPositioning.coordinate(63, 64) - Waypoint { - id: waypoint1 - coordinate: QtPositioning.coordinate(70, 70) - bearing: 42 - } - - Waypoint { - id: waypoint2 - coordinate: QtPositioning.coordinate(71, 71) - bearing: 43 - } + property geoCoordinate waypoint1: QtPositioning.coordinate(70, 70) + property geoCoordinate waypoint2: QtPositioning.coordinate(71, 71) RouteQuery {id: routeQuery} property var routeQueryDefaultWaypoints: [ @@ -848,48 +840,31 @@ Item { /* Test waypoints */ // Verify that bearing is NaN for coordinates - verify(isNaN(filledRouteQuery.waypointObjects()[0].bearing)) + verify(isNaN(filledRouteQuery.waypoints[0].bearing)) var numWaypoints = filledRouteQuery.waypoints.length // Add a waypoint with bearing filledRouteQuery.addWaypoint(waypoint1) tryCompare (spy, "count", 5) - compare(filledRouteQuery.waypointObjects()[numWaypoints].bearing, 42) +// compare(filledRouteQuery.waypoints[numWaypoints].bearing, 42) // testing Waypoint to coordinate conversion - compare(filledRouteQuery.waypoints[numWaypoints], filledRouteQuery.waypointObjects()[numWaypoints].coordinate) +// compare(filledRouteQuery.waypoints[numWaypoints], filledRouteQuery.waypoints[numWaypoints].coordinate) waypoint1.latitude += 0.1 compare(model.get(0).distance, 0) - tryCompare (spy, "count", 6) + tryCompare (spy, "count", 5) numWaypoints++; filledRouteQuery.addWaypoint(waypoint2) numWaypoints++; - tryCompare (spy, "count", 7) - compare(filledRouteQuery.waypointObjects()[numWaypoints-1].bearing, 43) + tryCompare (spy, "count", 6) +// compare(filledRouteQuery.waypointObjects()[numWaypoints-1].bearing, 43) compare(model.get(0).distance, 0) - waypoint1.latitude += 0.1 - tryCompare (spy, "count", 8) - waypoint2.latitude += 0.1 - tryCompare (spy, "count", 9) + // remove non-existent waypoint filledRouteQuery.removeWaypoint(waypoint1) - tryCompare (spy, "count", 10) - waypoint2.latitude += 0.1 - tryCompare (spy, "count", 11) - waypoint1.latitude += 0.1 - tryCompare (spy, "count", 11) // No effect, now disconnected - // test with other props - waypoint2.longitude += 0.1 - tryCompare (spy, "count", 12) - waypoint2.altitude = 42 - tryCompare (spy, "count", 13) - waypoint2.bearing += 1 - tryCompare (spy, "count", 14) - compare(waypoint2.longitude, 71.1) - compare(waypoint2.altitude, 42) - compare(waypoint2.bearing, 44) + tryCompare (spy, "count", 6) // Change query model.query = filledRouteQuery2 filledRouteQuery2.numberAlternativeRoutes = 3 - tryCompare (spy, "count", 15) + tryCompare (spy, "count", 7) compare (model.get(0).path.length, 3) // Verify that the old query is disconnected internally ie. does not trigger update @@ -901,7 +876,7 @@ Item { { latitude: 67, longitude: 68 } ]; wait(800) // wait to hope no further updates comes through - compare (spy.count, 15) + compare (spy.count, 7) compare(model.get(0).path.length, 3); // departure time @@ -910,11 +885,11 @@ Item { var validDate = new Date("2011-02-07T11:05:00"); filledRouteQuery2.departureTime = validDate - tryCompare(spy, "count", 16) + tryCompare(spy, "count", 8) compare(model.get(0).extendedAttributes["tst_departureTime"], validDate) filledRouteQuery2.departureTime = invalidDate - tryCompare (spy, "count", 17) + tryCompare (spy, "count", 9) verify(!model.get(0).extendedAttributes["tst_departureTime"]) // ReSetting |