diff --git a/navigation-formats/src/main/java/slash/navigation/base/BaseRoute.java b/navigation-formats/src/main/java/slash/navigation/base/BaseRoute.java
index 5822895..5e544c6 100644
--- a/navigation-formats/src/main/java/slash/navigation/base/BaseRoute.java
+++ b/navigation-formats/src/main/java/slash/navigation/base/BaseRoute.java
@@ -125,6 +125,7 @@
import static slash.common.type.CompactCalendar.fromCalendar;
import static slash.navigation.base.Positions.contains;
import static slash.navigation.base.Positions.getSignificantPositions;
+import slash.navigation.simple.*;
/**
* The base of all routes formats.
@@ -581,6 +582,13 @@
}
@SuppressWarnings("UnusedDeclaration")
+ public SimpleRoute asApeMapFormat() {
+ if (getFormat() instanceof ApeMapFormat)
+ return (SimpleRoute) this;
+ return asSimpleFormat(new ApeMapFormat());
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
public GpxRoute asGpx10Format() {
if (getFormat() instanceof Gpx10Format)
return (GpxRoute) this;
@@ -761,7 +769,7 @@
if (getFormat() instanceof MTP0809Format)
return (BcrRoute) this;
return asBcrFormat(new MTP0809Format());
- }
+ }
@SuppressWarnings("UnusedDeclaration")
public SimpleRoute asNavigatingPoiWarnerFormat() {
diff --git a/navigation-formats/src/main/java/slash/navigation/base/NavigationFormats.java b/navigation-formats/src/main/java/slash/navigation/base/NavigationFormats.java
index ca89c8a..9a6c0e1 100644
--- a/navigation-formats/src/main/java/slash/navigation/base/NavigationFormats.java
+++ b/navigation-formats/src/main/java/slash/navigation/base/NavigationFormats.java
@@ -132,6 +132,7 @@
import static java.util.Arrays.asList;
import static java.util.Arrays.sort;
import static slash.common.io.Transfer.trim;
+import slash.navigation.simple.ApeMapFormat;
/**
* Contains a list of all navigation formats.
@@ -252,6 +253,8 @@
addFormat(GarminPoiFormat.class);
addFormat(Igo8TrackFormat.class);
addFormat(GarminPoiDbFormat.class);
+
+ addFormat(ApeMapFormat.class);
}
public static void addFormat(Class extends NavigationFormat> format) {
diff --git a/navigation-formats/src/main/java/slash/navigation/simple/ApeMapFormat.java b/navigation-formats/src/main/java/slash/navigation/simple/ApeMapFormat.java
new file mode 100644
index 0000000..ddcdc8d
--- /dev/null
+++ b/navigation-formats/src/main/java/slash/navigation/simple/ApeMapFormat.java
@@ -0,0 +1,147 @@
+/*
+ This file is part of RouteConverter.
+
+ RouteConverter is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ RouteConverter is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with RouteConverter; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Copyright (C) 2007 Christian Pesch. All Rights Reserved.
+*/
+
+package slash.navigation.simple;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import static slash.common.io.Transfer.parseDouble;
+import static slash.common.io.Transfer.parseLong;
+import slash.common.type.CompactCalendar;
+import static slash.common.type.CompactCalendar.fromMillis;
+import static slash.navigation.base.RouteCharacteristics.Track;
+import slash.navigation.base.*;
+
+/**
+ * Reads Ape Map http://www.apemap.com/ (.trk) files.
+ *
{
+ private static final char SEPARATOR = ',';
+ private static final String FIRST_HEADER_LINE = "[track]";
+ private static final String SECOND_HEADER_LINE = "--start--";
+ private static final String TIME = "[0-9]+";
+
+ private static final Pattern LINE_PATTERN = Pattern.
+ compile(BEGIN_OF_LINE +
+ "\\(" + "(" + POSITION + ")" + SEPARATOR + "(" + POSITION + ")" + SEPARATOR + "(" + POSITION + ")" + SEPARATOR + "(" + TIME + ")" + "\\)" +
+ "(;#CMDNewSegment)*"+
+ "\\s*" +
+ END_OF_LINE);
+
+ private static final Pattern START_POS_PATTERN = Pattern.
+ compile(BEGIN_OF_LINE +
+ "\\(" + "(" + POSITION + ")" + SEPARATOR + "(" + POSITION + ")" + "\\)" +
+ "\\s*" +
+ END_OF_LINE);
+
+
+ @Override
+ public String getExtension() {
+ return ".trk";
+ }
+
+ @Override
+ public String getName() {
+ return "ape@map (*" + getExtension() + ")";
+ }
+
+ @SuppressWarnings({"unchecked"})
+ @Override
+ public SimpleRoute createRoute(RouteCharacteristics characteristics, String name, List
positions) {
+ return new Wgs84Route(this, characteristics, (List) positions);
+ }
+
+ @Override
+ protected RouteCharacteristics getRouteCharacteristics() {
+ return Track;
+ }
+
+ private boolean isStartPos( String line ) {
+ Matcher matcher = START_POS_PATTERN.matcher(line);
+ return matcher.matches();
+ }
+
+ @Override
+ protected boolean isValidLine(String line) {
+
+ boolean ret = isPosition(line) ||
+ line.startsWith(FIRST_HEADER_LINE) ||
+ line.startsWith(SECOND_HEADER_LINE) ||
+ isStartPos(line);
+
+ // System.out.println("ApeMape: " + ret + ":" + line + "<");
+
+ return ret;
+ }
+
+
+ @Override
+ public boolean isSupportsWriting() {
+ // TODO
+ return false;
+ }
+
+ @Override
+ protected boolean isPosition(String line) {
+ Matcher matcher = LINE_PATTERN.matcher(line);
+ return matcher.matches();
+ }
+
+ private CompactCalendar parseTime(String time) {
+ Long milliseconds = parseLong(time);
+ if (milliseconds == null || milliseconds == 0)
+ return null;
+ return fromMillis(milliseconds * 1000);
+ }
+
+ @Override
+ protected Wgs84Position parsePosition(String line, CompactCalendar startDate) {
+ Matcher lineMatcher = LINE_PATTERN.matcher(line);
+ if (!lineMatcher.matches())
+ throw new IllegalArgumentException("'" + line + "' does not match");
+ String latitude = lineMatcher.group(1);
+ String longitude = lineMatcher.group(2);
+ String altitude = lineMatcher.group(3);
+ String time = lineMatcher.group(4);
+ Wgs84Position position = new Wgs84Position(parseDouble(longitude), parseDouble(latitude),
+ parseDouble(altitude), 0.0, parseTime(time), null);
+ return position;
+ }
+
+ @Override
+ protected void writePosition(Wgs84Position position, PrintWriter writer, int index, boolean firstPosition) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+}
diff --git a/navigation-formats/src/test/java/slash/navigation/simple/ApeMapFormatTest.java b/navigation-formats/src/test/java/slash/navigation/simple/ApeMapFormatTest.java
new file mode 100644
index 0000000..785ad20
--- /dev/null
+++ b/navigation-formats/src/test/java/slash/navigation/simple/ApeMapFormatTest.java
@@ -0,0 +1,84 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package slash.navigation.simple;
+
+import java.text.DateFormat;
+import org.junit.*;
+import static org.junit.Assert.*;
+import slash.common.type.CompactCalendar;
+import slash.navigation.base.Wgs84Position;
+import static slash.common.TestCase.assertDoubleEquals;
+import static slash.common.TestCase.utcCalendar;
+
+/**
+ *
+ * @author martin
+ */
+public class ApeMapFormatTest {
+ ApeMapFormat format = new ApeMapFormat();
+
+ /**
+ * Test of getExtension method, of class ApeMapFormat.
+ */
+ @Test
+ public void testGetExtension() {
+ assertEquals(".trk", format.getExtension());
+ }
+
+ /**
+ * Test of isValidLine method, of class ApeMapFormat.
+ */
+ @Test
+ public void testIsValidLine() {
+ System.out.println("isValidLine");
+ assertTrue( format.isValidLine("(47.13336181640625,15.496421813964844,401.0,1370092005)"));
+ assertTrue( format.isValidLine("(47.13031005859375,15.495400428771973,429.0,1370092161)"));
+ assertTrue( format.isValidLine("(47.13031005859375,15.495400428771973,429.0,1370092161) "));
+ assertTrue( format.isValidLine("[track]"));
+ assertTrue( format.isValidLine("[track] "));
+ assertTrue( format.isValidLine("(47.14454650878906,15.500686645507813)"));
+ assertTrue( format.isValidLine("(47.13923645019531,15.501678466796875)"));
+ assertTrue( format.isValidLine("(47.13923645019531,15.501678466796875) "));
+ assertTrue( format.isValidLine("--start--"));
+ assertTrue( format.isValidLine("(47.070213317871094,15.496063232421875,437.0,1370785949)"));
+ assertTrue( format.isValidLine("(47.067962646484375,15.495849609375,405.0,1370788358);#CMDNewSegment"));
+ assertTrue( format.isValidLine("(47.06767654418945,15.495771408081055,407.0,1370788454)"));
+ assertTrue( format.isValidLine("(47.06760787963867,15.495786666870117,407.0,1370790160)"));
+ assertTrue( format.isValidLine("(47.070228576660156,15.496109962463379,407.0,1370790161);#CMDNewSegment"));
+ assertTrue( format.isValidLine("(47.070186614990234,15.496094703674316,424.0,1370790212)"));
+ assertTrue( format.isValidLine("(47.070186614990234,15.496094703674316,471.3,1370790216)"));
+ }
+
+ /**
+ * Test of isPosition method, of class ApeMapFormat.
+ */
+ @Test
+ public void testIsPosition() {
+ assertTrue(format.isPosition("(47.13336181640625,15.496421813964844,401.0,1370092005)"));
+ assertFalse(format.isPosition("[track]"));
+ assertFalse(format.isPosition("--start--"));
+ assertFalse(format.isPosition("(47.14454650878906,15.500686645507813)"));
+ assertFalse(format.isPosition("(47.13923645019531,15.501678466796875)"));
+ }
+
+ /**
+ * Test of parsePosition method, of class ApeMapFormat.
+ */
+ @Test
+ public void testParsePosition() {
+
+ Wgs84Position position = format.parsePosition("(47.13336181640625,15.496421813964844,401.0,1370092005)", null);
+ assertDoubleEquals(15.496421813964844, position.getLongitude());
+ assertDoubleEquals(47.13336181640625, position.getLatitude());
+ assertDoubleEquals(401.0, position.getElevation());
+ String actual = DateFormat.getDateTimeInstance().format(position.getTime().getTime());
+ CompactCalendar expectedCal = utcCalendar(1370092005000L);
+ String expected = DateFormat.getDateTimeInstance().format(expectedCal.getTime());
+ assertEquals(expected, actual);
+ assertEquals(expectedCal, position.getTime());
+ assertNull(position.getComment());
+ }
+
+}