Merge animateRout into master

This commit is contained in:
Victor Shcherb 2011-10-05 01:43:11 +02:00
commit 7caad71372
8 changed files with 138 additions and 6 deletions

View file

@ -10,6 +10,7 @@
<!-- not visible by default --> <!-- not visible by default -->
<item android:id="@+id/map_navigate_to_point" android:title="@string/stop_navigation" android:visible="false" android:icon="@android:drawable/ic_menu_close_clear_cancel"></item> <item android:id="@+id/map_navigate_to_point" android:title="@string/stop_navigation" android:visible="false" android:icon="@android:drawable/ic_menu_close_clear_cancel"></item>
<item android:id="@+id/map_mute" android:title="@string/menu_mute_off" android:visible="false"></item> <item android:id="@+id/map_mute" android:title="@string/menu_mute_off" android:visible="false"></item>
<item android:id="@+id/map_animate_route" android:title="@string/animate_route" 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_get_directions" android:title="@string/get_directions" android:icon="@android:drawable/ic_menu_directions"></item>
<item android:title="@string/context_menu_item_search" android:id="@+id/map_specify_point" android:icon="@android:drawable/ic_menu_search"></item> <item android:title="@string/context_menu_item_search" android:id="@+id/map_specify_point" android:icon="@android:drawable/ic_menu_search"></item>

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?> <?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources> <resources>
<string name="animate_route_off">Animate off</string>
<string name="animate_route">Animate on</string>
<string name="tip_recent_changes_0_6_8_t">Changes in 0.6.8 : <string name="tip_recent_changes_0_6_8_t">Changes in 0.6.8 :
\n\t- Completely redesigned search (POI, Address)! Make address search much faster and responsiveness. Leave one search with many different search aspects. \n\t- Completely redesigned search (POI, Address)! Make address search much faster and responsiveness. Leave one search with many different search aspects.
\n\t- Implement search POI by name big areas (countries) \n\t- Implement search POI by name big areas (countries)
@ -60,6 +63,7 @@
<string name="file_with_name_already_exist">File with same name already exists.</string> <string name="file_with_name_already_exist">File with same name already exists.</string>
<string name="default_buttons_save">Save</string> <string name="default_buttons_save">Save</string>
<string name="menu_save_directions">Save directions</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_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_items_uploaded">%1$d of %2$d item(s) successfully uploaded.</string>
<string name="local_index_mi_upload_gpx">Send to OSM...</string> <string name="local_index_mi_upload_gpx">Send to OSM...</string>

View file

@ -0,0 +1,34 @@
package net.osmand;
import android.location.Location;
public class LatLonUtils {
public static Location middleLocation(Location start, Location end,
float meters) {
double lat1 = toRad(start.getLatitude());
double lon1 = toRad(start.getLongitude());
double R = 6371; // radius of earth in km
double d = meters / 1000; // in km
float brng = (float) (toRad(start.bearingTo(end)));
double lat2 = Math.asin(Math.sin(lat1) * Math.cos(d / R)
+ Math.cos(lat1) * Math.sin(d / R) * Math.cos(brng));
double lon2 = lon1
+ Math.atan2(Math.sin(brng) * Math.sin(d / R) * Math.cos(lat1),
Math.cos(d / R) - Math.sin(lat1) * Math.sin(lat2));
Location nl = new Location(start);
nl.setLatitude(toDegree(lat2));
nl.setLongitude(toDegree(lon2));
nl.setBearing(brng);
return nl;
}
private static double toDegree(double radians) {
return radians * 180 / Math.PI;
}
private static double toRad(double degree) {
return degree * Math.PI / 180;
}
}

View file

@ -27,12 +27,12 @@ import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.PointLocationLayer; import net.osmand.plus.views.PointLocationLayer;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog; import android.app.Dialog;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -57,6 +57,7 @@ import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.provider.Settings.Secure;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.Menu; import android.view.Menu;
@ -64,8 +65,8 @@ import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.Window;
import android.view.animation.AccelerateInterpolator; import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.Transformation; import android.view.animation.Transformation;
@ -121,6 +122,8 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
// Store previous map rotation settings for rotate button // Store previous map rotation settings for rotate button
private Integer previousMapRotate = null; private Integer previousMapRotate = null;
private RouteAnimation routeAnimation = new RouteAnimation();
private boolean isMapLinkedToLocation = false; private boolean isMapLinkedToLocation = false;
private ProgressDialog startProgressDialog; private ProgressDialog startProgressDialog;
@ -536,6 +539,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
savingTrackHelper.close(); savingTrackHelper.close();
routeAnimation.close();
if(mNotificationManager != null){ if(mNotificationManager != null){
mNotificationManager.cancel(APP_NOTIFICATION_ID); mNotificationManager.cancel(APP_NOTIFICATION_ID);
} }
@ -986,6 +990,21 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
directions.setTitle(R.string.get_directions); directions.setTitle(R.string.get_directions);
} }
MenuItem animateMenu = menu.findItem(R.id.map_animate_route);
if (animateMenu != null) {
if(settings.TEST_ANIMATE_ROUTING.get()){
animateMenu.setTitle(routeAnimation.isRouteAnimating() ? R.string.animate_route_off
: R.string.animate_route);
animateMenu.setVisible("1".equals(Secure.getString(
getContentResolver(), Secure.ALLOW_MOCK_LOCATION))
&& settings.getPointToNavigate() != null
&& routingHelper.isRouteCalculated());
animateMenu.setVisible(true);
} else {
animateMenu.setVisible(false);
}
}
return val; return val;
} }
@ -1049,6 +1068,10 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
case R.id.map_show_point_options: case R.id.map_show_point_options:
contextMenuPoint(mapView.getLatitude(), mapView.getLongitude()); contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
return true; return true;
case R.id.map_animate_route:
//animate moving on route
routeAnimation.startStopRouteAnimation(routingHelper, this);
return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }

View file

@ -0,0 +1,65 @@
package net.osmand.plus.activities;
import java.util.ArrayList;
import java.util.List;
import net.osmand.LatLonUtils;
import android.location.Location;
public class RouteAnimation {
private Thread routeAnimation;
public boolean isRouteAnimating() {
return routeAnimation != null;
}
public void startStopRouteAnimation(final RoutingHelper routingHelper,
final MapActivity ma) {
if (!isRouteAnimating()) {
routeAnimation = new Thread() {
public void run() {
final List<Location> directions = new ArrayList<Location>(
routingHelper.getCurrentRoute());
Location current = null;
float meters = 20.0f;
while (!directions.isEmpty() && routeAnimation != null) {
if (current == null) {
current = new Location(directions.remove(0));
} else {
if (current.distanceTo(directions.get(0)) > meters) {
current = LatLonUtils.middleLocation(current,
directions.get(0), meters);
} else {
current = new Location(directions.remove(0));
}
}
current.setSpeed(meters);
current.setTime(System.currentTimeMillis());
ma.setLocation(current);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// do nothing
}
}
RouteAnimation.this.stop();
};
};
routeAnimation.start();
} else {
// stop the animation
stop();
}
}
private void stop() {
routeAnimation = null;
}
public void close() {
if (isRouteAnimating()) {
stop();
}
}
}

View file

@ -19,7 +19,6 @@ import net.osmand.plus.voice.CommandPlayer;
import android.content.Context; import android.content.Context;
import android.location.Location; import android.location.Location;
import android.os.Handler; import android.os.Handler;
import android.os.Message;
import android.util.FloatMath; import android.util.FloatMath;
import android.widget.Toast; import android.widget.Toast;
@ -127,6 +126,12 @@ public class RoutingHelper {
return currentGPXRoute; return currentGPXRoute;
} }
public List<Location> getCurrentRoute() {
return currentGPXRoute == null || currentGPXRoute.points.isEmpty() ? Collections
.unmodifiableList(routeNodes) : Collections
.unmodifiableList(currentGPXRoute.points);
}
public void setAppMode(ApplicationMode mode){ public void setAppMode(ApplicationMode mode){
this.mode = mode; this.mode = mode;
voiceRouter.updateAppMode(); voiceRouter.updateAppMode();