]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/load/NmeaFileLoader.java
76ed15785dc1fff93ec18661790e8c9955539711
[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                 }
97         }
98
99         /**
100          * Process the given GGA sentence and return the message
101          * @param inLine line to process
102          * @return message object
103          */
104         private static NmeaMessage processGGA(String inLine)
105         {
106                 // Only consider lines which are long enough and begin with the GPS position sentence
107                 if (inLine == null || inLine.length() < 20 || !inLine.startsWith("$GPGGA")) {
108                         return null;
109                 }
110                 // Assume comma delimiter, split into array
111                 String[] splitLine = inLine.split(",");
112                 if (splitLine != null && splitLine.length >= 10)
113                 {
114                         return new NmeaMessage(splitLine[2] + splitLine[3], // latitude
115                                 splitLine[4] + splitLine[5], // longitude
116                                 splitLine[9], // altitude
117                                 splitLine[1], // timestamp
118                                 splitLine[6]); // fix
119                 }
120                 // Couldn't parse it, return null
121                 return null;
122         }
123
124         /**
125          * Process the given MRC sentence and return the date
126          * @param inLine line to process
127          * @return date, if any
128          */
129         private static String getDateFromRMC(String inLine)
130         {
131                 // Only consider lines which are long enough and begin with the RMC sentence
132                 if (inLine == null || inLine.length() < 20 || !inLine.startsWith("$GPRMC")) {
133                         return null;
134                 }
135                 // Assume comma delimiter, split into array
136                 String[] splitLine = inLine.split(",");
137                 if (splitLine != null && splitLine.length >= 10)
138                 {
139                         return splitLine[9]; // date in position 9
140                 }
141                 // Couldn't parse it, return null
142                 return null;
143         }
144
145         /**
146          * Make an object array from the data list
147          * @param inList list of messages
148          * @return object array for loading
149          */
150         private static Object[][] makeDataArray(ArrayList<NmeaMessage> inList)
151         {
152                 Object[][] result = new Object[inList.size()][];
153                 for (int i=0; i<inList.size(); i++) {
154                         result[i] = inList.get(i).getStrings();
155                 }
156                 return result;
157         }
158
159         /**
160          * @see tim.prune.load.xml.XmlHandler#getFieldArray()
161          */
162         public Field[] getFieldArray()
163         {
164                 final Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.ALTITUDE,
165                         Field.TIMESTAMP, Field.NEW_SEGMENT};
166                 return fields;
167         }
168 }