8#include <QtCore/QCoreApplication>
9#include <QtQml/QQmlEngine>
10#include <QtQml/qqmlinfo.h>
11#include <QtLocation/QGeoRoutingManager>
12#include <QtPositioning/QGeoRectangle>
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
81
83QDeclarativeGeoRouteModel::QDeclarativeGeoRouteModel(QObject *parent)
84 : QAbstractListModel(parent)
89
90
91
92
93
94
96int QDeclarativeGeoRouteModel::count()
const
98 return routes_.count();
102
103
104
105
106
107
109void QDeclarativeGeoRouteModel::reset()
111 if (!routes_.isEmpty()) {
115 emit routesChanged();
119 emit abortRequested();
120 setError(NoError, QString());
121 setStatus(QDeclarativeGeoRouteModel::Null);
125
126
127
128
129
130void QDeclarativeGeoRouteModel::cancel()
132 emit abortRequested();
133 setError(NoError, QString());
134 setStatus(routes_.isEmpty() ? Null : Ready);
138
139
140
141
142
143
144
145
146
148QGeoRoute QDeclarativeGeoRouteModel::get(
int index)
150 if (index < 0 || index >= routes_.count()) {
151 qmlWarning(
this) << QStringLiteral(
"Index '%1' out of range").arg(index);
154 return routes_.at(index);
158
159
160void QDeclarativeGeoRouteModel::componentComplete()
169
170
171int QDeclarativeGeoRouteModel::rowCount(
const QModelIndex &parent)
const
174 return routes_.count();
178
179
180QVariant QDeclarativeGeoRouteModel::data(
const QModelIndex &index,
int role)
const
182 if (!index.isValid()) {
183 qmlWarning(
this) << QStringLiteral(
"Error in indexing route model's data (invalid index).");
187 if (index.row() >= routes_.count()) {
188 qmlWarning(
this) << QStringLiteral(
"Fatal error in indexing route model's data (index overflow).");
192 if (role == RouteRole)
193 return QVariant::fromValue(routes_.at(index.row()));
197QHash<
int, QByteArray> QDeclarativeGeoRouteModel::roleNames()
const
199 QHash<
int, QByteArray> roleNames = QAbstractListModel::roleNames();
200 roleNames.insert(RouteRole,
"routeData");
205
206
207void QDeclarativeGeoRouteModel::setPlugin(QDeclarativeGeoServiceProvider *plugin)
209 if (plugin_ == plugin)
215 disconnect(plugin_, &QDeclarativeGeoServiceProvider::localesChanged,
216 this, &QDeclarativeGeoRouteModel::measurementSystemChanged);
219 connect(plugin, &QDeclarativeGeoServiceProvider::localesChanged,
220 this, &QDeclarativeGeoRouteModel::measurementSystemChanged);
226 emit pluginChanged();
231 if (plugin_->isAttached()) {
234 connect(plugin_, &QDeclarativeGeoServiceProvider::attached,
235 this, &QDeclarativeGeoRouteModel::pluginReady);
240
241
242void QDeclarativeGeoRouteModel::pluginReady()
244 QGeoServiceProvider *serviceProvider = plugin_->sharedGeoServiceProvider();
245 QGeoRoutingManager *routingManager = serviceProvider->routingManager();
247 if (serviceProvider->routingError() != QGeoServiceProvider::NoError) {
248 QDeclarativeGeoRouteModel::RouteError newError = UnknownError;
249 switch (serviceProvider->routingError()) {
250 case QGeoServiceProvider::NotSupportedError:
251 newError = EngineNotSetError;
break;
252 case QGeoServiceProvider::UnknownParameterError:
253 newError = UnknownParameterError;
break;
254 case QGeoServiceProvider::MissingRequiredParameterError:
255 newError = MissingRequiredParameterError;
break;
256 case QGeoServiceProvider::ConnectionError:
257 newError = CommunicationError;
break;
262 setError(newError, serviceProvider->routingErrorString());
266 if (!routingManager) {
267 setError(EngineNotSetError, tr(
"Plugin does not support routing."));
271 connect(routingManager, &QGeoRoutingManager::finished,
272 this, &QDeclarativeGeoRouteModel::routingFinished);
273 connect(routingManager, &QGeoRoutingManager::errorOccurred,
274 this, &QDeclarativeGeoRouteModel::routingError);
278
279
280void QDeclarativeGeoRouteModel::queryDetailsChanged()
282 if (autoUpdate_ && complete_)
287
288
289
290
291
292
293
294
295
296
297
299QDeclarativeGeoServiceProvider *QDeclarativeGeoRouteModel::plugin()
const
305
306
307void QDeclarativeGeoRouteModel::setQuery(QDeclarativeGeoRouteQuery *query)
309 if (!query || query == routeQuery_)
312 routeQuery_->disconnect(
this);
314 connect(query, &QDeclarativeGeoRouteQuery::queryDetailsChanged,
315 this, &QDeclarativeGeoRouteModel::queryDetailsChanged);
324
325
326
327
328
329
331QDeclarativeGeoRouteQuery *QDeclarativeGeoRouteModel::query()
const
337
338
339void QDeclarativeGeoRouteModel::setAutoUpdate(
bool autoUpdate)
341 if (autoUpdate_ == autoUpdate)
343 autoUpdate_ = autoUpdate;
345 emit autoUpdateChanged();
349
350
351
352
353
354
355
356
357
358
359
360
362bool QDeclarativeGeoRouteModel::autoUpdate()
const
368
369
370
371
372
373
374
375
376
377void QDeclarativeGeoRouteModel::setMeasurementSystem(QLocale::MeasurementSystem ms)
382 QGeoServiceProvider *serviceProvider = plugin_->sharedGeoServiceProvider();
383 if (!serviceProvider)
386 QGeoRoutingManager *routingManager = serviceProvider->routingManager();
390 if (routingManager->measurementSystem() == ms)
393 routingManager->setMeasurementSystem(ms);
394 emit measurementSystemChanged();
397QLocale::MeasurementSystem QDeclarativeGeoRouteModel::measurementSystem()
const
400 return QLocale().measurementSystem();
402 QGeoServiceProvider *serviceProvider = plugin_->sharedGeoServiceProvider();
403 if (!serviceProvider) {
404 if (plugin_->locales().isEmpty())
405 return QLocale().measurementSystem();
407 return QLocale(plugin_->locales().first()).measurementSystem();
410 QGeoRoutingManager *routingManager = serviceProvider->routingManager();
411 if (!routingManager) {
412 if (plugin_->locales().isEmpty())
413 return QLocale().measurementSystem();
415 return QLocale(plugin_->locales().first()).measurementSystem();
418 return routingManager->measurementSystem();
422
423
424void QDeclarativeGeoRouteModel::setStatus(QDeclarativeGeoRouteModel::Status status)
426 if (status_ == status)
432 emit statusChanged();
436
437
438
439
440
441
442
443
444
445
446
448QDeclarativeGeoRouteModel::Status QDeclarativeGeoRouteModel::status()
const
454
455
456
457
458
459
460
461
463QString QDeclarativeGeoRouteModel::errorString()
const
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
487QDeclarativeGeoRouteModel::RouteError QDeclarativeGeoRouteModel::error()
const
492void QDeclarativeGeoRouteModel::setError(RouteError error,
const QString& errorString)
494 if (error_ == error && errorString_ == errorString)
497 errorString_ = errorString;
502
503
504
505
506
507
508void QDeclarativeGeoRouteModel::update()
514 setError(EngineNotSetError, tr(
"Cannot route, plugin not set."));
518 QGeoServiceProvider *serviceProvider = plugin_->sharedGeoServiceProvider();
519 if (!serviceProvider)
522 QGeoRoutingManager *routingManager = serviceProvider->routingManager();
523 if (!routingManager) {
524 setError(EngineNotSetError, tr(
"Cannot route, route manager not set."));
528 setError(ParseError, tr(
"Cannot route, valid query not set."));
531 emit abortRequested();
532 QGeoRouteRequest request = routeQuery_->routeRequest();
533 if (request.waypoints().count() < 2) {
534 setError(ParseError,tr(
"Not enough waypoints for routing."));
538 setError(NoError, QString());
540 QGeoRouteReply *reply = routingManager->calculateRoute(request);
541 setStatus(QDeclarativeGeoRouteModel::Loading);
542 if (!reply->isFinished()) {
543 connect(
this, &QDeclarativeGeoRouteModel::abortRequested, reply, &QGeoRouteReply::abort);
545 if (reply->error() == QGeoRouteReply::NoError) {
546 routingFinished(reply);
548 routingError(reply, reply->error(), reply->errorString());
554
555
556void QDeclarativeGeoRouteModel::routingFinished(QGeoRouteReply *reply)
560 reply->deleteLater();
561 if (reply->error() != QGeoRouteReply::NoError)
565 const int oldCount = routes_.count();
566 routes_ = reply->routes();
569 setError(NoError, QString());
570 setStatus(QDeclarativeGeoRouteModel::Ready);
572 if (oldCount != 0 || routes_.count() != 0)
573 emit routesChanged();
574 if (oldCount != routes_.count())
579
580
581void QDeclarativeGeoRouteModel::routingError(QGeoRouteReply *reply,
582 QGeoRouteReply::Error error,
583 const QString &errorString)
587 reply->deleteLater();
588 setError(
static_cast<QDeclarativeGeoRouteModel::RouteError>(error), errorString);
589 setStatus(QDeclarativeGeoRouteModel::Error);
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
641
643QDeclarativeGeoRouteQuery::QDeclarativeGeoRouteQuery(QObject *parent)
648QDeclarativeGeoRouteQuery::QDeclarativeGeoRouteQuery(
const QGeoRouteRequest &request, QObject *parent)
649 : QObject(parent), request_(request)
653 m_waypoints = request_.waypoints();
656QDeclarativeGeoRouteQuery::~QDeclarativeGeoRouteQuery()
661
662
663void QDeclarativeGeoRouteQuery::componentComplete()
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
690QList<
int> QDeclarativeGeoRouteQuery::featureTypes()
const
694 const auto featureTypes = request_.featureTypes();
695 for (
const auto &featureType : featureTypes)
696 list.append(
static_cast<
int>(featureType));
701
702
703
704
705
708int QDeclarativeGeoRouteQuery::numberAlternativeRoutes()
const
710 return request_.numberAlternativeRoutes();
713void QDeclarativeGeoRouteQuery::setNumberAlternativeRoutes(
int numberAlternativeRoutes)
715 if (numberAlternativeRoutes == request_.numberAlternativeRoutes())
718 request_.setNumberAlternativeRoutes(numberAlternativeRoutes);
721 emit numberAlternativeRoutesChanged();
722 emit queryDetailsChanged();
727
728
729
730
731
732
733
734
735
736
737
739QList<QGeoCoordinate> QDeclarativeGeoRouteQuery::waypoints()
const
744void QDeclarativeGeoRouteQuery::setWaypoints(
const QList<QGeoCoordinate> &value)
746 if (m_waypoints == value)
754
755
756
757
758
759
760
761
762
763QList<QGeoRectangle> QDeclarativeGeoRouteQuery::excludedAreas()
const
765 return request_.excludeAreas();
768void QDeclarativeGeoRouteQuery::setExcludedAreas(
const QList<QGeoRectangle> &value)
770 if (request_.excludeAreas() == value)
773 request_.setExcludeAreas(value);
776 emit excludedAreasChanged();
777 emit queryDetailsChanged();
782
783
784
785
786
787
788
789
792void QDeclarativeGeoRouteQuery::addExcludedArea(
const QGeoRectangle &area)
797 QList<QGeoRectangle> excludedAreas = request_.excludeAreas();
799 if (excludedAreas.contains(area))
802 excludedAreas.append(area);
804 request_.setExcludeAreas(excludedAreas);
807 emit excludedAreasChanged();
808 emit queryDetailsChanged();
813
814
815
816
817
818
820void QDeclarativeGeoRouteQuery::removeExcludedArea(
const QGeoRectangle &area)
825 QList<QGeoRectangle> excludedAreas = request_.excludeAreas();
827 int index = excludedAreas.lastIndexOf(area);
829 qmlWarning(
this) << QStringLiteral(
"Cannot remove nonexistent area.");
832 excludedAreas.removeAt(index);
833 request_.setExcludeAreas(excludedAreas);
836 emit excludedAreasChanged();
837 emit queryDetailsChanged();
842
843
844
845
846
847
849void QDeclarativeGeoRouteQuery::clearExcludedAreas()
851 if (request_.excludeAreas().isEmpty())
854 request_.setExcludeAreas(QList<QGeoRectangle>());
857 emit excludedAreasChanged();
858 emit queryDetailsChanged();
863
864
865
866
867
868
869
870void QDeclarativeGeoRouteQuery::addWaypoint(
const QGeoCoordinate &waypoint)
872 if (!waypoint.isValid()) {
873 qmlWarning(
this) << QStringLiteral(
"Invalid coordinate as waypoint");
877 m_waypoints << waypoint;
882
883
884
885
886
887
888
889
890void QDeclarativeGeoRouteQuery::removeWaypoint(
const QGeoCoordinate &waypoint)
892 if (!waypoint.isValid()) {
893 qmlWarning(
this) << QStringLiteral(
"Invalid coordinate as waypoint");
897 if (qsizetype idx = m_waypoints.lastIndexOf(waypoint); idx >= 0) {
898 m_waypoints.remove(idx);
901 qmlWarning(
this) << QStringLiteral(
"Cannot remove nonexistent waypoint.");
906
907
908
909
910
911
912void QDeclarativeGeoRouteQuery::clearWaypoints()
914 if (m_waypoints.isEmpty())
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
950
952void QDeclarativeGeoRouteQuery::setFeatureWeight(FeatureType featureType, FeatureWeight featureWeight)
954 if (featureType == NoFeature && !request_.featureTypes().isEmpty()) {
955 resetFeatureWeights();
960 FeatureWeight originalWeight =
static_cast<FeatureWeight>(request_.featureWeight(
static_cast<QGeoRouteRequest::FeatureType>(featureType)));
961 if (featureWeight == originalWeight)
964 request_.setFeatureWeight(
static_cast<QGeoRouteRequest::FeatureType>(featureType),
965 static_cast<QGeoRouteRequest::FeatureWeight>(featureWeight));
966 if (complete_ && ((originalWeight == NeutralFeatureWeight) || (featureWeight == NeutralFeatureWeight))) {
969 emit featureTypesChanged();
970 emit queryDetailsChanged();
975
976
977
978
979
980
981void QDeclarativeGeoRouteQuery::resetFeatureWeights()
984 const auto featureTypes = request_.featureTypes();
985 for (
const auto &featureType : featureTypes)
986 request_.setFeatureWeight(featureType, QGeoRouteRequest::NeutralFeatureWeight);
988 emit featureTypesChanged();
989 emit queryDetailsChanged();
994
995
996
997
998
999
1001int QDeclarativeGeoRouteQuery::featureWeight(FeatureType featureType)
1003 return request_.featureWeight(
static_cast<QGeoRouteRequest::FeatureType>(featureType));
1007
1008
1009void QDeclarativeGeoRouteQuery::setTravelModes(QDeclarativeGeoRouteQuery::TravelModes travelModes)
1011 QGeoRouteRequest::TravelModes reqTravelModes;
1013 if (travelModes & QDeclarativeGeoRouteQuery::CarTravel)
1014 reqTravelModes |= QGeoRouteRequest::CarTravel;
1015 if (travelModes & QDeclarativeGeoRouteQuery::PedestrianTravel)
1016 reqTravelModes |= QGeoRouteRequest::PedestrianTravel;
1017 if (travelModes & QDeclarativeGeoRouteQuery::BicycleTravel)
1018 reqTravelModes |= QGeoRouteRequest::BicycleTravel;
1019 if (travelModes & QDeclarativeGeoRouteQuery::PublicTransitTravel)
1020 reqTravelModes |= QGeoRouteRequest::PublicTransitTravel;
1021 if (travelModes & QDeclarativeGeoRouteQuery::TruckTravel)
1022 reqTravelModes |= QGeoRouteRequest::TruckTravel;
1024 if (reqTravelModes == request_.travelModes())
1027 request_.setTravelModes(reqTravelModes);
1030 emit travelModesChanged();
1031 emit queryDetailsChanged();
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1050void QDeclarativeGeoRouteQuery::setSegmentDetail(SegmentDetail segmentDetail)
1052 if (
static_cast<QGeoRouteRequest::SegmentDetail>(segmentDetail) == request_.segmentDetail())
1054 request_.setSegmentDetail(
static_cast<QGeoRouteRequest::SegmentDetail>(segmentDetail));
1056 emit segmentDetailChanged();
1057 emit queryDetailsChanged();
1061QDeclarativeGeoRouteQuery::SegmentDetail QDeclarativeGeoRouteQuery::segmentDetail()
const
1063 return static_cast<QDeclarativeGeoRouteQuery::SegmentDetail>(request_.segmentDetail());
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1080void QDeclarativeGeoRouteQuery::setManeuverDetail(ManeuverDetail maneuverDetail)
1082 if (
static_cast<QGeoRouteRequest::ManeuverDetail>(maneuverDetail) == request_.maneuverDetail())
1084 request_.setManeuverDetail(
static_cast<QGeoRouteRequest::ManeuverDetail>(maneuverDetail));
1086 emit maneuverDetailChanged();
1087 emit queryDetailsChanged();
1091QDeclarativeGeoRouteQuery::ManeuverDetail QDeclarativeGeoRouteQuery::maneuverDetail()
const
1093 return static_cast<QDeclarativeGeoRouteQuery::ManeuverDetail>(request_.maneuverDetail());
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1120QDeclarativeGeoRouteQuery::TravelModes QDeclarativeGeoRouteQuery::travelModes()
const
1122 QGeoRouteRequest::TravelModes reqTravelModes = request_.travelModes();
1123 QDeclarativeGeoRouteQuery::TravelModes travelModes;
1125 if (reqTravelModes & QGeoRouteRequest::CarTravel)
1126 travelModes |= QDeclarativeGeoRouteQuery::CarTravel;
1127 if (reqTravelModes & QGeoRouteRequest::PedestrianTravel)
1128 travelModes |= QDeclarativeGeoRouteQuery::PedestrianTravel;
1129 if (reqTravelModes & QGeoRouteRequest::BicycleTravel)
1130 travelModes |= QDeclarativeGeoRouteQuery::BicycleTravel;
1131 if (reqTravelModes & QGeoRouteRequest::PublicTransitTravel)
1132 travelModes |= QDeclarativeGeoRouteQuery::PublicTransitTravel;
1133 if (reqTravelModes & QGeoRouteRequest::TruckTravel)
1134 travelModes |= QDeclarativeGeoRouteQuery::TruckTravel;
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1161QDeclarativeGeoRouteQuery::RouteOptimizations QDeclarativeGeoRouteQuery::routeOptimizations()
const
1163 QGeoRouteRequest::RouteOptimizations reqOptimizations = request_.routeOptimization();
1164 QDeclarativeGeoRouteQuery::RouteOptimizations optimization;
1166 if (reqOptimizations & QGeoRouteRequest::ShortestRoute)
1167 optimization |= QDeclarativeGeoRouteQuery::ShortestRoute;
1168 if (reqOptimizations & QGeoRouteRequest::FastestRoute)
1169 optimization |= QDeclarativeGeoRouteQuery::FastestRoute;
1170 if (reqOptimizations & QGeoRouteRequest::MostEconomicRoute)
1171 optimization |= QDeclarativeGeoRouteQuery::MostEconomicRoute;
1172 if (reqOptimizations & QGeoRouteRequest::MostScenicRoute)
1173 optimization |= QDeclarativeGeoRouteQuery::MostScenicRoute;
1175 return optimization;
1179
1180
1181
1182
1183
1184
1185
1186void QDeclarativeGeoRouteQuery::setDepartureTime(
const QDateTime &departureTime)
1188 if (departureTime == request_.departureTime())
1191 request_.setDepartureTime(departureTime);
1193 emit departureTimeChanged();
1194 emit queryDetailsChanged();
1198QDateTime QDeclarativeGeoRouteQuery::departureTime()
const
1200 return request_.departureTime();
1203void QDeclarativeGeoRouteQuery::setRouteOptimizations(QDeclarativeGeoRouteQuery::RouteOptimizations optimization)
1205 QGeoRouteRequest::RouteOptimizations reqOptimizations;
1207 if (optimization & QDeclarativeGeoRouteQuery::ShortestRoute)
1208 reqOptimizations |= QGeoRouteRequest::ShortestRoute;
1209 if (optimization & QDeclarativeGeoRouteQuery::FastestRoute)
1210 reqOptimizations |= QGeoRouteRequest::FastestRoute;
1211 if (optimization & QDeclarativeGeoRouteQuery::MostEconomicRoute)
1212 reqOptimizations |= QGeoRouteRequest::MostEconomicRoute;
1213 if (optimization & QDeclarativeGeoRouteQuery::MostScenicRoute)
1214 reqOptimizations |= QGeoRouteRequest::MostScenicRoute;
1216 if (reqOptimizations == request_.routeOptimization())
1219 request_.setRouteOptimization(reqOptimizations);
1222 emit routeOptimizationsChanged();
1223 emit queryDetailsChanged();
1228
1229
1230QGeoRouteRequest QDeclarativeGeoRouteQuery::routeRequest()
const
1232 if (m_waypointsChanged) {
1233 m_waypointsChanged =
false;
1235 request_.setWaypoints(m_waypoints);
1240void QDeclarativeGeoRouteQuery::excludedAreaCoordinateChanged()
1242 if (!m_excludedAreaCoordinateChanged) {
1243 m_excludedAreaCoordinateChanged =
true;
1244 QMetaObject::invokeMethod(
this,
"doCoordinateChanged", Qt::QueuedConnection);
1248void QDeclarativeGeoRouteQuery::waypointChanged()
1250 m_waypointsChanged =
true;
1252 emit waypointsChanged();
1253 emit queryDetailsChanged();
1257void QDeclarativeGeoRouteQuery::doCoordinateChanged()
1259 m_excludedAreaCoordinateChanged =
false;
1261 emit queryDetailsChanged();
Combined button and popup list for selecting options.