fix transport bugs

git-svn-id: https://osmand.googlecode.com/svn/trunk@279 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-07-02 17:51:40 +00:00
parent 45864fc97e
commit d5214f02c6
7 changed files with 127 additions and 108 deletions

View file

@ -26,7 +26,7 @@ public class ToDoConstants {
// Fix some missing turns in CloudMade (for secondary roads wo name). Add them (if dist to prev/next turn > 150m) [dacha] // Fix some missing turns in CloudMade (for secondary roads wo name). Add them (if dist to prev/next turn > 150m) [dacha]
// 33. Build transport locations. Create transport index (transport-stops) (investigate) // 33. Build transport locations. Create transport index (transport-stops) (investigate)
// DONE : Load transport routes in swing, init // DONE : Load transport routes in swing, init
// TODO : add progress calculating (fix performance), fix area radius // TODO : add progress calculating, add intermediate points, add menu for stops
// 66. Transport routing (show next stop, total distance, show stop get out). // 66. Transport routing (show next stop, total distance, show stop get out).
@ -42,7 +42,7 @@ public class ToDoConstants {
// 40. Support simple vector road rendering (require new index file) (?) // 40. Support simple vector road rendering (require new index file) (?)
// 63. Support simple offline routing(require new index file) (?) // 63. Support simple offline routing(require new index file) (?)
// BUGS Android // FIXME BUGS Android
// FIXME !!!! Check agains ID is not unique ! (for relation/node/way - it could be the same) - checked for data extraction & index creator // FIXME !!!! Check agains ID is not unique ! (for relation/node/way - it could be the same) - checked for data extraction & index creator
// REFACTOR Settings activity ( for check box properties!) // REFACTOR Settings activity ( for check box properties!)
// Download index show current index information // Download index show current index information
@ -57,19 +57,7 @@ public class ToDoConstants {
// BUGS Swing // BUGS Swing
// DONE ANDROID : // DONE ANDROID :
// 55. Update POI data from internet for selected area (do not suggest to create or extend POI index)
// 62. History of searched points (once point was selected to go/to show it is saved in history db and could be shown)
// 47. Internet connectivity could be checked before trying to use [merged with 45]
// 26. Show the whole street on map (when it is chosen in search activity). Possibly extend that story to show layer with streets.
// [Closed : because it is not necessary]
// 53. Add progress bars : to internet communication activities [editing/commiting/deleting poi], do not hide edit poi dialog if operation failed
// 63. Implement internet search address [OSM Nominatim]
// 56. Add usage of CloudMade API for calculating route (show next turn & distance to it instead of mini map).
// 57. Implement routing information about expected time arriving
// 58. Implement difference about show route/follow route (show travel time/arrival time, show mini map/next turn, etc)
// 59. Show route information (directions/time, ....). Now is shown in context menu route (about route)
// 46. Implement downloading strategy for tiles : select max zoom to download [16,15,14,...]
// That means you can save internet because from [16 -> zoom -> 18], [14 -> zoom -> 16 - suitable for speed > 40], ...
// DONE SWING // DONE SWING

View file

@ -326,6 +326,7 @@ public class DataIndexWriter {
private void writeRouteStops(PreparedStatement prepRouteStops, PreparedStatement prepStops, Map<PreparedStatement, Integer> count, private void writeRouteStops(PreparedStatement prepRouteStops, PreparedStatement prepStops, Map<PreparedStatement, Integer> count,
Set<Long> writtenStops, TransportRoute r, List<TransportStop> stops, boolean direction) throws SQLException { Set<Long> writtenStops, TransportRoute r, List<TransportStop> stops, boolean direction) throws SQLException {
int i = 0;
for(TransportStop s : stops){ for(TransportStop s : stops){
if (!writtenStops.contains(s.getId())) { if (!writtenStops.contains(s.getId())) {
assert IndexTransportStop.values().length == 5; assert IndexTransportStop.values().length == 5;
@ -337,10 +338,11 @@ public class DataIndexWriter {
addBatch(count, prepStops); addBatch(count, prepStops);
writtenStops.add(s.getId()); writtenStops.add(s.getId());
} }
assert IndexTransportRouteStop.values().length == 3; assert IndexTransportRouteStop.values().length == 4;
prepRouteStops.setLong(IndexTransportRouteStop.ROUTE.ordinal() + 1, r.getId()); prepRouteStops.setLong(IndexTransportRouteStop.ROUTE.ordinal() + 1, r.getId());
prepRouteStops.setLong(IndexTransportRouteStop.STOP.ordinal() + 1, s.getId()); prepRouteStops.setLong(IndexTransportRouteStop.STOP.ordinal() + 1, s.getId());
prepRouteStops.setInt(IndexTransportRouteStop.DIRECTION.ordinal() + 1, direction ? 1 : 0); prepRouteStops.setInt(IndexTransportRouteStop.DIRECTION.ordinal() + 1, direction ? 1 : 0);
prepRouteStops.setInt(IndexTransportRouteStop.ORD.ordinal() + 1, i++);
addBatch(count, prepRouteStops); addBatch(count, prepRouteStops);
} }
} }

View file

@ -327,7 +327,7 @@ public class IndexConstants {
public enum IndexTransportRouteStop implements IndexColumn { public enum IndexTransportRouteStop implements IndexColumn {
STOP("long", true), ROUTE("long", true), DIRECTION("short"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ STOP("long", true), ROUTE("long", true), ORD("int"), DIRECTION("short"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
boolean index = false; boolean index = false;
String type = null; String type = null;

View file

@ -213,7 +213,9 @@ public class MapUtils {
} else if(meters >= 10000){ } else if(meters >= 10000){
return MessageFormat.format("{0,number,#.#} "+Messages.getMessage(Messages.KEY_KM), ((float) meters) / 1000); //$NON-NLS-1$ return MessageFormat.format("{0,number,#.#} "+Messages.getMessage(Messages.KEY_KM), ((float) meters) / 1000); //$NON-NLS-1$
} else if(meters > 1500){ } else if(meters > 1500){
return MessageFormat.format("{0,number,#.##} "+Messages.getMessage(Messages.KEY_KM), ((float) meters) / 1000); //$NON-NLS-1$ return MessageFormat.format("{0,number,#.#} "+Messages.getMessage(Messages.KEY_KM), ((float) meters) / 1000); //$NON-NLS-1$
} else if(meters > 900){
return MessageFormat.format("{0,number,#.##} "+Messages.getMessage(Messages.KEY_KM), ((float) meters) / 1000); //$NON-NLS-1$
} else { } else {
return meters + " "+Messages.getMessage(Messages.KEY_M); //$NON-NLS-1$ return meters + " "+Messages.getMessage(Messages.KEY_M); //$NON-NLS-1$
} }

View file

@ -4,6 +4,7 @@
android:orientation="vertical" android:layout_width="fill_parent" android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"> android:layout_height="fill_parent">
<LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">
<ProgressBar android:id="@+id/ProgressBar" android:layout_width="wrap_content" android:layout_height="wrap_content"></ProgressBar>
<Button android:text="@string/search_POI_level_btn" android:id="@+id/SearchPOILevelButton" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_weight="1"></Button> <Button android:text="@string/search_POI_level_btn" android:id="@+id/SearchPOILevelButton" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_weight="1"></Button>
<TextView android:layout_width="wrap_content" android:text="" android:id="@+id/SearchAreaText" android:layout_height="wrap_content"/> <TextView android:layout_width="wrap_content" android:text="" android:id="@+id/SearchAreaText" android:layout_height="wrap_content"/>

View file

@ -210,110 +210,136 @@ public class TransportIndexRepository extends BaseLocationIndexRepository<Transp
System.currentTimeMillis() - now, registeredRoutes.size())); System.currentTimeMillis() - now, registeredRoutes.size()));
} }
ArrayList<RouteInfoLocation> list = new ArrayList<RouteInfoLocation>(registeredRoutes.values()); List<RouteInfoLocation> list = preloadRouteStopsAndCalculateDistance(loc, locationToGo, registeredRoutes);
preloadRouteStopsAndCalculateDistance(loc, locationToGo, list);
return list; return list;
} }
private static String cacheSQLRouteStops = null; protected List<RouteInfoLocation> preloadRouteStopsAndCalculateDistance(final LatLon loc, LatLon locationToGo,
protected void preloadRouteStopsAndCalculateDistance(final LatLon loc, LatLon locationToGo, List<RouteInfoLocation> listRoutes){ Map<Long, RouteInfoLocation> registeredRoutes) {
if(registeredRoutes.isEmpty()){
return Collections.emptyList();
}
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
// TODO do 1 request StringBuilder sql = new StringBuilder(200);
if(cacheSQLRouteStops == null){ sql.append("SELECT "); //$NON-NLS-1$
StringBuilder sql = new StringBuilder(200); String[] cols = IndexConstants.generateColumnNames(IndexTransportStop.values());
sql.append("SELECT "); //$NON-NLS-1$ for (int i = 0; i < cols.length; i++) {
String[] cols = IndexConstants.generateColumnNames(IndexTransportStop.values()); if (i > 0) {
for(int i=0; i<cols.length; i++){ sql.append(", "); //$NON-NLS-1$
if(i>0){ }
sql.append(", "); //$NON-NLS-1$ sql.append(IndexTransportStop.getTable()).append(".").append(cols[i]); //$NON-NLS-1$
}
sql.append(", ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(", ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.DIRECTION); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" FROM ").append(IndexTransportStop.getTable()); //$NON-NLS-1$
// join with stops table
sql.append(" JOIN ").append(IndexTransportRouteStop.getTable()); //$NON-NLS-1$
sql.append(" ON ").append(IndexTransportStop.getTable()).append(".").append(IndexTransportStop.ID); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" = ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.STOP); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" WHERE "); //$NON-NLS-1$
boolean f = true;
for (RouteInfoLocation il : registeredRoutes.values()) {
if (f) {
f = false;
} else {
sql.append(" OR "); //$NON-NLS-1$
}
sql.append("("); //$NON-NLS-1$
sql.append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$
sql.append(" = ").append(il.getRoute().getId()); //$NON-NLS-1$
sql.append(" AND ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.DIRECTION); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" = ").append(il.getDirection() ? 1 : 0); //$NON-NLS-1$
sql.append(")"); //$NON-NLS-1$
}
sql.append(" ORDER BY ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ORD).append(" ASC"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
int qShift = IndexTransportStop.values().length;
Map<Long, Integer> distanceToLoc = new LinkedHashMap<Long, Integer>();
Cursor query = db.rawQuery(sql.toString(), new String[] {});
if (query.moveToFirst()) {
// load only part of the route
do {
TransportStop st = null;
long routeId = query.getLong(qShift);
int direction = query.getInt(qShift + 1);
long id = routeId << 1 + direction;
boolean found = distanceToLoc.containsKey(id);
RouteInfoLocation i = registeredRoutes.get(id);
if (found) {
st = new TransportStop();
st.setId(query.getLong(IndexTransportStop.ID.ordinal()));
st.setLocation(query.getDouble(IndexTransportStop.LATITUDE.ordinal()), query.getDouble(IndexTransportStop.LONGITUDE
.ordinal()));
st.setName(query.getString(IndexTransportStop.NAME.ordinal()));
st.setEnName(query.getString(IndexTransportStop.NAME_EN.ordinal()));
} else if (query.getLong(IndexTransportStop.ID.ordinal()) == i.getStart().getId()) {
st = i.getStart();
found = true;
Integer dist = null;
if (locationToGo != null) {
dist = (int) MapUtils.getDistance(locationToGo, i.getStart().getLocation());
}
distanceToLoc.put(id, dist);
} }
sql.append(IndexTransportStop.getTable()).append(".").append(cols[i]); //$NON-NLS-1$
}
sql.append(" FROM ").append(IndexTransportRouteStop.getTable()); //$NON-NLS-1$
// join with stops table
sql.append(" JOIN ").append(IndexTransportStop.getTable()); //$NON-NLS-1$
sql.append(" ON ").append(IndexTransportStop.getTable()).append(".").append(IndexTransportStop.ID); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" = ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.STOP); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" WHERE ").append("? = "). //$NON-NLS-1$//$NON-NLS-2$ if (found) {
append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$ if (locationToGo != null) {
sql.append(" AND ?=").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.DIRECTION); //$NON-NLS-1$ //$NON-NLS-2$ double d = MapUtils.getDistance(locationToGo, st.getLocation());
cacheSQLRouteStops = sql.toString(); if (d < distanceToLoc.get(id)) {
} distanceToLoc.put(id, (int) d);
for(RouteInfoLocation i : listRoutes){
int dist = 0;
if(locationToGo != null){
dist = (int) MapUtils.getDistance(locationToGo, i.getStart().getLocation());
}
Cursor query = db.rawQuery(cacheSQLRouteStops,
new String[] {i.getRoute().getId()+"", i.getDirection()?"1":"0"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if (query.moveToFirst()) {
// load only part of the route
boolean found = false;
do {
TransportStop st = null;
if(found){
st = new TransportStop();
st.setId(query.getLong(IndexTransportStop.ID.ordinal()));
st.setLocation(query.getDouble(IndexTransportStop.LATITUDE.ordinal()),
query.getDouble(IndexTransportStop.LONGITUDE.ordinal()));
st.setName(query.getString(IndexTransportStop.NAME.ordinal() ));
st.setEnName(query.getString(IndexTransportStop.NAME_EN.ordinal()));
} else if(query.getLong(IndexTransportStop.ID.ordinal())== i.getStart().getId()){
st = i.getStart();
found = true;
}
if(found){
if(locationToGo != null){
double d = MapUtils.getDistance(locationToGo,st.getLocation());
if(d < dist){
dist = (int) d;
}
}
if(i.direction){
i.getRoute().getForwardStops().add(st);
} else {
i.getRoute().getBackwardStops().add(st);
} }
} }
} while (query.moveToNext()); if (i.direction) {
} i.getRoute().getForwardStops().add(st);
} else {
i.getRoute().getBackwardStops().add(st);
}
}
} while (query.moveToNext());
query.close(); query.close();
if(locationToGo != null){
i.setDistToLocation(dist);
}
} }
if (locationToGo != null) {
for (Long l : registeredRoutes.keySet()) {
Integer dist = distanceToLoc.get(l);
if (dist != null) {
registeredRoutes.get(l).setDistToLocation(dist);
}
}
}
ArrayList<RouteInfoLocation> listRoutes = new ArrayList<RouteInfoLocation>(registeredRoutes.values());
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(String.format("Loading routes done in %s ms for %s routes.", //$NON-NLS-1$ log.debug(String.format("Loading routes done in %s ms for %s routes.", //$NON-NLS-1$
System.currentTimeMillis() - now, listRoutes.size())); System.currentTimeMillis() - now, listRoutes.size()));
} }
if(locationToGo != null){ if (locationToGo != null) {
Collections.sort(listRoutes, new Comparator<RouteInfoLocation>(){ Collections.sort(listRoutes, new Comparator<RouteInfoLocation>() {
@Override @Override
public int compare(RouteInfoLocation object1, RouteInfoLocation object2) { public int compare(RouteInfoLocation object1, RouteInfoLocation object2) {
return object1.getDistToLocation() - object2.getDistToLocation(); return object1.getDistToLocation() - object2.getDistToLocation();
} }
}); });
} else { } else {
Collections.sort(listRoutes, new Comparator<RouteInfoLocation>(){ Collections.sort(listRoutes, new Comparator<RouteInfoLocation>() {
@Override @Override
public int compare(RouteInfoLocation object1, RouteInfoLocation object2) { public int compare(RouteInfoLocation object1, RouteInfoLocation object2) {
return Double.compare(MapUtils.getDistance(loc, object1.getStart().getLocation()), return Double.compare(MapUtils.getDistance(loc, object1.getStart().getLocation()), MapUtils.getDistance(loc, object2
MapUtils.getDistance(loc, object2.getStart().getLocation())); .getStart().getLocation()));
} }
}); });
} }
return listRoutes;
} }
public static class RouteInfoLocation { public static class RouteInfoLocation {

View file

@ -75,19 +75,14 @@ public class SearchTransportActivity extends ListActivity {
} }
public String getSearchArea(){ public String getSearchArea(){
// TODO return " < " + 125 * (1 << (17 - zoom)) + " " + Messages.getMessage(Messages.KEY_M); //$NON-NLS-1$//$NON-NLS-2$
if(zoom <= 14){
int d = (int) (1 * (1 << (14 - zoom)));
return " < " + d + " " + Messages.getMessage(Messages.KEY_KM); //$NON-NLS-1$//$NON-NLS-2$
} else {
return " < 500 " + Messages.getMessage(Messages.KEY_M); //$NON-NLS-1$
}
} }
public boolean isSearchFurtherAvailable() { public boolean isSearchFurtherAvailable() {
return zoom >= finalZoom; return zoom >= finalZoom;
} }
public void searchFurther(){ public void searchFurther(){
// TODO use progress
if (lastKnownMapLocation != null) { if (lastKnownMapLocation != null) {
List<TransportIndexRepository> rs = ResourceManager.getResourceManager().searchTransportRepositories(lastKnownMapLocation.getLatitude(), List<TransportIndexRepository> rs = ResourceManager.getResourceManager().searchTransportRepositories(lastKnownMapLocation.getLatitude(),
lastKnownMapLocation.getLongitude()); lastKnownMapLocation.getLongitude());
@ -96,7 +91,7 @@ public class SearchTransportActivity extends ListActivity {
searchTransportLevel.setEnabled(isSearchFurtherAvailable()); searchTransportLevel.setEnabled(isSearchFurtherAvailable());
List<RouteInfoLocation> res = repo.searchTransportRouteStops(lastKnownMapLocation.getLatitude(), lastKnownMapLocation.getLongitude(), List<RouteInfoLocation> res = repo.searchTransportRouteStops(lastKnownMapLocation.getLatitude(), lastKnownMapLocation.getLongitude(),
locationToGo, zoom); locationToGo, zoom);
// TODO add progress
stopsAdapter.setNewModel(res); stopsAdapter.setNewModel(res);
} else { } else {
repo = null; repo = null;
@ -127,10 +122,12 @@ public class SearchTransportActivity extends ListActivity {
for(TransportStop st : stops){ for(TransportStop st : stops){
String n = st.getName(OsmandSettings.usingEnglishNames(this)); String n = st.getName(OsmandSettings.usingEnglishNames(this));
if(locationToGo != null){ if(locationToGo != null){
n += " - " + MapUtils.getFormattedDistance((int) MapUtils.getDistance(locationToGo, st.getLocation())); //$NON-NLS-1$ n += " - [" + MapUtils.getFormattedDistance((int) MapUtils.getDistance(locationToGo, st.getLocation())) +"]"; //$NON-NLS-1$ //$NON-NLS-2$
} }
n = MapUtils.getFormattedDistance((int) MapUtils.getDistance(lastKnownMapLocation, st.getLocation())) +" - " + n; //$NON-NLS-1$
items.add(n); items.add(n);
} }
// TODO show menu mark as intermediate mark on map
builder.setItems(items.toArray(new String[items.size()]), null); builder.setItems(items.toArray(new String[items.size()]), null);
builder.show(); builder.show();
} }
@ -166,10 +163,13 @@ public class SearchTransportActivity extends ListActivity {
TransportRoute route = stop.getRoute(); TransportRoute route = stop.getRoute();
StringBuilder labelW = new StringBuilder(150); StringBuilder labelW = new StringBuilder(150);
labelW.append(route.getType()).append(" ").append(route.getRef()); //$NON-NLS-1$ labelW.append(route.getType()).append(" ").append(route.getRef()); //$NON-NLS-1$
labelW.append(" - ["); //$NON-NLS-1$
if (locationToGo != null) { if (locationToGo != null) {
labelW.append(" - ").append(MapUtils.getFormattedDistance(stop.getDistToLocation())); //$NON-NLS-1$ labelW.append(MapUtils.getFormattedDistance(stop.getDistToLocation()));
} else {
labelW.append("no target");
} }
labelW.append("\n").append(route.getName(OsmandSettings.usingEnglishNames(SearchTransportActivity.this))); //$NON-NLS-1$ labelW.append("]\n").append(route.getName(OsmandSettings.usingEnglishNames(SearchTransportActivity.this))); //$NON-NLS-1$
label.setText(labelW.toString()); label.setText(labelW.toString());
// TODO icons // TODO icons
if (stop.getDistToLocation() < 400) { if (stop.getDistToLocation() < 400) {