diff --git a/DataExtractionOSM/src/com/osmand/ToDoConstants.java b/DataExtractionOSM/src/com/osmand/ToDoConstants.java index 1f3be97ec9..a06686367e 100644 --- a/DataExtractionOSM/src/com/osmand/ToDoConstants.java +++ b/DataExtractionOSM/src/com/osmand/ToDoConstants.java @@ -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] // 33. Build transport locations. Create transport index (transport-stops) (investigate) // 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). @@ -42,7 +42,7 @@ public class ToDoConstants { // 40. Support simple vector road rendering (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 // REFACTOR Settings activity ( for check box properties!) // Download index show current index information @@ -57,19 +57,7 @@ public class ToDoConstants { // BUGS Swing // 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 diff --git a/DataExtractionOSM/src/com/osmand/data/index/DataIndexWriter.java b/DataExtractionOSM/src/com/osmand/data/index/DataIndexWriter.java index 1bd541243d..49597ca6b9 100644 --- a/DataExtractionOSM/src/com/osmand/data/index/DataIndexWriter.java +++ b/DataExtractionOSM/src/com/osmand/data/index/DataIndexWriter.java @@ -326,6 +326,7 @@ public class DataIndexWriter { private void writeRouteStops(PreparedStatement prepRouteStops, PreparedStatement prepStops, Map count, Set writtenStops, TransportRoute r, List stops, boolean direction) throws SQLException { + int i = 0; for(TransportStop s : stops){ if (!writtenStops.contains(s.getId())) { assert IndexTransportStop.values().length == 5; @@ -337,10 +338,11 @@ public class DataIndexWriter { addBatch(count, prepStops); 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.STOP.ordinal() + 1, s.getId()); prepRouteStops.setInt(IndexTransportRouteStop.DIRECTION.ordinal() + 1, direction ? 1 : 0); + prepRouteStops.setInt(IndexTransportRouteStop.ORD.ordinal() + 1, i++); addBatch(count, prepRouteStops); } } diff --git a/DataExtractionOSM/src/com/osmand/data/index/IndexConstants.java b/DataExtractionOSM/src/com/osmand/data/index/IndexConstants.java index 2a4f1aca57..58a6910dbe 100644 --- a/DataExtractionOSM/src/com/osmand/data/index/IndexConstants.java +++ b/DataExtractionOSM/src/com/osmand/data/index/IndexConstants.java @@ -327,7 +327,7 @@ public class IndexConstants { 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; String type = null; diff --git a/DataExtractionOSM/src/com/osmand/osm/MapUtils.java b/DataExtractionOSM/src/com/osmand/osm/MapUtils.java index 8fdc8d85ef..83c08a83dc 100644 --- a/DataExtractionOSM/src/com/osmand/osm/MapUtils.java +++ b/DataExtractionOSM/src/com/osmand/osm/MapUtils.java @@ -213,7 +213,9 @@ public class MapUtils { } else if(meters >= 10000){ return MessageFormat.format("{0,number,#.#} "+Messages.getMessage(Messages.KEY_KM), ((float) meters) / 1000); //$NON-NLS-1$ } 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 { return meters + " "+Messages.getMessage(Messages.KEY_M); //$NON-NLS-1$ } diff --git a/OsmAnd/res/layout/search_transport.xml b/OsmAnd/res/layout/search_transport.xml index 5fdb0be309..e006db035f 100644 --- a/OsmAnd/res/layout/search_transport.xml +++ b/OsmAnd/res/layout/search_transport.xml @@ -4,6 +4,7 @@ android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> + diff --git a/OsmAnd/src/com/osmand/TransportIndexRepository.java b/OsmAnd/src/com/osmand/TransportIndexRepository.java index 3483641ab8..6d438b6d2a 100644 --- a/OsmAnd/src/com/osmand/TransportIndexRepository.java +++ b/OsmAnd/src/com/osmand/TransportIndexRepository.java @@ -210,110 +210,136 @@ public class TransportIndexRepository extends BaseLocationIndexRepository list = new ArrayList(registeredRoutes.values()); - preloadRouteStopsAndCalculateDistance(loc, locationToGo, list); + List list = preloadRouteStopsAndCalculateDistance(loc, locationToGo, registeredRoutes); return list; } - private static String cacheSQLRouteStops = null; - protected void preloadRouteStopsAndCalculateDistance(final LatLon loc, LatLon locationToGo, List listRoutes){ + protected List preloadRouteStopsAndCalculateDistance(final LatLon loc, LatLon locationToGo, + Map registeredRoutes) { + if(registeredRoutes.isEmpty()){ + return Collections.emptyList(); + } long now = System.currentTimeMillis(); - // TODO do 1 request - if(cacheSQLRouteStops == null){ - StringBuilder sql = new StringBuilder(200); - sql.append("SELECT "); //$NON-NLS-1$ - String[] cols = IndexConstants.generateColumnNames(IndexTransportStop.values()); - for(int i=0; i0){ - sql.append(", "); //$NON-NLS-1$ + StringBuilder sql = new StringBuilder(200); + sql.append("SELECT "); //$NON-NLS-1$ + String[] cols = IndexConstants.generateColumnNames(IndexTransportStop.values()); + for (int i = 0; i < cols.length; i++) { + 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 distanceToLoc = new LinkedHashMap(); + + 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$ - append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$ - sql.append(" AND ?=").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.DIRECTION); //$NON-NLS-1$ //$NON-NLS-2$ - cacheSQLRouteStops = sql.toString(); - } - - 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); + if (found) { + if (locationToGo != null) { + double d = MapUtils.getDistance(locationToGo, st.getLocation()); + if (d < distanceToLoc.get(id)) { + distanceToLoc.put(id, (int) d); } } - } while (query.moveToNext()); - } + if (i.direction) { + i.getRoute().getForwardStops().add(st); + } else { + i.getRoute().getBackwardStops().add(st); + } + } + + } while (query.moveToNext()); 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 listRoutes = new ArrayList(registeredRoutes.values()); if (log.isDebugEnabled()) { 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){ - Collections.sort(listRoutes, new Comparator(){ + + if (locationToGo != null) { + Collections.sort(listRoutes, new Comparator() { @Override public int compare(RouteInfoLocation object1, RouteInfoLocation object2) { return object1.getDistToLocation() - object2.getDistToLocation(); } - + }); } else { - Collections.sort(listRoutes, new Comparator(){ + Collections.sort(listRoutes, new Comparator() { @Override public int compare(RouteInfoLocation object1, RouteInfoLocation object2) { - return Double.compare(MapUtils.getDistance(loc, object1.getStart().getLocation()), - MapUtils.getDistance(loc, object2.getStart().getLocation())); + return Double.compare(MapUtils.getDistance(loc, object1.getStart().getLocation()), MapUtils.getDistance(loc, object2 + .getStart().getLocation())); } - + }); } - + return listRoutes; } public static class RouteInfoLocation { diff --git a/OsmAnd/src/com/osmand/activities/search/SearchTransportActivity.java b/OsmAnd/src/com/osmand/activities/search/SearchTransportActivity.java index abbd989d86..782a1a74fe 100644 --- a/OsmAnd/src/com/osmand/activities/search/SearchTransportActivity.java +++ b/OsmAnd/src/com/osmand/activities/search/SearchTransportActivity.java @@ -75,19 +75,14 @@ public class SearchTransportActivity extends ListActivity { } public String getSearchArea(){ - // TODO - 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$ - } + return " < " + 125 * (1 << (17 - zoom)) + " " + Messages.getMessage(Messages.KEY_M); //$NON-NLS-1$//$NON-NLS-2$ } public boolean isSearchFurtherAvailable() { return zoom >= finalZoom; } public void searchFurther(){ + // TODO use progress if (lastKnownMapLocation != null) { List rs = ResourceManager.getResourceManager().searchTransportRepositories(lastKnownMapLocation.getLatitude(), lastKnownMapLocation.getLongitude()); @@ -96,7 +91,7 @@ public class SearchTransportActivity extends ListActivity { searchTransportLevel.setEnabled(isSearchFurtherAvailable()); List res = repo.searchTransportRouteStops(lastKnownMapLocation.getLatitude(), lastKnownMapLocation.getLongitude(), locationToGo, zoom); - // TODO add progress + stopsAdapter.setNewModel(res); } else { repo = null; @@ -127,10 +122,12 @@ public class SearchTransportActivity extends ListActivity { for(TransportStop st : stops){ String n = st.getName(OsmandSettings.usingEnglishNames(this)); 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); } + // TODO show menu mark as intermediate mark on map builder.setItems(items.toArray(new String[items.size()]), null); builder.show(); } @@ -166,10 +163,13 @@ public class SearchTransportActivity extends ListActivity { TransportRoute route = stop.getRoute(); StringBuilder labelW = new StringBuilder(150); labelW.append(route.getType()).append(" ").append(route.getRef()); //$NON-NLS-1$ + labelW.append(" - ["); //$NON-NLS-1$ 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()); // TODO icons if (stop.getDistToLocation() < 400) {