Save GPX route between crashes

This commit is contained in:
Victor Shcherb 2011-09-05 12:08:48 +02:00
parent db74682557
commit f14194558d
9 changed files with 521 additions and 386 deletions

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent" android:orientation="vertical">
<TextView android:text="@string/file_with_name_already_exist" android:id="@+id/DuplicateFileName" android:layout_marginLeft="5dp" android:layout_width="fill_parent" android:layout_height="wrap_content"
android:visibility="gone"/>
<LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_marginTop="3dp">
<TextView android:text="@string/filename_input" android:layout_marginLeft="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<EditText android:id="@+id/FileNameEdit" android:layout_marginLeft="5dp" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"
android:gravity="bottom|center" android:layout_marginTop="5dp">
<Button android:layout_width="125dp" android:layout_height="wrap_content" android:text="@string/default_buttons_save" android:id="@+id/Save"></Button>
<Button android:layout_width="125dp" android:layout_height="wrap_content" android:text="@string/default_buttons_cancel" android:id="@+id/Cancel"></Button>
</LinearLayout>
</LinearLayout>

View file

@ -12,6 +12,7 @@
<item android:id="@+id/map_mute" android:title="@string/menu_mute_off" android:visible="false"></item>
<item android:id="@+id/map_get_directions" android:title="@string/get_directions" android:icon="@android:drawable/ic_menu_directions"></item>
<item android:id="@+id/map_save_directions" android:title="@string/menu_save_directions" android:icon="@android:drawable/ic_menu_save" visible="false"></item>
<item android:title="@string/map_specify_point" android:id="@+id/map_specify_point" android:icon="@android:drawable/ic_menu_search"></item>
<item android:title="@string/show_gps_status" android:id="@+id/map_show_gps_status" android:icon="@android:drawable/ic_menu_compass"></item>

View file

@ -1,5 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<string name="save_route_dialog_title">Save route as GPX track</string>
<string name="route_successfully_saved_at">Route is successfully saved at \'%1$s\'.</string>
<string name="filename_input">File name : </string>
<string name="file_with_name_already_exist">File with same name already exists.</string>
<string name="default_buttons_save">Save</string>
<string name="menu_save_directions">Save directions</string>
<string name="local_index_upload_gpx_description">Upload GPX files to OSM community. They will be used to improve maps.</string>
<string name="local_index_items_uploaded">%1$d of %2$d item(s) successfully uploaded.</string>
<string name="local_index_mi_upload_gpx">Send to OSM...</string>

View file

