]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/load/NmeaFileLoader.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / src / tim / prune / load / NmeaFileLoader.java
diff --git a/src/tim/prune/load/NmeaFileLoader.java b/src/tim/prune/load/NmeaFileLoader.java
new file mode 100644 (file)
index 0000000..d62ba5f
--- /dev/null
@@ -0,0 +1,167 @@
+package tim.prune.load;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import tim.prune.App;
+import tim.prune.data.Field;
+import tim.prune.data.SourceInfo;
+
+/**
+ * Class to handle the loading of Nmea files
+ */
+public class NmeaFileLoader
+{
+       /** App for callback of file loading */
+       private App _app = null;
+
+       /**
+        * Constructor
+        * @param inApp App object
+        */
+       public NmeaFileLoader(App inApp)
+       {
+               _app = inApp;
+       }
+
+       /**
+        * Open the selected file
+        * @param inFile File to open
+        */
+       public void openFile(File inFile)
+       {
+               BufferedReader reader = null;
+               ArrayList<NmeaMessage> messages = new ArrayList<NmeaMessage>();
+               String lastDate = null;
+               try
+               {
+                       reader = new BufferedReader(new FileReader(inFile));
+                       String currLine = reader.readLine();
+                       boolean newSegment = true;
+                       while (currLine != null)
+                       {
+                               // Try to make an NmeaMessage object for each line of file
+                               if (currLine.trim().length() > 0)
+                               {
+                                       NmeaMessage message = processGGA(currLine);
+                                       if (message != null)
+                                       {
+                                               if (message.hasFix())
+                                               {
+                                                       message.setSegment(newSegment);
+                                                       message.setDate(lastDate);
+                                                       // add message to list
+                                                       messages.add(message);
+                                               }
+                                               // Start a new segment if fix lost
+                                               newSegment = !message.hasFix();
+                                       }
+                                       else {
+                                               String date = getDateFromRMC(currLine);
+                                               if (date != null)
+                                               {
+                                                       if (lastDate == null && !messages.isEmpty()) {
+                                                               // Backfill first few messages received before the first date
+                                                               for (int m=0; m<messages.size(); m++) {
+                                                                       messages.get(m).setDate(date);
+                                                               }
+                                                       }
+                                                       lastDate = date;
+                                               }
+                                       }
+                               }
+                               // Read next line, if any
+                               currLine = reader.readLine();
+                       }
+               }
+               catch (IOException ioe) {
+                       _app.showErrorMessage("error.load.dialogtitle", "error.load.noread");
+               }
+               finally
+               {
+                       // close file ignoring errors
+                       try {
+                               if (reader != null) reader.close();
+                       }
+                       catch (Exception e) {}
+               }
+               if (messages.size() > 0)
+               {
+                       _app.informDataLoaded(getFieldArray(), makeDataArray(messages),
+                               null, new SourceInfo(inFile, SourceInfo.FILE_TYPE.NMEA), null);
+               }
+       }
+
+       /**
+        * Process the given GGA sentence and return the message
+        * @param inLine line to process
+        * @return message object
+        */
+       private static NmeaMessage processGGA(String inLine)
+       {
+               // Only consider lines which are long enough and begin with the GPS position sentence
+               if (inLine == null || inLine.length() < 20 || !inLine.startsWith("$GPGGA")) {
+                       return null;
+               }
+               // Assume comma delimiter, split into array
+               String[] splitLine = inLine.split(",");
+               if (splitLine != null && splitLine.length >= 10)
+               {
+                       return new NmeaMessage(splitLine[2] + splitLine[3], // latitude
+                               splitLine[4] + splitLine[5], // longitude
+                               splitLine[9], // altitude
+                               splitLine[1], // timestamp
+                               splitLine[6]); // fix
+               }
+               // Couldn't parse it, return null
+               return null;
+       }
+
+       /**
+        * Process the given MRC sentence and return the date
+        * @param inLine line to process
+        * @return date, if any
+        */
+       private static String getDateFromRMC(String inLine)
+       {
+               // Only consider lines which are long enough and begin with the RMC sentence
+               if (inLine == null || inLine.length() < 20 || !inLine.startsWith("$GPRMC")) {
+                       return null;
+               }
+               // Assume comma delimiter, split into array
+               String[] splitLine = inLine.split(",");
+               if (splitLine != null && splitLine.length >= 10)
+               {
+                       return splitLine[9]; // date in position 9
+               }
+               // Couldn't parse it, return null
+               return null;
+       }
+
+       /**
+        * Make an object array from the data list
+        * @param inList list of messages
+        * @return object array for loading
+        */
+       private static Object[][] makeDataArray(ArrayList<NmeaMessage> inList)
+       {
+               Object[][] result = new Object[inList.size()][];
+               for (int i=0; i<inList.size(); i++) {
+                       result[i] = inList.get(i).getStrings();
+               }
+               return result;
+       }
+
+       /**
+        * @see tim.prune.load.xml.XmlHandler#getFieldArray()
+        */
+       public Field[] getFieldArray()
+       {
+               final Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.ALTITUDE,
+                       Field.TIMESTAMP, Field.NEW_SEGMENT};
+               return fields;
+       }
+}