-
-
Save javisantana/1326141 to your computer and use it in GitHub Desktop.
this software is under the terms of MIT license: http://opensource.org/licenses/MIT |
package es.agroguia.model; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class NMEA { | |
interface SentenceParser { | |
public boolean parse(String [] tokens, GPSPosition position); | |
} | |
// utils | |
static float Latitude2Decimal(String lat, String NS) { | |
float med = Float.parseFloat(lat.substring(2))/60.0f; | |
med += Float.parseFloat(lat.substring(0, 2)); | |
if(NS.startsWith("S")) { | |
med = -med; | |
} | |
return med; | |
} | |
static float Longitude2Decimal(String lon, String WE) { | |
float med = Float.parseFloat(lon.substring(3))/60.0f; | |
med += Float.parseFloat(lon.substring(0, 3)); | |
if(WE.startsWith("W")) { | |
med = -med; | |
} | |
return med; | |
} | |
// parsers | |
class GPGGA implements SentenceParser { | |
public boolean parse(String [] tokens, GPSPosition position) { | |
position.time = Float.parseFloat(tokens[1]); | |
position.lat = Latitude2Decimal(tokens[2], tokens[3]); | |
position.lon = Longitude2Decimal(tokens[4], tokens[5]); | |
position.quality = Integer.parseInt(tokens[6]); | |
position.altitude = Float.parseFloat(tokens[9]); | |
return true; | |
} | |
} | |
class GPGGL implements SentenceParser { | |
public boolean parse(String [] tokens, GPSPosition position) { | |
position.lat = Latitude2Decimal(tokens[1], tokens[2]); | |
position.lon = Longitude2Decimal(tokens[3], tokens[4]); | |
position.time = Float.parseFloat(tokens[5]); | |
return true; | |
} | |
} | |
class GPRMC implements SentenceParser { | |
public boolean parse(String [] tokens, GPSPosition position) { | |
position.time = Float.parseFloat(tokens[1]); | |
position.lat = Latitude2Decimal(tokens[3], tokens[4]); | |
position.lon = Longitude2Decimal(tokens[5], tokens[6]); | |
position.velocity = Float.parseFloat(tokens[7]); | |
position.dir = Float.parseFloat(tokens[8]); | |
return true; | |
} | |
} | |
class GPVTG implements SentenceParser { | |
public boolean parse(String [] tokens, GPSPosition position) { | |
position.dir = Float.parseFloat(tokens[3]); | |
return true; | |
} | |
} | |
class GPRMZ implements SentenceParser { | |
public boolean parse(String [] tokens, GPSPosition position) { | |
position.altitude = Float.parseFloat(tokens[1]); | |
return true; | |
} | |
} | |
public class GPSPosition { | |
public float time = 0.0f; | |
public float lat = 0.0f; | |
public float lon = 0.0f; | |
public boolean fixed = false; | |
public int quality = 0; | |
public float dir = 0.0f; | |
public float altitude = 0.0f; | |
public float velocity = 0.0f; | |
public void updatefix() { | |
fixed = quality > 0; | |
} | |
public String toString() { | |
return String.format("POSITION: lat: %f, lon: %f, time: %f, Q: %d, dir: %f, alt: %f, vel: %f", lat, lon, time, quality, dir, altitude, velocity); | |
} | |
} | |
GPSPosition position = new GPSPosition(); | |
private static final Map<String, SentenceParser> sentenceParsers = new HashMap<String, SentenceParser>(); | |
public NMEA() { | |
sentenceParsers.put("GPGGA", new GPGGA()); | |
sentenceParsers.put("GPGGL", new GPGGL()); | |
sentenceParsers.put("GPRMC", new GPRMC()); | |
sentenceParsers.put("GPRMZ", new GPRMZ()); | |
//only really good GPS devices have this sentence but ... | |
sentenceParsers.put("GPVTG", new GPVTG()); | |
} | |
public GPSPosition parse(String line) { | |
if(line.startsWith("$")) { | |
String nmea = line.substring(1); | |
String[] tokens = nmea.split(","); | |
String type = tokens[0]; | |
//TODO check crc | |
if(sentenceParsers.containsKey(type)) { | |
sentenceParsers.get(type).parse(tokens, position); | |
} | |
position.updatefix(); | |
} | |
return position; | |
} | |
} |
Here is some very basic test code:
public class TestMain
{
static String GPGGA_Test = "$GPGGA,211034,4738.9577,N,12220.9329,W,1,09,1.0,10.8,M,-18.4,M,,*42";
public static void main(String [ ] args)
{
NMEA nmea = new NMEA();
nmea.parse(GPGGA_Test);
System.out.println(nmea.position);
}
}
Hi wb9coy,
Degrees could be a one, two or three digit number. So your implementation of latitude and longitude will be wrong in other scenarios. Correct way would be as follows:
// utils
static float Latitude2Decimal(String lat, String NS) {
int minutesPosition = lat.indexOf('.') - 2;
float minutes = Float.parseFloat(lat.substring(minutesPosition));
float decimalDegrees = Float.parseFloat(lat.substring(minutesPosition))/60.0f;
float degree = Float.parseFloat(lat) - minutes;
float wholeDegrees = (int)degree/100;
float latitudeDegrees = wholeDegrees + decimalDegrees;
if(NS.startsWith("S")) {
latitudeDegrees = -latitudeDegrees;
}
return latitudeDegrees;
}
static float Longitude2Decimal(String lon, String WE) {
int minutesPosition = lon.indexOf('.') - 2;
float minutes = Float.parseFloat(lon.substring(minutesPosition));
float decimalDegrees = Float.parseFloat(lon.substring(minutesPosition))/60.0f;
float degree = Float.parseFloat(lon) - minutes;
float wholeDegrees = (int)degree/100;
float longitudeDegrees = wholeDegrees + decimalDegrees;
if(WE.startsWith("W")) {
longitudeDegrees = -longitudeDegrees;
}
return longitudeDegrees;
}`
pls. any help as I am also a new java user
why no result shown when running this example
public class TestMain
{
static String GPGGA_Test = "$GPGGA,211034,4738.9577,N,12220.9329,W,1,09,1.0,10.8,M,-18.4,M,,*42";
public static void main(String [ ] args)
{
NMEA nmea = new NMEA();
nmea.parse(GPGGA_Test);
System.out.println(nmea.position);
- No "try.. catch" in parseFloats - the NMEA receivers in non-established state cause exception and overall fault
- No "GNGGA" and others - mainly now data is gathered from GPS, GLONASS and Galileo +BeiDou sometimes and reports GNRMC etc not GPRMC and etc.
- No support for feeding data(incomplete sentences will be lost)
- does not suck 👍
Not too much good...Lat and Lon must to be double instead of float
thanks for the comments. This code is not meant to do everything but is that simple that you can modify and adapt to your needs. So instead of using a huge library you don't understand, you use a small piece of code you know how it works and everybody can read and understand in 5 minutes.
Hey Mate.
I am very new to java do you have a usage example?