Add basic intermediate support

This commit is contained in:
Victor Shcherb 2012-09-17 01:37:20 +02:00
parent aa2fe68d90
commit 4e99dd0ebf
42 changed files with 512 additions and 123 deletions

View file

@ -165,6 +165,10 @@ public class BinaryRoutePlanner {
return road;
}
public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, List<RouteSegment> intermediate, boolean leftSideNavigation) throws IOException {
// TODO
return searchRoute(ctx, start, end, leftSideNavigation);
}
/**

View file

@ -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 '].

View file

@ -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?

View file

@ -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'].

View file

@ -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ä '].

View file

@ -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 '].

View file

@ -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 == ['आप अपनी मंजिल पर पहोच चुके है '].

View file

@ -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 '].

View file

@ -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'].

View file

@ -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 == ['목적지에 도착하였습니다 '].

View file

@ -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ā '].

View file

@ -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 '].

View file

@ -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! '].

View file

@ -33,6 +33,8 @@ go_ahead == ['Продолжайте движение прямо '].
go_ahead(Dist) == ['Продолжайте движение ', D]:- distance(Dist) == D.
and_arrive_destination == ['и вы прибудете в пункт назначения '].
and_arrive_intermediate == ['и вы прибудете в промежуточный пункт '].
reached_intermediate == ['вы прибыли в промежуточный пункт'].
then == ['затем '].
reached_destination == ['вы прибыли в пункт назначения '].

View file

@ -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?

View file

@ -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'].

View file

@ -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'].

View file

@ -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 '].

View file

@ -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 == ['抵達終點 '].

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -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
-->
<string name="intermediate_point_too_far">Intermediate point %1$s too far from nearest road.</string>
<string name="arrived_at_intermediate_point">You have arrived at your intermediate point</string>
<string name="context_menu_item_intermediate_point">Add intermediate point</string>
<string name="map_widget_intermediate_distance">Intermediate point</string>
<string name="ending_point_too_far">Starting point too far from nearest road.</string>
<string name="btn_add_tag">Add Tag</string>
<string name="btn_advanced_mode">Advanced Mode...</string>

View file

@ -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<LatLon> getIntermediatePoints() {
List<LatLon> list = new ArrayList<LatLon>();
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<LatLon> 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<LatLon> ps = getIntermediatePoints();
ps.remove(index);
return saveIntermediatePoints(ps);
}
private boolean saveIntermediatePoints(List<LatLon> ps) {
StringBuilder sb = new StringBuilder();
for(int i=0; i<ps.size(); i++) {
if(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();

View file

@ -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;

View file

@ -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<LatLon>());
mapView.refreshMap(changed);
}
private void restoreRoutingMode(final LatLon pointToNavigate) {
private void restoreRoutingMode(final LatLon pointToNavigate, final List<LatLon> 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<LatLon> getIntermediatePoitns(){
return mapLayers.getNavigationLayer().getIntermediatePoints();
}
public LatLon getFirstIntermediatePoint(){
List<LatLon> ip = mapLayers.getNavigationLayer().getIntermediatePoints();
if(ip.size() > 0) {
return ip.get(0);
}
return null;
}
public RoutingHelper getRoutingHelper() {
return routingHelper;
}

View file

@ -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<LatLon>());
}
}
// 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<LatLon>(), 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<LatLon>(), 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;

View file

@ -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;

View file

@ -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();
}

View file

@ -26,21 +26,24 @@ public class RouteCalculationResult {
private final List<AlarmInfo> 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<Location> list, List<RouteDirectionInfo> directions, Location start, LatLon end, String errorMessage,
Context ctx, boolean leftSide, boolean addMissingTurns) {
public RouteCalculationResult(List<Location> list, List<RouteDirectionInfo> directions, Location start, LatLon end,
List<LatLon> intermediates, String errorMessage, Context ctx, boolean leftSide, boolean addMissingTurns) {
this.errorMessage = errorMessage;
this.intermediatePoints = new int[intermediates == null ? 0 : intermediates.size()];
List<Location> locations = list == null ? new ArrayList<Location>() : new ArrayList<Location>(list);
List<RouteDirectionInfo> localDirections = directions == null? new ArrayList<RouteDirectionInfo>() : new ArrayList<RouteDirectionInfo>(directions);
if (!locations.isEmpty()) {
@ -59,15 +62,16 @@ public class RouteCalculationResult {
this.listDistance = new int[locations.size()];
updateListDistanceTime();
this.alarmInfo = new ArrayList<AlarmInfo>();
calculateIntermediateIndexes(ctx, intermediates, localDirections);
this.directions = Collections.unmodifiableList(localDirections);
updateDirectionsTime();
}
public RouteCalculationResult(List<RouteSegmentResult> list, Location start, LatLon end,
public RouteCalculationResult(List<RouteSegmentResult> list, Location start, LatLon end, List<LatLon> intermediates,
Context ctx, boolean leftSide) {
List<RouteDirectionInfo> computeDirections = new ArrayList<RouteDirectionInfo>();
this.errorMessage = null;
this.intermediatePoints = new int[intermediates == null ? 0 : intermediates.size()];
List<Location> locations = new ArrayList<Location>();
ArrayList<AlarmInfo> alarms = new ArrayList<AlarmInfo>();
List<RouteSegmentResult> 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<LatLon> intermediates, List<RouteDirectionInfo> 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<AlarmInfo> 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;
}

View file

@ -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<LatLon> 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<Location> sublist = new ArrayList<Location>(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<RouteDirectionInfo> subdirections = new ArrayList<RouteDirectionInfo>();
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<LatLon> intermediates, ApplicationMode mode, OsmandApplication app,
List<RouteSegmentResult> 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<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>();
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<RouteSegmentResult> result = router.searchRoute(ctx, st, en, leftSide);
return new RouteCalculationResult(result, start, end, app, leftSide);
List<RouteSegmentResult> 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<LatLon> intermediates, ApplicationMode mode, Context ctx, boolean fast, boolean leftSide)
throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException {
List<Location> res = new ArrayList<Location>();
List<RouteDirectionInfo> 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<RouteDirectionInfo> parseCloudmadeRoute(List<Location> 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){

View file

@ -49,6 +49,7 @@ public class RoutingHelper {
private RouteCalculationResult route = new RouteCalculationResult("");
private LatLon finalLocation;
private List<LatLon> 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<LatLon> 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<LatLon> 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<LatLon> 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<LatLon> intermediates;
public RouteRecalculationThread(String name,
Location start, LatLon end, GPXRouteParams gpxRoute, RouteCalculationResult previousRoute){
Location start, LatLon end, List<LatLon> 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<LatLon> 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);
}
}

View file

@ -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) {

View file

@ -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);

View file

@ -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<LatLon> intermediatePoints = new ArrayList<LatLon>();
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<LatLon> 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<LatLon> intermediatePoints) {
this.pointToNavigate = pointToNavigate;
this.intermediatePoints.clear();
this.intermediatePoints.addAll(intermediatePoints);
view.refreshMap();
}
public List<LatLon> getIntermediatePoints() {
return intermediatePoints;
}
@Override
public void destroyLayer() {

View file

@ -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;
}

View file

@ -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);
}
}