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 "qgeoroute.h"
38#include "qgeoroute_p.h"
39
40#include "qgeorectangle.h"
41#include "qgeoroutesegment.h"
42
43#include <QDateTime>
44#include <QVariantMap>
45
46QT_BEGIN_NAMESPACE
47
48template<>
49QGeoRoutePrivate *QExplicitlySharedDataPointer<QGeoRoutePrivate>::clone()
50{
51 return d->clone();
52}
53
54/*!
55 \class QGeoRoute
56 \inmodule QtLocation
57 \ingroup QtLocation-routing
58 \since 5.6
59
60 \brief The QGeoRoute class represents a route between two points.
61
62 A QGeoRoute object contains high level information about a route, such
63 as the length the route, the estimated travel time for the route,
64 and enough information to render a basic image of the route on a map.
65
66 The QGeoRoute object also contains a list of QGeoRouteSegment objecs which
67 describe subsections of the route in greater detail.
68
69 Routing information is normally requested using
70 QGeoRoutingManager::calculateRoute(), which returns a QGeoRouteReply
71 instance. If the operation is completed successfully the routing
72 information can be accessed with QGeoRouteReply::routes()
73
74 \sa QGeoRoutingManager
75*/
76
77/*!
78 Constructs a route object.
79*/
80QGeoRoute::QGeoRoute()
81 : d_ptr(new QGeoRoutePrivateDefault()) {}
82
83/*!
84 Constructs a route object using \a dd as private implementation.
85*/
86QGeoRoute::QGeoRoute(const QExplicitlySharedDataPointer<QGeoRoutePrivate> &dd): d_ptr(dd)
87{
88}
89
90/*!
91 Returns the private implementation.
92*/
93QExplicitlySharedDataPointer<QGeoRoutePrivate> &QGeoRoute::d()
94{
95 return d_ptr;
96}
97
98const QExplicitlySharedDataPointer<QGeoRoutePrivate> &QGeoRoute::const_d() const
99{
100 return d_ptr;
101}
102
103/*!
104 Constructs a route object from the contents of \a other.
105*/
106QGeoRoute::QGeoRoute(const QGeoRoute &other)
107 : d_ptr(other.d_ptr) {}
108
109/*!
110 Destroys this route object.
111*/
112QGeoRoute::~QGeoRoute()
113{
114}
115
116/*!
117 Assigns the contents of \a other to this route and returns a reference to
118 this route.
119*/
120QGeoRoute &QGeoRoute::operator= (const QGeoRoute & other)
121{
122 if (this == &other)
123 return *this;
124
125 d_ptr = other.d_ptr;
126 return *this;
127}
128
129/*!
130 Returns whether this route and \a other are equal.
131*/
132bool QGeoRoute::operator ==(const QGeoRoute &other) const
133{
134 return ( (d_ptr.constData() == other.d_ptr.constData())
135 || (*d_ptr) == (*other.d_ptr));
136}
137
138/*!
139 Returns whether this route and \a other are not equal.
140*/
141bool QGeoRoute::operator !=(const QGeoRoute &other) const
142{
143 return !(operator==(other));
144}
145
146/*!
147 Sets the identifier of this route to \a id.
148
149 Service providers which support the updating of routes commonly assign
150 identifiers to routes. If this route came from such a service provider changing
151 the identifier will probably cause route updates to stop working.
152*/
153void QGeoRoute::setRouteId(const QString &id)
154{
155 d_ptr->setId(id);
156}
157
158/*!
159 Returns the identifier of this route.
160
161 Service providers which support the updating of routes commonly assign
162 identifiers to routes. If this route did not come from such a service provider
163 the function will return an empty string.
164*/
165QString QGeoRoute::routeId() const
166{
167 return d_ptr->id();
168}
169
170/*!
171 Sets the route request which describes the criteria used in the
172 calculcation of this route to \a request.
173*/
174void QGeoRoute::setRequest(const QGeoRouteRequest &request)
175{
176 d_ptr->setRequest(request);
177}
178
179/*!
180 Returns the route request which describes the criteria used in
181 the calculation of this route.
182*/
183QGeoRouteRequest QGeoRoute::request() const
184{
185 return d_ptr->request();
186}
187
188/*!
189 Sets the bounding box which encompasses the entire route to \a bounds.
190*/
191void QGeoRoute::setBounds(const QGeoRectangle &bounds)
192{
193 d_ptr->setBounds(bounds);
194}
195
196/*!
197 Returns a bounding box which encompasses the entire route.
198*/
199QGeoRectangle QGeoRoute::bounds() const
200{
201 return d_ptr->bounds();
202}
203
204/*!
205 Sets the first route segment in the route to \a routeSegment.
206*/
207void QGeoRoute::setFirstRouteSegment(const QGeoRouteSegment &routeSegment)
208{
209 d_ptr->setFirstSegment(routeSegment);
210}
211
212/*!
213 Returns the first route segment in the route.
214
215 Will return an invalid route segment if there are no route segments
216 associated with the route.
217
218 The remaining route segments can be accessed sequentially with
219 QGeoRouteSegment::nextRouteSegment.
220*/
221QGeoRouteSegment QGeoRoute::firstRouteSegment() const
222{
223 return d_ptr->firstSegment();
224}
225
226/*!
227 Sets the estimated amount of time it will take to traverse this route,
228 in seconds, to \a secs.
229*/
230void QGeoRoute::setTravelTime(int secs)
231{
232 d_ptr->setTravelTime(secs);
233}
234
235/*!
236 Returns the estimated amount of time it will take to traverse this route,
237 in seconds.
238*/
239int QGeoRoute::travelTime() const
240{
241 return d_ptr->travelTime();
242}
243
244/*!
245 Sets the distance covered by this route, in meters, to \a distance.
246*/
247void QGeoRoute::setDistance(qreal distance)
248{
249 d_ptr->setDistance(distance);
250}
251
252/*!
253 Returns the distance covered by this route, in meters.
254*/
255qreal QGeoRoute::distance() const
256{
257 return d_ptr->distance();
258}
259
260/*!
261 Sets the travel mode for this route to \a mode.
262
263 This should be one of the travel modes returned by request().travelModes().
264*/
265void QGeoRoute::setTravelMode(QGeoRouteRequest::TravelMode mode)
266{
267 d_ptr->setTravelMode(mode);
268}
269
270/*!
271 Returns the travel mode for the this route.
272
273 This should be one of the travel modes returned by request().travelModes().
274*/
275QGeoRouteRequest::TravelMode QGeoRoute::travelMode() const
276{
277 return d_ptr->travelMode();
278}
279
280/*!
281 Sets the geometric shape of the route to \a path.
282
283 The coordinates in \a path should be listed in the order in which they
284 would be traversed by someone traveling along this segment of the route.
285*/
286void QGeoRoute::setPath(const QList<QGeoCoordinate> &path)
287{
288 d_ptr->setPath(path);
289}
290
291/*!
292 Returns the geometric shape of the route.
293
294 The coordinates should be listed in the order in which they
295 would be traversed by someone traveling along this segment of the route.
296*/
297QList<QGeoCoordinate> QGeoRoute::path() const
298{
299 return d_ptr->path();
300}
301
302/*!
303 Sets the route \a legs for a multi-waypoint route.
304
305 \sa QGeoRouteLeg
306 \since 5.12
307*/
308void QGeoRoute::setRouteLegs(const QList<QGeoRouteLeg> &legs)
309{
310 d_ptr->setRouteLegs(legs);
311}
312
313/*!
314 Returns the legs for the route.
315
316 \sa QGeoRouteLeg
317 \since 5.12
318*/
319QList<QGeoRouteLeg> QGeoRoute::routeLegs() const
320{
321 return d_ptr->routeLegs();
322}
323
324/*!
325 Sets the extended attributes \a extendedAttributes associated with this route.
326
327 \since 5.13
328*/
329void QGeoRoute::setExtendedAttributes(const QVariantMap &extendedAttributes)
330{
331 d_ptr->setExtendedAttributes(extendedAttributes);
332}
333
334/*!
335 Returns the extended attributes associated with this route.
336
337 \since 5.13
338*/
339QVariantMap QGeoRoute::extendedAttributes() const
340{
341 return d_ptr->extendedAttributes();
342}
343
344/*******************************************************************************
345*******************************************************************************/
346
347QGeoRoutePrivate::QGeoRoutePrivate()
348{
349
350}
351
352QGeoRoutePrivate::QGeoRoutePrivate(const QGeoRoutePrivate &other) : QSharedData(other)
353{
354
355}
356
357QGeoRoutePrivate::~QGeoRoutePrivate() {}
358
359bool QGeoRoutePrivate::operator ==(const QGeoRoutePrivate &other) const
360{
361 return equals(other);
362}
363
364bool QGeoRoutePrivate::equals(const QGeoRoutePrivate &other) const
365{
366 if (!other.engineName().isEmpty()) // only way to know if other comes from an engine without dynamic_cast
367 return false;
368
369 // here both routes are of type QGeoRoutePrivateDefault
370 QGeoRouteSegment s1 = firstSegment();
371 QGeoRouteSegment s2 = other.firstSegment();
372
373 while (true) {
374 if (s1.isValid() != s2.isValid())
375 return false;
376 if (!s1.isValid())
377 break;
378 if (s1 != s2)
379 return false;
380 s1 = s1.nextRouteSegment();
381 s2 = s2.nextRouteSegment();
382 }
383
384 return ( (id() == other.id())
385 && (request() == other.request())
386 && (bounds() == other.bounds())
387 && (travelTime() == other.travelTime())
388 && (distance() == other.distance())
389 && (travelMode() == other.travelMode())
390 && (path() == other.path())
391 && (metadata() == other.metadata())
392 && (routeLegs() == other.routeLegs())
393 && (extendedAttributes() == other.extendedAttributes()) );
394}
395
396void QGeoRoutePrivate::setId(const QString &id)
397{
398 Q_UNUSED(id);
399}
400
401QString QGeoRoutePrivate::id() const
402{
403 return QString();
404}
405
406void QGeoRoutePrivate::setRequest(const QGeoRouteRequest &request)
407{
408 Q_UNUSED(request);
409}
410
411QGeoRouteRequest QGeoRoutePrivate::request() const
412{
413 return QGeoRouteRequest();
414}
415
416void QGeoRoutePrivate::setBounds(const QGeoRectangle &bounds)
417{
418 Q_UNUSED(bounds);
419}
420
421QGeoRectangle QGeoRoutePrivate::bounds() const
422{
423 return QGeoRectangle();
424}
425
426void QGeoRoutePrivate::setTravelTime(int travelTime)
427{
428 Q_UNUSED(travelTime);
429}
430
431int QGeoRoutePrivate::travelTime() const
432{
433 return 0;
434}
435
436void QGeoRoutePrivate::setDistance(qreal distance)
437{
438 Q_UNUSED(distance);
439}
440
441qreal QGeoRoutePrivate::distance() const
442{
443 return 0;
444}
445
446void QGeoRoutePrivate::setTravelMode(QGeoRouteRequest::TravelMode mode)
447{
448 Q_UNUSED(mode);
449}
450
451QGeoRouteRequest::TravelMode QGeoRoutePrivate::travelMode() const
452{
453 return QGeoRouteRequest::CarTravel;
454}
455
456void QGeoRoutePrivate::setPath(const QList<QGeoCoordinate> &path)
457{
458 Q_UNUSED(path);
459}
460
461QList<QGeoCoordinate> QGeoRoutePrivate::path() const
462{
463 return QList<QGeoCoordinate>();
464}
465
466void QGeoRoutePrivate::setFirstSegment(const QGeoRouteSegment &firstSegment)
467{
468 Q_UNUSED(firstSegment);
469}
470
471QGeoRouteSegment QGeoRoutePrivate::firstSegment() const
472{
473 return QGeoRouteSegment();
474}
475
476const QGeoRoutePrivate *QGeoRoutePrivate::routePrivateData(const QGeoRoute &route)
477{
478 return route.d_ptr.data();
479}
480
481QVariantMap QGeoRoutePrivate::metadata() const
482{
483 return QVariantMap();
484}
485
486void QGeoRoutePrivate::setRouteLegs(const QList<QGeoRouteLeg> &/*legs*/)
487{
488
489}
490
491QList<QGeoRouteLeg> QGeoRoutePrivate::routeLegs() const
492{
493 return QList<QGeoRouteLeg>();
494}
495
496void QGeoRoutePrivate::setExtendedAttributes(const QVariantMap &/*extendedAttributes*/)
497{
498
499}
500
501QVariantMap QGeoRoutePrivate::extendedAttributes() const
502{
503 return QVariantMap();
504}
505
506void QGeoRoutePrivate::setLegIndex(int /*idx*/)
507{
508
509}
510
511int QGeoRoutePrivate::legIndex() const
512{
513 return 0;
514}
515
516void QGeoRoutePrivate::setContainingRoute(const QGeoRoute &/*route*/)
517{
518
519}
520
521QGeoRoute QGeoRoutePrivate::containingRoute() const
522{
523 return QGeoRoute();
524}
525
526/*******************************************************************************
527*******************************************************************************/
528
529
530QGeoRoutePrivateDefault::QGeoRoutePrivateDefault()
531 : m_travelTime(0),
532 m_distance(0.0),
533 m_travelMode(QGeoRouteRequest::CarTravel),
534 m_numSegments(-1) {}
535
536QGeoRoutePrivateDefault::QGeoRoutePrivateDefault(const QGeoRoutePrivateDefault &other)
537 : QGeoRoutePrivate(other),
538 m_id(other.m_id),
539 m_request(other.m_request),
540 m_bounds(other.m_bounds),
541 m_routeSegments(other.m_routeSegments),
542 m_travelTime(other.m_travelTime),
543 m_distance(other.m_distance),
544 m_travelMode(other.m_travelMode),
545 m_path(other.m_path),
546 m_legs(other.m_legs),
547 m_firstSegment(other.m_firstSegment),
548 m_numSegments(other.m_numSegments),
549 m_extendedAttributes(other.m_extendedAttributes) {} // Purposedly ignoring legIndex and parentRoute
550
551
552QGeoRoutePrivateDefault::~QGeoRoutePrivateDefault() {}
553
554QGeoRoutePrivate *QGeoRoutePrivateDefault::clone()
555{
556 return new QGeoRoutePrivateDefault(*this);
557}
558
559void QGeoRoutePrivateDefault::setId(const QString &id)
560{
561 m_id = id;
562}
563
564QString QGeoRoutePrivateDefault::id() const
565{
566 return m_id;
567}
568
569void QGeoRoutePrivateDefault::setRequest(const QGeoRouteRequest &request)
570{
571 m_request = request;
572}
573
574QGeoRouteRequest QGeoRoutePrivateDefault::request() const
575{
576 return m_request;
577}
578
579void QGeoRoutePrivateDefault::setBounds(const QGeoRectangle &bounds)
580{
581 m_bounds = bounds;
582}
583
584QGeoRectangle QGeoRoutePrivateDefault::bounds() const
585{
586 return m_bounds;
587}
588
589void QGeoRoutePrivateDefault::setTravelTime(int travelTime)
590{
591 m_travelTime = travelTime;
592}
593
594int QGeoRoutePrivateDefault::travelTime() const
595{
596 return m_travelTime;
597}
598
599void QGeoRoutePrivateDefault::setDistance(qreal distance)
600{
601 m_distance = distance;
602}
603
604qreal QGeoRoutePrivateDefault::distance() const
605{
606 return m_distance;
607}
608
609void QGeoRoutePrivateDefault::setTravelMode(QGeoRouteRequest::TravelMode mode)
610{
611 m_travelMode = mode;
612}
613
614QGeoRouteRequest::TravelMode QGeoRoutePrivateDefault::travelMode() const
615{
616 return m_travelMode;
617}
618
619void QGeoRoutePrivateDefault::setPath(const QList<QGeoCoordinate> &path)
620{
621 m_path = path;
622}
623
624QList<QGeoCoordinate> QGeoRoutePrivateDefault::path() const
625{
626 return m_path;
627}
628
629void QGeoRoutePrivateDefault::setFirstSegment(const QGeoRouteSegment &firstSegment)
630{
631 m_firstSegment = firstSegment;
632}
633
634QGeoRouteSegment QGeoRoutePrivateDefault::firstSegment() const
635{
636 return m_firstSegment;
637}
638
639QString QGeoRoutePrivateDefault::engineName() const
640{
641 return QString();
642}
643
644int QGeoRoutePrivateDefault::segmentsCount() const
645{
646 if (m_numSegments >= 0)
647 return m_numSegments;
648
649 int count = 0;
650 QGeoRouteSegment segment = m_firstSegment;
651 while (segment.isValid()) {
652 ++count;
653 if (segment.isLegLastSegment() && m_containingRoute.data()) // if containing route, this is a leg
654 break;
655 segment = segment.nextRouteSegment();
656 }
657 m_numSegments = count;
658 return count;
659}
660
661void QGeoRoutePrivateDefault::setRouteLegs(const QList<QGeoRouteLeg> &legs)
662{
663 m_legs = legs;
664}
665
666QList<QGeoRouteLeg> QGeoRoutePrivateDefault::routeLegs() const
667{
668 return m_legs;
669}
670
671void QGeoRoutePrivateDefault::setExtendedAttributes(const QVariantMap &extendedAttributes)
672{
673 m_extendedAttributes = extendedAttributes;
674}
675
676QVariantMap QGeoRoutePrivateDefault::extendedAttributes() const
677{
678 return m_extendedAttributes;
679}
680
681void QGeoRoutePrivateDefault::setLegIndex(int idx)
682{
683 if (idx >= 0)
684 m_legIndex = idx;
685}
686
687int QGeoRoutePrivateDefault::legIndex() const
688{
689 return m_legIndex;
690}
691
692void QGeoRoutePrivateDefault::setContainingRoute(const QGeoRoute &route)
693{
694 QScopedPointer<QGeoRoute> containingRoute(new QGeoRoute(route));
695 m_containingRoute.swap(other&: containingRoute);
696}
697
698QGeoRoute QGeoRoutePrivateDefault::containingRoute() const
699{
700 if (m_containingRoute)
701 return *m_containingRoute;
702 return QGeoRoute();
703}
704
705/*!
706 \class QGeoRouteLeg
707 \inmodule QtLocation
708 \ingroup QtLocation-routing
709 \since 5.12
710
711 \brief The QGeoRouteLeg class represents a leg of a route, that is the portion
712 of a route between one waypoint and the next.
713 This is a subclass of QGeoRoute, exposing route leg specific API.
714
715 \note QGeoRoute::routeLegs will return an empty list if called on a route leg.
716
717 \sa QGeoRoute
718*/
719
720/*!
721 Constructs a route leg object.
722*/
723
724QGeoRouteLeg::QGeoRouteLeg() : QGeoRoute()
725{
726
727}
728
729/*!
730 Constructs a route leg object from the contents of \a other.
731*/
732QGeoRouteLeg::QGeoRouteLeg(const QGeoRouteLeg &other) : QGeoRoute(other)
733{
734
735}
736
737/*!
738 Destroys this route object.
739*/
740QGeoRouteLeg::~QGeoRouteLeg()
741{
742
743}
744
745/*!
746 Sets the route leg index to \a idx.
747*/
748void QGeoRouteLeg::setLegIndex(int idx)
749{
750 d()->setLegIndex(idx);
751}
752
753/*!
754 Returns the index of this route leg inside the containing QGeoRoute::routeLegs list.
755 Can be used to find the next legs.
756*/
757int QGeoRouteLeg::legIndex() const
758{
759 return const_d()->legIndex();
760}
761
762/*!
763 Sets the \a route that contains this route leg.
764*/
765void QGeoRouteLeg::setOverallRoute(const QGeoRoute &route)
766{
767 d()->setContainingRoute(route);
768}
769
770/*!
771 Returns the route that contains this route leg.
772*/
773QGeoRoute QGeoRouteLeg::overallRoute() const
774{
775 return const_d()->containingRoute();
776}
777
778QGeoRouteLeg::QGeoRouteLeg(const QExplicitlySharedDataPointer<QGeoRoutePrivate> &dd) : QGeoRoute(dd)
779{
780
781}
782
783QT_END_NAMESPACE
784

source code of qtlocation/src/location/maps/qgeoroute.cpp