24static QList<QGeoCoordinate> decodePolyline(
const QString &polylineString)
26 QList<QGeoCoordinate> path;
27 if (polylineString.isEmpty())
30 const QByteArray data = polylineString.toLatin1();
32 bool parsingLatitude =
true;
37 QGeoCoordinate coord(0, 0);
39 for (qsizetype i = 0; i < data.length(); ++i) {
40 unsigned char c = data.at(i) - 63;
42 value |= (c & 0x1f) << shift;
49 int diff = (value & 1) ? ~(value >> 1) : (value >> 1);
51 if (parsingLatitude) {
52 coord.setLatitude(coord.latitude() + (
double)diff/1e6);
54 coord.setLongitude(coord.longitude() + (
double)diff/1e6);
58 parsingLatitude = !parsingLatitude;
70 case QLocationUtils::CardinalN:
73 return QGeoRouteParserOsrmV5::tr(
"North");
74 case QLocationUtils::CardinalE:
75 return QGeoRouteParserOsrmV5::tr(
"East");
76 case QLocationUtils::CardinalS:
77 return QGeoRouteParserOsrmV5::tr(
"South");
78 case QLocationUtils::CardinalW:
79 return QGeoRouteParserOsrmV5::tr(
"West");
87 static QList<QString> ordinals;
89 if (!ordinals.size()) {
90 ordinals.append(QLatin1String(
""));
92 ordinals.append(QGeoRouteParserOsrmV5::tr(
"first",
"roundabout exit"));
93 ordinals.append(QGeoRouteParserOsrmV5::tr(
"second",
"roundabout exit"));
94 ordinals.append(QGeoRouteParserOsrmV5::tr(
"third",
"roundabout exit"));
95 ordinals.append(QGeoRouteParserOsrmV5::tr(
"fourth",
"roundabout exit"));
96 ordinals.append(QGeoRouteParserOsrmV5::tr(
"fifth",
"roundabout exit"));
97 ordinals.append(QGeoRouteParserOsrmV5::tr(
"sixth",
"roundabout exit"));
98 ordinals.append(QGeoRouteParserOsrmV5::tr(
"seventh",
"roundabout exit"));
99 ordinals.append(QGeoRouteParserOsrmV5::tr(
"eighth",
"roundabout exit"));
100 ordinals.append(QGeoRouteParserOsrmV5::tr(
"ninth",
"roundabout exit"));
101 ordinals.append(QGeoRouteParserOsrmV5::tr(
"tenth",
"roundabout exit"));
102 ordinals.append(QGeoRouteParserOsrmV5::tr(
"eleventh",
"roundabout exit"));
103 ordinals.append(QGeoRouteParserOsrmV5::tr(
"twelfth",
"roundabout exit"));
104 ordinals.append(QGeoRouteParserOsrmV5::tr(
"thirteenth",
"roundabout exit"));
105 ordinals.append(QGeoRouteParserOsrmV5::tr(
"fourteenth",
"roundabout exit"));
106 ordinals.append(QGeoRouteParserOsrmV5::tr(
"fifteenth",
"roundabout exit"));
107 ordinals.append(QGeoRouteParserOsrmV5::tr(
"sixteenth",
"roundabout exit"));
108 ordinals.append(QGeoRouteParserOsrmV5::tr(
"seventeenth",
"roundabout exit"));
109 ordinals.append(QGeoRouteParserOsrmV5::tr(
"eighteenth",
"roundabout exit"));
110 ordinals.append(QGeoRouteParserOsrmV5::tr(
"nineteenth",
"roundabout exit"));
111 ordinals.append(QGeoRouteParserOsrmV5::tr(
"twentieth",
"roundabout exit"));
114 if (exit < 1 || exit > ordinals.size())
116 return ordinals[exit];
140 case QGeoManeuver::DirectionForward:
141 return QGeoRouteParserOsrmV5::tr(
"You have arrived at your destination, straight ahead");
142 case QGeoManeuver::DirectionUTurnLeft:
143 case QGeoManeuver::DirectionHardLeft:
144 case QGeoManeuver::DirectionLeft:
145 case QGeoManeuver::DirectionLightLeft:
146 case QGeoManeuver::DirectionBearLeft:
147 return QGeoRouteParserOsrmV5::tr(
"You have arrived at your destination, on the left");
148 case QGeoManeuver::DirectionUTurnRight:
149 case QGeoManeuver::DirectionHardRight:
150 case QGeoManeuver::DirectionRight:
151 case QGeoManeuver::DirectionLightRight:
152 case QGeoManeuver::DirectionBearRight:
153 return QGeoRouteParserOsrmV5::tr(
"You have arrived at your destination, on the right");
155 return QGeoRouteParserOsrmV5::tr(
"You have arrived at your destination");
162 case QGeoManeuver::DirectionForward:
163 if (wayName.isEmpty())
164 return QGeoRouteParserOsrmV5::tr(
"Continue straight");
166 return QGeoRouteParserOsrmV5::tr(
"Continue straight on %1").arg(wayName);
167 case QGeoManeuver::DirectionHardLeft:
168 case QGeoManeuver::DirectionLeft:
169 if (wayName.isEmpty())
170 return QGeoRouteParserOsrmV5::tr(
"Continue left");
172 return QGeoRouteParserOsrmV5::tr(
"Continue left onto %1").arg(wayName);
173 case QGeoManeuver::DirectionLightLeft:
174 case QGeoManeuver::DirectionBearLeft:
175 if (wayName.isEmpty())
176 return QGeoRouteParserOsrmV5::tr(
"Continue slightly left");
178 return QGeoRouteParserOsrmV5::tr(
"Continue slightly left on %1").arg(wayName);
179 case QGeoManeuver::DirectionHardRight:
180 case QGeoManeuver::DirectionRight:
181 if (wayName.isEmpty())
182 return QGeoRouteParserOsrmV5::tr(
"Continue right");
184 return QGeoRouteParserOsrmV5::tr(
"Continue right onto %1").arg(wayName);
185 case QGeoManeuver::DirectionLightRight:
186 case QGeoManeuver::DirectionBearRight:
187 if (wayName.isEmpty())
188 return QGeoRouteParserOsrmV5::tr(
"Continue slightly right");
190 return QGeoRouteParserOsrmV5::tr(
"Continue slightly right on %1").arg(wayName);
191 case QGeoManeuver::DirectionUTurnLeft:
192 case QGeoManeuver::DirectionUTurnRight:
193 if (wayName.isEmpty())
194 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn");
196 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn onto %1").arg(wayName);
198 if (wayName.isEmpty())
199 return QGeoRouteParserOsrmV5::tr(
"Continue");
201 return QGeoRouteParserOsrmV5::tr(
"Continue on %1").arg(wayName);
225 case QGeoManeuver::DirectionHardLeft:
226 case QGeoManeuver::DirectionLeft:
227 case QGeoManeuver::DirectionLightLeft:
228 case QGeoManeuver::DirectionBearLeft:
229 if (wayName.isEmpty())
230 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, turn left");
232 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, turn left onto %1").arg(wayName);
233 case QGeoManeuver::DirectionHardRight:
234 case QGeoManeuver::DirectionRight:
235 case QGeoManeuver::DirectionLightRight:
236 case QGeoManeuver::DirectionBearRight:
237 if (wayName.isEmpty())
238 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, turn right");
240 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, turn right onto %1").arg(wayName);
241 case QGeoManeuver::DirectionUTurnLeft:
242 case QGeoManeuver::DirectionUTurnRight:
243 if (wayName.isEmpty())
244 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, make a U-turn");
246 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, make a U-turn onto %1").arg(wayName);
247 case QGeoManeuver::DirectionForward:
248 if (wayName.isEmpty())
249 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, continue straight");
251 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, continue straight onto %1").arg(wayName);
253 if (wayName.isEmpty())
254 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, continue");
256 return QGeoRouteParserOsrmV5::tr(
"At the end of the road, continue onto %1").arg(wayName);
269static QString
instructionFork(
const QString &wayName, QGeoManeuver::InstructionDirection direction)
272 case QGeoManeuver::DirectionHardLeft:
273 if (wayName.isEmpty())
274 return QGeoRouteParserOsrmV5::tr(
"At the fork, take a sharp left");
276 return QGeoRouteParserOsrmV5::tr(
"At the fork, take a sharp left onto %1").arg(wayName);
277 case QGeoManeuver::DirectionLeft:
278 if (wayName.isEmpty())
279 return QGeoRouteParserOsrmV5::tr(
"At the fork, turn left");
281 return QGeoRouteParserOsrmV5::tr(
"At the fork, turn left onto %1").arg(wayName);
282 case QGeoManeuver::DirectionLightLeft:
283 case QGeoManeuver::DirectionBearLeft:
284 if (wayName.isEmpty())
285 return QGeoRouteParserOsrmV5::tr(
"At the fork, keep left");
287 return QGeoRouteParserOsrmV5::tr(
"At the fork, keep left onto %1").arg(wayName);
288 case QGeoManeuver::DirectionHardRight:
289 if (wayName.isEmpty())
290 return QGeoRouteParserOsrmV5::tr(
"At the fork, take a sharp right");
292 return QGeoRouteParserOsrmV5::tr(
"At the fork, take a sharp right onto %1").arg(wayName);
293 case QGeoManeuver::DirectionRight:
294 if (wayName.isEmpty())
295 return QGeoRouteParserOsrmV5::tr(
"At the fork, turn right");
297 return QGeoRouteParserOsrmV5::tr(
"At the fork, turn right onto %1").arg(wayName);
298 case QGeoManeuver::DirectionLightRight:
299 case QGeoManeuver::DirectionBearRight:
300 if (wayName.isEmpty())
301 return QGeoRouteParserOsrmV5::tr(
"At the fork, keep right");
303 return QGeoRouteParserOsrmV5::tr(
"At the fork, keep right onto %1").arg(wayName);
304 case QGeoManeuver::DirectionUTurnLeft:
305 case QGeoManeuver::DirectionUTurnRight:
306 if (wayName.isEmpty())
307 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn");
309 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn onto %1").arg(wayName);
310 case QGeoManeuver::DirectionForward:
311 if (wayName.isEmpty())
312 return QGeoRouteParserOsrmV5::tr(
"At the fork, continue straight ahead");
314 return QGeoRouteParserOsrmV5::tr(
"At the fork, continue straight ahead onto %1").arg(wayName);
316 if (wayName.isEmpty())
317 return QGeoRouteParserOsrmV5::tr(
"At the fork, continue");
319 return QGeoRouteParserOsrmV5::tr(
"At the fork, continue onto %1").arg(wayName);
323static QString
instructionMerge(
const QString &wayName, QGeoManeuver::InstructionDirection direction)
326 case QGeoManeuver::DirectionUTurnLeft:
327 case QGeoManeuver::DirectionHardLeft:
328 if (wayName.isEmpty())
329 return QGeoRouteParserOsrmV5::tr(
"Merge sharply left");
331 return QGeoRouteParserOsrmV5::tr(
"Merge sharply left onto %1").arg(wayName);
332 case QGeoManeuver::DirectionLeft:
333 if (wayName.isEmpty())
334 return QGeoRouteParserOsrmV5::tr(
"Merge left");
336 return QGeoRouteParserOsrmV5::tr(
"Merge left onto %1").arg(wayName);
337 case QGeoManeuver::DirectionLightLeft:
338 case QGeoManeuver::DirectionBearLeft:
339 if (wayName.isEmpty())
340 return QGeoRouteParserOsrmV5::tr(
"Merge slightly left");
342 return QGeoRouteParserOsrmV5::tr(
"Merge slightly left on %1").arg(wayName);
343 case QGeoManeuver::DirectionUTurnRight:
344 case QGeoManeuver::DirectionHardRight:
345 if (wayName.isEmpty())
346 return QGeoRouteParserOsrmV5::tr(
"Merge sharply right");
348 return QGeoRouteParserOsrmV5::tr(
"Merge sharply right onto %1").arg(wayName);
349 case QGeoManeuver::DirectionRight:
350 if (wayName.isEmpty())
351 return QGeoRouteParserOsrmV5::tr(
"Merge right");
353 return QGeoRouteParserOsrmV5::tr(
"Merge right onto %1").arg(wayName);
354 case QGeoManeuver::DirectionLightRight:
355 case QGeoManeuver::DirectionBearRight:
356 if (wayName.isEmpty())
357 return QGeoRouteParserOsrmV5::tr(
"Merge slightly right");
359 return QGeoRouteParserOsrmV5::tr(
"Merge slightly right on %1").arg(wayName);
360 case QGeoManeuver::DirectionForward:
361 if (wayName.isEmpty())
362 return QGeoRouteParserOsrmV5::tr(
"Merge straight");
364 return QGeoRouteParserOsrmV5::tr(
"Merge straight on %1").arg(wayName);
366 if (wayName.isEmpty())
367 return QGeoRouteParserOsrmV5::tr(
"Merge");
369 return QGeoRouteParserOsrmV5::tr(
"Merge onto %1").arg(wayName);
373static QString
instructionNewName(
const QString &wayName, QGeoManeuver::InstructionDirection direction)
376 case QGeoManeuver::DirectionHardLeft:
377 if (wayName.isEmpty())
378 return QGeoRouteParserOsrmV5::tr(
"Take a sharp left");
380 return QGeoRouteParserOsrmV5::tr(
"Take a sharp left onto %1").arg(wayName);
381 case QGeoManeuver::DirectionLeft:
382 if (wayName.isEmpty())
383 return QGeoRouteParserOsrmV5::tr(
"Turn left");
385 return QGeoRouteParserOsrmV5::tr(
"Turn left onto %1").arg(wayName);
386 case QGeoManeuver::DirectionLightLeft:
387 case QGeoManeuver::DirectionBearLeft:
388 if (wayName.isEmpty())
389 return QGeoRouteParserOsrmV5::tr(
"Continue slightly left");
391 return QGeoRouteParserOsrmV5::tr(
"Continue slightly left onto %1").arg(wayName);
392 case QGeoManeuver::DirectionHardRight:
393 if (wayName.isEmpty())
394 return QGeoRouteParserOsrmV5::tr(
"Take a sharp right");
396 return QGeoRouteParserOsrmV5::tr(
"Take a sharp right onto %1").arg(wayName);
397 case QGeoManeuver::DirectionRight:
398 if (wayName.isEmpty())
399 return QGeoRouteParserOsrmV5::tr(
"Turn right");
401 return QGeoRouteParserOsrmV5::tr(
"Turn right onto %1").arg(wayName);
402 case QGeoManeuver::DirectionLightRight:
403 case QGeoManeuver::DirectionBearRight:
404 if (wayName.isEmpty())
405 return QGeoRouteParserOsrmV5::tr(
"Continue slightly right");
407 return QGeoRouteParserOsrmV5::tr(
"Continue slightly right onto %1").arg(wayName);
408 case QGeoManeuver::DirectionUTurnLeft:
409 case QGeoManeuver::DirectionUTurnRight:
410 if (wayName.isEmpty())
411 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn");
413 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn onto %1").arg(wayName);
414 case QGeoManeuver::DirectionForward:
415 if (wayName.isEmpty())
416 return QGeoRouteParserOsrmV5::tr(
"Continue straight");
418 return QGeoRouteParserOsrmV5::tr(
"Continue straight onto %1").arg(wayName);
420 if (wayName.isEmpty())
421 return QGeoRouteParserOsrmV5::tr(
"Continue");
423 return QGeoRouteParserOsrmV5::tr(
"Continue onto %1").arg(wayName);
430 case QGeoManeuver::DirectionUTurnLeft:
431 case QGeoManeuver::DirectionHardLeft:
432 case QGeoManeuver::DirectionLeft:
433 case QGeoManeuver::DirectionLightLeft:
434 case QGeoManeuver::DirectionBearLeft:
435 if (wayName.isEmpty())
436 return QGeoRouteParserOsrmV5::tr(
"Continue on the left");
438 return QGeoRouteParserOsrmV5::tr(
"Continue on the left on %1").arg(wayName);
439 case QGeoManeuver::DirectionUTurnRight:
440 case QGeoManeuver::DirectionHardRight:
441 case QGeoManeuver::DirectionRight:
442 case QGeoManeuver::DirectionLightRight:
443 case QGeoManeuver::DirectionBearRight:
444 if (wayName.isEmpty())
445 return QGeoRouteParserOsrmV5::tr(
"Continue on the right");
447 return QGeoRouteParserOsrmV5::tr(
"Continue on the right on %1").arg(wayName);
448 case QGeoManeuver::DirectionForward:
450 if (wayName.isEmpty())
451 return QGeoRouteParserOsrmV5::tr(
"Continue");
453 return QGeoRouteParserOsrmV5::tr(
"Continue on %1").arg(wayName);
457static QString
instructionOffRamp(
const QString &wayName, QGeoManeuver::InstructionDirection direction)
460 case QGeoManeuver::DirectionUTurnLeft:
461 case QGeoManeuver::DirectionHardLeft:
462 case QGeoManeuver::DirectionLeft:
463 case QGeoManeuver::DirectionLightLeft:
464 case QGeoManeuver::DirectionBearLeft:
465 if (wayName.isEmpty())
466 return QGeoRouteParserOsrmV5::tr(
"Take the ramp on the left");
468 return QGeoRouteParserOsrmV5::tr(
"Take the ramp on the left onto %1").arg(wayName);
469 case QGeoManeuver::DirectionUTurnRight:
470 case QGeoManeuver::DirectionHardRight:
471 case QGeoManeuver::DirectionRight:
472 case QGeoManeuver::DirectionLightRight:
473 case QGeoManeuver::DirectionBearRight:
474 if (wayName.isEmpty())
475 return QGeoRouteParserOsrmV5::tr(
"Take the ramp on the right");
477 return QGeoRouteParserOsrmV5::tr(
"Take the ramp on the right onto %1").arg(wayName);
478 case QGeoManeuver::DirectionForward:
480 if (wayName.isEmpty())
481 return QGeoRouteParserOsrmV5::tr(
"Take the ramp");
483 return QGeoRouteParserOsrmV5::tr(
"Take the ramp onto %1").arg(wayName);
530 case QGeoManeuver::DirectionForward:
531 if (wayName.isEmpty())
532 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, continue straight");
534 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, continue straight on %1").arg(wayName);
535 case QGeoManeuver::DirectionHardLeft:
536 case QGeoManeuver::DirectionLeft:
537 case QGeoManeuver::DirectionLightLeft:
538 case QGeoManeuver::DirectionBearLeft:
539 if (wayName.isEmpty())
540 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn left");
542 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn left onto %1").arg(wayName);
543 case QGeoManeuver::DirectionHardRight:
544 case QGeoManeuver::DirectionRight:
545 case QGeoManeuver::DirectionLightRight:
546 case QGeoManeuver::DirectionBearRight:
547 if (wayName.isEmpty())
548 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn right");
550 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn right onto %1").arg(wayName);
551 case QGeoManeuver::DirectionUTurnLeft:
552 case QGeoManeuver::DirectionUTurnRight:
553 if (wayName.isEmpty())
554 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn around");
556 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, turn around onto %1").arg(wayName);
558 if (wayName.isEmpty())
559 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, continue");
561 return QGeoRouteParserOsrmV5::tr(
"At the roundabout, continue onto %1").arg(wayName);
572static QString
instructionTurn(
const QString &wayName, QGeoManeuver::InstructionDirection direction)
575 case QGeoManeuver::DirectionForward:
576 if (wayName.isEmpty())
577 return QGeoRouteParserOsrmV5::tr(
"Go straight");
579 return QGeoRouteParserOsrmV5::tr(
"Go straight onto %1").arg(wayName);
580 case QGeoManeuver::DirectionHardLeft:
581 case QGeoManeuver::DirectionLeft:
582 if (wayName.isEmpty())
583 return QGeoRouteParserOsrmV5::tr(
"Turn left");
585 return QGeoRouteParserOsrmV5::tr(
"Turn left onto %1").arg(wayName);
586 case QGeoManeuver::DirectionLightLeft:
587 case QGeoManeuver::DirectionBearLeft:
588 if (wayName.isEmpty())
589 return QGeoRouteParserOsrmV5::tr(
"Turn slightly left");
591 return QGeoRouteParserOsrmV5::tr(
"Turn slightly left onto %1").arg(wayName);
592 case QGeoManeuver::DirectionHardRight:
593 case QGeoManeuver::DirectionRight:
594 if (wayName.isEmpty())
595 return QGeoRouteParserOsrmV5::tr(
"Turn right");
597 return QGeoRouteParserOsrmV5::tr(
"Turn right onto %1").arg(wayName);
598 case QGeoManeuver::DirectionLightRight:
599 case QGeoManeuver::DirectionBearRight:
600 if (wayName.isEmpty())
601 return QGeoRouteParserOsrmV5::tr(
"Turn slightly right");
603 return QGeoRouteParserOsrmV5::tr(
"Turn slightly right onto %1").arg(wayName);
604 case QGeoManeuver::DirectionUTurnLeft:
605 case QGeoManeuver::DirectionUTurnRight:
606 if (wayName.isEmpty())
607 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn");
609 return QGeoRouteParserOsrmV5::tr(
"Make a U-turn onto %1").arg(wayName);
611 if (wayName.isEmpty())
612 return QGeoRouteParserOsrmV5::tr(
"Turn");
614 return QGeoRouteParserOsrmV5::tr(
"Turn onto %1").arg(wayName);
618static QString
instructionUseLane(
const QJsonObject &maneuver,
const QString &wayName, QGeoManeuver::InstructionDirection direction)
620 QString laneTypes = maneuver.value(QLatin1String(
"laneTypes")).toString();
621 QString laneInstruction;
622 if (laneTypes == QLatin1String(
"xo") || laneTypes == QLatin1String(
"xoo") || laneTypes == QLatin1String(
"xxo"))
624 laneInstruction = QLatin1String(
"Keep right");
625 else if (laneTypes == QLatin1String(
"ox") || laneTypes == QLatin1String(
"oox") || laneTypes == QLatin1String(
"oxx"))
626 laneInstruction = QLatin1String(
"Keep left");
627 else if (laneTypes == QLatin1String(
"xox"))
628 laneInstruction = QLatin1String(
"Use the middle lane");
629 else if (laneTypes == QLatin1String(
"oxo"))
630 laneInstruction = QLatin1String(
"Use the left or the right lane");
632 if (laneInstruction.isEmpty()) {
633 if (wayName.isEmpty())
634 return QGeoRouteParserOsrmV5::tr(
"Continue straight");
636 return QGeoRouteParserOsrmV5::tr(
"Continue straight onto %1").arg(wayName);
640 case QGeoManeuver::DirectionForward:
641 if (wayName.isEmpty())
643 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and continue straight");
645 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and continue straight onto %1").arg(wayName);
646 case QGeoManeuver::DirectionHardLeft:
647 if (wayName.isEmpty())
648 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a sharp left");
650 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a sharp left onto %1").arg(wayName);
651 case QGeoManeuver::DirectionLeft:
652 if (wayName.isEmpty())
653 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and turn left");
655 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and turn left onto %1").arg(wayName);
656 case QGeoManeuver::DirectionLightLeft:
657 case QGeoManeuver::DirectionBearLeft:
658 if (wayName.isEmpty())
659 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a slight left");
661 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a slight left onto %1").arg(wayName);
662 case QGeoManeuver::DirectionHardRight:
663 if (wayName.isEmpty())
664 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a sharp right");
666 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a sharp right onto %1").arg(wayName);
667 case QGeoManeuver::DirectionRight:
668 if (wayName.isEmpty())
669 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and turn right");
671 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and turn right onto %1").arg(wayName);
672 case QGeoManeuver::DirectionLightRight:
673 case QGeoManeuver::DirectionBearRight:
674 if (wayName.isEmpty())
675 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a slight right");
677 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a slight right onto %1").arg(wayName);
678 case QGeoManeuver::DirectionUTurnLeft:
679 case QGeoManeuver::DirectionUTurnRight:
680 if (wayName.isEmpty())
681 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a U-turn");
683 return laneInstruction + QGeoRouteParserOsrmV5::tr(
" and make a U-turn onto %1").arg(wayName);
685 return laneInstruction;
689static QString
instructionText(
const QJsonObject &step,
const QJsonObject &maneuver, QGeoManeuver::InstructionDirection direction) {
691 if (maneuver.value(QLatin1String(
"modifier")).isString())
692 modifier = maneuver.value(QLatin1String(
"modifier")).toString();
693 QString maneuverType;
694 if (maneuver.value(QLatin1String(
"type")).isString())
695 maneuverType = maneuver.value(QLatin1String(
"type")).toString();
696 QString wayName = QLatin1String(
"unknown street");
697 if (step.value(QLatin1String(
"name")).isString())
698 wayName = step.value(QLatin1String(
"name")).toString();
701 if (maneuverType == QLatin1String(
"arrive"))
702 return instructionArrive(direction);
703 else if (maneuverType == QLatin1String(
"continue"))
704 return instructionContinue(wayName, direction);
705 else if (maneuverType == QLatin1String(
"depart"))
706 return instructionDepart(maneuver, wayName);
707 else if (maneuverType == QLatin1String(
"end of road"))
708 return instructionEndOfRoad(wayName, direction);
709 else if (maneuverType == QLatin1String(
"ferry"))
710 return instructionFerry(wayName);
711 else if (maneuverType == QLatin1String(
"fork"))
712 return instructionFork(wayName, direction);
713 else if (maneuverType == QLatin1String(
"merge"))
714 return instructionMerge(wayName, direction);
715 else if (maneuverType == QLatin1String(
"new name"))
716 return instructionNewName(wayName, direction);
717 else if (maneuverType == QLatin1String(
"notification"))
718 return instructionNotification(wayName, direction);
719 else if (maneuverType == QLatin1String(
"off ramp"))
720 return instructionOffRamp(wayName, direction);
721 else if (maneuverType == QLatin1String(
"on ramp"))
722 return instructionOnRamp(wayName, direction);
723 else if (maneuverType == QLatin1String(
"pushing bike"))
724 return instructionPushingBike(wayName);
725 else if (maneuverType == QLatin1String(
"rotary"))
726 return instructionRotary(step, maneuver, wayName);
727 else if (maneuverType == QLatin1String(
"roundabout"))
728 return instructionRoundabout(maneuver, wayName);
729 else if (maneuverType == QLatin1String(
"roundabout turn"))
730 return instructionRoundaboutTurn(wayName, direction);
731 else if (maneuverType == QLatin1String(
"train"))
732 return instructionTrain(wayName);
733 else if (maneuverType == QLatin1String(
"turn"))
734 return instructionTurn(wayName, direction);
735 else if (maneuverType == QLatin1String(
"use lane"))
736 return instructionUseLane(maneuver, wayName, direction);
738 return maneuverType + QLatin1String(
" to/onto ") + wayName;
744 if (maneuver.value(QLatin1String(
"modifier")).isString())
745 modifier = maneuver.value(QLatin1String(
"modifier")).toString();
747 if (modifier.isEmpty())
748 return QGeoManeuver::NoDirection;
749 else if (modifier == QLatin1String(
"straight"))
750 return QGeoManeuver::DirectionForward;
751 else if (modifier == QLatin1String(
"right"))
752 return QGeoManeuver::DirectionRight;
753 else if (modifier == QLatin1String(
"sharp right"))
754 return QGeoManeuver::DirectionHardRight;
755 else if (modifier == QLatin1String(
"slight right"))
756 return QGeoManeuver::DirectionLightRight;
757 else if (modifier == QLatin1String(
"uturn")) {
758 switch (trafficSide) {
759 case QGeoRouteParser::RightHandTraffic:
760 return QGeoManeuver::DirectionUTurnLeft;
761 case QGeoRouteParser::LeftHandTraffic:
762 return QGeoManeuver::DirectionUTurnRight;
764 return QGeoManeuver::DirectionUTurnLeft;
765 }
else if (modifier == QLatin1String(
"left"))
766 return QGeoManeuver::DirectionLeft;
767 else if (modifier == QLatin1String(
"sharp left"))
768 return QGeoManeuver::DirectionHardLeft;
769 else if (modifier == QLatin1String(
"slight left"))
770 return QGeoManeuver::DirectionLightLeft;
772 return QGeoManeuver::NoDirection;
807 QGeoRouteSegment segment;
808 if (!step.value(QLatin1String(
"maneuver")).isObject())
810 QJsonObject maneuver = step.value(QLatin1String(
"maneuver")).toObject();
811 if (!step.value(QLatin1String(
"duration")).isDouble())
813 if (!step.value(QLatin1String(
"distance")).isDouble())
815 if (!step.value(QLatin1String(
"intersections")).isArray())
817 if (!maneuver.value(QLatin1String(
"location")).isArray())
820 double time = step.value(QLatin1String(
"duration")).toDouble();
821 double distance = step.value(QLatin1String(
"distance")).toDouble();
823 QJsonArray position = maneuver.value(QLatin1String(
"location")).toArray();
824 if (position.isEmpty())
826 double latitude = position[1].toDouble();
827 double longitude = position[0].toDouble();
828 QGeoCoordinate coord(latitude, longitude);
830 QString geometry = step.value(QLatin1String(
"geometry")).toString();
831 QList<QGeoCoordinate> path = decodePolyline(geometry);
833 QGeoManeuver::InstructionDirection maneuverInstructionDirection = instructionDirection(maneuver, trafficSide);
835 QString maneuverInstructionText = instructionText(step, maneuver, maneuverInstructionDirection);
837 QGeoManeuver geoManeuver;
838 geoManeuver.setDirection(maneuverInstructionDirection);
839 geoManeuver.setDistanceToNextInstruction(distance);
840 geoManeuver.setTimeToNextInstruction(time);
841 geoManeuver.setInstructionText(maneuverInstructionText);
842 geoManeuver.setPosition(coord);
843 geoManeuver.setWaypoint(coord);
845 QVariantMap extraAttributes;
846 static const QStringList extras {
847 QLatin1String(
"bearing_before"),
848 QLatin1String(
"bearing_after"),
849 QLatin1String(
"instruction"),
850 QLatin1String(
"type"),
851 QLatin1String(
"modifier") };
852 for (
const QString &e: extras) {
853 if (maneuver.find(e) != maneuver.end())
854 extraAttributes.insert(e, maneuver.value(e).toVariant());
858 extraAttributes.insert(QLatin1String(
"leg_index"), legIndex);
859 extraAttributes.insert(QLatin1String(
"step_index"), stepIndex);
861 geoManeuver.setExtendedAttributes(extraAttributes);
863 segment.setDistance(distance);
864 segment.setPath(path);
865 segment.setTravelTime(time);
866 segment.setManeuver(geoManeuver);
868 m_extension->updateSegment(segment, step, maneuver);
876 QJsonDocument document = QJsonDocument::fromJson(reply);
877 if (document.isObject()) {
878 QJsonObject object = document.object();
880 QString status = object.value(QLatin1String(
"code")).toString();
881 if (status != QLatin1String(
"Ok")) {
882 errorString = status;
883 return QGeoRouteReply::UnknownError;
885 if (!object.value(QLatin1String(
"routes")).isArray()) {
886 errorString = QLatin1String(
"No routes found");
887 return QGeoRouteReply::ParseError;
890 const QJsonArray osrmRoutes = object.value(QLatin1String(
"routes")).toArray();
891 for (
const QJsonValueConstRef r : osrmRoutes) {
894 QJsonObject routeObject = r.toObject();
895 if (!routeObject.value(QLatin1String(
"legs")).isArray())
897 if (!routeObject.value(QLatin1String(
"duration")).isDouble())
899 if (!routeObject.value(QLatin1String(
"distance")).isDouble())
902 double distance = routeObject.value(QLatin1String(
"distance")).toDouble();
903 double travelTime = routeObject.value(QLatin1String(
"duration")).toDouble();
905 QList<QGeoRouteSegment> segments;
907 const QJsonArray legs = routeObject.value(QLatin1String(
"legs")).toArray();
908 QList<QGeoRoute> routeLegs;
910 for (
int legIndex = 0; legIndex < legs.size(); ++legIndex) {
911 const QJsonValue &l = legs.at(legIndex);
913 QList<QGeoRouteSegment> legSegments;
918 const QJsonObject leg = l.toObject();
919 if (!leg.value(QLatin1String(
"steps")).isArray()) {
923 const double legDistance = leg.value(QLatin1String(
"distance")).toDouble();
924 const double legTravelTime = leg.value(QLatin1String(
"duration")).toDouble();
925 const QJsonArray steps = leg.value(QLatin1String(
"steps")).toArray();
926 QGeoRouteSegment segment;
927 for (
int stepIndex = 0; stepIndex < steps.size(); ++stepIndex) {
928 const QJsonValue &s = steps.at(stepIndex);
933 segment = parseStep(s.toObject(), legIndex, stepIndex);
934 if (segment.isValid()) {
936 legSegments.append(segment);
945 QGeoRouteSegmentPrivate *segmentPrivate = QGeoRouteSegmentPrivate::get(segment);
946 segmentPrivate->setLegLastSegment(
true);
947 QList<QGeoCoordinate> path;
948 for (
const QGeoRouteSegment &s: std::as_const(legSegments))
949 path.append(s.path());
950 routeLeg.setLegIndex(legIndex);
951 routeLeg.setOverallRoute(route);
952 routeLeg.setDistance(legDistance);
953 routeLeg.setTravelTime(legTravelTime);
954 if (!path.isEmpty()) {
955 routeLeg.setPath(path);
956 routeLeg.setFirstRouteSegment(legSegments.first());
958 routeLegs << routeLeg;
960 segments.append(legSegments);
964 QList<QGeoCoordinate> path;
965 for (
const QGeoRouteSegment &s : segments)
966 path.append(s.path());
968 for (qsizetype i = segments.size() - 1; i > 0; --i)
969 segments[i-1].setNextRouteSegment(segments[i]);
971 route.setDistance(distance);
972 route.setTravelTime(travelTime);
973 if (!path.isEmpty()) {
975 route.setBounds(QGeoPath(path).boundingGeoRectangle());
976 route.setFirstRouteSegment(segments.first());
978 route.setRouteLegs(routeLegs);
980 routes.append(route);
985 return QGeoRouteReply::NoError;
987 errorString = QLatin1String(
"Couldn't parse json.");
988 return QGeoRouteReply::ParseError;
994 QString routingUrl = prefix;
996 const QList<QGeoCoordinate> waypoints = request.waypoints();
997 for (qsizetype i = 0; i < waypoints.size(); i++) {
998 const QGeoCoordinate &c = waypoints.at(i);
1000 routingUrl.append(QLatin1Char(
';'));
1001 routingUrl.append(QString::number(c.longitude(),
'f', 7)).append(QLatin1Char(
',')).append(QString::number(c.latitude(),
'f', 7));
1005 QUrl url(routingUrl);
1007 query.addQueryItem(QLatin1String(
"overview"), QLatin1String(
"full"));
1008 query.addQueryItem(QLatin1String(
"steps"), QLatin1String(
"true"));
1009 query.addQueryItem(QLatin1String(
"geometries"), QLatin1String(
"polyline6"));
1010 query.addQueryItem(QLatin1String(
"alternatives"), QLatin1String(
"true"));
1012 m_extension->updateQuery(query);
1013 url.setQuery(query);