]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/load/NmeaFileLoader.java
Version 14, October 2012
[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                 String lastDate = null;
40                 try
41                 {
42                         reader = new BufferedReader(new FileReader(inFile));
43                         String currLine = reader.readLine();
44                         boolean newSegment = true;
45                         while (currLine != null)
46                         {
47                                 // Try to make an NmeaMessage object for each line of file
48                                 if (currLine.trim().length() > 0)
49                                 {
50                                         NmeaMessage message = processGGA(currLine);
51                                         if (message != null)
52                                         {
53                                                 if (message.hasFix())
54                                                 {
55                                                         message.setSegment(newSegment);
56                                                         message.setDate(lastDate);
57                                                         // add message to list
58                                                         messages.add(message);
59                                                 }
60                                                 // Start a new segment if fix lost
61                                                 newSegment = !message.hasFix();
62                                         }
63                                         else {
64                                                 String date = getDateFromRMC(currLine);
65                                                 if (date != null)
66                                                 {
67                                                         if (lastDate == null && !messages.isEmpty()) {
68                                                                 // Backfill first few messages received before the first date
69                                                                 for (int m=0; m<messages.size(); m++) {
70                                                                         messages.get(m).setDate(date);
71                                                                 }
72                                                         }
73                                                         lastDate = date;
74                                                 }
75                                         }
76                                 }
77                                 // Read next line, if any
78                                 currLine = reader.readLine();
79                         }
80                 }
81                 catch (IOException ioe) {
82                         _app.showErrorMessage("error.load.dialogtitle", "error.load.noread");
83                 }
84                 finally
85                 {
86                         // close file ignoring errors
87                         try {
88                                 if (reader != null) reader.close();
89                         }
90                         catch (Exception e) {}
91                 }
92                 if (messages.size() > 0)
93                 {
94                         _app.informDataLoaded(getFieldArray(), makeDataArray(messages),
95                                 Altitude.Format.METRES, new SourceInfo(inFile, SourceInfo.FILE_TYPE.NMEA),
96                                 null);
97                 }
98         }
99
100         /**
101          * Process the given GGA sentence and return the message
102          * @param inLine line to process
103          * @return message object
104          */
105         private static NmeaMessage processGGA(String inLine)
106         {
107                 // Only consider lines which are long enough and begin with the GPS position sentence
108                 if (inLine == null || inLine.length() < 20 || !inLine.startsWith("$GPGGA")) {
109                         return null;
110                 }
111                 // Assume comma delimiter, split into array
112                 String[] splitLine = inLine.split(",");
113                 if (splitLine != null && splitLine.length >= 10)
114                 {
115                         return new NmeaMessage(splitLine[2] + splitLine[3], // latitude
116                                 splitLine[4] + splitLine[5], // longitude
117                                 splitLine[9], // altitude
118                                 splitLine[1], // timestamp
119                                 splitLine[6]); // fix
120                 }
121                 // Couldn't parse it, return null
122                 return null;
123         }
124
125         /**
126          * Process the given MRC sentence and return the date
127          * @param inLine line to process
128          * @return date, if any
129          */
130         private static String getDateFromRMC(String inLine)
131         {
132                 // Only consider lines which are long enough and begin with the RMC sentence
133                 if (inLine == null || inLine.length() < 20 || !inLine.startsWith("$GPRMC")) {
134                         return null;
135                 }
136                 // Assume comma delimiter, split into array
137                 String[] splitLine = inLine.split(",");
138                 if (splitLine != null && splitLine.length >= 10)
139                 {
140                         return splitLine[9]; // date in position 9
141                 }
142                 // Couldn't parse it, return null
143                 return null;
144         }
145
146         /**
147          * Make an object array from the data list
148          * @param inList list of messages
149          * @return object array for loading
150          */
151         private static Object[][] makeDataArray(ArrayList<NmeaMessage> inList)
152         {
153                 Object[][] result = new Object[inList.size()][];
154                 for (int i=0; i<inList.size(); i++) {
155                         result[i] = inList.get(i).getStrings();
156                 }
157                 return result;
158         }
159
160         /**
161          * @see tim.prune.load.xml.XmlHandler#getFieldArray()
162          */
163         public Field[] getFieldArray()
164         {
165                 final Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.ALTITUDE,
166                         Field.TIMESTAMP, Field.NEW_SEGMENT};
167                 return fields;
168         }
169 }