7#include <QtCore/QCoreApplication>
8#include <QtQml/QQmlEngine>
9#include <QtQml/qqmlinfo.h>
10#include <QtLocation/QGeoRoutingManager>
11#include <QtPositioning/QGeoRectangle>
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
82QDeclarativeGeoRouteModel::QDeclarativeGeoRouteModel(QObject *parent)
83 : QAbstractListModel(parent)
88
89
90
91
92
93
95int QDeclarativeGeoRouteModel::count()
const
97 return routes_.count();
101
102
103
104
105
106
108void QDeclarativeGeoRouteModel::reset()
110 if (!routes_.isEmpty()) {
114 emit routesChanged();
118 emit abortRequested();
119 setError(NoError, QString());
120 setStatus(QDeclarativeGeoRouteModel::Null);
124
125
126
127
128
129void QDeclarativeGeoRouteModel::cancel()
131 emit abortRequested();
132 setError(NoError, QString());
133 setStatus(routes_.isEmpty() ? Null : Ready);
137
138
139
140
141
142
143
144
145
147QGeoRoute QDeclarativeGeoRouteModel::get(
int index)
149 if (index < 0 || index >= routes_.count()) {
150 qmlWarning(
this) << QStringLiteral(
"Index '%1' out of range").arg(index);
153 return routes_.at(index);
157
158
159void QDeclarativeGeoRouteModel::componentComplete()
168
169
170int QDeclarativeGeoRouteModel::rowCount(
const QModelIndex &parent)
const
173 return routes_.count();
177
178
179QVariant QDeclarativeGeoRouteModel::data(
const QModelIndex &index,
int role)
const
181 if (!index.isValid()) {
182 qmlWarning(
this) << QStringLiteral(
"Error in indexing route model's data (invalid index).");
186 if (index.row() >= routes_.count()) {
187 qmlWarning(
this) << QStringLiteral(
"Fatal error in indexing route model's data (index overflow).");
191 if (role == RouteRole)
192 return QVariant::fromValue(routes_.at(index.row()));
196QHash<
int, QByteArray> QDeclarativeGeoRouteModel::roleNames()
const
198 QHash<
int, QByteArray> roleNames = QAbstractListModel::roleNames();
199 roleNames.insert(RouteRole,
"routeData");
204
205
206void QDeclarativeGeoRouteModel::setPlugin(QDeclarativeGeoServiceProvider *plugin)
208 if (plugin_ == plugin)
214 disconnect(plugin_, &QDeclarativeGeoServiceProvider::localesChanged,
215 this, &QDeclarativeGeoRouteModel::measurementSystemChanged);
218 connect(plugin, &QDeclarativeGeoServiceProvider::localesChanged,
219 this, &QDeclarativeGeoRouteModel::measurementSystemChanged);
225 emit pluginChanged();
230 if (plugin_->isAttached()) {
233 connect(plugin_, &QDeclarativeGeoServiceProvider::attached,
234 this, &QDeclarativeGeoRouteModel::pluginReady);
239
240
241void QDeclarativeGeoRouteModel::pluginReady()
243 QGeoServiceProvider *serviceProvider = plugin_->sharedGeoServiceProvider();
244 QGeoRoutingManager *routingManager = serviceProvider->routingManager();
246 if (serviceProvider->routingError() != QGeoServiceProvider::NoError) {
247 QDeclarativeGeoRouteModel::RouteError newError = UnknownError;
248 switch (serviceProvider->routingError()) {
249 case QGeoServiceProvider::NotSupportedError:
250 newError = EngineNotSetError;
break;
251 case QGeoServiceProvider::UnknownParameterError:
252 newError = UnknownParameterError;
break;
253 case QGeoServiceProvider::MissingRequiredParameterError:
254 newError = MissingRequiredParameterError;
break;
255 case QGeoServiceProvider::ConnectionError:
256 newError = CommunicationError;
break;
261 setError(newError, serviceProvider->routingErrorString());
265 if (!routingManager) {
266 setError(EngineNotSetError, tr(
"Plugin does not support routing."));
270 connect(routingManager, &QGeoRoutingManager::finished,
271 this, &QDeclarativeGeoRouteModel::routingFinished);
272 connect(routingManager, &QGeoRoutingManager::errorOccurred,
273 this, &QDeclarativeGeoRouteModel::routingError);
277
278
279void QDeclarativeGeoRouteModel::queryDetailsChanged()
281 if (autoUpdate_ && complete_)
286
287
288
289
290
291
292
293
294
295
296
298QDeclarativeGeoServiceProvider *QDeclarativeGeoRouteModel::plugin()
const
304
305
306void QDeclarativeGeoRouteModel::setQuery(QDeclarativeGeoRouteQuery *query)
308 if (!query || query == routeQuery_)
311 routeQuery_->disconnect(
this);
313 connect(query, &QDeclarativeGeoRouteQuery::queryDetailsChanged,
314 this, &QDeclarativeGeoRouteModel::queryDetailsChanged);
323
324
325
326
327
328
330QDeclarativeGeoRouteQuery *QDeclarativeGeoRouteModel::query()
const
336
337
338void QDeclarativeGeoRouteModel::setAutoUpdate(
bool autoUpdate)
340 if (autoUpdate_ == autoUpdate)
342 autoUpdate_ = autoUpdate;
344 emit autoUpdateChanged();
348
349
350
351
352
353
354
355
356
357
358
359
361bool QDeclarativeGeoRouteModel::autoUpdate()
const
367
368
369
370
371
372
373
374
375
376void QDeclarativeGeoRouteModel::setMeasurementSystem(QLocale::MeasurementSystem ms)
381 QGeoServiceProvider *serviceProvider = plugin_->sharedGeoServiceProvider();
382 if (!serviceProvider)
385 QGeoRoutingManager *routingManager = serviceProvider->routingManager();
389 if (routingManager->measurementSystem() == ms)
392 routingManager->setMeasurementSystem(ms);
393 emit measurementSystemChanged();
396QLocale::MeasurementSystem QDeclarativeGeoRouteModel::measurementSystem()
const
399 return QLocale().measurementSystem();
401 QGeoServiceProvider *serviceProvider = plugin_->sharedGeoServiceProvider();
402 if (!serviceProvider) {
403 if (plugin_->locales().isEmpty())
404 return QLocale().measurementSystem();
406 return QLocale(plugin_->locales().first()).measurementSystem();
409 QGeoRoutingManager *routingManager = serviceProvider->routingManager();
410 if (!routingManager) {
411 if (plugin_->locales().isEmpty())
412 return QLocale().measurementSystem();
414 return QLocale(plugin_->locales().first()).measurementSystem();
417 return routingManager->measurementSystem();
421
422
423void QDeclarativeGeoRouteModel::setStatus(QDeclarativeGeoRouteModel::Status status)
425 if (status_ == status)
431 emit statusChanged();
435
436
437
438
439
440
441
442
443
444
445
447QDeclarativeGeoRouteModel::Status QDeclarativeGeoRouteModel::status()
const
453
454
455
456
457
458
459
460
462QString QDeclarativeGeoRouteModel::errorString()
const
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
486QDeclarativeGeoRouteModel::RouteError QDeclarativeGeoRouteModel::error()
const
491void QDeclarativeGeoRouteModel::setError(RouteError error,
const QString& errorString)
493 if (error_ == error && errorString_ == errorString)
496 errorString_ = errorString;
501
502
503
504
505
506
507void QDeclarativeGeoRouteModel::update()
513 setError(EngineNotSetError, tr(
"Cannot route, plugin not set."));
517 QGeoServiceProvider *serviceProvider = plugin_->sharedGeoServiceProvider();
518 if (!serviceProvider)
521 QGeoRoutingManager *routingManager = serviceProvider->routingManager();
522 if (!routingManager) {
523 setError(EngineNotSetError, tr(
"Cannot route, route manager not set."));
527 setError(ParseError, tr(
"Cannot route, valid query not set."));
530 emit abortRequested();
531 QGeoRouteRequest request = routeQuery_->routeRequest();
532 if (request.waypoints().count() < 2) {
533 setError(ParseError,tr(
"Not enough waypoints for routing."));
537 setError(NoError, QString());
539 QGeoRouteReply *reply = routingManager->calculateRoute(request);
540 setStatus(QDeclarativeGeoRouteModel::Loading);
541 if (!reply->isFinished()) {
542 connect(
this, &QDeclarativeGeoRouteModel::abortRequested, reply, &QGeoRouteReply::abort);
544 if (reply->error() == QGeoRouteReply::NoError) {
545 routingFinished(reply);
547 routingError(reply, reply->error(), reply->errorString());
553
554
555void QDeclarativeGeoRouteModel::routingFinished(QGeoRouteReply *reply)
559 reply->deleteLater();
560 if (reply->error() != QGeoRouteReply::NoError)
564 const int oldCount = routes_.count();
565 routes_ = reply->routes();
568 setError(NoError, QString());
569 setStatus(QDeclarativeGeoRouteModel::Ready);
571 if (oldCount != 0 || routes_.count() != 0)
572 emit routesChanged();
573 if (oldCount != routes_.count())
578
579
580void QDeclarativeGeoRouteModel::routingError(QGeoRouteReply *reply,
581 QGeoRouteReply::Error error,
582 const QString &errorString)
586 reply->deleteLater();
587 setError(
static_cast<QDeclarativeGeoRouteModel::RouteError>(error), errorString);
588 setStatus(QDeclarativeGeoRouteModel::Error);
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
642QDeclarativeGeoRouteQuery::QDeclarativeGeoRouteQuery(QObject *parent)
647QDeclarativeGeoRouteQuery::QDeclarativeGeoRouteQuery(
const QGeoRouteRequest &request, QObject *parent)
648 : QObject(parent), request_(request)
652 m_waypoints = request_.waypoints();
655QDeclarativeGeoRouteQuery::~QDeclarativeGeoRouteQuery()
660
661
662void QDeclarativeGeoRouteQuery::componentComplete()
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
689QList<
int> QDeclarativeGeoRouteQuery::featureTypes()
const
693 const auto featureTypes = request_.featureTypes();
694 for (
const auto &featureType : featureTypes)
695 list.append(
static_cast<
int>(featureType));
700
701
702
703
704
707int QDeclarativeGeoRouteQuery::numberAlternativeRoutes()
const
709 return request_.numberAlternativeRoutes();
712void QDeclarativeGeoRouteQuery::setNumberAlternativeRoutes(
int numberAlternativeRoutes)
714 if (numberAlternativeRoutes == request_.numberAlternativeRoutes())
717 request_.setNumberAlternativeRoutes(numberAlternativeRoutes);
720 emit numberAlternativeRoutesChanged();
721 emit queryDetailsChanged();
726
727
728
729
730
731
732
733
734
735
736
738QList<QGeoCoordinate> QDeclarativeGeoRouteQuery::waypoints()
const
743void QDeclarativeGeoRouteQuery::setWaypoints(
const QList<QGeoCoordinate> &value)
745 if (m_waypoints == value)
753
754
755
756
757
758
759
760
761
762QList<QGeoRectangle> QDeclarativeGeoRouteQuery::excludedAreas()
const
764 return request_.excludeAreas();
767void QDeclarativeGeoRouteQuery::setExcludedAreas(
const QList<QGeoRectangle> &value)
769 if (request_.excludeAreas() == value)
772 request_.setExcludeAreas(value);
775 emit excludedAreasChanged();
776 emit queryDetailsChanged();
781
782
783
784
785
786
787
788
791void QDeclarativeGeoRouteQuery::addExcludedArea(
const QGeoRectangle &area)
796 QList<QGeoRectangle> excludedAreas = request_.excludeAreas();
798 if (excludedAreas.contains(area))
801 excludedAreas.append(area);
803 request_.setExcludeAreas(excludedAreas);
806 emit excludedAreasChanged();
807 emit queryDetailsChanged();
812
813
814
815
816
817
819void QDeclarativeGeoRouteQuery::removeExcludedArea(
const QGeoRectangle &area)
824 QList<QGeoRectangle> excludedAreas = request_.excludeAreas();
826 int index = excludedAreas.lastIndexOf(area);
828 qmlWarning(
this) << QStringLiteral(
"Cannot remove nonexistent area.");
831 excludedAreas.removeAt(index);
832 request_.setExcludeAreas(excludedAreas);
835 emit excludedAreasChanged();
836 emit queryDetailsChanged();
841
842
843
844
845
846
848void QDeclarativeGeoRouteQuery::clearExcludedAreas()
850 if (request_.excludeAreas().isEmpty())
853 request_.setExcludeAreas(QList<QGeoRectangle>());
856 emit excludedAreasChanged();
857 emit queryDetailsChanged();
862
863
864
865
866
867
868
869void QDeclarativeGeoRouteQuery::addWaypoint(
const QGeoCoordinate &waypoint)
871 if (!waypoint.isValid()) {
872 qmlWarning(
this) << QStringLiteral(
"Invalid coordinate as waypoint");
876 m_waypoints << waypoint;
881
882
883
884
885
886
887
888
889void QDeclarativeGeoRouteQuery::removeWaypoint(
const QGeoCoordinate &waypoint)
891 if (!waypoint.isValid()) {
892 qmlWarning(
this) << QStringLiteral(
"Invalid coordinate as waypoint");
896 if (qsizetype idx = m_waypoints.lastIndexOf(waypoint); idx >= 0) {
897 m_waypoints.remove(idx);
900 qmlWarning(
this) << QStringLiteral(
"Cannot remove nonexistent waypoint.");
905
906
907
908
909
910
911void QDeclarativeGeoRouteQuery::clearWaypoints()
913 if (m_waypoints.isEmpty())
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
951void QDeclarativeGeoRouteQuery::setFeatureWeight(FeatureType featureType, FeatureWeight featureWeight)
953 if (featureType == NoFeature && !request_.featureTypes().isEmpty()) {
954 resetFeatureWeights();
959 FeatureWeight originalWeight =
static_cast<FeatureWeight>(request_.featureWeight(
static_cast<QGeoRouteRequest::FeatureType>(featureType)));
960 if (featureWeight == originalWeight)
963 request_.setFeatureWeight(
static_cast<QGeoRouteRequest::FeatureType>(featureType),
964 static_cast<QGeoRouteRequest::FeatureWeight>(featureWeight));
965 if (complete_ && ((originalWeight == NeutralFeatureWeight) || (featureWeight == NeutralFeatureWeight))) {
968 emit featureTypesChanged();
969 emit queryDetailsChanged();
974
975
976
977
978
979
980void QDeclarativeGeoRouteQuery::resetFeatureWeights()
983 const auto featureTypes = request_.featureTypes();
984 for (
const auto &featureType : featureTypes)
985 request_.setFeatureWeight(featureType, QGeoRouteRequest::NeutralFeatureWeight);
987 emit featureTypesChanged();
988 emit queryDetailsChanged();
993
994
995
996
997
998
1000int QDeclarativeGeoRouteQuery::featureWeight(FeatureType featureType)
1002 return request_.featureWeight(
static_cast<QGeoRouteRequest::FeatureType>(featureType));
1006
1007
1008void QDeclarativeGeoRouteQuery::setTravelModes(QDeclarativeGeoRouteQuery::TravelModes travelModes)
1010 QGeoRouteRequest::TravelModes reqTravelModes;
1012 if (travelModes & QDeclarativeGeoRouteQuery::CarTravel)
1013 reqTravelModes |= QGeoRouteRequest::CarTravel;
1014 if (travelModes & QDeclarativeGeoRouteQuery::PedestrianTravel)
1015 reqTravelModes |= QGeoRouteRequest::PedestrianTravel;
1016 if (travelModes & QDeclarativeGeoRouteQuery::BicycleTravel)
1017 reqTravelModes |= QGeoRouteRequest::BicycleTravel;
1018 if (travelModes & QDeclarativeGeoRouteQuery::PublicTransitTravel)
1019 reqTravelModes |= QGeoRouteRequest::PublicTransitTravel;
1020 if (travelModes & QDeclarativeGeoRouteQuery::TruckTravel)
1021 reqTravelModes |= QGeoRouteRequest::TruckTravel;
1023 if (reqTravelModes == request_.travelModes())
1026 request_.setTravelModes(reqTravelModes);
1029 emit travelModesChanged();
1030 emit queryDetailsChanged();
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1049void QDeclarativeGeoRouteQuery::setSegmentDetail(SegmentDetail segmentDetail)
1051 if (
static_cast<QGeoRouteRequest::SegmentDetail>(segmentDetail) == request_.segmentDetail())
1053 request_.setSegmentDetail(
static_cast<QGeoRouteRequest::SegmentDetail>(segmentDetail));
1055 emit segmentDetailChanged();
1056 emit queryDetailsChanged();
1060QDeclarativeGeoRouteQuery::SegmentDetail QDeclarativeGeoRouteQuery::segmentDetail()
const
1062 return static_cast<QDeclarativeGeoRouteQuery::SegmentDetail>(request_.segmentDetail());
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1079void QDeclarativeGeoRouteQuery::setManeuverDetail(ManeuverDetail maneuverDetail)
1081 if (
static_cast<QGeoRouteRequest::ManeuverDetail>(maneuverDetail) == request_.maneuverDetail())
1083 request_.setManeuverDetail(
static_cast<QGeoRouteRequest::ManeuverDetail>(maneuverDetail));
1085 emit maneuverDetailChanged();
1086 emit queryDetailsChanged();
1090QDeclarativeGeoRouteQuery::ManeuverDetail QDeclarativeGeoRouteQuery::maneuverDetail()
const
1092 return static_cast<QDeclarativeGeoRouteQuery::ManeuverDetail>(request_.maneuverDetail());
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1119QDeclarativeGeoRouteQuery::TravelModes QDeclarativeGeoRouteQuery::travelModes()
const
1121 QGeoRouteRequest::TravelModes reqTravelModes = request_.travelModes();
1122 QDeclarativeGeoRouteQuery::TravelModes travelModes;
1124 if (reqTravelModes & QGeoRouteRequest::CarTravel)
1125 travelModes |= QDeclarativeGeoRouteQuery::CarTravel;
1126 if (reqTravelModes & QGeoRouteRequest::PedestrianTravel)
1127 travelModes |= QDeclarativeGeoRouteQuery::PedestrianTravel;
1128 if (reqTravelModes & QGeoRouteRequest::BicycleTravel)
1129 travelModes |= QDeclarativeGeoRouteQuery::BicycleTravel;
1130 if (reqTravelModes & QGeoRouteRequest::PublicTransitTravel)
1131 travelModes |= QDeclarativeGeoRouteQuery::PublicTransitTravel;
1132 if (reqTravelModes & QGeoRouteRequest::TruckTravel)
1133 travelModes |= QDeclarativeGeoRouteQuery::TruckTravel;
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1160QDeclarativeGeoRouteQuery::RouteOptimizations QDeclarativeGeoRouteQuery::routeOptimizations()
const
1162 QGeoRouteRequest::RouteOptimizations reqOptimizations = request_.routeOptimization();
1163 QDeclarativeGeoRouteQuery::RouteOptimizations optimization;
1165 if (reqOptimizations & QGeoRouteRequest::ShortestRoute)
1166 optimization |= QDeclarativeGeoRouteQuery::ShortestRoute;
1167 if (reqOptimizations & QGeoRouteRequest::FastestRoute)
1168 optimization |= QDeclarativeGeoRouteQuery::FastestRoute;
1169 if (reqOptimizations & QGeoRouteRequest::MostEconomicRoute)
1170 optimization |= QDeclarativeGeoRouteQuery::MostEconomicRoute;
1171 if (reqOptimizations & QGeoRouteRequest::MostScenicRoute)
1172 optimization |= QDeclarativeGeoRouteQuery::MostScenicRoute;
1174 return optimization;
1178
1179
1180
1181
1182
1183
1184
1185void QDeclarativeGeoRouteQuery::setDepartureTime(
const QDateTime &departureTime)
1187 if (departureTime == request_.departureTime())
1190 request_.setDepartureTime(departureTime);
1192 emit departureTimeChanged();
1193 emit queryDetailsChanged();
1197QDateTime QDeclarativeGeoRouteQuery::departureTime()
const
1199 return request_.departureTime();
1202void QDeclarativeGeoRouteQuery::setRouteOptimizations(QDeclarativeGeoRouteQuery::RouteOptimizations optimization)
1204 QGeoRouteRequest::RouteOptimizations reqOptimizations;
1206 if (optimization & QDeclarativeGeoRouteQuery::ShortestRoute)
1207 reqOptimizations |= QGeoRouteRequest::ShortestRoute;
1208 if (optimization & QDeclarativeGeoRouteQuery::FastestRoute)
1209 reqOptimizations |= QGeoRouteRequest::FastestRoute;
1210 if (optimization & QDeclarativeGeoRouteQuery::MostEconomicRoute)
1211 reqOptimizations |= QGeoRouteRequest::MostEconomicRoute;
1212 if (optimization & QDeclarativeGeoRouteQuery::MostScenicRoute)
1213 reqOptimizations |= QGeoRouteRequest::MostScenicRoute;
1215 if (reqOptimizations == request_.routeOptimization())
1218 request_.setRouteOptimization(reqOptimizations);
1221 emit routeOptimizationsChanged();
1222 emit queryDetailsChanged();
1227
1228
1229QGeoRouteRequest QDeclarativeGeoRouteQuery::routeRequest()
const
1231 if (m_waypointsChanged) {
1232 m_waypointsChanged =
false;
1234 request_.setWaypoints(m_waypoints);
1239void QDeclarativeGeoRouteQuery::excludedAreaCoordinateChanged()
1241 if (!m_excludedAreaCoordinateChanged) {
1242 m_excludedAreaCoordinateChanged =
true;
1243 QMetaObject::invokeMethod(
this,
"doCoordinateChanged", Qt::QueuedConnection);
1247void QDeclarativeGeoRouteQuery::waypointChanged()
1249 m_waypointsChanged =
true;
1251 emit waypointsChanged();
1252 emit queryDetailsChanged();
1256void QDeclarativeGeoRouteQuery::doCoordinateChanged()
1258 m_excludedAreaCoordinateChanged =
false;
1260 emit queryDetailsChanged();