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 | */ |
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(sender: d_ptr->engine, |
167 | SIGNAL(finished(QGeoRouteReply*)), |
168 | receiver: this, |
169 | SIGNAL(finished(QGeoRouteReply*))); |
170 | |
171 | connect(sender: d_ptr->engine, |
172 | SIGNAL(error(QGeoRouteReply*,QGeoRouteReply::Error,QString)), |
173 | receiver: this, |
174 | SIGNAL(error(QGeoRouteReply*,QGeoRouteReply::Error,QString))); |
175 | } else { |
176 | qFatal(msg: "The routing manager engine that was set for this routing manager was NULL." ); |
177 | } |
178 | } |
179 | |
180 | /*! |
181 | Destroys this manager. |
182 | */ |
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 | */ |
195 | 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 | */ |
207 | 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 | */ |
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 | */ |
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 | */ |
273 | 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 | */ |
282 | 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 | */ |
291 | 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 | */ |
299 | 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 | */ |
308 | 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 | */ |
317 | 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 | */ |
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 | */ |
339 | 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 | */ |
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 | */ |
366 | 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 | |
403 | QGeoRoutingManagerPrivate::QGeoRoutingManagerPrivate() |
404 | : engine(0) {} |
405 | |
406 | QGeoRoutingManagerPrivate::~QGeoRoutingManagerPrivate() |
407 | { |
408 | delete engine; |
409 | } |
410 | |
411 | QT_END_NAMESPACE |
412 | |