1. small improvements

2. online routing
3. update todo constants

git-svn-id: https://osmand.googlecode.com/svn/trunk@170 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-06-19 09:41:01 +00:00
parent 8e854cf3c4
commit d7b27a8ebf
14 changed files with 668 additions and 29 deletions

View file

@ -27,6 +27,10 @@ public class ToDoConstants {
// 42. Revise UI (icons/layouts). Support different devices. Add inactive/focus(!) icon versions. // 42. Revise UI (icons/layouts). Support different devices. Add inactive/focus(!) icon versions.
// 37. Get rid of exit button (!). Think about when notification should go & how clear resources if it is necessary
// DONE :
// TODO : add to app settings preference (Refresh indexes).
// 32. Introduce POI predefined filters (car filter(other-fuel, transportation-car_wash, show-car) and others) // 32. Introduce POI predefined filters (car filter(other-fuel, transportation-car_wash, show-car) and others)
// DONE : back end (POI filter object, save, delete, read) // DONE : back end (POI filter object, save, delete, read)
// TODO : activity to create/edit new index, activity to read both user defined/osm standard, add actions to remove/create // TODO : activity to create/edit new index, activity to read both user defined/osm standard, add actions to remove/create
@ -36,19 +40,24 @@ public class ToDoConstants {
// DONE: Load transport routes in swing. // DONE: Load transport routes in swing.
// TODO: Create transport index, create transport activity // TODO: Create transport index, create transport activity
// 37. Get rid of exit button (!). Think about when notification should go & how clear resources if it is necessary
// DONE :
// TODO : add to app settings preference (Refresh indexes).
// 34. Suppport navigation for calculated route (example of get route from internet is in swing app). // 34. Suppport navigation for calculated route (example of get route from internet is in swing app).
// IDEA : Victor have ideas // IDEA : Victor have ideas
// FUTURE RELEASES // FUTURE RELEASES
// 48. Enable change favourite point (for example fav - "car") means last point you left car. It is not static point.
// 43. Enable poi filter by name (?) // 43. Enable poi filter by name (?)
// 44. Show gps status (possibly open existing gps-compass app (free) or suggest to install it - no sense to write own activity)
// 45. Get clear <Use internet> settings. Move that setting on top settings screen.
// That setting should rule all activities that use internet. It should ask whenever internet is used
// (would you like to use internet for that operation - if using internet is not checked).
// Internet using now for : edit POI osm, show osm bugs layer, download tiles.
// 40. Support simple vector road rendering (require new index file) (?) // 40. Support simple vector road rendering (require new index file) (?)
// 26. Show the whole street on map (when it is chosen in search activity). Possibly extend that story to show layer with streets. (?) // 26. Show the whole street on map (when it is chosen in search activity). Possibly extend that story to show layer with streets. (?)
// 46. Implement downloading strategy for tiles (do not load 17 zoom, load only 16 for example) - try to scale 15 zoom for 17 (?)
// 47. Internet connectivity could be checked before trying to use
// BUGS Android // BUGS Android
// 5. Improvement : Implement caching files existing on FS, implement specific method in RM // 5. Improvement : Implement caching files existing on FS, implement specific method in RM

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="use_online_routing_descr">Use internet to calculate route</string>
<string name="use_online_routing">Use online routing</string>
<string name="user_password_descr">Input osm password</string> <string name="user_password_descr">Input osm password</string>
<string name="user_password">User password</string> <string name="user_password">User password</string>
<string name="osm_settings_descr">Specify osm settings: show bugs, osm login</string> <string name="osm_settings_descr">Specify osm settings: show bugs, osm login</string>

View file

@ -4,7 +4,7 @@
<ListPreference android:summary="@string/settings_preset_descr" android:title="@string/settings_preset" android:key="application_mode"></ListPreference> <ListPreference android:summary="@string/settings_preset_descr" android:title="@string/settings_preset" android:key="application_mode"></ListPreference>
<CheckBoxPreference android:key="use_internet_to_calculate_route" android:title="@string/use_online_routing" android:summary="@string/use_online_routing_descr"></CheckBoxPreference>
<PreferenceScreen android:title="@string/map_preferences" android:summary="@string/map_preferences_descr"> <PreferenceScreen android:title="@string/map_preferences" android:summary="@string/map_preferences_descr">
<CheckBoxPreference android:key="use_internet_to_download_tiles" android:title="@string/use_internet" android:summary="@string/use_internet_to_download_tile"></CheckBoxPreference> <CheckBoxPreference android:key="use_internet_to_download_tiles" android:title="@string/use_internet" android:summary="@string/use_internet_to_download_tile"></CheckBoxPreference>
<ListPreference android:title="@string/map_tile_source" android:summary="@string/map_tile_source_descr" android:key="map_tile_sources"></ListPreference> <ListPreference android:title="@string/map_tile_source" android:summary="@string/map_tile_source_descr" android:key="map_tile_sources"></ListPreference>

View file

@ -167,6 +167,8 @@ public class AmenityIndexRepository {
db = SQLiteDatabase.openOrCreateDatabase(file, null); db = SQLiteDatabase.openOrCreateDatabase(file, null);
name = file.getName().substring(0, file.getName().indexOf('.')); name = file.getName().substring(0, file.getName().indexOf('.'));
if(db.getVersion() != IndexConstants.POI_TABLE_VERSION){ if(db.getVersion() != IndexConstants.POI_TABLE_VERSION){
db.close();
db = null;
return false; return false;
} }

View file

@ -47,6 +47,14 @@ public class OsmandSettings {
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE); SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
return prefs.getBoolean(USE_INTERNET_TO_DOWNLOAD_TILES, true); return prefs.getBoolean(USE_INTERNET_TO_DOWNLOAD_TILES, true);
} }
// this value string is synchronized with settings_pref.xml preference name
public static final String USE_INTERNET_TO_CALCULATE_ROUTE = "use_internet_to_calculate_route";
public static boolean isUsingInternetToCalculateRoute(Context ctx) {
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
return prefs.getBoolean(USE_INTERNET_TO_CALCULATE_ROUTE, false);
}
// this value string is synchronized with settings_pref.xml preference name // this value string is synchronized with settings_pref.xml preference name
public static final String SHOW_POI_OVER_MAP = "show_poi_over_map"; public static final String SHOW_POI_OVER_MAP = "show_poi_over_map";

View file

@ -51,6 +51,8 @@ public class RegionAddressRepository {
db = SQLiteDatabase.openOrCreateDatabase(file, null); db = SQLiteDatabase.openOrCreateDatabase(file, null);
name = file.getName().substring(0, file.getName().indexOf('.')); name = file.getName().substring(0, file.getName().indexOf('.'));
if(db.getVersion() != IndexConstants.ADDRESS_TABLE_VERSION){ if(db.getVersion() != IndexConstants.ADDRESS_TABLE_VERSION){
db.close();
db = null;
return false; return false;
} }

View file

@ -53,7 +53,6 @@ public class MainMenuActivity extends Activity {
public void startApplication(){ public void startApplication(){
if(!applicationAlreadyStarted){ if(!applicationAlreadyStarted){
// TODO exception!!! has leaked window ?
final ProgressDialog dlg = ProgressDialog.show(this, "Loading data", "Reading indices...", true); final ProgressDialog dlg = ProgressDialog.show(this, "Loading data", "Reading indices...", true);
final ProgressDialogImplementation impl = new ProgressDialogImplementation(dlg); final ProgressDialogImplementation impl = new ProgressDialogImplementation(dlg);
impl.setRunnable("Initializing app", new Runnable(){ impl.setRunnable("Initializing app", new Runnable(){
@ -63,6 +62,12 @@ public class MainMenuActivity extends Activity {
List<String> warnings = new ArrayList<String>(); List<String> warnings = new ArrayList<String>();
warnings.addAll(ResourceManager.getResourceManager().indexingPoi(impl)); warnings.addAll(ResourceManager.getResourceManager().indexingPoi(impl));
warnings.addAll(ResourceManager.getResourceManager().indexingAddresses(impl)); warnings.addAll(ResourceManager.getResourceManager().indexingAddresses(impl));
SavingTrackHelper helper = new SavingTrackHelper(MainMenuActivity.this);
if (helper.hasDataToSave()) {
impl.startTask("Saving gpx tracks to SD...", -1);
helper.saveDataToGpx();
}
helper.close();
showWarnings(warnings); showWarnings(warnings);
} finally { } finally {
dlg.dismiss(); dlg.dismiss();
@ -90,9 +95,6 @@ public class MainMenuActivity extends Activity {
getPreferences(MODE_WORLD_READABLE).edit().putLong(EXCEPTION_FILE_SIZE, 0).commit(); getPreferences(MODE_WORLD_READABLE).edit().putLong(EXCEPTION_FILE_SIZE, 0).commit();
} }
} }
SavingTrackHelper helper = new SavingTrackHelper(this);
helper.saveDataToGpx();
helper.close();
} }
} }

View file

@ -49,6 +49,7 @@ import com.osmand.views.OsmandMapTileView;
import com.osmand.views.POIMapLayer; import com.osmand.views.POIMapLayer;
import com.osmand.views.PointLocationLayer; import com.osmand.views.PointLocationLayer;
import com.osmand.views.PointNavigationLayer; import com.osmand.views.PointNavigationLayer;
import com.osmand.views.RouteLayer;
public class MapActivity extends Activity implements LocationListener, IMapLocationListener, SensorEventListener { public class MapActivity extends Activity implements LocationListener, IMapLocationListener, SensorEventListener {
@ -65,6 +66,8 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
private MapInfoLayer mapInfoLayer; private MapInfoLayer mapInfoLayer;
private OsmBugsLayer osmBugsLayer; private OsmBugsLayer osmBugsLayer;
private SavingTrackHelper savingTrackHelper; private SavingTrackHelper savingTrackHelper;
private RoutingHelper routingHelper;
private RouteLayer routeLayer;
private WakeLock wakeLock; private WakeLock wakeLock;
private boolean sensorRegistered = false; private boolean sensorRegistered = false;
@ -73,6 +76,8 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
private boolean isMapLinkedToLocation(){ private boolean isMapLinkedToLocation(){
return OsmandSettings.isMapSyncToGpsLocation(this); return OsmandSettings.isMapSyncToGpsLocation(this);
} }
@ -99,11 +104,18 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
mapView.addLayer(mapInfoLayer); mapView.addLayer(mapInfoLayer);
osmBugsLayer = new OsmBugsLayer(this); osmBugsLayer = new OsmBugsLayer(this);
savingTrackHelper = new SavingTrackHelper(this); savingTrackHelper = new SavingTrackHelper(this);
routingHelper = new RoutingHelper(this);
routeLayer = new RouteLayer(routingHelper);
mapView.addLayer(routeLayer);
locationLayer.setAppMode(OsmandSettings.getApplicationMode(this)); locationLayer.setAppMode(OsmandSettings.getApplicationMode(this));
LatLon pointToNavigate = OsmandSettings.getPointToNavigate(this); LatLon pointToNavigate = OsmandSettings.getPointToNavigate(this);
if(OsmandSettings.isUsingInternetToCalculateRoute(this)){
routingHelper.setAppMode(OsmandSettings.getApplicationMode(this));
routingHelper.setFinalLocation(pointToNavigate);
}
navigationLayer.setPointToNavigate(pointToNavigate); navigationLayer.setPointToNavigate(pointToNavigate);
SharedPreferences prefs = getSharedPreferences(OsmandSettings.SHARED_PREFERENCES_NAME, MODE_WORLD_READABLE); SharedPreferences prefs = getSharedPreferences(OsmandSettings.SHARED_PREFERENCES_NAME, MODE_WORLD_READABLE);
@ -220,6 +232,8 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
MapTileDownloader.getInstance().removeDownloaderCallback(mapView); MapTileDownloader.getInstance().removeDownloaderCallback(mapView);
} }
public void setLocation(Location location){ public void setLocation(Location location){
// show point view only if gps enabled // show point view only if gps enabled
@ -242,11 +256,13 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
} }
} }
Log.d(LogUtil.TAG, "Location changed"); Log.d(LogUtil.TAG, "Location changed");
// TODO delete // TODO delete !!! (only for test purposes)
if(locationLayer.getLastKnownLocation() != null){ if(!location.hasSpeed() && locationLayer.getLastKnownLocation() != null){
location.setSpeed(location.distanceTo(locationLayer.getLastKnownLocation())); location.setSpeed(location.distanceTo(locationLayer.getLastKnownLocation()));
} }
locationLayer.setLastKnownLocation(location); locationLayer.setLastKnownLocation(location);
routingHelper.setCurrentLocation(location);
if (location != null) { if (location != null) {
if (isMapLinkedToLocation()) { if (isMapLinkedToLocation()) {
if(OsmandSettings.isAutoZoomEnabled(this) && location.hasSpeed()){ if(OsmandSettings.isAutoZoomEnabled(this) && location.hasSpeed()){
@ -291,6 +307,11 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
} else { } else {
OsmandSettings.clearPointToNavigate(this); OsmandSettings.clearPointToNavigate(this);
} }
routingHelper.setFinalLocation(point);
// TODO do it more clear
if(routingHelper.getLastFixedLocation() != null){
routingHelper.setCurrentLocation(routingHelper.getLastFixedLocation());
}
navigationLayer.setPointToNavigate(point); navigationLayer.setPointToNavigate(point);
updateNavigateToPointMenu(); updateNavigateToPointMenu();
} }
@ -306,6 +327,10 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
public LatLon getPointToNavigate(){ public LatLon getPointToNavigate(){
return navigationLayer.getPointToNavigate(); return navigationLayer.getPointToNavigate();
} }
public RoutingHelper getRoutingHelper() {
return routingHelper;
}
@Override @Override
@ -434,6 +459,10 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
locationChanged(lat, lon, this); locationChanged(lat, lon, this);
} }
public OsmandMapTileView getMapView() {
return mapView;
}
@Override @Override
public void onSensorChanged(SensorEvent event) { public void onSensorChanged(SensorEvent event) {
// Attention : sensor produces a lot of events & can hang the system // Attention : sensor produces a lot of events & can hang the system
@ -514,7 +543,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
} else if(which == 3){ } else if(which == 3){
osmBugsLayer.openBug(MapActivity.this, getLayoutInflater(), mapView, latitude, longitude); osmBugsLayer.openBug(MapActivity.this, getLayoutInflater(), mapView, latitude, longitude);
} else if(which == 4){ } else if(which == 4){
EditingPOIActivity activity = new EditingPOIActivity(MapActivity.this, mapView); EditingPOIActivity activity = new EditingPOIActivity(MapActivity.this);
activity.showCreateDialog(latitude, longitude); activity.showCreateDialog(latitude, longitude);
} }
} }

View file

@ -0,0 +1,440 @@
package com.osmand.activities;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import android.location.Location;
import android.util.FloatMath;
import android.widget.Toast;
import com.osmand.LogUtil;
import com.osmand.OsmandSettings.ApplicationMode;
import com.osmand.osm.LatLon;
import com.osmand.osm.MapUtils;
public class RoutingHelper {
private static final org.apache.commons.logging.Log log = LogUtil.getLog(RoutingHelper.class);
private final MapActivity activity;
private List<Location> routeNodes = new ArrayList<Location>();
private int[] listDistance = null;
private int currentRoute = 0;
private LatLon finalLocation;
private Location lastFixedLocation;
private Thread currentRunningJob;
private long lastTimeEvaluatedRoute = 0;
private int evalWaitInterval = 3000;
private ApplicationMode mode;
// TEST CODE
// private static List<Location> testRoute = new ArrayList<Location>();
// private static void addTestLocation(double lat, double lon){
// Location l = new Location("p");
// l.setLatitude(lat);
// l.setLongitude(lon);
// testRoute.add(l);
// }
// static {
// addTestLocation(53.83330108605482, 27.590844306640605);
// addTestLocation(53.83319978227928, 27.580802116088847);
// addTestLocation(53.83319978227928, 27.57196155517576);
// addTestLocation(53.833149130299624, 27.563893470458964);
// addTestLocation(53.8330984782587, 27.55651203124998);
// addTestLocation(53.83340238958535, 27.551448020629863);
// addTestLocation(53.834263459701916, 27.543208274536113);
// addTestLocation(53.835428408740796, 27.53325191467283);
// addTestLocation(53.83598554682643, 27.531964454345683);
// addTestLocation(53.83654267750025, 27.532221946411113);
// addTestLocation(53.836441381565386, 27.533166083984355);
// addTestLocation(53.8341621582541, 27.53325191467283);
// addTestLocation(53.83016055507444, 27.533595237426738);
// addTestLocation(53.82696912916281, 27.533938560180644);
// addTestLocation(53.8255506396008, 27.53376689880369);
// addTestLocation(53.82119354992355, 27.531706962280253);
// addTestLocation(53.817646747077355, 27.53050533264158);
// addTestLocation(53.81156581517512, 27.529389533691386);
// addTestLocation(53.81404896894648, 27.5300761791992);
// addTestLocation(53.80994408432531, 27.529217872314433);
// addTestLocation(53.8062949605079, 27.529217872314433);
// addTestLocation(53.80203724791403, 27.529132041625957);
// addTestLocation(53.794838702875424, 27.52878871887205);
// addTestLocation(53.79052912343052, 27.52758708923338);
// addTestLocation(53.77922071028288, 27.524497184448222);
// addTestLocation(53.76714827905046, 27.520978126220683);
// addTestLocation(53.756138036056214, 27.515914115600566);
// addTestLocation(53.75121547304873, 27.51385417907713);
// addTestLocation(53.74745972778275, 27.513425025634746);
// addTestLocation(53.74284071585075, 27.51402584045408);
// addTestLocation(53.738373496098994, 27.514884147338847);
// addTestLocation(53.735175081196715, 27.516257438354472);
// addTestLocation(53.711966594109235, 27.519604835205058);
// addTestLocation(53.70769930787764, 27.520463142089824);
// addTestLocation(53.69992563864831, 27.52381053894041);
// addTestLocation(53.69728328030487, 27.521235618286113);
// }
// END TEST CODE
public RoutingHelper(MapActivity activity){
this.activity = activity;
}
public void setFinalLocation(LatLon finalLocation){
this.finalLocation = finalLocation;
}
public void setAppMode(ApplicationMode mode){
this.mode = mode;
}
public ApplicationMode getAppMode() {
return mode;
}
public LatLon getFinalLocation() {
return finalLocation;
}
public boolean finishAtLocation(Location currentLocation) {
Location lastPoint = routeNodes.get(routeNodes.size() - 1);
if(currentRoute > routeNodes.size() - 3 && currentLocation.distanceTo(lastPoint) < 50){
if(lastFixedLocation != null && lastFixedLocation.distanceTo(lastPoint) < 50){
// TODO mark as finished
showMessage("You arrived at destination point");
currentRoute = routeNodes.size() - 1;
}
lastFixedLocation = currentLocation;
// ??? even if you go away from place you can't navigate once time
// finalLocation = null
return true;
}
return false;
}
public Location getLastFixedLocation() {
return lastFixedLocation;
}
public void setCurrentLocation(Location currentLocation) {
if(finalLocation == null || currentLocation == null){
return;
}
boolean calculateRoute = false;
synchronized (this) {
if(routeNodes.isEmpty() || routeNodes.size() <= currentRoute){
calculateRoute = true;
} else {
// 1. try to mark passed route (move forward)
float dist = currentLocation.distanceTo(routeNodes.get(currentRoute));
while(currentRoute + 1 < routeNodes.size()){
float newDist = currentLocation.distanceTo(routeNodes.get(currentRoute + 1));
if (newDist < dist) {
// that node already passed
currentRoute++;
dist = newDist;
} else {
break;
}
}
// 2. check if destination found
if(finishAtLocation(currentLocation)){
return;
}
// 3. check if closest location already passed
if(currentRoute + 1 < routeNodes.size()){
float bearing = routeNodes.get(currentRoute).bearingTo(routeNodes.get(currentRoute + 1));
float bearingMovement = currentLocation.bearingTo(routeNodes.get(currentRoute));
if(Math.abs(bearing - bearingMovement) > 130 && Math.abs(bearing - bearingMovement) < 230){
currentRoute++;
}
}
// 4. evaluate distance to the route and reevaluate if needed
if(currentRoute > 0){
float bearing = routeNodes.get(currentRoute - 1).bearingTo(routeNodes.get(currentRoute));
float bearingMovement = currentLocation.bearingTo(routeNodes.get(currentRoute));
float d = Math.abs(currentLocation.distanceTo(routeNodes.get(currentRoute)) * FloatMath.sin((bearingMovement - bearing)*3.14f/180f));
if(d > 50) {
log.info("Recalculate route, because correlation : " + d);
calculateRoute = true;
}
}
// 5. also check bearing by summing distance
if(!calculateRoute){
float d = currentLocation.distanceTo(routeNodes.get(currentRoute));
if (d > 80) {
if (currentRoute > 0) {
// possibly that case is not needed (often it is covered by 4.)
float f1 = currentLocation.distanceTo(routeNodes.get(currentRoute - 1)) + d;
float c = routeNodes.get(currentRoute - 1).distanceTo(routeNodes.get(currentRoute));
if (c * 2 < d + f1) {
log.info("Recalculate route, because too far from points : " + d + " " + f1 + " >> " + c);
calculateRoute = true;
}
} else {
// that case is needed
log.info("Recalculate route, because too far from start : " + d);
calculateRoute = true;
}
}
}
// 5. Also bearing could be checked (is it same direction)
// float bearing;
// if(currentLocation.hasBearing()){
// bearing = currentLocation.getBearing();
// } else if(lastFixedLocation != null){
// bearing = lastFixedLocation.bearingTo(currentLocation);
// }
// bearingRoute = currentLocation.bearingTo(routeNodes.get(currentRoute));
// if (Math.abs(bearing - bearingRoute) > 60f && 360 - Math.abs(bearing - bearingRoute) > 60f) {
// something wrong however it could be starting movement
// }
}
}
lastFixedLocation = currentLocation;
if(calculateRoute){
calculateRoute(lastFixedLocation, finalLocation);
}
}
private void setNewRoute(List<Location> locations){
routeNodes = locations;
listDistance = new int[locations.size()];
if (!locations.isEmpty()) {
listDistance[locations.size() - 1] = 0;
for (int i = locations.size() - 1; i > 0; i--) {
listDistance[i - 1] = (int) locations.get(i - 1).distanceTo(locations.get(i));
listDistance[i - 1] += listDistance[i];
}
}
currentRoute = 0;
}
public int getDistance(){
if(listDistance != null && currentRoute < listDistance.length){
return listDistance[currentRoute];
}
return 0;
}
public void calculateRoute(final Location start, final LatLon end){
if(currentRunningJob == null){
// do not evaluate very often
if (System.currentTimeMillis() - lastTimeEvaluatedRoute > evalWaitInterval) {
synchronized (this) {
currentRunningJob = new Thread(new Runnable() {
@Override
public void run() {
RouteCalculationResult res = calculateRouteImpl(start, end);
synchronized (RoutingHelper.this) {
if (res.isCalculated()) {
setNewRoute(res.list);
// reset error wait interval
evalWaitInterval = 3000;
} else {
evalWaitInterval = evalWaitInterval * 3 / 2;
if(evalWaitInterval > 120000){
evalWaitInterval = 120000;
}
}
currentRunningJob = null;
}
if(res.isCalculated()){
showMessage("New route is calculated distance : " + MapUtils.getFormattedDistance(sumDistance(res.list)));
// be aware that is non ui thread
activity.getMapView().refreshMap();
} else {
if(res.errorMessage != null){
showMessage("Error calculating route : " + res.errorMessage);
} else if(res.list == null){
showMessage("Error occurred while calculating route");
} else {
showMessage("Empty route is calculated");
}
}
lastTimeEvaluatedRoute = System.currentTimeMillis();
}
}, "Calculating route");
currentRunningJob.start();
}
}
}
}
private int sumDistance(List<Location> locations) {
int d = 0;
if (locations.size() > 1) {
for (int i = 1; i < locations.size(); i++) {
d += locations.get(i - 1).distanceTo(locations.get(i));
}
}
return d;
}
private void showMessage(final String msg){
activity.runOnUiThread(new Runnable(){
@Override
public void run() {
Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show();
}
});
}
public boolean hasPointsToShow(){
return finalLocation != null && !routeNodes.isEmpty();
}
public synchronized void fillLocationsToShow(double topLatitude, double leftLongitude, double bottomLatitude,double rightLongitude, List<Location> l){
l.clear();
boolean previousVisible = false;
if(lastFixedLocation != null){
if(leftLongitude <= lastFixedLocation.getLongitude() && lastFixedLocation.getLongitude() <= rightLongitude &&
bottomLatitude <= lastFixedLocation.getLatitude() && lastFixedLocation.getLatitude() <= topLatitude){
l.add(lastFixedLocation);
previousVisible = true;
}
}
for(int i=currentRoute; i<routeNodes.size(); i++){
Location ls = routeNodes.get(i);
if(leftLongitude <= ls.getLongitude() && ls.getLongitude() <= rightLongitude &&
bottomLatitude <= ls.getLatitude() && ls.getLatitude() <= topLatitude){
l.add(ls);
if (i > currentRoute) {
l.add(0, ls);
previousVisible = true;
} else if(lastFixedLocation != null){
l.add(0, ls);
}
previousVisible = true;
} else if(previousVisible){
l.add(ls);
previousVisible = false;
// do not continue make method more efficient (because it calls in UI thread)
// this break also has logical sense !
break;
}
}
}
private static class RouteCalculationResult {
public List<Location> list;
public String errorMessage;
public RouteCalculationResult( List<Location> list, String errorMessage) {
this.errorMessage = errorMessage;
this.list = list;
}
public boolean isCalculated(){
return list != null && !list.isEmpty();
}
}
private RouteCalculationResult calculateRouteImpl(Location start, LatLon end){
long time = System.currentTimeMillis();
if (start != null && end != null) {
List<Location> res = new ArrayList<Location>();
if(log.isInfoEnabled()){
log.info("Start finding route from " + start + " to " + end);
}
try {
StringBuilder uri = new StringBuilder();
uri.append("http://www.yournavigation.org/api/1.0/gosmore.php?format=kml");
uri.append("&flat=").append(start.getLatitude());
uri.append("&flon=").append(start.getLongitude());
uri.append("&tlat=").append(end.getLatitude());
uri.append("&tlon=").append(end.getLongitude());
if(ApplicationMode.PEDESTRIAN== mode){
uri.append("&v=foot") ;
} else if(ApplicationMode.BICYCLE == mode){
uri.append("&v=bicycle") ;
} else {
uri.append("&v=motorcar");
}
uri.append("&fast=1").append("&layer=mapnik");
URL url = new URL(uri.toString());
URLConnection connection = url.openConnection();
DocumentBuilder dom = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = dom.parse(new InputSource(new InputStreamReader(connection.getInputStream())));
NodeList list = doc.getElementsByTagName("coordinates");
for(int i=0; i<list.getLength(); i++){
Node item = list.item(i);
String str = item.getFirstChild().getNodeValue();
if(str == null){
continue;
}
int st = 0;
int next = 0;
while((next = str.indexOf('\n', st)) != -1){
String coordinate = str.substring(st, next + 1);
int s = coordinate.indexOf(',');
if (s != -1) {
try {
double lon = Double.parseDouble(coordinate.substring(0, s));
double lat = Double.parseDouble(coordinate.substring(s + 1));
Location l = new Location("router");
l.setLatitude(lat);
l.setLongitude(lon);
res.add(l);
} catch (NumberFormatException e) {
}
}
st = next + 1;
}
}
if(list.getLength() == 0){
if(doc.getChildNodes().getLength() == 1){
Node item = doc.getChildNodes().item(0);
return new RouteCalculationResult(null, item.getNodeValue());
}
}
if(log.isInfoEnabled()){
log.info("Finding route contained " + res.size() + " points for " + (System.currentTimeMillis() - time) + " ms");
}
return new RouteCalculationResult(res, null);
} catch (IOException e) {
log.error("Failed to find route ", e);
} catch (ParserConfigurationException e) {
log.error("Failed to find route ", e);
} catch (SAXException e) {
log.error("Failed to find route ", e);
}
}
return new RouteCalculationResult(null, null);
}
}

View file

@ -5,7 +5,6 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
@ -77,7 +76,12 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
try { try {
for (String f : data.keySet()) { for (String f : data.keySet()) {
FileOutputStream output = new FileOutputStream(new File(dir, f + ".gpx")); File fout = new File(dir, f + ".gpx");
int ind = 1;
while(fout.exists()){
fout = new File(dir, f + "_"+(++ind)+".gpx");
}
FileOutputStream output = new FileOutputStream(fout);
XmlSerializer serializer = Xml.newSerializer(); XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(output, "UTF-8"); serializer.setOutput(output, "UTF-8");
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@ -129,6 +133,18 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
} }
} }
public boolean hasDataToSave(){
SQLiteDatabase db = getReadableDatabase();
if(db != null){
Cursor q = db.query(false, TRACK_NAME, new String[0], null, null, null, null, null, null);
boolean m = q.moveToFirst();
q.close();
return m;
}
return false;
}
public void saveDataToGpx(){ public void saveDataToGpx(){
SQLiteDatabase db = getReadableDatabase(); SQLiteDatabase db = getReadableDatabase();
File file = Environment.getExternalStorageDirectory(); File file = Environment.getExternalStorageDirectory();
@ -188,13 +204,14 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
db = getWritableDatabase(); db = getWritableDatabase();
if(db != null){ if(db != null){
Calendar cal = Calendar.getInstance(); // Calendar cal = Calendar.getInstance();
cal.setTime(new java.util.Date()); // cal.setTime(new java.util.Date());
cal.set(Calendar.HOUR_OF_DAY, 0); // cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0); // cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0); // cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0); // cal.set(Calendar.MILLISECOND, 0);
db.execSQL("DELETE FROM " + TRACK_NAME+ " WHERE " + TRACK_COL_DATE + " <= ?", new Object[]{cal.getTimeInMillis()}); // remove all from db
db.execSQL("DELETE FROM " + TRACK_NAME+ " WHERE " + TRACK_COL_DATE + " <= ?", new Object[]{System.currentTimeMillis()});
} }
} }

View file

@ -38,6 +38,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
private ListPreference applicationMode; private ListPreference applicationMode;
private CheckBoxPreference autoZoom; private CheckBoxPreference autoZoom;
private EditTextPreference userPassword; private EditTextPreference userPassword;
private CheckBoxPreference useInternetToCalculateRoute;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -48,6 +49,8 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
applicationMode =(ListPreference) screen.findPreference(OsmandSettings.APPLICATION_MODE); applicationMode =(ListPreference) screen.findPreference(OsmandSettings.APPLICATION_MODE);
applicationMode.setOnPreferenceChangeListener(this); applicationMode.setOnPreferenceChangeListener(this);
useInternetToCalculateRoute = (CheckBoxPreference) screen.findPreference(OsmandSettings.USE_INTERNET_TO_CALCULATE_ROUTE);
useInternetToCalculateRoute.setOnPreferenceChangeListener(this);
useInternetToDownloadTiles = (CheckBoxPreference) screen.findPreference(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES); useInternetToDownloadTiles = (CheckBoxPreference) screen.findPreference(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES);
useInternetToDownloadTiles.setOnPreferenceChangeListener(this); useInternetToDownloadTiles.setOnPreferenceChangeListener(this);
showPoiOnMap =(CheckBoxPreference) screen.findPreference(OsmandSettings.SHOW_POI_OVER_MAP); showPoiOnMap =(CheckBoxPreference) screen.findPreference(OsmandSettings.SHOW_POI_OVER_MAP);
@ -89,6 +92,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
} }
public void updateAllSettings(){ public void updateAllSettings(){
useInternetToCalculateRoute.setChecked(OsmandSettings.isUsingInternetToCalculateRoute(this));
useInternetToDownloadTiles.setChecked(OsmandSettings.isUsingInternetToDownloadTiles(this)); useInternetToDownloadTiles.setChecked(OsmandSettings.isUsingInternetToDownloadTiles(this));
showPoiOnMap.setChecked(OsmandSettings.isShowingPoiOverMap(this)); showPoiOnMap.setChecked(OsmandSettings.isShowingPoiOverMap(this));
rotateMapToBearing.setChecked(OsmandSettings.isRotateMapToBearing(this)); rotateMapToBearing.setChecked(OsmandSettings.isRotateMapToBearing(this));
@ -155,6 +159,9 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
} else if(preference == showPoiOnMap){ } else if(preference == showPoiOnMap){
edit.putBoolean(OsmandSettings.SHOW_POI_OVER_MAP, (Boolean) newValue); edit.putBoolean(OsmandSettings.SHOW_POI_OVER_MAP, (Boolean) newValue);
edit.commit(); edit.commit();
} else if(preference == useInternetToCalculateRoute){
edit.putBoolean(OsmandSettings.USE_INTERNET_TO_CALCULATE_ROUTE, (Boolean) newValue);
edit.commit();
} else if(preference == useInternetToDownloadTiles){ } else if(preference == useInternetToDownloadTiles){
edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, (Boolean) newValue); edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, (Boolean) newValue);
edit.commit(); edit.commit();
@ -206,6 +213,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
public void setAppMode(ApplicationMode preset, Editor edit){ public void setAppMode(ApplicationMode preset, Editor edit){
if(preset == ApplicationMode.CAR){ if(preset == ApplicationMode.CAR){
edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, true); edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, true);
edit.putBoolean(OsmandSettings.USE_INTERNET_TO_CALCULATE_ROUTE, true);
// edit.putBoolean(OsmandSettings.SHOW_POI_OVER_MAP, _); // edit.putBoolean(OsmandSettings.SHOW_POI_OVER_MAP, _);
edit.putBoolean(OsmandSettings.ROTATE_MAP_TO_BEARING, true); edit.putBoolean(OsmandSettings.ROTATE_MAP_TO_BEARING, true);
edit.putBoolean(OsmandSettings.SHOW_VIEW_ANGLE, false); edit.putBoolean(OsmandSettings.SHOW_VIEW_ANGLE, false);
@ -219,6 +227,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
} else if(preset == ApplicationMode.BICYCLE){ } else if(preset == ApplicationMode.BICYCLE){
// edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, _); // edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, _);
// edit.putBoolean(OsmandSettings.USE_INTERNET_TO_CALCULATE_ROUTE, _);
edit.putBoolean(OsmandSettings.SHOW_POI_OVER_MAP, true); edit.putBoolean(OsmandSettings.SHOW_POI_OVER_MAP, true);
edit.putBoolean(OsmandSettings.ROTATE_MAP_TO_BEARING, true); edit.putBoolean(OsmandSettings.ROTATE_MAP_TO_BEARING, true);
edit.putBoolean(OsmandSettings.SHOW_VIEW_ANGLE, false); edit.putBoolean(OsmandSettings.SHOW_VIEW_ANGLE, false);
@ -232,6 +241,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
} else if(preset == ApplicationMode.PEDESTRIAN){ } else if(preset == ApplicationMode.PEDESTRIAN){
// edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, _); // edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, _);
edit.putBoolean(OsmandSettings.USE_INTERNET_TO_CALCULATE_ROUTE, false);
edit.putBoolean(OsmandSettings.SHOW_POI_OVER_MAP, true); edit.putBoolean(OsmandSettings.SHOW_POI_OVER_MAP, true);
edit.putBoolean(OsmandSettings.ROTATE_MAP_TO_BEARING, false); edit.putBoolean(OsmandSettings.ROTATE_MAP_TO_BEARING, false);
edit.putBoolean(OsmandSettings.SHOW_VIEW_ANGLE, true); edit.putBoolean(OsmandSettings.SHOW_VIEW_ANGLE, true);
@ -247,6 +257,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
} else if(preset == ApplicationMode.DEFAULT){ } else if(preset == ApplicationMode.DEFAULT){
// edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, _); // edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, _);
edit.putBoolean(OsmandSettings.USE_INTERNET_TO_CALCULATE_ROUTE, false);
edit.putBoolean(OsmandSettings.SHOW_POI_OVER_MAP, true); edit.putBoolean(OsmandSettings.SHOW_POI_OVER_MAP, true);
edit.putBoolean(OsmandSettings.ROTATE_MAP_TO_BEARING, false); edit.putBoolean(OsmandSettings.ROTATE_MAP_TO_BEARING, false);
edit.putBoolean(OsmandSettings.SHOW_VIEW_ANGLE, false); edit.putBoolean(OsmandSettings.SHOW_VIEW_ANGLE, false);

View file

@ -87,7 +87,7 @@ public class MapInfoLayer implements OsmandMapLayer {
} }
public boolean distChanged(int oldDist, int dist){ public boolean distChanged(int oldDist, int dist){
if(oldDist != 0 && Math.abs(((float) dist - oldDist)/oldDist) < 0.01){ if(oldDist != 0 && ((oldDist - dist > 100) || (Math.abs(((float) dist - oldDist)/oldDist) < 0.01))){
return false; return false;
} }
return true; return true;
@ -96,10 +96,17 @@ public class MapInfoLayer implements OsmandMapLayer {
@Override @Override
public void onDraw(Canvas canvas) { public void onDraw(Canvas canvas) {
if(map.getPointToNavigate() != null){ if(map.getPointToNavigate() != null){
Location.distanceBetween(view.getLatitude(), view.getLongitude(), map.getPointToNavigate().getLatitude(), int d = 0;
map.getPointToNavigate().getLongitude(), calculations); if(map.getRoutingHelper().getFinalLocation() != null){
if(distChanged(cachedMeters, (int)calculations[0])){ d = map.getRoutingHelper().getDistance();
cachedMeters = (int)calculations[0]; }
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){ if(cachedMeters <= 20){
cachedMeters = 0; cachedMeters = 0;
cachedDistString = null; cachedDistString = null;
@ -128,7 +135,7 @@ public class MapInfoLayer implements OsmandMapLayer {
// draw speed // draw speed
if(map.getLastKnownLocation() != null && map.getLastKnownLocation().hasSpeed()){ if(map.getLastKnownLocation() != null && map.getLastKnownLocation().hasSpeed()){
if(Math.abs(map.getLastKnownLocation().getSpeed() - cachedSpeed) > .3f){ if(Math.abs(map.getLastKnownLocation().getSpeed() - cachedSpeed) > .3f){
cachedSpeed = (int) map.getLastKnownLocation().getSpeed(); cachedSpeed = map.getLastKnownLocation().getSpeed();
cachedSpeedString = ((int) (cachedSpeed * 3.6f)) + " km/h"; cachedSpeedString = ((int) (cachedSpeed * 3.6f)) + " km/h";
float right = paintBlack.measureText(cachedSpeedString) + 8 + boundsForSpeed.left; float right = paintBlack.measureText(cachedSpeedString) + 8 + boundsForSpeed.left;
boundsForSpeed.right = boundsForDist.right = Math.max(right, boundsForDist.right); boundsForSpeed.right = boundsForDist.right = Math.max(right, boundsForDist.right);

View file

@ -153,8 +153,8 @@ public class PointLocationLayer implements OsmandMapLayer {
} }
public void setLastKnownLocation(Location lastKnownLocation) { public void setLastKnownLocation(Location lastKnownLocation) {
this.lastKnownLocation = lastKnownLocation;
boolean redraw = isLocationVisible(this.lastKnownLocation) || isLocationVisible(lastKnownLocation); boolean redraw = isLocationVisible(this.lastKnownLocation) || isLocationVisible(lastKnownLocation);
this.lastKnownLocation = lastKnownLocation;
if (redraw) { if (redraw) {
view.refreshMap(); view.refreshMap();
} }

View file

@ -0,0 +1,110 @@
package com.osmand.views;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.location.Location;
import android.util.Log;
import com.osmand.LogUtil;
import com.osmand.activities.RoutingHelper;
import com.osmand.osm.MapUtils;
public class RouteLayer implements OsmandMapLayer {
private OsmandMapTileView view;
private final RoutingHelper helper;
private Rect boundsRect;
private RectF tileRect;
private List<Location> points = new ArrayList<Location>();
private Paint paint;
private Path path;
public RouteLayer(RoutingHelper helper){
this.helper = helper;
}
private void initUI() {
boundsRect = new Rect(0, 0, view.getWidth(), view.getHeight());
tileRect = new RectF();
paint = new Paint();
paint.setColor(Color.GRAY);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(14);
paint.setAlpha(150);
paint.setAntiAlias(true);
path = new Path();
}
public void initLayer(OsmandMapTileView view) {
this.view = view;
initUI();
}
@Override
public void onDraw(Canvas canvas) {
if (helper.hasPointsToShow()) {
long time = System.currentTimeMillis();
boundsRect = new Rect(0, 0, view.getWidth(), view.getHeight());
view.calculateTileRectangle(boundsRect, view.getCenterPointX(), view.getCenterPointY(), view.getXTile(), view.getYTile(),
tileRect);
double topLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.top);
double leftLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.left);
double bottomLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.bottom);
double rightLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.right);
helper.fillLocationsToShow(topLatitude, leftLongitude, bottomLatitude, rightLongitude, points);
if((System.currentTimeMillis() - time) > 40){
Log.e(LogUtil.TAG, "Calculate route layer " + (System.currentTimeMillis() - time));
}
if (points.size() > 0) {
int px = view.getMapXForPoint(points.get(0).getLongitude());
int py = view.getMapYForPoint(points.get(0).getLatitude());
path.reset();
path.moveTo(px, py);
for (Location o : points) {
int x = view.getMapXForPoint(o.getLongitude());
int y = view.getMapYForPoint(o.getLatitude());
path.lineTo(x, y);
}
canvas.drawPath(path, paint);
}
}
}
@Override
public void destroyLayer() {
}
@Override
public boolean drawInScreenPixels() {
return false;
}
@Override
public boolean onLongPressEvent(PointF point) {
return false;
}
@Override
public boolean onTouchEvent(PointF point) {
return false;
}
}