Implement GPX explorer. Issue 514
This commit is contained in:
parent
0297beee77
commit
b7c38b27a9
6 changed files with 166 additions and 41 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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$
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue