package Parse; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.LinkedList; import java.util.TimeZone; import DataStructure.GPScoordinate; // Parse GPS textual file public class NMEAParse { private BufferedReader br; private FileReader fr; // private DateFormat time = new SimpleDateFormat("HHmmss.SSS"); private DateFormat date = new SimpleDateFormat("HHmmssddMMyy"); private DateFormat dateWithMillis = new SimpleDateFormat("HHmmss.SSSddMMyy"); private boolean QualityGood; private LinkedList GPSData = new LinkedList(); private int valid; // Constructor public NMEAParse(String fileName) { // Try open file read-only try { this.fr = new FileReader(fileName); this.br = new BufferedReader(this.fr); } catch (IOException e) { System.out.println("Cannot open file"); e.printStackTrace(); System.exit(-1); } try { Parse(); } catch (NumberFormatException e) { System.out.println("Cannot parse time"); e.printStackTrace(); } catch (IOException e) { System.out.println("Cannot read file"); e.printStackTrace(); } } private int getTimeDiff(Date UTCtime) { TimeZone tz = TimeZone.getDefault(); return tz.getOffset(UTCtime.getTime()); } private void Parse() throws NumberFormatException, IOException { Date time = new Date(); String content; // TimeZone tz = TimeZone.getDefault(); int utcDifference = 0; boolean timeSet = false; while ((content = br.readLine()) != null) { // check if something is wrong, for example more than one & is // inside if (StringIsWrong(content)) { continue; } // parse current Date if (content.contains("GPRMC")) { String[] Array = content.split(","); try { // DateFormat time = DateFormat.getTimeInstance(); String timeString = Array[1].concat(Array[9]); if (timeString.contains(".")) { time = dateWithMillis.parse(timeString); } else { time = this.date.parse(Array[1].concat(Array[9])); } // time.parse(Array[1].concat(Array[9]); // to current TimeZone // if TimeZone not yet checked, do it if (!timeSet) { utcDifference = getTimeDiff(time); // System.out.println("Found time difference: " // + utcDifference / (60 * 60 * 1000)); // timeSet = true; //time is set } time.setTime(time.getTime() + utcDifference); } catch (ParseException e) { // System.out.println("Cannot read time or date"); time = new Date(); // e.printStackTrace(); // continue; } // TODO: compare to current time. Add Time-Zone offset } // parse coordinates if (content.contains("$GPGGA")) { String[] Array = content.split(","); // Parse coordinate 1 in DEZ (GoogleEarth style coordinate) // see http://www.kowoma.de/gps/zusatzerklaerungen/NMEA.htm double coordNS = Double.parseDouble(Array[2].substring(0, 2)) + Double.parseDouble(Array[2].substring(2, Array[2].length())) / 60; char NS = Array[3].charAt(0); if (NS == 'S') coordNS = coordNS * (-1); // Parse coordinate 2 in DEZ (GoogleEarth style coordinate) double coordEW = Double.parseDouble(Array[4].substring(0, 3)) + Double.parseDouble(Array[4].substring(3, Array[4].length())) / 60; char EW = Array[5].charAt(0); if (EW == 'W') coordEW = coordEW * (-1); // check quality // String quality = "bad"; QualityGood = false; if (Integer.parseInt(Array[6]) == 1) { // quality = "GPS"; QualityGood = true; } if (Integer.parseInt(Array[6]) == 2) { // quality = "DGPS"; QualityGood = true; } // String justSeconds = "HH:mm:ss"; // String secondsAndMilliSeconds = "HH:mm:ss.SSS"; // return (new SimpleDateFormat(justSeconds).format(time) + ";" // + coordNS + ";" + NS + ";" + coordEW + ";" + EW + ";" + // quality); GPScoordinate currentGPS = new GPScoordinate(time, coordNS, NS, coordEW, EW, QualityGood); // currentGPS.coord1S = coordNSString; // currentGPS.coord2S = coordEWString; // check if currentGPS is valid if (currentGPS.isValid()) { GPSData.add(currentGPS); valid++; } } } System.out.println("Valid NMEA-Lines: " + valid); } /** * Returns true if something in this NMEA line is wrong * * @param content * @return */ private boolean StringIsWrong(String content) { // check if more than one $ is inside if (content.lastIndexOf('$') > 1) { return true; } return false; } public LinkedList getGPSList() { // remove first coordinate. Date might be set wrong; GPSData.remove(); return GPSData; } public double getMinX() { Iterator itr = GPSData.iterator(); GPScoordinate current; double min = 181; while (itr.hasNext()) { current = itr.next(); if (current.coord2 < min) min = current.coord2; } return min; } public double getMaxX() { Iterator itr = GPSData.iterator(); GPScoordinate current; double max = -181; while (itr.hasNext()) { current = itr.next(); if (current.coord2 > max) max = current.coord2; } return max; } public double getMinY() { Iterator itr = GPSData.iterator(); GPScoordinate current; double min = 181; while (itr.hasNext()) { current = itr.next(); if (current.coord1 < min) min = current.coord1; } return min; } public double getMaxY() { Iterator itr = GPSData.iterator(); GPScoordinate current; double max = -181; while (itr.hasNext()) { current = itr.next(); if (current.coord1 > max) max = current.coord1; } return max; } }