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