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
classBegin()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>
quickChildren()229     QList<T*> quickChildren() const
230     {
231         QList<T*> res;
232         for (auto kid : qAsConst(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 extraParametersChanged();
248 
249 private Q_SLOTS:
250     void extraParameterChanged();
251 
252 protected:
253     // From QQmlParserStatus
classBegin()254     void classBegin() override {}
componentComplete()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
classBegin()311     void classBegin() {}
312     void componentComplete();
313 
314     QGeoRouteRequest routeRequest();
315     QVariantMap extraParameters();
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>
quickChildren()417     QList<T*> quickChildren() const
418     {
419         QList<T*> res;
420         for (auto kid : qAsConst(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 extraParametersChanged();
442     void departureTimeChanged();
443 
444 private Q_SLOTS:
445     void excludedAreaCoordinateChanged();
446     void extraParameterChanged();
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 m_extraParametersChanged = 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