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 #include "qgeoroutingmanager.h"
38 #include "qgeoroutingmanager_p.h"
39 #include "qgeoroutingmanagerengine.h"
40 
41 #include <QLocale>
42 
43 QT_BEGIN_NAMESPACE
44 
45 /*!
46     \class QGeoRoutingManager
47     \inmodule QtLocation
48     \ingroup QtLocation-routing
49     \since 5.6
50 
51     \brief The QGeoRoutingManager class provides support for geographic routing
52     operations.
53 
54     The calculateRoute() and updateRoute() methods function QGeoRouteReply
55     objects, which manage these operations and report on the result of the
56     operations and any errors which may have occurred.
57 
58     The calculateRoute() function is used to find a route (or routes) that
59     follows a set of waypoints and matches various other criteria.  The
60     QGeoRouteRequest class is used to specify this information.
61 
62     If supportsRouteUpdates() returns true then the QGeoRoutingManager
63     supports updating route information based on position updates.  This
64     will cause the travel time and distance estimates to be updated, and
65     any QGeoRouteSegments already traversed to be removed from the route.
66 
67     The updates can be triggered with the updateRoute() function, which makes
68     use of the QGeoPositionInfo instances emitted as position updates by
69     QGeoPositionInfoSource.
70 
71     Instances of QGeoRoutingManager can be accessed with
72     QGeoServiceProvider::routingManager().
73 
74     A small example of the usage of QGeoRoutingManager and QGeoRouteRequests
75     follows:
76 
77     \code
78 class MyRouteHandler : public QObject
79 {
80     Q_OBJECT
81 public:
82     MyRouteHandler(QGeoRoutingManager *routingManager,
83                    const QGeoCoordinate &origin,
84                    const QGeoCoordinate &destination) {
85 
86         QGeoRouteRequest request(origin, destination);
87 
88         // The request defaults to the fastest route by car, which is
89         // equivalent to:
90         // request.setTravelMode(QGeoRouteRequest::CarTravel);
91         // request.setRouteOptimization(QGeoRouteRequest::FastestRoute);
92 
93         request.setAvoidFeatureTypes(QGeoRouteRequest::AvoidTolls);
94         request.setAvoidFeatureTypes(QGeoRouteRequest::AvoidMotorPoolLanes);
95 
96         QGeoRouteRequest::AvoidFeaturesTypes avoidableFeatures = routingManager->supportedAvoidFeatureTypes();
97 
98         if (!(avoidableFeatures & request.avoidFeatureTypes())) {
99             // ... inform the user that the routing manager does not
100             // provide support for avoiding tolls and/or motor pool lanes ...
101             return;
102         }
103 
104         QGeoRouteReply *reply = routingManager->calculateRoute(request);
105 
106         if (reply->isFinished()) {
107             if (reply->error() == QGeoRouteReply::NoError) {
108                 routeCalculated(reply);
109             } else {
110                 routeError(reply, reply->error(), reply->errorString());
111             }
112             return;
113         }
114 
115         connect(routingManager,
116                 SIGNAL(finished(QGeoRouteReply*)),
117                 this,
118                 SLOT(routeCalculated(QGeoRouteReply*)));
119 
120         connect(routingManager,
121                 SIGNAL(error(QGeoRouteReply*,QGeoRouteReply::Error,QString)),
122                 this,
123                 SLOT(routeError(QGeoRouteReply*,QGeoRouteReply::Error,QString)));
124     }
125 
126 private slots:
127     void routeCalculated(QGeoRouteReply *reply)
128     {
129         // A route request can ask for several alternative routes ...
130         if (reply->routes().size() != 0) {
131 
132             // ... but by default it will only get a single route
133             QGeoRoute route = reply->routes().at(0);
134 
135             //... now we have to make use of the route ...
136         }
137 
138         reply->deleteLater();
139     }
140 
141     void routeError(QGeoRouteReply *reply, QGeoRouteReply:Error error, const QString &errorString)
142     {
143         // ... inform the user that an error has occurred ...
144         reply->deleteLater();
145     }
146 };
147     \endcode
148 */
149 
150 /*!
151     Constructs a new manager with the specified \a parent and with the
152     implementation provided by \a engine.
153 
154     This constructor is used internally by QGeoServiceProviderFactory. Regular
155     users should acquire instances of QGeoRoutingManager with
156     QGeoServiceProvider::routingManager();
157 */
QGeoRoutingManager(QGeoRoutingManagerEngine * engine,QObject * parent)158 QGeoRoutingManager::QGeoRoutingManager(QGeoRoutingManagerEngine *engine, QObject *parent)
159     : QObject(parent),
160       d_ptr(new QGeoRoutingManagerPrivate())
161 {
162     d_ptr->engine = engine;
163     if (d_ptr->engine) {
164         d_ptr->engine->setParent(this);
165 
166         connect(d_ptr->engine,
167                 SIGNAL(finished(QGeoRouteReply*)),
168                 this,
169                 SIGNAL(finished(QGeoRouteReply*)));
170 
171         connect(d_ptr->engine,
172                 SIGNAL(error(QGeoRouteReply*,QGeoRouteReply::Error,QString)),
173                 this,
174                 SIGNAL(error(QGeoRouteReply*,QGeoRouteReply::Error,QString)));
175     } else {
176         qFatal("The routing manager engine that was set for this routing manager was NULL.");
177     }
178 }
179 
180 /*!
181     Destroys this manager.
182 */
~QGeoRoutingManager()183 QGeoRoutingManager::~QGeoRoutingManager()
184 {
185     delete d_ptr;
186 }
187 
188 /*!
189     Returns the name of the engine which implements the behaviour of this
190     routing manager.
191 
192     The combination of managerName() and managerVersion() should be unique
193     amongst the plugin implementations.
194 */
managerName() const195 QString QGeoRoutingManager::managerName() const
196 {
197     return d_ptr->engine->managerName();
198 }
199 
200 /*!
201     Returns the version of the engine which implements the behaviour of this
202     routin manager.
203 
204     The combination of managerName() and managerVersion() should be unique
205     amongst the plugin implementations.
206 */
managerVersion() const207 int QGeoRoutingManager::managerVersion() const
208 {
209     return d_ptr->engine->managerVersion();
210 }
211 
212 /*!
213     Begins the calculation of the route specified by \a request.
214 
215     A QGeoRouteReply object will be returned, which can be used to manage the
216     routing operation and to return the results of the operation.
217 
218     This manager and the returned QGeoRouteReply object will emit signals
219     indicating if the operation completes or if errors occur.
220 
221     Once the operation has completed, QGeoRouteReply::routes can be used to
222     retrieve the calculated route or routes.
223 
224     If \a request includes features which are not supported by this manager, as
225     reported by the methods in this manager, then a
226     QGeoRouteReply::UnsupportedOptionError will occur.
227 
228     The user is responsible for deleting the returned reply object, although
229     this can be done in the slot connected to QGeoRoutingManager::finished(),
230     QGeoRoutingManager::error(), QGeoRouteReply::finished() or
231     QGeoRouteReply::error() with deleteLater().
232 */
calculateRoute(const QGeoRouteRequest & request)233 QGeoRouteReply *QGeoRoutingManager::calculateRoute(const QGeoRouteRequest &request)
234 {
235     return d_ptr->engine->calculateRoute(request);
236 }
237 
238 /*!
239     Begins the process of updating \a route based on the current position \a
240     position.
241 
242     A QGeoRouteReply object will be returned, which can be used to manage the
243     routing operation and to return the results of the operation.
244 
245     This manager and the returned QGeoRouteReply object will emit signals
246     indicating if the operation completes or if errors occur.
247 
248     If supportsRouteUpdates() returns false an
249     QGeoRouteReply::UnsupportedOptionError will occur.
250 
251     Once the operation has completed, QGeoRouteReply::routes can be used to
252     retrieve the updated route.
253 
254     The returned route could be entirely different to the original route,
255     especially if \a position is far away from the initial route.
256     Otherwise the route will be similar, although the remaining time and
257     distance will be updated and any segments of the original route which
258     have been traversed will be removed.
259 
260     The user is responsible for deleting the returned reply object, although
261     this can be done in the slot connected to QGeoRoutingManager::finished(),
262     QGeoRoutingManager::error(), QGeoRouteReply::finished() or
263     QGeoRouteReply::error() with deleteLater().
264 */
updateRoute(const QGeoRoute & route,const QGeoCoordinate & position)265 QGeoRouteReply *QGeoRoutingManager::updateRoute(const QGeoRoute &route, const QGeoCoordinate &position)
266 {
267     return d_ptr->engine->updateRoute(route, position);
268 }
269 
270 /*!
271     Returns the travel modes supported by this manager.
272 */
supportedTravelModes() const273 QGeoRouteRequest::TravelModes QGeoRoutingManager::supportedTravelModes() const
274 {
275     return d_ptr->engine->supportedTravelModes();
276 }
277 
278 /*!
279     Returns the types of features that this manager can take into account
280     during route planning.
281 */
supportedFeatureTypes() const282 QGeoRouteRequest::FeatureTypes QGeoRoutingManager::supportedFeatureTypes() const
283 {
284     return d_ptr->engine->supportedFeatureTypes();
285 }
286 
287 /*!
288     Returns the weightings which this manager can apply to different features
289     during route planning.
290 */
supportedFeatureWeights() const291 QGeoRouteRequest::FeatureWeights QGeoRoutingManager::supportedFeatureWeights() const
292 {
293     return d_ptr->engine->supportedFeatureWeights();
294 }
295 
296 /*!
297     Returns the route optimizations supported by this manager.
298 */
supportedRouteOptimizations() const299 QGeoRouteRequest::RouteOptimizations QGeoRoutingManager::supportedRouteOptimizations() const
300 {
301     return d_ptr->engine->supportedRouteOptimizations();
302 }
303 
304 /*!
305     Returns the levels of detail for routing segments which can be requested
306     with this manager.
307 */
supportedSegmentDetails() const308 QGeoRouteRequest::SegmentDetails QGeoRoutingManager::supportedSegmentDetails() const
309 {
310     return d_ptr->engine->supportedSegmentDetails();
311 }
312 
313 /*!
314     Returns the levels of detail for navigation maneuvers which can be
315     requested by this manager.
316 */
supportedManeuverDetails() const317 QGeoRouteRequest::ManeuverDetails QGeoRoutingManager::supportedManeuverDetails() const
318 {
319     return d_ptr->engine->supportedManeuverDetails();
320 }
321 
322 /*!
323     Sets the locale to be used by this manager to \a locale.
324 
325     If this routing manager supports returning addresses and instructions
326     in different languages, they will be returned in the language of \a locale.
327 
328     The locale used defaults to the system locale if this is not set.
329 */
setLocale(const QLocale & locale)330 void QGeoRoutingManager::setLocale(const QLocale &locale)
331 {
332     d_ptr->engine->setLocale(locale);
333 }
334 
335 /*!
336     Returns the locale used to hint to this routing manager about what
337     language to use for addresses and instructions.
338 */
locale() const339 QLocale QGeoRoutingManager::locale() const
340 {
341     return d_ptr->engine->locale();
342 }
343 
344 /*!
345     Sets the measurement system used by this manager to \a system.
346 
347     The measurement system can be set independently of the locale. Both setLocale() and this
348     function set the measurement system. The value set by the last function called will be used.
349 
350     \sa measurementSystem(), locale(), setLocale()
351 */
setMeasurementSystem(QLocale::MeasurementSystem system)352 void QGeoRoutingManager::setMeasurementSystem(QLocale::MeasurementSystem system)
353 {
354     d_ptr->engine->setMeasurementSystem(system);
355 }
356 
357 /*!
358     Returns the measurement system used by this manager.
359 
360     If setMeasurementSystem() has been called then the value returned by this function may be
361     different to that returned by locale().\l {QLocale::measurementSystem()}{measurementSystem()}.
362     In which case the value returned by this function is what will be used by the manager.
363 
364     \sa setMeasurementSystem(), setLocale()
365 */
measurementSystem() const366 QLocale::MeasurementSystem QGeoRoutingManager::measurementSystem() const
367 {
368     return d_ptr->engine->measurementSystem();
369 }
370 
371 /*!
372 \fn void QGeoRoutingManager::finished(QGeoRouteReply *reply)
373 
374 This signal is emitted when \a reply has finished processing.
375 
376 If reply::error() equals QGeoRouteReply::NoError then the processing
377 finished successfully.
378 
379 This signal and QGeoRouteReply::finished() will be emitted at the same time.
380 
381 \note Do not delete the \a reply object in the slot connected to this signal.
382 Use deleteLater() instead.
383 */
384 
385 /*!
386 \fn void QGeoRoutingManager::error(QGeoRouteReply *reply, QGeoRouteReply::Error error, QString errorString)
387 
388 This signal is emitted when an error has been detected in the processing of
389 \a reply.  The QGeoRoutingManager::finished() signal will probably follow.
390 
391 The error will be described by the error code \a error.  If \a errorString is
392 not empty it will contain a textual description of the error.
393 
394 This signal and QGeoRouteReply::error() will be emitted at the same time.
395 
396 \note Do not delete the \a reply object in the slot connected to this signal.
397 Use deleteLater() instead.
398 */
399 
400 /*******************************************************************************
401 *******************************************************************************/
402 
QGeoRoutingManagerPrivate()403 QGeoRoutingManagerPrivate::QGeoRoutingManagerPrivate()
404     : engine(0) {}
405 
~QGeoRoutingManagerPrivate()406 QGeoRoutingManagerPrivate::~QGeoRoutingManagerPrivate()
407 {
408     delete engine;
409 }
410 
411 QT_END_NAMESPACE
412