| 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 | */ |
| 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 | */ |
| 230 | QGeoRouteRequest::QGeoRouteRequest(const QGeoCoordinate &origin, const QGeoCoordinate &destination) |
| 231 | : d_ptr(new QGeoRouteRequestPrivate()) |
| 232 | { |
| 233 | d_ptr->waypoints.append(t: origin); |
| 234 | d_ptr->waypoints.append(t: destination); |
| 235 | } |
| 236 | |
| 237 | /*! |
| 238 | Constructs a route request object from the contents of \a other. |
| 239 | */ |
| 240 | QGeoRouteRequest::QGeoRouteRequest(const QGeoRouteRequest &other) |
| 241 | : d_ptr(other.d_ptr) {} |
| 242 | |
| 243 | /*! |
| 244 | Destroys the request. |
| 245 | */ |
| 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 | */ |
| 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 | */ |
| 264 | 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 | */ |
| 273 | 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 | */ |
| 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 | */ |
| 294 | 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 | */ |
| 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 | */ |
| 315 | 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 | */ |
| 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 | */ |
| 331 | 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 | */ |
| 342 | void QGeoRouteRequest::setNumberAlternativeRoutes(int alternatives) |
| 343 | { |
| 344 | d_ptr->numberAlternativeRoutes = qMax(a: 0, b: alternatives); |
| 345 | } |
| 346 | |
| 347 | /*! |
| 348 | Returns the number of alternative routes which will be requested. |
| 349 | */ |
| 350 | 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 | */ |
| 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 | */ |
| 370 | 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 | */ |
| 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(akey: 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 | */ |
| 399 | QGeoRouteRequest::FeatureWeight QGeoRouteRequest::featureWeight(QGeoRouteRequest::FeatureType featureType) const |
| 400 | { |
| 401 | return d_ptr->featureWeights.value(akey: featureType, adefaultValue: 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 | */ |
| 408 | 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 | */ |
| 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 | */ |
| 428 | 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 | */ |
| 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 | */ |
| 446 | 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 | */ |
| 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 | */ |
| 466 | 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 | */ |
| 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 | */ |
| 490 | 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 | */ |
| 501 | void QGeoRouteRequest::(const QVariantMap &) |
| 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 | */ |
| 511 | QVariantMap QGeoRouteRequest::() const |
| 512 | { |
| 513 | return d_ptr->extraParameters; |
| 514 | } |
| 515 | |
| 516 | /******************************************************************************* |
| 517 | *******************************************************************************/ |
| 518 | |
| 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 | |
| 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 | |
| 540 | QGeoRouteRequestPrivate::~QGeoRouteRequestPrivate() {} |
| 541 | |
| 542 | 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 | |