diff --git a/brouter-core/src/main/java/btools/router/FormatGpx.java b/brouter-core/src/main/java/btools/router/FormatGpx.java
index 06f8564..582cb44 100644
--- a/brouter-core/src/main/java/btools/router/FormatGpx.java
+++ b/brouter-core/src/main/java/btools/router/FormatGpx.java
@@ -49,7 +49,7 @@ public class FormatGpx extends Formatter {
sb.append("\n");
sb.append("\n");
@@ -121,7 +121,7 @@ public class FormatGpx extends Formatter {
sb.append(" \n")
.append(" ")
- .append(turnInstructionMode == 3 ? hint.getMessageString() : hint.getCruiserMessageString())
+ .append(turnInstructionMode == 3 ? hint.getMessageString(turnInstructionMode) : hint.getCruiserMessageString())
.append("\n \n");
rteTime = t.getVoiceHintTime(i + 1);
@@ -132,7 +132,7 @@ public class FormatGpx extends Formatter {
lastRteTime = rteTime;
}
sb.append(" ")
- .append(turnInstructionMode == 3 ? hint.getCommandString() : hint.getCruiserCommandString())
+ .append(turnInstructionMode == 3 ? hint.getCommandString(turnInstructionMode) : hint.getCruiserCommandString())
.append("\n ").append("" + (int) hint.angle)
.append("\n ").append("" + hint.indexInTrack).append("\n \n \n");
}
@@ -154,7 +154,7 @@ public class FormatGpx extends Formatter {
.append(formatILat(hint.ilat)).append("\">")
.append(hint.selev == Short.MIN_VALUE ? "" : "" + (hint.selev / 4.) + "")
.append("")
- .append(hint.getMessageString())
+ .append(hint.getMessageString(turnInstructionMode))
.append("")
.append("").append("" + hint.distanceToNext).append("");
float rteTime = t.getVoiceHintTime(i + 1);
@@ -173,9 +173,9 @@ public class FormatGpx extends Formatter {
for (VoiceHint hint : t.voiceHints.list) {
sb.append(" ")
- .append("").append(hint.getMessageString()).append("")
- .append("").append(hint.getSymbolString().toLowerCase()).append("")
- .append("").append(hint.getSymbolString()).append("")
+ .append("").append(hint.getMessageString(turnInstructionMode)).append("")
+ .append("").append(hint.getSymbolString(turnInstructionMode).toLowerCase()).append("")
+ .append("").append(hint.getSymbolString(turnInstructionMode)).append("")
.append("\n");
}
}
@@ -270,7 +270,7 @@ public class FormatGpx extends Formatter {
sele += "" + mwpt.name + "";
}
sele += "" + hint.getCruiserMessageString() + "";
- sele += "" + hint.getCommandString(hint.cmd) + "";
+ sele += "" + hint.getCommandString(hint.cmd, turnInstructionMode) + "";
if (mwpt != null) {
sele += "Via";
}
@@ -287,7 +287,7 @@ public class FormatGpx extends Formatter {
sele += "" + (((int) (speed * 10)) / 10.f) + "";
}
- sele += "" + hint.getCommandString() + ";" + (int) (hint.distanceToNext) + "," + hint.formatGeometry() + "";
+ sele += "" + hint.getCommandString(turnInstructionMode) + ";" + (int) (hint.distanceToNext) + "," + hint.formatGeometry() + "";
if (n.message != null && n.message.wayKeyValues != null && !n.message.wayKeyValues.equals(lastway)) {
sele += "" + n.message.wayKeyValues + "";
lastway = n.message.wayKeyValues;
diff --git a/brouter-core/src/main/java/btools/router/FormatJson.java b/brouter-core/src/main/java/btools/router/FormatJson.java
index dc7dcd4..3c52d9a 100644
--- a/brouter-core/src/main/java/btools/router/FormatJson.java
+++ b/brouter-core/src/main/java/btools/router/FormatJson.java
@@ -41,13 +41,13 @@ public class FormatJson extends Formatter {
for (VoiceHint hint : t.voiceHints.list) {
sb.append(" [");
sb.append(hint.indexInTrack);
- sb.append(',').append(hint.getJsonCommandIndex());
+ sb.append(',').append(hint.getJsonCommandIndex(turnInstructionMode));
sb.append(',').append(hint.getExitNumber());
sb.append(',').append(hint.distanceToNext);
sb.append(',').append((int) hint.angle);
// not always include geometry because longer and only needed for comment style
- if (turnInstructionMode == 4) { // comment style
+ if (turnInstructionMode == 4 || turnInstructionMode == 9) { // comment style
sb.append(",\"").append(hint.formatGeometry()).append("\"");
}
@@ -122,7 +122,7 @@ public class FormatJson extends Formatter {
.append(sele).append("],\n");
nn = n;
}
- if (t.nodes != null && !t.nodes.isEmpty()) sb.deleteCharAt(sb.lastIndexOf(","));
+ sb.deleteCharAt(sb.lastIndexOf(","));
sb.append(" ]\n");
sb.append(" }\n");
diff --git a/brouter-core/src/main/java/btools/router/VoiceHint.java b/brouter-core/src/main/java/btools/router/VoiceHint.java
index 09123a5..20a66f4 100644
--- a/brouter-core/src/main/java/btools/router/VoiceHint.java
+++ b/brouter-core/src/main/java/btools/router/VoiceHint.java
@@ -26,6 +26,8 @@ public class VoiceHint {
static final int RNLB = 14; // Roundabout left
static final int TU = 15; // 180 degree u-turn
static final int BL = 16; // Beeline routing
+ static final int EL = 17; // Beeline routing
+ static final int ER = 18; // Beeline routing
int ilon;
int ilat;
@@ -65,7 +67,7 @@ public class VoiceHint {
badWays.add(badWay);
}
- public int getJsonCommandIndex() {
+ public int getJsonCommandIndex(int timode) {
switch (cmd) {
case TLU:
return 10;
@@ -97,6 +99,10 @@ public class VoiceHint {
return 14;
case BL:
return 16;
+ case EL:
+ return timode == 2 || timode == 9 ? 17 : 8;
+ case ER:
+ return timode == 2 || timode == 9 ? 18 : 9;
case OFFR:
return 12;
default:
@@ -111,7 +117,7 @@ public class VoiceHint {
/*
* used by comment style, osmand style
*/
- public String getCommandString() {
+ public String getCommandString(int timode) {
switch (cmd) {
case TLU:
return "TU"; // should be changed to TLU when osmand uses new voice hint constants
@@ -143,6 +149,10 @@ public class VoiceHint {
return "RNLB" + (-roundaboutExit);
case BL:
return "BL";
+ case EL:
+ return timode == 2 || timode == 9 ? "EL" : "KL";
+ case ER:
+ return timode == 2 || timode == 9 ? "ER" : "KR";
case OFFR:
return "OFFR";
default:
@@ -153,7 +163,7 @@ public class VoiceHint {
/*
* used by trkpt/sym style
*/
- public String getCommandString(int c) {
+ public String getCommandString(int c, int timode) {
switch (c) {
case TLU:
return "TLU";
@@ -185,6 +195,10 @@ public class VoiceHint {
return "RNLB" + (-roundaboutExit);
case BL:
return "BL";
+ case EL:
+ return timode == 2 || timode == 9 ? "EL" : "KL";
+ case ER:
+ return timode == 2 || timode == 9 ? "ER" : "KR";
case OFFR:
return "OFFR";
default:
@@ -195,7 +209,7 @@ public class VoiceHint {
/*
* used by gpsies style
*/
- public String getSymbolString() {
+ public String getSymbolString(int timode) {
switch (cmd) {
case TLU:
return "TU";
@@ -227,6 +241,10 @@ public class VoiceHint {
return "RNLB" + (-roundaboutExit);
case BL:
return "BL";
+ case EL:
+ return timode == 2 || timode == 9 ? "EL" : "KL";
+ case ER:
+ return timode == 2 || timode == 9 ? "ER" : "KR";
case OFFR:
return "OFFR";
default:
@@ -269,6 +287,10 @@ public class VoiceHint {
return "roundabout_e" + (-roundaboutExit);
case BL:
return "beeline";
+ case EL:
+ return "exit_left";
+ case ER:
+ return "exit_right";
default:
throw new IllegalArgumentException("unknown command: " + cmd);
}
@@ -277,7 +299,7 @@ public class VoiceHint {
/*
* used by osmand style
*/
- public String getMessageString() {
+ public String getMessageString(int timode) {
switch (cmd) {
case TLU:
return "u-turn"; // should be changed to u-turn-left when osmand uses new voice hint constants
@@ -307,6 +329,10 @@ public class VoiceHint {
return "Take exit " + roundaboutExit;
case RNLB:
return "Take exit " + (-roundaboutExit);
+ case EL:
+ return timode == 2 || timode == 9 ? "exit left" : "keep left";
+ case ER:
+ return timode == 2 || timode == 9 ? "exit right" : "keep right";
default:
throw new IllegalArgumentException("unknown command: " + cmd);
}
@@ -345,6 +371,10 @@ public class VoiceHint {
return 26 + roundaboutExit;
case RNLB:
return 26 - roundaboutExit;
+ case EL:
+ return 9;
+ case ER:
+ return 10;
default:
throw new IllegalArgumentException("unknown command: " + cmd);
}
@@ -383,6 +413,10 @@ public class VoiceHint {
return 1008 + roundaboutExit;
case RNLB:
return 1008 + roundaboutExit;
+ case EL:
+ return 1015;
+ case ER:
+ return 1014;
default:
throw new IllegalArgumentException("unknown command: " + cmd);
}
@@ -423,6 +457,10 @@ public class VoiceHint {
return "RNLB" + (-roundaboutExit);
case BL:
return "BL";
+ case EL:
+ return "EL";
+ case ER:
+ return "ER";
case OFFR:
return "OFFR";
default:
@@ -465,6 +503,10 @@ public class VoiceHint {
return "take exit " + (-roundaboutExit);
case BL:
return "beeline";
+ case EL:
+ return "exit left";
+ case ER:
+ return "exit right";
case OFFR:
return "offroad";
default:
diff --git a/brouter-core/src/main/java/btools/router/VoiceHintProcessor.java b/brouter-core/src/main/java/btools/router/VoiceHintProcessor.java
index ebc61c7..ee2d905 100644
--- a/brouter-core/src/main/java/btools/router/VoiceHintProcessor.java
+++ b/brouter-core/src/main/java/btools/router/VoiceHintProcessor.java
@@ -334,6 +334,17 @@ public final class VoiceHintProcessor {
inputLastSaved.distanceToNext += input.distanceToNext;
}
}
+ } else if ((input.goodWay.getPrio() == 29 && input.maxBadPrio == 30) &&
+ ((hintIdx + 1 < inputs.size() && inputs.get(hintIdx+1).goodWay.getPrio() < 29) ||
+ (hintIdx + 2 < inputs.size() && inputs.get(hintIdx+2).goodWay.getPrio() < 29))) {
+ // leave motorway
+ if (input.cmd == VoiceHint.KR || input.cmd == VoiceHint.TSLR) {
+ input.cmd = VoiceHint.ER;
+ } else if (input.cmd == VoiceHint.KL || input.cmd == VoiceHint.TSLL) {
+ input.cmd = VoiceHint.EL;
+ }
+ results.add(input);
+ inputLastSaved = input;
} else {
// add all others
// ignore motorway / primary continue
@@ -384,6 +395,14 @@ public final class VoiceHintProcessor {
inputLastSaved.distanceToNext += input.distanceToNext;
}
}
+ } else if ((input.goodWay.getPrio() == 29 && input.maxBadPrio == 30)) {
+ // leave motorway
+ if (input.cmd == VoiceHint.KR || input.cmd == VoiceHint.TSLR) {
+ input.cmd = VoiceHint.ER;
+ } else if (input.cmd == VoiceHint.KL || input.cmd == VoiceHint.TSLL) {
+ input.cmd = VoiceHint.EL;
+ }
+ save = true;
} else if (VoiceHint.is180DegAngle(input.angle)) {
// add u-turn, 180 degree
save = true;
diff --git a/docs/features/voicehints.md b/docs/features/voicehints.md
index f4c3e78..446190f 100644
--- a/docs/features/voicehints.md
+++ b/docs/features/voicehints.md
@@ -25,6 +25,7 @@ And there are other rules
* merge two hints when near to each other - e.g. left, left to u-turn left
* marker when highway exit and continue nearly same direction
* beeline goes direct from via to via point
+* junction on motorway via motorway_link and next way less then motorway_link is a motorway exit
There are some variables in the profiles that affect on the voice hint generation:
* considerTurnRestrictions -
@@ -51,4 +52,6 @@ Voice hint variables
| RNDB | roundabout |
| RNLB | roundabout left |
| BL | beeline routing |
+| EL | exit left |
+| ER | exit right |