class GPSParser:
def __init__(self, nmea_string):
self.nmea_string = nmea_string
self.data = {}
def parse(self):
if self.nmea_string.startswith('$GNRMC'):
self._parse_rmc()
elif self.nmea_string.startswith('$GNGGA'):
self._parse_gga()
elif self.nmea_string.startswith('$GNGSA'):
self._parse_gsa()
elif self.nmea_string.startswith('$GPGSV'):
self._parse_gsv()
def _parse_rmc(self):
fields = self.nmea_string.split(',')
self.data['time'] = fields[1]
self.data['status'] = fields[2]
self.data['lat'] = self._convert_latlon(fields[3])
self.data['lon'] = self._convert_latlon(fields[5])
self.data['speed'] = float(fields[7])
#self.data['course'] = float(fields[8])
def _parse_gga(self):
fields = self.nmea_string.split(',')
self.data['time'] = fields[1]
self.data['lat'] = self._convert_latlon(fields[2])
self.data['lon'] = self._convert_latlon(fields[4])
self.data['fix_quality'] = int(fields[6])
self.data['num_sats'] = int(fields[7])
self.data['altitude'] = float(fields[9])
def _parse_gsa(self):
fields = self.nmea_string.split(',')
self.data['mode'] = fields[1]
self.data['fix_type'] = int(fields[2])
self.data['sats'] = [int(sat) for sat in fields[3:15] if sat]
def _parse_gsv(self):
fields = self.nmea_string.split(',')
num_msgs = int(fields[1])
msg_num = int(fields[2])
num_sats = int(fields[3])
sats = []
for i in range(num_sats):
j = i * 4 + 4
if j + 3 < len(fields):
sats.append({
'id': int(fields[j]),
'elevation': int(fields[j + 1]),
'azimuth': int(fields[j + 2]),
'snr': int(fields[j + 3]),
})
if msg_num == 1:
self.data['sats'] = sats
else:
self.data['sats'].extend(sats)
def _convert_latlon(self, coord_str):
degrees = int(coord_str[:2])
minutes = float(coord_str[2:])
return degrees + minutes / 60
nmea_string = "$GNRMC,120533.00,A,3023.71432,N,00932.07743,W,0.058,,270223,,,A*7F"
parser = GPSParser(nmea_string)
parser.parse()
print(parser.data)