| 1 | /**************************************************************************** |
| 2 | ** |
| 3 | ** Copyright (C) 2015 The Qt Company Ltd. |
| 4 | ** Contact: http://www.qt.io/licensing/ |
| 5 | ** |
| 6 | ** This file is part of the QtLocation module of the Qt Toolkit. |
| 7 | ** |
| 8 | ** $QT_BEGIN_LICENSE:LGPL3$ |
| 9 | ** Commercial License Usage |
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in |
| 11 | ** accordance with the commercial license agreement provided with the |
| 12 | ** Software or, alternatively, in accordance with the terms contained in |
| 13 | ** a written agreement between you and The Qt Company. For licensing terms |
| 14 | ** and conditions see http://www.qt.io/terms-conditions. For further |
| 15 | ** information use the contact form at http://www.qt.io/contact-us. |
| 16 | ** |
| 17 | ** GNU Lesser General Public License Usage |
| 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
| 19 | ** General Public License version 3 as published by the Free Software |
| 20 | ** Foundation and appearing in the file LICENSE.LGPLv3 included in the |
| 21 | ** packaging of this file. Please review the following information to |
| 22 | ** ensure the GNU Lesser General Public License version 3 requirements |
| 23 | ** will be met: https://www.gnu.org/licenses/lgpl.html. |
| 24 | ** |
| 25 | ** GNU General Public License Usage |
| 26 | ** Alternatively, this file may be used under the terms of the GNU |
| 27 | ** General Public License version 2.0 or later as published by the Free |
| 28 | ** Software Foundation and appearing in the file LICENSE.GPL included in |
| 29 | ** the packaging of this file. Please review the following information to |
| 30 | ** ensure the GNU General Public License version 2.0 requirements will be |
| 31 | ** met: http://www.gnu.org/licenses/gpl-2.0.html. |
| 32 | ** |
| 33 | ** $QT_END_LICENSE$ |
| 34 | ** |
| 35 | ****************************************************************************/ |
| 36 | |
| 37 | #ifndef QDECLARATIVEGEOROUTEMODEL_H |
| 38 | #define QDECLARATIVEGEOROUTEMODEL_H |
| 39 | |
| 40 | // |
| 41 | // W A R N I N G |
| 42 | // ------------- |
| 43 | // |
| 44 | // This file is not part of the Qt API. It exists purely as an |
| 45 | // implementation detail. This header file may change from version to |
| 46 | // version without notice, or even be removed. |
| 47 | // |
| 48 | // We mean it. |
| 49 | // |
| 50 | |
| 51 | #include <QtLocation/private/qlocationglobal_p.h> |
| 52 | #include <QtLocation/private/qdeclarativegeoserviceprovider_p.h> |
| 53 | |
| 54 | #include <QtPositioning/QGeoCoordinate> |
| 55 | #include <QtPositioning/QGeoRectangle> |
| 56 | #include <QtPositioning/private/qgeocoordinateobject_p.h> |
| 57 | |
| 58 | #include <qgeorouterequest.h> |
| 59 | #include <qgeoroutereply.h> |
| 60 | |
| 61 | #include <QtQml/qqml.h> |
| 62 | #include <QtQml/QQmlParserStatus> |
| 63 | #include <QtQml/private/qv4engine_p.h> |
| 64 | #include <QAbstractListModel> |
| 65 | |
| 66 | #include <QObject> |
| 67 | |
| 68 | QT_BEGIN_NAMESPACE |
| 69 | |
| 70 | class QGeoServiceProvider; |
| 71 | class QGeoRoutingManager; |
| 72 | class QDeclarativeGeoRoute; |
| 73 | class QDeclarativeGeoRouteQuery; |
| 74 | |
| 75 | class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoRouteModel : public QAbstractListModel, public QQmlParserStatus |
| 76 | { |
| 77 | Q_OBJECT |
| 78 | Q_ENUMS(Status) |
| 79 | Q_ENUMS(RouteError) |
| 80 | |
| 81 | Q_PROPERTY(QDeclarativeGeoServiceProvider *plugin READ plugin WRITE setPlugin NOTIFY pluginChanged) |
| 82 | Q_PROPERTY(QDeclarativeGeoRouteQuery *query READ query WRITE setQuery NOTIFY queryChanged) |
| 83 | Q_PROPERTY(int count READ count NOTIFY countChanged) |
| 84 | Q_PROPERTY(bool autoUpdate READ autoUpdate WRITE setAutoUpdate NOTIFY autoUpdateChanged) |
| 85 | Q_PROPERTY(Status status READ status NOTIFY statusChanged) |
| 86 | Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged) |
| 87 | Q_PROPERTY(RouteError error READ error NOTIFY errorChanged) |
| 88 | Q_PROPERTY(QLocale::MeasurementSystem measurementSystem READ measurementSystem WRITE setMeasurementSystem NOTIFY measurementSystemChanged) |
| 89 | |
| 90 | Q_INTERFACES(QQmlParserStatus) |
| 91 | |
| 92 | public: |
| 93 | enum Roles { |
| 94 | RouteRole = Qt::UserRole + 500 |
| 95 | }; |
| 96 | |
| 97 | enum Status { |
| 98 | Null, |
| 99 | Ready, |
| 100 | Loading, |
| 101 | Error |
| 102 | }; |
| 103 | |
| 104 | enum RouteError { |
| 105 | NoError = QGeoRouteReply::NoError, |
| 106 | EngineNotSetError = QGeoRouteReply::EngineNotSetError, |
| 107 | CommunicationError = QGeoRouteReply::CommunicationError, |
| 108 | ParseError = QGeoRouteReply::ParseError, |
| 109 | UnsupportedOptionError = QGeoRouteReply::UnsupportedOptionError, |
| 110 | UnknownError = QGeoRouteReply::UnknownError, |
| 111 | //we leave gap for future QGeoRouteReply errors |
| 112 | |
| 113 | //QGeoServiceProvider related errors start here |
| 114 | UnknownParameterError = 100, |
| 115 | MissingRequiredParameterError |
| 116 | }; |
| 117 | |
| 118 | explicit QDeclarativeGeoRouteModel(QObject *parent = 0); |
| 119 | ~QDeclarativeGeoRouteModel(); |
| 120 | |
| 121 | // From QQmlParserStatus |
| 122 | void classBegin() {} |
| 123 | void componentComplete(); |
| 124 | |
| 125 | // From QAbstractListModel |
| 126 | int rowCount(const QModelIndex &parent) const; |
| 127 | QVariant data(const QModelIndex &index, int role) const; |
| 128 | virtual QHash<int,QByteArray> roleNames() const; |
| 129 | |
| 130 | void setPlugin(QDeclarativeGeoServiceProvider *plugin); |
| 131 | QDeclarativeGeoServiceProvider *plugin() const; |
| 132 | |
| 133 | void setQuery(QDeclarativeGeoRouteQuery *query); |
| 134 | QDeclarativeGeoRouteQuery *query() const; |
| 135 | |
| 136 | void setAutoUpdate(bool autoUpdate); |
| 137 | bool autoUpdate() const; |
| 138 | |
| 139 | void setMeasurementSystem(QLocale::MeasurementSystem ms); |
| 140 | QLocale::MeasurementSystem measurementSystem() const; |
| 141 | |
| 142 | Status status() const; |
| 143 | QString errorString() const; |
| 144 | RouteError error() const; |
| 145 | |
| 146 | int count() const; |
| 147 | Q_INVOKABLE QDeclarativeGeoRoute *get(int index); |
| 148 | Q_INVOKABLE void reset(); |
| 149 | Q_INVOKABLE void cancel(); |
| 150 | |
| 151 | Q_SIGNALS: |
| 152 | void countChanged(); |
| 153 | void pluginChanged(); |
| 154 | void queryChanged(); |
| 155 | void autoUpdateChanged(); |
| 156 | void statusChanged(); |
| 157 | void errorChanged(); //emitted also for errorString notification |
| 158 | void routesChanged(); |
| 159 | void measurementSystemChanged(); |
| 160 | void abortRequested(); |
| 161 | |
| 162 | public Q_SLOTS: |
| 163 | void update(); |
| 164 | |
| 165 | private Q_SLOTS: |
| 166 | void routingFinished(QGeoRouteReply *reply); |
| 167 | void routingError(QGeoRouteReply *reply, |
| 168 | QGeoRouteReply::Error error, |
| 169 | const QString &errorString); |
| 170 | void queryDetailsChanged(); |
| 171 | void pluginReady(); |
| 172 | |
| 173 | private: |
| 174 | void setStatus(Status status); |
| 175 | void setError(RouteError error, const QString &errorString); |
| 176 | |
| 177 | bool complete_; |
| 178 | |
| 179 | QDeclarativeGeoServiceProvider *plugin_; |
| 180 | QDeclarativeGeoRouteQuery *routeQuery_; |
| 181 | |
| 182 | QList<QDeclarativeGeoRoute *> routes_; |
| 183 | bool autoUpdate_; |
| 184 | Status status_; |
| 185 | QString errorString_; |
| 186 | RouteError error_; |
| 187 | }; |
| 188 | |
| 189 | |
| 190 | |
| 191 | // purpose of this class is to be convertible to a QGeoCoordinate (through QGeoWaypoint), but also |
| 192 | // to behave like it, so that in QML source compatibility would be preserved. This is, however, not possible to achieve at the present. |
| 193 | class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoWaypoint : public QGeoCoordinateObject, public QQmlParserStatus |
| 194 | { |
| 195 | Q_OBJECT |
| 196 | |
| 197 | Q_PROPERTY(double latitude READ latitude WRITE setLatitude STORED false) |
| 198 | Q_PROPERTY(double longitude READ longitude WRITE setLongitude STORED false) |
| 199 | Q_PROPERTY(double altitude READ altitude WRITE setAltitude STORED false) |
| 200 | Q_PROPERTY(bool isValid READ isValid STORED false) |
| 201 | |
| 202 | Q_PROPERTY(qreal bearing READ bearing WRITE setBearing NOTIFY bearingChanged) |
| 203 | Q_PROPERTY(QVariantMap metadata READ metadata) |
| 204 | Q_PROPERTY(QQmlListProperty<QObject> quickChildren READ declarativeChildren DESIGNABLE false) |
| 205 | Q_CLASSINFO("DefaultProperty" , "quickChildren" ) |
| 206 | Q_INTERFACES(QQmlParserStatus) |
| 207 | |
| 208 | public: |
| 209 | QDeclarativeGeoWaypoint(QObject *parent = 0); |
| 210 | virtual ~QDeclarativeGeoWaypoint(); |
| 211 | |
| 212 | bool operator==(const QDeclarativeGeoWaypoint &other) const; |
| 213 | |
| 214 | qreal latitude() const; |
| 215 | void setLatitude(qreal latitude); |
| 216 | |
| 217 | qreal longitude() const; |
| 218 | void setLongitude(qreal longitude); |
| 219 | |
| 220 | qreal altitude() const; |
| 221 | void setAltitude(qreal altitude); |
| 222 | |
| 223 | bool isValid() const; |
| 224 | |
| 225 | qreal bearing() const; |
| 226 | void setBearing(qreal bearing); |
| 227 | |
| 228 | template <typename T = QObject> |
| 229 | QList<T*> quickChildren() const |
| 230 | { |
| 231 | QList<T*> res; |
| 232 | for (auto kid : qAsConst(t: m_children)) { |
| 233 | auto val = qobject_cast<T*>(kid); |
| 234 | if (val) |
| 235 | res.push_back(val); |
| 236 | } |
| 237 | return res; |
| 238 | } |
| 239 | |
| 240 | QVariantMap metadata(); |
| 241 | void setMetadata(const QVariantMap &meta); |
| 242 | |
| 243 | Q_SIGNALS: |
| 244 | void completed(); |
| 245 | void waypointDetailsChanged(); |
| 246 | void bearingChanged(); |
| 247 | void (); |
| 248 | |
| 249 | private Q_SLOTS: |
| 250 | void (); |
| 251 | |
| 252 | protected: |
| 253 | // From QQmlParserStatus |
| 254 | void classBegin() override {} |
| 255 | void componentComplete() override { m_complete = true; emit completed(); } |
| 256 | |
| 257 | // For quickChildren |
| 258 | static void append(QQmlListProperty<QObject> *p, QObject *v); |
| 259 | static int count(QQmlListProperty<QObject> *p); |
| 260 | static QObject *at(QQmlListProperty<QObject> *p, int idx); |
| 261 | static void clear(QQmlListProperty<QObject> *p); |
| 262 | QQmlListProperty<QObject> declarativeChildren(); |
| 263 | QList<QObject*> m_children; |
| 264 | |
| 265 | // other data members |
| 266 | bool m_metadataChanged = false; |
| 267 | bool m_complete = false; |
| 268 | |
| 269 | qreal m_bearing = Q_QNAN; |
| 270 | QVariantMap m_metadata; |
| 271 | }; |
| 272 | |
| 273 | |
| 274 | |
| 275 | |
| 276 | class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoRouteQuery : public QObject, public QQmlParserStatus |
| 277 | { |
| 278 | Q_OBJECT |
| 279 | Q_ENUMS(TravelMode) |
| 280 | Q_ENUMS(FeatureType) |
| 281 | Q_ENUMS(FeatureWeight) |
| 282 | Q_ENUMS(SegmentDetail) |
| 283 | Q_ENUMS(ManeuverDetail) |
| 284 | Q_ENUMS(RouteOptimization) |
| 285 | Q_FLAGS(RouteOptimizations) |
| 286 | Q_FLAGS(ManeuverDetails) |
| 287 | Q_FLAGS(SegmentDetails) |
| 288 | Q_FLAGS(TravelModes) |
| 289 | |
| 290 | Q_PROPERTY(int numberAlternativeRoutes READ numberAlternativeRoutes WRITE setNumberAlternativeRoutes NOTIFY numberAlternativeRoutesChanged) |
| 291 | Q_PROPERTY(TravelModes travelModes READ travelModes WRITE setTravelModes NOTIFY travelModesChanged) |
| 292 | Q_PROPERTY(RouteOptimizations routeOptimizations READ routeOptimizations WRITE setRouteOptimizations NOTIFY routeOptimizationsChanged) |
| 293 | Q_PROPERTY(SegmentDetail segmentDetail READ segmentDetail WRITE setSegmentDetail NOTIFY segmentDetailChanged) |
| 294 | Q_PROPERTY(ManeuverDetail maneuverDetail READ maneuverDetail WRITE setManeuverDetail NOTIFY maneuverDetailChanged) |
| 295 | Q_PROPERTY(QVariantList waypoints READ waypoints WRITE setWaypoints NOTIFY waypointsChanged) |
| 296 | Q_PROPERTY(QJSValue excludedAreas READ excludedAreas WRITE setExcludedAreas NOTIFY excludedAreasChanged) |
| 297 | Q_PROPERTY(QList<int> featureTypes READ featureTypes NOTIFY featureTypesChanged) |
| 298 | Q_PROPERTY(QVariantMap extraParameters READ extraParameters REVISION 11) |
| 299 | Q_PROPERTY(QDateTime departureTime READ departureTime WRITE setDepartureTime NOTIFY departureTimeChanged REVISION 13) |
| 300 | Q_PROPERTY(QQmlListProperty<QObject> quickChildren READ declarativeChildren DESIGNABLE false) |
| 301 | Q_CLASSINFO("DefaultProperty" , "quickChildren" ) |
| 302 | Q_INTERFACES(QQmlParserStatus) |
| 303 | |
| 304 | public: |
| 305 | |
| 306 | explicit QDeclarativeGeoRouteQuery(QObject *parent = 0); |
| 307 | QDeclarativeGeoRouteQuery(const QGeoRouteRequest &request, QObject *parent = 0); // init from request. For instances intended to be read only |
| 308 | ~QDeclarativeGeoRouteQuery(); |
| 309 | |
| 310 | // From QQmlParserStatus |
| 311 | void classBegin() {} |
| 312 | void componentComplete(); |
| 313 | |
| 314 | QGeoRouteRequest routeRequest(); |
| 315 | QVariantMap (); |
| 316 | |
| 317 | enum TravelMode { |
| 318 | CarTravel = QGeoRouteRequest::CarTravel, |
| 319 | PedestrianTravel = QGeoRouteRequest::PedestrianTravel, |
| 320 | BicycleTravel = QGeoRouteRequest::BicycleTravel, |
| 321 | PublicTransitTravel = QGeoRouteRequest::PublicTransitTravel, |
| 322 | TruckTravel = QGeoRouteRequest::TruckTravel |
| 323 | }; |
| 324 | Q_DECLARE_FLAGS(TravelModes, TravelMode) |
| 325 | |
| 326 | enum FeatureType { |
| 327 | NoFeature = QGeoRouteRequest::NoFeature, |
| 328 | TollFeature = QGeoRouteRequest::TollFeature, |
| 329 | HighwayFeature = QGeoRouteRequest::HighwayFeature, |
| 330 | PublicTransitFeature = QGeoRouteRequest::PublicTransitFeature, |
| 331 | FerryFeature = QGeoRouteRequest::FerryFeature, |
| 332 | TunnelFeature = QGeoRouteRequest::TunnelFeature, |
| 333 | DirtRoadFeature = QGeoRouteRequest::DirtRoadFeature, |
| 334 | ParksFeature = QGeoRouteRequest::ParksFeature, |
| 335 | MotorPoolLaneFeature = QGeoRouteRequest::MotorPoolLaneFeature, |
| 336 | TrafficFeature = QGeoRouteRequest::TrafficFeature |
| 337 | }; |
| 338 | Q_DECLARE_FLAGS(FeatureTypes, FeatureType) |
| 339 | |
| 340 | enum FeatureWeight { |
| 341 | NeutralFeatureWeight = QGeoRouteRequest::NeutralFeatureWeight, |
| 342 | PreferFeatureWeight = QGeoRouteRequest::PreferFeatureWeight, |
| 343 | RequireFeatureWeight = QGeoRouteRequest::RequireFeatureWeight, |
| 344 | AvoidFeatureWeight = QGeoRouteRequest::AvoidFeatureWeight, |
| 345 | DisallowFeatureWeight = QGeoRouteRequest::DisallowFeatureWeight |
| 346 | }; |
| 347 | Q_DECLARE_FLAGS(FeatureWeights, FeatureWeight) |
| 348 | |
| 349 | enum RouteOptimization { |
| 350 | ShortestRoute = QGeoRouteRequest::ShortestRoute, |
| 351 | FastestRoute = QGeoRouteRequest::FastestRoute, |
| 352 | MostEconomicRoute = QGeoRouteRequest::MostEconomicRoute, |
| 353 | MostScenicRoute = QGeoRouteRequest::MostScenicRoute |
| 354 | }; |
| 355 | Q_DECLARE_FLAGS(RouteOptimizations, RouteOptimization) |
| 356 | |
| 357 | enum SegmentDetail { |
| 358 | NoSegmentData = 0x0000, |
| 359 | BasicSegmentData = 0x0001 |
| 360 | }; |
| 361 | Q_DECLARE_FLAGS(SegmentDetails, SegmentDetail) |
| 362 | |
| 363 | enum ManeuverDetail { |
| 364 | NoManeuvers = 0x0000, |
| 365 | BasicManeuvers = 0x0001 |
| 366 | }; |
| 367 | Q_DECLARE_FLAGS(ManeuverDetails, ManeuverDetail) |
| 368 | |
| 369 | void setNumberAlternativeRoutes(int numberAlternativeRoutes); |
| 370 | int numberAlternativeRoutes() const; |
| 371 | |
| 372 | //QList<FeatureType> featureTypes(); |
| 373 | QList<int> featureTypes(); |
| 374 | |
| 375 | |
| 376 | QVariantList waypoints(); |
| 377 | Q_INVOKABLE QVariantList waypointObjects(); |
| 378 | void setWaypoints(const QVariantList &value); |
| 379 | |
| 380 | // READ functions for list properties |
| 381 | QJSValue excludedAreas() const; |
| 382 | void setExcludedAreas(const QJSValue &value); |
| 383 | |
| 384 | Q_INVOKABLE void addWaypoint(const QVariant &w); |
| 385 | Q_INVOKABLE void removeWaypoint(const QVariant &waypoint); |
| 386 | Q_INVOKABLE void clearWaypoints(); |
| 387 | void flushWaypoints(QList<QDeclarativeGeoWaypoint *> &waypoints); |
| 388 | |
| 389 | Q_INVOKABLE void addExcludedArea(const QGeoRectangle &area); |
| 390 | Q_INVOKABLE void removeExcludedArea(const QGeoRectangle &area); |
| 391 | Q_INVOKABLE void clearExcludedAreas(); |
| 392 | |
| 393 | Q_INVOKABLE void setFeatureWeight(FeatureType featureType, FeatureWeight featureWeight); |
| 394 | Q_INVOKABLE int featureWeight(FeatureType featureType); |
| 395 | Q_INVOKABLE void resetFeatureWeights(); |
| 396 | |
| 397 | /* |
| 398 | feature weights |
| 399 | */ |
| 400 | |
| 401 | void setTravelModes(TravelModes travelModes); |
| 402 | TravelModes travelModes() const; |
| 403 | |
| 404 | void setSegmentDetail(SegmentDetail segmentDetail); |
| 405 | SegmentDetail segmentDetail() const; |
| 406 | |
| 407 | void setManeuverDetail(ManeuverDetail maneuverDetail); |
| 408 | ManeuverDetail maneuverDetail() const; |
| 409 | |
| 410 | void setRouteOptimizations(RouteOptimizations optimization); |
| 411 | RouteOptimizations routeOptimizations() const; |
| 412 | |
| 413 | void setDepartureTime(const QDateTime &departureTime); |
| 414 | QDateTime departureTime() const; |
| 415 | |
| 416 | template <typename T = QObject> |
| 417 | QList<T*> quickChildren() const |
| 418 | { |
| 419 | QList<T*> res; |
| 420 | for (auto kid : qAsConst(t: m_children)) { |
| 421 | auto val = qobject_cast<T*>(kid); |
| 422 | if (val) |
| 423 | res.push_back(val); |
| 424 | } |
| 425 | return res; |
| 426 | } |
| 427 | |
| 428 | Q_SIGNALS: |
| 429 | void numberAlternativeRoutesChanged(); |
| 430 | void travelModesChanged(); |
| 431 | void routeOptimizationsChanged(); |
| 432 | |
| 433 | void waypointsChanged(); |
| 434 | void excludedAreasChanged(); |
| 435 | |
| 436 | void featureTypesChanged(); |
| 437 | void maneuverDetailChanged(); |
| 438 | void segmentDetailChanged(); |
| 439 | |
| 440 | void queryDetailsChanged(); |
| 441 | Q_REVISION(11) void (); |
| 442 | void departureTimeChanged(); |
| 443 | |
| 444 | private Q_SLOTS: |
| 445 | void excludedAreaCoordinateChanged(); |
| 446 | void (); |
| 447 | void waypointChanged(); |
| 448 | |
| 449 | protected: |
| 450 | static void append(QQmlListProperty<QObject> *p, QObject *v); |
| 451 | static int count(QQmlListProperty<QObject> *p); |
| 452 | static QObject *at(QQmlListProperty<QObject> *p, int idx); |
| 453 | static void clear(QQmlListProperty<QObject> *p); |
| 454 | |
| 455 | QQmlListProperty<QObject> declarativeChildren(); |
| 456 | QList<QObject*> m_children; |
| 457 | |
| 458 | private: |
| 459 | Q_INVOKABLE void doCoordinateChanged(); |
| 460 | |
| 461 | QGeoRouteRequest request_; |
| 462 | bool complete_; |
| 463 | bool m_excludedAreaCoordinateChanged; |
| 464 | bool = false; |
| 465 | bool m_waypointsChanged = false; |
| 466 | QList<QDeclarativeGeoWaypoint *> m_waypoints; |
| 467 | }; |
| 468 | |
| 469 | QT_END_NAMESPACE |
| 470 | |
| 471 | Q_DECLARE_METATYPE(QDeclarativeGeoWaypoint*) |
| 472 | |
| 473 | #endif |
| 474 | |