add transport navigation

git-svn-id: https://osmand.googlecode.com/svn/trunk@281 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-07-04 21:09:26 +00:00
parent ccbf031587
commit 7de3b2dd96
9 changed files with 460 additions and 71 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 intermediate points, add menu for stops (show map) // TODO : add show on map key stops, update current stop with gps, add transport activity to map (remove tab)
// 66. Transport routing (show next stop, total distance, show stop get out). // 66. Transport routing (show next stop, total distance, show stop get out).

View file

@ -2,13 +2,21 @@
<!-- This file is at /res/layout/list.xml --> <!-- This file is at /res/layout/list.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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" android:id="@+id/RootLayout">
<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> <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"/>
</LinearLayout> </LinearLayout>
<ListView android:id="@android:id/list" android:layout_width="fill_parent" <RelativeLayout android:id="@+id/RelativeLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center">
android:layout_height="fill_parent"></ListView> <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_alignParentBottom="true"
android:layout_height="wrap_content" android:layout_below="@+id/listView"
></ListView>
<ListView android:id="@+id/listView" android:layout_width="fill_parent"
android:layout_alignParentTop="true" android:layout_height="wrap_content"></ListView>
</RelativeLayout>
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- <TextView android:id="@+id/distance_label" android:layout_marginLeft="5dp"
android:layout_width="80dp" android:layout_height="fill_parent" android:gravity="left"
android:textSize="20px"/> -->
<TextView android:id="@+id/label" android:layout_weight="1" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="20px" />
<ImageButton android:id="@+id/remove" android:layout_width="wrap_content" android:background="@drawable/reset"
android:paddingLeft="2px" android:paddingRight="2px"
android:paddingTop="2px" android:layout_height="wrap_content" />
</LinearLayout>

View file

@ -1,5 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="transport_Stop">Остановка</string>
<string name="transport_stops">остановок</string>
<string name="transport_searching_transport">Искать транспорт (нет цели)</string>
<string name="transport_searching_route">Искать {0} маршрут </string>
<string name="transport_search_none">нету</string>
<string name="transport_search_after">Искать маршрут после</string>
<string name="transport_search_before">Искать маршрут до</string>
<string name="transport_finish_search">Остановить поиск</string>
<string name="transport_stop_to_go_out">Выберите остановку</string>
<string name="transport_to_go_after">идти после</string>
<string name="transport_to_go_before">идти до</string>
<string name="transport_stops_to_pass">остановок в пути</string>
<string name="transport_route_distance">Длина пути</string>
<string name="transport">Транспорт</string>
<string name="default_buttons_ok">OK</string>
<string name="show_transport_over_map_description">Показать остановки транспорта на карте</string> <string name="show_transport_over_map_description">Показать остановки транспорта на карте</string>
<string name="show_transport_over_map">Показать транспорт</string> <string name="show_transport_over_map">Показать транспорт</string>
<string name="hello">Навигационное приложение OsmAnd</string> <string name="hello">Навигационное приложение OsmAnd</string>
@ -56,7 +71,7 @@
<string name="get_directions">Маршрут</string> <string name="get_directions">Маршрут</string>
<string name="gps_status_app_not_found">Приложение Gps status не найдено</string> <string name="gps_status_app_not_found">Приложение Gps status не найдено</string>
<string name="show_gps_status">GPS статус</string> <string name="show_gps_status">GPS статус</string>
<string name="opening_hours">Рабочие часы: </string> <string name="opening_hours">Рабочие часы : </string>
<string name="opening_changeset">Открытие пакета правок</string> <string name="opening_changeset">Открытие пакета правок</string>
<string name="closing_changeset">Закрытие пакета правок</string> <string name="closing_changeset">Закрытие пакета правок</string>
<string name="commiting_node">Сохранения объекта</string> <string name="commiting_node">Сохранения объекта</string>
@ -71,7 +86,7 @@
<string name="loading">Загрузка</string> <string name="loading">Загрузка</string>
<string name="poi">POI</string> <string name="poi">POI</string>
<string name="error_occurred_saving_gpx">Ошибка во время сохранения пути в gpx</string> <string name="error_occurred_saving_gpx">Ошибка во время сохранения пути в gpx</string>
<string name="error_calculating_route">Ошибка прокладки маршрута: </string> <string name="error_calculating_route">Ошибка прокладки маршрута : </string>
<string name="error_calculating_route_occured">Ошибка во время прокладки маршрута</string> <string name="error_calculating_route_occured">Ошибка во время прокладки маршрута</string>
<string name="empty_route_calculated">Пустой путь рассчитан</string> <string name="empty_route_calculated">Пустой путь рассчитан</string>
<string name="new_route_calculated_dist">Проложен новый путь, расстояние : </string> <string name="new_route_calculated_dist">Проложен новый путь, расстояние : </string>
@ -211,7 +226,7 @@
<string name="default_buttons_cancel">Отмена</string> <string name="default_buttons_cancel">Отмена</string>
<string name="default_buttons_apply">Применить</string><string name="default_buttons_add">Добавить</string><string name="default_buttons_no">Нет</string><string name="add_favorite_dialog_top_text">Введите имя точки</string> <string name="default_buttons_apply">Применить</string><string name="default_buttons_add">Добавить</string><string name="default_buttons_no">Нет</string><string name="add_favorite_dialog_top_text">Введите имя точки</string>
<string name="add_favorite_dialog_default_favourite_name">Избранная</string> <string name="add_favorite_dialog_default_favourite_name">Избранная</string>
<string name="add_favorite_dialog_favourite_added_template">Точка \'{0}\' была успешно добавлена к Избранным.</string> <string name="add_favorite_dialog_favourite_added_template">Точка \'\'{0}\'\' была успешно добавлена к Избранным.</string>
<string name="favourites_context_menu_title">Контекстное меню</string> <string name="favourites_context_menu_title">Контекстное меню</string>
<string name="favourites_context_menu_navigate">Идти к</string> <string name="favourites_context_menu_navigate">Идти к</string>

View file

@ -1,7 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="transport_Stop">Stop</string>
<string name="transport_stops">stops</string>
<string name="transport_searching_transport">Searching transport (no target)</string>
<string name="transport_searching_route">Searching for {0} route</string>
<string name="transport_search_none">none</string>
<string name="transport_search_after">Search route after</string>
<string name="transport_search_before">Search route before</string>
<string name="transport_finish_search">Finish search</string>
<string name="transport_stop_to_go_out">Choose stop to go out</string>
<string name="transport_to_go_after">to go after</string>
<string name="transport_to_go_before">to go before</string>
<string name="transport_stops_to_pass">stops to pass</string>
<string name="transport_route_distance">Route distance</string>
<string name="transport">Transport</string> <string name="transport">Transport</string>
<!-- TODO rus --> <string name="default_buttons_ok">OK</string>
<string name="show_transport_over_map_description">Show public transport stops on map</string> <string name="show_transport_over_map_description">Show public transport stops on map</string>
<string name="show_transport_over_map">Show transport stops</string> <string name="show_transport_over_map">Show transport stops</string>
<string name="hello">Navigation application OsmAnd</string> <string name="hello">Navigation application OsmAnd</string>
@ -94,7 +107,7 @@ See osmand.googlecode.com.</string>
<string name="use_online_routing">Use online routing</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>
<string name="monitor_preferences_descr">Specify monitor settings : save track</string> <string name="monitor_preferences_descr">Specify monitor settings : save track</string>
<string name="data_settings_descr">Specify data settings : language, update data</string> <string name="data_settings_descr">Specify data settings : language, update data</string>
<string name="map_preferences_descr">Specify map settings : rotation, poi filter</string> <string name="map_preferences_descr">Specify map settings : rotation, poi filter</string>
@ -214,7 +227,7 @@ See osmand.googlecode.com.</string>
<string name="default_buttons_cancel">Cancel</string> <string name="default_buttons_cancel">Cancel</string>
<string name="default_buttons_apply">Apply</string><string name="default_buttons_add">Add</string><string name="default_buttons_no">No</string><string name="add_favorite_dialog_top_text">Input name of favourite point</string> <string name="default_buttons_apply">Apply</string><string name="default_buttons_add">Add</string><string name="default_buttons_no">No</string><string name="add_favorite_dialog_top_text">Input name of favourite point</string>
<string name="add_favorite_dialog_default_favourite_name">Favourite</string> <string name="add_favorite_dialog_default_favourite_name">Favourite</string>
<string name="add_favorite_dialog_favourite_added_template">Favourite point \'{0}\' was added successfully.</string> <string name="add_favorite_dialog_favourite_added_template">Favourite point \'\'{0}\'\' was added successfully.</string>
<string name="favourites_context_menu_title">Context menu</string> <string name="favourites_context_menu_title">Context menu</string>
<string name="favourites_context_menu_navigate">Navigate to</string> <string name="favourites_context_menu_navigate">Navigate to</string>

View file

@ -257,7 +257,7 @@ public class TransportIndexRepository extends BaseLocationIndexRepository<Transp
int qShift = IndexTransportStop.values().length; int qShift = IndexTransportStop.values().length;
Map<Long, Integer> distanceToLoc = new LinkedHashMap<Long, Integer>(); Map<Long, TransportStop> distanceToLoc = new LinkedHashMap<Long, TransportStop>();
Cursor query = db.rawQuery(sql.toString(), new String[] {}); Cursor query = db.rawQuery(sql.toString(), new String[] {});
if (query.moveToFirst()) { if (query.moveToFirst()) {
@ -280,18 +280,15 @@ public class TransportIndexRepository extends BaseLocationIndexRepository<Transp
} else if (query.getLong(IndexTransportStop.ID.ordinal()) == i.getStart().getId()) { } else if (query.getLong(IndexTransportStop.ID.ordinal()) == i.getStart().getId()) {
st = i.getStart(); st = i.getStart();
found = true; found = true;
Integer dist = null; distanceToLoc.put(id, st);
if (locationToGo != null) {
dist = (int) MapUtils.getDistance(locationToGo, i.getStart().getLocation());
}
distanceToLoc.put(id, dist);
} }
if (found) { if (found) {
if (locationToGo != null) { if (locationToGo != null) {
double d = MapUtils.getDistance(locationToGo, st.getLocation()); double d = MapUtils.getDistance(locationToGo, st.getLocation());
if (d < distanceToLoc.get(id)) { double dbase = MapUtils.getDistance(locationToGo, distanceToLoc.get(id).getLocation());
distanceToLoc.put(id, (int) d); if (d < dbase) {
distanceToLoc.put(id, st);
} }
} }
if (i.direction) { if (i.direction) {
@ -308,10 +305,11 @@ public class TransportIndexRepository extends BaseLocationIndexRepository<Transp
if (locationToGo != null) { if (locationToGo != null) {
for (Long l : registeredRoutes.keySet()) { for (Long l : registeredRoutes.keySet()) {
Integer dist = distanceToLoc.get(l); Integer dist = (int) MapUtils.getDistance(locationToGo, distanceToLoc.get(l).getLocation());
if (dist != null) { if (dist != null) {
registeredRoutes.get(l).setDistToLocation(dist); registeredRoutes.get(l).setDistToLocation(dist);
} }
registeredRoutes.get(l).setStop(distanceToLoc.get(l));
} }
} }
@ -325,7 +323,9 @@ public class TransportIndexRepository extends BaseLocationIndexRepository<Transp
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(); int x = (int) (MapUtils.getDistance(loc, object1.getStart().getLocation()) + object1.getDistToLocation());
int y = (int) (MapUtils.getDistance(loc, object2.getStart().getLocation()) + object2.getDistToLocation());
return x - y;
} }
}); });
@ -344,7 +344,9 @@ public class TransportIndexRepository extends BaseLocationIndexRepository<Transp
public static class RouteInfoLocation { public static class RouteInfoLocation {
private TransportStop start; private TransportStop start;
private TransportStop stop;
private TransportRoute route; private TransportRoute route;
private int stopNumbers;
private int distToLocation; private int distToLocation;
private boolean direction; private boolean direction;
@ -372,6 +374,22 @@ public class TransportIndexRepository extends BaseLocationIndexRepository<Transp
this.start = start; this.start = start;
} }
public TransportStop getStop() {
return stop;
}
public int getStopNumbers() {
return stopNumbers;
}
public void setStopNumbers(int stopNumbers) {
this.stopNumbers = stopNumbers;
}
public void setStop(TransportStop stop) {
this.stop = stop;
}
public void setRoute(TransportRoute route) { public void setRoute(TransportRoute route) {
this.route = route; this.route = route;
} }

View file

