📄 nmeaparser.java
字号:
*
* @param array is the data to scan.
* @param b is the byte to match.
* @param fromIndex is the first index into array to check.
* @return The last index where <code>b</code> was found; -1 if it was not
* found.
*/
protected static int lastIndexOf (byte[] array, byte b, int fromIndex)
{
for ( int position = fromIndex; position >= 0; position-- )
{
if ( array[position] == b )
{
return position;
}
}
// If we made it here, b was not found.
return -1;
}
/**
* @return The lastest location information.
*/
public synchronized GPSRecord getRecordBuffer() {
return recordBuffer;
}
/**
* @param record is the latest location information.
*/
private synchronized void setRecordBuffer(GPSRecord record) {
this.recordBuffer = record;
}
/**
* Process the sentence of the specified type. The sentence is
* every ASCII character stored in <code>data</code> between <code>offset</code>
* and <code>stop</code>.
*
* @param data contains the NMEA sentence to process.
* @param offset is the index that starts the NMEA sentence within <code>data</code>.
* @param stop is the index of the final character in the sentence.
* @param type - the sentence type
* @return the type of the setence processed. If the sentence cannot be
* processed this returns 0.
*/
private short processSentence(byte[] data, int offset, int stop, short type) {
// The index of the current token
short tokenIndex = 0;
// The boundaries of the current token
int tokenStart = 0;
// The calculated check sum
int checksum = 0;
// The check sum read from the sentence
int sentChecksum = 0;
// If the sentence is greater than the max size just discard it
if ( stop - offset <= MAX_SENTENCE_SIZE) {
SentenceData sentenceData = contructSentenceData(type);
for (int i = offset; i < stop; i++) {
byte character = data[i];
if (character == SENTENCE_START) {
// Ignore the dollar sign
} else if (character == CHECKSUM_START) {
// First process the remaining token
sentenceData.processToken(tokenIndex, data, tokenStart, i - tokenStart);
// get the sent check sum
try {
String transmittedChecksum = new String( data, i + 1, 2 );
sentChecksum = Integer.valueOf(transmittedChecksum, 16).intValue();
} catch (NumberFormatException nfe) {
// The check sum was corrupt so discard the sentence.
return TYPE_NONE;
}
// Stop processing
break;
} else {
// XOR the checksum with this character's value
checksum ^= character;
// If this is the delimiter, store the token
if (character == DELIMITER) {
sentenceData.processToken(tokenIndex, data, tokenStart, i - tokenStart);
tokenIndex++;
tokenStart = i + 1;
}
}
}
// Check if the check sums match
if (checksum == sentChecksum) {
// Apply the sentence data to the record
sentenceData.applySentenceData(record);
// return the type that we processed
return type;
}
}
return TYPE_NONE;
}
/**
* Contruct an instance of the sentence data interface that is appropriate
* for the type passed in.
*
* @param type - the type
* @return the appropriate sentence data implementation instance
*/
private SentenceData contructSentenceData(int type) {
switch (type) {
case TYPE_GPRMC:
return new GPRMCRecord();
case TYPE_GPGGA:
return new GPGGARecord();
case TYPE_GPGSA:
return new GPGSARecord();
default:
return null;
}
}
/**
* Interface implemented by classes that know the structure of
* NMEA sentences.
*/
private static interface SentenceData {
/**
* Processes a token within a NMEA sentence. Tokens are the data
* between commas.
*
* @param tokenIndex is the number of commas that have been seen.
* @param data contains the NMEA sentence to process.
* @param offset is the index that starts the NMEA sentence within <code>data</code>.
* @param length is the number of bytes the token is.
*/
public void processToken(short tokenIndex, byte[] data, int offset, int length);
/**
* Signals that the location data of the class should be stored in
* <code>record</code>.
*
* @param record is the most current GPS data.
*/
public void applySentenceData(GPSRecord record);
}
/**
* $GPGSA NMEA 0183 sentence. This sentence contains the accuracy (both
* horizontal and vertical) of the reading.
*/
private static final class GPGSARecord implements SentenceData {
public String hdop = null;
public String vdop = null;
public void processToken(short tokenIndex, byte[] data, int offset, int length) {
switch (tokenIndex) {
case 16:
hdop = new String( data, offset, length );
break;
case 17:
vdop = new String( data, offset, length );
break;
}
}
public void applySentenceData(GPSRecord record) {
record.hdop = hdop;
record.vdop = vdop;
}
}
/**
* $GPGGA NMEA 0183 sentence. This sentence the altitude of coordinates.
*/
private static final class GPGGARecord implements SentenceData {
public String quality = null;
public String satelliteCount = null;
public String altitude = null;
public void processToken(short tokenIndex, byte[] data, int offset, int length) {
switch (tokenIndex) {
case 6:
quality = new String( data, offset, length );
break;
case 7:
satelliteCount = new String( data, offset, length );
break;
case 9:
if ( length > 0 ) {
altitude = new String( data, offset, length );
} else {
altitude = null;
}
break;
}
}
public void applySentenceData(GPSRecord record) {
record.quality = quality;
record.satelliteCount = satelliteCount;
record.altitude = altitude;
}
}
/**
* $GPRMC NMEA 0183 sentence. This sentence the latitude, longitude,
* speed, and course.
*/
private static final class GPRMCRecord implements SentenceData {
public String date = null;
public String secondsSinceMidnight = null;
public String lattitude = null;
public char lattitudeDirection;
public String longitude = null;
public char longitudeDirection;
private String speed = null;
private String course = null;
public void processToken(short tokenIndex, byte[] data, int offset, int length) {
switch (tokenIndex) {
case 1:
secondsSinceMidnight = new String( data, offset, length );
break;
case 3:
lattitude = new String( data, offset, length );
break;
case 4:
if (length > 0) {
lattitudeDirection = (char)data[offset];
}
break;
case 5:
longitude = new String( data, offset, length );
break;
case 6:
if (length > 0) {
longitudeDirection = (char)data[offset];
}
break;
case 7:
speed = new String( data, offset, length );
break;
case 8:
if (length > 0) {
course = new String( data, offset, length );
}
break;
case 9:
if (length == 6) {
date = new String( data, offset, length );
}
break;
}
}
public void applySentenceData(GPSRecord record) {
record.date = date;
record.secondsSinceMidnight = secondsSinceMidnight;
record.lattitude = lattitude;
record.lattitudeDirection = lattitudeDirection;
record.longitude = longitude;
record.longitudeDirection = longitudeDirection;
record.speed = speed;
record.course = course;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -