1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
package tim.prune.load;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import tim.prune.App;
import tim.prune.data.Altitude;
import tim.prune.data.DataPoint;
import tim.prune.data.FileType;
import tim.prune.data.Latitude;
import tim.prune.data.Longitude;
import tim.prune.data.SourceInfo;
import tim.prune.data.UnitSetLibrary;
/**
* Class to handle the loading of Nmea files
*/
public class NmeaFileLoader extends FileTypeLoader
{
/**
* Constructor
* @param inApp App object
*/
public NmeaFileLoader(App inApp) {
super(inApp);
}
/**
* Open the selected file
* @param inFileLock File to open
* @param inAutoAppend true to automatically append
*/
public void openFile(FileToBeLoaded inFileLock, boolean inAutoAppend)
{
BufferedReader reader = null;
ArrayList<NmeaMessage> messages = new ArrayList<NmeaMessage>();
String lastDate = null;
try
{
reader = new BufferedReader(new FileReader(inFileLock.getFile()));
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 (NmeaMessage msg : messages) {
msg.setDate(date);
}
}
lastDate = date;
}
}
}
// Read next line, if any
currLine = reader.readLine();
}
}
catch (IOException ioe) {
getApp().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)
{
int appendOption = getAppendOption(inAutoAppend);
if (appendOption == JOptionPane.CANCEL_OPTION) {
return;
}
loadData(makePointList(messages), new SourceInfo(inFileLock.getFile(), FileType.NMEA),
appendOption == JOptionPane.YES_OPTION);
}
}
/**
* 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 List<DataPoint> makePointList(ArrayList<NmeaMessage> inList)
{
ArrayList<DataPoint> points = new ArrayList<>();
for (NmeaMessage nmea : inList)
{
DataPoint point = new DataPoint(Latitude.make(nmea.getLatitude()),
Longitude.make(nmea.getLongitude()),
new Altitude(nmea.getAltitude(), UnitSetLibrary.UNITS_METRES));
point.setSegmentStart(nmea.getSegmentFlag());
points.add(point);
}
return points;
}
}
|