Refactoring of the js voice guidance
This commit is contained in:
parent
3dc93e3c15
commit
cf5b44cbf1
7 changed files with 254 additions and 593 deletions
|
@ -21,6 +21,7 @@ import net.osmand.IndexConstants;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.activities.OsmandActionBarActivity;
|
import net.osmand.plus.activities.OsmandActionBarActivity;
|
||||||
|
import net.osmand.plus.routing.data.StreetName;
|
||||||
import net.osmand.plus.voice.AbstractPrologCommandPlayer;
|
import net.osmand.plus.voice.AbstractPrologCommandPlayer;
|
||||||
import net.osmand.plus.voice.JSCommandBuilder;
|
import net.osmand.plus.voice.JSCommandBuilder;
|
||||||
import net.osmand.plus.voice.JSMediaCommandPlayerImpl;
|
import net.osmand.plus.voice.JSMediaCommandPlayerImpl;
|
||||||
|
@ -167,115 +168,51 @@ public class TestVoiceActivity extends OsmandActionBarActivity {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Term street(CommandPlayer p, String name) {
|
|
||||||
return street(p, name, "", "", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private Term street(CommandPlayer p, String name, String ref) {
|
|
||||||
return street(p, name, ref, "", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private Term street(CommandPlayer p, String name, String ref, String dest) {
|
|
||||||
return street(p, name, ref, dest, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private Term getTermString(String s) {
|
|
||||||
if(!Algorithms.isEmpty(s)) {
|
|
||||||
return new Struct(s);
|
|
||||||
}
|
|
||||||
return new Struct("");
|
|
||||||
}
|
|
||||||
|
|
||||||
private Term street(CommandPlayer p, String name, String ref, String destName, String currentName) {
|
|
||||||
// Pass all test strings through our character replacement method
|
|
||||||
ref = VoiceRouter.getSpeakablePointName(ref);
|
|
||||||
name = VoiceRouter.getSpeakablePointName(name);
|
|
||||||
destName = VoiceRouter.getSpeakablePointName(destName);
|
|
||||||
currentName = VoiceRouter.getSpeakablePointName(currentName);
|
|
||||||
|
|
||||||
if(p.supportsStructuredStreetNames()) {
|
|
||||||
Struct next = new Struct(new Term[] { getTermString(ref),
|
|
||||||
getTermString(name),
|
|
||||||
getTermString(destName) });
|
|
||||||
Term current = new Struct("");
|
|
||||||
if (currentName.length() > 0) {
|
|
||||||
current = new Struct(new Term[] { getTermString(""),
|
|
||||||
getTermString(currentName),
|
|
||||||
getTermString("") });
|
|
||||||
}
|
|
||||||
Struct voice = new Struct("voice", next, current );
|
|
||||||
return voice;
|
|
||||||
}
|
|
||||||
return new Struct(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addButtons(final LinearLayout ll, CommandPlayer p) {
|
private void addButtons(final LinearLayout ll, CommandPlayer p) {
|
||||||
boolean isJS = p instanceof JSTTSCommandPlayerImpl || p instanceof JSMediaCommandPlayerImpl;
|
|
||||||
addButton(ll, "Route calculated and number tests:", builder(p));
|
addButton(ll, "Route calculated and number tests:", builder(p));
|
||||||
addButton(ll, "\u25BA (1.1) New route calculated, 150m, 230sec (00:03:50)", !isJS ? builder(p).newRouteCalculated(150, 230) : jsBuilder(p).newRouteCalculated(150, 230));
|
addButton(ll, "\u25BA (1.1) New route calculated, 150m, 230sec (00:03:50)", builder(p).newRouteCalculated(150, 230));
|
||||||
addButton(ll, "\u25BA (1.2) New route calculated, 1350m, 3680sec (01:01:20)", !isJS ? builder(p).newRouteCalculated(1350, 3680) : jsBuilder(p).newRouteCalculated(1350, 3680));
|
addButton(ll, "\u25BA (1.2) New route calculated, 1350m, 3680sec (01:01:20)", builder(p).newRouteCalculated(1350, 3680));
|
||||||
addButton(ll, "\u25BA (1.3) New route calculated 3700m, 7320sec (02:02)", !isJS ? builder(p).newRouteCalculated(3700, 7320) : jsBuilder(p).newRouteCalculated(3700, 7320));
|
addButton(ll, "\u25BA (1.3) New route calculated 3700m, 7320sec (02:02)", builder(p).newRouteCalculated(3700, 7320));
|
||||||
addButton(ll, "\u25BA (1.4) New route calculated 9100m, 10980sec (03:03)", !isJS ? builder(p).newRouteCalculated(9100, 10980) : jsBuilder(p).newRouteCalculated(9100, 10980));
|
addButton(ll, "\u25BA (1.4) New route calculated 9100m, 10980sec (03:03)", builder(p).newRouteCalculated(9100, 10980));
|
||||||
addButton(ll, "\u25BA (2.1) Route recalculated 11500m, 18600sec (05:10)", !isJS ? builder(p).routeRecalculated(11500, 18600) : jsBuilder(p).routeRecalculated(11500, 18600));
|
addButton(ll, "\u25BA (2.1) Route recalculated 11500m, 18600sec (05:10)", builder(p).routeRecalculated(11500, 18600));
|
||||||
addButton(ll, "\u25BA (2.2) Route recalculated 19633m, 26700sec (07:25)", !isJS ? builder(p).routeRecalculated(19633, 26700) : jsBuilder(p).routeRecalculated(19633, 26700));
|
addButton(ll, "\u25BA (2.2) Route recalculated 19633m, 26700sec (07:25)", builder(p).routeRecalculated(19633, 26700) );
|
||||||
addButton(ll, "\u25BA (2.3) Route recalculated 89750m, 55800sec (15:30)", !isJS ? builder(p).routeRecalculated(89750, 55800) : jsBuilder(p).routeRecalculated(89750, 55800));
|
addButton(ll, "\u25BA (2.3) Route recalculated 89750m, 55800sec (15:30)", builder(p).routeRecalculated(89750, 55800) );
|
||||||
addButton(ll, "\u25BA (2.4) Route recalculated 125900m, 92700sec (25:45)", !isJS ? builder(p).routeRecalculated(125900, 92700) : jsBuilder(p).routeRecalculated(125900, 92700));
|
addButton(ll, "\u25BA (2.4) Route recalculated 125900m, 92700sec (25:45)", builder(p).routeRecalculated(125900, 92700) );
|
||||||
|
|
||||||
addButton(ll, "All turn types: prepareTurn, makeTurnIn, turn:", builder(p));
|
addButton(ll, "All turn types: prepareTurn, makeTurnIn, turn:", builder(p));
|
||||||
addButton(ll, "\u25BA (3.1) After 1520m turn slightly left", !isJS ? builder(p).prepareTurn(AbstractPrologCommandPlayer.A_LEFT_SL, 1520, street(p, "")) :
|
addButton(ll, "\u25BA (3.1) After 1520m turn slightly left", builder(p).prepareTurn(AbstractPrologCommandPlayer.A_LEFT_SL, 1520, street(p, "")));
|
||||||
jsBuilder(p).prepareTurn(AbstractPrologCommandPlayer.A_LEFT_SL, 1520, jsStreet(p, "")));
|
addButton(ll, "\u25BA (3.2) In 450m turn sharply left onto 'Hauptstra"+"\u00df"+"e', then bear right", builder(p).turn(AbstractPrologCommandPlayer.A_LEFT_SH, 450, street(p, "Hauptstraße")).then().bearRight(street(p, "")));
|
||||||
addButton(ll, "\u25BA (3.2) In 450m turn sharply left onto 'Hauptstra"+"\u00df"+"e', then bear right", !isJS ? builder(p).turn(AbstractPrologCommandPlayer.A_LEFT_SH, 450, street(p, "Hauptstraße")).then().bearRight(street(p, "")) :
|
addButton(ll, "\u25BA (3.3) Turn left, then in 100m turn slightly right", builder(p).turn(AbstractPrologCommandPlayer.A_LEFT, street(p, "")).then().turn(AbstractPrologCommandPlayer.A_RIGHT_SL, 100, street(p, "")));
|
||||||
jsBuilder(p).turn(AbstractPrologCommandPlayer.A_LEFT_SH, 450, jsStreet(p, "Hauptstraße")).then().bearRight(jsStreet(p, "")));
|
addButton(ll, "\u25BA (3.4) After 3100m turn right onto 'SR 80' toward 'Rome'", builder(p).prepareTurn(AbstractPrologCommandPlayer.A_RIGHT, 3100, street(p, "", "SR 80", "Rome")));
|
||||||
addButton(ll, "\u25BA (3.3) Turn left, then in 100m turn slightly right", !isJS ? builder(p).turn(AbstractPrologCommandPlayer.A_LEFT, street(p, "")).then().turn(AbstractPrologCommandPlayer.A_RIGHT_SL, 100, street(p, "")) :
|
addButton(ll, "\u25BA (3.5) In 370m turn slightly right onto 'Route 23' 'Main Street', then bear left", builder(p).turn(AbstractPrologCommandPlayer.A_RIGHT_SL, 370, street(p, "Main Street", "Route 23")).then().bearLeft(street(p, "")));
|
||||||
jsBuilder(p).turn(AbstractPrologCommandPlayer.A_LEFT, jsStreet(p, "")).then().turn(AbstractPrologCommandPlayer.A_RIGHT_SL, 100, jsStreet(p, "")));
|
addButton(ll, "\u25BA (3.6) Turn sharply right onto 'Dr.-Quinn-Stra"+"\u00df"+"e'", builder(p).turn(AbstractPrologCommandPlayer.A_RIGHT_SH, street(p, "Dr.-Quinn-Straße")));
|
||||||
addButton(ll, "\u25BA (3.4) After 3100m turn right onto 'SR 80' toward 'Rome'", !isJS ? builder(p).prepareTurn(AbstractPrologCommandPlayer.A_RIGHT, 3100, street(p, "", "SR 80", "Rome")) :
|
|
||||||
jsBuilder(p).prepareTurn(AbstractPrologCommandPlayer.A_RIGHT, 3100, jsStreet(p, "", "SR 80", "Rome")));
|
|
||||||
addButton(ll, "\u25BA (3.5) In 370m turn slightly right onto 'Route 23' 'Main Street', then bear left", !isJS ? builder(p).turn(AbstractPrologCommandPlayer.A_RIGHT_SL, 370, street(p, "Main Street", "Route 23")).then().bearLeft(street(p, "")) :
|
|
||||||
jsBuilder(p).turn(AbstractPrologCommandPlayer.A_RIGHT_SL, 370, jsStreet(p, "Main jsStreet", "Route 23")).then().bearLeft(jsStreet(p, "")));
|
|
||||||
addButton(ll, "\u25BA (3.6) Turn sharply right onto 'Dr.-Quinn-Stra"+"\u00df"+"e'", !isJS ? builder(p).turn(AbstractPrologCommandPlayer.A_RIGHT_SH, street(p, "Dr.-Quinn-Straße")) :
|
|
||||||
jsBuilder(p).turn(AbstractPrologCommandPlayer.A_RIGHT_SH, jsStreet(p, "Dr.-Quinn-Straße")));
|
|
||||||
|
|
||||||
addButton(ll, "Keep left/right: prepareTurn, makeTurnIn, turn:", builder(p));
|
addButton(ll, "Keep left/right: prepareTurn, makeTurnIn, turn:", builder(p));
|
||||||
addButton(ll, "\u25BA (4.1) After 1810m keep left ' '", !isJS ? builder(p).prepareTurn(AbstractPrologCommandPlayer.A_LEFT_KEEP, 1810, street(p, "")) :
|
addButton(ll, "\u25BA (4.1) After 1810m keep left ' '", builder(p).prepareTurn(AbstractPrologCommandPlayer.A_LEFT_KEEP, 1810, street(p, "")));
|
||||||
jsBuilder(p).prepareTurn(AbstractPrologCommandPlayer.A_LEFT_KEEP, 1810, jsStreet(p, "")));
|
addButton(ll, "\u25BA (4.2) In 400m keep left ' ' then in 80m keep right onto 'A1'", builder(p).turn(AbstractPrologCommandPlayer.A_LEFT_KEEP, 400, street(p, "")).then().turn(AbstractPrologCommandPlayer.A_RIGHT_KEEP, 80, street(p,"", "A1")));
|
||||||
addButton(ll, "\u25BA (4.2) In 400m keep left ' ' then in 80m keep right onto 'A1'", !isJS ? builder(p).turn(AbstractPrologCommandPlayer.A_LEFT_KEEP, 400, street(p, "")).then().turn(AbstractPrologCommandPlayer.A_RIGHT_KEEP, 80, street(p,"", "A1")) :
|
addButton(ll, "\u25BA (4.3) Keep right on 'Highway 60'", builder(p).turn(AbstractPrologCommandPlayer.A_RIGHT_KEEP, street(p, "Highway 60", "", "", "Highway 60")));
|
||||||
jsBuilder(p).turn(AbstractPrologCommandPlayer.A_LEFT_KEEP, 400, jsStreet(p, "")).then().turn(AbstractPrologCommandPlayer.A_RIGHT_KEEP, 80, jsStreet(p,"", "A1")));
|
addButton(ll, "\u25BA (4.4) Turn left onto 'Broadway', then in 100m keep right and arrive at your destination 'Town Hall'",
|
||||||
addButton(ll, "\u25BA (4.3) Keep right on 'Highway 60'", !isJS ? builder(p).turn(AbstractPrologCommandPlayer.A_RIGHT_KEEP, street(p, "Highway 60", "", "", "Highway 60")) :
|
|
||||||
jsBuilder(p).turn(AbstractPrologCommandPlayer.A_RIGHT_KEEP, jsStreet(p, "Highway 60", "", "", "Highway 60")));
|
|
||||||
addButton(ll, "\u25BA (4.4) Turn left onto 'Broadway', then in 100m keep right and arrive at your destination 'Town Hall'", !isJS ?
|
|
||||||
builder(p).turn(AbstractPrologCommandPlayer.A_LEFT, street(p, "Broadway"))
|
builder(p).turn(AbstractPrologCommandPlayer.A_LEFT, street(p, "Broadway"))
|
||||||
.then().turn(AbstractPrologCommandPlayer.A_RIGHT_KEEP, 100, street(p, "")).andArriveAtDestination("Town Hall") :
|
.then().turn(AbstractPrologCommandPlayer.A_RIGHT_KEEP, 100, street(p, "")).andArriveAtDestination("Town Hall"));
|
||||||
jsBuilder(p).turn(AbstractPrologCommandPlayer.A_LEFT, jsStreet(p, "Broadway"))
|
|
||||||
.then().turn(AbstractPrologCommandPlayer.A_RIGHT_KEEP, 100, jsStreet(p, "")).andArriveAtDestination("Town Hall"));
|
|
||||||
|
|
||||||
addButton(ll, "Roundabouts: prepareTurn, makeTurnIn, turn:", builder(p));
|
addButton(ll, "Roundabouts: prepareTurn, makeTurnIn, turn:", builder(p));
|
||||||
addButton(ll, "\u25BA (5.1) After 1250m enter a roundabout", !isJS ? builder(p).prepareRoundAbout(1250, 3, street(p,"", "I 15", "Los Angeles")) :
|
addButton(ll, "\u25BA (5.1) After 1250m enter a roundabout", builder(p).prepareRoundAbout(1250, 3, street(p,"", "I 15", "Los Angeles")));
|
||||||
jsBuilder(p).prepareRoundAbout(1250, 3, jsStreet(p,"", "I 15", "Los Angeles")));
|
addButton(ll, "\u25BA (5.2) In 450m enter the roundabout and take the 1st exit onto 'I 15' toward 'Los Angeles'", builder(p).roundAbout(450, 0, 1, street(p,"", "I 15", "Los Angeles")));
|
||||||
addButton(ll, "\u25BA (5.2) In 450m enter the roundabout and take the 1st exit onto 'I 15' toward 'Los Angeles'", !isJS ? builder(p).roundAbout(450, 0, 1, street(p,"", "I 15", "Los Angeles")) :
|
addButton(ll, "\u25BA (5.3) Roundabout: Take the 2nd exit onto 'Highway 60'", builder(p).roundAbout(0, 2, street(p, "Highway 60")));
|
||||||
jsBuilder(p).roundAbout(450, 0, 1, jsStreet(p,"", "I 15", "Los Angeles")));
|
|
||||||
addButton(ll, "\u25BA (5.3) Roundabout: Take the 2nd exit onto 'Highway 60'", !isJS ? builder(p).roundAbout(0, 2, street(p, "Highway 60")) :
|
|
||||||
jsBuilder(p).roundAbout(0, 2, jsStreet(p, "Highway 60")));
|
|
||||||
|
|
||||||
addButton(ll, "U-turns: prepareTurn, makeTurnIn, turn, when possible:", builder(p));
|
addButton(ll, "U-turns: prepareTurn, makeTurnIn, turn, when possible:", builder(p));
|
||||||
addButton(ll, "\u25BA (6.1) After 640m make a U-turn", !isJS ? builder(p).prepareMakeUT(640, street(p, "")) :
|
addButton(ll, "\u25BA (6.1) After 640m make a U-turn", builder(p).prepareMakeUT(640, street(p, "")));
|
||||||
jsBuilder(p).prepareMakeUT(640, jsStreet(p, "")));
|
addButton(ll, "\u25BA (6.2) In 400m make a U-turn", builder(p).makeUT(400, street(p, "")));
|
||||||
addButton(ll, "\u25BA (6.2) In 400m make a U-turn", !isJS ? builder(p).makeUT(400, street(p, "")) :
|
addButton(ll, "\u25BA (6.3) Make a U-turn on 'Riviera'", builder(p).makeUT(street(p, "Riviera", "", "", "Riviera")));
|
||||||
jsBuilder(p).makeUT(400, jsStreet(p, "")));
|
|
||||||
addButton(ll, "\u25BA (6.3) Make a U-turn on 'Riviera'", !isJS ? builder(p).makeUT(street(p, "Riviera", "", "", "Riviera")) :
|
|
||||||
jsBuilder(p).makeUT(jsStreet(p, "Riviera", "", "", "Riviera")));
|
|
||||||
addButton(ll, "\u25BA (6.4) When possible, make a U-turn", builder(p).makeUTwp());
|
addButton(ll, "\u25BA (6.4) When possible, make a U-turn", builder(p).makeUTwp());
|
||||||
|
|
||||||
addButton(ll, "Go straight, follow the road, approaching:", builder(p));
|
addButton(ll, "Go straight, follow the road, approaching:", builder(p));
|
||||||
addButton(ll, "\u25BA (7.1) Straight ahead", builder(p).goAhead());
|
addButton(ll, "\u25BA (7.1) Straight ahead", builder(p).goAhead());
|
||||||
addButton(ll, "\u25BA (7.2) Continue for 2350m to ' '", !isJS ? builder(p).goAhead(2350, street(p, "")) :
|
addButton(ll, "\u25BA (7.2) Continue for 2350m to ' '", builder(p).goAhead(2350, street(p)));
|
||||||
jsBuilder(p).goAhead(2350, jsStreet(p, "")));
|
addButton(ll, "\u25BA (7.3) Continue for 360m to 'Broadway' and arrive at your intermediate destination ' '", builder(p).goAhead(360, street(p,"Broadway")).andArriveAtIntermediatePoint(""));
|
||||||
addButton(ll, "\u25BA (7.3) Continue for 360m to 'Broadway' and arrive at your intermediate destination ' '", !isJS ? builder(p).goAhead(360, street(p,"Broadway")).andArriveAtIntermediatePoint("") :
|
addButton(ll, "\u25BA (7.4) Continue for 800m to 'Dr Martin Luther King Jr Boulevard' and arrive at your destination ' '", builder(p).goAhead(800, street(p,"", "Dr Martin Luther King Jr Boulevard")).andArriveAtDestination(""));
|
||||||
jsBuilder(p).goAhead(360, jsStreet(p,"Broadway")).andArriveAtIntermediatePoint(""));
|
addButton(ll, "\u25BA (7.5) Continue for 200m and pass GPX waypoint 'Trailhead'", builder(p).goAhead(200, new StreetName()).andArriveAtWayPoint("Trailhead") );
|
||||||
addButton(ll, "\u25BA (7.4) Continue for 800m to 'Dr Martin Luther King Jr Boulevard' and arrive at your destination ' '", !isJS ? builder(p).goAhead(800, street(p,"", "Dr Martin Luther King Jr Boulevard")).andArriveAtDestination("") :
|
addButton(ll, "\u25BA (7.6) Continue for 400m and pass favorite 'Brewery'", builder(p).goAhead(400, new StreetName()).andArriveAtFavorite("Brewery") );
|
||||||
jsBuilder(p).goAhead(800, jsStreet(p,"", "Dr Martin Luther King Jr Boulevard")).andArriveAtDestination(""));
|
addButton(ll, "\u25BA (7.7) Continue for 600m and pass POI 'Museum'", builder(p).goAhead(600, new StreetName()).andArriveAtPoi("Museum") );
|
||||||
addButton(ll, "\u25BA (7.5) Continue for 200m and pass GPX waypoint 'Trailhead'", !isJS ? builder(p).goAhead(200, null).andArriveAtWayPoint("Trailhead") : jsBuilder(p).goAhead(200, new HashMap<String, String>()).andArriveAtWayPoint("Trailhead"));
|
|
||||||
addButton(ll, "\u25BA (7.6) Continue for 400m and pass favorite 'Brewery'", !isJS ? builder(p).goAhead(400, null).andArriveAtFavorite("Brewery") : jsBuilder(p).goAhead(400, new HashMap<String, String>()).andArriveAtFavorite("Brewery"));
|
|
||||||
addButton(ll, "\u25BA (7.7) Continue for 600m and pass POI 'Museum'", !isJS ? builder(p).goAhead(600, null).andArriveAtPoi("Museum") : jsBuilder(p).goAhead(600, new HashMap<String, String>()).andArriveAtPoi("Museum"));
|
|
||||||
|
|
||||||
addButton(ll, "Arriving and passing points:", builder(p));
|
addButton(ll, "Arriving and passing points:", builder(p));
|
||||||
addButton(ll, "\u25BA (8.1) Arrive at your destination 'Home'", builder(p).arrivedAtDestination("Home"));
|
addButton(ll, "\u25BA (8.1) Arrive at your destination 'Home'", builder(p).arrivedAtDestination("Home"));
|
||||||
|
@ -307,10 +244,10 @@ public class TestVoiceActivity extends OsmandActionBarActivity {
|
||||||
ll.forceLayout();
|
ll.forceLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> jsStreet(CommandPlayer p, String... args) {
|
private StreetName street(CommandPlayer p, String... args) {
|
||||||
Map<String, String> res = new HashMap<>();
|
Map<String, String> res = new HashMap<>();
|
||||||
if (!p.supportsStructuredStreetNames()) {
|
if (!p.supportsStructuredStreetNames()) {
|
||||||
return res;
|
return new StreetName();
|
||||||
}
|
}
|
||||||
String[] streetNames = new String[]{"toRef", "toStreetName", "toDest", "fromRef", "fromStreetName", "fromDest"};
|
String[] streetNames = new String[]{"toRef", "toStreetName", "toDest", "fromRef", "fromStreetName", "fromDest"};
|
||||||
for (int i = 0; i < args.length; i++) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
@ -321,17 +258,13 @@ public class TestVoiceActivity extends OsmandActionBarActivity {
|
||||||
res.put(streetName, "");
|
res.put(streetName, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return new StreetName(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CommandBuilder builder(CommandPlayer p){
|
private CommandBuilder builder(CommandPlayer p){
|
||||||
return p.newCommandBuilder();
|
return p.newCommandBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSCommandBuilder jsBuilder(CommandPlayer p) {
|
|
||||||
return (JSCommandBuilder) p.newCommandBuilder();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addButton(ViewGroup layout, final String description, final CommandBuilder builder){
|
public void addButton(ViewGroup layout, final String description, final CommandBuilder builder){
|
||||||
final Button button = new Button(this);
|
final Button button = new Button(this);
|
||||||
button.setGravity(Gravity.LEFT);
|
button.setGravity(Gravity.LEFT);
|
||||||
|
|
|
@ -1,330 +0,0 @@
|
||||||
package net.osmand.plus.routing;
|
|
||||||
|
|
||||||
import net.osmand.Location;
|
|
||||||
import net.osmand.binary.RouteDataObject;
|
|
||||||
import net.osmand.plus.OsmandSettings;
|
|
||||||
import net.osmand.plus.voice.CommandBuilder;
|
|
||||||
import net.osmand.plus.voice.JSCommandBuilder;
|
|
||||||
import net.osmand.router.RouteSegmentResult;
|
|
||||||
import net.osmand.router.TurnType;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class JSVoiceRouter extends VoiceRouter {
|
|
||||||
|
|
||||||
public JSVoiceRouter(RoutingHelper router, OsmandSettings settings) {
|
|
||||||
super(router, settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getSpeakableJSStreetName(RouteSegmentResult currentSegment, RouteDirectionInfo i, boolean includeDest) {
|
|
||||||
Map<String, String> result = new HashMap<>();
|
|
||||||
if (i == null || !router.getSettings().SPEAK_STREET_NAMES.get()) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (player != null && player.supportsStructuredStreetNames()) {
|
|
||||||
|
|
||||||
// Issue 2377: Play Dest here only if not already previously announced, to avoid repetition
|
|
||||||
if (includeDest == true) {
|
|
||||||
result.put("toRef", getNonNullString(getSpeakablePointName(i.getRef())));
|
|
||||||
result.put("toStreetName", getNonNullString(getSpeakablePointName(i.getStreetName())));
|
|
||||||
result.put("toDest", getNonNullString(getSpeakablePointName(i.getDestinationName())));
|
|
||||||
} else {
|
|
||||||
result.put("toRef", getNonNullString(getSpeakablePointName(i.getRef())));
|
|
||||||
result.put("toStreetName", getNonNullString(getSpeakablePointName(i.getStreetName())));
|
|
||||||
result.put("toDest", "");
|
|
||||||
}
|
|
||||||
if (currentSegment != null) {
|
|
||||||
// Issue 2377: Play Dest here only if not already previously announced, to avoid repetition
|
|
||||||
if (includeDest == true) {
|
|
||||||
RouteDataObject obj = currentSegment.getObject();
|
|
||||||
result.put("fromRef", getNonNullString(getSpeakablePointName(obj.getRef(settings.MAP_PREFERRED_LOCALE.get(),
|
|
||||||
settings.MAP_TRANSLITERATE_NAMES.get(), currentSegment.isForwardDirection()))));
|
|
||||||
result.put("fromStreetName", getNonNullString(getSpeakablePointName(obj.getName(settings.MAP_PREFERRED_LOCALE.get(),
|
|
||||||
settings.MAP_TRANSLITERATE_NAMES.get()))));
|
|
||||||
result.put("fromDest", getNonNullString(getSpeakablePointName(obj.getDestinationName(settings.MAP_PREFERRED_LOCALE.get(),
|
|
||||||
settings.MAP_TRANSLITERATE_NAMES.get(), currentSegment.isForwardDirection()))));
|
|
||||||
} else {
|
|
||||||
RouteDataObject obj = currentSegment.getObject();
|
|
||||||
result.put("fromRef", getNonNullString(getSpeakablePointName(obj.getRef(settings.MAP_PREFERRED_LOCALE.get(),
|
|
||||||
settings.MAP_TRANSLITERATE_NAMES.get(), currentSegment.isForwardDirection()))));
|
|
||||||
result.put("fromStreetName", getNonNullString(getSpeakablePointName(obj.getName(settings.MAP_PREFERRED_LOCALE.get(),
|
|
||||||
settings.MAP_TRANSLITERATE_NAMES.get()))));
|
|
||||||
result.put("fromDest", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
result.put("toRef", getNonNullString(getSpeakablePointName(i.getRef())));
|
|
||||||
result.put("toStreetName", getNonNullString(getSpeakablePointName(i.getStreetName())));
|
|
||||||
result.put("toDest", "");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getNonNullString(String speakablePointName) {
|
|
||||||
return speakablePointName == null ? "" : speakablePointName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates status of voice guidance
|
|
||||||
* @param currentLocation
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void updateStatus(Location currentLocation, boolean repeat) {
|
|
||||||
// Directly after turn: goAhead (dist), unless:
|
|
||||||
// < PREPARE_LONG_DISTANCE (e.g. 3500m): playPrepareTurn (-not played any more-)
|
|
||||||
// < PREPARE_DISTANCE (e.g. 1500m): playPrepareTurn ("Turn after ...")
|
|
||||||
// < TURN_IN_DISTANCE (e.g. 390m or 30sec): playMakeTurnIn ("Turn in ...")
|
|
||||||
// < TURN_DISTANCE (e.g. 50m or 7sec): playMakeTurn ("Turn ...")
|
|
||||||
float speed = DEFAULT_SPEED;
|
|
||||||
if (currentLocation != null && currentLocation.hasSpeed()) {
|
|
||||||
speed = Math.max(currentLocation.getSpeed(), speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
RouteCalculationResult.NextDirectionInfo nextInfo = router.getNextRouteDirectionInfo(new RouteCalculationResult.NextDirectionInfo(), true);
|
|
||||||
RouteSegmentResult currentSegment = router.getCurrentSegmentResult();
|
|
||||||
if (nextInfo == null || nextInfo.directionInfo == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int dist = nextInfo.distanceTo;
|
|
||||||
RouteDirectionInfo next = nextInfo.directionInfo;
|
|
||||||
|
|
||||||
// If routing is changed update status to unknown
|
|
||||||
if (next != nextRouteDirection) {
|
|
||||||
nextRouteDirection = next;
|
|
||||||
currentStatus = STATUS_UNKNOWN;
|
|
||||||
suppressDest = false;
|
|
||||||
playedAndArriveAtTarget = false;
|
|
||||||
announceBackOnRoute = false;
|
|
||||||
if (playGoAheadDist != -1) {
|
|
||||||
playGoAheadDist = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!repeat) {
|
|
||||||
if (dist <= 0) {
|
|
||||||
return;
|
|
||||||
} else if (needsInforming()) {
|
|
||||||
playGoAhead(dist, getSpeakableJSStreetName(currentSegment, next, false));
|
|
||||||
return;
|
|
||||||
} else if (currentStatus == STATUS_TOLD) {
|
|
||||||
// nothing said possibly that's wrong case we should say before that
|
|
||||||
// however it should be checked manually ?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentStatus == STATUS_UNKNOWN) {
|
|
||||||
// Play "Continue for ..." if (1) after route calculation no other prompt is due, or (2) after a turn if next turn is more than PREPARE_LONG_DISTANCE away
|
|
||||||
if ((playGoAheadDist == -1) || (dist > PREPARE_LONG_DISTANCE)) {
|
|
||||||
playGoAheadDist = dist - 3 * TURN_DISTANCE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RouteCalculationResult.NextDirectionInfo nextNextInfo = router.getNextRouteDirectionInfoAfter(nextInfo, new RouteCalculationResult.NextDirectionInfo(), true); //I think "true" is correct here, not "!repeat"
|
|
||||||
// Note: getNextRouteDirectionInfoAfter(nextInfo, x, y).distanceTo is distance from nextInfo, not from current position!
|
|
||||||
|
|
||||||
// STATUS_TURN = "Turn (now)"
|
|
||||||
if ((repeat || statusNotPassed(STATUS_TURN)) && isDistanceLess(speed, dist, TURN_DISTANCE, TURN_DEFAULT_SPEED)) {
|
|
||||||
if (nextNextInfo.distanceTo < TURN_IN_DISTANCE_END && nextNextInfo != null) {
|
|
||||||
playMakeTurn(currentSegment, next, nextNextInfo);
|
|
||||||
} else {
|
|
||||||
playMakeTurn(currentSegment, next, null);
|
|
||||||
}
|
|
||||||
if (!next.getTurnType().goAhead() && isTargetPoint(nextNextInfo)) { // !goAhead() avoids isolated "and arrive.." prompt, as goAhead() is not pronounced
|
|
||||||
if (nextNextInfo.distanceTo < TURN_IN_DISTANCE_END) {
|
|
||||||
// Issue #2865: Ensure a distance associated with the destination arrival is always announced, either here, or in subsequent "Turn in" prompt
|
|
||||||
// Distance fon non-straights already announced in "Turn (now)"'s nextnext code above
|
|
||||||
if ((nextNextInfo != null) && (nextNextInfo.directionInfo != null) && nextNextInfo.directionInfo.getTurnType().goAhead()) {
|
|
||||||
playThen();
|
|
||||||
playGoAhead(nextNextInfo.distanceTo, new HashMap<String, String>());
|
|
||||||
}
|
|
||||||
playAndArriveAtDestination(nextNextInfo);
|
|
||||||
} else if (nextNextInfo.distanceTo < 1.2f * TURN_IN_DISTANCE_END) {
|
|
||||||
// 1.2 is safety margin should the subsequent "Turn in" prompt not fit in amy more
|
|
||||||
playThen();
|
|
||||||
playGoAhead(nextNextInfo.distanceTo, new HashMap<String, String>());
|
|
||||||
playAndArriveAtDestination(nextNextInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nextStatusAfter(STATUS_TURN);
|
|
||||||
|
|
||||||
// STATUS_TURN_IN = "Turn in ..."
|
|
||||||
} else if ((repeat || statusNotPassed(STATUS_TURN_IN)) && isDistanceLess(speed, dist, TURN_IN_DISTANCE, 0f)) {
|
|
||||||
if (repeat || dist >= TURN_IN_DISTANCE_END) {
|
|
||||||
if ((isDistanceLess(speed, nextNextInfo.distanceTo, TURN_DISTANCE, 0f) || nextNextInfo.distanceTo < TURN_IN_DISTANCE_END) &&
|
|
||||||
nextNextInfo != null) {
|
|
||||||
playMakeTurnIn(currentSegment, next, dist - (int) btScoDelayDistance, nextNextInfo.directionInfo);
|
|
||||||
} else {
|
|
||||||
playMakeTurnIn(currentSegment, next, dist - (int) btScoDelayDistance, null);
|
|
||||||
}
|
|
||||||
playGoAndArriveAtDestination(repeat, nextInfo, currentSegment);
|
|
||||||
}
|
|
||||||
nextStatusAfter(STATUS_TURN_IN);
|
|
||||||
|
|
||||||
// STATUS_PREPARE = "Turn after ..."
|
|
||||||
} else if ((repeat || statusNotPassed(STATUS_PREPARE)) && (dist <= PREPARE_DISTANCE)) {
|
|
||||||
if (repeat || dist >= PREPARE_DISTANCE_END) {
|
|
||||||
if (!repeat && (next.getTurnType().keepLeft() || next.getTurnType().keepRight())) {
|
|
||||||
// Do not play prepare for keep left/right
|
|
||||||
} else {
|
|
||||||
playPrepareTurn(currentSegment, next, dist);
|
|
||||||
playGoAndArriveAtDestination(repeat, nextInfo, currentSegment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nextStatusAfter(STATUS_PREPARE);
|
|
||||||
|
|
||||||
// STATUS_LONG_PREPARE = also "Turn after ...", we skip this now, users said this is obsolete
|
|
||||||
} else if ((repeat || statusNotPassed(STATUS_LONG_PREPARE)) && (dist <= PREPARE_LONG_DISTANCE)) {
|
|
||||||
if (repeat || dist >= PREPARE_LONG_DISTANCE_END) {
|
|
||||||
playPrepareTurn(currentSegment, next, dist);
|
|
||||||
playGoAndArriveAtDestination(repeat, nextInfo, currentSegment);
|
|
||||||
}
|
|
||||||
nextStatusAfter(STATUS_LONG_PREPARE);
|
|
||||||
|
|
||||||
// STATUS_UNKNOWN = "Continue for ..." if (1) after route calculation no other prompt is due, or (2) after a turn if next turn is more than PREPARE_LONG_DISTANCE away
|
|
||||||
} else if (statusNotPassed(STATUS_UNKNOWN)) {
|
|
||||||
// Strange how we get here but
|
|
||||||
nextStatusAfter(STATUS_UNKNOWN);
|
|
||||||
} else if (repeat || (statusNotPassed(STATUS_PREPARE) && dist < playGoAheadDist)) {
|
|
||||||
playGoAheadDist = 0;
|
|
||||||
playGoAhead(dist, getSpeakableJSStreetName(currentSegment, next, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void playPrepareTurn(RouteSegmentResult currentSegment, RouteDirectionInfo next, int dist) {
|
|
||||||
JSCommandBuilder play = (JSCommandBuilder) getNewCommandPlayerToPlay();
|
|
||||||
if (play != null) {
|
|
||||||
String tParam = getTurnType(next.getTurnType());
|
|
||||||
if (tParam != null) {
|
|
||||||
notifyOnVoiceMessage();
|
|
||||||
play.prepareTurn(tParam, dist, getSpeakableJSStreetName(currentSegment, next, true)).play();
|
|
||||||
} else if (next.getTurnType().isRoundAbout()) {
|
|
||||||
notifyOnVoiceMessage();
|
|
||||||
play.prepareRoundAbout(dist, next.getTurnType().getExitOut(), getSpeakableJSStreetName(currentSegment, next, true)).play();
|
|
||||||
} else if (next.getTurnType().getValue() == TurnType.TU || next.getTurnType().getValue() == TurnType.TRU) {
|
|
||||||
notifyOnVoiceMessage();
|
|
||||||
play.prepareMakeUT(dist, getSpeakableJSStreetName(currentSegment, next, true)).play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void playMakeTurnIn(RouteSegmentResult currentSegment, RouteDirectionInfo next, int dist, RouteDirectionInfo pronounceNextNext) {
|
|
||||||
JSCommandBuilder play = (JSCommandBuilder) getNewCommandPlayerToPlay();
|
|
||||||
if (play != null) {
|
|
||||||
String tParam = getTurnType(next.getTurnType());
|
|
||||||
boolean isPlay = true;
|
|
||||||
if (tParam != null) {
|
|
||||||
play.turn(tParam, dist, getSpeakableJSStreetName(currentSegment, next, true));
|
|
||||||
suppressDest = true;
|
|
||||||
} else if (next.getTurnType().isRoundAbout()) {
|
|
||||||
play.roundAbout(dist, next.getTurnType().getTurnAngle(), next.getTurnType().getExitOut(), getSpeakableJSStreetName(currentSegment, next, true));
|
|
||||||
// Other than in prepareTurn, in prepareRoundabout we do not announce destination, so we can repeat it one more time
|
|
||||||
suppressDest = false;
|
|
||||||
} else if (next.getTurnType().getValue() == TurnType.TU || next.getTurnType().getValue() == TurnType.TRU) {
|
|
||||||
play.makeUT(dist, getSpeakableJSStreetName(currentSegment, next, true));
|
|
||||||
suppressDest = true;
|
|
||||||
} else {
|
|
||||||
isPlay = false;
|
|
||||||
}
|
|
||||||
// 'then keep' preparation for next after next. (Also announces an interim straight segment, which is not pronounced above.)
|
|
||||||
if (pronounceNextNext != null) {
|
|
||||||
TurnType t = pronounceNextNext.getTurnType();
|
|
||||||
isPlay = true;
|
|
||||||
if (t.getValue() != TurnType.C && next.getTurnType().getValue() == TurnType.C) {
|
|
||||||
play.goAhead(dist, getSpeakableJSStreetName(currentSegment, next, true));
|
|
||||||
}
|
|
||||||
if (t.getValue() == TurnType.TL || t.getValue() == TurnType.TSHL || t.getValue() == TurnType.TSLL
|
|
||||||
|| t.getValue() == TurnType.TU || t.getValue() == TurnType.KL ) {
|
|
||||||
play.then().bearLeft(getSpeakableJSStreetName(currentSegment, next, false));
|
|
||||||
} else if (t.getValue() == TurnType.TR || t.getValue() == TurnType.TSHR || t.getValue() == TurnType.TSLR
|
|
||||||
|| t.getValue() == TurnType.TRU || t.getValue() == TurnType.KR) {
|
|
||||||
play.then().bearRight(getSpeakableJSStreetName(currentSegment, next, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isPlay) {
|
|
||||||
notifyOnVoiceMessage();
|
|
||||||
play.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void playGoAhead(int dist, Map<String, String> streetName) {
|
|
||||||
CommandBuilder play = getNewCommandPlayerToPlay();
|
|
||||||
JSCommandBuilder playJs = (JSCommandBuilder) play;
|
|
||||||
if (play != null) {
|
|
||||||
notifyOnVoiceMessage();
|
|
||||||
playJs.goAhead(dist, streetName).play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void playMakeTurn(RouteSegmentResult currentSegment, RouteDirectionInfo next, RouteCalculationResult.NextDirectionInfo nextNextInfo) {
|
|
||||||
JSCommandBuilder play = (JSCommandBuilder) getNewCommandPlayerToPlay();
|
|
||||||
if (play != null) {
|
|
||||||
String tParam = getTurnType(next.getTurnType());
|
|
||||||
boolean isplay = true;
|
|
||||||
if (tParam != null) {
|
|
||||||
play.turn(tParam, getSpeakableJSStreetName(currentSegment, next, !suppressDest));
|
|
||||||
} else if (next.getTurnType().isRoundAbout()) {
|
|
||||||
play.roundAbout(next.getTurnType().getTurnAngle(), next.getTurnType().getExitOut(), getSpeakableJSStreetName(currentSegment, next, !suppressDest));
|
|
||||||
} else if (next.getTurnType().getValue() == TurnType.TU || next.getTurnType().getValue() == TurnType.TRU) {
|
|
||||||
play.makeUT(getSpeakableJSStreetName(currentSegment, next, !suppressDest));
|
|
||||||
// Do not announce goAheads
|
|
||||||
//} else if (next.getTurnType().getValue() == TurnType.C)) {
|
|
||||||
// play.goAhead();
|
|
||||||
} else {
|
|
||||||
isplay = false;
|
|
||||||
}
|
|
||||||
// Add turn after next
|
|
||||||
if ((nextNextInfo != null) && (nextNextInfo.directionInfo != null)) {
|
|
||||||
|
|
||||||
// This case only needed should we want a prompt at the end of straight segments (equivalent of makeTurn) when nextNextInfo should be announced again there.
|
|
||||||
if (nextNextInfo.directionInfo.getTurnType().getValue() != TurnType.C && next.getTurnType().getValue() == TurnType.C) {
|
|
||||||
play.goAhead();
|
|
||||||
isplay = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
String t2Param = getTurnType(nextNextInfo.directionInfo.getTurnType());
|
|
||||||
if (t2Param != null) {
|
|
||||||
if (isplay) {
|
|
||||||
play.then();
|
|
||||||
play.turn(t2Param, nextNextInfo.distanceTo, new HashMap<String, String>());
|
|
||||||
}
|
|
||||||
} else if (nextNextInfo.directionInfo.getTurnType().isRoundAbout()) {
|
|
||||||
if (isplay) {
|
|
||||||
play.then();
|
|
||||||
play.roundAbout(nextNextInfo.distanceTo, nextNextInfo.directionInfo.getTurnType().getTurnAngle(),
|
|
||||||
nextNextInfo.directionInfo.getTurnType().getExitOut(), new HashMap<String, String>());
|
|
||||||
}
|
|
||||||
} else if (nextNextInfo.directionInfo.getTurnType().getValue() == TurnType.TU) {
|
|
||||||
if (isplay) {
|
|
||||||
play.then();
|
|
||||||
play.makeUT(nextNextInfo.distanceTo, new HashMap<String, String>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isplay) {
|
|
||||||
notifyOnVoiceMessage();
|
|
||||||
play.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void playGoAndArriveAtDestination(boolean repeat, RouteCalculationResult.NextDirectionInfo nextInfo, RouteSegmentResult currentSegment) {
|
|
||||||
RouteDirectionInfo next = nextInfo.directionInfo;
|
|
||||||
if (isTargetPoint(nextInfo) && (!playedAndArriveAtTarget || repeat)) {
|
|
||||||
if (next.getTurnType().goAhead()) {
|
|
||||||
playGoAhead(nextInfo.distanceTo, getSpeakableJSStreetName(currentSegment, next, false));
|
|
||||||
playAndArriveAtDestination(nextInfo);
|
|
||||||
playedAndArriveAtTarget = true;
|
|
||||||
} else if (nextInfo.distanceTo <= 2 * TURN_IN_DISTANCE) {
|
|
||||||
playAndArriveAtDestination(nextInfo);
|
|
||||||
playedAndArriveAtTarget = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -97,9 +97,7 @@ public class RoutingHelper {
|
||||||
public RoutingHelper(OsmandApplication context){
|
public RoutingHelper(OsmandApplication context){
|
||||||
this.app = context;
|
this.app = context;
|
||||||
settings = context.getSettings();
|
settings = context.getSettings();
|
||||||
boolean useJS = settings.USE_JS_VOICE_GUIDANCE.get();
|
voiceRouter = new VoiceRouter(this, settings);
|
||||||
voiceRouter = useJS ? new JSVoiceRouter(this, settings)
|
|
||||||
: new VoiceRouter(this, settings);
|
|
||||||
provider = new RouteProvider();
|
provider = new RouteProvider();
|
||||||
setAppMode(settings.APPLICATION_MODE.get());
|
setAppMode(settings.APPLICATION_MODE.get());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@ package net.osmand.plus.routing;
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import net.osmand.Location;
|
import net.osmand.Location;
|
||||||
|
@ -13,6 +15,7 @@ import net.osmand.plus.OsmandSettings;
|
||||||
import net.osmand.plus.helpers.WaypointHelper.LocationPointWrapper;
|
import net.osmand.plus.helpers.WaypointHelper.LocationPointWrapper;
|
||||||
import net.osmand.plus.routing.AlarmInfo.AlarmInfoType;
|
import net.osmand.plus.routing.AlarmInfo.AlarmInfoType;
|
||||||
import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo;
|
import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo;
|
||||||
|
import net.osmand.plus.routing.data.StreetName;
|
||||||
import net.osmand.plus.voice.AbstractPrologCommandPlayer;
|
import net.osmand.plus.voice.AbstractPrologCommandPlayer;
|
||||||
import net.osmand.plus.voice.CommandBuilder;
|
import net.osmand.plus.voice.CommandBuilder;
|
||||||
import net.osmand.plus.voice.CommandPlayer;
|
import net.osmand.plus.voice.CommandPlayer;
|
||||||
|
@ -28,48 +31,51 @@ import android.media.SoundPool;
|
||||||
|
|
||||||
public class VoiceRouter {
|
public class VoiceRouter {
|
||||||
private static final int STATUS_UTWP_TOLD = -1;
|
private static final int STATUS_UTWP_TOLD = -1;
|
||||||
static final int STATUS_UNKNOWN = 0;
|
private static final int STATUS_UNKNOWN = 0;
|
||||||
static final int STATUS_LONG_PREPARE = 1;
|
private static final int STATUS_LONG_PREPARE = 1;
|
||||||
static final int STATUS_PREPARE = 2;
|
private static final int STATUS_PREPARE = 2;
|
||||||
static final int STATUS_TURN_IN = 3;
|
private static final int STATUS_TURN_IN = 3;
|
||||||
static final int STATUS_TURN = 4;
|
private static final int STATUS_TURN = 4;
|
||||||
static final int STATUS_TOLD = 5;
|
private static final int STATUS_TOLD = 5;
|
||||||
|
public static final String TO_REF = "toRef";
|
||||||
|
public static final String TO_STREET_NAME = "toStreetName";
|
||||||
|
public static final String TO_DEST = "toDest";
|
||||||
|
public static final String FROM_REF = "fromRef";
|
||||||
|
public static final String FROM_STREET_NAME = "fromStreetName";
|
||||||
|
public static final String FROM_DEST = "fromDest";
|
||||||
|
|
||||||
protected final RoutingHelper router;
|
protected final RoutingHelper router;
|
||||||
protected static CommandPlayer player;
|
protected static CommandPlayer player;
|
||||||
protected final OsmandSettings settings;
|
protected final OsmandSettings settings;
|
||||||
|
|
||||||
private static boolean mute = false;
|
private static boolean mute = false;
|
||||||
static int currentStatus = STATUS_UNKNOWN;
|
private static int currentStatus = STATUS_UNKNOWN;
|
||||||
static boolean playedAndArriveAtTarget = false;
|
private static boolean playedAndArriveAtTarget = false;
|
||||||
static float playGoAheadDist = 0;
|
private static float playGoAheadDist = 0;
|
||||||
private static long lastAnnouncedSpeedLimit = 0;
|
private static long lastAnnouncedSpeedLimit = 0;
|
||||||
private static long waitAnnouncedSpeedLimit = 0;
|
private static long waitAnnouncedSpeedLimit = 0;
|
||||||
private static long lastAnnouncedOffRoute = 0;
|
private static long lastAnnouncedOffRoute = 0;
|
||||||
private static long waitAnnouncedOffRoute = 0;
|
private static long waitAnnouncedOffRoute = 0;
|
||||||
static boolean suppressDest = false;
|
private static boolean suppressDest = false;
|
||||||
static boolean announceBackOnRoute = false;
|
private static boolean announceBackOnRoute = false;
|
||||||
// private static long lastTimeRouteRecalcAnnounced = 0;
|
// private static long lastTimeRouteRecalcAnnounced = 0;
|
||||||
// Remember when last announcement was made
|
// Remember when last announcement was made
|
||||||
private static long lastAnnouncement = 0;
|
private static long lastAnnouncement = 0;
|
||||||
|
|
||||||
// Default speed to have comfortable announcements (Speed in m/s)
|
// Default speed to have comfortable announcements (Speed in m/s)
|
||||||
protected float DEFAULT_SPEED = 12;
|
private float DEFAULT_SPEED = 12;
|
||||||
protected float TURN_DEFAULT_SPEED = 5;
|
private float TURN_DEFAULT_SPEED = 5;
|
||||||
|
|
||||||
protected int PREPARE_LONG_DISTANCE = 0;
|
private int PREPARE_LONG_DISTANCE = 0;
|
||||||
protected int PREPARE_LONG_DISTANCE_END = 0;
|
private int PREPARE_LONG_DISTANCE_END = 0;
|
||||||
protected int PREPARE_DISTANCE = 0;
|
protected int PREPARE_DISTANCE = 0;
|
||||||
protected int PREPARE_DISTANCE_END = 0;
|
private int PREPARE_DISTANCE_END = 0;
|
||||||
protected int TURN_IN_DISTANCE = 0;
|
private int TURN_IN_DISTANCE = 0;
|
||||||
protected int TURN_IN_DISTANCE_END = 0;
|
private int TURN_IN_DISTANCE_END = 0;
|
||||||
protected int TURN_DISTANCE = 0;
|
private int TURN_DISTANCE = 0;
|
||||||
|
|
||||||
protected static VoiceCommandPending pendingCommand = null;
|
private static VoiceCommandPending pendingCommand = null;
|
||||||
static RouteDirectionInfo nextRouteDirection;
|
private static RouteDirectionInfo nextRouteDirection;
|
||||||
private Term empty;
|
|
||||||
|
|
||||||
private boolean useJS;
|
|
||||||
|
|
||||||
public interface VoiceMessageListener {
|
public interface VoiceMessageListener {
|
||||||
void onVoiceMessage();
|
void onVoiceMessage();
|
||||||
|
@ -77,17 +83,15 @@ public class VoiceRouter {
|
||||||
|
|
||||||
private ConcurrentHashMap<VoiceMessageListener, Integer> voiceMessageListeners;
|
private ConcurrentHashMap<VoiceMessageListener, Integer> voiceMessageListeners;
|
||||||
|
|
||||||
public VoiceRouter(RoutingHelper router, final OsmandSettings settings) {
|
VoiceRouter(RoutingHelper router, final OsmandSettings settings) {
|
||||||
this.router = router;
|
this.router = router;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
useJS = settings.USE_JS_VOICE_GUIDANCE.get();
|
mute = settings.VOICE_MUTE.get();
|
||||||
this.mute = settings.VOICE_MUTE.get();
|
|
||||||
empty = new Struct("");
|
|
||||||
voiceMessageListeners = new ConcurrentHashMap<VoiceRouter.VoiceMessageListener, Integer>();
|
voiceMessageListeners = new ConcurrentHashMap<VoiceRouter.VoiceMessageListener, Integer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlayer(CommandPlayer player) {
|
public void setPlayer(CommandPlayer player) {
|
||||||
this.player = player;
|
VoiceRouter.player = player;
|
||||||
if (pendingCommand != null && player != null) {
|
if (pendingCommand != null && player != null) {
|
||||||
CommandBuilder newCommand = getNewCommandPlayerToPlay();
|
CommandBuilder newCommand = getNewCommandPlayerToPlay();
|
||||||
if (newCommand != null) {
|
if (newCommand != null) {
|
||||||
|
@ -109,7 +113,7 @@ public class VoiceRouter {
|
||||||
return mute;
|
return mute;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CommandBuilder getNewCommandPlayerToPlay() {
|
private CommandBuilder getNewCommandPlayerToPlay() {
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -167,7 +171,7 @@ public class VoiceRouter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double btScoDelayDistance = 0;
|
private double btScoDelayDistance = 0;
|
||||||
|
|
||||||
public boolean isDistanceLess(float currentSpeed, double dist, double etalon, float defSpeed) {
|
public boolean isDistanceLess(float currentSpeed, double dist, double etalon, float defSpeed) {
|
||||||
if (defSpeed <= 0) {
|
if (defSpeed <= 0) {
|
||||||
|
@ -204,7 +208,7 @@ public class VoiceRouter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nextStatusAfter(int previousStatus) {
|
private void nextStatusAfter(int previousStatus) {
|
||||||
//STATUS_UNKNOWN=0 -> STATUS_LONG_PREPARE=1 -> STATUS_PREPARE=2 -> STATUS_TURN_IN=3 -> STATUS_TURN=4 -> STATUS_TOLD=5
|
//STATUS_UNKNOWN=0 -> STATUS_LONG_PREPARE=1 -> STATUS_PREPARE=2 -> STATUS_TURN_IN=3 -> STATUS_TURN=4 -> STATUS_TOLD=5
|
||||||
if (previousStatus != STATUS_TOLD) {
|
if (previousStatus != STATUS_TOLD) {
|
||||||
this.currentStatus = previousStatus + 1;
|
this.currentStatus = previousStatus + 1;
|
||||||
|
@ -213,7 +217,7 @@ public class VoiceRouter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean statusNotPassed(int statusToCheck) {
|
private boolean statusNotPassed(int statusToCheck) {
|
||||||
return currentStatus <= statusToCheck;
|
return currentStatus <= statusToCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +241,7 @@ public class VoiceRouter {
|
||||||
|
|
||||||
public void announceBackOnRoute() {
|
public void announceBackOnRoute() {
|
||||||
CommandBuilder p = getNewCommandPlayerToPlay();
|
CommandBuilder p = getNewCommandPlayerToPlay();
|
||||||
if (announceBackOnRoute == true) {
|
if (announceBackOnRoute) {
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
notifyOnVoiceMessage();
|
notifyOnVoiceMessage();
|
||||||
p.backOnRoute().play();
|
p.backOnRoute().play();
|
||||||
|
@ -398,14 +402,14 @@ public class VoiceRouter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isTargetPoint(NextDirectionInfo info) {
|
private boolean isTargetPoint(NextDirectionInfo info) {
|
||||||
boolean in = info != null && info.intermediatePoint;
|
boolean in = info != null && info.intermediatePoint;
|
||||||
boolean target = info == null || info.directionInfo == null
|
boolean target = info == null || info.directionInfo == null
|
||||||
|| info.directionInfo.distance == 0;
|
|| info.directionInfo.distance == 0;
|
||||||
return in || target;
|
return in || target;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean needsInforming() {
|
private boolean needsInforming() {
|
||||||
final Integer repeat = settings.KEEP_INFORMING.get();
|
final Integer repeat = settings.KEEP_INFORMING.get();
|
||||||
if (repeat == null || repeat == 0) return false;
|
if (repeat == null || repeat == 0) return false;
|
||||||
|
|
||||||
|
@ -485,13 +489,13 @@ public class VoiceRouter {
|
||||||
// Distance fon non-straights already announced in "Turn (now)"'s nextnext code above
|
// Distance fon non-straights already announced in "Turn (now)"'s nextnext code above
|
||||||
if ((nextNextInfo != null) && (nextNextInfo.directionInfo != null) && nextNextInfo.directionInfo.getTurnType().goAhead()) {
|
if ((nextNextInfo != null) && (nextNextInfo.directionInfo != null) && nextNextInfo.directionInfo.getTurnType().goAhead()) {
|
||||||
playThen();
|
playThen();
|
||||||
playGoAhead(nextNextInfo.distanceTo, empty);
|
playGoAhead(nextNextInfo.distanceTo, new StreetName());
|
||||||
}
|
}
|
||||||
playAndArriveAtDestination(nextNextInfo);
|
playAndArriveAtDestination(nextNextInfo);
|
||||||
} else if (nextNextInfo.distanceTo < 1.2f * TURN_IN_DISTANCE_END) {
|
} else if (nextNextInfo.distanceTo < 1.2f * TURN_IN_DISTANCE_END) {
|
||||||
// 1.2 is safety margin should the subsequent "Turn in" prompt not fit in amy more
|
// 1.2 is safety margin should the subsequent "Turn in" prompt not fit in amy more
|
||||||
playThen();
|
playThen();
|
||||||
playGoAhead(nextNextInfo.distanceTo, empty);
|
playGoAhead(nextNextInfo.distanceTo, new StreetName());
|
||||||
playAndArriveAtDestination(nextNextInfo);
|
playAndArriveAtDestination(nextNextInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,7 +572,7 @@ public class VoiceRouter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playGoAhead(int dist, Term streetName) {
|
private void playGoAhead(int dist, StreetName streetName) {
|
||||||
CommandBuilder play = getNewCommandPlayerToPlay();
|
CommandBuilder play = getNewCommandPlayerToPlay();
|
||||||
if (play != null) {
|
if (play != null) {
|
||||||
notifyOnVoiceMessage();
|
notifyOnVoiceMessage();
|
||||||
|
@ -576,57 +580,54 @@ public class VoiceRouter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Term getSpeakableStreetName(RouteSegmentResult currentSegment, RouteDirectionInfo i, boolean includeDest) {
|
private StreetName getSpeakableStreetName(RouteSegmentResult currentSegment, RouteDirectionInfo i, boolean includeDest) {
|
||||||
|
Map<String, String> result = new HashMap<>();
|
||||||
if (i == null || !router.getSettings().SPEAK_STREET_NAMES.get()) {
|
if (i == null || !router.getSettings().SPEAK_STREET_NAMES.get()) {
|
||||||
return empty;
|
return new StreetName(result);
|
||||||
}
|
}
|
||||||
if (player != null && player.supportsStructuredStreetNames()) {
|
if (player != null && player.supportsStructuredStreetNames()) {
|
||||||
Term next = empty;
|
|
||||||
// Issue 2377: Play Dest here only if not already previously announced, to avoid repetition
|
// Issue 2377: Play Dest here only if not already previously announced, to avoid repetition
|
||||||
if (includeDest == true) {
|
if (includeDest == true) {
|
||||||
next = new Struct(new Term[] { getTermString(getSpeakablePointName(i.getRef())),
|
result.put(TO_REF, getNonNullString(getSpeakablePointName(i.getRef())));
|
||||||
getTermString(getSpeakablePointName(i.getStreetName())),
|
result.put(TO_STREET_NAME, getNonNullString(getSpeakablePointName(i.getStreetName())));
|
||||||
getTermString(getSpeakablePointName(i.getDestinationName())) });
|
result.put(TO_DEST, getNonNullString(getSpeakablePointName(i.getDestinationName())));
|
||||||
} else {
|
} else {
|
||||||
next = new Struct(new Term[] { getTermString(getSpeakablePointName(i.getRef())),
|
result.put(TO_REF, getNonNullString(getSpeakablePointName(i.getRef())));
|
||||||
getTermString(getSpeakablePointName(i.getStreetName())),
|
result.put(TO_STREET_NAME, getNonNullString(getSpeakablePointName(i.getStreetName())));
|
||||||
empty });
|
result.put(TO_DEST, "");
|
||||||
}
|
}
|
||||||
Term current = empty;
|
|
||||||
if (currentSegment != null) {
|
if (currentSegment != null) {
|
||||||
// Issue 2377: Play Dest here only if not already previously announced, to avoid repetition
|
// Issue 2377: Play Dest here only if not already previously announced, to avoid repetition
|
||||||
if (includeDest == true) {
|
if (includeDest == true) {
|
||||||
RouteDataObject obj = currentSegment.getObject();
|
RouteDataObject obj = currentSegment.getObject();
|
||||||
current = new Struct(new Term[] { getTermString(getSpeakablePointName(obj.getRef(settings.MAP_PREFERRED_LOCALE.get(),
|
result.put(FROM_REF, getNonNullString(getSpeakablePointName(obj.getRef(settings.MAP_PREFERRED_LOCALE.get(),
|
||||||
settings.MAP_TRANSLITERATE_NAMES.get(), currentSegment.isForwardDirection()))),
|
settings.MAP_TRANSLITERATE_NAMES.get(), currentSegment.isForwardDirection()))));
|
||||||
getTermString(getSpeakablePointName(obj.getName(settings.MAP_PREFERRED_LOCALE.get(), settings.MAP_TRANSLITERATE_NAMES.get()))),
|
result.put(FROM_STREET_NAME, getNonNullString(getSpeakablePointName(obj.getName(settings.MAP_PREFERRED_LOCALE.get(),
|
||||||
getTermString(getSpeakablePointName(obj.getDestinationName(settings.MAP_PREFERRED_LOCALE.get(),
|
settings.MAP_TRANSLITERATE_NAMES.get()))));
|
||||||
settings.MAP_TRANSLITERATE_NAMES.get(), currentSegment.isForwardDirection()))) });
|
result.put(FROM_DEST, getNonNullString(getSpeakablePointName(obj.getDestinationName(settings.MAP_PREFERRED_LOCALE.get(),
|
||||||
|
settings.MAP_TRANSLITERATE_NAMES.get(), currentSegment.isForwardDirection()))));
|
||||||
} else {
|
} else {
|
||||||
RouteDataObject obj = currentSegment.getObject();
|
RouteDataObject obj = currentSegment.getObject();
|
||||||
current = new Struct(new Term[] { getTermString(getSpeakablePointName(obj.getRef(settings.MAP_PREFERRED_LOCALE.get(),
|
result.put(FROM_REF, getNonNullString(getSpeakablePointName(obj.getRef(settings.MAP_PREFERRED_LOCALE.get(),
|
||||||
settings.MAP_TRANSLITERATE_NAMES.get(), currentSegment.isForwardDirection()))),
|
settings.MAP_TRANSLITERATE_NAMES.get(), currentSegment.isForwardDirection()))));
|
||||||
getTermString(getSpeakablePointName(obj.getName(settings.MAP_PREFERRED_LOCALE.get(),
|
result.put(FROM_STREET_NAME, getNonNullString(getSpeakablePointName(obj.getName(settings.MAP_PREFERRED_LOCALE.get(),
|
||||||
settings.MAP_TRANSLITERATE_NAMES.get()))),
|
settings.MAP_TRANSLITERATE_NAMES.get()))));
|
||||||
empty });
|
result.put(FROM_DEST, "");
|
||||||
}
|
|
||||||
}
|
|
||||||
Struct voice = new Struct("voice", next, current );
|
|
||||||
return voice;
|
|
||||||
} else {
|
|
||||||
Term rf = getTermString(getSpeakablePointName(i.getRef()));
|
|
||||||
if (rf == empty) {
|
|
||||||
rf = getTermString(getSpeakablePointName(i.getStreetName()));
|
|
||||||
}
|
|
||||||
return rf;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Term getTermString(String s) {
|
} else {
|
||||||
if (!Algorithms.isEmpty(s)) {
|
result.put("toRef", getNonNullString(getSpeakablePointName(i.getRef())));
|
||||||
return new Struct(s);
|
result.put(TO_STREET_NAME, getNonNullString(getSpeakablePointName(i.getStreetName())));
|
||||||
|
result.put(TO_DEST, "");
|
||||||
}
|
}
|
||||||
return empty;
|
return new StreetName(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String getNonNullString(String speakablePointName) {
|
||||||
|
return speakablePointName == null ? "" : speakablePointName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSpeakablePointName(String pn) {
|
public static String getSpeakablePointName(String pn) {
|
||||||
|
@ -718,7 +719,7 @@ public class VoiceRouter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void playAndArriveAtDestination(NextDirectionInfo info) {
|
private void playAndArriveAtDestination(NextDirectionInfo info) {
|
||||||
if (isTargetPoint(info)) {
|
if (isTargetPoint(info)) {
|
||||||
String pointName = info == null ? "" : info.pointName;
|
String pointName = info == null ? "" : info.pointName;
|
||||||
CommandBuilder play = getNewCommandPlayerToPlay();
|
CommandBuilder play = getNewCommandPlayerToPlay();
|
||||||
|
@ -763,17 +764,17 @@ public class VoiceRouter {
|
||||||
if (t2Param != null) {
|
if (t2Param != null) {
|
||||||
if (isplay) {
|
if (isplay) {
|
||||||
play.then();
|
play.then();
|
||||||
play.turn(t2Param, nextNextInfo.distanceTo, empty);
|
play.turn(t2Param, nextNextInfo.distanceTo, new StreetName());
|
||||||
}
|
}
|
||||||
} else if (nextNextInfo.directionInfo.getTurnType().isRoundAbout()) {
|
} else if (nextNextInfo.directionInfo.getTurnType().isRoundAbout()) {
|
||||||
if (isplay) {
|
if (isplay) {
|
||||||
play.then();
|
play.then();
|
||||||
play.roundAbout(nextNextInfo.distanceTo, nextNextInfo.directionInfo.getTurnType().getTurnAngle(), nextNextInfo.directionInfo.getTurnType().getExitOut(), empty);
|
play.roundAbout(nextNextInfo.distanceTo, nextNextInfo.directionInfo.getTurnType().getTurnAngle(), nextNextInfo.directionInfo.getTurnType().getExitOut(), new StreetName());
|
||||||
}
|
}
|
||||||
} else if (nextNextInfo.directionInfo.getTurnType().getValue() == TurnType.TU) {
|
} else if (nextNextInfo.directionInfo.getTurnType().getValue() == TurnType.TU) {
|
||||||
if (isplay) {
|
if (isplay) {
|
||||||
play.then();
|
play.then();
|
||||||
play.makeUT(nextNextInfo.distanceTo, empty);
|
play.makeUT(nextNextInfo.distanceTo, new StreetName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -784,7 +785,7 @@ public class VoiceRouter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String getTurnType(TurnType t) {
|
private String getTurnType(TurnType t) {
|
||||||
if (TurnType.TL == t.getValue()) {
|
if (TurnType.TL == t.getValue()) {
|
||||||
return AbstractPrologCommandPlayer.A_LEFT;
|
return AbstractPrologCommandPlayer.A_LEFT;
|
||||||
} else if (TurnType.TSHL == t.getValue()) {
|
} else if (TurnType.TSHL == t.getValue()) {
|
||||||
|
|
56
OsmAnd/src/net/osmand/plus/routing/data/StreetName.java
Normal file
56
OsmAnd/src/net/osmand/plus/routing/data/StreetName.java
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package net.osmand.plus.routing.data;
|
||||||
|
|
||||||
|
import net.osmand.plus.routing.VoiceRouter;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import alice.tuprolog.Struct;
|
||||||
|
import alice.tuprolog.Term;
|
||||||
|
|
||||||
|
public class StreetName {
|
||||||
|
|
||||||
|
private Map<String, String> names;
|
||||||
|
private static final Term empty = new Struct("");;
|
||||||
|
|
||||||
|
public StreetName(Map<String, String> data) {
|
||||||
|
this.names = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StreetName() {
|
||||||
|
names = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> toMap() {
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Term toTerm() {
|
||||||
|
if (names == null || names.isEmpty()) {
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
if (names.size() > 3) {
|
||||||
|
Term next = new Struct(new Term[]{getTermString(names.get(VoiceRouter.TO_REF)),
|
||||||
|
getTermString(names.get(VoiceRouter.TO_STREET_NAME)),
|
||||||
|
getTermString(names.get(VoiceRouter.TO_DEST))});
|
||||||
|
Term current = new Struct(new Term[]{getTermString(names.get(VoiceRouter.FROM_REF)),
|
||||||
|
getTermString(names.get(VoiceRouter.FROM_STREET_NAME)),
|
||||||
|
getTermString(names.get(VoiceRouter.FROM_DEST))});
|
||||||
|
return new Struct("voice", next, current);
|
||||||
|
} else {
|
||||||
|
Term rf = getTermString(names.get(VoiceRouter.TO_REF));
|
||||||
|
if (rf == empty) {
|
||||||
|
rf = getTermString(names.get(VoiceRouter.TO_STREET_NAME));
|
||||||
|
}
|
||||||
|
return rf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Term getTermString(String s) {
|
||||||
|
if (!Algorithms.isEmpty(s)) {
|
||||||
|
return new Struct(s);
|
||||||
|
}
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import java.util.List;
|
||||||
|
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.routing.data.StreetName;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
@ -80,6 +81,8 @@ public class CommandBuilder {
|
||||||
Object o = args[i];
|
Object o = args[i];
|
||||||
if(o instanceof Term){
|
if(o instanceof Term){
|
||||||
list[i] = (Term) o;
|
list[i] = (Term) o;
|
||||||
|
} else if (o instanceof StreetName){
|
||||||
|
list[i] = ((StreetName)o).toTerm();
|
||||||
} else if(o instanceof java.lang.Number){
|
} else if(o instanceof java.lang.Number){
|
||||||
if(o instanceof java.lang.Double){
|
if(o instanceof java.lang.Double){
|
||||||
list[i] = new alice.tuprolog.Double((Double) o);
|
list[i] = new alice.tuprolog.Double((Double) o);
|
||||||
|
@ -113,12 +116,11 @@ public class CommandBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CommandBuilder goAhead(){
|
public CommandBuilder goAhead(){
|
||||||
return addCommand(C_GO_AHEAD);
|
return addCommand(C_GO_AHEAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder goAhead(double dist, Term streetName){
|
public CommandBuilder goAhead(double dist, StreetName streetName){
|
||||||
return alt(prepareStruct(C_GO_AHEAD, dist, streetName), prepareStruct(C_GO_AHEAD, dist));
|
return alt(prepareStruct(C_GO_AHEAD, dist, streetName), prepareStruct(C_GO_AHEAD, dist));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +128,7 @@ public class CommandBuilder {
|
||||||
return addCommand(C_MAKE_UTWP);
|
return addCommand(C_MAKE_UTWP);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder makeUT(Term streetName){
|
public CommandBuilder makeUT(StreetName streetName){
|
||||||
return alt(prepareStruct(C_MAKE_UT, streetName), prepareStruct(C_MAKE_UT));
|
return alt(prepareStruct(C_MAKE_UT, streetName), prepareStruct(C_MAKE_UT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,20 +148,19 @@ public class CommandBuilder {
|
||||||
return addCommand(C_BACK_ON_ROUTE);
|
return addCommand(C_BACK_ON_ROUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder makeUT(double dist, Term streetName){
|
public CommandBuilder makeUT(double dist, StreetName streetName){
|
||||||
return alt(prepareStruct(C_MAKE_UT, dist, streetName), prepareStruct(C_MAKE_UT, dist));
|
return alt(prepareStruct(C_MAKE_UT, dist, streetName), prepareStruct(C_MAKE_UT, dist));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder prepareMakeUT(double dist, Term streetName){
|
public CommandBuilder prepareMakeUT(double dist, StreetName streetName){
|
||||||
return alt(prepareStruct(C_PREPARE_MAKE_UT, dist, streetName), prepareStruct(C_PREPARE_MAKE_UT, dist));
|
return alt(prepareStruct(C_PREPARE_MAKE_UT, dist, streetName), prepareStruct(C_PREPARE_MAKE_UT, dist));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandBuilder turn(String param, StreetName streetName) {
|
||||||
public CommandBuilder turn(String param, Term streetName) {
|
|
||||||
return alt(prepareStruct(C_TURN, param, streetName), prepareStruct(C_TURN, param));
|
return alt(prepareStruct(C_TURN, param, streetName), prepareStruct(C_TURN, param));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder turn(String param, double dist, Term streetName){
|
public CommandBuilder turn(String param, double dist, StreetName streetName){
|
||||||
return alt(prepareStruct(C_TURN, param, dist, streetName), prepareStruct(C_TURN, param, dist));
|
return alt(prepareStruct(C_TURN, param, dist, streetName), prepareStruct(C_TURN, param, dist));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,19 +170,19 @@ public class CommandBuilder {
|
||||||
* @param dist
|
* @param dist
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public CommandBuilder prepareTurn(String param, double dist, Term streetName){
|
public CommandBuilder prepareTurn(String param, double dist, StreetName streetName){
|
||||||
return alt(prepareStruct(C_PREPARE_TURN, param, dist, streetName), prepareStruct(C_PREPARE_TURN, param, dist));
|
return alt(prepareStruct(C_PREPARE_TURN, param, dist, streetName), prepareStruct(C_PREPARE_TURN, param, dist));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder prepareRoundAbout(double dist, int exit, Term streetName){
|
public CommandBuilder prepareRoundAbout(double dist, int exit, StreetName streetName){
|
||||||
return alt(prepareStruct(C_PREPARE_ROUNDABOUT, dist, exit, streetName), prepareStruct(C_PREPARE_ROUNDABOUT, dist));
|
return alt(prepareStruct(C_PREPARE_ROUNDABOUT, dist, exit, streetName), prepareStruct(C_PREPARE_ROUNDABOUT, dist));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder roundAbout(double dist, double angle, int exit, Term streetName){
|
public CommandBuilder roundAbout(double dist, double angle, int exit, StreetName streetName){
|
||||||
return alt(prepareStruct(C_ROUNDABOUT, dist, angle, exit, streetName), prepareStruct(C_ROUNDABOUT, dist, angle, exit));
|
return alt(prepareStruct(C_ROUNDABOUT, dist, angle, exit, streetName), prepareStruct(C_ROUNDABOUT, dist, angle, exit));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder roundAbout(double angle, int exit, Term streetName) {
|
public CommandBuilder roundAbout(double angle, int exit, StreetName streetName) {
|
||||||
return alt(prepareStruct(C_ROUNDABOUT, angle, exit, streetName), prepareStruct(C_ROUNDABOUT, angle, exit));
|
return alt(prepareStruct(C_ROUNDABOUT, angle, exit, streetName), prepareStruct(C_ROUNDABOUT, angle, exit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,11 +226,11 @@ public class CommandBuilder {
|
||||||
return addCommand(C_REACHED_POI, name);
|
return addCommand(C_REACHED_POI, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder bearLeft(Term streetName){
|
public CommandBuilder bearLeft(StreetName streetName){
|
||||||
return alt(prepareStruct(C_BEAR_LEFT, streetName), prepareStruct(C_BEAR_LEFT));
|
return alt(prepareStruct(C_BEAR_LEFT, streetName), prepareStruct(C_BEAR_LEFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder bearRight(Term streetName){
|
public CommandBuilder bearRight(StreetName streetName){
|
||||||
return alt(prepareStruct(C_BEAR_RIGHT, streetName), prepareStruct(C_BEAR_RIGHT));
|
return alt(prepareStruct(C_BEAR_RIGHT, streetName), prepareStruct(C_BEAR_RIGHT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package net.osmand.plus.voice;
|
package net.osmand.plus.voice;
|
||||||
|
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
|
import net.osmand.plus.routing.data.StreetName;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
@ -40,8 +41,8 @@ public class JSCommandBuilder extends CommandBuilder {
|
||||||
this.jsScope = jsScope;
|
this.jsScope = jsScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object convertStreetName(Map<String, String> streetName) {
|
private Object convertStreetName(StreetName streetName) {
|
||||||
return NativeJSON.parse(jsContext, jsScope, new JSONObject(streetName).toString(),
|
return NativeJSON.parse(jsContext, jsScope, new JSONObject(streetName.toMap()).toString(),
|
||||||
new NullCallable());
|
new NullCallable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,18 +71,19 @@ public class JSCommandBuilder extends CommandBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSCommandBuilder goAhead(){
|
public JSCommandBuilder goAhead(){
|
||||||
return goAhead(-1, new HashMap<String, String>());
|
return goAhead(-1, new StreetName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSCommandBuilder goAhead(double dist, Map<String, String> streetName){
|
public JSCommandBuilder goAhead(double dist, StreetName streetName){
|
||||||
return addCommand(C_GO_AHEAD, dist, convertStreetName(streetName));
|
return addCommand(C_GO_AHEAD, dist, convertStreetName(streetName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public JSCommandBuilder makeUTwp(){
|
public JSCommandBuilder makeUTwp(){
|
||||||
return makeUT(new HashMap<String, String>());
|
return makeUT(new StreetName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSCommandBuilder makeUT(Map<String, String> streetName){
|
public JSCommandBuilder makeUT(StreetName streetName){
|
||||||
return makeUT(-1, streetName);
|
return makeUT(-1, streetName);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -101,20 +103,20 @@ public class JSCommandBuilder extends CommandBuilder {
|
||||||
return addCommand(C_BACK_ON_ROUTE);
|
return addCommand(C_BACK_ON_ROUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSCommandBuilder makeUT(double dist, Map<String,String> streetName){
|
public JSCommandBuilder makeUT(double dist, StreetName streetName){
|
||||||
return addCommand(C_MAKE_UT, dist, convertStreetName(streetName));
|
return addCommand(C_MAKE_UT, dist, convertStreetName(streetName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSCommandBuilder prepareMakeUT(double dist, Map<String, String> streetName){
|
public JSCommandBuilder prepareMakeUT(double dist, StreetName streetName){
|
||||||
return addCommand(C_PREPARE_MAKE_UT, dist, convertStreetName(streetName));
|
return addCommand(C_PREPARE_MAKE_UT, dist, convertStreetName(streetName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public JSCommandBuilder turn(String param, Map<String, String> streetName) {
|
public JSCommandBuilder turn(String param, StreetName streetName) {
|
||||||
return turn(param, -1, streetName);
|
return turn(param, -1, streetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSCommandBuilder turn(String param, double dist, Map<String, String> streetName) {
|
public JSCommandBuilder turn(String param, double dist, StreetName streetName) {
|
||||||
return addCommand(C_TURN, param, dist, convertStreetName(streetName));
|
return addCommand(C_TURN, param, dist, convertStreetName(streetName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,19 +126,19 @@ public class JSCommandBuilder extends CommandBuilder {
|
||||||
* @param dist
|
* @param dist
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public JSCommandBuilder prepareTurn(String param, double dist, Map<String, String> streetName){
|
public JSCommandBuilder prepareTurn(String param, double dist, StreetName streetName){
|
||||||
return addCommand(C_PREPARE_TURN, param, dist, convertStreetName(streetName));
|
return addCommand(C_PREPARE_TURN, param, dist, convertStreetName(streetName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSCommandBuilder prepareRoundAbout(double dist, int exit, Map<String, String> streetName){
|
public JSCommandBuilder prepareRoundAbout(double dist, int exit, StreetName streetName){
|
||||||
return addCommand(C_PREPARE_ROUNDABOUT, dist, exit, convertStreetName(streetName));
|
return addCommand(C_PREPARE_ROUNDABOUT, dist, exit, convertStreetName(streetName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSCommandBuilder roundAbout(double dist, double angle, int exit, Map<String, String> streetName){
|
public JSCommandBuilder roundAbout(double dist, double angle, int exit, StreetName streetName){
|
||||||
return addCommand(C_ROUNDABOUT, dist, angle, exit, convertStreetName(streetName));
|
return addCommand(C_ROUNDABOUT, dist, angle, exit, convertStreetName(streetName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSCommandBuilder roundAbout(double angle, int exit, Map<String, String> streetName) {
|
public JSCommandBuilder roundAbout(double angle, int exit, StreetName streetName) {
|
||||||
return roundAbout(-1, angle, exit, streetName);
|
return roundAbout(-1, angle, exit, streetName);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -180,11 +182,11 @@ public class JSCommandBuilder extends CommandBuilder {
|
||||||
return addCommand(C_REACHED_POI, name);
|
return addCommand(C_REACHED_POI, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSCommandBuilder bearLeft(Map<String,String> streetName){
|
public JSCommandBuilder bearLeft(StreetName streetName){
|
||||||
return addCommand(C_BEAR_LEFT, convertStreetName(streetName));
|
return addCommand(C_BEAR_LEFT, convertStreetName(streetName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSCommandBuilder bearRight(Map<String, String> streetName){
|
public JSCommandBuilder bearRight(StreetName streetName){
|
||||||
return addCommand(C_BEAR_RIGHT, convertStreetName(streetName));
|
return addCommand(C_BEAR_RIGHT, convertStreetName(streetName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue