Implement new GPX reader. Fix issue with cloudmade GPX files navigation
This commit is contained in:
commit
5059ae6238
12 changed files with 628 additions and 367 deletions
|
@ -2,7 +2,7 @@
|
|||
<resources>
|
||||
<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">\nСредняя высота : %1$.0f метров\nМинимальная высота : %2$.0f метров\Максимальная высота : %3$.0f метров\nПодъем вверх : %4$.0f метров\nПодъем вниз : %5$.0f метров</string>
|
||||
<string name="local_index_gpx_info_elevation">\nСредняя высота : %1$.0f метров\nМинимальная высота : %2$.0f метров\nМаксимальная высота : %3$.0f метров\nПодъем вверх : %4$.0f метров\nПодъем вниз : %5$.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>
|
||||
|
|
|
@ -2,17 +2,23 @@ package net.osmand;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
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.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
|
@ -28,16 +34,35 @@ import android.util.Xml;
|
|||
|
||||
public class GPXUtilities {
|
||||
public final static Log log = LogUtil.getLog(GPXUtilities.class);
|
||||
|
||||
|
||||
|
||||
private final static String GPX_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; //$NON-NLS-1$
|
||||
|
||||
private final static NumberFormat latLonFormat = new DecimalFormat("0.00#####", new DecimalFormatSymbols(Locale.US));
|
||||
|
||||
public static class WptPt {
|
||||
public static class GPXExtensions {
|
||||
Map<String, String> extensions = null;
|
||||
|
||||
public Map<String, String> getExtensionsToRead() {
|
||||
if(extensions == null){
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return extensions;
|
||||
}
|
||||
|
||||
public Map<String, String> getExtensionsToWrite() {
|
||||
if(extensions == null){
|
||||
extensions = new LinkedHashMap<String, String>();
|
||||
}
|
||||
return extensions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class WptPt extends GPXExtensions {
|
||||
public double lat;
|
||||
public double lon;
|
||||
public String name = null;
|
||||
public String desc = null;
|
||||
// by default
|
||||
public long time = 0;
|
||||
public double ele = Double.NaN;
|
||||
|
@ -45,17 +70,55 @@ public class GPXUtilities {
|
|||
public double hdop = Double.NaN;
|
||||
}
|
||||
|
||||
public static class TrkSegment {
|
||||
|
||||
public static class TrkSegment extends GPXExtensions {
|
||||
public List<WptPt> points = new ArrayList<WptPt>();
|
||||
}
|
||||
|
||||
public static class Track {
|
||||
public static class Track extends GPXExtensions {
|
||||
public String name = null;
|
||||
public String desc = null;
|
||||
public List<TrkSegment> segments = new ArrayList<TrkSegment>();
|
||||
}
|
||||
|
||||
public static class GPXFile {
|
||||
public static class Route extends GPXExtensions {
|
||||
public String name = null;
|
||||
public String desc = null;
|
||||
public List<WptPt> points = new ArrayList<WptPt>();
|
||||
}
|
||||
|
||||
public static class GPXFile extends GPXExtensions {
|
||||
public String author;
|
||||
public List<Track> tracks = new ArrayList<Track>();
|
||||
public List<WptPt> points = new ArrayList<WptPt>();
|
||||
public List<Route> routes = new ArrayList<Route>();
|
||||
public String warning = null;
|
||||
|
||||
public boolean isCloudmadeRouteFile(){
|
||||
return "cloudmade".equalsIgnoreCase(author);
|
||||
}
|
||||
|
||||
public WptPt findPointToShow(){
|
||||
for(Track t : tracks){
|
||||
for(TrkSegment s : t.segments){
|
||||
if(s.points.size() > 0){
|
||||
return s.points.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Route s : routes) {
|
||||
if (s.points.size() > 0) {
|
||||
return s.points.get(0);
|
||||
}
|
||||
}
|
||||
if (points.size() > 0) {
|
||||
return points.get(0);
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,7 +133,11 @@ public class GPXUtilities {
|
|||
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$
|
||||
if(file.author == null ){
|
||||
serializer.attribute(null, "creator", Version.APP_NAME_VERSION); //$NON-NLS-1$
|
||||
} else {
|
||||
serializer.attribute(null, "creator", file.author); //$NON-NLS-1$
|
||||
}
|
||||
serializer.attribute(null, "xmlns", "http://www.topografix.com/GPX/1/1"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
serializer.attribute(null, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
|
||||
serializer.attribute(null, "xsi:schemaLocation", "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd");
|
||||
|
@ -78,31 +145,38 @@ public class GPXUtilities {
|
|||
|
||||
for (Track track : file.tracks) {
|
||||
serializer.startTag(null, "trk"); //$NON-NLS-1$
|
||||
writeNotNullText(serializer, "name", track.name);
|
||||
writeNotNullText(serializer, "desc", track.desc);
|
||||
for (TrkSegment segment : track.segments) {
|
||||
serializer.startTag(null, "trkseg"); //$NON-NLS-1$
|
||||
for (WptPt p : segment.points) {
|
||||
serializer.startTag(null, "trkpt"); //$NON-NLS-1$
|
||||
writeWpt(format, serializer, p);
|
||||
|
||||
serializer.endTag(null, "trkpt"); //$NON-NLS-1$
|
||||
}
|
||||
serializer.endTag(null, "trkseg"); //$NON-NLS-1$
|
||||
}
|
||||
writeExtensions(serializer, track);
|
||||
serializer.endTag(null, "trk"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
for (Route track : file.routes) {
|
||||
serializer.startTag(null, "rte"); //$NON-NLS-1$
|
||||
writeNotNullText(serializer, "name", track.name);
|
||||
writeNotNullText(serializer, "desc", track.desc);
|
||||
|
||||
for (WptPt p : track.points) {
|
||||
serializer.startTag(null, "rtept"); //$NON-NLS-1$
|
||||
writeWpt(format, serializer, p);
|
||||
serializer.endTag(null, "rtept"); //$NON-NLS-1$
|
||||
}
|
||||
writeExtensions(serializer, track);
|
||||
serializer.endTag(null, "rte"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
for (WptPt l : file.points) {
|
||||
serializer.startTag(null, "wpt"); //$NON-NLS-1$
|
||||
serializer.attribute(null, "lat", latLonFormat.format(l.lat)); //$NON-NLS-1$
|
||||
serializer.attribute(null, "lon", latLonFormat.format(l.lon)); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
if (l.time != 0) {
|
||||
serializer.startTag(null, "time"); //$NON-NLS-1$
|
||||
serializer.text(format.format(new Date(l.time)));
|
||||
serializer.endTag(null, "time"); //$NON-NLS-1$
|
||||
}
|
||||
serializer.startTag(null, "name"); //$NON-NLS-1$
|
||||
serializer.text(l.name);
|
||||
serializer.endTag(null, "name"); //$NON-NLS-1$
|
||||
writeWpt(format, serializer, l);
|
||||
serializer.endTag(null, "wpt"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
|
@ -118,38 +192,42 @@ public class GPXUtilities {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void writeNotNullText(XmlSerializer serializer, String tag, String value) throws IOException {
|
||||
if(value != null){
|
||||
serializer.startTag(null, tag);
|
||||
serializer.text(value);
|
||||
serializer.endTag(null, tag);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeExtensions(XmlSerializer serializer, GPXExtensions p) throws IOException {
|
||||
serializer.startTag(null, "extensions");
|
||||
for(Map.Entry<String, String> s : p.getExtensionsToRead().entrySet()){
|
||||
writeNotNullText(serializer, s.getKey(), s.getValue());
|
||||
}
|
||||
serializer.endTag(null, "extensions");
|
||||
}
|
||||
|
||||
private static void writeWpt(SimpleDateFormat format, XmlSerializer serializer, WptPt p) throws IOException {
|
||||
serializer.attribute(null, "lat", latLonFormat.format(p.lat)); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
serializer.attribute(null, "lon", latLonFormat.format(p.lon)); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
if(!Double.isNaN(p.ele)){
|
||||
serializer.startTag(null, "ele"); //$NON-NLS-1$
|
||||
serializer.text(p.ele + ""); //$NON-NLS-1$
|
||||
serializer.endTag(null, "ele"); //$NON-NLS-1$
|
||||
}
|
||||
if(p.name != null){
|
||||
serializer.startTag(null, "name"); //$NON-NLS-1$
|
||||
serializer.text(p.name);
|
||||
serializer.endTag(null, "name"); //$NON-NLS-1$
|
||||
writeNotNullText(serializer, "ele", p.ele+"");
|
||||
}
|
||||
writeNotNullText(serializer, "name", p.name);
|
||||
writeNotNullText(serializer, "desc", p.desc);
|
||||
if(!Double.isNaN(p.hdop)){
|
||||
serializer.startTag(null, "hdop"); //$NON-NLS-1$
|
||||
serializer.text(p.hdop +"");
|
||||
serializer.endTag(null, "hdop"); //$NON-NLS-1$
|
||||
writeNotNullText(serializer, "hdop", p.hdop+"");
|
||||
}
|
||||
if(p.time != 0){
|
||||
serializer.startTag(null, "time"); //$NON-NLS-1$
|
||||
serializer.text(format.format(new Date(p.time)));
|
||||
serializer.endTag(null, "time"); //$NON-NLS-1$
|
||||
writeNotNullText(serializer, "time", format.format(new Date(p.time)));
|
||||
}
|
||||
if (p.speed > 0) {
|
||||
serializer.startTag(null, "extensions");
|
||||
serializer.startTag(null, "speed"); //$NON-NLS-1$
|
||||
serializer.text(p.speed + ""); //$NON-NLS-1$
|
||||
serializer.endTag(null, "speed"); //$NON-NLS-1$
|
||||
serializer.endTag(null, "extensions");
|
||||
p.getExtensionsToWrite().put("speed", p.speed+"");
|
||||
}
|
||||
writeExtensions(serializer, p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -174,114 +252,209 @@ public class GPXUtilities {
|
|||
}
|
||||
}
|
||||
|
||||
public static GPXFileResult loadGPXFile(Context ctx, File f){
|
||||
GPXFileResult res = new GPXFileResult();
|
||||
|
||||
private static String readText(XmlPullParser parser, String key) throws XmlPullParserException, IOException {
|
||||
int tok;
|
||||
String text = null;
|
||||
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||
if(tok == XmlPullParser.END_TAG && parser.getName().equals(key)){
|
||||
break;
|
||||
} else if(tok == XmlPullParser.TEXT){
|
||||
if(text == null){
|
||||
text = parser.getText();
|
||||
} else {
|
||||
text += parser.getText();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static GPXFile loadGPXFile(Context ctx, File f, boolean convertCloudmadeSource) {
|
||||
try {
|
||||
return loadGPXFile(ctx, new FileInputStream(f), convertCloudmadeSource);
|
||||
} catch (FileNotFoundException e) {
|
||||
GPXFile res = new GPXFile();
|
||||
log.error("Error reading gpx", e); //$NON-NLS-1$
|
||||
res.warning = ctx.getString(R.string.error_reading_gpx);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public static GPXFile loadGPXFile(Context ctx, InputStream f, boolean convertCloudmadeSource) {
|
||||
GPXFile res = new GPXFile();
|
||||
SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT);
|
||||
format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
try {
|
||||
res.cloudMadeFile = false;
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$
|
||||
|
||||
parser.setInput(f, "UTF-8"); //$NON-NLS-1$
|
||||
Stack<Object> parserState = new Stack<Object>();
|
||||
boolean extensionReadMode = false;
|
||||
parserState.push(res);
|
||||
int tok;
|
||||
Location current = null;
|
||||
String currentName = ""; //$NON-NLS-1$
|
||||
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||
if (tok == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("copyright")) { //$NON-NLS-1$
|
||||
res.cloudMadeFile |= "cloudmade".equalsIgnoreCase(parser.getAttributeValue("", "author")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
|
||||
} else if (parser.getName().equals("trkseg")) { //$NON-NLS-1$
|
||||
res.locations.add(new ArrayList<Location>());
|
||||
} else if (parser.getName().equals("wpt") || parser.getName().equals("trkpt") || //$NON-NLS-1$//$NON-NLS-2$
|
||||
(!res.cloudMadeFile && parser.getName().equals("rtept"))) { //$NON-NLS-1$
|
||||
// currently not distinguish different point represents all as a line
|
||||
try {
|
||||
currentName = ""; //$NON-NLS-1$
|
||||
current = new Location("gpx_file"); //$NON-NLS-1$
|
||||
current.setLatitude(Double.parseDouble(parser.getAttributeValue("", "lat"))); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
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("hdop")) { //$NON-NLS-1$
|
||||
if (parser.next() == XmlPullParser.TEXT) {
|
||||
try {
|
||||
current.setAccuracy(Float.parseFloat(parser.getText()));
|
||||
} catch (NumberFormatException 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") || (!res.cloudMadeFile && parser.getName().equals("rtept"))) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
if (current != null) {
|
||||
if (parser.getName().equals("wpt") && !res.cloudMadeFile) { //$NON-NLS-1$
|
||||
res.wayPoints.add(convertLocationToWayPoint(current, currentName));
|
||||
} else {
|
||||
if (res.locations.isEmpty()) {
|
||||
res.locations.add(new ArrayList<Location>());
|
||||
Object parse = parserState.peek();
|
||||
String tag = parser.getName();
|
||||
if (extensionReadMode && parse instanceof GPXExtensions) {
|
||||
String value = readText(parser, tag);
|
||||
if (value != null) {
|
||||
((GPXExtensions) parse).getExtensionsToWrite().put(tag, value);
|
||||
if (tag.equals("speed") && parse instanceof WptPt) {
|
||||
try {
|
||||
((WptPt) parse).speed = Float.parseFloat(value);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (parse instanceof GPXExtensions && tag.equals("extensions")) {
|
||||
extensionReadMode = true;
|
||||
} else {
|
||||
if (parse instanceof GPXFile) {
|
||||
if (parser.getName().equals("gpx")) {
|
||||
((GPXFile) parse).author = parser.getAttributeValue("", "creator");
|
||||
}
|
||||
if (parser.getName().equals("trk")) {
|
||||
Track track = new Track();
|
||||
((GPXFile) parse).tracks.add(track);
|
||||
parserState.push(track);
|
||||
}
|
||||
if (parser.getName().equals("rte")) {
|
||||
Route route = new Route();
|
||||
((GPXFile) parse).routes.add(route);
|
||||
parserState.push(route);
|
||||
}
|
||||
if (parser.getName().equals("wpt")) {
|
||||
WptPt wptPt = parseWptAttributes(parser);
|
||||
((GPXFile) parse).points.add(wptPt);
|
||||
parserState.push(wptPt);
|
||||
}
|
||||
} else if (parse instanceof Route) {
|
||||
if (parser.getName().equals("name")) {
|
||||
((Route) parse).name = readText(parser, "name");
|
||||
}
|
||||
if (parser.getName().equals("desc")) {
|
||||
((Route) parse).desc = readText(parser, "desc");
|
||||
}
|
||||
if (parser.getName().equals("rtept")) {
|
||||
WptPt wptPt = parseWptAttributes(parser);
|
||||
((Route) parse).points.add(wptPt);
|
||||
parserState.push(wptPt);
|
||||
}
|
||||
} else if (parse instanceof Track) {
|
||||
if (parser.getName().equals("name")) {
|
||||
((Track) parse).name = readText(parser, "name");
|
||||
}
|
||||
if (parser.getName().equals("desc")) {
|
||||
((Track) parse).desc = readText(parser, "desc");
|
||||
}
|
||||
if (parser.getName().equals("trkseg")) {
|
||||
TrkSegment trkSeg = new TrkSegment();
|
||||
((Track) parse).segments.add(trkSeg);
|
||||
parserState.push(trkSeg);
|
||||
}
|
||||
} else if (parse instanceof TrkSegment) {
|
||||
if (parser.getName().equals("trkpt")) {
|
||||
WptPt wptPt = parseWptAttributes(parser);
|
||||
((TrkSegment) parse).points.add(wptPt);
|
||||
parserState.push(wptPt);
|
||||
}
|
||||
// main object to parse
|
||||
} else if (parse instanceof WptPt) {
|
||||
if (parser.getName().equals("name")) {
|
||||
((WptPt) parse).name = readText(parser, "name");
|
||||
} else if (parser.getName().equals("desc")) {
|
||||
((WptPt) parse).desc = readText(parser, "desc");
|
||||
} else if (parser.getName().equals("ele")) {
|
||||
String text = readText(parser, "ele");
|
||||
if (text != null) {
|
||||
try {
|
||||
((WptPt) parse).ele = Float.parseFloat(text);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
} else if (parser.getName().equals("hdop")) {
|
||||
String text = readText(parser, "hdop");
|
||||
if (text != null) {
|
||||
try {
|
||||
((WptPt) parse).hdop = Float.parseFloat(text);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
} else if (parser.getName().equals("time")) {
|
||||
String text = readText(parser, "time");
|
||||
if (text != null) {
|
||||
try {
|
||||
((WptPt) parse).time = format.parse(text).getTime();
|
||||
} catch (ParseException e) {
|
||||
}
|
||||
}
|
||||
res.locations.get(res.locations.size() - 1).add(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (tok == XmlPullParser.END_TAG) {
|
||||
Object parse = parserState.peek();
|
||||
String tag = parser.getName();
|
||||
if (parse instanceof GPXExtensions && tag.equals("extensions")) {
|
||||
extensionReadMode = false;
|
||||
}
|
||||
|
||||
if(tag.equals("trkpt")){
|
||||
Object pop = parserState.pop();
|
||||
assert pop instanceof WptPt;
|
||||
} else if(tag.equals("wpt")){
|
||||
Object pop = parserState.pop();
|
||||
assert pop instanceof WptPt;
|
||||
} else if(tag.equals("rtept")){
|
||||
Object pop = parserState.pop();
|
||||
assert pop instanceof WptPt;
|
||||
} else if(tag.equals("trk")){
|
||||
Object pop = parserState.pop();
|
||||
assert pop instanceof Track;
|
||||
} else if(tag.equals("rte")){
|
||||
Object pop = parserState.pop();
|
||||
assert pop instanceof Route;
|
||||
} else if(tag.equals("trkseg")){
|
||||
Object pop = parserState.pop();
|
||||
assert pop instanceof TrkSegment;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(convertCloudmadeSource && res.isCloudmadeRouteFile()){
|
||||
Track tk = new Track();
|
||||
res.tracks.add(tk);
|
||||
TrkSegment segment = new TrkSegment();
|
||||
tk.segments.add(segment);
|
||||
|
||||
for(WptPt wp : res.points){
|
||||
segment.points.add(wp);
|
||||
}
|
||||
res.points.clear();
|
||||
}
|
||||
} catch (XmlPullParserException e) {
|
||||
log.error("Error reading gpx", e); //$NON-NLS-1$
|
||||
res.error = ctx.getString(R.string.error_reading_gpx);
|
||||
res.warning = ctx.getString(R.string.error_reading_gpx);
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading gpx", e); //$NON-NLS-1$
|
||||
res.error = ctx.getString(R.string.error_reading_gpx);
|
||||
res.warning = ctx.getString(R.string.error_reading_gpx);
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private static WptPt convertLocationToWayPoint(Location current, String name){
|
||||
WptPt pt = new WptPt();
|
||||
pt.lat = current.getLatitude();
|
||||
pt.lon = current.getLongitude();
|
||||
if(current.hasAltitude()) {
|
||||
pt.ele = current.getAltitude();
|
||||
|
||||
private static WptPt parseWptAttributes(XmlPullParser parser) {
|
||||
WptPt wpt = new WptPt();
|
||||
try {
|
||||
wpt.lat = Double.parseDouble(parser.getAttributeValue("", "lat")); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
wpt.lon = Double.parseDouble(parser.getAttributeValue("", "lon")); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
if(current.hasSpeed()) {
|
||||
pt.speed = current.getSpeed();
|
||||
}
|
||||
if(current.hasAccuracy()) {
|
||||
pt.hdop = current.getAccuracy();
|
||||
}
|
||||
pt.time = current.getTime();
|
||||
pt.name = name;
|
||||
return pt;
|
||||
return wpt;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -16,7 +16,6 @@ import net.osmand.FavouritePoint;
|
|||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.OsmAndFormatter;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.GPXFileResult;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
|
@ -377,15 +376,18 @@ public class FavouritesActivity extends ExpandableListActivity {
|
|||
existedPoints.add(fp.getName() + "_" + fp.getCategory());
|
||||
}
|
||||
}
|
||||
GPXFileResult res = GPXUtilities.loadGPXFile(FavouritesActivity.this, f);
|
||||
if(res.error != null){
|
||||
return res.error;
|
||||
GPXFile res = GPXUtilities.loadGPXFile(FavouritesActivity.this, f, false);
|
||||
if(res.warning != null){
|
||||
return res.warning;
|
||||
}
|
||||
for(WptPt p : res.wayPoints){
|
||||
for(WptPt p : res.points){
|
||||
if(!existedPoints.contains(p.name)){
|
||||
String categoryName = FavouritesActivity.this.getString(R.string.favorite_default_category);
|
||||
int c;
|
||||
String name = p.name;
|
||||
if(name == null){
|
||||
name = "";
|
||||
}
|
||||
if((c = p.name.lastIndexOf('_')) != -1){
|
||||
categoryName = p.name.substring(c + 1);
|
||||
name = p.name.substring(0, c);
|
||||
|
|
|
@ -15,7 +15,10 @@ import java.util.TreeSet;
|
|||
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.OsmAndFormatter;
|
||||
import net.osmand.GPXUtilities.GPXFileResult;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.Track;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.binary.BinaryIndexPart;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.binary.BinaryMapAddressReaderAdapter.AddressRegion;
|
||||
|
@ -35,7 +38,6 @@ 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 {
|
||||
|
@ -103,21 +105,21 @@ public class LocalIndexHelper {
|
|||
|
||||
private void updateGpxInfo(LocalIndexInfo info, File f) {
|
||||
if(info.getGpxFile() == null){
|
||||
info.setGpxFile(GPXUtilities.loadGPXFile(app, f));
|
||||
info.setGpxFile(GPXUtilities.loadGPXFile(app, f, true));
|
||||
}
|
||||
GPXFileResult result = info.getGpxFile();
|
||||
if(result.error != null){
|
||||
GPXFile result = info.getGpxFile();
|
||||
if(result.warning != null){
|
||||
info.setCorrupted(true);
|
||||
info.setDescription(result.error);
|
||||
info.setDescription(result.warning);
|
||||
} else {
|
||||
int totalDistance = 0;
|
||||
int totalTracks = 0;
|
||||
long startTime = Long.MAX_VALUE;
|
||||
long endTime = Long.MIN_VALUE;
|
||||
|
||||
double diffElevationUp = 0;
|
||||
double diffElevationDown = 0;
|
||||
double totalElevation = 0;
|
||||
double Elevation = 0;
|
||||
double minElevation = 99999;
|
||||
double maxElevation = 0;
|
||||
|
||||
|
@ -126,39 +128,48 @@ public class LocalIndexHelper {
|
|||
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 ++;
|
||||
for(int i = 0; i< result.tracks.size() ; i++){
|
||||
Track subtrack = result.tracks.get(i);
|
||||
for(TrkSegment segment : subtrack.segments){
|
||||
totalTracks++;
|
||||
points += segment.points.size();
|
||||
for (int j = 0; j < segment.points.size(); j++) {
|
||||
WptPt point = segment.points.get(j);
|
||||
long time = point.time;
|
||||
if(time != 0){
|
||||
startTime = Math.min(startTime, time);
|
||||
endTime = Math.max(startTime, time);
|
||||
}
|
||||
float speed = (float) point.speed;
|
||||
if(speed > 0){
|
||||
totalSpeedSum += speed;
|
||||
maxSpeed = Math.max(speed, maxSpeed);
|
||||
speedCount ++;
|
||||
}
|
||||
|
||||
double elevation = point.ele;
|
||||
if (!Double.isNaN(elevation)) {
|
||||
totalElevation += elevation;
|
||||
minElevation = Math.min(elevation, minElevation);
|
||||
maxElevation = Math.max(elevation, maxElevation);
|
||||
}
|
||||
if (j > 0) {
|
||||
WptPt prev = segment.points.get(j - 1);
|
||||
if (!Double.isNaN(point.ele) && !Double.isNaN(prev.ele)) {
|
||||
double diff = point.ele - prev.ele;
|
||||
if (diff > 0) {
|
||||
diffElevationUp += diff;
|
||||
} else {
|
||||
diffElevationDown -= diff;
|
||||
}
|
||||
}
|
||||
totalDistance += MapUtils.getDistance(prev.lat, prev.lon, point.lat, point.lon);
|
||||
}
|
||||
}
|
||||
|
||||
Elevation = subtrack.get(j).getAltitude();
|
||||
totalElevation += Elevation;
|
||||
minElevation = Math.min(Elevation, minElevation);
|
||||
maxElevation = Math.max(Elevation, maxElevation);
|
||||
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();
|
||||
|
@ -167,8 +178,8 @@ public class LocalIndexHelper {
|
|||
endTime = f.lastModified();
|
||||
}
|
||||
|
||||
info.setDescription(app.getString(R.string.local_index_gpx_info, result.locations.size(), points,
|
||||
result.wayPoints.size(), OsmAndFormatter.getFormattedDistance(totalDistance, app),
|
||||
info.setDescription(app.getString(R.string.local_index_gpx_info, totalTracks, points,
|
||||
result.points.size(), OsmAndFormatter.getFormattedDistance(totalDistance, app),
|
||||
startTime, endTime));
|
||||
if(totalElevation != 0 || diffElevationUp != 0 || diffElevationDown != 0){
|
||||
info.setDescription(info.getDescription() +
|
||||
|
@ -403,7 +414,7 @@ public class LocalIndexHelper {
|
|||
// UI state expanded
|
||||
private boolean expanded;
|
||||
|
||||
private GPXFileResult gpxFile;
|
||||
private GPXFile gpxFile;
|
||||
|
||||
public LocalIndexInfo(LocalIndexType type, File f, boolean backuped){
|
||||
pathToData = f.getAbsolutePath();
|
||||
|
@ -446,11 +457,11 @@ public class LocalIndexHelper {
|
|||
this.kbSize = size;
|
||||
}
|
||||
|
||||
public void setGpxFile(GPXFileResult gpxFile) {
|
||||
public void setGpxFile(GPXFile gpxFile) {
|
||||
this.gpxFile = gpxFile;
|
||||
}
|
||||
|
||||
public GPXFileResult getGpxFile() {
|
||||
public GPXFile getGpxFile() {
|
||||
return gpxFile;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Set;
|
|||
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.IProgress;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.ResourceManager;
|
||||
|
@ -27,7 +28,6 @@ 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;
|
||||
|
@ -97,10 +97,10 @@ public class LocalIndexesActivity extends ExpandableListActivity {
|
|||
if (child >= 0 && group >= 0) {
|
||||
final LocalIndexInfo point = (LocalIndexInfo) listAdapter.getChild(group, child);
|
||||
if (point != null && point.getGpxFile() != null) {
|
||||
Location loc = point.getGpxFile().findFistLocation();
|
||||
WptPt loc = point.getGpxFile().findPointToShow();
|
||||
if (loc != null) {
|
||||
OsmandSettings.getOsmandSettings(LocalIndexesActivity.this).setMapLocationToShow(loc.getLatitude(),
|
||||
loc.getLongitude());
|
||||
OsmandSettings.getOsmandSettings(LocalIndexesActivity.this).setMapLocationToShow(loc.lat,
|
||||
loc.lon);
|
||||
}
|
||||
((OsmandApplication) getApplication()).setGpxFileToDisplay(point.getGpxFile());
|
||||
MapActivity.launchMapActivityMoveToTop(LocalIndexesActivity.this);
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package net.osmand.plus.activities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.CallbackWithObject;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.Version;
|
||||
import net.osmand.GPXUtilities.GPXFileResult;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.data.MapTileDownloader;
|
||||
import net.osmand.data.MapTileDownloader.DownloadRequest;
|
||||
import net.osmand.data.MapTileDownloader.IMapDownloaderCallback;
|
||||
|
@ -19,6 +18,7 @@ import net.osmand.plus.FavouritesDbHelper;
|
|||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.ResourceManager;
|
||||
import net.osmand.plus.activities.RouteProvider.GPXRouteParams;
|
||||
import net.osmand.plus.activities.search.SearchActivity;
|
||||
import net.osmand.plus.activities.search.SearchPoiFilterActivity;
|
||||
import net.osmand.plus.activities.search.SearchTransportActivity;
|
||||
|
@ -1190,10 +1190,10 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
|||
|
||||
private void useGPXRouting() {
|
||||
final LatLon endForRouting = getPointToNavigate();
|
||||
mapLayers.selectGPXFileLayer(new CallbackWithObject<GPXFileResult>() {
|
||||
mapLayers.selectGPXFileLayer(new CallbackWithObject<GPXFile>() {
|
||||
|
||||
@Override
|
||||
public boolean processResult(final GPXFileResult result) {
|
||||
public boolean processResult(final GPXFile result) {
|
||||
Builder builder = new AlertDialog.Builder(MapActivity.this);
|
||||
final boolean[] props = new boolean[]{false, false, false};
|
||||
builder.setMultiChoiceItems(new String[] { getString(R.string.gpx_option_reverse_route),
|
||||
|
@ -1209,35 +1209,35 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
|||
public void onClick(DialogInterface dialog, int which) {
|
||||
boolean reverse = props[0];
|
||||
boolean passWholeWay = props[2];
|
||||
ArrayList<List<Location>> locations = result.locations;
|
||||
List<Location> l = new ArrayList<Location>();
|
||||
for(List<Location> s : locations){
|
||||
l.addAll(s);
|
||||
}
|
||||
if(reverse){
|
||||
Collections.reverse(l);
|
||||
}
|
||||
boolean useDestination = props[1];
|
||||
GPXRouteParams gpxRoute = new GPXRouteParams(result, reverse);
|
||||
|
||||
Location loc = getLastKnownLocation();
|
||||
if(passWholeWay && loc != null){
|
||||
l.add(0, loc);
|
||||
gpxRoute.setStartPoint(loc);
|
||||
}
|
||||
|
||||
Location startForRouting = getLastKnownLocation();
|
||||
if(startForRouting == null && !l.isEmpty()){
|
||||
startForRouting = l.get(0);
|
||||
if(startForRouting == null){
|
||||
startForRouting = gpxRoute.getStartPointForRoute();
|
||||
}
|
||||
|
||||
LatLon endPoint = endForRouting;
|
||||
if((endPoint == null || !props[1]) && !l.isEmpty()){
|
||||
LatLon point = new LatLon(l.get(l.size() - 1).getLatitude(), l.get(l.size() - 1).getLongitude());
|
||||
settings.setPointToNavigate(point.getLatitude(), point.getLongitude(), null);
|
||||
endPoint = point;
|
||||
mapLayers.getNavigationLayer().setPointToNavigate(point);
|
||||
if(endPoint == null || !useDestination){
|
||||
LatLon point = gpxRoute.getLastPoint();
|
||||
if(point != null){
|
||||
endPoint = point;
|
||||
}
|
||||
if(endPoint != null) {
|
||||
settings.setPointToNavigate(point.getLatitude(), point.getLongitude(), null);
|
||||
mapLayers.getNavigationLayer().setPointToNavigate(point);
|
||||
}
|
||||
}
|
||||
mapView.refreshMap();
|
||||
if(endPoint != null){
|
||||
settings.FOLLOW_TO_THE_ROUTE.set(true);
|
||||
routingHelper.setFollowingMode(true);
|
||||
routingHelper.setFinalAndCurrentLocation(endPoint, startForRouting, l);
|
||||
routingHelper.setFinalAndCurrentLocation(endPoint, startForRouting, gpxRoute);
|
||||
getMyApplication().showDialogInitializingCommandPlayer(MapActivity.this);
|
||||
}
|
||||
}
|
||||
|
@ -1246,7 +1246,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
|||
builder.show();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
public void contextMenuPoint(final double latitude, final double longitude){
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.util.Map.Entry;
|
|||
import net.osmand.Algoritms;
|
||||
import net.osmand.CallbackWithObject;
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFileResult;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.OsmAndFormatter;
|
||||
import net.osmand.data.AmenityType;
|
||||
import net.osmand.map.ITileSource;
|
||||
|
@ -327,9 +327,9 @@ public class MapActivityLayers {
|
|||
|
||||
public void showGPXFileLayer(final OsmandMapTileView mapView){
|
||||
final OsmandSettings settings = getApplication().getSettings();
|
||||
selectGPXFileLayer(new CallbackWithObject<GPXFileResult>() {
|
||||
selectGPXFileLayer(new CallbackWithObject<GPXFile>() {
|
||||
@Override
|
||||
public boolean processResult(GPXFileResult result) {
|
||||
public boolean processResult(GPXFile result) {
|
||||
settings.SHOW_FAVORITES.set(true);
|
||||
if (result != null) {
|
||||
getApplication().setGpxFileToDisplay(result);
|
||||
|
@ -338,19 +338,19 @@ public class MapActivityLayers {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
|
||||
private void updateGPXLayer(){
|
||||
GPXFileResult gpxFileToDisplay = getApplication().getGpxFileToDisplay();
|
||||
GPXFile gpxFileToDisplay = getApplication().getGpxFileToDisplay();
|
||||
if(gpxFileToDisplay == null){
|
||||
gpxLayer.setTracks(null);
|
||||
} else {
|
||||
gpxLayer.setTracks(gpxFileToDisplay.locations);
|
||||
gpxLayer.setTracks(gpxFileToDisplay.tracks);
|
||||
}
|
||||
}
|
||||
|
||||
public void selectGPXFileLayer(final CallbackWithObject<GPXFileResult> callbackWithObject) {
|
||||
public void selectGPXFileLayer(final CallbackWithObject<GPXFile> callbackWithObject, final boolean convertCloudmade) {
|
||||
final List<String> list = new ArrayList<String>();
|
||||
final OsmandSettings settings = getApplication().getSettings();
|
||||
final File dir = settings.extendOsmandPath(ResourceManager.GPX_PATH);
|
||||
|
@ -393,22 +393,16 @@ public class MapActivityLayers {
|
|||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final GPXFileResult res = GPXUtilities.loadGPXFile(activity, f);
|
||||
if (res.error != null) {
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(activity, res.error, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
final GPXFile res = GPXUtilities.loadGPXFile(activity, f, convertCloudmade);
|
||||
dlg.dismiss();
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callbackWithObject.processResult(res);
|
||||
|
||||
if(res.warning != null){
|
||||
Toast.makeText(activity, res.warning, Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
callbackWithObject.processResult(res);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import java.util.Locale;
|
|||
import net.osmand.Algoritms;
|
||||
import net.osmand.FavouritePoint;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.GPXUtilities.GPXFileResult;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.FavouritesDbHelper;
|
||||
import net.osmand.plus.NavigationService;
|
||||
|
@ -35,7 +35,6 @@ import android.content.Context;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.text.format.DateFormat;
|
||||
import android.util.Log;
|
||||
|
@ -60,7 +59,7 @@ public class OsmandApplication extends Application {
|
|||
private ProgressDialogImplementation startDialog;
|
||||
private List<String> startingWarnings;
|
||||
private Handler uiHandler;
|
||||
private GPXFileResult gpxFileToDisplay;
|
||||
private GPXFile gpxFileToDisplay;
|
||||
|
||||
private boolean applicationInitializing = false;
|
||||
private Locale prefferedLocale = null;
|
||||
|
@ -106,16 +105,19 @@ public class OsmandApplication extends Application {
|
|||
return poiFilters;
|
||||
}
|
||||
|
||||
public void setGpxFileToDisplay(GPXFileResult gpxFileToDisplay) {
|
||||
public void setGpxFileToDisplay(GPXFile gpxFileToDisplay) {
|
||||
this.gpxFileToDisplay = gpxFileToDisplay;
|
||||
if(gpxFileToDisplay == null){
|
||||
getFavorites().setFavoritePointsFromGPXFile(null);
|
||||
} else {
|
||||
List<FavouritePoint> pts = new ArrayList<FavouritePoint>();
|
||||
for (WptPt p : gpxFileToDisplay.wayPoints) {
|
||||
for (WptPt p : gpxFileToDisplay.points) {
|
||||
FavouritePoint pt = new FavouritePoint();
|
||||
pt.setLatitude(p.lat);
|
||||
pt.setLongitude(p.lon);
|
||||
if(p.name == null){
|
||||
p.name = "";
|
||||
}
|
||||
pt.setName(p.name);
|
||||
pts.add(pt);
|
||||
}
|
||||
|
@ -123,7 +125,7 @@ public class OsmandApplication extends Application {
|
|||
}
|
||||
}
|
||||
|
||||
public GPXFileResult getGpxFileToDisplay() {
|
||||
public GPXFile getGpxFileToDisplay() {
|
||||
return gpxFileToDisplay;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.net.MalformedURLException;
|
|||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -14,8 +15,14 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
|||
import javax.xml.parsers.FactoryConfigurationError;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.OsmAndFormatter;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.Route;
|
||||
import net.osmand.GPXUtilities.Track;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
|
@ -31,7 +38,6 @@ import net.osmand.router.RoutingContext;
|
|||
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
|
@ -57,6 +63,76 @@ public class RouteProvider {
|
|||
public RouteProvider(){
|
||||
}
|
||||
|
||||
public static class GPXRouteParams {
|
||||
List<Location> points = new ArrayList<Location>();
|
||||
List<RouteDirectionInfo> directions;
|
||||
|
||||
public GPXRouteParams(GPXFile file, boolean reverse){
|
||||
prepareEverything(file, reverse);
|
||||
}
|
||||
|
||||
public void setStartPoint(Location startPoint) {
|
||||
points.add(0, startPoint);
|
||||
}
|
||||
|
||||
|
||||
public Location getStartPointForRoute(){
|
||||
if(!points.isEmpty()){
|
||||
return points.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public LatLon getLastPoint() {
|
||||
if(!points.isEmpty()){
|
||||
Location l = points.get(points.size() - 1);
|
||||
LatLon point = new LatLon(l.getLatitude(), l.getLongitude());
|
||||
return point;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void prepareEverything(GPXFile file, boolean reverse){
|
||||
if(file.isCloudmadeRouteFile()){
|
||||
directions = parseCloudmadeRoute(points, file);
|
||||
if(reverse){
|
||||
// clear directions all turns should be recalculated
|
||||
directions = null;
|
||||
Collections.reverse(points);
|
||||
}
|
||||
} else {
|
||||
// first of all check tracks
|
||||
for (Track tr : file.tracks) {
|
||||
for (TrkSegment tkSeg : tr.segments) {
|
||||
for (WptPt pt : tkSeg.points) {
|
||||
points.add(createLocation(pt));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (points.isEmpty()) {
|
||||
for (Route rte : file.routes) {
|
||||
for (WptPt pt : rte.points) {
|
||||
points.add(createLocation(pt));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reverse) {
|
||||
Collections.reverse(points);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Location createLocation(WptPt pt){
|
||||
Location loc = new Location("OsmandRouteProvider");
|
||||
loc.setLatitude(pt.lat);
|
||||
loc.setLongitude(pt.lon);
|
||||
loc.setSpeed((float) pt.speed);
|
||||
loc.setAltitude(pt.ele);
|
||||
loc.setAccuracy((float) pt.hdop);
|
||||
return loc;
|
||||
}
|
||||
|
||||
|
||||
public static class RouteCalculationResult {
|
||||
private final List<Location> locations;
|
||||
|
@ -169,7 +245,7 @@ public class RouteProvider {
|
|||
}
|
||||
|
||||
public RouteCalculationResult calculateRouteImpl(Location start, LatLon end, ApplicationMode mode, RouteService type, Context ctx,
|
||||
List<Location> gpxRoute, boolean fast){
|
||||
GPXRouteParams gpxRoute, boolean fast){
|
||||
long time = System.currentTimeMillis();
|
||||
if (start != null && end != null) {
|
||||
if(log.isInfoEnabled()){
|
||||
|
@ -177,7 +253,7 @@ public class RouteProvider {
|
|||
}
|
||||
try {
|
||||
RouteCalculationResult res;
|
||||
if(gpxRoute != null && !gpxRoute.isEmpty()){
|
||||
if(gpxRoute != null && !gpxRoute.points.isEmpty()){
|
||||
res = calculateGpxRoute(start, end, gpxRoute);
|
||||
addMissingTurnsToRoute(res, start, end, mode, ctx);
|
||||
} else if (type == RouteService.YOURS) {
|
||||
|
@ -206,11 +282,12 @@ public class RouteProvider {
|
|||
return new RouteCalculationResult(null);
|
||||
}
|
||||
|
||||
private RouteCalculationResult calculateGpxRoute(Location start, LatLon end, List<Location> gpxRoute) {
|
||||
private RouteCalculationResult calculateGpxRoute(Location start, LatLon end, GPXRouteParams params) {
|
||||
RouteCalculationResult res;
|
||||
// get the closest point to start and to end
|
||||
float minDist = Integer.MAX_VALUE;
|
||||
int startI = 0;
|
||||
List<Location> gpxRoute = params.points;
|
||||
int endI = gpxRoute.size();
|
||||
if (start != null) {
|
||||
for (int i = 0; i < gpxRoute.size(); i++) {
|
||||
|
@ -227,7 +304,7 @@ public class RouteProvider {
|
|||
l.setLatitude(end.getLatitude());
|
||||
l.setLongitude(end.getLongitude());
|
||||
minDist = Integer.MAX_VALUE;
|
||||
// get in reverse order taking into account cycle ways
|
||||
// get in reverse order taking into account ways with cycle
|
||||
for (int i = gpxRoute.size() - 1; i >= startI; i--) {
|
||||
float d = gpxRoute.get(i).distanceTo(l);
|
||||
if (d < minDist) {
|
||||
|
@ -236,7 +313,27 @@ public class RouteProvider {
|
|||
minDist = d - 40;
|
||||
}
|
||||
}
|
||||
res = new RouteCalculationResult(new ArrayList<Location>(gpxRoute.subList(startI, endI)), null, start, end, null);
|
||||
ArrayList<Location> sublist = new ArrayList<Location>(gpxRoute.subList(startI, endI));
|
||||
if(params.directions == null){
|
||||
res = new RouteCalculationResult(sublist, params.directions, start, end, null);
|
||||
} else {
|
||||
List<RouteDirectionInfo> subdirections = new ArrayList<RouteDirectionInfo>();
|
||||
for (RouteDirectionInfo info : params.directions) {
|
||||
if(info.routePointOffset >= startI && info.routePointOffset < endI){
|
||||
RouteDirectionInfo ch = new RouteDirectionInfo();
|
||||
ch.routePointOffset = info.routePointOffset - startI;
|
||||
ch.descriptionRoute = info.descriptionRoute;
|
||||
ch.expectedTime = info.expectedTime;
|
||||
ch.turnType = info.turnType;
|
||||
|
||||
// recalculate
|
||||
ch.distance = 0;
|
||||
ch.afterLeftTime = 0;
|
||||
subdirections.add(ch);
|
||||
}
|
||||
}
|
||||
res = new RouteCalculationResult(sublist, subdirections, start, end, null);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -554,137 +651,124 @@ public class RouteProvider {
|
|||
}
|
||||
|
||||
|
||||
protected RouteCalculationResult findCloudMadeRoute(Location start, LatLon end, ApplicationMode mode, Context ctx, boolean fast) throws MalformedURLException, IOException,
|
||||
ParserConfigurationException, FactoryConfigurationError, SAXException {
|
||||
protected RouteCalculationResult findCloudMadeRoute(Location start, LatLon end, ApplicationMode mode, Context ctx, boolean fast)
|
||||
throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException {
|
||||
List<Location> res = new ArrayList<Location>();
|
||||
List<RouteDirectionInfo> directions = null;
|
||||
StringBuilder uri = new StringBuilder();
|
||||
// possibly hide that API key because it is privacy of osmand
|
||||
uri.append("http://routes.cloudmade.com/A6421860EBB04234AB5EF2D049F2CD8F/api/0.3/"); //$NON-NLS-1$
|
||||
uri.append(start.getLatitude()+"").append(","); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
uri.append(start.getLongitude()+"").append(","); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
uri.append(end.getLatitude()+"").append(","); //$NON-NLS-1$//$NON-NLS-2$
|
||||
uri.append(end.getLongitude()+"").append("/"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
uri.append(start.getLatitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
uri.append(start.getLongitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
uri.append(end.getLatitude() + "").append(","); //$NON-NLS-1$//$NON-NLS-2$
|
||||
uri.append(end.getLongitude() + "").append("/"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
if (ApplicationMode.PEDESTRIAN == mode) {
|
||||
uri.append("foot.gpx"); //$NON-NLS-1$
|
||||
} else if (ApplicationMode.BICYCLE == mode) {
|
||||
uri.append("bicycle.gpx"); //$NON-NLS-1$
|
||||
} else {
|
||||
if(fast){
|
||||
if (fast) {
|
||||
uri.append("car.gpx"); //$NON-NLS-1$
|
||||
} else {
|
||||
uri.append("car/shortest.gpx"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
uri.append("?lang=").append(Locale.getDefault().getLanguage()); //$NON-NLS-1$
|
||||
|
||||
URL url = new URL(uri.toString());
|
||||
URLConnection connection = url.openConnection();
|
||||
DocumentBuilder dom = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document doc = dom.parse(new InputSource(new InputStreamReader(connection.getInputStream())));
|
||||
// TODO how to find that error occurred ? Gpx API doesn't say anything
|
||||
NodeList list = doc.getElementsByTagName("wpt"); //$NON-NLS-1$
|
||||
for (int i = 0; i < list.getLength(); i++) {
|
||||
Element item = (Element) list.item(i);
|
||||
try {
|
||||
Location l = new Location("router"); //$NON-NLS-1$
|
||||
l.setLatitude(Double.parseDouble(item.getAttribute("lat"))); //$NON-NLS-1$
|
||||
l.setLongitude(Double.parseDouble(item.getAttribute("lon"))); //$NON-NLS-1$
|
||||
res.add(l);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
GPXFile gpxFile = GPXUtilities.loadGPXFile(ctx, connection.getInputStream(), false);
|
||||
directions = parseCloudmadeRoute(res, gpxFile);
|
||||
|
||||
return new RouteCalculationResult(res, directions, start, end, null);
|
||||
}
|
||||
|
||||
private static List<RouteDirectionInfo> parseCloudmadeRoute(List<Location> res, GPXFile gpxFile) {
|
||||
List<RouteDirectionInfo> directions = null;
|
||||
for (WptPt pt : gpxFile.points) {
|
||||
res.add(createLocation(pt));
|
||||
}
|
||||
|
||||
|
||||
|
||||
list = doc.getElementsByTagName("rtept"); //$NON-NLS-1$
|
||||
if(list.getLength() > 0){
|
||||
directions = new ArrayList<RouteDirectionInfo>();
|
||||
Route route = null;
|
||||
if (gpxFile.routes.size() > 0) {
|
||||
route = gpxFile.routes.get(0);
|
||||
}
|
||||
RouteDirectionInfo previous = null;
|
||||
for (int i = 0; i < list.getLength(); i++) {
|
||||
Element item = (Element) list.item(i);
|
||||
try {
|
||||
RouteDirectionInfo dirInfo = new RouteDirectionInfo();
|
||||
dirInfo.descriptionRoute = getContentFromNode(item, "desc"); //$NON-NLS-1$
|
||||
String stime = getContentFromNode(item, "time"); //$NON-NLS-1$
|
||||
if(stime != null){
|
||||
dirInfo.expectedTime = Integer.parseInt(stime);
|
||||
}
|
||||
String stype = getContentFromNode(item, "turn"); //$NON-NLS-1$
|
||||
if(stype != null){
|
||||
dirInfo.turnType = TurnType.valueOf(stype.toUpperCase());
|
||||
} else {
|
||||
dirInfo.turnType = TurnType.valueOf(TurnType.C);
|
||||
}
|
||||
String sturn = getContentFromNode(item, "turn-angle"); //$NON-NLS-1$
|
||||
if(sturn != null){
|
||||
dirInfo.turnType.setTurnAngle((float) Double.parseDouble(sturn));
|
||||
}
|
||||
|
||||
int offset = Integer.parseInt(getContentFromNode(item, "offset")); //$NON-NLS-1$
|
||||
dirInfo.routePointOffset = offset;
|
||||
|
||||
if(previous != null && previous.turnType != null && !TurnType.C.equals(previous.turnType.getValue())){
|
||||
// calculate angle
|
||||
if(previous.routePointOffset > 0){
|
||||
float paz = res.get(previous.routePointOffset - 1).bearingTo(res.get(previous.routePointOffset));
|
||||
float caz;
|
||||
if(previous.turnType.isRoundAbout() && dirInfo.routePointOffset < res.size() - 1){
|
||||
caz = res.get(dirInfo.routePointOffset).bearingTo(res.get(dirInfo.routePointOffset + 1));
|
||||
} else {
|
||||
caz = res.get(dirInfo.routePointOffset - 1).bearingTo(res.get(dirInfo.routePointOffset));
|
||||
}
|
||||
float angle = caz - paz;
|
||||
if(angle < 0){
|
||||
angle += 360;
|
||||
} else if(angle > 360){
|
||||
angle -= 360;
|
||||
}
|
||||
// that magic number helps to fix some errors for turn
|
||||
angle += 75;
|
||||
if (route != null && route.points.size() > 0) {
|
||||
directions = new ArrayList<RouteDirectionInfo>();
|
||||
for (WptPt item : route.points) {
|
||||
try {
|
||||
RouteDirectionInfo dirInfo = new RouteDirectionInfo();
|
||||
dirInfo.descriptionRoute = item.desc; //$NON-NLS-1$
|
||||
String stime = item.getExtensionsToRead().get("time");
|
||||
if (stime != null) {
|
||||
dirInfo.expectedTime = Integer.parseInt(stime);
|
||||
}
|
||||
String stype = item.getExtensionsToRead().get("turn"); //$NON-NLS-1$
|
||||
if (stype != null) {
|
||||
dirInfo.turnType = TurnType.valueOf(stype.toUpperCase());
|
||||
} else {
|
||||
dirInfo.turnType = TurnType.valueOf(TurnType.C);
|
||||
}
|
||||
String sturn = item.getExtensionsToRead().get("turn-angle"); //$NON-NLS-1$
|
||||
if (sturn != null) {
|
||||
dirInfo.turnType.setTurnAngle((float) Double.parseDouble(sturn));
|
||||
}
|
||||
|
||||
if(previous.turnType.getTurnAngle() < 0.5f){
|
||||
previous.turnType.setTurnAngle(angle);
|
||||
int offset = Integer.parseInt(item.getExtensionsToRead().get("offset")); //$NON-NLS-1$
|
||||
dirInfo.routePointOffset = offset;
|
||||
|
||||
if (previous != null && previous.turnType != null && !TurnType.C.equals(previous.turnType.getValue())) {
|
||||
// calculate angle
|
||||
if (previous.routePointOffset > 0) {
|
||||
float paz = res.get(previous.routePointOffset - 1).bearingTo(res.get(previous.routePointOffset));
|
||||
float caz;
|
||||
if (previous.turnType.isRoundAbout() && dirInfo.routePointOffset < res.size() - 1) {
|
||||
caz = res.get(dirInfo.routePointOffset).bearingTo(res.get(dirInfo.routePointOffset + 1));
|
||||
} else {
|
||||
caz = res.get(dirInfo.routePointOffset - 1).bearingTo(res.get(dirInfo.routePointOffset));
|
||||
}
|
||||
float angle = caz - paz;
|
||||
if (angle < 0) {
|
||||
angle += 360;
|
||||
} else if (angle > 360) {
|
||||
angle -= 360;
|
||||
}
|
||||
// that magic number helps to fix some errors for turn
|
||||
angle += 75;
|
||||
|
||||
if (previous.turnType.getTurnAngle() < 0.5f) {
|
||||
previous.turnType.setTurnAngle(angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
directions.add(dirInfo);
|
||||
|
||||
previous = dirInfo;
|
||||
} catch (NumberFormatException e) {
|
||||
log.info("Exception", e); //$NON-NLS-1$
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.info("Exception", e); //$NON-NLS-1$
|
||||
|
||||
directions.add(dirInfo);
|
||||
|
||||
previous = dirInfo;
|
||||
} catch (NumberFormatException e) {
|
||||
log.info("Exception", e); //$NON-NLS-1$
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.info("Exception", e); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
if(previous != null && previous.turnType != null && !TurnType.C.equals(previous.turnType.getValue())){
|
||||
if (previous != null && previous.turnType != null && !TurnType.C.equals(previous.turnType.getValue())) {
|
||||
// calculate angle
|
||||
if(previous.routePointOffset > 0 && previous.routePointOffset < res.size() - 1){
|
||||
if (previous.routePointOffset > 0 && previous.routePointOffset < res.size() - 1) {
|
||||
float paz = res.get(previous.routePointOffset - 1).bearingTo(res.get(previous.routePointOffset));
|
||||
float caz = res.get(previous.routePointOffset).bearingTo(res.get(res.size() -1));
|
||||
float angle = caz - paz;
|
||||
if(angle < 0){
|
||||
float caz = res.get(previous.routePointOffset).bearingTo(res.get(res.size() - 1));
|
||||
float angle = caz - paz;
|
||||
if (angle < 0) {
|
||||
angle += 360;
|
||||
}
|
||||
if(previous.turnType.getTurnAngle() < 0.5f){
|
||||
if (previous.turnType.getTurnAngle() < 0.5f) {
|
||||
previous.turnType.setTurnAngle(angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new RouteCalculationResult(res, directions, start, end, null);
|
||||
return directions;
|
||||
}
|
||||
|
||||
private String getContentFromNode(Element item, String tagName){
|
||||
NodeList list = item.getElementsByTagName(tagName);
|
||||
if(list.getLength() > 0){
|
||||
return list.item(0).getFirstChild().getNodeValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.osmand.osm.LatLon;
|
|||
import net.osmand.osm.MapUtils;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.RouteProvider.GPXRouteParams;
|
||||
import net.osmand.plus.activities.RouteProvider.RouteCalculationResult;
|
||||
import net.osmand.plus.activities.RouteProvider.RouteService;
|
||||
import net.osmand.plus.voice.CommandPlayer;
|
||||
|
@ -30,6 +31,7 @@ public class RoutingHelper {
|
|||
public void routeWasCancelled();
|
||||
}
|
||||
|
||||
|
||||
private final double DISTANCE_TO_USE_OSMAND_ROUTER = 20000;
|
||||
|
||||
private List<IRouteInformationListener> listeners = new ArrayList<IRouteInformationListener>();
|
||||
|
@ -41,7 +43,7 @@ public class RoutingHelper {
|
|||
|
||||
private boolean isFollowingMode = false;
|
||||
|
||||
private List<Location> currentGPXRoute = null;
|
||||
private GPXRouteParams currentGPXRoute = null;
|
||||
// instead of this properties RouteCalculationResult could be used
|
||||
private List<Location> routeNodes = new ArrayList<Location>();
|
||||
private List<RouteDirectionInfo> directionInfo = null;
|
||||
|
@ -87,7 +89,7 @@ public class RoutingHelper {
|
|||
setFinalAndCurrentLocation(finalLocation, currentLocation, null);
|
||||
}
|
||||
|
||||
public synchronized void setFinalAndCurrentLocation(LatLon finalLocation, Location currentLocation, List<Location> gpxRoute){
|
||||
public synchronized void setFinalAndCurrentLocation(LatLon finalLocation, Location currentLocation, GPXRouteParams gpxRoute){
|
||||
clearCurrentRoute(finalLocation);
|
||||
currentGPXRoute = gpxRoute;
|
||||
// to update route
|
||||
|
@ -120,7 +122,7 @@ public class RoutingHelper {
|
|||
|
||||
}
|
||||
|
||||
public List<Location> getCurrentGPXRoute() {
|
||||
public GPXRouteParams getCurrentGPXRoute() {
|
||||
return currentGPXRoute;
|
||||
}
|
||||
|
||||
|
@ -433,7 +435,7 @@ public class RoutingHelper {
|
|||
return 0;
|
||||
}
|
||||
|
||||
private void recalculateRouteInBackground(final Location start, final LatLon end, final List<Location> currentGPXRoute){
|
||||
private void recalculateRouteInBackground(final Location start, final LatLon end, final GPXRouteParams gpxRoute){
|
||||
if (start == null || end == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -460,7 +462,7 @@ public class RoutingHelper {
|
|||
if(service != RouteService.OSMAND && !settings.isInternetConnectionAvailable()){
|
||||
showMessage(context.getString(R.string.internet_connection_required_for_online_route), Toast.LENGTH_LONG);
|
||||
}
|
||||
RouteCalculationResult res = provider.calculateRouteImpl(start, end, mode, service, context, currentGPXRoute, fastRouteMode);
|
||||
RouteCalculationResult res = provider.calculateRouteImpl(start, end, mode, service, context, gpxRoute, fastRouteMode);
|
||||
synchronized (RoutingHelper.this) {
|
||||
if (res.isCalculated()) {
|
||||
setNewRoute(res);
|
||||
|
@ -640,6 +642,12 @@ public class RoutingHelper {
|
|||
// location when you should action (turn or go ahead)
|
||||
public int routePointOffset;
|
||||
|
||||
// TODO add from parser
|
||||
public String ref;
|
||||
public String streetName;
|
||||
// speed limit in m/s (should be array of speed limits?)
|
||||
public float speedLimit;
|
||||
|
||||
// calculated vars
|
||||
|
||||
// after action (excluding expectedTime)
|
||||
|
|
|
@ -3,6 +3,10 @@ package net.osmand.plus.views;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.osmand.GPXUtilities.Track;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
|
@ -12,14 +16,13 @@ import android.graphics.RectF;
|
|||
import android.graphics.Paint.Cap;
|
||||
import android.graphics.Paint.Join;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.location.Location;
|
||||
|
||||
public class GPXLayer implements OsmandMapLayer {
|
||||
|
||||
|
||||
private OsmandMapTileView view;
|
||||
|
||||
private List<List<Location>> points = new ArrayList<List<Location>>();
|
||||
private List<List<WptPt>> points = new ArrayList<List<WptPt>>();
|
||||
private Paint paint;
|
||||
|
||||
|
||||
|
@ -51,23 +54,24 @@ public class GPXLayer implements OsmandMapLayer {
|
|||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, boolean nightMode) {
|
||||
List<List<WptPt>> points = this.points;
|
||||
if(points.isEmpty()){
|
||||
return;
|
||||
}
|
||||
|
||||
for (List<Location> l : points) {
|
||||
for (List<WptPt> l : points) {
|
||||
path.rewind();
|
||||
int startIndex = -1;
|
||||
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
Location ls = l.get(i);
|
||||
WptPt ls = l.get(i);
|
||||
if (startIndex == -1) {
|
||||
if (ls.getLatitude() >= latLonBounds.bottom && ls.getLatitude() <= latLonBounds.top && ls.getLongitude() >= latLonBounds.left
|
||||
&& ls.getLongitude() <= latLonBounds.right ) {
|
||||
if (ls.lat >= latLonBounds.bottom && ls.lat <= latLonBounds.top && ls.lon >= latLonBounds.left
|
||||
&& ls.lon <= latLonBounds.right ) {
|
||||
startIndex = i > 0 ? i - 1 : i;
|
||||
}
|
||||
} else if (!(latLonBounds.left <= ls.getLongitude() + 0.03 && ls.getLongitude() - 0.03 <= latLonBounds.right
|
||||
&& latLonBounds.bottom <= ls.getLatitude() + 0.03 && ls.getLatitude() - 0.03 <= latLonBounds.top)) {
|
||||
} else if (!(latLonBounds.left <= ls.lon + 0.03 && ls.lon - 0.03 <= latLonBounds.right
|
||||
&& latLonBounds.bottom <= ls.lat + 0.03 && ls.lat - 0.03 <= latLonBounds.top)) {
|
||||
drawSegment(canvas, l, startIndex, i);
|
||||
// do not continue make method more efficient (because it calls in UI thread)
|
||||
// this break also has logical sense !
|
||||
|
@ -84,14 +88,14 @@ public class GPXLayer implements OsmandMapLayer {
|
|||
}
|
||||
|
||||
|
||||
private void drawSegment(Canvas canvas, List<Location> l, int startIndex, int endIndex) {
|
||||
int px = view.getMapXForPoint(l.get(startIndex).getLongitude());
|
||||
int py = view.getMapYForPoint(l.get(startIndex).getLatitude());
|
||||
private void drawSegment(Canvas canvas, List<WptPt> l, int startIndex, int endIndex) {
|
||||
int px = view.getMapXForPoint(l.get(startIndex).lon);
|
||||
int py = view.getMapYForPoint(l.get(startIndex).lat);
|
||||
path.moveTo(px, py);
|
||||
for (int i = startIndex + 1; i <= endIndex; i++) {
|
||||
Location p = l.get(i);
|
||||
int x = view.getMapXForPoint(p.getLongitude());
|
||||
int y = view.getMapYForPoint(p.getLatitude());
|
||||
WptPt p = l.get(i);
|
||||
int x = view.getMapXForPoint(p.lon);
|
||||
int y = view.getMapYForPoint(p.lat);
|
||||
path.lineTo(x, y);
|
||||
}
|
||||
canvas.drawPath(path, paint);
|
||||
|
@ -107,11 +111,18 @@ public class GPXLayer implements OsmandMapLayer {
|
|||
points.clear();
|
||||
}
|
||||
|
||||
public void setTracks(List<List<Location>> tracks){
|
||||
public void setTracks(List<Track> tracks){
|
||||
if(tracks == null){
|
||||
clearCurrentGPX();
|
||||
} else {
|
||||
points = tracks;
|
||||
List<List<WptPt>> tpoints = new ArrayList<List<WptPt>>();
|
||||
for (Track t : tracks) {
|
||||
for (TrkSegment ts : t.segments) {
|
||||
tpoints.add(ts.points);
|
||||
}
|
||||
}
|
||||
points = tpoints;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
cd ~/gen_indexes
|
||||
rm osmand.log
|
||||
rm console
|
||||
# update map creator
|
||||
cd OsmAndMapCreator
|
||||
yes | unzip /var/www-download/latest-night-build/OsmAndMapCreator-development.zip
|
||||
cd ..
|
||||
|
||||
# remove backup and create new backup
|
||||
rm -r backup
|
||||
mkdir backup
|
||||
mv indexes/uploaded/*.* backup
|
||||
|
||||
# remove all previous files
|
||||
rm -r indexes
|
||||
mkdir indexes
|
||||
mkdir indexes/osm
|
||||
mkdir indexes/uploaded
|
||||
|
||||
#run batch creator
|
||||
./batch_indexing.sh > /dev/null 2&>console &
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue