23static QList<QGeoCoordinate> decodePolyline(
const QString &polylineString)
25 QList<QGeoCoordinate> path;
26 if (polylineString.isEmpty())
29 const QByteArray data = polylineString.toLatin1();
31 bool parsingLatitude =
true;
36 QGeoCoordinate coord(0, 0);
38 for (qsizetype i = 0; i < data.length(); ++i) {
39 unsigned char c = data.at(i) - 63;
41 value |= (c & 0x1f) << shift;
48 int diff = (value & 1) ? ~(value >> 1) : (value >> 1);
50 if (parsingLatitude) {
51 coord.setLatitude(coord.latitude() + (
double)diff/1e6);
53 coord.setLongitude(coord.longitude() + (
double)diff/1e6);
57 parsingLatitude = !parsingLatitude;
69 case QLocationUtils::CardinalN:
72 return QGeoRouteParserOsrmV5::tr(
"North");
73 case QLocationUtils::CardinalE:
74 return QGeoRouteParserOsrmV5::tr(
"East");
75 case QLocationUtils::CardinalS:
76 return QGeoRouteParserOsrmV5::tr(
"South");
77 case QLocationUtils::CardinalW:
78 return QGeoRouteParserOsrmV5::tr(
"West");
86 static QList<QString> ordinals;
88 if (!ordinals.size()) {
89 ordinals.append(QLatin1String(
""));
91 ordinals.append(QGeoRouteParserOsrmV5::tr(
"first",
"roundabout exit"));
92 ordinals.append(QGeoRouteParserOsrmV5::tr(
"second",
"roundabout exit"));
93 ordinals.append(QGeoRouteParserOsrmV5::tr(
"third",
"roundabout exit"));
94 ordinals.append(QGeoRouteParserOsrmV5::tr(
"fourth",
"roundabout exit"));
95 ordinals.append(QGeoRouteParserOsrmV5::tr(
"fifth",
"roundabout exit"));
96 ordinals.append(QGeoRouteParserOsrmV5::tr(
"sixth",
"roundabout exit"));
97 ordinals.append(QGeoRouteParserOsrmV5::tr(
"seventh",
"roundabout exit"));
98 ordinals.append(QGeoRouteParserOsrmV5::tr(
"eighth",
"roundabout exit"));
99 ordinals.append(QGeoRouteParserOsrmV5::tr(
"ninth",
"roundabout exit"));
100 ordinals.append(QGeoRouteParserOsrmV5::tr(
"tenth",
"roundabout exit"));
101 ordinals.append(QGeoRouteParserOsrmV5::tr(
"eleventh",
"roundabout exit"));
102 ordinals.append(QGeoRouteParserOsrmV5::tr(
"twelfth",
"roundabout exit"));
103 ordinals.append(QGeoRouteParserOsrmV5::tr(
"thirteenth",
"roundabout exit"));
104 ordinals.append(QGeoRouteParserOsrmV5::tr(
"fourteenth",
"roundabout exit"));
105 ordinals.append(QGeoRouteParserOsrmV5::tr(
"fifteenth",
"roundabout exit"));
106 ordinals.append(QGeoRouteParserOsrmV5::tr(
"sixteenth",
"roundabout exit"));
107 ordinals.append(QGeoRouteParserOsrmV5::tr(
"seventeenth",
"roundabout exit"));
108 ordinals.append(QGeoRouteParserOsrmV5::tr(
"eighteenth",
"roundabout exit"));
109 ordinals.append(QGeoRouteParserOsrmV5::tr(
"nineteenth",
"roundabout exit"));
110 ordinals.append(QGeoRouteParserOsrmV5::tr(
"twentieth",
"roundabout exit"));
113 if (exit < 1 || exit > ordinals.size())
115 return ordinals[exit];
139 case QGeoManeuver::DirectionForward:
140 return QGeoRouteParserOsrmV5::tr(
"You have arrived at your destination, straight ahead");
141 case QGeoManeuver::DirectionUTurnLeft:
142 case QGeoManeuver::DirectionHardLeft:
143 case QGeoManeuver::DirectionLeft:
144 case QGeoManeuver::DirectionLightLeft:
145 case QGeoManeuver::DirectionBearLeft:
146 return QGeoRouteParserOsrmV5::tr(
"You have arrived at your destination, on the left");
147 case QGeoManeuver::DirectionUTurnRight:
148 case QGeoManeuver::DirectionHardRight:
149 case QGeoManeuver::DirectionRight:
150 case QGeoManeuver::DirectionLightRight:
151 case QGeoManeuver::DirectionBearRight:
152 return QGeoRouteParserOsrmV5::tr(
"You have arrived at your destination, on the right");
154 return QGeoRouteParserOsrmV5::tr(
"You have arrived at your destination");
161 case QGeoManeuver::DirectionForward:
162 if (wayName.isEmpty())
163 return QGeoRouteParserOsrmV5::tr(
"Continue straight");
165 return QGeoRouteParserOsrmV5::tr(
"Continue straight on %1").arg(wayName);
166 case QGeoManeuver::DirectionHardLeft:
167 case QGeoManeuver::DirectionLeft:
168 if (wayName.isEmpty())
169 return QGeoRouteParserOsrmV5::tr(
"Continue left");
171 return QGeoRouteParserOsrmV5::tr(
"Continue left onto %1").arg(wayName);
172 case QGeoManeuver::DirectionLightLeft:
173 case QGeoManeuver::DirectionBearLeft:
174 if (wayName.isEmpty())
175 return QGeoRouteParserOsrmV5::tr(
"Continue slightly left");
177 return QGeoRouteParserOsrmV5::tr(
"Continue slightly left on %1").arg(wayName);
178 case QGeoManeuver::DirectionHardRight:
179 case QGeoManeuver::DirectionRight:
180 if (wayName.isEmpty())
181 return QGeoRouteParserOsrmV5::tr(
"Continue right");
183 return QGeoRouteParserOsrmV5::tr(
"Continue right onto %1").arg(wayName);
184 case QGeoManeuver::DirectionLightRight:
185 case QGeoManeuver::DirectionBearRight:
186 if (wayName.isEmpty())
187 return QGeoRouteParserOsrmV5::tr(
"Continue slightly right");
189 return QGeoRouteParserOsrmV5::tr(
"Continue slightly right on %1").arg(wayName);
190 case QGeoManeuver::DirectionUTurnLeft:
191 case QGeoManeuver::DirectionUTurnRight:
192 if (wayName.isEmpty())
193 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn");
195 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn onto %1").arg(wayName);
197 if (wayName.isEmpty())
198 return QGeoRouteParserOsrmV5::tr(
"Continue");
200 return QGeoRouteParserOsrmV5::tr(
"Continue on %1").arg(wayName);
224 case QGeoManeuver::DirectionHardLeft:
225 case QGeoManeuver::DirectionLeft:
226 case QGeoManeuver::DirectionLightLeft:
227 case QGeoManeuver::DirectionBearLeft:
228 if (wayName.isEmpty())
229 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, turn left");
231 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, turn left onto %1").arg(wayName);
232 case QGeoManeuver::DirectionHardRight:
233 case QGeoManeuver::DirectionRight:
234 case QGeoManeuver::DirectionLightRight:
235 case QGeoManeuver::DirectionBearRight:
236 if (wayName.isEmpty())
237 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, turn right");
239 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, turn right onto %1").arg(wayName);
240 case QGeoManeuver::DirectionUTurnLeft:
241 case QGeoManeuver::DirectionUTurnRight:
242 if (wayName.isEmpty())
243 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, make a U-turn");
245 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, make a U-turn onto %1").arg(wayName);
246 case QGeoManeuver::DirectionForward:
247 if (wayName.isEmpty())
248 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, continue straight");
250 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, continue straight onto %1").arg(wayName);
252 if (wayName.isEmpty())
253 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, continue");
255 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, continue onto %1").arg(wayName);
268static QString
instructionFork(
const QString &wayName, QGeoManeuver::InstructionDirection direction)
271 case QGeoManeuver::DirectionHardLeft:
272 if (wayName.isEmpty())
273 return QGeoRouteParserOsrmV5::tr(
"At the fork, take a sharp left");
275 return QGeoRouteParserOsrmV5::tr(
"At the fork, take a sharp left onto %1").arg(wayName);
276 case QGeoManeuver::DirectionLeft:
277 if (wayName.isEmpty())
278 return QGeoRouteParserOsrmV5::tr(
"At the fork, turn left");
280 return QGeoRouteParserOsrmV5::tr(
"At the fork, turn left onto %1").arg(wayName);
281 case QGeoManeuver::DirectionLightLeft:
282 case QGeoManeuver::DirectionBearLeft:
283 if (wayName.isEmpty())
284 return QGeoRouteParserOsrmV5::tr(
"At the fork, keep left");
286 return QGeoRouteParserOsrmV5::tr(
"At the fork, keep left onto %1").arg(wayName);
287 case QGeoManeuver::DirectionHardRight:
288 if (wayName.isEmpty())
289 return QGeoRouteParserOsrmV5::tr(
"At the fork, take a sharp right");
291 return QGeoRouteParserOsrmV5::tr(
"At the fork, take a sharp right onto %1").arg(wayName);
292 case QGeoManeuver::DirectionRight:
293 if (wayName.isEmpty())
294 return QGeoRouteParserOsrmV5::tr(
"At the fork, turn right");
296 return QGeoRouteParserOsrmV5::tr(
"At the fork, turn right onto %1").arg(wayName);
297 case QGeoManeuver::DirectionLightRight:
298 case QGeoManeuver::DirectionBearRight:
299 if (wayName.isEmpty())
300 return QGeoRouteParserOsrmV5::tr(
"At the fork, keep right");
302 return QGeoRouteParserOsrmV5::tr(
"At the fork, keep right onto %1").arg(wayName);
303 case QGeoManeuver::DirectionUTurnLeft:
304 case QGeoManeuver::DirectionUTurnRight:
305 if (wayName.isEmpty())
306 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn");
308 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn onto %1").arg(wayName);
309 case QGeoManeuver::DirectionForward:
310 if (wayName.isEmpty())
311 return QGeoRouteParserOsrmV5::tr(
"At the fork, continue straight ahead");
313 return QGeoRouteParserOsrmV5::tr(
"At the fork, continue straight ahead onto %1").arg(wayName);
315 if (wayName.isEmpty())
316 return QGeoRouteParserOsrmV5::tr(
"At the fork, continue");
318 return QGeoRouteParserOsrmV5::tr(
"At the fork, continue onto %1").arg(wayName);
322static QString
instructionMerge(
const QString &wayName, QGeoManeuver::InstructionDirection direction)
325 case QGeoManeuver::DirectionUTurnLeft:
326 case QGeoManeuver::DirectionHardLeft:
327 if (wayName.isEmpty())
328 return QGeoRouteParserOsrmV5::tr(
"Merge sharply left");
330 return QGeoRouteParserOsrmV5::tr(
"Merge sharply left onto %1").arg(wayName);
331 case QGeoManeuver::DirectionLeft:
332 if (wayName.isEmpty())
333 return QGeoRouteParserOsrmV5::tr(
"Merge left");
335 return QGeoRouteParserOsrmV5::tr(
"Merge left onto %1").arg(wayName);
336 case QGeoManeuver::DirectionLightLeft:
337 case QGeoManeuver::DirectionBearLeft:
338 if (wayName.isEmpty())
339 return QGeoRouteParserOsrmV5::tr(
"Merge slightly left");
341 return QGeoRouteParserOsrmV5::tr(
"Merge slightly left on %1").arg(wayName);
342 case QGeoManeuver::DirectionUTurnRight:
343 case QGeoManeuver::DirectionHardRight:
344 if (wayName.isEmpty())
345 return QGeoRouteParserOsrmV5::tr(
"Merge sharply right");
347 return QGeoRouteParserOsrmV5::tr(
"Merge sharply right onto %1").arg(wayName);
348 case QGeoManeuver::DirectionRight:
349 if (wayName.isEmpty())
350 return QGeoRouteParserOsrmV5::tr(
"Merge right");
352 return QGeoRouteParserOsrmV5::tr(
"Merge right onto %1").arg(wayName);
353 case QGeoManeuver::DirectionLightRight:
354 case QGeoManeuver::DirectionBearRight:
355 if (wayName.isEmpty())
356 return QGeoRouteParserOsrmV5::tr(
"Merge slightly right");
358 return QGeoRouteParserOsrmV5::tr(
"Merge slightly right on %1").arg(wayName);
359 case QGeoManeuver::DirectionForward:
360 if (wayName.isEmpty())
361 return QGeoRouteParserOsrmV5::tr(
"Merge straight");
363 return QGeoRouteParserOsrmV5::tr(
"Merge straight on %1").arg(wayName);
365 if (wayName.isEmpty())
366 return QGeoRouteParserOsrmV5::tr(
"Merge");
368 return QGeoRouteParserOsrmV5::tr(
"Merge onto %1").arg(wayName);
372static QString
instructionNewName(
const QString &wayName, QGeoManeuver::InstructionDirection direction)
375 case QGeoManeuver::DirectionHardLeft:
376 if (wayName.isEmpty())
377 return QGeoRouteParserOsrmV5::tr(
"Take a sharp left");
379 return QGeoRouteParserOsrmV5::tr(
"Take a sharp left onto %1").arg(wayName);
380 case QGeoManeuver::DirectionLeft:
381 if (wayName.isEmpty())
382 return QGeoRouteParserOsrmV5::tr(
"Turn left");
384 return QGeoRouteParserOsrmV5::tr(
"Turn left onto %1").arg(wayName);
385 case QGeoManeuver::DirectionLightLeft:
386 case QGeoManeuver::DirectionBearLeft:
387 if (wayName.isEmpty())
388 return QGeoRouteParserOsrmV5::tr(
"Continue slightly left");
390 return QGeoRouteParserOsrmV5::tr(
"Continue slightly left onto %1").arg(wayName);
391 case QGeoManeuver::DirectionHardRight:
392 if (wayName.isEmpty())
393 return QGeoRouteParserOsrmV5::tr(
"Take a sharp right");
395 return QGeoRouteParserOsrmV5::tr(
"Take a sharp right onto %1").arg(wayName);
396 case QGeoManeuver::DirectionRight:
397 if (wayName.isEmpty())
398 return QGeoRouteParserOsrmV5::tr(
"Turn right");
400 return QGeoRouteParserOsrmV5::tr(
"Turn right onto %1").arg(wayName);
401 case QGeoManeuver::DirectionLightRight:
402 case QGeoManeuver::DirectionBearRight:
403 if (wayName.isEmpty())
404 return QGeoRouteParserOsrmV5::tr(
"Continue slightly right");
406 return QGeoRouteParserOsrmV5::tr(
"Continue slightly right onto %1").arg(wayName);
407 case QGeoManeuver::DirectionUTurnLeft:
408 case QGeoManeuver::DirectionUTurnRight:
409 if (wayName.isEmpty())
410 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn");
412 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn onto %1").arg(wayName);
413 case QGeoManeuver::DirectionForward:
414 if (wayName.isEmpty())
415 return QGeoRouteParserOsrmV5::tr(
"Continue straight");
417 return QGeoRouteParserOsrmV5::tr(
"Continue straight onto %1").arg(wayName);
419 if (wayName.isEmpty())
420 return QGeoRouteParserOsrmV5::tr(
"Continue");
422 return QGeoRouteParserOsrmV5::tr(
"Continue onto %1").arg(wayName);
429 case QGeoManeuver::DirectionUTurnLeft:
430 case QGeoManeuver::DirectionHardLeft:
431 case QGeoManeuver::DirectionLeft:
432 case QGeoManeuver::DirectionLightLeft:
433 case QGeoManeuver::DirectionBearLeft:
434 if (wayName.isEmpty())
435 return QGeoRouteParserOsrmV5::tr(
"Continue on the left");
437 return QGeoRouteParserOsrmV5::tr(
"Continue on the left on %1").arg(wayName);
438 case QGeoManeuver::DirectionUTurnRight:
439 case QGeoManeuver::DirectionHardRight:
440 case QGeoManeuver::DirectionRight:
441 case QGeoManeuver::DirectionLightRight:
442 case QGeoManeuver::DirectionBearRight:
443 if (wayName.isEmpty())
444 return QGeoRouteParserOsrmV5::tr(
"Continue on the right");
446 return QGeoRouteParserOsrmV5::tr(
"Continue on the right on %1").arg(wayName);
447 case QGeoManeuver::DirectionForward:
449 if (wayName.isEmpty())
450 return QGeoRouteParserOsrmV5::tr(
"Continue");
452 return QGeoRouteParserOsrmV5::tr(
"Continue on %1").arg(wayName);
456static QString
instructionOffRamp(
const QString &wayName, QGeoManeuver::InstructionDirection direction)
459 case QGeoManeuver::DirectionUTurnLeft:
460 case QGeoManeuver::DirectionHardLeft:
461 case QGeoManeuver::DirectionLeft:
462 case QGeoManeuver::DirectionLightLeft:
463 case QGeoManeuver::DirectionBearLeft:
464 if (wayName.isEmpty())
465 return QGeoRouteParserOsrmV5::tr(
"Take the ramp on the left");
467 return QGeoRouteParserOsrmV5::tr(
"Take the ramp on the left onto %1").arg(wayName);
468 case QGeoManeuver::DirectionUTurnRight:
469 case QGeoManeuver::DirectionHardRight:
470 case QGeoManeuver::DirectionRight:
471 case QGeoManeuver::DirectionLightRight:
472 case QGeoManeuver::DirectionBearRight:
473 if (wayName.isEmpty())
474 return QGeoRouteParserOsrmV5::tr(
"Take the ramp on the right");
476 return QGeoRouteParserOsrmV5::tr(
"Take the ramp on the right onto %1").arg(wayName);
477 case QGeoManeuver::DirectionForward:
479 if (wayName.isEmpty())
480 return QGeoRouteParserOsrmV5::tr(
"Take the ramp");
482 return QGeoRouteParserOsrmV5::tr(
"Take the ramp onto %1").arg(wayName);
529 case QGeoManeuver::DirectionForward:
530 if (wayName.isEmpty())
531 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, continue straight");
533 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, continue straight on %1").arg(wayName);
534 case QGeoManeuver::DirectionHardLeft:
535 case QGeoManeuver::DirectionLeft:
536 case QGeoManeuver::DirectionLightLeft:
537 case QGeoManeuver::DirectionBearLeft:
538 if (wayName.isEmpty())
539 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn left");
541 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn left onto %1").arg(wayName);
542 case QGeoManeuver::DirectionHardRight:
543 case QGeoManeuver::DirectionRight:
544 case QGeoManeuver::DirectionLightRight:
545 case QGeoManeuver::DirectionBearRight:
546 if (wayName.isEmpty())
547 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn right");
549 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn right onto %1").arg(wayName);
550 case QGeoManeuver::DirectionUTurnLeft:
551 case QGeoManeuver::DirectionUTurnRight:
552 if (wayName.isEmpty())
553 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn around");
555 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn around onto %1").arg(wayName);
557 if (wayName.isEmpty())
558 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, continue");
560 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, continue onto %1").arg(wayName);
571static QString
instructionTurn(
const QString &wayName, QGeoManeuver::InstructionDirection direction)
574 case QGeoManeuver::DirectionForward:
575 if (wayName.isEmpty())
576 return QGeoRouteParserOsrmV5::tr(
"Go straight");
578 return QGeoRouteParserOsrmV5::tr(
"Go straight onto %1").arg(wayName);
579 case QGeoManeuver::DirectionHardLeft:
580 case QGeoManeuver::DirectionLeft:
581 if (wayName.isEmpty())
582 return QGeoRouteParserOsrmV5::tr(
"Turn left");
584 return QGeoRouteParserOsrmV5::tr(
"Turn left onto %1").arg(wayName);
585 case QGeoManeuver::DirectionLightLeft:
586 case QGeoManeuver::DirectionBearLeft:
587 if (wayName.isEmpty())
588 return QGeoRouteParserOsrmV5::tr(
"Turn slightly left");
590 return QGeoRouteParserOsrmV5::tr(
"Turn slightly left onto %1").arg(wayName);
591 case QGeoManeuver::DirectionHardRight:
592 case QGeoManeuver::DirectionRight:
593 if (wayName.isEmpty())
594 return QGeoRouteParserOsrmV5::tr(
"Turn right");
596 return QGeoRouteParserOsrmV5::tr(
"Turn right onto %1").arg(wayName);
597 case QGeoManeuver::DirectionLightRight:
598 case QGeoManeuver::DirectionBearRight:
599 if (wayName.isEmpty())
600 return QGeoRouteParserOsrmV5::tr(
"Turn slightly right");
602 return QGeoRouteParserOsrmV5::tr(
"Turn slightly right onto %1").arg(wayName);
603 case QGeoManeuver::DirectionUTurnLeft:
604 case QGeoManeuver::DirectionUTurnRight:
605 if (wayName.isEmpty())
606 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn");
608 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn onto %1").arg(wayName);
610 if (wayName.isEmpty())
611 return QGeoRouteParserOsrmV5::tr(
"Turn");
613 return QGeoRouteParserOsrmV5::tr(
"Turn onto %1").arg(wayName);
617static QString
instructionUseLane(
const QJsonObject &maneuver,
const QString &wayName, QGeoManeuver::InstructionDirection direction)
619 QString laneTypes = maneuver.value(QLatin1String(
"laneTypes")).toString();
620 QString laneInstruction;
621 if (laneTypes == QLatin1String(
"xo") || laneTypes == QLatin1String(
"xoo") || laneTypes == QLatin1String(
"xxo"))
623 laneInstruction = QLatin1String(
"Keep right");
624 else if (laneTypes == QLatin1String(
"ox") || laneTypes == QLatin1String(
"oox") || laneTypes == QLatin1String(
"oxx"))
625 laneInstruction = QLatin1String(
"Keep left");
626 else if (laneTypes == QLatin1String(
"xox"))
627 laneInstruction = QLatin1String(
"Use the middle lane");
628 else if (laneTypes == QLatin1String(
"oxo"))
629 laneInstruction = QLatin1String(
"Use the left or the right lane");
631 if (laneInstruction.isEmpty()) {
632 if (wayName.isEmpty())
633 return QGeoRouteParserOsrmV5::tr(
"Continue straight");
635 return QGeoRouteParserOsrmV5::tr(
"Continue straight onto %1").arg(wayName);
639 case QGeoManeuver::DirectionForward:
640 if (wayName.isEmpty())
642 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and continue straight");
644 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and continue straight onto %1").arg(wayName);
645 case QGeoManeuver::DirectionHardLeft:
646 if (wayName.isEmpty())
647 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a sharp left");
649 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a sharp left onto %1").arg(wayName);
650 case QGeoManeuver::DirectionLeft:
651 if (wayName.isEmpty())
652 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and turn left");
654 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and turn left onto %1").arg(wayName);
655 case QGeoManeuver::DirectionLightLeft:
656 case QGeoManeuver::DirectionBearLeft:
657 if (wayName.isEmpty())
658 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a slight left");
660 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a slight left onto %1").arg(wayName);
661 case QGeoManeuver::DirectionHardRight:
662 if (wayName.isEmpty())
663 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a sharp right");
665 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a sharp right onto %1").arg(wayName);
666 case QGeoManeuver::DirectionRight:
667 if (wayName.isEmpty())
668 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and turn right");
670 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and turn right onto %1").arg(wayName);
671 case QGeoManeuver::DirectionLightRight:
672 case QGeoManeuver::DirectionBearRight:
673 if (wayName.isEmpty())
674 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a slight right");
676 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a slight right onto %1").arg(wayName);
677 case QGeoManeuver::DirectionUTurnLeft:
678 case QGeoManeuver::DirectionUTurnRight:
679 if (wayName.isEmpty())
680 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a U-turn");
682 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a U-turn onto %1").arg(wayName);
684 return laneInstruction;
688static QString
instructionText(
const QJsonObject &step,
const QJsonObject &maneuver, QGeoManeuver::InstructionDirection direction) {
690 if (maneuver.value(QLatin1String(
"modifier")).isString())
691 modifier = maneuver.value(QLatin1String(
"modifier")).toString();
692 QString maneuverType;
693 if (maneuver.value(QLatin1String(
"type")).isString())
694 maneuverType = maneuver.value(QLatin1String(
"type")).toString();
695 QString wayName = QLatin1String(
"unknown street");
696 if (step.value(QLatin1String(
"name")).isString())
697 wayName = step.value(QLatin1String(
"name")).toString();
700 if (maneuverType == QLatin1String(
"arrive"))
701 return instructionArrive(direction);
702 else if (maneuverType == QLatin1String(
"continue"))
703 return instructionContinue(wayName, direction);
704 else if (maneuverType == QLatin1String(
"depart"))
705 return instructionDepart(maneuver, wayName);
706 else if (maneuverType == QLatin1String(
"end of road"))
707 return instructionEndOfRoad(wayName, direction);
708 else if (maneuverType == QLatin1String(
"ferry"))
709 return instructionFerry(wayName);
710 else if (maneuverType == QLatin1String(
"fork"))
711 return instructionFork(wayName, direction);
712 else if (maneuverType == QLatin1String(
"merge"))
713 return instructionMerge(wayName, direction);
714 else if (maneuverType == QLatin1String(
"new name"))
715 return instructionNewName(wayName, direction);
716 else if (maneuverType == QLatin1String(
"notification"))
717 return instructionNotification(wayName, direction);
718 else if (maneuverType == QLatin1String(
"off ramp"))
719 return instructionOffRamp(wayName, direction);
720 else if (maneuverType == QLatin1String(
"on ramp"))
721 return instructionOnRamp(wayName, direction);
722 else if (maneuverType == QLatin1String(
"pushing bike"))
723 return instructionPushingBike(wayName);
724 else if (maneuverType == QLatin1String(
"rotary"))
725 return instructionRotary(step, maneuver, wayName);
726 else if (maneuverType == QLatin1String(
"roundabout"))
727 return instructionRoundabout(maneuver, wayName);
728 else if (maneuverType == QLatin1String(
"roundabout turn"))
729 return instructionRoundaboutTurn(wayName, direction);
730 else if (maneuverType == QLatin1String(
"train"))
731 return instructionTrain(wayName);
732 else if (maneuverType == QLatin1String(
"turn"))
733 return instructionTurn(wayName, direction);
734 else if (maneuverType == QLatin1String(
"use lane"))
735 return instructionUseLane(maneuver, wayName, direction);
737 return maneuverType + QLatin1String(
" to/onto ") + wayName;
743 if (maneuver.value(QLatin1String(
"modifier")).isString())
744 modifier = maneuver.value(QLatin1String(
"modifier")).toString();
746 if (modifier.isEmpty())
747 return QGeoManeuver::NoDirection;
748 else if (modifier == QLatin1String(
"straight"))
749 return QGeoManeuver::DirectionForward;
750 else if (modifier == QLatin1String(
"right"))
751 return QGeoManeuver::DirectionRight;
752 else if (modifier == QLatin1String(
"sharp right"))
753 return QGeoManeuver::DirectionHardRight;
754 else if (modifier == QLatin1String(
"slight right"))
755 return QGeoManeuver::DirectionLightRight;
756 else if (modifier == QLatin1String(
"uturn")) {
757 switch (trafficSide) {
758 case QGeoRouteParser::RightHandTraffic:
759 return QGeoManeuver::DirectionUTurnLeft;
760 case QGeoRouteParser::LeftHandTraffic:
761 return QGeoManeuver::DirectionUTurnRight;
763 return QGeoManeuver::DirectionUTurnLeft;
764 }
else if (modifier == QLatin1String(
"left"))
765 return QGeoManeuver::DirectionLeft;
766 else if (modifier == QLatin1String(
"sharp left"))
767 return QGeoManeuver::DirectionHardLeft;
768 else if (modifier == QLatin1String(
"slight left"))
769 return QGeoManeuver::DirectionLightLeft;
771 return QGeoManeuver::NoDirection;
806 QGeoRouteSegment segment;
807 if (!step.value(QLatin1String(
"maneuver")).isObject())
809 QJsonObject maneuver = step.value(QLatin1String(
"maneuver")).toObject();
810 if (!step.value(QLatin1String(
"duration")).isDouble())
812 if (!step.value(QLatin1String(
"distance")).isDouble())
814 if (!step.value(QLatin1String(
"intersections")).isArray())
816 if (!maneuver.value(QLatin1String(
"location")).isArray())
819 double time = step.value(QLatin1String(
"duration")).toDouble();
820 double distance = step.value(QLatin1String(
"distance")).toDouble();
822 QJsonArray position = maneuver.value(QLatin1String(
"location")).toArray();
823 if (position.isEmpty())
825 double latitude = position[1].toDouble();
826 double longitude = position[0].toDouble();
827 QGeoCoordinate coord(latitude, longitude);
829 QString geometry = step.value(QLatin1String(
"geometry")).toString();
830 QList<QGeoCoordinate> path = decodePolyline(geometry);
832 QGeoManeuver::InstructionDirection maneuverInstructionDirection = instructionDirection(maneuver, trafficSide);
834 QString maneuverInstructionText = instructionText(step, maneuver, maneuverInstructionDirection);
836 QGeoManeuver geoManeuver;
837 geoManeuver.setDirection(maneuverInstructionDirection);
838 geoManeuver.setDistanceToNextInstruction(distance);
839 geoManeuver.setTimeToNextInstruction(time);
840 geoManeuver.setInstructionText(maneuverInstructionText);
841 geoManeuver.setPosition(coord);
842 geoManeuver.setWaypoint(coord);
844 QVariantMap extraAttributes;
845 static const QStringList extras {
846 QLatin1String(
"bearing_before"),
847 QLatin1String(
"bearing_after"),
848 QLatin1String(
"instruction"),
849 QLatin1String(
"type"),
850 QLatin1String(
"modifier") };
851 for (
const QString &e: extras) {
852 if (maneuver.find(e) != maneuver.end())
853 extraAttributes.insert(e, maneuver.value(e).toVariant());
857 extraAttributes.insert(QLatin1String(
"leg_index"), legIndex);
858 extraAttributes.insert(QLatin1String(
"step_index"), stepIndex);
860 geoManeuver.setExtendedAttributes(extraAttributes);
862 segment.setDistance(distance);
863 segment.setPath(path);
864 segment.setTravelTime(time);
865 segment.setManeuver(geoManeuver);
867 m_extension->updateSegment(segment, step, maneuver);
875 QJsonDocument document = QJsonDocument::fromJson(reply);
876 if (document.isObject()) {
877 QJsonObject object = document.object();
879 QString status = object.value(QLatin1String(
"code")).toString();
880 if (status != QLatin1String(
"Ok")) {
881 errorString = status;
882 return QGeoRouteReply::UnknownError;
884 if (!object.value(QLatin1String(
"routes")).isArray()) {
885 errorString = QLatin1String(
"No routes found");
886 return QGeoRouteReply::ParseError;
889 const QJsonArray osrmRoutes = object.value(QLatin1String(
"routes")).toArray();
890 for (
const QJsonValueConstRef r : osrmRoutes) {
893 QJsonObject routeObject = r.toObject();
894 if (!routeObject.value(QLatin1String(
"legs")).isArray())
896 if (!routeObject.value(QLatin1String(
"duration")).isDouble())
898 if (!routeObject.value(QLatin1String(
"distance")).isDouble())
901 double distance = routeObject.value(QLatin1String(
"distance")).toDouble();
902 double travelTime = routeObject.value(QLatin1String(
"duration")).toDouble();
904 QList<QGeoRouteSegment> segments;
906 const QJsonArray legs = routeObject.value(QLatin1String(
"legs")).toArray();
907 QList<QGeoRoute> routeLegs;
909 for (
int legIndex = 0; legIndex < legs.size(); ++legIndex) {
910 const QJsonValue &l = legs.at(legIndex);
912 QList<QGeoRouteSegment> legSegments;
917 const QJsonObject leg = l.toObject();
918 if (!leg.value(QLatin1String(
"steps")).isArray()) {
922 const double legDistance = leg.value(QLatin1String(
"distance")).toDouble();
923 const double legTravelTime = leg.value(QLatin1String(
"duration")).toDouble();
924 const QJsonArray steps = leg.value(QLatin1String(
"steps")).toArray();
925 QGeoRouteSegment segment;
926 for (
int stepIndex = 0; stepIndex < steps.size(); ++stepIndex) {
927 const QJsonValue &s = steps.at(stepIndex);
932 segment = parseStep(s.toObject(), legIndex, stepIndex);
933 if (segment.isValid()) {
935 legSegments.append(segment);
944 QGeoRouteSegmentPrivate *segmentPrivate = QGeoRouteSegmentPrivate::get(segment);
945 segmentPrivate->setLegLastSegment(
true);
946 QList<QGeoCoordinate> path;
947 for (
const QGeoRouteSegment &s: std::as_const(legSegments))
948 path.append(s.path());
949 routeLeg.setLegIndex(legIndex);
950 routeLeg.setOverallRoute(route);
951 routeLeg.setDistance(legDistance);
952 routeLeg.setTravelTime(legTravelTime);
953 if (!path.isEmpty()) {
954 routeLeg.setPath(path);
955 routeLeg.setFirstRouteSegment(legSegments.first());
957 routeLegs << routeLeg;
959 segments.append(legSegments);
963 QList<QGeoCoordinate> path;
964 for (
const QGeoRouteSegment &s : segments)
965 path.append(s.path());
967 for (qsizetype i = segments.size() - 1; i > 0; --i)
968 segments[i-1].setNextRouteSegment(segments[i]);
970 route.setDistance(distance);
971 route.setTravelTime(travelTime);
972 if (!path.isEmpty()) {
974 route.setBounds(QGeoPath(path).boundingGeoRectangle());
975 route.setFirstRouteSegment(segments.first());
977 route.setRouteLegs(routeLegs);
979 routes.append(route);
984 return QGeoRouteReply::NoError;
986 errorString = QLatin1String(
"Couldn't parse json.");
987 return QGeoRouteReply::ParseError;
993 QString routingUrl = prefix;
995 const QList<QGeoCoordinate> waypoints = request.waypoints();
996 for (qsizetype i = 0; i < waypoints.size(); i++) {
997 const QGeoCoordinate &c = waypoints.at(i);
999 routingUrl.append(QLatin1Char(
';'));
1000 routingUrl.append(QString::number(c.longitude(),
'f', 7)).append(QLatin1Char(
',')).append(QString::number(c.latitude(),
'f', 7));
1004 QUrl url(routingUrl);
1006 query.addQueryItem(QLatin1String(
"overview"), QLatin1String(
"full"));
1007 query.addQueryItem(QLatin1String(
"steps"), QLatin1String(
"true"));
1008 query.addQueryItem(QLatin1String(
"geometries"), QLatin1String(
"polyline6"));
1009 query.addQueryItem(QLatin1String(
"alternatives"), QLatin1String(
"true"));
1011 m_extension->updateQuery(query);
1012 url.setQuery(query);