diff --git a/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java b/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java index c28dc66ddb..ead44976ba 100644 --- a/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java +++ b/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java @@ -165,6 +165,10 @@ public class BinaryRoutePlanner { return road; } + public List searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, List intermediate, boolean leftSideNavigation) throws IOException { + // TODO + return searchRoute(ctx, start, end, leftSideNavigation); + } /** diff --git a/OsmAnd/assets/voice/en-tts/ttsconfig.p b/OsmAnd/assets/voice/en-tts/ttsconfig.p index d6deea7d4a..b49867f500 100644 --- a/OsmAnd/assets/voice/en-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/en-tts/ttsconfig.p @@ -36,6 +36,8 @@ and_arrive_destination == ['and arrive at your destination ']. then == ['then ']. reached_destination == ['you have reached your destination ']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. bear_right == ['keep right ']. bear_left == ['keep left ']. diff --git a/OsmAnd/assets/voice/en/config.p b/OsmAnd/assets/voice/en/config.p index acd896a800..368f2cdd0d 100644 --- a/OsmAnd/assets/voice/en/config.p +++ b/OsmAnd/assets/voice/en/config.p @@ -38,8 +38,12 @@ roundabout(Dist, _Angle, Exit) == ['after-m.ogg', delay_300, D, delay_300, 'ente roundabout(_Angle, Exit) == ['taking.ogg', delay_250, E, 'exit-e.ogg'] :- nth(Exit, E). and_arrive_destination == ['arrive_at_your_destination-e.ogg']. % Miss and? -then == ['then.ogg', delay_350]. reached_destination == ['you_have_reached_your_destination.ogg']. +and_arrive_intermediate == ['arrive_at_viapoint-e.ogg']. +reached_intermediate == ['you_have_reached_a_viapoint.ogg']. + +then == ['then.ogg', delay_350]. + bear_right == ['keep_right-e.ogg']. bear_left == ['keep_left-e.ogg']. route_recalc(_Dist) == ['recalc.ogg']. %nothing to said possibly beep? diff --git a/OsmAnd/assets/voice/es/config.p b/OsmAnd/assets/voice/es/config.p index c80df6257d..5f2e8850be 100644 --- a/OsmAnd/assets/voice/es/config.p +++ b/OsmAnd/assets/voice/es/config.p @@ -38,6 +38,8 @@ roundabout(Dist, _Angle, Exit) == ['despues_de.ogg', delay_300, D, delay_300, 'e roundabout(_Angle, Exit) == ['tomando la.ogg', delay_250, E, 'salida.ogg'] :- nth(Exit, E). and_arrive_destination == ['destino.ogg']. % Miss and? +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == ['entonces.ogg', delay_350]. reached_destination == ['llegado.ogg']. bear_right == ['mantener_derecha.ogg']. diff --git a/OsmAnd/assets/voice/fi-tts/ttsconfig.p b/OsmAnd/assets/voice/fi-tts/ttsconfig.p index 8429bbaef4..75d6a2ae7b 100644 --- a/OsmAnd/assets/voice/fi-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/fi-tts/ttsconfig.p @@ -42,6 +42,8 @@ go_ahead == ['Jatka suoraan ']. go_ahead(Dist) == ['Jatka suoraan ', D]:- distance(Dist, metria) == D. and_arrive_destination == ['ja olet perillä ']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == ['sitten ']. reached_destination == ['olet perillä ']. diff --git a/OsmAnd/assets/voice/fr-tts/ttsconfig.p b/OsmAnd/assets/voice/fr-tts/ttsconfig.p index 9013f0b22a..bce0ae86cc 100644 --- a/OsmAnd/assets/voice/fr-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/fr-tts/ttsconfig.p @@ -36,6 +36,8 @@ and_arrive_destination == ['et arrivez à destination ']. then == ['puis ']. reached_destination == ['vous êtes arrivé à destination ']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. bear_right == ['serrez à droite ']. bear_left == ['serrez à gauche ']. diff --git a/OsmAnd/assets/voice/hi-tts/ttsconfig.p b/OsmAnd/assets/voice/hi-tts/ttsconfig.p index f0c7c40b63..93c4f25aec 100644 --- a/OsmAnd/assets/voice/hi-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/hi-tts/ttsconfig.p @@ -33,6 +33,8 @@ go_ahead == [' सीधे आगे जाये ']. go_ahead(Dist) == [D, ' तक रास्ते का पालन करे ']:- distance(Dist) == D. and_arrive_destination == [' और अपनी मंजिल पर पहोचे ']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == ['और फिर ']. reached_destination == ['आप अपनी मंजिल पर पहोच चुके है ']. diff --git a/OsmAnd/assets/voice/hu-tts/ttsconfig.p b/OsmAnd/assets/voice/hu-tts/ttsconfig.p index 77c21b10af..4646b9c8b9 100644 --- a/OsmAnd/assets/voice/hu-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/hu-tts/ttsconfig.p @@ -33,6 +33,8 @@ go_ahead == ['Haladj tovább egyenesen ']. go_ahead(Dist) == ['Menj tovább ', D] :- distance(Dist, t) == D. and_arrive_destination == ['és megérkezel az úti célhoz ']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == ['majd ']. reached_destination == ['megérkeztél az úti célhoz ']. diff --git a/OsmAnd/assets/voice/it-tts/ttsconfig.p b/OsmAnd/assets/voice/it-tts/ttsconfig.p index cc2f3aa13a..672c5ba019 100644 --- a/OsmAnd/assets/voice/it-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/it-tts/ttsconfig.p @@ -33,6 +33,8 @@ go_ahead == ['Sempre dritto ']. go_ahead(Dist) == ['Sempre dritto per ', D]:- distance(Dist) == D. and_arrive_destination == ['e arrivate a destinazione']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == [', poi ']. reached_destination == ['arrivato a destinazione']. diff --git a/OsmAnd/assets/voice/ko-tts/ttsconfig.p b/OsmAnd/assets/voice/ko-tts/ttsconfig.p index ec37c05569..4b82b5190f 100644 --- a/OsmAnd/assets/voice/ko-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/ko-tts/ttsconfig.p @@ -33,6 +33,8 @@ go_ahead == ['직진을 계속하세요 ']. go_ahead(Dist) == [D, ' 직진하세요 ']:- distance(Dist) == D. and_arrive_destination == [' 다음은 목적지에 도착합니다 ']. % Miss and? +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == [', 다음은 ']. reached_destination == ['목적지에 도착하였습니다 ']. diff --git a/OsmAnd/assets/voice/lv-tts/ttsconfig.p b/OsmAnd/assets/voice/lv-tts/ttsconfig.p index 4986eb691e..cc5ff631dc 100644 --- a/OsmAnd/assets/voice/lv-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/lv-tts/ttsconfig.p @@ -33,6 +33,8 @@ go_ahead == ['Dodaties taisni uz priekšu ']. go_ahead(Dist) == ['Brauciet pa ceļu ', D]:- distance2(Dist) == D. and_arrive_destination == ['un ierodaties galapunktā ']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == ['tad ']. reached_destination == ['jūs esiet nokļuvis galapunktā ']. diff --git a/OsmAnd/assets/voice/nl-tts/ttsconfig.p b/OsmAnd/assets/voice/nl-tts/ttsconfig.p index 0344767feb..5c77c6fb51 100644 --- a/OsmAnd/assets/voice/nl-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/nl-tts/ttsconfig.p @@ -33,6 +33,8 @@ go_ahead == ['Verder dóorrijden ']. go_ahead(Dist) == ['De weg', D,'volgen']:- distance(Dist) == D. and_arrive_destination == ['dan heeft u uw bestemming bereikt ']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == ['dan ']. reached_destination == ['Bestemming bereikt ']. diff --git a/OsmAnd/assets/voice/pl-tts/ttsconfig.p b/OsmAnd/assets/voice/pl-tts/ttsconfig.p index 25f6c93d2d..9faaa2fa70 100644 --- a/OsmAnd/assets/voice/pl-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/pl-tts/ttsconfig.p @@ -33,6 +33,8 @@ go_ahead == ['Jedź prosto ']. go_ahead(Dist) == ['Jedź prosto ', D]:- distance(Dist) == D. and_arrive_destination == ['następnie dojedź do celu ']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == ['następnie ']. reached_destination == ['Cel został osiągnięty! ']. diff --git a/OsmAnd/assets/voice/ru-tts/ttsconfig.p b/OsmAnd/assets/voice/ru-tts/ttsconfig.p index a22458e73e..26e65345f7 100644 --- a/OsmAnd/assets/voice/ru-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/ru-tts/ttsconfig.p @@ -33,6 +33,8 @@ go_ahead == ['Продолжайте движение прямо ']. go_ahead(Dist) == ['Продолжайте движение ', D]:- distance(Dist) == D. and_arrive_destination == ['и вы прибудете в пункт назначения ']. +and_arrive_intermediate == ['и вы прибудете в промежуточный пункт ']. +reached_intermediate == ['вы прибыли в промежуточный пункт']. then == ['затем ']. reached_destination == ['вы прибыли в пункт назначения ']. diff --git a/OsmAnd/assets/voice/ru2/config.p b/OsmAnd/assets/voice/ru2/config.p index 6d57c9553f..3d9718f09f 100644 --- a/OsmAnd/assets/voice/ru2/config.p +++ b/OsmAnd/assets/voice/ru2/config.p @@ -40,6 +40,9 @@ roundabout(_Angle, Exit) == ['taking_the.ogg', delay_250, E, 'exit-e.ogg'] :- n and_arrive_destination == ['arrive_at_your_destination-e.ogg']. % Miss and? then == ['then.ogg', delay_350]. reached_destination == ['you_have_reached_your_destination.ogg']. +and_arrive_intermediate == ['arrive_at_viapoint-e.ogg']. +reached_intermediate == ['you_have_reached_a_viapoint.ogg']. + bear_right == ['keep_right-e.ogg']. bear_left == ['keep_left-e.ogg']. route_recalc(_Dist) == []. % ['recalc.ogg']. %nothing to said possibly beep? diff --git a/OsmAnd/assets/voice/ru3/config.p b/OsmAnd/assets/voice/ru3/config.p index 78437be839..bdef91d22b 100644 --- a/OsmAnd/assets/voice/ru3/config.p +++ b/OsmAnd/assets/voice/ru3/config.p @@ -37,8 +37,12 @@ roundabout(Dist, _Angle, Exit) == ['after-n.ogg',D, 'enter_the_roundabout-e.ogg' roundabout(_Angle, Exit) == ['take_the.ogg', E, 'exit-e.ogg'] :- nth(Exit, E). and_arrive_destination == ['then.ogg', delay_150, 'arrive_at_your_destination-e.ogg']. -then == ['then.ogg', delay_150]. + reached_destination == ['you_have_reached_your_destination.ogg']. +and_arrive_intermediate == ['arrive_at_viapoint-e.ogg']. +reached_intermediate == ['you_have_reached_a_viapoint.ogg']. + +then == ['then.ogg', delay_150]. bear_right == ['keep_right-e.ogg']. location_lost == ['gps_signal_lost.ogg']. bear_left == ['keep_left-e.ogg']. diff --git a/OsmAnd/assets/voice/sk-tts/ttsconfig.p b/OsmAnd/assets/voice/sk-tts/ttsconfig.p index c5e00b7609..f9015ed34d 100644 --- a/OsmAnd/assets/voice/sk-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/sk-tts/ttsconfig.p @@ -40,6 +40,8 @@ go_ahead == ['pokračujte rovno']. go_ahead(Dist) == ['pokračujte ', D]:- distance(Dist) == D. and_arrive_destination == ['a dorazíte do cieľa']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == ['potom ']. reached_destination == ['dorazili ste do cieľa']. diff --git a/OsmAnd/assets/voice/sv-tts/ttsconfig.p b/OsmAnd/assets/voice/sv-tts/ttsconfig.p index 265dd5c0bc..93c761b8bd 100644 --- a/OsmAnd/assets/voice/sv-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/sv-tts/ttsconfig.p @@ -33,6 +33,8 @@ go_ahead == ['Kör rakt fram ']. go_ahead(Dist) == ['Följ den här vägen ', D]:- distance(Dist) == D. and_arrive_destination == ['och du är framme ']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == ['sedan ']. reached_destination == ['du är framme ']. diff --git a/OsmAnd/assets/voice/zh-tts/ttsconfig.p b/OsmAnd/assets/voice/zh-tts/ttsconfig.p index 751db5a132..9feb3d5966 100644 --- a/OsmAnd/assets/voice/zh-tts/ttsconfig.p +++ b/OsmAnd/assets/voice/zh-tts/ttsconfig.p @@ -33,6 +33,8 @@ go_ahead == ['直直往前開 ']. go_ahead(Dist) == ['沿著馬路往前 ', D]:- distance(Dist) == D. and_arrive_destination == ['然後可達終點 ']. +and_arrive_intermediate == ['and arrive at your via point ']. +reached_intermediate == ['you have reached your via point']. then == ['然後 ']. reached_destination == ['抵達終點 ']. diff --git a/OsmAnd/res/drawable-hdpi/info_intermediate.png b/OsmAnd/res/drawable-hdpi/info_intermediate.png new file mode 100644 index 0000000000..7f3c007a6d Binary files /dev/null and b/OsmAnd/res/drawable-hdpi/info_intermediate.png differ diff --git a/OsmAnd/res/drawable-hdpi/intermediate_point.png b/OsmAnd/res/drawable-hdpi/intermediate_point.png new file mode 100644 index 0000000000..ae373cce07 Binary files /dev/null and b/OsmAnd/res/drawable-hdpi/intermediate_point.png differ diff --git a/OsmAnd/res/drawable-hdpi/list_view_set_intermediate.png b/OsmAnd/res/drawable-hdpi/list_view_set_intermediate.png new file mode 100644 index 0000000000..78dce84fca Binary files /dev/null and b/OsmAnd/res/drawable-hdpi/list_view_set_intermediate.png differ diff --git a/OsmAnd/res/drawable-hdpi/widget_intermediate.png b/OsmAnd/res/drawable-hdpi/widget_intermediate.png new file mode 100644 index 0000000000..afd0cd8e16 Binary files /dev/null and b/OsmAnd/res/drawable-hdpi/widget_intermediate.png differ diff --git a/OsmAnd/res/drawable-large/info_intermediate.png b/OsmAnd/res/drawable-large/info_intermediate.png new file mode 100644 index 0000000000..7f3c007a6d Binary files /dev/null and b/OsmAnd/res/drawable-large/info_intermediate.png differ diff --git a/OsmAnd/res/drawable-large/intermediate_point.png b/OsmAnd/res/drawable-large/intermediate_point.png new file mode 100644 index 0000000000..ae373cce07 Binary files /dev/null and b/OsmAnd/res/drawable-large/intermediate_point.png differ diff --git a/OsmAnd/res/drawable-large/list_view_set_intermediate.png b/OsmAnd/res/drawable-large/list_view_set_intermediate.png new file mode 100644 index 0000000000..78dce84fca Binary files /dev/null and b/OsmAnd/res/drawable-large/list_view_set_intermediate.png differ diff --git a/OsmAnd/res/drawable-large/widget_intermediate.png b/OsmAnd/res/drawable-large/widget_intermediate.png new file mode 100644 index 0000000000..afd0cd8e16 Binary files /dev/null and b/OsmAnd/res/drawable-large/widget_intermediate.png differ diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 08b3a78205..d9643318cb 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,10 @@ 1. All your modified/created strings are in the top of the file (to make easier find what\'s translated). PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy --> + Intermediate point %1$s too far from nearest road. + You have arrived at your intermediate point + Add intermediate point + Intermediate point Starting point too far from nearest road. Add Tag Advanced Mode... diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 12bbcb8827..9b7b3f3487 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -2,6 +2,7 @@ package net.osmand.plus; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; @@ -973,6 +974,7 @@ public class OsmandSettings { public final static String POINT_NAVIGATE_LAT = "point_navigate_lat"; //$NON-NLS-1$ public final static String POINT_NAVIGATE_LON = "point_navigate_lon"; //$NON-NLS-1$ public final static String POINT_NAVIGATE_ROUTE = "point_navigate_route"; //$NON-NLS-1$ + public final static String INTERMEDIATE_POINTS = "intermediate_points"; //$NON-NLS-1$ public LatLon getPointToNavigate() { float lat = globalPreferences.getFloat(POINT_NAVIGATE_LAT, 0); @@ -989,6 +991,52 @@ public class OsmandSettings { return t; } + public boolean clearIntermediatePoints() { + return globalPreferences.edit().remove(INTERMEDIATE_POINTS).commit(); + } + + public List getIntermediatePoints() { + List list = new ArrayList(); + String ip = globalPreferences.getString(INTERMEDIATE_POINTS, ""); + if (ip.trim().length() > 0) { + StringTokenizer tok = new StringTokenizer(ip, ","); + while (tok.hasMoreTokens()) { + String lat = tok.nextToken(); + if (!tok.hasMoreTokens()) { + break; + } + String lon = tok.nextToken(); + list.add(new LatLon(Float.parseFloat(lat), Float.parseFloat(lon))); + } + } + return list; + } + + public boolean setIntermediatePoint(double latitude, double longitude, String historyDescription, int index) { + List ps = getIntermediatePoints(); + ps.add(index, new LatLon(latitude, longitude)); + if (historyDescription != null) { + SearchHistoryHelper.getInstance().addNewItemToHistory(latitude, longitude, historyDescription, ctx); + } + return saveIntermediatePoints(ps); + } + public boolean deleteIntermediatePoint( int index) { + List ps = getIntermediatePoints(); + ps.remove(index); + return saveIntermediatePoints(ps); + } + + private boolean saveIntermediatePoints(List ps) { + StringBuilder sb = new StringBuilder(); + for(int i=0; i 0){ + sb.append(","); + } + sb.append(((float)ps.get(i).getLatitude()+"")).append(",").append(((float)ps.get(i).getLongitude()+"")); + } + return globalPreferences.edit().putString(INTERMEDIATE_POINTS, sb.toString()).commit(); + } + public boolean clearPointToNavigate() { return globalPreferences.edit().remove(POINT_NAVIGATE_LAT).remove(POINT_NAVIGATE_LON). remove(POINT_NAVIGATE_ROUTE).commit(); diff --git a/OsmAnd/src/net/osmand/plus/activities/FontFitTextView.java b/OsmAnd/src/net/osmand/plus/activities/FontFitTextView.java index 985659ad63..87775a6cf0 100644 --- a/OsmAnd/src/net/osmand/plus/activities/FontFitTextView.java +++ b/OsmAnd/src/net/osmand/plus/activities/FontFitTextView.java @@ -10,9 +10,6 @@ import android.view.Gravity; import android.widget.LinearLayout; import android.widget.TextView; -/* Based on - * from http://stackoverflow.com/questions/2617266/how-to-adjust-text-font-size-to-fit-textview - */ public class FontFitTextView extends LinearLayout { private static float MAX_TEXT_SIZE = 28; diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 5feb0b05b1..76930113d9 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -194,13 +194,11 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe savingTrackHelper = getMyApplication().getSavingTrackHelper(); liveMonitoringHelper = getMyApplication().getLiveMonitoringHelper(); - LatLon pointToNavigate = settings.getPointToNavigate(); - routingHelper = getMyApplication().getRoutingHelper(); // This situtation could be when navigation suddenly crashed and after restarting // it tries to continue the last route if(settings.FOLLOW_THE_ROUTE.get() && !routingHelper.isRouteCalculated()){ - restoreRoutingMode(pointToNavigate); + restoreRoutingMode(settings.getPointToNavigate(), settings.getIntermediatePoints()); } mapView.setMapLocationListener(this); @@ -241,7 +239,8 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe setRequestedOrientation(settings.MAP_SCREEN_ORIENTATION.get()); // can't return from this method we are not sure if activity will be recreated or not } - mapLayers.getNavigationLayer().setPointToNavigate(settings.getPointToNavigate()); + mapLayers.getNavigationLayer().setPointToNavigate(settings.getPointToNavigate(), settings.getIntermediatePoints()); + Location loc = getLastKnownLocation(); if (loc != null && (System.currentTimeMillis() - loc.getTime()) > 30 * 1000) { setLocation(null); @@ -266,8 +265,13 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe setMapLinkedToLocation(false); // if destination point was changed try to recalculate route - if (routingHelper.isFollowingMode() && !Algoritms.objectEquals(settings.getPointToNavigate(), routingHelper.getFinalLocation())) { - routingHelper.setFinalAndCurrentLocation(settings.getPointToNavigate(), getLastKnownLocation(), routingHelper.getCurrentGPXRoute()); + if (routingHelper.isFollowingMode() && ( + !Algoritms.objectEquals(settings.getPointToNavigate(), routingHelper.getFinalLocation() )|| + !Algoritms.objectEquals(settings.getIntermediatePoints(), routingHelper.getIntermediatePoints()) + )) { + routingHelper.setFinalAndCurrentLocation(settings.getPointToNavigate(), + settings.getIntermediatePoints(), + getLastKnownLocation(), routingHelper.getCurrentGPXRoute()); } startLocationRequests(); @@ -328,11 +332,11 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe private void notRestoreRoutingMode(){ boolean changed = settings.APPLICATION_MODE.set(settings.PREV_APPLICATION_MODE.get()); updateApplicationModeSettings(); - routingHelper.clearCurrentRoute(null); + routingHelper.clearCurrentRoute(null, new ArrayList()); mapView.refreshMap(changed); } - private void restoreRoutingMode(final LatLon pointToNavigate) { + private void restoreRoutingMode(final LatLon pointToNavigate, final List intermediates) { final String gpxPath = settings.FOLLOW_THE_GPX_ROUTE.get(); if (pointToNavigate == null && gpxPath == null) { notRestoreRoutingMode(); @@ -423,7 +427,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe notRestoreRoutingMode(); } else { routingHelper.setFollowingMode(true); - routingHelper.setFinalAndCurrentLocation(endPoint, startPoint, gpxRoute); + routingHelper.setFinalAndCurrentLocation(endPoint, intermediates, startPoint, gpxRoute); getMyApplication().showDialogInitializingCommandPlayer(MapActivity.this); } } @@ -931,17 +935,24 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe return zoomDelta; } - public void navigateToPoint(LatLon point, boolean updateRoute){ + public void navigateToPoint(LatLon point, boolean updateRoute, boolean intermediate){ if(point != null){ - settings.setPointToNavigate(point.getLatitude(), point.getLongitude(), null); + if(!intermediate) { + settings.setPointToNavigate(point.getLatitude(), point.getLongitude(), null); + } else { + int sz = mapLayers.getNavigationLayer().getIntermediatePoints().size(); + settings.setIntermediatePoint(point.getLatitude(), point.getLongitude(), null, sz); + } } else { settings.clearPointToNavigate(); + settings.clearIntermediatePoints(); } if(updateRoute && ( routingHelper.isRouteBeingCalculated() || routingHelper.isRouteCalculated() || routingHelper.isFollowingMode())) { - routingHelper.setFinalAndCurrentLocation(point, getLastKnownLocation(), routingHelper.getCurrentGPXRoute()); + routingHelper.setFinalAndCurrentLocation(settings.getPointToNavigate(), + settings.getIntermediatePoints(), getLastKnownLocation(), routingHelper.getCurrentGPXRoute()); } - mapLayers.getNavigationLayer().setPointToNavigate(point); + mapLayers.getNavigationLayer().setPointToNavigate(settings.getPointToNavigate(), settings.getIntermediatePoints()); } public Location getLastKnownLocation(){ @@ -956,6 +967,18 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe return mapLayers.getNavigationLayer().getPointToNavigate(); } + public List getIntermediatePoitns(){ + return mapLayers.getNavigationLayer().getIntermediatePoints(); + } + + public LatLon getFirstIntermediatePoint(){ + List ip = mapLayers.getNavigationLayer().getIntermediatePoints(); + if(ip.size() > 0) { + return ip.get(0); + } + return null; + } + public RoutingHelper getRoutingHelper() { return routingHelper; } diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 8bb9428f91..fd38d4e34f 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -473,7 +473,8 @@ public class MapActivityActions implements DialogProvider { settings.FOLLOW_THE_ROUTE.set(false); settings.FOLLOW_THE_GPX_ROUTE.set(null); routingHelper.setFollowingMode(false); - routingHelper.setFinalAndCurrentLocation(mapActivity.getPointToNavigate(), from, null); + routingHelper.setFinalAndCurrentLocation(mapActivity.getPointToNavigate(), + mapActivity.getIntermediatePoitns(),from, null); } }; @@ -511,7 +512,8 @@ public class MapActivityActions implements DialogProvider { settings.FOLLOW_THE_ROUTE.set(true); settings.FOLLOW_THE_GPX_ROUTE.set(null); routingHelper.setFollowingMode(true); - routingHelper.setFinalAndCurrentLocation(mapActivity.getPointToNavigate(), current, null); + routingHelper.setFinalAndCurrentLocation(mapActivity.getPointToNavigate(), mapActivity.getIntermediatePoitns(), + current, null); dialog.dismiss(); getMyApplication().showDialogInitializingCommandPlayer(mapActivity); } @@ -587,7 +589,7 @@ public class MapActivityActions implements DialogProvider { } if(endPoint != null) { settings.setPointToNavigate(point.getLatitude(), point.getLongitude(), null); - mapLayers.getNavigationLayer().setPointToNavigate(point); + mapLayers.getNavigationLayer().setPointToNavigate(point, new ArrayList()); } } // change global settings @@ -604,7 +606,8 @@ public class MapActivityActions implements DialogProvider { settings.FOLLOW_THE_ROUTE.set(true); settings.FOLLOW_THE_GPX_ROUTE.set(result.path); routingHelper.setFollowingMode(true); - routingHelper.setFinalAndCurrentLocation(endPoint, startForRouting, gpxRoute); + routingHelper.setFinalAndCurrentLocation(endPoint, + new ArrayList(), startForRouting, gpxRoute); getMyApplication().showDialogInitializingCommandPlayer(mapActivity); } } @@ -710,6 +713,7 @@ public class MapActivityActions implements DialogProvider { adapter.registerItem(R.string.context_menu_item_search, R.drawable.list_view_search_near_here); adapter.registerItem(R.string.context_menu_item_share_location, R.drawable.list_view_share_location); adapter.registerItem(R.string.context_menu_item_add_favorite, R.drawable.list_activities_favorites); + adapter.registerItem(R.string.context_menu_item_intermediate_point, R.drawable.list_view_set_intermediate); OsmandPlugin.registerMapContextMenu(mapActivity, latitude, longitude, adapter, selectedObj); @@ -750,10 +754,10 @@ public class MapActivityActions implements DialogProvider { intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); mapActivity.startActivity(intent); } else if (standardId == R.string.context_menu_item_navigate_point) { - mapActivity.navigateToPoint(new LatLon(latitude, longitude), true); + mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, false); } else if (standardId == R.string.context_menu_item_directions) { Location loc = mapActivity.getLastKnownLocation(); - mapActivity.navigateToPoint(new LatLon(latitude, longitude), false); + mapActivity.navigateToPoint(new LatLon(latitude, longitude), false, false); // always enable and follow and let calculate it (GPS is not accessible in garage) getDirections(loc, true); } else if (standardId == R.string.context_menu_item_show_route) { @@ -763,6 +767,8 @@ public class MapActivityActions implements DialogProvider { loc.setLongitude(longitude); getDirections(loc, true); } + } else if (standardId == R.string.context_menu_item_intermediate_point) { + mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, true); } else if (standardId == R.string.context_menu_item_share_location) { shareLocation(latitude, longitude, mapActivity.getMapView().getZoom()); } else if (standardId == R.string.context_menu_item_add_favorite) { @@ -921,14 +927,14 @@ public class MapActivityActions implements DialogProvider { @Override public boolean onClick(MenuItem item) { if (routingHelper.isRouteCalculated() || routingHelper.isFollowingMode() || routingHelper.isRouteBeingCalculated()) { - routingHelper.setFinalAndCurrentLocation(null, mapActivity.getLastKnownLocation(), + routingHelper.setFinalAndCurrentLocation(null, new ArrayList(), mapActivity.getLastKnownLocation(), routingHelper.getCurrentGPXRoute()); // restore default mode boolean changed = settings.APPLICATION_MODE.set(settings.PREV_APPLICATION_MODE.get()); mapActivity.updateApplicationModeSettings(); mapView.refreshMap(changed); } else { - mapActivity.navigateToPoint(null, true); + mapActivity.navigateToPoint(null, true, false); } mapView.refreshMap(); return true; diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchHistoryHelper.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchHistoryHelper.java index 976f7afe61..272497f4a8 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchHistoryHelper.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchHistoryHelper.java @@ -11,7 +11,7 @@ import android.database.sqlite.SQLiteOpenHelper; public class SearchHistoryHelper { private static SearchHistoryHelper helper = new SearchHistoryHelper(); - private static final int HISTORY_LIMIT = 10; + private static final int HISTORY_LIMIT = 50; public static SearchHistoryHelper getInstance(){ return helper; diff --git a/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java b/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java index c4dd0b90ec..066a840df6 100644 --- a/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java +++ b/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java @@ -91,8 +91,10 @@ public class TestVoiceActivity extends Activity { addButton(ll, "GPS signal lost", builder(p).gpsLocationLost()); addButton(ll, "Route recalculated (23150m)", builder(p).routeRecalculated(23150)); addButton(ll, "Continue straight ahead", builder(p).goAhead()); + addButton(ll, "Arrive at intermediate point", builder(p).andArriveAtIntermediatePoint()); addButton(ll, "Follow the road for 2350m", builder(p).goAhead(2350)); addButton(ll, "Follow the road for 800m and arrive at destination", builder(p).goAhead(800).andArriveAtDestination()); + addButton(ll, "Follow the road for 360m and arrive at intermediate point", builder(p).goAhead(360).andArriveAtIntermediatePoint()); addButton(ll, "Arrive at destination", builder(p).arrivedAtDestination()); ll.forceLayout(); } diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java index fa2ca0bdec..308bec3327 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java @@ -26,21 +26,24 @@ public class RouteCalculationResult { private final List alarmInfo; private final String errorMessage; private final int[] listDistance; + private final int[] intermediatePoints; // Note always currentRoute > get(currentDirectionInfo).routeOffset, // but currentRoute <= get(currentDirectionInfo+1).routeOffset protected int currentDirectionInfo = 0; protected int currentRoute = 0; + protected int nextIntermediate = 0; protected int nextAlarmInfo = 0; public RouteCalculationResult(String errorMessage) { - this(null, null, null, null, errorMessage, null, false, false); + this(null, null, null, null, null, errorMessage, null, false, false); } - public RouteCalculationResult(List list, List directions, Location start, LatLon end, String errorMessage, - Context ctx, boolean leftSide, boolean addMissingTurns) { + public RouteCalculationResult(List list, List directions, Location start, LatLon end, + List intermediates, String errorMessage, Context ctx, boolean leftSide, boolean addMissingTurns) { this.errorMessage = errorMessage; + this.intermediatePoints = new int[intermediates == null ? 0 : intermediates.size()]; List locations = list == null ? new ArrayList() : new ArrayList(list); List localDirections = directions == null? new ArrayList() : new ArrayList(directions); if (!locations.isEmpty()) { @@ -59,15 +62,16 @@ public class RouteCalculationResult { this.listDistance = new int[locations.size()]; updateListDistanceTime(); this.alarmInfo = new ArrayList(); - + calculateIntermediateIndexes(ctx, intermediates, localDirections); this.directions = Collections.unmodifiableList(localDirections); updateDirectionsTime(); } - public RouteCalculationResult(List list, Location start, LatLon end, + public RouteCalculationResult(List list, Location start, LatLon end, List intermediates, Context ctx, boolean leftSide) { List computeDirections = new ArrayList(); this.errorMessage = null; + this.intermediatePoints = new int[intermediates == null ? 0 : intermediates.size()]; List locations = new ArrayList(); ArrayList alarms = new ArrayList(); List segments = convertVectorResult(computeDirections, locations, list, alarms, ctx); @@ -76,13 +80,55 @@ public class RouteCalculationResult { this.locations = Collections.unmodifiableList(locations); this.segments = Collections.unmodifiableList(segments); this.listDistance = new int[locations.size()]; + calculateIntermediateIndexes(ctx, intermediates, computeDirections); updateListDistanceTime(); this.directions = Collections.unmodifiableList(computeDirections); updateDirectionsTime(); this.alarmInfo = Collections.unmodifiableList(alarms); + } + private void calculateIntermediateIndexes(Context ctx, List intermediates, List localDirections) { + if(intermediates != null && localDirections != null) { + int[] interLocations = new int[intermediates.size()]; + int currentIntermediate = 0; + int currentLocation = 0; + while(currentIntermediate < intermediates.size() && currentLocation < this.locations.size()){ + if(MapUtils.getDistance(intermediates.get(currentIntermediate), + this.locations.get(currentLocation).getLatitude(), this.locations.get(currentLocation).getLongitude()) < + 15) { + interLocations[currentIntermediate] = currentLocation; + currentIntermediate++; + } + currentLocation ++; + } + int currentDirection = 0; + currentIntermediate = 0; + while(currentIntermediate < intermediates.size() && currentDirection < localDirections.size()){ + int locationIndex = localDirections.get(currentDirection).routePointOffset ; + if (locationIndex >= interLocations[currentIntermediate]) { + // split directions + if (locationIndex > interLocations[currentIntermediate] + && MapUtils.getDistance(intermediates.get(currentIntermediate), + this.locations.get(locationIndex).getLatitude(), this.locations.get(locationIndex).getLongitude()) > 50) { + RouteDirectionInfo toSplit = localDirections.get(currentDirection); + RouteDirectionInfo info = new RouteDirectionInfo(localDirections.get(currentDirection).getAverageSpeed(), TurnType.valueOf(TurnType.C, + false)); + info.setRef(toSplit.getRef()); + info.setStreetName(toSplit.getStreetName()); + info.routePointOffset = interLocations[currentIntermediate]; + info.setDescriptionRoute(ctx.getString(R.string.route_head));//; //$NON-NLS-1$ + localDirections.add(currentDirection, info); + } + intermediatePoints[currentIntermediate] = currentDirection; + currentIntermediate++; + } + currentDirection ++; + } + } + } + private void attachAlarmInfo(List alarms, RouteSegmentResult res, int intId, int locInd) { int[] pointTypes = res.getObject().getPointTypes(intId); RouteRegion reg = res.getObject().region; @@ -565,6 +611,14 @@ public class RouteCalculationResult { while (nextAlarmInfo < alarmInfo.size() && alarmInfo.get(nextAlarmInfo).locationIndex < currentRoute) { nextAlarmInfo++; } + while(nextIntermediate < intermediatePoints.length) { + RouteDirectionInfo dir = directions.get(intermediatePoints[nextIntermediate]); + if(dir.routePointOffset < currentRoute) { + nextIntermediate ++; + } else { + break; + } + } } public Location getLocationFromRouteDirection(RouteDirectionInfo i){ @@ -596,6 +650,9 @@ public class RouteCalculationResult { info.directionInfo = directions.get(nextInd); dist -= listDistance[directions.get(nextInd).routePointOffset]; } + if(intermediatePoints != null && nextIntermediate < intermediatePoints.length) { + info.intermediatePoint = intermediatePoints[nextIntermediate] == nextInd; + } info.directionInfoInd = nextInd; info.distanceTo = dist; return info; @@ -624,6 +681,9 @@ public class RouteCalculationResult { next.directionInfo = directions.get(nextInd); dist -= listDistance[directions.get(nextInd).routePointOffset]; } + if(intermediatePoints != null && nextIntermediate < intermediatePoints.length) { + next.intermediatePoint = intermediatePoints[nextIntermediate] == nextInd; + } next.distanceTo = dist; next.directionInfoInd = nextInd; return next; @@ -709,6 +769,30 @@ public class RouteCalculationResult { return 0; } + public int getDistanceToNextIntermediate(Location fromLoc) { + if(listDistance != null && currentRoute < listDistance.length){ + int dist = listDistance[currentRoute]; + Location l = locations.get(currentRoute); + if(fromLoc != null){ + dist += fromLoc.distanceTo(l); + } + if(nextIntermediate >= intermediatePoints.length ){ + return 0; + } else { + int directionInd = intermediatePoints[nextIntermediate]; + return dist - listDistance[directions.get(directionInd).routePointOffset]; + } + } + return 0; + } + + public int getIntermediatePointsToPass(){ + if(nextIntermediate >= intermediatePoints.length) { + return 0; + } + return intermediatePoints.length - nextIntermediate; + } + public int getLeftTime(Location fromLoc){ int time = 0; if(currentDirectionInfo < directions.size()) { @@ -732,7 +816,7 @@ public class RouteCalculationResult { public static class NextDirectionInfo { public RouteDirectionInfo directionInfo; public int distanceTo; - // + public boolean intermediatePoint; public int imminent; private int directionInfoInd; } diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 7533c1d96d..d270a959ab 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -148,7 +148,7 @@ public class RouteProvider { - public RouteCalculationResult calculateRouteImpl(Location start, LatLon end, ApplicationMode mode, RouteService type, Context ctx, + public RouteCalculationResult calculateRouteImpl(Location start, LatLon end, List intermediates, ApplicationMode mode, RouteService type, Context ctx, GPXRouteParams gpxRoute, RouteCalculationResult previousToRecalculate, boolean fast, boolean leftSide, Interruptable interruptable){ long time = System.currentTimeMillis(); if (start != null && end != null) { @@ -168,9 +168,9 @@ public class RouteProvider { if(previousToRecalculate != null) { originalRoute = previousToRecalculate.getOriginalRoute(); } - res = findVectorMapsRoute(start, end, mode, (OsmandApplication)ctx.getApplicationContext(), originalRoute, leftSide, interruptable); + res = findVectorMapsRoute(start, end, intermediates, mode, (OsmandApplication)ctx.getApplicationContext(), originalRoute, leftSide, interruptable); } else { - res = findCloudMadeRoute(start, end, mode, ctx, fast, leftSide); + res = findCloudMadeRoute(start, end, intermediates, mode, ctx, fast, leftSide); } if(log.isInfoEnabled() ){ log.info("Finding route contained " + res.getImmutableLocations().size() + " points for " + (System.currentTimeMillis() - time) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ @@ -220,7 +220,7 @@ public class RouteProvider { } ArrayList sublist = new ArrayList(gpxRoute.subList(startI, endI)); if(params.directions == null){ - res = new RouteCalculationResult(sublist, params.directions, start, end, null, ctx, leftSide, true); + res = new RouteCalculationResult(sublist, params.directions, start, end, null, null, ctx, leftSide, true); } else { List subdirections = new ArrayList(); for (RouteDirectionInfo info : params.directions) { @@ -235,7 +235,7 @@ public class RouteProvider { subdirections.add(ch); } } - res = new RouteCalculationResult(sublist, subdirections, start, end, null, ctx, leftSide, true); + res = new RouteCalculationResult(sublist, subdirections, start, end, null, null, ctx, leftSide, true); } return res; } @@ -305,10 +305,10 @@ public class RouteProvider { } } - return new RouteCalculationResult(res, null, start, end, null, ctx, leftSide, true); + return new RouteCalculationResult(res, null, start, end, null, null, ctx, leftSide, true); } - protected RouteCalculationResult findVectorMapsRoute(Location start, LatLon end, ApplicationMode mode, OsmandApplication app, + protected RouteCalculationResult findVectorMapsRoute(Location start, LatLon end, List intermediates, ApplicationMode mode, OsmandApplication app, List previousRoute, boolean leftSide, Interruptable interruptable) throws IOException { BinaryMapIndexReader[] files = app.getResourceManager().getRoutingMapFiles(); @@ -361,9 +361,25 @@ public class RouteProvider { if (en == null) { return new RouteCalculationResult(app.getString(R.string.ending_point_too_far)); } + List inters = new ArrayList(); + if (intermediates != null) { + int ind = 1; + for (LatLon il : intermediates) { + RouteSegment is = router.findRouteSegment(il.getLatitude(), il.getLongitude(), ctx); + if (is == null) { + return new RouteCalculationResult(app.getString(R.string.intermediate_point_too_far, "'" + ind + "'")); + } + ind++; + } + } try { - List result = router.searchRoute(ctx, st, en, leftSide); - return new RouteCalculationResult(result, start, end, app, leftSide); + List result; + if(inters.size() > 0){ + result = router.searchRoute(ctx, st, en, inters, leftSide); + } else { + result = router.searchRoute(ctx, st, en, leftSide); + } + return new RouteCalculationResult(result, start, end, intermediates, app, leftSide); } catch (OutOfMemoryError e) { ActivityManager activityManager = (ActivityManager)app.getSystemService(Context.ACTIVITY_SERVICE); ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); @@ -373,7 +389,7 @@ public class RouteProvider { } - protected RouteCalculationResult findCloudMadeRoute(Location start, LatLon end, ApplicationMode mode, Context ctx, boolean fast, boolean leftSide) + protected RouteCalculationResult findCloudMadeRoute(Location start, LatLon end, List intermediates, ApplicationMode mode, Context ctx, boolean fast, boolean leftSide) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException { List res = new ArrayList(); List directions = null; @@ -382,6 +398,20 @@ public class RouteProvider { uri.append("http://routes.cloudmade.com/A6421860EBB04234AB5EF2D049F2CD8F/api/0.3/"); //$NON-NLS-1$ uri.append(start.getLatitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$ uri.append(start.getLongitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$ + if(intermediates != null && intermediates.size() > 0) { + uri.append("["); + boolean first = true; + for(LatLon il : intermediates) { + if(!first){ + uri.append(","); + } else { + first = false; + } + uri.append(il.getLatitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$ + uri.append(il.getLongitude() + ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + uri.append("],"); + } uri.append(end.getLatitude() + "").append(","); //$NON-NLS-1$//$NON-NLS-2$ uri.append(end.getLongitude() + "").append("/"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -406,7 +436,7 @@ public class RouteProvider { GPXFile gpxFile = GPXUtilities.loadGPXFile(ctx, connection.getInputStream(), false); directions = parseCloudmadeRoute(res, gpxFile, false, leftSide, speed); - return new RouteCalculationResult(res, directions, start, end, null, ctx, leftSide, true); + return new RouteCalculationResult(res, directions, start, end, intermediates, null, ctx, leftSide, true); } private static List parseCloudmadeRoute(List res, GPXFile gpxFile, boolean osmandRouter, @@ -585,7 +615,7 @@ public class RouteProvider { } } - return new RouteCalculationResult(res, null, start, end, null, ctx, leftSide, true); + return new RouteCalculationResult(res, null, start, end, null, null, ctx, leftSide, true); } public GPXFile createOsmandRouterGPX(RouteCalculationResult srcRoute){ diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index 55fd56a61e..e19ed3dd6f 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -49,6 +49,7 @@ public class RoutingHelper { private RouteCalculationResult route = new RouteCalculationResult(""); private LatLon finalLocation; + private List intermediatePoints; private Location lastProjection; private Location lastFixedLocation; @@ -67,6 +68,7 @@ public class RoutingHelper { private long makeUTwpDetected = 0; + public boolean makeUturnWhenPossible() { return makeUturnWhenPossible; } @@ -89,15 +91,15 @@ public class RoutingHelper { - public synchronized void setFinalAndCurrentLocation(LatLon finalLocation, Location currentLocation, GPXRouteParams gpxRoute){ - clearCurrentRoute(finalLocation); + public synchronized void setFinalAndCurrentLocation(LatLon finalLocation, List intermediatePoints, Location currentLocation, GPXRouteParams gpxRoute){ + clearCurrentRoute(finalLocation, intermediatePoints); currentGPXRoute = gpxRoute; // to update route setCurrentLocation(currentLocation, false); } - public synchronized void clearCurrentRoute(LatLon newFinalLocation) { + public synchronized void clearCurrentRoute(LatLon newFinalLocation, List newIntermediatePoints) { route = new RouteCalculationResult(""); makeUturnWhenPossible = false; evalWaitInterval = 3000; @@ -110,6 +112,7 @@ public class RoutingHelper { } }); this.finalLocation = newFinalLocation; + this.intermediatePoints = newIntermediatePoints; if(currentRunningJob != null) { currentRunningJob.stopCalculation(); } @@ -144,6 +147,10 @@ public class RoutingHelper { return finalLocation; } + public List getIntermediatePoints() { + return intermediatePoints; + } + public boolean isRouteCalculated(){ return route.isCalculated(); } @@ -233,7 +240,7 @@ public class RoutingHelper { } if (calculateRoute) { - recalculateRouteInBackground(currentLocation, finalLocation, currentGPXRoute, + recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute, route.isCalculated()? route : null); } double projectDist = mode == ApplicationMode.CAR ? posTolerance : posTolerance / 2; @@ -330,13 +337,27 @@ public class RoutingHelper { break; } } + + // 2. check if intermediate found + if(getLeftDistanceNextIntermediate() < posTolerance * 1.5f){ + showMessage(context.getString(R.string.arrived_at_intermediate_point)); + voiceRouter.arrivedIntermediatePoint(); + } + if(intermediatePoints != null && intermediatePoints.size() > 0) { + while(route.getIntermediatePointsToPass() > settings.getIntermediatePoints().size()) { + settings.deleteIntermediatePoint(0); + } + while(route.getIntermediatePointsToPass() > intermediatePoints.size()) { + intermediatePoints.remove(0); + } + } - // 2. check if destination found + // 3. check if destination found Location lastPoint = routeNodes.get(routeNodes.size() - 1); if (currentRoute > routeNodes.size() - 3 && currentLocation.distanceTo(lastPoint) < posTolerance * 1.5) { showMessage(context.getString(R.string.arrived_at_destination)); voiceRouter.arrivedDestinationPoint(); - clearCurrentRoute(null); + clearCurrentRoute(null, null); return true; } return false; @@ -444,6 +465,10 @@ public class RoutingHelper { return route.getDistanceToFinish(lastFixedLocation); } + public synchronized int getLeftDistanceNextIntermediate() { + return route.getDistanceToNextIntermediate(lastFixedLocation); + } + public synchronized int getLeftTime() { return route.getLeftTime(lastFixedLocation); } @@ -535,15 +560,17 @@ public class RoutingHelper { private final RouteCalculationResult previousRoute; private RouteService service; private boolean interrupted = false; + private final List intermediates; public RouteRecalculationThread(String name, - Location start, LatLon end, GPXRouteParams gpxRoute, RouteCalculationResult previousRoute){ + Location start, LatLon end, List intermediates, GPXRouteParams gpxRoute, RouteCalculationResult previousRoute){ super(name); this.start = start; this.end = end; + this.intermediates = intermediates; this.gpxRoute = gpxRoute; this.previousRoute = previousRoute; - service = settings.ROUTER_SERVICE.get(); + service = settings.ROUTER_SERVICE.getModeValue(mode); } @@ -560,7 +587,7 @@ public class RoutingHelper { public void run() { boolean leftSide = settings.LEFT_SIDE_NAVIGATION.get(); boolean fastRoute = settings.FAST_ROUTE_MODE.get(); - RouteCalculationResult res = provider.calculateRouteImpl(start, end, mode, service, context, gpxRoute, previousRoute, fastRoute, + RouteCalculationResult res = provider.calculateRouteImpl(start, end, intermediates, mode, service, context, gpxRoute, previousRoute, fastRoute, leftSide, this); if (interrupted) { currentRunningJob = null; @@ -595,7 +622,7 @@ public class RoutingHelper { } - private void recalculateRouteInBackground(final Location start, final LatLon end, final GPXRouteParams gpxRoute, final RouteCalculationResult previousRoute){ + private void recalculateRouteInBackground(final Location start, final LatLon end, final List intermediates, final GPXRouteParams gpxRoute, final RouteCalculationResult previousRoute){ if (start == null || end == null) { return; } @@ -603,7 +630,7 @@ public class RoutingHelper { // do not evaluate very often if (System.currentTimeMillis() - lastTimeEvaluatedRoute > evalWaitInterval) { synchronized (this) { - currentRunningJob = new RouteRecalculationThread("Calculating route", start, end, gpxRoute, previousRoute); //$NON-NLS-1$ + currentRunningJob = new RouteRecalculationThread("Calculating route", start, end, intermediates, gpxRoute, previousRoute); //$NON-NLS-1$ currentRunningJob.start(); } } @@ -641,5 +668,5 @@ public class RoutingHelper { public GPXFile generateGPXFileWithRoute(){ return provider.createOsmandRouterGPX(route); } - + } diff --git a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java index 2145dd0345..4c9e2ab251 100644 --- a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java +++ b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java @@ -191,7 +191,6 @@ public class VoiceRouter { // after last turn say: if (nextInfo == null || nextInfo.directionInfo == null || nextInfo.directionInfo.distance == 0) { // if(currentStatus <= STATUS_UNKNOWN && currentDirection > 0){ This caused this prompt to be suppressed when coming back from a - // UTwp situation if (currentStatus <= STATUS_UNKNOWN) { if (playGoAheadToDestination()) { currentStatus = STATUS_TOLD; @@ -200,6 +199,15 @@ public class VoiceRouter { } return; } + if(nextInfo.intermediatePoint){ + if (currentStatus <= STATUS_UNKNOWN) { + if (playGoAheadToIntermediate()) { + currentStatus = STATUS_TOLD; + playGoAheadDist = 0; + } + } + return; + } int dist = nextInfo.distanceTo; RouteDirectionInfo next = nextInfo.directionInfo; @@ -343,6 +351,15 @@ public class VoiceRouter { return false; } + private boolean playGoAheadToIntermediate() { + CommandBuilder play = getNewCommandPlayerToPlay(); + if(play != null){ + play.goAhead(router.getLeftDistanceNextIntermediate()).andArriveAtDestination().play(); + return true; + } + return false; + } + private boolean playMakeUTwp() { CommandBuilder play = getNewCommandPlayerToPlay(); if(play != null){ @@ -505,6 +522,13 @@ public class VoiceRouter { play.arrivedAtDestination().play(); } } + + public void arrivedIntermediatePoint() { + CommandBuilder play = getNewCommandPlayerToPlay(); + if(play != null){ + play.arrivedAtIntermediatePoint().play(); + } + } public void onApplicationTerminate(Context ctx) { if (player != null) { diff --git a/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java b/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java index dfcbf6527f..1ea84029ea 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java @@ -239,23 +239,25 @@ public class MapInfoLayer extends OsmandMapLayer { //mapInfoControls.registerSideWidget(miniMap, R.drawable.widget_next_turn, R.string.map_widget_mini_route, "mini_route", true, none, none, 20); // right stack TextInfoControl dist = ric.createDistanceControl(map, paintText, paintSubText); - mapInfoControls.registerSideWidget(dist, R.drawable.widget_target, R.string.map_widget_distance, "distance", false, carDefault, none, 5); + mapInfoControls.registerSideWidget(dist, R.drawable.widget_target, R.string.map_widget_distance, "distance", false, all, none, 5); TextInfoControl time = ric.createTimeControl(map, paintText, paintSubText); - mapInfoControls.registerSideWidget(time, R.drawable.widget_time, R.string.map_widget_time, "time",false, carDefault, none, 10); + mapInfoControls.registerSideWidget(time, R.drawable.widget_time, R.string.map_widget_time, "time",false, all, none, 10); TextInfoControl speed = ric.createSpeedControl(map, paintText, paintSubText); - mapInfoControls.registerSideWidget(speed, R.drawable.widget_speed, R.string.map_widget_speed, "speed", false, carDefault, none, 15); + mapInfoControls.registerSideWidget(speed, R.drawable.widget_speed, R.string.map_widget_speed, "speed", false, all, none, 15); + TextInfoControl intermediateDist = ric.createIntermediateDistanceControl(map, paintText, paintSubText); + mapInfoControls.registerSideWidget(intermediateDist, R.drawable.widget_intermediate, R.string.map_widget_intermediate_distance, "intermediate_distance", false, all, none, 17); TextInfoControl alt = ric.createAltitudeControl(map, paintText, paintSubText); mapInfoControls.registerSideWidget(alt, R.drawable.widget_altitude, R.string.map_widget_altitude, "altitude", false, EnumSet.of(ApplicationMode.PEDESTRIAN), none, 20); // Top widgets ImageViewControl compassView = createCompassView(map); - mapInfoControls.registerTopWidget(compassView, R.drawable.compass, R.string.map_widget_compass, "compass", MapInfoControls.LEFT_CONTROL, carDefault, 5); + mapInfoControls.registerTopWidget(compassView, R.drawable.compass, R.string.map_widget_compass, "compass", MapInfoControls.LEFT_CONTROL, all, 5); View config = createConfiguration(); - mapInfoControls.registerTopWidget(config, R.drawable.widget_config, R.string.map_widget_config, "config", MapInfoControls.RIGHT_CONTROL, carDefault, 10).required(ApplicationMode.DEFAULT); + mapInfoControls.registerTopWidget(config, R.drawable.widget_config, R.string.map_widget_config, "config", MapInfoControls.RIGHT_CONTROL, all, 10).required(ApplicationMode.DEFAULT); ImageView lockView = lockInfoControl.createLockScreenWidget(view, map); mapInfoControls.registerTopWidget(lockView, R.drawable.lock_enabled, R.string.bg_service_screen_lock, "bgService", MapInfoControls.LEFT_CONTROL, exceptCar, 15); backToLocation = createBackToLocation(map); - mapInfoControls.registerTopWidget(backToLocation, R.drawable.default_location, R.string.map_widget_back_to_loc, "back_to_location", MapInfoControls.RIGHT_CONTROL, carDefault, 5); + mapInfoControls.registerTopWidget(backToLocation, R.drawable.default_location, R.string.map_widget_back_to_loc, "back_to_location", MapInfoControls.RIGHT_CONTROL, all, 5); View globus = createGlobus(); mapInfoControls.registerTopWidget(globus, R.drawable.globus, R.string.map_widget_map_select, "progress", MapInfoControls.RIGHT_CONTROL, none, 15); diff --git a/OsmAnd/src/net/osmand/plus/views/PointNavigationLayer.java b/OsmAnd/src/net/osmand/plus/views/PointNavigationLayer.java index 67b7d3ff41..f8c47db2fc 100644 --- a/OsmAnd/src/net/osmand/plus/views/PointNavigationLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/PointNavigationLayer.java @@ -1,12 +1,18 @@ package net.osmand.plus.views; +import java.util.ArrayList; +import java.util.List; + import net.osmand.osm.LatLon; import net.osmand.plus.R; +import net.osmand.plus.routing.RoutingHelper; import android.content.Context; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.Paint.Align; import android.graphics.Paint.Style; import android.graphics.PointF; import android.graphics.RectF; @@ -21,12 +27,18 @@ public class PointNavigationLayer extends OsmandMapLayer { private Paint bitmapPaint; protected LatLon pointToNavigate = null; + protected List intermediatePoints = new ArrayList(); private OsmandMapTileView view; private float[] calculations = new float[2]; private DisplayMetrics dm; private Bitmap targetPoint; + private Bitmap intermediatePoint; private Bitmap arrowToDestination; + + private Paint textPaint; + + private RoutingHelper routingHelper; @@ -41,7 +53,13 @@ public class PointNavigationLayer extends OsmandMapLayer { bitmapPaint.setDither(true); bitmapPaint.setAntiAlias(true); bitmapPaint.setFilterBitmap(true); + textPaint = new Paint(); + float sp = Resources.getSystem().getDisplayMetrics().scaledDensity; + textPaint.setTextSize(sp * 18); + textPaint.setTextAlign(Align.CENTER); + textPaint.setAntiAlias(true); targetPoint = BitmapFactory.decodeResource(view.getResources(), R.drawable.target_point); + intermediatePoint = BitmapFactory.decodeResource(view.getResources(), R.drawable.intermediate_point); arrowToDestination = BitmapFactory.decodeResource(view.getResources(), R.drawable.arrow_to_destination); @@ -53,6 +71,7 @@ public class PointNavigationLayer extends OsmandMapLayer { dm = new DisplayMetrics(); WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE); wmgr.getDefaultDisplay().getMetrics(dm); + routingHelper = view.getApplication().getRoutingHelper(); initUI(); } @@ -60,17 +79,35 @@ public class PointNavigationLayer extends OsmandMapLayer { @Override public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) { - if(pointToNavigate == null){ - return; + int index = 0; + + if(routingHelper != null && routingHelper.isFollowingMode() && routingHelper.isRouteCalculated()) { + List ip = routingHelper.getIntermediatePoints(); + int sz = ip == null ? 0 : ip.size(); + while(sz > intermediatePoints.size()) { + intermediatePoints.remove(0); + } } - if (isLocationVisible()) { + for (LatLon ip : intermediatePoints) { + index ++; + if (isLocationVisible(ip)) { + int marginX = intermediatePoint.getWidth() / 3; + int marginY = 2 * intermediatePoint.getHeight() / 3; + int locationX = view.getMapXForPoint(ip.getLongitude()); + int locationY = view.getMapYForPoint(ip.getLatitude()); + canvas.rotate(-view.getRotate(), locationX, locationY); + canvas.drawBitmap(intermediatePoint, locationX - marginX, locationY - marginY, bitmapPaint); + canvas.drawText(index + "", locationX + marginX, locationY, textPaint); + } + } + if (isLocationVisible(pointToNavigate)) { int marginX = targetPoint.getWidth() / 3; int marginY = 2 * targetPoint.getHeight() / 3; int locationX = view.getMapXForPoint(pointToNavigate.getLongitude()); int locationY = view.getMapYForPoint(pointToNavigate.getLatitude()); canvas.rotate(-view.getRotate(), locationX, locationY); canvas.drawBitmap(targetPoint, locationX - marginX, locationY - marginY, bitmapPaint); - } else { + } else if (pointToNavigate != null) { Location.distanceBetween(view.getLatitude(), view.getLongitude(), pointToNavigate.getLatitude(), pointToNavigate.getLongitude(), calculations); float bearing = calculations[1] - 90; @@ -78,15 +115,15 @@ public class PointNavigationLayer extends OsmandMapLayer { canvas.rotate(bearing, view.getCenterPointX(), view.getCenterPointY()); canvas.translate(-24 * dm.density + radiusBearing, -22 * dm.density); canvas.drawBitmap(arrowToDestination, view.getCenterPointX(), view.getCenterPointY(), bitmapPaint); - } + } - public boolean isLocationVisible(){ - if(pointToNavigate == null || view == null){ + public boolean isLocationVisible(LatLon p){ + if(p == null || view == null){ return false; } - return view.isPointOnTheRotatedMap(pointToNavigate.getLatitude(), pointToNavigate.getLongitude()); + return view.isPointOnTheRotatedMap(p.getLatitude(), p.getLongitude()); } @@ -94,10 +131,17 @@ public class PointNavigationLayer extends OsmandMapLayer { return pointToNavigate; } - public void setPointToNavigate(LatLon pointToNavigate) { + public void setPointToNavigate(LatLon pointToNavigate, List intermediatePoints) { this.pointToNavigate = pointToNavigate; + this.intermediatePoints.clear(); + this.intermediatePoints.addAll(intermediatePoints); view.refreshMap(); } + + public List getIntermediatePoints() { + return intermediatePoints; + } + @Override public void destroyLayer() { diff --git a/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java b/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java index a4c7875807..fa829a8f5a 100644 --- a/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java +++ b/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java @@ -339,62 +339,103 @@ public class RouteInfoControls { return speedControl; } - protected TextInfoControl createDistanceControl(final MapActivity map, Paint paintText, Paint paintSubText) { - final OsmandMapTileView view = map.getMapView(); - TextInfoControl distanceControl = new TextInfoControl(map, 0, paintText, paintSubText) { - private float[] calculations = new float[1]; - private int cachedMeters = 0; - - - @Override - public boolean updateInfo() { - if (map.getPointToNavigate() != null) { - int d = 0; - if (map.getRoutingHelper().isRouteCalculated()) { - d = map.getRoutingHelper().getLeftDistance(); + public abstract static class DistanceToPointInfoControl extends TextInfoControl { + + private final OsmandMapTileView view; + private float[] calculations = new float[1]; + private int cachedMeters; + + public DistanceToPointInfoControl(Context ctx, int leftMargin, Paint textPaint, Paint subtextPaint, Drawable d, + final OsmandMapTileView view) { + super(ctx, leftMargin, textPaint, subtextPaint); + this.view = view; + setImageDrawable(d); + setText(null, null); + setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + AnimateDraggingMapThread thread = view.getAnimatedDraggingThread(); + LatLon pointToNavigate = getPointToNavigate(); + if (pointToNavigate != null) { + float fZoom = view.getFloatZoom() < 15 ? 15 : view.getFloatZoom(); + thread.startMoving(pointToNavigate.getLatitude(), pointToNavigate.getLongitude(), fZoom, true); } - if (d == 0) { - Location.distanceBetween(view.getLatitude(), view.getLongitude(), map.getPointToNavigate().getLatitude(), map - .getPointToNavigate().getLongitude(), calculations); - d = (int) calculations[0]; - } - if (distChanged(cachedMeters, d)) { - cachedMeters = d; - if (cachedMeters <= 20) { - cachedMeters = 0; - setText(null, null); - } else { - String ds = OsmAndFormatter.getFormattedDistance(cachedMeters, map); - int ls = ds.lastIndexOf(' '); - if (ls == -1) { - setText(ds, null); - } else { - setText(ds.substring(0, ls), ds.substring(ls + 1)); - } - } - return true; - } - } else if (cachedMeters != 0) { + } + }); + } + @Override + public boolean updateInfo() { + int d = getDistance(); + if (distChanged(cachedMeters, d)) { + cachedMeters = d; + if (cachedMeters <= 20) { cachedMeters = 0; setText(null, null); - return true; + } else { + String ds = OsmAndFormatter.getFormattedDistance(cachedMeters, view.getContext()); + int ls = ds.lastIndexOf(' '); + if (ls == -1) { + setText(ds, null); + } else { + setText(ds.substring(0, ls), ds.substring(ls + 1)); + } } - return false; + return true; + } + return false; + } + + public abstract LatLon getPointToNavigate(); + + public int getDistance() { + int d = 0; + LatLon l = getPointToNavigate(); + if (l != null) { + Location.distanceBetween(view.getLatitude(), view.getLongitude(), l.getLatitude(), l.getLongitude(), calculations); + d = (int) calculations[0]; + } + return d; + } + } + + protected TextInfoControl createDistanceControl(final MapActivity map, Paint paintText, Paint paintSubText) { + final OsmandMapTileView view = map.getMapView(); + DistanceToPointInfoControl distanceControl = new DistanceToPointInfoControl(map, 0, paintText, paintSubText, map.getResources() + .getDrawable(R.drawable.info_target), view) { + @Override + public LatLon getPointToNavigate() { + return map.getPointToNavigate(); + } + + @Override + public int getDistance() { + if (map.getRoutingHelper().isRouteCalculated()) { + return map.getRoutingHelper().getLeftDistance(); + } + return super.getDistance(); } }; - distanceControl.setOnClickListener(new View.OnClickListener() { + return distanceControl; + } + + protected TextInfoControl createIntermediateDistanceControl(final MapActivity map, Paint paintText, Paint paintSubText) { + final OsmandMapTileView view = map.getMapView(); + DistanceToPointInfoControl distanceControl = new DistanceToPointInfoControl(map, 0, paintText, paintSubText, map.getResources() + .getDrawable(R.drawable.info_intermediate), view) { @Override - public void onClick(View v) { - AnimateDraggingMapThread thread = view.getAnimatedDraggingThread(); - LatLon pointToNavigate = view.getSettings().getPointToNavigate(); - if (pointToNavigate != null) { - float fZoom = view.getFloatZoom() < 15 ? 15 : view.getFloatZoom(); - thread.startMoving(pointToNavigate.getLatitude(), pointToNavigate.getLongitude(), fZoom, true); - } + public LatLon getPointToNavigate() { + return map.getFirstIntermediatePoint(); } - }); - distanceControl.setText(null, null); - distanceControl.setImageDrawable(view.getResources().getDrawable(R.drawable.info_target)); + + @Override + public int getDistance() { + if (getPointToNavigate() != null && map.getRoutingHelper().isRouteCalculated()) { + return map.getRoutingHelper().getLeftDistanceNextIntermediate(); + } + return super.getDistance(); + } + }; return distanceControl; } @@ -602,7 +643,7 @@ public class RouteInfoControls { } - public boolean distChanged(int oldDist, int dist){ + public static boolean distChanged(int oldDist, int dist){ if(oldDist != 0 && Math.abs(oldDist - dist) < 10){ return false; } diff --git a/OsmAnd/src/net/osmand/plus/voice/CommandBuilder.java b/OsmAnd/src/net/osmand/plus/voice/CommandBuilder.java index 51547eca18..90fb64ebaa 100644 --- a/OsmAnd/src/net/osmand/plus/voice/CommandBuilder.java +++ b/OsmAnd/src/net/osmand/plus/voice/CommandBuilder.java @@ -25,8 +25,11 @@ public class CommandBuilder { protected static final String C_MAKE_UTWP = "make_ut_wp"; //$NON-NLS-1$ protected static final String C_PREAMBLE = "preamble"; //$NON-NLS-1$ protected static final String C_AND_ARRIVE_DESTINATION = "and_arrive_destination"; //$NON-NLS-1$ - protected static final String C_THEN = "then"; //$NON-NLS-1$ protected static final String C_REACHED_DESTINATION = "reached_destination"; //$NON-NLS-1$ + protected static final String C_AND_ARRIVE_INTERMEDIATE = "and_arrive_intermediate"; //$NON-NLS-1$ + protected static final String C_REACHED_INTERMEDIATE = "reached_intermediate"; //$NON-NLS-1$ + protected static final String C_THEN = "then"; //$NON-NLS-1$ + protected static final String C_BEAR_LEFT = "bear_left"; //$NON-NLS-1$ protected static final String C_BEAR_RIGHT = "bear_right"; //$NON-NLS-1$ protected static final String C_ROUTE_RECALC = "route_recalc"; //$NON-NLS-1$ @@ -151,6 +154,14 @@ public class CommandBuilder { return addCommand(C_REACHED_DESTINATION); } + public CommandBuilder arrivedAtIntermediatePoint() { + return addCommand(C_REACHED_INTERMEDIATE); + } + + public CommandBuilder andArriveAtIntermediatePoint(){ + return addCommand(C_AND_ARRIVE_INTERMEDIATE); + } + public CommandBuilder bearLeft(){ return addCommand(C_BEAR_LEFT); } @@ -186,5 +197,6 @@ public class CommandBuilder { return this.commandPlayer.execute(listStruct); } + } \ No newline at end of file