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 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. + *

+ * [track] + * (47.14454650878906,15.500686645507813) + * (47.13923645019531,15.501678466796875) + * --start-- + * (47.14453887939453,15.501603126525879,461.0,1370091148) + * (47.14454650878906,15.501594543457031,503.4,1370091545) + * (47.14454650878906,15.501594543457031,456.0,1370091547) + * (47.144256591796875,15.501456260681152,449.0,1370091775) + * + * @author Martin Oberzalek + */ + +public class ApeMapFormat extends SimpleLineBasedFormat { + 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()); + } + +}