From fa4feb317355ede791bbf31bb58dc0b47ae895c0 Mon Sep 17 00:00:00 2001 From: Andrey Novikov Date: Tue, 24 Oct 2023 23:44:07 +0300 Subject: [PATCH] Extend GPX route parsing --- .../main/java/mobi/maptrek/data/Route.java | 19 ++++++++++----- .../java/mobi/maptrek/io/gpx/GpxFile.java | 9 +++---- .../java/mobi/maptrek/io/gpx/GpxParser.java | 24 ++++++++++++++----- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/mobi/maptrek/data/Route.java b/app/src/main/java/mobi/maptrek/data/Route.java index 6258c3fe..845019ca 100644 --- a/app/src/main/java/mobi/maptrek/data/Route.java +++ b/app/src/main/java/mobi/maptrek/data/Route.java @@ -44,7 +44,7 @@ public class Route implements Parcelable { public RouteStyle style = new RouteStyle(); public DataSource source; // back reference to it's source - private final ArrayList instructions = new ArrayList<>(); + public final ArrayList instructions = new ArrayList<>(); private Instruction lastInstruction; private UpdateListener updateListener; @@ -59,13 +59,20 @@ public Route(String name, String description, boolean show) { distance = 0; } - public void addInstruction(int latitudeE6, int longitudeE6) { - addInstruction(new GeoPoint(latitudeE6, longitudeE6)); + public Instruction addInstruction(int latitudeE6, int longitudeE6) { + return addInstruction(new GeoPoint(latitudeE6, longitudeE6)); } - public void addInstruction(GeoPoint point) { + public Instruction addInstruction(GeoPoint point) { Instruction instruction = new Instruction(point); addInstruction(instruction); + return instruction; + } + + public Instruction addInstruction(int latitudeE6, int longitudeE6, String text, int sign) { + Instruction instruction = new Instruction(latitudeE6, longitudeE6, text, sign); + addInstruction(instruction); + return instruction; } private void addInstruction(Instruction instruction) { @@ -384,8 +391,8 @@ public static class Instruction extends GeoPoint { public static final int KEEP_RIGHT = 7; public static final int U_TURN_RIGHT = 8; - private String text; - private int sign; + public String text; + public int sign; private int distance; // TODO Use distance if set Instruction(GeoPoint point) { diff --git a/app/src/main/java/mobi/maptrek/io/gpx/GpxFile.java b/app/src/main/java/mobi/maptrek/io/gpx/GpxFile.java index ea63d853..31f5502d 100644 --- a/app/src/main/java/mobi/maptrek/io/gpx/GpxFile.java +++ b/app/src/main/java/mobi/maptrek/io/gpx/GpxFile.java @@ -21,6 +21,7 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; +import java.util.Objects; public class GpxFile { public static final String NS = "http://www.topografix.com/GPX/1/1"; @@ -41,14 +42,14 @@ public class GpxFile { public static final String ATTRIBUTE_LON = "lon"; public static final String ATTRIBUTE_CREATOR = "creator"; - static final DateFormat TRKTIME = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault()); - static final DateFormat TRKTIME_MS = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault()); + static final DateFormat TRKTIME = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); + static final DateFormat TRKTIME_MS = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ROOT); public static long parseTime(String timeString) throws ParseException { if (timeString.length() > 20) - return GpxFile.TRKTIME_MS.parse(timeString).getTime(); + return Objects.requireNonNull(GpxFile.TRKTIME_MS.parse(timeString)).getTime(); else - return GpxFile.TRKTIME.parse(timeString).getTime(); + return Objects.requireNonNull(GpxFile.TRKTIME.parse(timeString)).getTime(); } public static String formatTime(Date date) { diff --git a/app/src/main/java/mobi/maptrek/io/gpx/GpxParser.java b/app/src/main/java/mobi/maptrek/io/gpx/GpxParser.java index de965e82..c8c3cf93 100644 --- a/app/src/main/java/mobi/maptrek/io/gpx/GpxParser.java +++ b/app/src/main/java/mobi/maptrek/io/gpx/GpxParser.java @@ -107,7 +107,7 @@ private static GpxFile.Metadata readMetadata(XmlPullParser parser) throws XmlPul @NonNull private static Waypoint readWaypoint(XmlPullParser parser) throws XmlPullParserException, IOException { parser.require(XmlPullParser.START_TAG, NS, GpxFile.TAG_WPT); - Waypoint waypoint = new Waypoint(Float.valueOf(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LAT)), Float.valueOf(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LON))); + Waypoint waypoint = new Waypoint(Float.parseFloat(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LAT)), Float.parseFloat(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LON))); waypoint.locked = true; while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) { @@ -196,8 +196,8 @@ private static void readTrackSegment(XmlPullParser parser, Track track) throws X private static void readTrackPoint(XmlPullParser parser, Track track, boolean continuous) throws XmlPullParserException, IOException { parser.require(XmlPullParser.START_TAG, NS, GpxFile.TAG_TRKPT); - float lat = Float.valueOf(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LAT)); - float lon = Float.valueOf(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LON)); + float lat = Float.parseFloat(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LAT)); + float lon = Float.parseFloat(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LON)); float altitude = Float.NaN; long time = 0; while (parser.next() != XmlPullParser.END_TAG) { @@ -257,21 +257,33 @@ private static Route readRoute(XmlPullParser parser) throws XmlPullParserExcepti private static void readRoutePoint(XmlPullParser parser, Route route) throws XmlPullParserException, IOException { parser.require(XmlPullParser.START_TAG, NS, GpxFile.TAG_RTEPT); - float lat = Float.valueOf(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LAT)); - float lon = Float.valueOf(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LON)); + float lat = Float.parseFloat(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LAT)); + float lon = Float.parseFloat(parser.getAttributeValue(null, GpxFile.ATTRIBUTE_LON)); + String pointName = null; + String pointDesc = null; while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) { continue; } String name = parser.getName(); switch (name) { + case GpxFile.TAG_NAME: + pointName = readTextElement(parser, GpxFile.TAG_NAME); + break; + case GpxFile.TAG_DESC: + pointDesc = readTextElement(parser, GpxFile.TAG_DESC); + break; default: skip(parser); break; } } parser.require(XmlPullParser.END_TAG, NS, GpxFile.TAG_RTEPT); - route.addInstruction((int) (lat * 1E6), (int) (lon * 1E6)); + Route.Instruction instruction = route.addInstruction((int) (lat * 1E6), (int) (lon * 1E6)); + if (pointDesc != null) + instruction.text = pointDesc; + else if (pointName != null) + instruction.text = pointName; } private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {