1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtLocation module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL$
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 https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 or (at your option) any later version
20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 ** included in the packaging of this file. Please review the following
23 ** information to ensure the GNU General Public License requirements will
24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 **
26 ** $QT_END_LICENSE$
27 **
28 ****************************************************************************/
29
30 #include "qdeclarativenavigator_p.h"
31 #include "qdeclarativenavigator_p_p.h"
32 #include <QtLocation/private/qdeclarativegeomap_p.h>
33 #include <QtLocation/private/qdeclarativegeoserviceprovider_p.h>
34 #include <QtLocation/private/qnavigationmanager_p.h>
35 #include <QtLocation/private/qnavigationmanagerengine_p.h>
36 #include <QtLocation/private/qgeomapparameter_p.h>
37 #include <QtLocation/private/qdeclarativegeoroute_p.h>
38 #include <QtLocation/private/qdeclarativegeoroutemodel_p.h>
39 #include <QtLocation/private/qdeclarativegeoroutesegment_p.h>
40 #include <QtLocation/qgeoserviceprovider.h>
41 #include <QtPositioningQuick/private/qdeclarativepositionsource_p.h>
42 #include <QtQml/qqmlinfo.h>
43
44 QT_BEGIN_NAMESPACE
45
46 /*!
47 \qmlmodule Qt.labs.location 1.0
48 \title Qt Labs Location QML Types
49 \ingroup qmlmodules
50 \brief Provides experimental QtLocation QML types, such as \l Navigator and
51 various map objects types (not to be confused with map items).
52
53 To use this module, import the module with the following line:
54
55 \qml
56 import Qt.labs.location 1.0
57 \endqml
58
59 \note These types are experimental and subject to source-incompatible changes from one
60 Qt minor release to the next, until they are ready to be moved to the stable QtLocation QML
61 module.
62 */
63
64 /*!
65 \qmltype Navigator
66 \instantiates QDeclarativeNavigator
67 \inqmlmodule Qt.labs.location
68 \ingroup qml-QtLocation5-maps
69
70 \brief The Navigator type offers functionalities to perform turn-by-turn navigation.
71
72 The Navigator purpose is to use a plugin's turn-by-turn navigation implementation in a QML
73 application in a seamless manner.
74 This object may take control of the map position, orientation, tilting and zoom, as well as changing
75 the map style, elements on the map such as direction information.
76 In certain cases, it may also restrict user interaction with the Map and with the items on it.
77 */
78
79 /*!
80 \qmlproperty Plugin Qt.labs.location::Navigator::plugin
81
82 This property holds the plugin which provides the navigation functionality.
83
84 This is a write-once property. Once the Navigator has a plugin associated with
85 it, any attempted modifications of the plugin property will be ignored.
86
87 \sa Plugin
88 */
89
90 /*!
91 \qmlproperty Map Qt.labs.location::Navigator::map
92
93 This property holds the Map that the navigator is in charge of controlling.
94
95 This is a write-once property. Once the Navigator has a Map associated with
96 it, any attempted modifications of the map property will be ignored.
97
98 \sa Map
99 */
100
101 /*!
102 \qmlproperty Route Qt.labs.location::Navigator::route
103
104 This property holds the Route that the navigator is using
105 to perform the navigation.
106
107 \note Setting this property while a navigation session is ongoing will
108 stop the navigation.
109
110 \sa Route
111 */
112
113 /*!
114 \qmlproperty PositionSource Qt.labs.location::Navigator::positionSource
115
116 This property holds the PositionSource that the navigator will receive position
117 updates from to perform the navigation.
118
119 This is a write-once property. Once the Navigator has a PositionSource associated with
120 it, any attempted modifications of the positionSource property will be ignored.
121
122 \sa PositionSource
123 */
124
125 /*!
126 \qmlproperty bool Qt.labs.location::Navigator::active
127
128 This property tells whether the Navigator is navigating or not.
129 Set this property to \c true to start the navigation.
130 Set it to \c false to stop an active navigation session.
131 */
132
133 /*!
134 \qmlproperty bool Qt.labs.location::Navigator::navigatorReady
135
136 This read-only property tells whether the navigator is ready
137 to start the navigation or not.
138 A Navigator becomes ready once the plugin is attached and a navigation engine has been
139 instantiated, and the other required properties are set to valid values.
140 */
141
142 /*!
143 \qmlproperty bool Qt.labs.location::Navigator::trackPositionSource
144
145 This property tells whether the Navigator should control the Map camera to
146 keep track of position source updates. This property is enabled (\c true) by
147 default, and setting it to \c false is useful in cases where e.g. the user
148 starts gesturing over the map area.
149
150 Navigator plugins can also control this property directly e.g. user map
151 interaction could trigger the property change. Honoring the user-specified
152 value of this property is plugin dependent.
153 */
154
155 /*!
156 \qmlproperty bool Qt.labs.location::Navigator::automaticReroutingEnabled
157
158 This property tells whether the Navigator should automatically recalculate
159 the route when the position from \l positionSource ends too far from the route.
160 The operation performed in such case is equivalent to calling \l recalculateRoutes.
161 The default value is \c true.
162
163 \note Whether this property has any effect is plugin-dependent.
164 Also, whether or not it has an effect while the navigator is active is plugin-dependent.
165 */
166
167 /*!
168 \qmlproperty bool Qt.labs.location::Navigator::isOnRoute
169
170 While the Navigator is in active tracking mode, this property tells
171 whether the position from \l positionSource is on the route or not.
172 */
173
174 /*!
175 \qmlmethod void Qt.labs.location::Navigator::recalculateRoutes()
176
177 Calling this method forces the backend to trigger a routes recalculation.
178
179 \sa automaticReroutingEnabled
180 */
181
182 /*!
183 \qmlproperty enumeration Qt.labs.location::Navigator::error
184 \readonly
185
186 This read-only property holds the latest error value of the geocoding request.
187
188 \value Navigator.NoError
189 No error has occurred.
190 \value Navigator.NotSupportedError
191 Navigation is not supported by the service provider.
192 \value Navigator.ConnectionError
193 An error occurred while communicating with the service provider.
194 \value Navigator.LoaderError
195 The geoservice provider library could not be loaded. Setting
196 QT_DEBUG_PLUGINS environment variable may help diagnosing the
197 problem.
198 \value Navigator.UnknownParameterError
199 An unknown parameter was specified.
200 \value Navigator.MissingRequiredParameterError
201 Required parameter was not specified.
202 \value Navigator.UnknownError
203 Unknown error occurred.
204 */
205
QDeclarativeNavigatorPrivate(QParameterizableObject * q_)206 QDeclarativeNavigatorPrivate::QDeclarativeNavigatorPrivate(QParameterizableObject *q_)
207 : q(q_), m_params(new QDeclarativeNavigatorParams), m_basicDirections(static_cast<QDeclarativeNavigator *>(q_))
208 {
209 }
210
QDeclarativeNavigator(QObject * parent)211 QDeclarativeNavigator::QDeclarativeNavigator(QObject *parent)
212 : QParameterizableObject(parent), d_ptr(new QDeclarativeNavigatorPrivate(this))
213 {
214 }
215
~QDeclarativeNavigator()216 QDeclarativeNavigator::~QDeclarativeNavigator()
217 {
218 }
219
classBegin()220 void QDeclarativeNavigator::classBegin()
221 {
222 }
223
componentComplete()224 void QDeclarativeNavigator::componentComplete()
225 {
226 d_ptr->m_completed = true;
227 // Children have been completed
228 for (auto param : quickChildren<QGeoMapParameter>())
229 d_ptr->m_params->m_parameters.push_back(param);
230 if (d_ptr->m_plugin && d_ptr->m_plugin->isAttached())
231 pluginReady();
232 }
233
plugin() const234 QDeclarativeGeoServiceProvider *QDeclarativeNavigator::plugin() const
235 {
236 return d_ptr->m_plugin;
237 }
238
setMap(QDeclarativeGeoMap * map)239 void QDeclarativeNavigator::setMap(QDeclarativeGeoMap *map)
240 {
241 if (d_ptr->m_params->m_map || !map) // set once prop
242 return;
243
244 d_ptr->m_params->m_map = map;
245 connect(map, &QObject::destroyed, this,
246 [this]() {
247 this->mapChanged();
248 this->updateReadyState();
249 });
250 emit mapChanged();
251 updateReadyState();
252 }
253
map() const254 QDeclarativeGeoMap *QDeclarativeNavigator::map() const
255 {
256 return d_ptr->m_params->m_map;
257 }
258
setRoute(QDeclarativeGeoRoute * route)259 void QDeclarativeNavigator::setRoute(QDeclarativeGeoRoute *route)
260 {
261 if (d_ptr->m_params->m_route == route) // This isn't set-once
262 return;
263
264 const bool isReady = d_ptr->m_navigator && d_ptr->m_navigator->ready();
265 const bool isActive = active();
266 if (isReady && isActive)
267 setActive(false); // Stop current session
268
269 d_ptr->m_params->m_route = route;
270 d_ptr->m_params->m_geoRoute = route ? route->route() : QGeoRoute();
271 if (route) {
272 connect(route, &QObject::destroyed,
273 [this]() {
274 // Do not stop navigation if route disappears. d_ptr->m_geoRoute will still be valid.
275 // Engines can stop navigation if desired.
276 this->routeChanged();
277 });
278 }
279 emit routeChanged();
280 updateReadyState();
281 }
282
route() const283 QDeclarativeGeoRoute *QDeclarativeNavigator::route() const
284 {
285 return d_ptr->m_params->m_route;
286 }
287
setPositionSource(QDeclarativePositionSource * positionSource)288 void QDeclarativeNavigator::setPositionSource(QDeclarativePositionSource *positionSource)
289 {
290 if (d_ptr->m_params->m_positionSource || !positionSource) // set once prop
291 return;
292
293 d_ptr->m_params->m_positionSource = positionSource;
294 QObject::connect(positionSource, &QObject::destroyed,
295 [this]() {
296 this->positionSourceChanged();
297 this->updateReadyState();
298 }
299 );
300 emit positionSourceChanged();
301 updateReadyState();
302 }
303
positionSource() const304 QDeclarativePositionSource *QDeclarativeNavigator::positionSource() const
305 {
306 return d_ptr->m_params->m_positionSource;
307 }
308
309 // navigator automatically adjusts route when user leaves it
automaticReroutingEnabled() const310 bool QDeclarativeNavigator::automaticReroutingEnabled() const
311 {
312 if (d_ptr->m_navigator)
313 return d_ptr->m_navigator->automaticReroutingEnabled();
314 return d_ptr->m_params->m_autoRerouting;
315 }
316
317 // Whether or not it has an effect while the navigator is active should be plugin-dependent
setAutomaticReroutingEnabled(bool autoRerouting)318 void QDeclarativeNavigator::setAutomaticReroutingEnabled(bool autoRerouting)
319 {
320 const bool autoReroutingOld = automaticReroutingEnabled();
321 d_ptr->m_params->m_autoRerouting = autoRerouting;
322 // Done this way, and not via signal like setTrackPositionSource because
323 // plugins might not support automatic rerouting.
324 if (d_ptr->m_navigator)
325 d_ptr->m_navigator->setAutomaticReroutingEnabled(autoRerouting);
326 if (autoRerouting != autoReroutingOld)
327 emit automaticReroutingEnabledChanged();
328 }
329
330
navigatorReady() const331 bool QDeclarativeNavigator::navigatorReady() const
332 {
333 if (d_ptr->m_navigator)
334 return d_ptr->m_navigator->ready();
335 return d_ptr->m_ready;
336 }
337
trackPositionSource() const338 bool QDeclarativeNavigator::trackPositionSource() const
339 {
340 return d_ptr->m_params->m_trackPositionSource;
341 }
342
343 // Navigator is in active tracking mode and the route is being followed.
344 // This may turn \c false if the user leaves the route.
isOnRoute() const345 bool QDeclarativeNavigator::isOnRoute() const
346 {
347 if (d_ptr->m_navigator)
348 return d_ptr->m_navigator->isOnRoute();
349 return false;
350 }
351
setTrackPositionSource(bool trackPositionSource)352 void QDeclarativeNavigator::setTrackPositionSource(bool trackPositionSource)
353 {
354 if (trackPositionSource == d_ptr->m_params->m_trackPositionSource)
355 return;
356
357 d_ptr->m_params->m_trackPositionSource = trackPositionSource;
358
359 emit trackPositionSourceChanged(trackPositionSource);
360 }
361
directions() const362 QDeclarativeNavigationBasicDirections *QDeclarativeNavigator::directions() const
363 {
364 return &d_ptr->m_basicDirections;
365 }
366
error() const367 QDeclarativeNavigator::NavigationError QDeclarativeNavigator::error() const
368 {
369 return d_ptr->m_error;
370 }
371
errorString() const372 QString QDeclarativeNavigator::errorString() const
373 {
374 return d_ptr->m_errorString;
375 }
376
recalculateRoutes()377 void QDeclarativeNavigator::recalculateRoutes()
378 {
379 if (d_ptr->m_navigator)
380 d_ptr->m_navigator->recalculateRoutes();
381 }
382
383 /* !NOT DOCUMENTED YET!
384 \qmlproperty QAbstractNavigator *Qt.labs.location::Navigator::engineHandle
385
386 This property returns a handle to the navigation object created by the engine.
387 This object can carry engine-specific properties, signals and methods, to expose
388 engine-specific features and data.
389
390 \warning Using this property leads to writing code that's likely to work
391 with only a single plugin.
392 */
abstractNavigator() const393 QAbstractNavigator *QDeclarativeNavigator::abstractNavigator() const
394 {
395 return d_ptr->m_navigator.data();
396
397 }
398
active() const399 bool QDeclarativeNavigator::active() const
400 {
401 return d_ptr->m_active;
402 }
403
setPlugin(QDeclarativeGeoServiceProvider * plugin)404 void QDeclarativeNavigator::setPlugin(QDeclarativeGeoServiceProvider *plugin)
405 {
406 if (d_ptr->m_plugin)
407 return; // set once property.
408
409 d_ptr->m_plugin = plugin;
410 emit pluginChanged();
411
412 if (d_ptr->m_plugin->isAttached()) {
413 pluginReady();
414 } else {
415 connect(d_ptr->m_plugin, &QDeclarativeGeoServiceProvider::attached,
416 this, &QDeclarativeNavigator::pluginReady);
417 }
418 }
419
setActive(bool active)420 void QDeclarativeNavigator::setActive(bool active)
421 {
422 if (d_ptr->m_active == active)
423 return;
424
425 d_ptr->m_active = active;
426 if (!d_ptr->m_plugin)
427 return;
428
429 if (active)
430 start();
431 else
432 stop();
433 }
434
start()435 void QDeclarativeNavigator::start()
436 {
437 if (!d_ptr->m_ready) {
438 qmlWarning(this) << QStringLiteral("Navigation manager not ready.");
439 return;
440 }
441
442 if (!d_ptr->m_navigator->active())
443 d_ptr->m_active = d_ptr->m_navigator->start();
444 }
445
stop()446 void QDeclarativeNavigator::stop()
447 {
448 if (!ensureEngine()) { // If somebody re-set route to null or something, this may become !d_ptr->m_ready
449 qmlWarning(this) << QStringLiteral("Navigation manager not ready.");
450 return;
451 }
452
453 if (d_ptr->m_navigator->active())
454 d_ptr->m_active = d_ptr->m_navigator->stop();
455
456 // Cached data are cleared in response to signals emitted by m_navigator upon stop().
457 // For example, m_navigator emits currentRouteChanged with an empty route,
458 // and QDeclarativeNavigationBasicDirections reacts by clearing the declarative route.
459 }
460
pluginReady()461 void QDeclarativeNavigator::pluginReady()
462 {
463 if (!d_ptr->m_completed)
464 return;
465
466 ensureEngine();
467 updateReadyState();
468 if (d_ptr->m_active)
469 start();
470 }
471
ensureEngine()472 bool QDeclarativeNavigator::ensureEngine()
473 {
474 if (d_ptr->m_navigator)
475 return true;
476 if (!d_ptr->m_completed || !d_ptr->m_plugin->isAttached())
477 return false;
478
479 QGeoServiceProvider *serviceProvider = d_ptr->m_plugin->sharedGeoServiceProvider();
480 // if m_plugin->isAttached(), serviceProvider cannot be null
481 QNavigationManager *manager = serviceProvider->navigationManager();
482
483 if (serviceProvider->navigationError() != QGeoServiceProvider::NoError) {
484 QDeclarativeNavigator::NavigationError newError = UnknownError;
485 switch (serviceProvider->navigationError()) {
486 case QGeoServiceProvider::NotSupportedError:
487 newError = NotSupportedError; break;
488 case QGeoServiceProvider::UnknownParameterError:
489 newError = UnknownParameterError; break;
490 case QGeoServiceProvider::MissingRequiredParameterError:
491 newError = MissingRequiredParameterError; break;
492 case QGeoServiceProvider::ConnectionError:
493 newError = ConnectionError; break;
494 case QGeoServiceProvider::LoaderError:
495 newError = LoaderError; break;
496 default:
497 break;
498 }
499
500 setError(newError, serviceProvider->navigationErrorString());
501 return false;
502 }
503
504 if (!manager) {
505 setError(NotSupportedError, tr("Plugin does not support navigation."));
506 return false;
507 }
508
509 d_ptr->m_navigator.reset(manager->createNavigator(d_ptr->m_params));
510 if (!d_ptr->m_navigator) {
511 setError(UnknownError, tr("Failed to create a navigator object."));
512 return false;
513 }
514
515 d_ptr->m_navigator->setLocale(manager->locale());
516 d_ptr->m_navigator->setMeasurementSystem(manager->measurementSystem());
517
518 connect(d_ptr->m_navigator.get(), &QAbstractNavigator::activeChanged, this, [this](bool active){
519 d_ptr->m_active = active;
520 emit activeChanged(active);
521 });
522 connect(this, &QDeclarativeNavigator::trackPositionSourceChanged, d_ptr->m_navigator.get(), &QAbstractNavigator::setTrackPosition);
523
524 // read-only progress info updates
525 connect(d_ptr->m_navigator.get(), &QAbstractNavigator::waypointReached,
526 &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::waypointReached);
527 connect(d_ptr->m_navigator.get(), &QAbstractNavigator::destinationReached,
528 &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::destinationReached);
529 connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentRouteChanged,
530 &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::onCurrentRouteChanged);
531 connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentRouteLegChanged,
532 &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::onCurrentRouteLegChanged);
533 connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentSegmentChanged,
534 &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::currentSegmentChanged);
535 connect(d_ptr->m_navigator.get(), &QAbstractNavigator::nextManeuverIconChanged,
536 &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::nextManeuverIconChanged);
537 connect(d_ptr->m_navigator.get(), &QAbstractNavigator::progressInformationChanged,
538 &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::progressInformationChanged);
539 connect(d_ptr->m_navigator.get(), &QAbstractNavigator::isOnRouteChanged,
540 this, &QDeclarativeNavigator::isOnRouteChanged);
541 connect(d_ptr->m_navigator.get(), &QAbstractNavigator::alternativeRoutesChanged,
542 &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::onAlternativeRoutesChanged);
543
544 emit navigatorReadyChanged(true);
545 return true;
546 }
547
updateReadyState()548 void QDeclarativeNavigator::updateReadyState() {
549 const bool oldReady = d_ptr->m_ready;
550 if (!d_ptr->m_navigator)
551 d_ptr->m_ready = false;
552 else
553 d_ptr->m_ready = d_ptr->m_navigator->ready();
554
555 if (oldReady != d_ptr->m_ready)
556 emit navigatorReadyChanged(d_ptr->m_ready);
557 }
558
setError(QDeclarativeNavigator::NavigationError error,const QString & errorString)559 void QDeclarativeNavigator::setError(QDeclarativeNavigator::NavigationError error, const QString &errorString)
560 {
561 d_ptr->m_error = error;
562 d_ptr->m_errorString = errorString;
563 emit errorChanged();
564 }
565
QDeclarativeNavigationBasicDirections(QDeclarativeNavigator * parent)566 QDeclarativeNavigationBasicDirections::QDeclarativeNavigationBasicDirections(QDeclarativeNavigator *parent)
567 : QObject(parent), m_navigator(parent), m_routes(QByteArrayLiteral("routeData"), this)
568 {
569 if (m_navigator)
570 m_navigatorPrivate = m_navigator->d_ptr.data();
571 }
572
573 /*!
574 \qmlpropertygroup Qt.labs.location::Navigator::directions
575 \readonly
576 \qmlproperty Variant Qt.labs.location::Navigator::directions.nextManeuverIcon
577 \qmlproperty real Qt.labs.location::Navigator::directions.distanceToNextManeuver
578 \qmlproperty real Qt.labs.location::Navigator::directions.remainingTravelDistance
579 \qmlproperty real Qt.labs.location::Navigator::directions.remainingTravelDistanceToNextWaypoint
580 \qmlproperty real Qt.labs.location::Navigator::directions.traveledDistance
581 \qmlproperty int Qt.labs.location::Navigator::directions.timeToNextManeuver
582 \qmlproperty int Qt.labs.location::Navigator::directions.remainingTravelTime
583 \qmlproperty int Qt.labs.location::Navigator::directions.remainingTravelTimeToNextWaypoint
584 \qmlproperty int Qt.labs.location::Navigator::directions.traveledTime
585 \qmlproperty Route Qt.labs.location::Navigator::directions.currentRoute
586 \qmlproperty RouteLeg Qt.labs.location::Navigator::directions.currentRouteLeg
587 \qmlproperty int Qt.labs.location::Navigator::directions.currentSegment
588 \qmlproperty model Qt.labs.location::Navigator::directions.alternativeRoutes
589
590 These read-only properties are part of the \e directions property group.
591 This property group holds the navigation progress information that can be
592 used to access the route data and to extract directions.
593
594 \note Some backends might not provide a full set of navigation progress
595 information.
596
597 \list
598 \li The \c nextManeuverIcon property holds the next turn icon.
599 \li The \c distanceToNextManeuver property holds the distance to the
600 next maneuver, in meters.
601 \li The \c remainingTravelDistance property holds the remaining travel
602 distance, in meters.
603 \li The \c remainingTravelDistanceToNextWaypoint property holds the
604 remaining travel distance to the next waypoint, in meters.
605 \li The \c traveledDistance property holds the traveled distance, in
606 meters.
607 \li The \c timeToNextManeuver property holds the time to the next
608 maneuver, in milliseconds.
609 \li The \c remainingTravelTime property holds the remaining travel
610 time, in milliseconds.
611 \li The \c remainingTravelTimeToNextWaypoint property holds the
612 remaining travel time to the next waypoint, in milliseconds.
613 \li The \c traveledTime property holds the traveled time, in
614 milliseconds.
615 \li The \c currentRoute property holds the current route the navigator
616 is following. This can be the same as \l route, or can be
617 different, if the navigator cannot follow the user-specified route.
618 For example, if the position coming from \l positionSource is
619 considerably off route, the navigation engine may recalculate and
620 start to follow a new route.
621 \li The \c currentRouteLeg property holds the current route leg the
622 navigator is following. This is always a part of \c currentRoute,
623 so the \l {RouteLeg::}{overallRoute} property of \c currentRouteLeg
624 holds the same route as \c currentRoute.
625 \li The \c currentSegment property holds the index of the current
626 RouteSegment in the \c currentRoute.
627 \li The \c alternativeRoutes property holds the list of alternative routes provided by
628 the engine. If no alternative routes are present, the model will be empty.
629 \endlist
630
631 \sa directions.waypointReached(), directions.destinationReached(), Route, RouteLeg, RouteSegment, Waypoint
632 */
633
634 /*!
635 \qmlsignal Qt.labs.location::Navigator::directions.waypointReached(Waypoint waypoint)
636
637 This signal is emitted when a \a waypoint has been reached.
638
639 \sa directions, directions.destinationReached()
640 */
641
642 /*!
643 \qmlsignal Qt.labs.location::Navigator::directions.destinationReached()
644
645 This signal is emitted when the last waypoint of the route, the
646 destination, has been reached.
647
648 \sa directions, directions.waypointReached()
649 */
nextManeuverIcon() const650 QVariant QDeclarativeNavigationBasicDirections::nextManeuverIcon() const
651 {
652 if (m_navigatorPrivate->m_navigator)
653 return m_navigatorPrivate->m_navigator->nextManeuverIcon();
654 return QVariant();
655 }
656
distanceToNextManeuver() const657 qreal QDeclarativeNavigationBasicDirections::distanceToNextManeuver() const
658 {
659 if (m_navigatorPrivate->m_navigator)
660 return m_navigatorPrivate->m_navigator->distanceToNextManeuver();
661 return qQNaN();
662 }
663
remainingTravelDistance() const664 qreal QDeclarativeNavigationBasicDirections::remainingTravelDistance() const
665 {
666 if (m_navigatorPrivate->m_navigator)
667 return m_navigatorPrivate->m_navigator->remainingTravelDistance();
668 return qQNaN();
669 }
670
remainingTravelDistanceToNextWaypoint() const671 qreal QDeclarativeNavigationBasicDirections::remainingTravelDistanceToNextWaypoint() const
672 {
673 if (m_navigatorPrivate->m_navigator)
674 return m_navigatorPrivate->m_navigator->remainingTravelDistanceToNextWaypoint();
675 return qQNaN();
676 }
677
traveledDistance() const678 qreal QDeclarativeNavigationBasicDirections::traveledDistance() const
679 {
680 if (m_navigatorPrivate->m_navigator)
681 return m_navigatorPrivate->m_navigator->traveledDistance();
682 return 0;
683 }
684
timeToNextManeuver() const685 int QDeclarativeNavigationBasicDirections::timeToNextManeuver() const
686 {
687 if (m_navigatorPrivate->m_navigator)
688 return m_navigatorPrivate->m_navigator->timeToNextManeuver();
689 return -1;
690 }
691
remainingTravelTime() const692 int QDeclarativeNavigationBasicDirections::remainingTravelTime() const
693 {
694 if (m_navigatorPrivate->m_navigator)
695 return m_navigatorPrivate->m_navigator->remainingTravelTime();
696 return -1;
697 }
698
remainingTravelTimeToNextWaypoint() const699 int QDeclarativeNavigationBasicDirections::remainingTravelTimeToNextWaypoint() const
700 {
701 if (m_navigatorPrivate->m_navigator)
702 return m_navigatorPrivate->m_navigator->remainingTravelTimeToNextWaypoint();
703 return -1;
704 }
705
traveledTime() const706 int QDeclarativeNavigationBasicDirections::traveledTime() const
707 {
708 if (m_navigatorPrivate->m_navigator)
709 return m_navigatorPrivate->m_navigator->traveledTime();
710 return 0;
711 }
712
currentRoute() const713 QDeclarativeGeoRoute *QDeclarativeNavigationBasicDirections::currentRoute() const
714 {
715 if (!m_navigatorPrivate->m_ready
716 || !m_navigatorPrivate->m_navigator
717 || !m_navigatorPrivate->m_navigator->active())
718 return m_navigatorPrivate->m_params->m_route.data(); // the user-specified route, if any
719 return m_currentRoute;
720 }
721
currentRouteLeg() const722 QDeclarativeGeoRouteLeg *QDeclarativeNavigationBasicDirections::currentRouteLeg() const
723 {
724 if (!m_navigatorPrivate->m_ready
725 || !m_navigatorPrivate->m_navigator
726 || !m_navigatorPrivate->m_navigator->active())
727 return nullptr;
728 return m_currentRouteLeg;
729 }
730
currentSegment() const731 int QDeclarativeNavigationBasicDirections::currentSegment() const
732 {
733 if (!m_navigatorPrivate->m_ready
734 || !m_navigatorPrivate->m_navigator
735 || !m_navigatorPrivate->m_navigator->active())
736 return 0;
737 return m_navigatorPrivate->m_navigator->currentSegment();
738 }
739
alternativeRoutes()740 QAbstractItemModel *QDeclarativeNavigationBasicDirections::alternativeRoutes()
741 {
742 return &m_routes;
743 }
744
onCurrentRouteChanged()745 void QDeclarativeNavigationBasicDirections::onCurrentRouteChanged()
746 {
747 if (m_currentRoute)
748 m_currentRoute->deleteLater();
749 m_currentRoute = new QDeclarativeGeoRoute(m_navigatorPrivate->m_navigator->currentRoute(), this);
750 emit currentRouteChanged();
751 }
752
onCurrentRouteLegChanged()753 void QDeclarativeNavigationBasicDirections::onCurrentRouteLegChanged()
754 {
755 if (m_currentRouteLeg)
756 m_currentRouteLeg->deleteLater();
757 m_currentRouteLeg = new QDeclarativeGeoRouteLeg(m_navigatorPrivate->m_navigator->currentRouteLeg(), this);
758 emit currentRouteLegChanged();
759 }
760
onAlternativeRoutesChanged()761 void QDeclarativeNavigationBasicDirections::onAlternativeRoutesChanged()
762 {
763 const QList<QGeoRoute> &routes = m_navigatorPrivate->m_navigator->alternativeRoutes();
764 QList<QDeclarativeGeoRoute *> declarativeRoutes;
765 for (int i = 0; i < routes.size(); ++i) {
766 QDeclarativeGeoRoute *route = new QDeclarativeGeoRoute(routes.at(i), &m_routes);
767 QQmlEngine::setContextForObject(route, QQmlEngine::contextForObject(this));
768 declarativeRoutes.append(route);
769 }
770 m_routes.updateData(declarativeRoutes);
771 }
772
773 QT_END_NAMESPACE
774
775