@ -266,7 +266,7 @@ public class EditingPOIActivity {
throw new IllegalArgumentException(requestMethod + " is invalid method"); //$NON-NLS-1$ throw new IllegalArgumentException(requestMethod + " is invalid method"); //$NON-NLS-1$
} }
if (requestMethod.equals("PUT") || requestMethod.equals("POST") || requestMethod.equals("DELETE")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (requestMethod.equals("PUT") || requestMethod.equals("POST") || requestMethod.equals("DELETE")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
// TODO // TODO add when needed
// connection.setDoOutput(true); // connection.setDoOutput(true);
// connection.setRequestProperty("Content-type", "text/xml"); // connection.setRequestProperty("Content-type", "text/xml");
// OutputStream out = connection.getOutputStream(); // OutputStream out = connection.getOutputStream();

View file

@ -83,6 +83,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
private static final int GPS_DIST_REQUEST = 5; private static final int GPS_DIST_REQUEST = 5;
private boolean providerSupportsBearing = false; private boolean providerSupportsBearing = false;
@SuppressWarnings("unused")
private boolean providerSupportsSpeed = false; private boolean providerSupportsSpeed = false;
private String currentLocationProvider = null; private String currentLocationProvider = null;
@ -354,7 +355,9 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
private void updateSpeedBearing(Location location) { private void updateSpeedBearing(Location location) {
// For network/gps it's bad way (not accurate). It's widely used for testing purposes // For network/gps it's bad way (not accurate). It's widely used for testing purposes
// possibly keep using only for emulator case // possibly keep using only for emulator case
if (!providerSupportsSpeed && locationLayer.getLastKnownLocation() != null && location != null) { // if (!providerSupportsSpeed
if (isRunningOnEmulator()
&& locationLayer.getLastKnownLocation() != null && location != null) {
if (locationLayer.getLastKnownLocation().distanceTo(location) > 3) { if (locationLayer.getLastKnownLocation().distanceTo(location) > 3) {
float d = location.distanceTo(locationLayer.getLastKnownLocation()); float d = location.distanceTo(locationLayer.getLastKnownLocation());
long time = location.getTime() - locationLayer.getLastKnownLocation().getTime(); long time = location.getTime() - locationLayer.getLastKnownLocation().getTime();

View file

@ -3,12 +3,15 @@
*/ */
package com.osmand.activities.search; package com.osmand.activities.search;
import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.ListActivity; import android.app.ListActivity;
import android.app.AlertDialog.Builder; import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -16,6 +19,7 @@ import android.view.ViewGroup;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ListView; import android.widget.ListView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
@ -41,9 +45,8 @@ public class SearchTransportActivity extends ListActivity {
private Button searchTransportLevel; private Button searchTransportLevel;
private TransportStopAdapter stopsAdapter;
private LatLon lastKnownMapLocation;
private LatLon locationToGo;
private TextView searchArea; private TextView searchArea;
private TransportIndexRepository repo; private TransportIndexRepository repo;
@ -51,10 +54,18 @@ public class SearchTransportActivity extends ListActivity {
private final static int initialZoom = 17; private final static int initialZoom = 17;
private int zoom = initialZoom; private int zoom = initialZoom;
private ProgressBar progress; private ProgressBar progress;
private Thread thread;
// TODO test when these args null
private LatLon lastKnownMapLocation;
private LatLon destinationLocation;
private TransportStopAdapter stopsAdapter;
private TransportRouteAdapter intermediateListAdapater;
private static List<RouteInfoLocation> lastEditedRoute = new ArrayList<RouteInfoLocation>();
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
@ -66,7 +77,7 @@ public class SearchTransportActivity extends ListActivity {
public void onClick(View v) { public void onClick(View v) {
if(isSearchFurtherAvailable()){ if(isSearchFurtherAvailable()){
zoom --; zoom --;
searchFurther(); searchTransport();
} }
} }
}); });
@ -74,8 +85,28 @@ public class SearchTransportActivity extends ListActivity {
progress.setVisibility(View.INVISIBLE); progress.setVisibility(View.INVISIBLE);
stopsAdapter = new TransportStopAdapter(new ArrayList<RouteInfoLocation>()); stopsAdapter = new TransportStopAdapter(new ArrayList<RouteInfoLocation>());
setListAdapter(stopsAdapter); setListAdapter(stopsAdapter);
searchArea.setText(getSearchArea());
ListView intermediateList = (ListView) findViewById(R.id.listView);
intermediateListAdapater = new TransportRouteAdapter(lastEditedRoute);
intermediateList.setAdapter(intermediateListAdapater);
intermediateListAdapater.add(null);
lastKnownMapLocation = OsmandSettings.getLastKnownMapLocation(this);
destinationLocation = OsmandSettings.getPointToNavigate(this);
searchTransport();
}
@Override
protected void onDestroy() {
super.onDestroy();
lastEditedRoute.clear();
for(int i= 0; i< intermediateListAdapater.getCount(); i++){
RouteInfoLocation item = intermediateListAdapater.getItem(i);
if(item != null){
lastEditedRoute.add(item);
}
}
} }
public String getSearchArea(){ public String getSearchArea(){
@ -85,40 +116,45 @@ public class SearchTransportActivity extends ListActivity {
return zoom >= finalZoom; return zoom >= finalZoom;
} }
public void searchFurther(){ public void searchTransport(){
// use progress // use progress
stopsAdapter.clear();
searchTransportLevel.setEnabled(false); searchTransportLevel.setEnabled(false);
if (lastKnownMapLocation != null) { searchArea.setText(getSearchArea());
List<TransportIndexRepository> rs = ResourceManager.getResourceManager().searchTransportRepositories(lastKnownMapLocation.getLatitude(), boolean routeCalculated = isRouteCalculated();
lastKnownMapLocation.getLongitude()); if (!routeCalculated && getLocationToStart() != null) {
final LatLon locationToStart = getLocationToStart();
final LatLon locationToGo = getLocationToGo();
List<TransportIndexRepository> rs = ResourceManager.getResourceManager().searchTransportRepositories(locationToStart.getLatitude(),
locationToStart.getLongitude());
if(!rs.isEmpty()){ if(!rs.isEmpty()){
repo = rs.get(0); repo = rs.get(0);
progress.setVisibility(View.VISIBLE); progress.setVisibility(View.VISIBLE);
new Thread(new Runnable(){ synchronized (this) {
@Override final Thread previousThread = thread;
public void run() { thread = new Thread(new Runnable() {
List<RouteInfoLocation> res = repo.searchTransportRouteStops(lastKnownMapLocation.getLatitude(), lastKnownMapLocation.getLongitude(), @Override
locationToGo, zoom); public void run() {
updateUIList(res); if (previousThread != null) {
} try {
},"SearchingTransport").start(); //$NON-NLS-1$ previousThread.join();
} catch (InterruptedException e) {
}
}
List<RouteInfoLocation> res = repo.searchTransportRouteStops(locationToStart.getLatitude(), locationToStart
.getLongitude(), locationToGo, zoom);
updateUIList(res);
}
}, "SearchingTransport"); //$NON-NLS-1$
thread.start();
}
} else { } else {
repo = null; repo = null;
stopsAdapter.clear();
} }
} else {
stopsAdapter.clear();
} }
} }
@Override
protected void onResume() {
super.onResume();
lastKnownMapLocation = OsmandSettings.getLastKnownMapLocation(this);
locationToGo = OsmandSettings.getPointToNavigate(this);
searchFurther();
}
protected void updateUIList(final List<RouteInfoLocation> stopsList){ protected void updateUIList(final List<RouteInfoLocation> stopsList){
runOnUiThread(new Runnable(){ runOnUiThread(new Runnable(){
@Override @Override
@ -131,34 +167,211 @@ public class SearchTransportActivity extends ListActivity {
}); });
} }
public String getInformation(RouteInfoLocation route, List<TransportStop> stops, int position, boolean part){
public void onListItemClick(ListView parent, View v, int position, long id) { StringBuilder text = new StringBuilder(200);
RouteInfoLocation item = ((TransportStopAdapter)getListAdapter()).getItem(position); double dist = 0;
Builder builder = new AlertDialog.Builder(this); int ind = 0;
List<String> items = new ArrayList<String>(); int stInd = stops.size();
List<TransportStop> stops = item.getDirection() ? item.getRoute().getForwardStops() : item.getRoute().getBackwardStops(); int eInd = stops.size();
for(TransportStop st : stops){ for (TransportStop s : stops) {
String n = st.getName(OsmandSettings.usingEnglishNames(this)); if (s == route.getStart()) {
if(locationToGo != null){ stInd = ind;
n += " - [" + MapUtils.getFormattedDistance((int) MapUtils.getDistance(locationToGo, st.getLocation())) +"]"; //$NON-NLS-1$ //$NON-NLS-2$ } else if (s == route.getStop()) {
} else { eInd = ind;
n = MapUtils.getFormattedDistance((int) MapUtils.getDistance(lastKnownMapLocation, st.getLocation())) +" - " + n; //$NON-NLS-1$
} }
items.add(n); if (ind > stInd && ind <= eInd) {
dist += MapUtils.getDistance(stops.get(ind - 1).getLocation(), s.getLocation());
}
ind++;
} }
// TODO show menu mark as intermediate mark on map text.append(getString(R.string.transport_route_distance)).append(" ").append(MapUtils.getFormattedDistance((int) dist)); //$NON-NLS-1$/
builder.setItems(items.toArray(new String[items.size()]), null); if(!part){
builder.show(); text.append(", ").append(getString(R.string.transport_stops_to_pass)).append(" ").append(eInd - stInd); //$NON-NLS-1$ //$NON-NLS-2$
String before = MapUtils.getFormattedDistance((int) MapUtils.getDistance(getEndStop(position - 1), route.getStart().getLocation()));
String after = MapUtils.getFormattedDistance((int) MapUtils.getDistance(getStartStop(position + 1), route.getStop().getLocation()));
text.append(", ").append(getString(R.string.transport_to_go_before)).append(" ").append(before).append(", "); //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-1$
text.append(getString(R.string.transport_to_go_after)).append(" ").append(after); //$NON-NLS-1$
}
return text.toString();
} }
public void onListItemClick(ListView parent, View v, int position, long id) {
final RouteInfoLocation item = ((TransportStopAdapter)getListAdapter()).getItem(position);
Builder builder = new AlertDialog.Builder(this);
List<String> items = new ArrayList<String>();
final List<TransportStop> stops = item.getDirection() ? item.getRoute().getForwardStops() : item.getRoute().getBackwardStops();
LatLon locationToGo = getLocationToGo();
LatLon locationToStart = getLocationToStart();
builder.setTitle(getString(R.string.transport_stop_to_go_out)+"\n"+getInformation(item, stops, getCurrentRouteLocation(), true)); //$NON-NLS-1$
int ind = 0;
for(TransportStop st : stops){
StringBuilder n = new StringBuilder(50);
n.append(ind++);
if(st == item.getStop()){
n.append("!! "); //$NON-NLS-1$
} else {
n.append(". "); //$NON-NLS-1$
}
String name = st.getName(OsmandSettings.usingEnglishNames(this));
if(locationToGo != null){
n.append(name).append(" - ["); //$NON-NLS-1$
n.append(MapUtils.getFormattedDistance((int) MapUtils.getDistance(locationToGo, st.getLocation()))).append("]"); //$NON-NLS-1$
} else {
n.append("[").append(MapUtils.getFormattedDistance((int) MapUtils.getDistance(locationToStart, st.getLocation()))).append("] - "); //$NON-NLS-1$ //$NON-NLS-2$
n.append(name);
}
items.add(n.toString());
}
builder.setItems(items.toArray(new String[items.size()]), new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
int i = which;
if(i >= 0){
TransportStop stop = stops.get(i);
showContextMenuOnStop(stop, item, i);
}
}
});
builder.show();
}
public void showContextMenuOnStop(final TransportStop stop, final RouteInfoLocation route, final int stopInd) {
Builder b = new AlertDialog.Builder(this);
b.setItems(new String[] { getString(R.string.transport_finish_search), getString(R.string.transport_search_before), getString(R.string.transport_search_after) },
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
int currentRouteCalculation = getCurrentRouteLocation();
route.setStop(stop);
route.setStopNumbers(stopInd);
if (which == 0) {
intermediateListAdapater.insert(route, currentRouteCalculation);
intermediateListAdapater.remove(null);
currentRouteCalculation = -1;
} else if (which == 1) {
intermediateListAdapater.insert(route, currentRouteCalculation + 1);
} else if (which == 2) {
intermediateListAdapater.insert(route, currentRouteCalculation);
}
// layout
zoom = initialZoom;
searchTransport();
}
});
b.show();
}
public void showContextMenuOnRoute(final RouteInfoLocation route, final int routeInd) {
Builder b = new AlertDialog.Builder(this);
List<TransportStop> stops = route.getDirection() ? route.getRoute().getForwardStops() : route.getRoute().getBackwardStops();
boolean en = OsmandSettings.isUsingInternetToDownloadTiles(this);
String info = getInformation(route, stops, routeInd, false);
StringBuilder txt = new StringBuilder(300);
txt.append(info);
boolean start = false;
for(TransportStop s : stops){
if(s == route.getStart()){
start = true;
}
if(start){
txt.append("\n").append(getString(R.string.transport_Stop)).append(" : ").append(s.getName(en)); //$NON-NLS-1$ //$NON-NLS-2$
}
if(s == route.getStop()){
break;
}
}
b.setMessage(txt.toString());
b.setPositiveButton(getString(R.string.default_buttons_ok), null);
b.setNeutralButton(getString(R.string.transport_search_before), new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
int toInsert = routeInd;
int c = getCurrentRouteLocation();
if(c >= 0 && c < routeInd){
toInsert --;
}
intermediateListAdapater.remove(null);
intermediateListAdapater.insert(null, routeInd);
zoom = initialZoom;
searchTransport();
}
});
b.setNegativeButton(getString(R.string.transport_search_after), new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
int toInsert = routeInd;
int c = getCurrentRouteLocation();
if(c > routeInd || c == -1){
toInsert ++;
}
intermediateListAdapater.remove(null);
intermediateListAdapater.insert(null, toInsert);
zoom = initialZoom;
searchTransport();
}
});
b.show();
}
public int getCurrentRouteLocation(){
return intermediateListAdapater.getPosition(null);
}
public boolean isRouteCalculated(){
return getCurrentRouteLocation() == -1;
}
public LatLon getLocationToStart() {
return getEndStop(getCurrentRouteLocation() - 1);
}
public LatLon getLocationToGo() {
return getStartStop(getCurrentRouteLocation() + 1);
}
// TODO always check for null
public LatLon getStartStop(int position){
if(position == intermediateListAdapater.getCount()){
return destinationLocation;
}
RouteInfoLocation item = intermediateListAdapater.getItem(position);
if(item == null){
return getStartStop(position + 1);
}
return item.getStart().getLocation();
}
// TODO always check for null
public LatLon getEndStop(int position){
if(position == -1){
return lastKnownMapLocation;
}
RouteInfoLocation item = intermediateListAdapater.getItem(position);
if(item == null){
return getEndStop(position -1);
}
return item.getStop().getLocation();
}
class TransportStopAdapter extends ArrayAdapter<RouteInfoLocation> { class TransportStopAdapter extends ArrayAdapter<RouteInfoLocation> {
private List<RouteInfoLocation> model;
TransportStopAdapter(List<RouteInfoLocation> list) { TransportStopAdapter(List<RouteInfoLocation> list) {
super(SearchTransportActivity.this, R.layout.search_transport_list_item, list); super(SearchTransportActivity.this, R.layout.search_transport_list_item, list);
this.setNotifyOnChange(false); model = list;
} }
public void setNewModel(List<RouteInfoLocation> stopsList) { public void setNewModel(List<RouteInfoLocation> stopsList) {
this.model = stopsList;
setNotifyOnChange(false); setNotifyOnChange(false);
((TransportStopAdapter) getListAdapter()).clear(); ((TransportStopAdapter) getListAdapter()).clear();
for (RouteInfoLocation obj : stopsList) { for (RouteInfoLocation obj : stopsList) {
@ -167,6 +380,10 @@ public class SearchTransportActivity extends ListActivity {
this.notifyDataSetChanged(); this.notifyDataSetChanged();
setNotifyOnChange(true); setNotifyOnChange(true);
} }
public List<RouteInfoLocation> getModel() {
return model;
}
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView; View row = convertView;
@ -174,6 +391,9 @@ public class SearchTransportActivity extends ListActivity {
LayoutInflater inflater = getLayoutInflater(); LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.search_transport_list_item, parent, false); row = inflater.inflate(R.layout.search_transport_list_item, parent, false);
} }
LatLon locationToGo = getLocationToGo();
LatLon locationToStart = getLocationToStart();
TextView label = (TextView) row.findViewById(R.id.label); TextView label = (TextView) row.findViewById(R.id.label);
TextView distanceLabel = (TextView) row.findViewById(R.id.distance); TextView distanceLabel = (TextView) row.findViewById(R.id.distance);
ImageView icon = (ImageView) row.findViewById(R.id.search_icon); ImageView icon = (ImageView) row.findViewById(R.id.search_icon);
@ -183,24 +403,120 @@ public class SearchTransportActivity extends ListActivity {
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$ labelW.append(" - ["); //$NON-NLS-1$
if (locationToGo != null) { if (locationToGo != null) {
labelW.append(MapUtils.getFormattedDistance(stop.getDistToLocation())); labelW.append(MapUtils.getFormattedDistance(stop.getDistToLocation()));
} else { } else {
labelW.append("none"); labelW.append(getString(R.string.transport_search_none));
} }
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 (locationToGo == null || stop.getDistToLocation() < 400) { if (locationToGo != null && stop.getDistToLocation() < 400) {
icon.setImageResource(R.drawable.poi); icon.setImageResource(R.drawable.poi);
} else { } else {
icon.setImageResource(R.drawable.closed_poi); icon.setImageResource(R.drawable.closed_poi);
} }
int dist = (int) (MapUtils.getDistance(stop.getStart().getLocation(), lastKnownMapLocation)); int dist = (int) (MapUtils.getDistance(stop.getStart().getLocation(), locationToStart));
distanceLabel.setText(" " + MapUtils.getFormattedDistance(dist)); //$NON-NLS-1$ distanceLabel.setText(" " + MapUtils.getFormattedDistance(dist)); //$NON-NLS-1$
return (row); return (row);
} }
} }
class TransportRouteAdapter extends ArrayAdapter<RouteInfoLocation> {
TransportRouteAdapter(List<RouteInfoLocation> list) {
super(SearchTransportActivity.this, R.layout.search_transport_route_item, list);
}
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
int currentRouteLocation = getCurrentRouteLocation();
if(position == currentRouteLocation){
TextView text = new TextView(getContext());
LatLon st = getStartStop(position + 1);
LatLon end = getEndStop(position - 1);
if(st != null){
int dist = (int) MapUtils.getDistance(st, end);
text.setText(MessageFormat.format(getString(R.string.transport_searching_route), MapUtils.getFormattedDistance(dist)));
} else {
text.setText(getString(R.string.transport_searching_transport));
}
text.setTextSize(21);
text.setTypeface(null, Typeface.ITALIC);
text.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
if(intermediateListAdapater.getCount() > 1){
intermediateListAdapater.remove(null);
searchTransport();
}
}
});
return text;
}
if (row == null || row instanceof TextView) {
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.search_transport_route_item, parent, false);
}
final RouteInfoLocation info = getItem(position);
TextView label = (TextView) row.findViewById(R.id.label);
ImageButton icon = (ImageButton) row.findViewById(R.id.remove);
TransportRoute route = info.getRoute();
icon.setVisibility(View.VISIBLE);
StringBuilder labelW = new StringBuilder(150);
labelW.append(route.getType()).append(" ").append(route.getRef()); //$NON-NLS-1$
boolean en = OsmandSettings.usingEnglishNames(SearchTransportActivity.this);
labelW.append(" : ").append(info.getStart().getName(en)).append(" - ").append(info.getStop().getName(en)); //$NON-NLS-1$ //$NON-NLS-2$
// additional information if route is calculated
if (currentRouteLocation == -1) {
labelW.append(" ("); //$NON-NLS-1$
labelW.append(info.getStopNumbers()).append(" ").append(getString(R.string.transport_stops)).append(", "); //$NON-NLS-1$ //$NON-NLS-2$
int startDist = (int) MapUtils.getDistance(getEndStop(position - 1), info.getStart().getLocation());
labelW.append(getString(R.string.transport_to_go_before)).append(" ").append(MapUtils.getFormattedDistance(startDist)); //$NON-NLS-1$
if (position == getCount() - 1) {
int endDist = (int) MapUtils.getDistance(getStartStop(position + 1), info.getStop().getLocation());
labelW.append(", ").append(getString(R.string.transport_to_go_after)).append(" ").append(MapUtils.getFormattedDistance(endDist)); //$NON-NLS-1$ //$NON-NLS-2$
}
labelW.append(")"); //$NON-NLS-1$
}
label.setText(labelW.toString());
icon.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
int p = position;
intermediateListAdapater.remove(null);
if(!isRouteCalculated() && getCurrentRouteLocation() < p){
p--;
}
intermediateListAdapater.insert(null, p);
intermediateListAdapater.remove(info);
intermediateListAdapater.notifyDataSetChanged();
zoom = initialZoom;
searchTransport();
}
});
View.OnClickListener clickListener = new View.OnClickListener(){
@Override
public void onClick(View v) {
showContextMenuOnRoute(info, position);
}
};
label.setOnClickListener(clickListener);
return row;
}
}
} }