summaryrefslogblamecommitdiffstats
path: root/Parse/NMEAParse.java
blob: 0f88cd3c3def4d49652be0f58a327614adaadbdc (plain) (tree)































































































































































































































                                                                                                  
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<GPScoordinate> GPSData = new LinkedList<GPScoordinate>();
	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<GPScoordinate> getGPSList() {
		// remove first coordinate. Date might be set wrong;
		GPSData.remove();
		return GPSData;
	}

	public double getMinX() {
		Iterator<GPScoordinate> 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<GPScoordinate> 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<GPScoordinate> 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<GPScoordinate> itr = GPSData.iterator();
		GPScoordinate current;
		double max = -181;
		while (itr.hasNext()) {
			current = itr.next();
			if (current.coord1 > max)
				max = current.coord1;
		}
		return max;
	}
}