@ -93,6 +93,7 @@ public class GPXUtilities {
public List<WptPt> points = new ArrayList<WptPt>();
public List<Route> routes = new ArrayList<Route>();
public String warning = null;
public String path = "";
public boolean isCloudmadeRouteFile(){
return "cloudmade".equalsIgnoreCase(author);
@ -273,9 +274,12 @@ public class GPXUtilities {
public static GPXFile loadGPXFile(Context ctx, File f, boolean convertCloudmadeSource) {
try {
return loadGPXFile(ctx, new FileInputStream(f), convertCloudmadeSource);
GPXFile file = loadGPXFile(ctx, new FileInputStream(f), convertCloudmadeSource);
file.path = f.getAbsolutePath();
return file;
} catch (FileNotFoundException e) {
GPXFile res = new GPXFile();
res.path = f.getAbsolutePath();
log.error("Error reading gpx", e); //$NON-NLS-1$
res.warning = ctx.getString(R.string.error_reading_gpx);
return res;

View file

@ -975,7 +975,8 @@ public class OsmandSettings {
public final OsmandPreference<String> CONTRIBUTION_INSTALL_APP_DATE = new StringPreference("CONTRIBUTION_INSTALL_APP_DATE", null, true);
public final OsmandPreference<Boolean> FOLLOW_TO_THE_ROUTE = new BooleanPreference("follow_to_route", false, true);
public final OsmandPreference<Boolean> FOLLOW_THE_ROUTE = new BooleanPreference("follow_to_route", false, true);
public final OsmandPreference<String> FOLLOW_THE_GPX_ROUTE = new StringPreference("follow_gpx", null, true);
public final OsmandPreference<Boolean> SHOW_ARRIVAL_TIME_OTHERWISE_EXPECTED_TIME =
new BooleanPreference("show_arrival_time", true, true);

View file

@ -1,10 +1,11 @@
package net.osmand.plus.activities;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import net.osmand.Algoritms;
import net.osmand.CallbackWithObject;
import net.osmand.GPXUtilities;
import net.osmand.LogUtil;
import net.osmand.Version;
import net.osmand.GPXUtilities.GPXFile;
@ -38,7 +39,6 @@ import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Color;
@ -53,6 +53,7 @@ import android.location.LocationManager;
import android.location.LocationProvider;
import android.media.AudioManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
@ -70,10 +71,8 @@ import android.view.View.OnClickListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.Toast;
import android.widget.ToggleButton;
public class MapActivity extends Activity implements IMapLocationListener, SensorEventListener {
@ -181,67 +180,37 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
mgr.tileDownloaded(request);
}
mapView.tileDownloaded(request);
}
});
savingTrackHelper = new SavingTrackHelper(this);
routingHelper = getMyApplication().getRoutingHelper();
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(!Algoritms.objectEquals(routingHelper.getFinalLocation(), pointToNavigate)){
routingHelper.setFollowingMode(false);
routingHelper.setFinalAndCurrentLocation(pointToNavigate, null);
}
if(settings.FOLLOW_TO_THE_ROUTE.get()){
if(pointToNavigate == null){
settings.FOLLOW_TO_THE_ROUTE.set(false);
} else if(!routingHelper.isRouteCalculated()){
Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.continue_follow_previous_route);
builder.setPositiveButton(R.string.default_buttons_yes, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
routingHelper.setFollowingMode(true);
getMyApplication().showDialogInitializingCommandPlayer(MapActivity.this);
}
});
builder.setNegativeButton(R.string.default_buttons_no, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
settings.APPLICATION_MODE.set(ApplicationMode.DEFAULT);
updateApplicationModeSettings();
settings.FOLLOW_TO_THE_ROUTE.set(false);
routingHelper.setFinalAndCurrentLocation(null, null);
mapView.refreshMap();
}
});
builder.show();
}
if(settings.FOLLOW_THE_ROUTE.get() && !routingHelper.isRouteCalculated()){
restoreRoutingMode(pointToNavigate);
}
mapView.setMapLocationListener(this);
mapLayers.createLayers(mapView);
if(!settings.isLastKnownMapLocation()){
// show first time when application ran
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
Location location = null;
try {
location = service.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
catch(IllegalArgumentException e) {
Log.d(LogUtil.TAG, "GPS location provider not available"); //$NON-NLS-1$
}
if(location == null){
for (String provider : service.getAllProviders()) {
try {
location = service.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
} catch(IllegalArgumentException e) {
Log.d(LogUtil.TAG, "Network location provider not available"); //$NON-NLS-1$
Location loc = service.getLastKnownLocation(provider);
if (location == null) {
location = loc;
} else if (loc != null && location.getTime() < loc.getTime()) {
location = loc;
}
} catch (IllegalArgumentException e) {
Log.d(LogUtil.TAG, "Location provider not available"); //$NON-NLS-1$
}
}
if(location != null){
@ -250,19 +219,150 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
}
}
backToLocation = (ImageButton)findViewById(R.id.BackToLocation);
backToLocation.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
backToLocationImpl();
}
});
}
@Override
protected void onResume() {
super.onResume();
if (settings.MAP_SCREEN_ORIENTATION.get() != getRequestedOrientation()) {
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());
currentScreenOrientation = getWindow().getWindowManager().getDefaultDisplay().getOrientation();
// for voice navigation
if (settings.AUDIO_STREAM_GUIDANCE.get() != null) {
setVolumeControlStream(settings.AUDIO_STREAM_GUIDANCE.get());
} else {
setVolumeControlStream(AudioManager.STREAM_MUSIC);
}
mapLayers.updateMapSource(mapView, null);
updateApplicationModeSettings();
mapLayers.getPoiMapLayer().setFilter(settings.getPoiFilterForMap((OsmandApplication) getApplication()));
backToLocation.setVisibility(View.INVISIBLE);
isMapLinkedToLocation = false;
if (routingHelper.isFollowingMode()) {
// by default turn off causing unexpected movements due to network establishing
// best to show previous location
isMapLinkedToLocation = true;
}
// if destination point was changed try to recalculate route
if (routingHelper.isFollowingMode() && !Algoritms.objectEquals(settings.getPointToNavigate(), routingHelper.getFinalLocation())) {
routingHelper.setFinalAndCurrentLocation(settings.getPointToNavigate(), routingHelper.getCurrentLocation(), routingHelper.getCurrentGPXRoute());
}
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
try {
service.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, gpsListener);
} catch (IllegalArgumentException e) {
Log.d(LogUtil.TAG, "GPS location provider not available"); //$NON-NLS-1$
}
// try to always ask for network provide : it is faster way to find location
try {
service.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, networkListener);
} catch (IllegalArgumentException e) {
Log.d(LogUtil.TAG, "Network location provider not available"); //$NON-NLS-1$
}
if (settings != null && settings.isLastKnownMapLocation()) {
LatLon l = settings.getLastKnownMapLocation();
mapView.setLatLon(l.getLatitude(), l.getLongitude());
mapView.setZoom(settings.getLastKnownMapZoom());
}
settings.MAP_ACTIVITY_ENABLED.set(true);
checkExternalStorage();
showAndHideMapPosition();
LatLon cur = new LatLon(mapView.getLatitude(), mapView.getLongitude());
LatLon latLon = settings.getAndClearMapLocationToShow();
if (latLon != null && !latLon.equals(cur)) {
mapView.getAnimatedDraggingThread().startMoving(latLon.getLatitude(), latLon.getLongitude(), settings.getMapZoomToShow(), true);
}
View progress = findViewById(R.id.ProgressBar);
if (progress != null) {
getMyApplication().getResourceManager().setBusyIndicator(new BusyIndicator(this, progress));
}
getMyApplication().getDaynightHelper().onMapResume();
}
private void notRestoreRoutingMode(){
settings.APPLICATION_MODE.set(ApplicationMode.DEFAULT);
updateApplicationModeSettings();
routingHelper.clearCurrentRoute(null);
mapView.refreshMap();
}
private void restoreRoutingMode(final LatLon pointToNavigate) {
final String gpxPath = settings.FOLLOW_THE_GPX_ROUTE.get();
if (pointToNavigate == null && gpxPath == null) {
notRestoreRoutingMode();
} else {
Builder builder = new AlertDialog.Builder(MapActivity.this);
builder.setMessage(R.string.continue_follow_previous_route);
builder.setPositiveButton(R.string.default_buttons_yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
AsyncTask<String, Void, GPXFile> task = new AsyncTask<String, Void, GPXFile>() {
@Override
protected GPXFile doInBackground(String... params) {
if (gpxPath != null) {
// Reverse also should be stored ?
GPXFile f = GPXUtilities.loadGPXFile(MapActivity.this, new File(gpxPath), false);
if (f.warning != null) {
return null;
}
return f;
} else {
return null;
}
}
@Override
protected void onPostExecute(GPXFile result) {
final GPXRouteParams gpxRoute = result == null ? null : new GPXRouteParams(result, false);
LatLon endPoint = pointToNavigate != null ? pointToNavigate : gpxRoute.getLastPoint();
Location startPoint = gpxRoute == null ? null : gpxRoute.getStartPointForRoute();
if (endPoint == null) {
notRestoreRoutingMode();
} else {
routingHelper.setFollowingMode(true);
routingHelper.setFinalAndCurrentLocation(endPoint, startPoint, gpxRoute);
getMyApplication().showDialogInitializingCommandPlayer(MapActivity.this);
}
}
};
task.execute(gpxPath);
}
});
builder.setNegativeButton(R.string.default_buttons_no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
notRestoreRoutingMode();
}
});
builder.show();
}
}
private OsmandApplication getMyApplication() {
OsmandApplication getMyApplication() {
return ((OsmandApplication) getApplication());
}
@ -706,7 +806,6 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorMgr.unregisterListener(this);
sensorRegistered = false;
routingHelper.setUiActivity(null);
getMyApplication().getDaynightHelper().onMapPause();
@ -755,84 +854,6 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
mapView.refreshMap();
}
@Override
protected void onResume() {
super.onResume();
if(settings.MAP_SCREEN_ORIENTATION.get() != getRequestedOrientation()){
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());
currentScreenOrientation = getWindow().getWindowManager().getDefaultDisplay().getOrientation();
// for voice navigation
if(settings.AUDIO_STREAM_GUIDANCE.get() != null){
setVolumeControlStream(settings.AUDIO_STREAM_GUIDANCE.get());
} else {
setVolumeControlStream(AudioManager.STREAM_MUSIC);
}
mapLayers.updateMapSource(mapView, null);
updateApplicationModeSettings();
mapLayers.getPoiMapLayer().setFilter(settings.getPoiFilterForMap((OsmandApplication) getApplication()));
backToLocation.setVisibility(View.INVISIBLE);
isMapLinkedToLocation = false;
if(routingHelper.isFollowingMode()){
// by default turn off causing unexpected movements due to network establishing
// best to show previous location
isMapLinkedToLocation = true;
}
routingHelper.setUiActivity(this);
if(routingHelper.isFollowingMode() && !Algoritms.objectEquals(settings.getPointToNavigate(), routingHelper.getFinalLocation())){
routingHelper.setFinalAndCurrentLocation(settings.getPointToNavigate(), routingHelper.getCurrentLocation());
}
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
try {
service.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, gpsListener);
} catch (IllegalArgumentException e) {
Log.d(LogUtil.TAG, "GPS location provider not available"); //$NON-NLS-1$
}
// try to always ask for network provide : it is faster way to find location
try {
service.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, networkListener);
} catch (IllegalArgumentException e) {
Log.d(LogUtil.TAG, "Network location provider not available"); //$NON-NLS-1$
}
if(settings != null && settings.isLastKnownMapLocation()){
LatLon l = settings.getLastKnownMapLocation();
mapView.setLatLon(l.getLatitude(), l.getLongitude());
mapView.setZoom(settings.getLastKnownMapZoom());
}
settings.MAP_ACTIVITY_ENABLED.set(true);
checkExternalStorage();
showAndHideMapPosition();
LatLon cur = new LatLon(mapView.getLatitude(), mapView.getLongitude());
LatLon latLon = settings.getAndClearMapLocationToShow();
if (latLon != null && !latLon.equals(cur)) {
mapView.getAnimatedDraggingThread().startMoving(latLon.getLatitude(),
latLon.getLongitude(), settings.getMapZoomToShow(), true);
}
View progress = findViewById(R.id.ProgressBar);
if(progress != null){
getMyApplication().getResourceManager().setBusyIndicator(new BusyIndicator(this, progress));
}
getMyApplication().getDaynightHelper().onMapResume();
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
@ -948,6 +969,11 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
muteMenu.setVisible(false);
}
}
MenuItem saveMenu = menu.findItem(R.id.map_save_directions);
if(saveMenu != null){
saveMenu.setVisible(routingHelper.isRouteCalculated());
}
return val;
}
@ -968,14 +994,17 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
case R.id.map_get_directions:
Location loc = getLastKnownLocation();
if(loc != null){
getDirections(loc.getLatitude(), loc.getLongitude(), true);
mapActions.getDirections(loc.getLatitude(), loc.getLongitude(), true);
} else {
getDirections(mapView.getLatitude(), mapView.getLongitude(), true);
mapActions.getDirections(mapView.getLatitude(), mapView.getLongitude(), true);
}
return true;
case R.id.map_layers:
mapLayers.openLayerSelectionDialog(mapView);
return true;
case R.id.map_save_directions :
mapActions.saveDirections();
return true;
case R.id.map_specify_point:
// next 2 lines replaced for Issue 493, replaced by new 3 lines
// NavigatePointActivity dlg = new NavigatePointActivity(this);
@ -998,7 +1027,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
mapView.refreshMap();
return true;
case R.id.map_gpx_routing:
useGPXRouting();
mapActions.navigateUsingGPX();
return true;
case R.id.map_show_point_options:
contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
@ -1040,125 +1069,6 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
}
}
private ApplicationMode getAppMode(ToggleButton[] buttons){
for(int i=0; i<buttons.length; i++){
if(buttons[i] != null && buttons[i].isChecked() && i < ApplicationMode.values().length){
return ApplicationMode.values()[i];
}
}
return settings.getApplicationMode();
}
protected void getDirections(final double lat, final double lon, boolean followEnabled){
if(mapLayers.getNavigationLayer().getPointToNavigate() == null){
Toast.makeText(this, R.string.mark_final_location_first, Toast.LENGTH_LONG).show();
return;
}
Builder builder = new AlertDialog.Builder(this);
View view = getLayoutInflater().inflate(R.layout.calculate_route, null);
final ToggleButton[] buttons = new ToggleButton[ApplicationMode.values().length];
buttons[ApplicationMode.CAR.ordinal()] = (ToggleButton) view.findViewById(R.id.CarButton);
buttons[ApplicationMode.BICYCLE.ordinal()] = (ToggleButton) view.findViewById(R.id.BicycleButton);
buttons[ApplicationMode.PEDESTRIAN.ordinal()] = (ToggleButton) view.findViewById(R.id.PedestrianButton);
ApplicationMode appMode = settings.getApplicationMode();
for(int i=0; i< buttons.length; i++){
if(buttons[i] != null){
final int ind = i;
ToggleButton b = buttons[i];
b.setChecked(appMode == ApplicationMode.values()[i]);
b.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
for (int j = 0; j < buttons.length; j++) {
if (buttons[j] != null) {
if(buttons[j].isChecked() != (ind == j)){
buttons[j].setChecked(ind == j);
}
}
}
} else {
// revert state
boolean revert = true;
for (int j = 0; j < buttons.length; j++) {
if (buttons[j] != null) {
if(buttons[j].isChecked()){
revert = false;
break;
}
}
}
if (revert){
buttons[ind].setChecked(true);
}
}
}
});
}
}
DialogInterface.OnClickListener onlyShowCall = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
ApplicationMode mode = getAppMode(buttons);
Location location = new Location("map"); //$NON-NLS-1$
location.setLatitude(lat);
location.setLongitude(lon);
routingHelper.setAppMode(mode);
settings.FOLLOW_TO_THE_ROUTE.set(false);
routingHelper.setFollowingMode(false);
routingHelper.setFinalAndCurrentLocation(getPointToNavigate(), location);
}
};
DialogInterface.OnClickListener followCall = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
ApplicationMode mode = getAppMode(buttons);
// change global settings
boolean changed = settings.APPLICATION_MODE.set(mode);
if (changed) {
updateApplicationModeSettings();
mapView.refreshMap();
}
Location location = getLocationToStartFrom(lat, lon);
routingHelper.setAppMode(mode);
settings.FOLLOW_TO_THE_ROUTE.set(true);
routingHelper.setFollowingMode(true);
routingHelper.setFinalAndCurrentLocation(getPointToNavigate(), location);
dialog.dismiss();
getMyApplication().showDialogInitializingCommandPlayer(MapActivity.this);
}
};
DialogInterface.OnClickListener showRoute = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(MapActivity.this, ShowRouteInfoActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
};
builder.setView(view);
if (followEnabled) {
builder.setTitle(R.string.follow_route);
builder.setPositiveButton(R.string.follow, followCall);
if (routingHelper.isRouterEnabled() && routingHelper.isRouteCalculated()) {
builder.setNeutralButton(R.string.route_about, showRoute);
}
builder.setNegativeButton(R.string.only_show, onlyShowCall);
} else {
builder.setTitle(R.string.show_route);
view.findViewById(R.id.TextView).setVisibility(View.GONE);
builder.setPositiveButton(R.string.show_route, onlyShowCall);
builder.setNegativeButton(R.string.default_buttons_cancel, null);
}
builder.show();
}
protected void parseLaunchIntentLocation(){
Intent intent = getIntent();
@ -1188,66 +1098,6 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
return getMyApplication().getFavorites();
}
private void useGPXRouting() {
final LatLon endForRouting = getPointToNavigate();
mapLayers.selectGPXFileLayer(new CallbackWithObject<GPXFile>() {
@Override
public boolean processResult(final GPXFile result) {
Builder builder = new AlertDialog.Builder(MapActivity.this);
final boolean[] props = new boolean[]{false, false, false};
builder.setMultiChoiceItems(new String[] { getString(R.string.gpx_option_reverse_route),
getString(R.string.gpx_option_destination_point), getString(R.string.gpx_option_from_start_point) }, props,
new OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
props[which] = isChecked;
}
});
builder.setPositiveButton(R.string.default_buttons_apply, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
boolean reverse = props[0];
boolean passWholeWay = props[2];
boolean useDestination = props[1];
GPXRouteParams gpxRoute = new GPXRouteParams(result, reverse);
Location loc = getLastKnownLocation();
if(passWholeWay && loc != null){
gpxRoute.setStartPoint(loc);
}
Location startForRouting = getLastKnownLocation();
if(startForRouting == null){
startForRouting = gpxRoute.getStartPointForRoute();
}
LatLon endPoint = endForRouting;
if(endPoint == null || !useDestination){
LatLon point = gpxRoute.getLastPoint();
if(point != null){
endPoint = point;
}
if(endPoint != null) {
settings.setPointToNavigate(point.getLatitude(), point.getLongitude(), null);
mapLayers.getNavigationLayer().setPointToNavigate(point);
}
}
mapView.refreshMap();
if(endPoint != null){
settings.FOLLOW_TO_THE_ROUTE.set(true);
routingHelper.setFollowingMode(true);
routingHelper.setFinalAndCurrentLocation(endPoint, startForRouting, gpxRoute);
getMyApplication().showDialogInitializingCommandPlayer(MapActivity.this);
}
}
});
builder.setNegativeButton(R.string.default_buttons_cancel, null);
builder.show();
return true;
}
}, false);
}
public void contextMenuPoint(final double latitude, final double longitude){
contextMenuPoint(latitude, longitude, null, null);
@ -1292,7 +1142,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
if(standardId == R.string.context_menu_item_navigate_point){
navigateToPoint(new LatLon(latitude, longitude));
} else if(standardId == R.string.context_menu_item_show_route){
getDirections(latitude, longitude, false);
mapActions. getDirections(latitude, longitude, false);
} else if(standardId == R.string.context_menu_item_search_poi){
Intent intent = new Intent(MapActivity.this, SearchPoiFilterActivity.class);
intent.putExtra(SearchPoiFilterActivity.SEARCH_LAT, latitude);
@ -1327,6 +1177,14 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
builder.create().show();
}
public MapActivityActions getMapActions() {
return mapActions;
}
public MapActivityLayers getMapLayers() {
return mapLayers;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@ -1337,14 +1195,5 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
activity.startActivity(newIntent);
}
private Location getLocationToStartFrom(final double lat, final double lon) {
Location location = getLastKnownLocation();
if(location == null){
location = new Location("map"); //$NON-NLS-1$
location.setLatitude(lat);
location.setLongitude(lon);
}
return location;
}
}

View file

@ -1,20 +1,27 @@
package net.osmand.plus.activities;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import net.osmand.CallbackWithObject;
import net.osmand.FavouritePoint;
import net.osmand.LogUtil;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.data.Amenity;
import net.osmand.map.ITileSource;
import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
import net.osmand.plus.AmenityIndexRepository;
import net.osmand.plus.AmenityIndexRepositoryOdb;
import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.ResourceManager;
import net.osmand.plus.activities.RouteProvider.GPXRouteParams;
import net.osmand.plus.views.BaseMapLayer;
import net.osmand.plus.views.MapTileLayer;
import net.osmand.plus.views.OsmandMapTileView;
@ -25,9 +32,12 @@ import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.RectF;
import android.location.Location;
import android.os.AsyncTask;
import android.text.ClipboardManager;
import android.text.Html;
import android.util.FloatMath;
@ -35,8 +45,11 @@ import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import android.widget.ToggleButton;
public class MapActivityActions {
@ -290,5 +303,271 @@ public class MapActivityActions {
builder.show();
}
protected void getDirections(final double lat, final double lon, boolean followEnabled){
MapActivityLayers mapLayers = mapActivity.getMapLayers();
final OsmandSettings settings = OsmandSettings.getOsmandSettings(mapActivity);
final RoutingHelper routingHelper = mapActivity.getRoutingHelper();
if(mapLayers.getNavigationLayer().getPointToNavigate() == null){
Toast.makeText(mapActivity, R.string.mark_final_location_first, Toast.LENGTH_LONG).show();
return;
}
Builder builder = new AlertDialog.Builder(mapActivity);
View view = mapActivity.getLayoutInflater().inflate(R.layout.calculate_route, null);
final ToggleButton[] buttons = new ToggleButton[ApplicationMode.values().length];
buttons[ApplicationMode.CAR.ordinal()] = (ToggleButton) view.findViewById(R.id.CarButton);
buttons[ApplicationMode.BICYCLE.ordinal()] = (ToggleButton) view.findViewById(R.id.BicycleButton);
buttons[ApplicationMode.PEDESTRIAN.ordinal()] = (ToggleButton) view.findViewById(R.id.PedestrianButton);
ApplicationMode appMode = settings.getApplicationMode();
for(int i=0; i< buttons.length; i++){
if(buttons[i] != null){
final int ind = i;
ToggleButton b = buttons[i];
b.setChecked(appMode == ApplicationMode.values()[i]);
b.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
for (int j = 0; j < buttons.length; j++) {
if (buttons[j] != null) {
if(buttons[j].isChecked() != (ind == j)){
buttons[j].setChecked(ind == j);
}
}
}
} else {
// revert state
boolean revert = true;
for (int j = 0; j < buttons.length; j++) {
if (buttons[j] != null) {
if(buttons[j].isChecked()){
revert = false;
break;
}
}
}
if (revert){
buttons[ind].setChecked(true);
}
}
}
});
}
}
DialogInterface.OnClickListener onlyShowCall = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
ApplicationMode mode = getAppMode(buttons, settings);
Location location = new Location("map"); //$NON-NLS-1$
location.setLatitude(lat);
location.setLongitude(lon);
routingHelper.setAppMode(mode);
settings.FOLLOW_THE_ROUTE.set(false);
settings.FOLLOW_THE_GPX_ROUTE.set(null);
routingHelper.setFollowingMode(false);
routingHelper.setFinalAndCurrentLocation(mapActivity.getPointToNavigate(), location);
}
};
DialogInterface.OnClickListener followCall = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
ApplicationMode mode = getAppMode(buttons, settings);
// change global settings
boolean changed = settings.APPLICATION_MODE.set(mode);
if (changed) {
mapActivity.updateApplicationModeSettings();
mapActivity.getMapView().refreshMap();
}
Location location = getLocationToStartFrom(lat, lon);
routingHelper.setAppMode(mode);
settings.FOLLOW_THE_ROUTE.set(true);
settings.FOLLOW_THE_GPX_ROUTE.set(null);
routingHelper.setFollowingMode(true);
routingHelper.setFinalAndCurrentLocation(mapActivity.getPointToNavigate(), location);
dialog.dismiss();
getMyApplication().showDialogInitializingCommandPlayer(mapActivity);
}
};
DialogInterface.OnClickListener showRoute = new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(mapActivity, ShowRouteInfoActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mapActivity.startActivity(intent);
}
};
builder.setView(view);
if (followEnabled) {
builder.setTitle(R.string.follow_route);
builder.setPositiveButton(R.string.follow, followCall);
if (routingHelper.isRouterEnabled() && routingHelper.isRouteCalculated()) {
builder.setNeutralButton(R.string.route_about, showRoute);
}
builder.setNegativeButton(R.string.only_show, onlyShowCall);
} else {
builder.setTitle(R.string.show_route);
view.findViewById(R.id.TextView).setVisibility(View.GONE);
builder.setPositiveButton(R.string.show_route, onlyShowCall);
builder.setNegativeButton(R.string.default_buttons_cancel, null);
}
builder.show();
}
protected OsmandApplication getMyApplication() {
return mapActivity.getMyApplication();
}
private Location getLocationToStartFrom(final double lat, final double lon) {
Location location = mapActivity.getLastKnownLocation();
if(location == null){
location = new Location("map"); //$NON-NLS-1$
location.setLatitude(lat);
location.setLongitude(lon);
}
return location;
}
public void navigateUsingGPX() {
final LatLon endForRouting = mapActivity.getPointToNavigate();
final MapActivityLayers mapLayers = mapActivity.getMapLayers();
final OsmandSettings settings = OsmandSettings.getOsmandSettings(mapActivity);
final RoutingHelper routingHelper = mapActivity.getRoutingHelper();
mapLayers.selectGPXFileLayer(new CallbackWithObject<GPXFile>() {
@Override
public boolean processResult(final GPXFile result) {
Builder builder = new AlertDialog.Builder(mapActivity);
final boolean[] props = new boolean[]{false, false, false};
builder.setMultiChoiceItems(new String[] { getString(R.string.gpx_option_reverse_route),
getString(R.string.gpx_option_destination_point), getString(R.string.gpx_option_from_start_point) }, props,
new OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
props[which] = isChecked;
}
});
builder.setPositiveButton(R.string.default_buttons_apply, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
boolean reverse = props[0];
boolean passWholeWay = props[2];
boolean useDestination = props[1];
GPXRouteParams gpxRoute = new GPXRouteParams(result, reverse);
Location loc = mapActivity.getLastKnownLocation();
if(passWholeWay && loc != null){
gpxRoute.setStartPoint(loc);
}
Location startForRouting = mapActivity.getLastKnownLocation();
if(startForRouting == null){
startForRouting = gpxRoute.getStartPointForRoute();
}
LatLon endPoint = endForRouting;
if(endPoint == null || !useDestination){
LatLon point = gpxRoute.getLastPoint();
if(point != null){
endPoint = point;
}
if(endPoint != null) {
settings.setPointToNavigate(point.getLatitude(), point.getLongitude(), null);
mapLayers.getNavigationLayer().setPointToNavigate(point);
}
}
mapActivity.getMapView().refreshMap();
if(endPoint != null){
settings.FOLLOW_THE_ROUTE.set(true);
settings.FOLLOW_THE_GPX_ROUTE.set(result.path);
routingHelper.setFollowingMode(true);
routingHelper.setFinalAndCurrentLocation(endPoint, startForRouting, gpxRoute);
getMyApplication().showDialogInitializingCommandPlayer(mapActivity);
}
}
});
builder.setNegativeButton(R.string.default_buttons_cancel, null);
builder.show();
return true;
}
}, false);
}
private ApplicationMode getAppMode(ToggleButton[] buttons, OsmandSettings settings){
for(int i=0; i<buttons.length; i++){
if(buttons[i] != null && buttons[i].isChecked() && i < ApplicationMode.values().length){
return ApplicationMode.values()[i];
}
}
return settings.getApplicationMode();
}
public void saveDirections() {
OsmandSettings settings = getMyApplication().getSettings();
final File fileDir = settings.extendOsmandPath(ResourceManager.GPX_PATH);
final Dialog dlg = new Dialog(mapActivity);
dlg.setTitle(R.string.save_route_dialog_title);
dlg.setContentView(R.layout.save_directions_dialog);
final EditText edit = (EditText) dlg.findViewById(R.id.FileNameEdit);
edit.setText("");
((Button) dlg.findViewById(R.id.Save)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = edit.getText().toString();
fileDir.mkdirs();
File toSave = fileDir;
if(name.length() > 0) {
if(!name.endsWith(".gpx")){
name += ".gpx";
}
toSave = new File(fileDir, name);
}
if(toSave.exists()){
dlg.findViewById(R.id.DuplicateFileName).setVisibility(View.VISIBLE);
} else {
new SaveDirectionsAsyncTask().execute(fileDir);
}
}
});
((Button) dlg.findViewById(R.id.Cancel)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dlg.dismiss();
}
});
dlg.show();
}
private class SaveDirectionsAsyncTask extends AsyncTask<File, Void, String> {
@Override
protected String doInBackground(File... params) {
if (params.length > 0) {
File file = params[0];
return mapActivity.getString(R.string.route_successfully_saved_at, file.getName());
}
return null;
}
@Override
protected void onPostExecute(String result) {
if(result != null){
Toast.makeText(mapActivity, result, Toast.LENGTH_SHORT);
}
}
}
}

View file

@ -14,9 +14,9 @@ import net.osmand.plus.activities.RouteProvider.GPXRouteParams;
import net.osmand.plus.activities.RouteProvider.RouteCalculationResult;
import net.osmand.plus.activities.RouteProvider.RouteService;
import net.osmand.plus.voice.CommandPlayer;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.os.Handler;
import android.util.FloatMath;
import android.widget.Toast;
@ -38,9 +38,6 @@ public class RoutingHelper {
private Context context;
// activity to show messages & refresh map when route is calculated
private Activity uiActivity;
private boolean isFollowingMode = false;
private GPXRouteParams currentGPXRoute = null;
@ -67,6 +64,8 @@ public class RoutingHelper {
private RouteProvider provider = new RouteProvider();
private VoiceRouter voiceRouter;
private Handler uiHandler;
@ -74,6 +73,7 @@ public class RoutingHelper {
this.settings = settings;
this.context = context;
voiceRouter = new VoiceRouter(this, player);
uiHandler = new Handler();
}
public boolean isFollowingMode() {
@ -97,29 +97,27 @@ public class RoutingHelper {
}
public void clearCurrentRoute(LatLon newFinalLocation){
public void clearCurrentRoute(LatLon newFinalLocation) {
this.routeNodes.clear();
listDistance = null;
directionInfo = null;
evalWaitInterval = 3000;
if(uiActivity != null){
uiActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
for(IRouteInformationListener l : listeners){
l.routeWasCancelled();
}
uiHandler.post(new Runnable() {
@Override
public void run() {
for (IRouteInformationListener l : listeners) {
l.routeWasCancelled();
}
});
}
}
});
this.finalLocation = newFinalLocation;
if(newFinalLocation == null){
settings.FOLLOW_TO_THE_ROUTE.set(false);
if (newFinalLocation == null) {
settings.FOLLOW_THE_ROUTE.set(false);
settings.FOLLOW_THE_GPX_ROUTE.set(null);
// clear last fixed location
this.lastFixedLocation = null;
this.isFollowingMode = false;
}
}
public GPXRouteParams getCurrentGPXRoute() {
@ -167,10 +165,6 @@ public class RoutingHelper {
return false;
}
public void setUiActivity(Activity uiActivity) {
this.uiActivity = uiActivity;
}
public Location getCurrentLocation() {
return lastFixedLocation;
}
@ -343,7 +337,7 @@ public class RoutingHelper {
}
private synchronized void setNewRoute(RouteCalculationResult res){
boolean updateRoute = !routeNodes.isEmpty();
final boolean updateRoute = !routeNodes.isEmpty();
routeNodes = res.getLocations();
directionInfo = res.getDirections();
listDistance = res.getListDistance();
@ -352,9 +346,15 @@ public class RoutingHelper {
if(isFollowingMode){
voiceRouter.newRouteIsCalculated(updateRoute);
}
for(IRouteInformationListener l : listeners){
l.newRouteIsCalculated(updateRoute);
}
uiHandler.post(new Runnable() {
@Override
public void run() {
for (IRouteInformationListener l : listeners) {
l.newRouteIsCalculated(updateRoute);
}
}
});
}
public synchronized int getLeftDistance(){
@ -482,10 +482,6 @@ public class RoutingHelper {
int l = dist != null && dist.length > 0 ? dist[0] : 0;
showMessage(context.getString(R.string.new_route_calculated_dist)
+ " : " + OsmAndFormatter.getFormattedDistance(l, context)); //$NON-NLS-1$
if (uiActivity instanceof MapActivity) {
// be aware that is non ui thread
((MapActivity) uiActivity).getMapView().refreshMap();
}
} else {
if (res.getErrorMessage() != null) {
showMessage(context.getString(R.string.error_calculating_route) + " : " + res.getErrorMessage()); //$NON-NLS-1$
@ -508,17 +504,13 @@ public class RoutingHelper {
return currentRunningJob != null;
}
private void showMessage(final String msg, final int length){
if (uiActivity != null) {
uiActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if(uiActivity != null){
Toast.makeText(uiActivity, msg, length).show();
}
}
});
}
private void showMessage(final String msg, final int length) {
uiHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(context, msg, length).show();
}
});
}
private void showMessage(final String msg){
showMessage(msg, Toast.LENGTH_SHORT);

View file

@ -16,7 +16,6 @@ import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.location.Location;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
@ -37,7 +36,6 @@ public class RouteInfoLayer implements OsmandMapLayer, IRouteInformationListener
private Button next;
private Button prev;
private Button info;
private Handler uiHandler;
private boolean visible = true;
private RectF border;
private RectF textBorder;
@ -136,7 +134,6 @@ public class RouteInfoLayer implements OsmandMapLayer, IRouteInformationListener
wmgr.getDefaultDisplay().getMetrics(dm);
textSize = (int) (BASE_TEXT_SIZE * dm.density);
uiHandler = new Handler();
border = new RectF();
paintBorder = new Paint();
paintBorder.setARGB(220, 160, 160, 160);
@ -217,17 +214,12 @@ public class RouteInfoLayer implements OsmandMapLayer, IRouteInformationListener
@Override
public void newRouteIsCalculated(boolean updateRoute) {
uiHandler.post(new Runnable(){
@Override
public void run() {
directionInfo = -1;
if(!routingHelper.isFollowingMode()){
visible = true;
}
updateVisibility();
}
});
directionInfo = -1;
if (!routingHelper.isFollowingMode()) {
visible = true;
}
updateVisibility();
view.refreshMap();
}
public boolean isUserDefinedVisible() {
@ -240,13 +232,8 @@ public class RouteInfoLayer implements OsmandMapLayer, IRouteInformationListener
}
@Override
public void routeWasCancelled() {
uiHandler.post(new Runnable(){
@Override
public void run() {
directionInfo = -1;
updateVisibility();
}
});
directionInfo = -1;
updateVisibility();
}