package slash.navigation.nmea; import slash.navigation.base.RouteCharacteristics; import slash.navigation.common.NavigationPosition; import slash.navigation.common.ValueAndOrientation; import java.io.PrintWriter; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.List; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import static slash.common.io.Transfer.*; /** * Reads and writes Magellan Explorist (.log) files. * * Header: $PMGNFMT,%TRK,LAT,HEMI,LON,HEMI,ALT,UNIT,TIME,VALID,NAME,%META,ASCII * Format: $PMGNTRK,4914.967,N,00651.208,E,000199,M,152224,A,KLLERTAL-RADWEG,210307*48 * * @author Christian Pesch */ public class MagellanExploristFormat extends BaseNmeaFormat { private static final String HEADER_LINE = "$PMGNFMT,%TRK,LAT,HEMI,LON,HEMI,ALT,UNIT,TIME,VALID,NAME,%META,ASCII"; private static final Pattern TRK_PATTERN = Pattern. compile("^\\$PMGNTRK" + SEPARATOR + "([\\d\\.]+)" + SEPARATOR + "([NS])" + SEPARATOR + "([\\d\\.]+)" + SEPARATOR + "([WE])" + SEPARATOR + "(-?[\\d\\.]+)" + SEPARATOR + "M" + SEPARATOR + "([\\d\\.]*)" + SEPARATOR + // UTC Time, hhmmss "[A]" + SEPARATOR + "(.*)" + SEPARATOR + // description, "(\\d*)" + // Date, ddmmyy END_OF_LINE); private static final NumberFormat ALTITUDE_NUMBER_FORMAT = DecimalFormat.getNumberInstance(Locale.US); static { ALTITUDE_NUMBER_FORMAT.setGroupingUsed(false); ALTITUDE_NUMBER_FORMAT.setMinimumFractionDigits(0); ALTITUDE_NUMBER_FORMAT.setMaximumFractionDigits(0); ALTITUDE_NUMBER_FORMAT.setMinimumIntegerDigits(6); ALTITUDE_NUMBER_FORMAT.setMaximumIntegerDigits(6); } public String getExtension() { return ".log"; } public String getName() { return "Magellan Explorist (*" + getExtension() + ")"; } @SuppressWarnings("unchecked") public <P extends NavigationPosition> NmeaRoute createRoute(RouteCharacteristics characteristics, String name, List<P> positions) { return new NmeaRoute(this, characteristics, (List<NmeaPosition>) positions); } protected boolean isPosition(String line) { Matcher matcher = TRK_PATTERN.matcher(line); return matcher.matches() && hasValidChecksum(line); } protected NmeaPosition parsePosition(String line) { Matcher matcher = TRK_PATTERN.matcher(line); if (matcher.matches()) { String latitude = matcher.group(1); String northOrSouth = matcher.group(2); String longitude = matcher.group(3); String westOrEast = matcher.group(4); String altitude = matcher.group(5); String time = matcher.group(6); String description = toMixedCase(matcher.group(7)); String date = matcher.group(8); return new NmeaPosition(parseDouble(longitude), westOrEast, parseDouble(latitude), northOrSouth, parseDouble(altitude), null, null, parseDateAndTime(date, time), trim(description)); } throw new IllegalArgumentException("'" + line + "' does not match"); } protected void writeHeader(PrintWriter writer) { writer.println(HEADER_LINE); } private String formatAltitude(Double aDouble) { if (aDouble == null) return "0"; return ALTITUDE_NUMBER_FORMAT.format(aDouble); } protected void writePosition(NmeaPosition position, PrintWriter writer) { ValueAndOrientation longitudeAsValueAndOrientation = position.getLongitudeAsValueAndOrientation(); String longitude = formatLongitude(longitudeAsValueAndOrientation.getValue()); String westOrEast = longitudeAsValueAndOrientation.getOrientation().value(); ValueAndOrientation latitudeAsValueAndOrientation = position.getLatitudeAsValueAndOrientation(); String latitude = formatLatitude(latitudeAsValueAndOrientation.getValue()); String northOrSouth = latitudeAsValueAndOrientation.getOrientation().value(); String description = escape(position.getDescription(), SEPARATOR, ';'); String time = formatTime(position.getTime()); String date = formatDate(position.getTime()); String altitude = formatAltitude(position.getElevation()); String trk = "PMGNTRK" + SEPARATOR + latitude + SEPARATOR + northOrSouth + SEPARATOR + longitude + SEPARATOR + westOrEast + SEPARATOR + altitude + SEPARATOR + "M" + SEPARATOR + time + SEPARATOR + "A" + SEPARATOR + description + SEPARATOR + date; writeSentence(writer, trk); } protected void writeFooter(PrintWriter writer) { writeSentence(writer, "PMGNCMD,END"); } }