implement import/export favorite points

git-svn-id: https://osmand.googlecode.com/svn/trunk@419 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-07-31 10:38:16 +00:00
parent 54a8294e52
commit cb80fc1430
8 changed files with 224 additions and 28 deletions

View file

@ -8,19 +8,14 @@ package com.osmand;
*/
public class ToDoConstants {
// TODO
// 80. Export/import favorite points
// 81. Add some objects to POI category (1) to add them into OSM 2) to help navigation)
// highway (?), traffic_calming (?), barrier(?), military(?-), landuse (?), office(?), man_made(?), power(?).
// TODO max 85
// ! 81. Add some objects to POI category (1) to add them into OSM 2) to help navigation)
// highway (?), traffic_calming (?), barrier(?), military(?-), landuse (?), office(?), man_made(?), power(?),
// railway( station, subway?) - issue 17
// TODO BUGS Android
// 3. different screens better support
// 2. GPS - network switch (+?)
// 5. route bug show further (+)
// 4. save state yandex traffic (+)
// 1. Alert no addresses (+)
// ! 3. different screens better support
// Improvements
// ! Download with wget
@ -42,12 +37,13 @@ public class ToDoConstants {
// TODO swing
// 9. Fix issues with big files (such as netherlands) - save memory (!) - very slow due to transport index !
// Current result : for big file (1 - task 60-80% time, 90% memory) (?)
// 10. Improve address indexing (use relations). (?) // SLOBODSKAYA 157, 95
// ! 10. Improve address indexing (use relations). (?) // SLOBODSKAYA 157, 95
// use relation "a6" (to accumulate streets!), "a3" to read all cities & define boundaries for city (& define that street in city).
// BUGS Swing
// DONE ANDROID :
// 80. Export/import favorite points
// 84. Send letter to developer when app crashes
// 78. Add ruler to the main tile view (100m, 200m,...) (+)
// 82. Add overzoom +2 for Mapnik

View file

@ -121,7 +121,7 @@
<string name="route_general_information">{0} Gesamtentfernung\n{1}:{2}Reisezeit</string>
<string name="router_service_descr">Dienst zur Streckenberechnung wählen</string>
<string name="router_service">Streckenberechnungsdienst</string>
<string name="download_sd_dir_not_accessible">Directory on SD card to save index is not accessible</string>
<string name="sd_dir_not_accessible">Directory on SD card to save is not accessible</string>
<string name="download_question">Do you want to download {0} - {1} ?</string>
<string name="download_question_exist">Index for {0} already exists ({1}). Do you want to update it ({2}) ?</string>
<string name="address">Adresse</string>

View file

@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="fav_imported_sucessfully">Избранные точки успешно импортированы</string>
<string name="fav_file_to_load_not_found">GPX файл, содержащий точки, не был найден в {0}</string>
<string name="fav_saved_sucessfully">Избранные точки сохранены в {0}</string>
<string name="no_fav_to_save">Нет избранных точек для сохранения</string>
<string name="import_fav">Импортировать</string>
<string name="export_fav">Экспортировать</string>
<string name="error_occurred_loading_gpx">Произошла ошибка во время загрузки gpx</string>
<string name="send_report">Отправить отчет</string>
<string name="none_region_found">Не найден ни один индекс на SD карточке. Можете загрузить их с интернета.</string>
<string name="poi_namefinder_query_empty">Введите запрос для поиска POI</string>
@ -123,7 +130,7 @@
<string name="route_general_information">Общая протяженность = {0}, время в пути = {1} ч. {2} мин.</string>
<string name="router_service_descr">Выберите сервис для прокладки маршрута</string>
<string name="router_service">Прокладка маршрута</string>
<string name="download_sd_dir_not_accessible">Директория на SD карточка не доступна для сохранения</string>
<string name="sd_dir_not_accessible">Директория на SD карточке не доступна для сохранения</string>
<string name="download_question">Вы хотите загрузить {0} - {1} ?</string>
<string name="download_question_exist">Индекс для {0} уже существует ({1}). Вы хотите его обновить ({2}) ?</string>
<string name="address">Адрес</string>

View file

@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="fav_imported_sucessfully">Favorite points were succesfully imported</string>
<string name="fav_file_to_load_not_found">GPX file to load favorite points is not found at {0}</string>
<string name="fav_saved_sucessfully">Favorite points were succesfully saved to {0}</string>
<string name="no_fav_to_save">No favorite points to save</string>
<string name="import_fav">Import</string>
<string name="export_fav">Export</string>
<string name="error_occurred_loading_gpx">Error occurred while loading gpx</string>
<string name="send_report">Send report</string>
<string name="none_region_found">None region were found on SD card. Try to download region from internet.</string>
<string name="poi_namefinder_query_empty">Input search query to find POI</string>
@ -123,7 +130,7 @@
<string name="route_general_information">Overall distance = {0}, travelling time = {1} h {2} m.</string>
<string name="router_service_descr">Choose routing service</string>
<string name="router_service">Routing</string>
<string name="download_sd_dir_not_accessible">Directory on SD card to save index is not accessible</string>
<string name="sd_dir_not_accessible">Directory on SD card to save is not accessible</string>
<string name="download_question">Do you want to download {0} - {1} ?</string>
<string name="download_question_exist">Index for {0} already exists ({1}). Do you want to update it ({2}) ?</string>
<string name="address">Address</string>

View file

@ -169,7 +169,7 @@ public class DownloadIndexActivity extends ListActivity {
parent.mkdirs();
}
if(parent == null || !parent.exists()){
Toast.makeText(DownloadIndexActivity.this, getString(R.string.download_sd_dir_not_accessible), Toast.LENGTH_LONG).show();
Toast.makeText(DownloadIndexActivity.this, getString(R.string.sd_dir_not_accessible), Toast.LENGTH_LONG).show();
return null;
}
File file = new File(parent, regionName);

View file

@ -3,9 +3,12 @@
*/
package com.osmand.activities;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import android.app.AlertDialog;
import android.app.ListActivity;
@ -18,8 +21,10 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.os.Environment;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@ -34,6 +39,8 @@ import android.widget.AdapterView.AdapterContextMenuInfo;
import com.osmand.OsmandSettings;
import com.osmand.R;
import com.osmand.ResourceManager;
import com.osmand.activities.SavingTrackHelper.WptPt;
import com.osmand.osm.LatLon;
import com.osmand.osm.MapUtils;
@ -46,6 +53,11 @@ public class FavouritesActivity extends ListActivity {
public static final int DELETE_ITEM = 1;
public static final int EDIT_ITEM = 2;
public static final int EXPORT_ID = 0;
public static final int IMPORT_ID = 1;
public static final String FILE_TO_SAVE = "favourites.gpx"; //$NON-NLS-1$
private List<FavouritePoint> favouritesList;
private FavouritesDbHelper helper;
@ -89,12 +101,12 @@ public class FavouritesActivity extends ListActivity {
public boolean onContextItemSelected(MenuItem aItem) {
AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) aItem.getMenuInfo();
final FavouritePoint point = (FavouritePoint) favouritesList.get(menuInfo.position);
if(aItem.getItemId() == NAVIGATE_TO){
// OsmandSettings.setMapLocationToShow(this, point.getLatitude(), point.getLongitude(), getString(R.string.favorite)+" : " + point.getName()); //$NON-NLS-1$
if (aItem.getItemId() == NAVIGATE_TO) {
//OsmandSettings.setMapLocationToShow(this, point.getLatitude(), point.getLongitude(), getString(R.string.favorite)+" : " + point.getName()); //$NON-NLS-1$
OsmandSettings.setPointToNavigate(this, point.getLatitude(), point.getLongitude());
Intent newIntent = new Intent(FavouritesActivity.this, MapActivity.class);
startActivity(newIntent);
} else if(aItem.getItemId() == EDIT_ITEM){
} else if (aItem.getItemId() == EDIT_ITEM) {
Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.favourites_edit_dialog_title);
final EditText editText = new EditText(this);
@ -113,7 +125,8 @@ public class FavouritesActivity extends ListActivity {
});
builder.create().show();
return true;
} if(aItem.getItemId() == DELETE_ITEM){
}
if (aItem.getItemId() == DELETE_ITEM) {
final Resources resources = this.getResources();
Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.favourites_remove_dialog_title);
@ -123,7 +136,8 @@ public class FavouritesActivity extends ListActivity {
public void onClick(DialogInterface dialog, int which) {
boolean deleted = helper.deleteFavourite(point);
if (deleted) {
Toast.makeText(FavouritesActivity.this, MessageFormat.format(resources.getString(R.string.favourites_remove_dialog_success), point.getName()),
Toast.makeText(FavouritesActivity.this,
MessageFormat.format(resources.getString(R.string.favourites_remove_dialog_success), point.getName()),
Toast.LENGTH_SHORT).show();
favouritesList.remove(point);
favouritesAdapter.notifyDataSetChanged();
@ -137,6 +151,73 @@ public class FavouritesActivity extends ListActivity {
return false;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuItem item = menu.add(0, EXPORT_ID, 0, R.string.export_fav);
item.setIcon(android.R.drawable.ic_menu_save);
item = menu.add(0, IMPORT_ID, 0, R.string.import_fav);
item.setIcon(android.R.drawable.ic_menu_upload);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == EXPORT_ID){
File appDir = new File(Environment.getExternalStorageDirectory(), ResourceManager.APP_DIR);
if(favouritesList == null || favouritesList.isEmpty()){
Toast.makeText(this, R.string.no_fav_to_save, Toast.LENGTH_LONG).show();
} else if(!appDir.exists()){
Toast.makeText(this, R.string.sd_dir_not_accessible, Toast.LENGTH_LONG).show();
} else {
File f = new File(appDir, FILE_TO_SAVE);
List<WptPt> wpt = new ArrayList<WptPt>();
for(FavouritePoint p : favouritesList){
WptPt pt = new WptPt();
pt.lat = p.latitude;
pt.lon = p.longitude;
pt.name = p.name;
wpt.add(pt);
}
if(SavingTrackHelper.saveToXMLFiles(f, wpt, this)){
Toast.makeText(this, MessageFormat.format(getString(R.string.fav_saved_sucessfully), f.getAbsolutePath()),
Toast.LENGTH_LONG).show();
}
}
} else if(item.getItemId() == IMPORT_ID){
File appDir = new File(Environment.getExternalStorageDirectory(), ResourceManager.APP_DIR);
File f = new File(appDir, FILE_TO_SAVE);
if(!f.exists()){
Toast.makeText(this, MessageFormat.format(getString(R.string.fav_file_to_load_not_found), f.getAbsolutePath()), Toast.LENGTH_LONG).show();
} else {
Set<String> existedPoints = new LinkedHashSet<String>();
if(favouritesList != null){
for(FavouritePoint fp : favouritesList){
existedPoints.add(fp.name);
}
}
List<WptPt> points = new ArrayList<WptPt>();
if(SavingTrackHelper.readWptPtFromFile(f, points, this)){
for(WptPt p : points){
if(!existedPoints.contains(p.name)){
FavouritePoint fp = new FavouritePoint();
fp.name = p.name;
fp.latitude = p.lat;
fp.longitude = p.lon;
helper.addFavourite(fp);
favouritesList.add(fp);
}
}
Toast.makeText(this, R.string.fav_imported_sucessfully, Toast.LENGTH_SHORT).show();
favouritesAdapter.notifyDataSetChanged();
}
}
} else {
return false;
}
return true;
}
public static class FavouritesDbHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;

View file

@ -16,6 +16,8 @@ import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -33,6 +35,7 @@ import com.osmand.LogUtil;
import com.osmand.ProgressDialogImplementation;
import com.osmand.R;
import com.osmand.ResourceManager;
import com.osmand.Version;
import com.osmand.activities.search.SearchActivity;
import com.osmand.voice.CommandPlayer;
@ -112,6 +115,14 @@ public class MainMenuActivity extends Activity {
text.append("\nProduct : ").append(Build.PRODUCT); //$NON-NLS-1$
text.append("\nBuild : ").append(Build.DISPLAY); //$NON-NLS-1$
text.append("\nVersion : ").append(Build.VERSION.RELEASE); //$NON-NLS-1$
text.append("\nApp Version : ").append(Version.APP_NAME_VERSION); //$NON-NLS-1$
try {
PackageInfo info = getPackageManager().getPackageInfo(getPackageResourcePath(), 0);
if (info != null) {
text.append("\nApk Version : ").append(info.versionName).append(" ").append(info.versionCode); //$NON-NLS-1$ //$NON-NLS-2$
}
} catch (NameNotFoundException e) {
}
intent.putExtra(Intent.EXTRA_TEXT, text.toString());
startActivity(Intent.createChooser(intent, getString(R.string.send_report)));
}

View file

@ -1,6 +1,7 @@
package com.osmand.activities;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
@ -11,6 +12,8 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import android.content.Context;
@ -64,7 +67,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
private static class TrkPt {
public static class TrkPt {
public double lat;
public double lon;
public double ele;
@ -72,8 +75,99 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
public long time;
}
public static class WptPt {
public double lat;
public double lon;
public String name;
}
protected void saveToXMLFiles(File dir, Map<String, List<List<TrkPt>>> data ){
public static boolean readWptPtFromFile(File fout, List<WptPt> readTo, Context ctx){
try {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new FileInputStream(fout), "UTF-8"); //$NON-NLS-1$
int tok;
WptPt current = null;
while((tok=parser.next()) != XmlPullParser.END_DOCUMENT){
if(tok == XmlPullParser.START_TAG){
if(parser.getName().equals("wpt")){ //$NON-NLS-1$
try {
current = new WptPt();
current.lat = Double.parseDouble(parser.getAttributeValue("", "lat")); //$NON-NLS-1$ //$NON-NLS-2$
current.lon = Double.parseDouble(parser.getAttributeValue("", "lon")); //$NON-NLS-1$ //$NON-NLS-2$
} catch (NumberFormatException e) {
current= null;
}
} else if(current != null && parser.getName().equals("name")){ //$NON-NLS-1$
if(parser.next() == XmlPullParser.TEXT){
current.name = parser.getText();
}
}
} else if(tok == XmlPullParser.END_TAG){
if(parser.getName().equals("wpt")){ //$NON-NLS-1$
if(current != null && current.name != null){
readTo.add(current);
}
current = null;
}
}
}
return true;
} catch (IOException e) {
log.error("Error loading gpx", e); //$NON-NLS-1$
Toast.makeText(ctx, ctx.getString(R.string.error_occurred_loading_gpx), Toast.LENGTH_LONG).show();
return false;
} catch (XmlPullParserException e) {
log.error("Error loading gpx", e); //$NON-NLS-1$
Toast.makeText(ctx, ctx.getString(R.string.error_occurred_loading_gpx), Toast.LENGTH_LONG).show();
return false;
}
}
public static boolean saveToXMLFiles(File fout, List<WptPt> data, Context ctx ){
try {
FileOutputStream output = new FileOutputStream(fout);
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(output, "UTF-8"); //$NON-NLS-1$
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); //$NON-NLS-1$
serializer.startDocument("UTF-8", true); //$NON-NLS-1$
serializer.startTag(null, "gpx"); //$NON-NLS-1$
serializer.attribute(null, "version", "1.1"); //$NON-NLS-1$ //$NON-NLS-2$
serializer.attribute(null, "creator", Version.APP_NAME_VERSION); //$NON-NLS-1$
serializer.attribute("xmlns", "xsi", "http://www.w3.org/2001/XMLSchema-instance"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
serializer.attribute("xsi", "schemaLocation", "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
serializer.attribute(null, "xmlns", "http://www.topografix.com/GPX/1/1"); //$NON-NLS-1$ //$NON-NLS-2$
for (WptPt l : data) {
serializer.startTag(null, "wpt"); //$NON-NLS-1$
serializer.attribute(null, "lat", l.lat + ""); //$NON-NLS-1$ //$NON-NLS-2$
serializer.attribute(null, "lon", l.lon + ""); //$NON-NLS-1$ //$NON-NLS-2$
serializer.startTag(null, "name"); //$NON-NLS-1$
serializer.text(l.name);
serializer.endTag(null, "name"); //$NON-NLS-1$
serializer.endTag(null, "wpt"); //$NON-NLS-1$
}
serializer.endTag(null, "gpx"); //$NON-NLS-1$
serializer.flush();
serializer.endDocument();
return true;
} catch (RuntimeException e) {
log.error("Error saving gpx", e); //$NON-NLS-1$
Toast.makeText(ctx, ctx.getString(R.string.error_occurred_saving_gpx), Toast.LENGTH_LONG).show();
return false;
} catch (IOException e) {
log.error("Error saving gpx", e); //$NON-NLS-1$
Toast.makeText(ctx, ctx.getString(R.string.error_occurred_saving_gpx), Toast.LENGTH_LONG).show();
return false;
}
}
public static void saveToXMLFiles(File dir, Map<String, List<List<TrkPt>>> data, Context ctx){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); //$NON-NLS-1$
try {
for (String f : data.keySet()) {
@ -127,10 +221,10 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
}
} catch (RuntimeException e) {
log.error("Error saving gpx", e); //$NON-NLS-1$
Toast.makeText(ctx, ctx.getString(R.string.error_occurred_saving_gpx), Toast.LENGTH_LONG);
Toast.makeText(ctx, ctx.getString(R.string.error_occurred_saving_gpx), Toast.LENGTH_LONG).show();
} catch (IOException e) {
log.error("Error saving gpx", e); //$NON-NLS-1$
Toast.makeText(ctx, ctx.getString(R.string.error_occurred_saving_gpx), Toast.LENGTH_LONG);
Toast.makeText(ctx, ctx.getString(R.string.error_occurred_saving_gpx), Toast.LENGTH_LONG).show();
}
}
@ -199,7 +293,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
} while (query.moveToNext());
}
query.close();
saveToXMLFiles(file, data);
saveToXMLFiles(file, data, ctx);
}
}