Implement GPX explorer. Issue 514

This commit is contained in:
Victor Shcherb 2011-08-21 15:15:57 +02:00
parent 0297beee77
commit b7c38b27a9
6 changed files with 166 additions and 41 deletions

View file

@ -413,28 +413,6 @@ public class MapUtils {
return rotate; return rotate;
} }
/**
* Serializes entity without id
*/
public static String serializeEntityPlainString(Entity e){
for(Entry<String, String> es : e.getTags().entrySet()) {
// TODO
}
return null;
}
/**
* Serializes entity without id
*/
public static Entity derializeEntityPlainString(String value, long id, EntityType t, boolean skipIfEmptyTags){
if(t == EntityType.NODE){
} else {
// TODO
}
return null;
}
} }

View file

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="local_index_gpx_info">Путей : %1$d\nВсего точек : %2$d\nОтмечено точек : %3$d</string> <string name="local_index_gpx_info_show">\n\nДлинное нажатие для просмотра на карте</string>
<string name="local_index_gpx_info_speed">\nСредняя скорость : %1$s \nМаксимальная скорость : %2$s</string>
<string name="local_index_gpx_info_elevation">Средняя высота : %1$.0f метров\nПодъем вверх : %2$.0f метров\nПодъем вниз : %2$.0f метров</string>
<string name="local_index_gpx_info">Путей : %1$d\nВсего точек : %2$d\nОтмечено точек : %3$d\nВсего расстояние : %4$s
\nНачало : %5$tD %5$tR\nОкончание : %6$tD %6$tR\n</string>
<string name="local_index_installed">Установлено</string> <string name="local_index_installed">Установлено</string>
<string name="local_index_items_backuped">%1$d из %2$d объектов успешно архивированы.</string> <string name="local_index_items_backuped">%1$d из %2$d объектов успешно архивированы.</string>
<string name="local_index_items_deleted">%1$d из %2$d объектов успешно удалены.</string> <string name="local_index_items_deleted">%1$d из %2$d объектов успешно удалены.</string>

View file

@ -3,7 +3,11 @@
<string name="vector_map_not_needed">Not needed</string> <string name="vector_map_not_needed">Not needed</string>
<string name="basemap_missing">Base world map is missing. Please consider to download it in order to have proper environment.</string> <string name="basemap_missing">Base world map is missing. Please consider to download it in order to have proper environment.</string>
<string name="vector_data_missing">On board data is missing on SD card. Please consider to download it in order to use maps offline.</string> <string name="vector_data_missing">On board data is missing on SD card. Please consider to download it in order to use maps offline.</string>
<string name="local_index_gpx_info">Subtracks : %1$d\nTotal Points : %2$d\nWay points : %3$d</string> <string name="local_index_gpx_info_show">\n\nLong click to show on map</string>
<string name="local_index_gpx_info_speed">\nAverage speed : %1$s \nMaximum speed : %2$s</string>
<string name="local_index_gpx_info_elevation">\nAverage altitude : %1$.0f meters\nElevation up : %2$.0f meters\nElevation down : %3$.0f meters</string>
<string name="local_index_gpx_info">Subtracks : %1$d\nTotal Points : %2$d\nWay points : %3$d\nTotal Distance : %4$s
\nStart Time : %5$tD %5$tR\nEnd Time : %6$tD %6$tR</string>
<string name="local_index_installed">Installed</string> <string name="local_index_installed">Installed</string>
<string name="local_index_items_backuped">%1$d items of %2$d succesfully backed up.</string> <string name="local_index_items_backuped">%1$d items of %2$d succesfully backed up.</string>
<string name="local_index_items_deleted">%1$d items of %2$d succesfully deleted.</string> <string name="local_index_items_deleted">%1$d items of %2$d succesfully deleted.</string>

View file

@ -7,6 +7,7 @@ import java.io.IOException;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols; import java.text.DecimalFormatSymbols;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -146,10 +147,23 @@ public class GPXUtilities {
// such as wpt. However they provide additional information into gpx. // such as wpt. However they provide additional information into gpx.
public boolean cloudMadeFile; public boolean cloudMadeFile;
public String error; public String error;
public Location findFistLocation(){
for(List<Location> l : locations){
for(Location ls : l){
if(ls != null){
return ls;
}
}
}
return null;
}
} }
public static GPXFileResult loadGPXFile(Context ctx, File f){ public static GPXFileResult loadGPXFile(Context ctx, File f){
GPXFileResult res = new GPXFileResult(); GPXFileResult res = new GPXFileResult();
SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
try { try {
boolean cloudMade = false; boolean cloudMade = false;
XmlPullParser parser = Xml.newPullParser(); XmlPullParser parser = Xml.newPullParser();
@ -175,13 +189,35 @@ public class GPXUtilities {
current.setLongitude(Double.parseDouble(parser.getAttributeValue("", "lon"))); //$NON-NLS-1$ //$NON-NLS-2$ current.setLongitude(Double.parseDouble(parser.getAttributeValue("", "lon"))); //$NON-NLS-1$ //$NON-NLS-2$
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
current = null; current = null;
} }
} else if (current != null && parser.getName().equals("name")) { //$NON-NLS-1$ } else if (current != null && parser.getName().equals("name")) { //$NON-NLS-1$
if (parser.next() == XmlPullParser.TEXT) { if (parser.next() == XmlPullParser.TEXT) {
currentName = parser.getText(); currentName = parser.getText();
} }
} else if (current != null && parser.getName().equals("time")) { //$NON-NLS-1$
if (parser.next() == XmlPullParser.TEXT) {
try {
current.setTime(format.parse(parser.getText()).getTime());
} catch (ParseException e) {
}
}
} else if (current != null && parser.getName().equals("ele")) { //$NON-NLS-1$
if (parser.next() == XmlPullParser.TEXT) {
try {
current.setAltitude(Double.parseDouble(parser.getText()));
} catch (NumberFormatException e) {
}
}
} else if (current != null && parser.getName().equals("speed")) { //$NON-NLS-1$
if (parser.next() == XmlPullParser.TEXT) {
try {
current.setSpeed(Float.parseFloat(parser.getText()));
} catch (NumberFormatException e) {
}
}
} }
} else if (tok == XmlPullParser.END_TAG) { } else if (tok == XmlPullParser.END_TAG) {
if (parser.getName().equals("wpt") || //$NON-NLS-1$ if (parser.getName().equals("wpt") || //$NON-NLS-1$
parser.getName().equals("trkpt") || (!cloudMade && parser.getName().equals("rtept"))) { //$NON-NLS-1$ //$NON-NLS-2$ parser.getName().equals("trkpt") || (!cloudMade && parser.getName().equals("rtept"))) { //$NON-NLS-1$ //$NON-NLS-2$

View file

@ -5,7 +5,6 @@ import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -14,6 +13,7 @@ import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import net.osmand.GPXUtilities; import net.osmand.GPXUtilities;
import net.osmand.OsmAndFormatter;
import net.osmand.GPXUtilities.GPXFileResult; import net.osmand.GPXUtilities.GPXFileResult;
import net.osmand.binary.BinaryIndexPart; import net.osmand.binary.BinaryIndexPart;
import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader;
@ -34,6 +34,7 @@ import net.osmand.plus.voice.MediaCommandPlayerImpl;
import net.osmand.plus.voice.TTSCommandPlayerImpl; import net.osmand.plus.voice.TTSCommandPlayerImpl;
import android.content.Context; import android.content.Context;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.location.Location;
import android.os.Build; import android.os.Build;
public class LocalIndexHelper { public class LocalIndexHelper {
@ -54,7 +55,6 @@ public class LocalIndexHelper {
return app.getString(R.string.local_index_installed) + " : " + dateformat.format(new Object[]{new Date(f.lastModified())}); return app.getString(R.string.local_index_installed) + " : " + dateformat.format(new Object[]{new Date(f.lastModified())});
} }
@SuppressWarnings("unchecked")
public void updateDescription(LocalIndexInfo info){ public void updateDescription(LocalIndexInfo info){
File f = new File(info.getPathToData()); File f = new File(info.getPathToData());
if(info.getType() == LocalIndexType.MAP_DATA){ if(info.getType() == LocalIndexType.MAP_DATA){
@ -63,18 +63,7 @@ public class LocalIndexHelper {
} else if(info.getType() == LocalIndexType.POI_DATA){ } else if(info.getType() == LocalIndexType.POI_DATA){
info.setDescription(getInstalledDate(f)); info.setDescription(getInstalledDate(f));
} else if(info.getType() == LocalIndexType.GPX_DATA){ } else if(info.getType() == LocalIndexType.GPX_DATA){
GPXFileResult result = GPXUtilities.loadGPXFile(app, f); updateGpxInfo(info, f);
if(result.error != null){
info.setCorrupted(true);
info.setDescription(result.error);
} else {
int points = 0;
for(int i =0; i< result.locations.size() ; i++){
points += result.locations.get(i).size();
}
info.setDescription(app.getString(R.string.local_index_gpx_info, result.locations.size(), points,
result.wayPoints.size()));
}
} else if(info.getType() == LocalIndexType.VOICE_DATA){ } else if(info.getType() == LocalIndexType.VOICE_DATA){
info.setDescription(getInstalledDate(f)); info.setDescription(getInstalledDate(f));
} else if(info.getType() == LocalIndexType.TTS_VOICE_DATA){ } else if(info.getType() == LocalIndexType.TTS_VOICE_DATA){
@ -109,6 +98,87 @@ public class LocalIndexHelper {
} }
} }
} }
private void updateGpxInfo(LocalIndexInfo info, File f) {
if(info.getGpxFile() == null){
info.setGpxFile(GPXUtilities.loadGPXFile(app, f));
}
GPXFileResult result = info.getGpxFile();
if(result.error != null){
info.setCorrupted(true);
info.setDescription(result.error);
} else {
int totalDistance = 0;
long startTime = Long.MAX_VALUE;
long endTime = Long.MIN_VALUE;
double diffElevationUp = 0;
double diffElevationDown = 0;
double totalElevation = 0;
float maxSpeed = 0;
int speedCount = 0;
double totalSpeedSum = 0;
int points = 0;
for(int i = 0; i< result.locations.size() ; i++){
List<Location> subtrack = result.locations.get(i);
points += subtrack.size();
int distance = 0;
for (int j = 0; j < subtrack.size(); j++) {
long time = subtrack.get(j).getTime();
if(time != 0){
startTime = Math.min(startTime, time);
endTime = Math.max(startTime, time);
}
float speed = subtrack.get(j).getSpeed();
if(speed > 0){
totalSpeedSum += speed;
maxSpeed = Math.max(speed, maxSpeed);
speedCount ++;
}
totalElevation += subtrack.get(j).getAltitude();
if (j > 0) {
double diff = subtrack.get(j).getAltitude() - subtrack.get(j - 1).getAltitude();
if(diff > 0){
diffElevationUp += diff;
} else {
diffElevationDown -= diff;
}
distance += MapUtils.getDistance(subtrack.get(j - 1).getLatitude(), subtrack.get(j - 1).getLongitude(), subtrack
.get(j).getLatitude(), subtrack.get(j).getLongitude());
}
}
totalDistance += distance;
}
if(startTime == Long.MAX_VALUE){
startTime = f.lastModified();
}
if(endTime == Long.MIN_VALUE){
endTime = f.lastModified();
}
info.setDescription(app.getString(R.string.local_index_gpx_info, result.locations.size(), points,
result.wayPoints.size(), OsmAndFormatter.getFormattedDistance(totalDistance, app),
startTime, endTime));
if(totalElevation != 0 || diffElevationUp != 0 || diffElevationDown != 0){
info.setDescription(info.getDescription() +
app.getString(R.string.local_index_gpx_info_elevation,
totalElevation / points, diffElevationUp, diffElevationDown));
}
if(speedCount > 0){
info.setDescription(info.getDescription() +
app.getString(R.string.local_index_gpx_info_speed,
OsmAndFormatter.getFormattedSpeed((float) (totalSpeedSum / speedCount), app),
OsmAndFormatter.getFormattedSpeed(maxSpeed, app)));
}
info.setDescription(info.getDescription() +
app.getString(R.string.local_index_gpx_info_show));
}
}
public List<LocalIndexInfo> getLocalIndexData(LocalIndexType type, LoadLocalIndexTask loadTask){ public List<LocalIndexInfo> getLocalIndexData(LocalIndexType type, LoadLocalIndexTask loadTask){
OsmandSettings settings = OsmandSettings.getOsmandSettings(app.getApplicationContext()); OsmandSettings settings = OsmandSettings.getOsmandSettings(app.getApplicationContext());
@ -165,8 +235,6 @@ public class LocalIndexHelper {
if(!TileSourceManager.isTileSourceMetaInfoExist(tileFile)){ if(!TileSourceManager.isTileSourceMetaInfoExist(tileFile)){
info.setCorrupted(true); info.setCorrupted(true);
} else {
// updateTileSourceInfo(tileFile, info);
} }
result.add(info); result.add(info);
loadTask.loadFile(info); loadTask.loadFile(info);
@ -321,6 +389,8 @@ public class LocalIndexHelper {
// UI state expanded // UI state expanded
private boolean expanded; private boolean expanded;
private GPXFileResult gpxFile;
public LocalIndexInfo(LocalIndexType type, File f, boolean backuped){ public LocalIndexInfo(LocalIndexType type, File f, boolean backuped){
pathToData = f.getAbsolutePath(); pathToData = f.getAbsolutePath();
fileName = f.getName(); fileName = f.getName();
@ -362,6 +432,14 @@ public class LocalIndexHelper {
this.kbSize = size; this.kbSize = size;
} }
public void setGpxFile(GPXFileResult gpxFile) {
this.gpxFile = gpxFile;
}
public GPXFileResult getGpxFile() {
return gpxFile;
}
public boolean isExpanded() { public boolean isExpanded() {
return expanded; return expanded;
} }

View file

@ -10,6 +10,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import net.osmand.Algoritms; import net.osmand.Algoritms;
import net.osmand.FavouritePoint;
import net.osmand.IProgress; import net.osmand.IProgress;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -24,15 +25,18 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.location.Location;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.AsyncTask.Status; import android.os.AsyncTask.Status;
import android.view.ContextMenu;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.BaseExpandableListAdapter; import android.widget.BaseExpandableListAdapter;
import android.widget.Button; import android.widget.Button;
@ -40,6 +44,8 @@ import android.widget.CheckBox;
import android.widget.ExpandableListView; import android.widget.ExpandableListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
public class LocalIndexesActivity extends ExpandableListActivity { public class LocalIndexesActivity extends ExpandableListActivity {
@ -74,6 +80,24 @@ public class LocalIndexesActivity extends ExpandableListActivity {
} }
}); });
getExpandableListView().setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
long packedPos = ((ExpandableListContextMenuInfo)menuInfo).packedPosition;
final LocalIndexInfo point = (LocalIndexInfo) listAdapter.getChild(ExpandableListView.getPackedPositionGroup(packedPos),
ExpandableListView.getPackedPositionChild(packedPos));
if(point.getGpxFile() != null){
Location loc = point.getGpxFile().findFistLocation();
if(loc != null){
OsmandSettings.getOsmandSettings(LocalIndexesActivity.this).setMapLocationToShow(loc.getLatitude(),loc.getLongitude());
}
((OsmandApplication) getApplication()).setGpxFileToDisplay(point.getGpxFile());
MapActivity.launchMapActivityMoveToTop(LocalIndexesActivity.this);
}
}
});
setListAdapter(listAdapter); setListAdapter(listAdapter);
} }
@ -263,6 +287,7 @@ public class LocalIndexesActivity extends ExpandableListActivity {
return true; return true;
} }
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();