]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/load/NmeaFileLoader.java
Version 9, February 2010
[GpsPrune.git] / tim / prune / load / NmeaFileLoader.java
1 package tim.prune.load;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileReader;
6 import java.io.IOException;
7 import java.util.ArrayList;
8
9 import tim.prune.App;
10 import tim.prune.data.Altitude;
11 import tim.prune.data.Field;
12 import tim.prune.data.SourceInfo;
13
14 /**
15  * Class to handle the loading of Nmea files
16  */
17 public class NmeaFileLoader
18 {
19         /** App for callback of file loading */
20         private App _app = null;
21
22         /**
23          * Constructor
24          * @param inApp App object
25          */
26         public NmeaFileLoader(App inApp)
27         {
28                 _app = inApp;
29         }
30
31         /**
32          * Open the selected file
33          * @param inFile File to open
34          */
35         public void openFile(File inFile)
36         {
37                 BufferedReader reader = null;
38                 ArrayList<NmeaMessage> messages = new ArrayList<NmeaMessage>();
39                 try
40                 {
41                         reader = new BufferedReader(new FileReader(inFile));
42                         String currLine = reader.readLine();
43                         boolean newSegment = true;
44                         while (currLine != null)
45                         {
46                                 // Try to make an NmeaMessage object for each line of file
47                                 if (currLine.trim().length() > 0)
48                                 {
49                                         NmeaMessage message = processLine(currLine);
50                                         if (message != null)
51                                         {
52                                                 if (message.hasFix()) {
53                                                         message.setSegment(newSegment);
54                                                         // add message to list
55                                                         messages.add(message);
56                                                 }
57                                                 // Start a new segment if fix lost
58                                                 newSegment = !message.hasFix();
59                                         }
60                                 }
61                                 // Read next line, if any
62                                 currLine = reader.readLine();
63                         }
64                 }
65                 catch (IOException ioe) {
66                         _app.showErrorMessage("error.load.dialogtitle", "error.load.noread");
67                 }
68                 finally
69                 {
70                         // close file ignoring errors
71                         try
72                         {
73                                 if (reader != null) reader.close();
74                         }
75                         catch (Exception e) {}
76                 }
77                 if (messages.size() > 0)
78                 {
79                         _app.informDataLoaded(getFieldArray(), makeDataArray(messages),
80                                 Altitude.Format.METRES, new SourceInfo(inFile, SourceInfo.FILE_TYPE.NMEA));
81                 }
82         }
83
84         /**
85          * Process the given NMEA line and return the message
86          * @param inLine line to process
87          * @return message object
88          */
89         private static NmeaMessage processLine(String inLine)
90         {
91                 // Only consider lines which are long enough and begin with the GPS position sentence
92                 if (inLine == null || inLine.length() < 20 || !inLine.startsWith("$GPGGA")) {
93                         return null;
94                 }
95                 // TODO: May be possible to pull date out of GPRMC messages, but then need to back-populate
96                 // Assume comma delimiter, split into array
97                 String[] splitLine = inLine.split(",");
98                 if (splitLine != null && splitLine.length >= 10)
99                 {
100                         return new NmeaMessage(splitLine[2] + splitLine[3], // latitude
101                                 splitLine[4] + splitLine[5], // longitude
102                                 splitLine[9], // altitude
103                                 splitLine[1], // timestamp
104                                 splitLine[6]); // fix
105                 }
106                 // Couldn't parse it, return null
107                 return null;
108         }
109
110         /**
111          * Make an object array from the data list
112          * @param inList list of messages
113          * @return object array for loading
114          */
115         private static Object[][] makeDataArray(ArrayList<NmeaMessage> inList)
116         {
117                 Object[][] result = new Object[inList.size()][];
118                 for (int i=0; i<inList.size(); i++) {
119                         result[i] = inList.get(i).getStrings();
120                 }
121                 return result;
122         }
123
124         /**
125          * @see tim.prune.load.xml.XmlHandler#getFieldArray()
126          */
127         public Field[] getFieldArray()
128         {
129                 final Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.ALTITUDE,
130                         Field.TIMESTAMP, Field.NEW_SEGMENT};
131                 return fields;
132         }
133 }