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;
}
/**
* 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"?>
<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_items_backuped">%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="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="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_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>

View file

@ -7,6 +7,7 @@ import java.io.IOException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@ -146,10 +147,23 @@ public class GPXUtilities {
// such as wpt. However they provide additional information into gpx.
public boolean cloudMadeFile;
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){
GPXFileResult res = new GPXFileResult();
SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
boolean cloudMade = false;
XmlPullParser parser = Xml.newPullParser();
@ -175,13 +189,35 @@ public class GPXUtilities {
current.setLongitude(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) {
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) {
if (parser.getName().equals("wpt") || //$NON-NLS-1$
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.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
@ -14,6 +13,7 @@ import java.util.Set;
import java.util.TreeSet;
import net.osmand.GPXUtilities;
import net.osmand.OsmAndFormatter;
import net.osmand.GPXUtilities.GPXFileResult;
import net.osmand.binary.BinaryIndexPart;
import net.osmand.binary.BinaryMapIndexReader;
@ -34,6 +34,7 @@ import net.osmand.plus.voice.MediaCommandPlayerImpl;
import net.osmand.plus.voice.TTSCommandPlayerImpl;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.location.Location;
import android.os.Build;
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())});
}
@SuppressWarnings("unchecked")
public void updateDescription(LocalIndexInfo info){
File f = new File(info.getPathToData());
if(info.getType() == LocalIndexType.MAP_DATA){
@ -63,18 +63,7 @@ public class LocalIndexHelper {
} else if(info.getType() == LocalIndexType.POI_DATA){
info.setDescription(getInstalledDate(f));
} else if(info.getType() == LocalIndexType.GPX_DATA){
GPXFileResult result = GPXUtilities.loadGPXFile(app, 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()));
}
updateGpxInfo(info, f);
} else if(info.getType() == LocalIndexType.VOICE_DATA){
info.setDescription(getInstalledDate(f));
} 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){
OsmandSettings settings = OsmandSettings.getOsmandSettings(app.getApplicationContext());
@ -165,8 +235,6 @@ public class LocalIndexHelper {
if(!TileSourceManager.isTileSourceMetaInfoExist(tileFile)){
info.setCorrupted(true);
} else {
// updateTileSourceInfo(tileFile, info);
}
result.add(info);
loadTask.loadFile(info);
@ -321,6 +389,8 @@ public class LocalIndexHelper {
// UI state expanded
private boolean expanded;
private GPXFileResult gpxFile;
public LocalIndexInfo(LocalIndexType type, File f, boolean backuped){
pathToData = f.getAbsolutePath();
fileName = f.getName();
@ -362,6 +432,14 @@ public class LocalIndexHelper {
this.kbSize = size;
}
public void setGpxFile(GPXFileResult gpxFile) {
this.gpxFile = gpxFile;
}
public GPXFileResult getGpxFile() {
return gpxFile;
}
public boolean isExpanded() {
return expanded;
}

View file

@ -10,6 +10,7 @@ import java.util.Map;
import java.util.Set;
import net.osmand.Algoritms;
import net.osmand.FavouritePoint;
import net.osmand.IProgress;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
@ -24,15 +25,18 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.AsyncTask.Status;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
@ -40,6 +44,8 @@ import android.widget.CheckBox;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
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);
}
@ -263,6 +287,7 @@ public class LocalIndexesActivity extends ExpandableListActivity {
return true;
}
@Override
protected void onPause() {
super.onPause();