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 "qgeorouterequest.h"
38 #include "qgeorouterequest_p.h"
39 
40 QT_BEGIN_NAMESPACE
41 
42 /*!
43     \class QGeoRouteRequest
44     \inmodule QtLocation
45     \ingroup QtLocation-routing
46     \since 5.6
47 
48     \brief The QGeoRouteRequest class represents the parameters and restrictions
49     which define a request for routing information.
50 
51     The default state of a QGeoRouteRequest instance will result in a request
52     for basic route segment and navigation maneuvers describing the fastest
53     route by car which covers the given waypoints.
54 
55     There may be significant variation in the features supported by different
56     providers of routing information, or even in the features supported by
57     the same provider if different levels of authorization are used.
58 
59     There are several functions in QGeoRoutingManager which can be used to
60     check which features are supported with the current provider and
61     authorization level.
62     \sa QGeoRoutingManager
63 */
64 
65 /*
66     DESIGN NOTE
67 
68     There are plans to make this extensible by allowing the user to set a
69     list of QGeoTransportOptions (or QGeoTransitOptions).  We don't have any
70     subclasses for that just yet, otherwise they'd be present.
71 
72     A QGeoPublicTransportOption subclass would allow users to specify things
73     like cost limits, the maximum number of changes of vehicle, the maximum
74     walking time / distance between changes of vehicle.
75 
76     There's Nokia / Navteq support for specifying things like Truck attributes
77     so you can route around various road restrictions and conditions which
78     effect trucks.
79 
80     A QGeoTrafficAwareTransportOption is probably also a good place to put the
81     inputs for the various traffic / time aware bits of information. A
82     departure / arrrival time could be set, and the presence of this transport
83     options subclass (and the fact that user auth said that the user had
84     support) would mean we could provide better values for the estimated
85     travel times and so on.
86 
87     This all relies on at least one service making this data available to us,
88     which would probably be tied to token based authorization.  It could be
89     some time before this becomes available.
90 */
91 
92 /*!
93     \enum QGeoRouteRequest::TravelMode
94 
95     Defines modes of travel to be used for a route.
96 
97     \value CarTravel
98         The route will be optimized for someone who is driving a car.
99     \value PedestrianTravel
100         The route will be optimized for someone who is walking.
101     \value BicycleTravel
102         The route will be optimized for someone who is riding a bicycle.
103     \value PublicTransitTravel
104         The route will be optimized for someone who is making use of public transit.
105     \value TruckTravel
106         The route will be optimized for someone who is driving a truck.
107 */
108 
109 /*!
110     \enum QGeoRouteRequest::FeatureType
111 
112     Defines a feature which is important to the planning of a route.
113 
114     These values will be used in combination with
115     QGeoRouteRequest::FeatureWeight to determine if they should or should
116     not be part of the route.
117 
118     \value NoFeature
119         Used by QGeoRoutingManager::supportedFeatureTypes() to indicate that
120         no features will be taken into account when planning the route.
121     \value TollFeature
122         Consdier tollways when planning the route.
123     \value HighwayFeature
124         Consider highways when planning the route.
125     \value PublicTransitFeature
126         Consider public transit when planning the route.
127     \value FerryFeature
128         Consider ferries when planning the route.
129     \value TunnelFeature
130         Consider tunnels when planning the route.
131     \value DirtRoadFeature
132         Consider dirt roads when planning the route.
133     \value ParksFeature
134         Consider parks when planning the route.
135     \value MotorPoolLaneFeature
136         Consider motor pool lanes when planning the route.
137     \value TrafficFeature
138         Consider the current traffic situation when planning the route. Since QtLocation 5.10
139 */
140 
141 /*!
142     \enum QGeoRouteRequest::FeatureWeight
143 
144     Defines the weight to associate with a feature during  the
145     planning of a route.
146 
147     These values will be used in combination with
148     QGeoRouteRequest::Feature to determine if they should or should
149     not be part of the route.
150 
151     \value NeutralFeatureWeight
152         The presence or absence of the feature will not affect the
153         planning of the route.
154     \value PreferFeatureWeight
155         Routes which contain the feature will be preferred over those that do
156         not.
157     \value RequireFeatureWeight
158         Only routes which contain the feature will be considered, otherwise
159         no route will be returned.
160     \value AvoidFeatureWeight
161         Routes which do not contain the feature will be preferred over those
162         that do.
163     \value DisallowFeatureWeight
164         Only routes which do not contain the feature will be considered,
165         otherwise no route will be returned.
166 */
167 
168 // TODO improve description of MostScenicRoute
169 /*!
170     \enum QGeoRouteRequest::RouteOptimization
171 
172     Defines the type of optimization which is applied to the planning of the route.
173 
174     \value ShortestRoute
175         Minimize the length of the journey.
176     \value FastestRoute
177         Minimize the traveling time for the journey.
178     \value MostEconomicRoute
179         Minimize the cost of the journey.
180     \value MostScenicRoute
181         Maximize the scenic potential of the journey.
182 */
183 
184 /*!
185     \enum QGeoRouteRequest::SegmentDetail
186 
187     Defines the amount of route segment information that should be included
188     with the route.
189 
190     \value NoSegmentData
191         No segment data should be included with the route.  A route requested
192         with this level of segment detail will initialize
193         QGeoRouteSegment::path() as a straight line between the positions of
194         the previous and next QGeoManeuver instances.
195 
196     \value BasicSegmentData
197         Basic segment data will be included with the route.  This will include
198         QGeoRouteSegment::path().
199 */
200 
201 /*!
202     \enum QGeoRouteRequest::ManeuverDetail
203 
204     Defines the amount of maneuver information that should be included with
205     the route.
206 
207     \value NoManeuvers
208         No maneuvers should be included with the route.
209 
210     \value BasicManeuvers
211         Basic manevuers will be included with the route. This will
212         include QGeoManeuver::instructionText().
213 */
214 
215 /*!
216     Constructs a request to calculate a route through the coordinates \a waypoints.
217 
218     The route will traverse the objects of \a waypoints in order.
219 */
QGeoRouteRequest(const QList<QGeoCoordinate> & waypoints)220 QGeoRouteRequest::QGeoRouteRequest(const QList<QGeoCoordinate> &waypoints)
221     : d_ptr(new QGeoRouteRequestPrivate())
222 {
223     d_ptr->waypoints = waypoints;
224 }
225 
226 /*!
227     Constructs a request to calculate a route between \a origin and
228     \a destination.
229 */
QGeoRouteRequest(const QGeoCoordinate & origin,const QGeoCoordinate & destination)230 QGeoRouteRequest::QGeoRouteRequest(const QGeoCoordinate &origin, const QGeoCoordinate &destination)
231     : d_ptr(new QGeoRouteRequestPrivate())
232 {
233     d_ptr->waypoints.append(origin);
234     d_ptr->waypoints.append(destination);
235 }
236 
237 /*!
238     Constructs a route request object from the contents of \a other.
239 */
QGeoRouteRequest(const QGeoRouteRequest & other)240 QGeoRouteRequest::QGeoRouteRequest(const QGeoRouteRequest &other)
241     : d_ptr(other.d_ptr) {}
242 
243 /*!
244     Destroys the request.
245 */
~QGeoRouteRequest()246 QGeoRouteRequest::~QGeoRouteRequest() {}
247 
248 /*!
249     Assigns \a other to this route request object and then returns a reference
250     to this route request object.
251 */
operator =(const QGeoRouteRequest & other)252 QGeoRouteRequest &QGeoRouteRequest::operator= (const QGeoRouteRequest & other)
253 {
254     if (this == &other)
255         return *this;
256 
257     d_ptr = other.d_ptr;
258     return *this;
259 }
260 
261 /*!
262     Returns whether this route request and \a other are equal.
263 */
operator ==(const QGeoRouteRequest & other) const264 bool QGeoRouteRequest::operator ==(const QGeoRouteRequest &other) const
265 {
266     return ( (d_ptr.constData() == other.d_ptr.constData())
267                         || (*d_ptr) == (*other.d_ptr));
268 }
269 
270 /*!
271     Returns whether this route request and \a other are equal.
272 */
operator !=(const QGeoRouteRequest & other) const273 bool QGeoRouteRequest::operator !=(const QGeoRouteRequest &other) const
274 {
275     return !(operator==(other));
276 }
277 
278 /*!
279     Sets \a waypoints as the waypoints that the route should pass through.
280 
281     The waypoints should be given in order from origin to destination.
282 
283     This request will be invalid until the waypoints have been set to a
284     list containing two or more coordinates.
285 */
setWaypoints(const QList<QGeoCoordinate> & waypoints)286 void QGeoRouteRequest::setWaypoints(const QList<QGeoCoordinate> &waypoints)
287 {
288     d_ptr->waypoints = waypoints;
289 }
290 
291 /*!
292     Returns the waypoints that the route will pass through.
293 */
waypoints() const294 QList<QGeoCoordinate> QGeoRouteRequest::waypoints() const
295 {
296     return d_ptr->waypoints;
297 }
298 
299 /*!
300     Sets \a waypointMetadata as the metadata for the waypoints set in this request.
301     The metadata are intended as one QVariantMap per waypoint, given in the same order as
302     the waypoints.
303 
304     The content of the QVariantMap is somehow backend-specific, but properties that can be specified using
305     \l Waypoint elements in QML can be assumed to be named and to work the same way across plugins, where supported.
306 */
setWaypointsMetadata(const QList<QVariantMap> & waypointMetadata)307 void QGeoRouteRequest::setWaypointsMetadata(const QList<QVariantMap> &waypointMetadata)
308 {
309     d_ptr->waypointMetadata = waypointMetadata;
310 }
311 
312 /*!
313     Returns the metadata for the waypoints in this request.
314 */
waypointsMetadata() const315 QList<QVariantMap> QGeoRouteRequest::waypointsMetadata() const
316 {
317     return d_ptr->waypointMetadata;
318 }
319 
320 /*!
321     Sets \a areas as excluded areas that the route must not cross.
322 */
setExcludeAreas(const QList<QGeoRectangle> & areas)323 void QGeoRouteRequest::setExcludeAreas(const QList<QGeoRectangle> &areas)
324 {
325     d_ptr->excludeAreas = areas;
326 }
327 
328 /*!
329     Returns areas the route must not cross.
330 */
excludeAreas() const331 QList<QGeoRectangle> QGeoRouteRequest::excludeAreas() const
332 {
333     return d_ptr->excludeAreas;
334 }
335 
336 /*!
337     Sets the number of alternative routes to request to \a alternatives. If \a alternatives is
338     negative the number of alternative routes is set to 0.
339 
340     The default value is 0.
341 */
setNumberAlternativeRoutes(int alternatives)342 void QGeoRouteRequest::setNumberAlternativeRoutes(int alternatives)
343 {
344     d_ptr->numberAlternativeRoutes = qMax(0, alternatives);
345 }
346 
347 /*!
348     Returns the number of alternative routes which will be requested.
349 */
numberAlternativeRoutes() const350 int QGeoRouteRequest::numberAlternativeRoutes() const
351 {
352     return d_ptr->numberAlternativeRoutes;
353 }
354 
355 /*!
356     Sets the travel modes which should be considered during the planning of the
357     route to \a travelModes.
358 
359     The default value is QGeoRouteRequest::CarTravel.
360 */
setTravelModes(QGeoRouteRequest::TravelModes travelModes)361 void QGeoRouteRequest::setTravelModes(QGeoRouteRequest::TravelModes travelModes)
362 {
363     d_ptr->travelModes = travelModes;
364 }
365 
366 /*!
367     Returns the travel modes which this request specifies should be considered
368     during the planning of the route.
369 */
travelModes() const370 QGeoRouteRequest::TravelModes QGeoRouteRequest::travelModes() const
371 {
372     return d_ptr->travelModes;
373 }
374 
375 /*!
376     Assigns the weight \a featureWeight to the feature \a featureType during
377     the planning of the route.
378 
379     By default all features are assigned a weight of NeutralFeatureWeight.
380 
381     It is impossible to assign a weight to QGeoRouteRequest::NoFeature.
382 */
setFeatureWeight(QGeoRouteRequest::FeatureType featureType,QGeoRouteRequest::FeatureWeight featureWeight)383 void QGeoRouteRequest::setFeatureWeight(QGeoRouteRequest::FeatureType featureType, QGeoRouteRequest::FeatureWeight featureWeight)
384 {
385     if (featureWeight != QGeoRouteRequest::NeutralFeatureWeight) {
386         if (featureType != QGeoRouteRequest::NoFeature)
387             d_ptr->featureWeights[featureType] = featureWeight;
388     } else {
389         d_ptr->featureWeights.remove(featureType);
390     }
391 }
392 
393 /*!
394     Returns the weight assigned to \a featureType in the planning of the route.
395 
396     If no feature weight has been specified for \a featureType then
397     NeutralFeatureWeight will be returned.
398 */
featureWeight(QGeoRouteRequest::FeatureType featureType) const399 QGeoRouteRequest::FeatureWeight QGeoRouteRequest::featureWeight(QGeoRouteRequest::FeatureType featureType) const
400 {
401     return d_ptr->featureWeights.value(featureType, QGeoRouteRequest::NeutralFeatureWeight);
402 }
403 
404 /*!
405     Returns the list of features that will be considered when planning the
406     route.  Features with a weight of NeutralFeatureWeight will not be returned.
407 */
featureTypes() const408 QList<QGeoRouteRequest::FeatureType> QGeoRouteRequest::featureTypes() const
409 {
410     return d_ptr->featureWeights.keys();
411 }
412 
413 /*!
414     Sets the optimization criteria to use while planning the route to
415     \a optimization.
416 
417     The default value is QGeoRouteRequest::FastestRoute.
418 */
setRouteOptimization(QGeoRouteRequest::RouteOptimizations optimization)419 void QGeoRouteRequest::setRouteOptimization(QGeoRouteRequest::RouteOptimizations optimization)
420 {
421     d_ptr->routeOptimization = optimization;
422 }
423 
424 /*!
425     Returns the optimization criteria which this request specifies should be
426     used while planning the route.
427 */
routeOptimization() const428 QGeoRouteRequest::RouteOptimizations QGeoRouteRequest::routeOptimization() const
429 {
430     return d_ptr->routeOptimization;
431 }
432 
433 /*!
434     Sets the level of detail to use when representing routing segments to
435     \a segmentDetail.
436 */
setSegmentDetail(QGeoRouteRequest::SegmentDetail segmentDetail)437 void QGeoRouteRequest::setSegmentDetail(QGeoRouteRequest::SegmentDetail segmentDetail)
438 {
439     d_ptr->segmentDetail = segmentDetail;
440 }
441 
442 /*!
443     Returns the level of detail which will be used in the representation of
444     routing segments.
445 */
segmentDetail() const446 QGeoRouteRequest::SegmentDetail QGeoRouteRequest::segmentDetail() const
447 {
448     return d_ptr->segmentDetail;
449 }
450 
451 /*!
452     Sets the level of detail to use when representing routing maneuvers to
453     \a maneuverDetail.
454 
455     The default value is QGeoRouteRequest::BasicManeuvers.
456 */
setManeuverDetail(QGeoRouteRequest::ManeuverDetail maneuverDetail)457 void QGeoRouteRequest::setManeuverDetail(QGeoRouteRequest::ManeuverDetail maneuverDetail)
458 {
459     d_ptr->maneuverDetail = maneuverDetail;
460 }
461 
462 /*!
463     Returns the level of detail which will be used in the representation of
464     routing maneuvers.
465 */
maneuverDetail() const466 QGeoRouteRequest::ManeuverDetail QGeoRouteRequest::maneuverDetail() const
467 {
468     return d_ptr->maneuverDetail;
469 }
470 
471 /*!
472     Sets the departure time \a departureTime for the route calculation. This
473     information can be used by the backend to calculate a faster route, for
474     example, by avoiding traffic congestion during rush hour.
475 
476     The default value is an invalid QDateTime.
477 
478     \since 5.13
479 */
setDepartureTime(const QDateTime & departureTime)480 void QGeoRouteRequest::setDepartureTime(const QDateTime &departureTime)
481 {
482     d_ptr->departureTime = departureTime;
483 }
484 
485 /*!
486     Returns the departure time in the request.
487 
488     \since 5.13
489 */
departureTime() const490 QDateTime QGeoRouteRequest::departureTime() const
491 {
492     return d_ptr->departureTime;
493 }
494 
495 /*!
496     Sets the extra parameters \a extraParameters for the route request.
497     The format of the extra parameters is plugin specific, and documented per plugin.
498 
499     \since 5.11
500 */
setExtraParameters(const QVariantMap & extraParameters)501 void QGeoRouteRequest::setExtraParameters(const QVariantMap &extraParameters)
502 {
503     d_ptr->extraParameters = extraParameters;
504 }
505 
506 /*!
507     Returns the extra parameters set for this route request.
508 
509     \since 5.11
510 */
extraParameters() const511 QVariantMap QGeoRouteRequest::extraParameters() const
512 {
513     return d_ptr->extraParameters;
514 }
515 
516 /*******************************************************************************
517 *******************************************************************************/
518 
QGeoRouteRequestPrivate()519 QGeoRouteRequestPrivate::QGeoRouteRequestPrivate()
520     : QSharedData(),
521       numberAlternativeRoutes(0),
522       travelModes(QGeoRouteRequest::CarTravel),
523       routeOptimization(QGeoRouteRequest::FastestRoute),
524       segmentDetail(QGeoRouteRequest::BasicSegmentData),
525       maneuverDetail(QGeoRouteRequest::BasicManeuvers) {}
526 
QGeoRouteRequestPrivate(const QGeoRouteRequestPrivate & other)527 QGeoRouteRequestPrivate::QGeoRouteRequestPrivate(const QGeoRouteRequestPrivate &other)
528     : QSharedData(other),
529       waypoints(other.waypoints),
530       waypointMetadata(other.waypointMetadata),
531       excludeAreas(other.excludeAreas),
532       numberAlternativeRoutes(other.numberAlternativeRoutes),
533       travelModes(other.travelModes),
534       featureWeights(other.featureWeights),
535       routeOptimization(other.routeOptimization),
536       segmentDetail(other.segmentDetail),
537       maneuverDetail(other.maneuverDetail),
538       extraParameters(other.extraParameters) {}
539 
~QGeoRouteRequestPrivate()540 QGeoRouteRequestPrivate::~QGeoRouteRequestPrivate() {}
541 
operator ==(const QGeoRouteRequestPrivate & other) const542 bool QGeoRouteRequestPrivate::operator ==(const QGeoRouteRequestPrivate &other) const
543 {
544     return ((waypoints == other.waypoints)
545             && (waypointMetadata == other.waypointMetadata)
546             && (excludeAreas == other.excludeAreas)
547             && (numberAlternativeRoutes == other.numberAlternativeRoutes)
548             && (travelModes == other.travelModes)
549             && (featureWeights == other.featureWeights)
550             && (routeOptimization == other.routeOptimization)
551             && (segmentDetail == other.segmentDetail)
552             && (maneuverDetail == other.maneuverDetail)
553             && (extraParameters ==  other.extraParameters));
554 }
555 
556 QT_END_NAMESPACE
557