//parses the lat and long to a decimal format from DDMM.MMM format //conversion method in the Mapping class private GPSPacket latLongConvertToDbl(GPSPacket updatedGpsDataForLatLong) { Mapping mapObjectTemp = new Mapping(); //used just for the lat/long parsing method mapObjectTemp.parseLatLong(updatedGpsDataForLatLong.latitude, updatedGpsDataForLatLong.longitude, false); updatedGpsDataForLatLong.latitude = mapObjectTemp.latitudeD.ToString(); updatedGpsDataForLatLong.longitude = mapObjectTemp.longitudeD.ToString(); return(updatedGpsDataForLatLong); }
//-------------------END NEW PARSING METHODS------------------------- //Make sure the checksum is correct by generating a checksum from the string and comparing public GPSPacket getChecksum(string sentence, GPSPacket updatedGpsData, int sentenceType) { string checksum = "", checksumStr = ""; //Start with first Item int checksumCalc = Convert.ToByte(sentence[sentence.IndexOf('$') + 1]); // Loop through all chars to get a checksum for (int i = sentence.IndexOf('$') + 2; i < sentence.IndexOf('*'); i++) { // No. XOR the checksum with this character's value checksumCalc ^= Convert.ToByte(sentence[i]); } //convert the integer value to a 2-digit hex (in string representation) checksumStr = checksumCalc.ToString("X2"); switch (sentenceType) { //case 0 = GPRMC case 0: checksum = checksumGNRMC; break; case 1: checksum = checksumGNGGA; break; case 2: checksum = checksumGNVTG; break; default: break; } // Check what was parsed from the NMEA string and compare to the raw calculation if (checksumStr == checksum) { //checksum passed, return object return(updatedGpsData); } else { //the checksum has failed, note that in the field switch (sentenceType) { //case 0 = GPRMC case 0: checksumGNRMC = "FAIL"; break; //case 1 = GPGGA case 1: checksumGNGGA = "FAIL"; break; //case 2 = GTVTG case 2: checksumGNVTG = "FAIL"; break; default: break; } return(updatedGpsData); } }
private GPSPacket trackToCardinal(GPSPacket updatedGpsData) { //each degree direction corresponds to some cardinal direction //first convert trkangle to a double to evaluate it double trkAngle_double; bool result = Double.TryParse(updatedGpsData.trkangle, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out trkAngle_double); if (result == true) { if ((348.75 >= trkAngle_double && trkAngle_double <= 360) || ((0 >= trkAngle_double && trkAngle_double <= 33.75))) { updatedGpsData.cardAngle = "N"; } else if ((33.75 > trkAngle_double && trkAngle_double <= 78.75)) { updatedGpsData.cardAngle = "NE"; } else if ((78.75 > trkAngle_double && trkAngle_double <= 101.25)) { updatedGpsData.cardAngle = "E"; } else if ((101.25 > trkAngle_double && trkAngle_double <= 168.75)) { updatedGpsData.cardAngle = "SE"; } else if ((168.75 > trkAngle_double && trkAngle_double <= 213.75)) { updatedGpsData.cardAngle = "S"; } else if ((213.75 > trkAngle_double && trkAngle_double <= 258.75)) { updatedGpsData.cardAngle = "SW"; } else if ((258.75 > trkAngle_double && trkAngle_double <= 303.75)) { updatedGpsData.cardAngle = "W"; } else if ((303.75 > trkAngle_double && trkAngle_double < 348.75)) { updatedGpsData.cardAngle = "NW"; } } return(updatedGpsData); }
public void populateDbFields(GPSPacket gpsDataForDB) { //create a document fragment that will be appended to the existing XML XmlWriter addToDb = createXmlDbStructure(); addToDb.WriteStartElement("Packet"); //start packet addToDb.WriteAttributeString("ID", gpsDataForDB.packetID.ToString()); addToDb.WriteElementString("Date", gpsDataForDB.date); addToDb.WriteElementString("Time", gpsDataForDB.time); addToDb.WriteElementString("Latitude", gpsDataForDB.latitude); addToDb.WriteElementString("Longitude", gpsDataForDB.longitude); addToDb.WriteStartElement("GroundSpeed"); addToDb.WriteAttributeString("Type", "knots"); addToDb.WriteValue(gpsDataForDB.grspd_k); addToDb.WriteEndElement(); addToDb.WriteStartElement("GroundSpeed"); addToDb.WriteAttributeString("Type", "kph"); addToDb.WriteValue(gpsDataForDB.grspd_kph); addToDb.WriteEndElement(); addToDb.WriteElementString("Altitude", gpsDataForDB.altitude); addToDb.WriteStartElement("Angle"); addToDb.WriteAttributeString("Type", "Cardinal"); addToDb.WriteValue(gpsDataForDB.cardAngle); addToDb.WriteEndElement(); addToDb.WriteStartElement("Angle"); addToDb.WriteAttributeString("Type", "Degrees"); addToDb.WriteValue(gpsDataForDB.trkangle); addToDb.WriteEndElement(); addToDb.WriteElementString("Accuracy", gpsDataForDB.accuracy); addToDb.WriteElementString("FixType", gpsDataForDB.fixtype_f); addToDb.WriteElementString("FixQuality", gpsDataForDB.fixqual_f); addToDb.WriteElementString("NumSats", gpsDataForDB.numsats); addToDb.WriteElementString("ChecksumResult", gpsDataForDB.checksumResultStatusForDisplay); addToDb.WriteEndElement(); //end Packet addToDb.Flush(); }
//insert the data into the table public void populateDbFieldsGPS(GPSPacket gpsDataForDB) { try { //check where to append from - if table data already exists sql = "SELECT MAX(packetID) FROM gpsData"; cmd = new MySqlCommand(sql, conn); result = cmd.ExecuteScalar(); if (result != null) { r = Convert.ToInt32(result); } else { r = 1; } //append to the table if already existing result = null; //test writing new tables sql = @"insert into gpsData values(" + (r + 1) + "," //this is the overall DB ID + gpsDataForDB.gpsSessionID + ",'" //note this ID is the packet per session + gpsDataForDB.date + "','" + gpsDataForDB.time + "','" + gpsDataForDB.latitude + "','" + gpsDataForDB.longitude + "','" + gpsDataForDB.grspd_k + "','" + gpsDataForDB.grspd_kph + "','" + gpsDataForDB.altitude + "');"; cmd = new MySqlCommand(sql, conn); result = cmd.ExecuteScalar(); } catch (Exception ex) { throw ex; } }
public void populateDbFieldsVideo(GPSPacket gpsDataDb, VideoOutputWindow voForDb, string logReason) { try { //check where to append from - if table data already exists sql = "SELECT MAX(eventID) FROM videoLog"; cmd = new MySqlCommand(sql, conn); result = cmd.ExecuteScalar(); if (result != null) { r = Convert.ToInt32(result); } else { r = 2; } //append to the table if already existing result = null; //test writing new tables sql = @"insert into videoLog values(" + (r + 1) + ",'" //this is the overall DB ID + gpsDataDb.date + "','" + DateTime.Now.ToString("HH:mm:ss") + "','" //use the PC time since if GPS is stuck it'll report the same time! + gpsDataDb.latitude + "','" + gpsDataDb.longitude + "','" + voForDb.currentlyActiveCamera + "','" + voForDb.videoLogFilename + "','" + logReason + "','" //event descriptions + "27760934353" + //sms number "');"; cmd = new MySqlCommand(sql, conn); result = cmd.ExecuteScalar(); } catch (Exception ex) { throw ex; } }
/*----------------Time and Date Parsing Method * Input: GPSData object * Output: Time and date parsed correctly * Objective: parse time and date from raw numbers and letters to a nice format & to computable values. Assumed time HHMMSS.SSS and date DD/MM/YY */ private void timeNiceDisplay(GPSPacket updatedGpsData) { string newDateTime; //immutable string so make a new one to copy into string fixTime; //new temp string for date string format = "dd/MM/yyyy HH:mm:ss.fff"; //set date time format System.Globalization.CultureInfo provider = System.Globalization.CultureInfo.InvariantCulture; //provider for display of date and time SA style newDateTime = updatedGpsData.date.Insert(6, "20"); //assume 2 digit date >2000 //---for UI updatedGpsData.date = newDateTime; fixTime = updatedGpsData.time.Insert(2, ":").Insert(5, ":"); updatedGpsData.time = fixTime; //--end UI formatting //now format to a DateTime object for later calc newDateTime += " " + fixTime; updatedGpsData.dt = DateTime.ParseExact(newDateTime, format, provider); //this will be used for computation }
private GPSPacket parseGNVTG(string sentenceBuffer, GPSPacket gpsData) { int sectionCount = 0; string subField = ""; foreach (var item in sentenceBuffer) { if (item.ToString() != "*") //the asterisk specifies the end of line { if (item.ToString() == ",") //increment counter for next segment { sectionCount++; subField = ""; } switch (sectionCount) //store the fields based on the expected section { //GPVTG section 7 is speed in KPH; we need the speed in KPH case 7: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.grspd_kph = subField; //parse double to a string for display } break; default: break; } } else { break; } } //after the asterisk there's a few chars of checksum //checksum is the first char after the asterisk to the end checksumGNVTG = sentenceBuffer.Substring(sentenceBuffer.IndexOf('*') + 1); return(gpsData); }
private GPSPacket parseGNRMC(string sentenceBuffer, GPSPacket gpsData) { int sectionCount = 0; //count for subsections of the GPRMC string int dateCtr = 0; //for formatting the date nicely gpsData.date = ""; string subField = ""; foreach (var item in sentenceBuffer) { if (item.ToString() != "*") //the asterisk specifies the end of line { if (item.ToString() == ",") //increment counter for next segment { sectionCount++; subField = ""; } switch (sectionCount) //store the fields based on the expected section { case 0: break; //GPRMC section 1 = time in HHMMSS case 1: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.time = subField; } break; //GPRMC section 2 = fix, A or V case 2: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.fixtype = subField; //pick the 2nd char ",A" for example gpsData.friendlyFlagString(gpsData.fixtype, gpsData.fixqual); //get the friendly string for the fix } break; //GPRMC section 3 = Latitude DDMMSS.SSS case 3: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.latitude = subField; //parse double to a string for display } break; //GPRMC section 4 = Latitude Cardinal Heading case 4: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.latitude += subField; //add the cardinal heading to the latitude } break; //GPRMC section 5 = Longitude DDMMSS.SSS case 5: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.longitude = subField; //parse double to a string for display } break; //GPRMC section 6 = Longitude Cardinal Heading case 6: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.longitude += subField; //add the cardinal heading to the longitude } break; //GPRMC section 7 = Ground speed in Knots case 7: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.grspd_k = subField; } break; //GPRMC section 8 = Track angle in degrees true case 8: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.trkangle = subField; } break; //GPRMC section 9 = Date ,DD/MM/YY case 9: if (item.ToString() != ",") //make sure the comma isn't included { dateCtr++; if (dateCtr % 2 == 0) { subField = item.ToString(); gpsData.date += subField; gpsData.date += "/"; //format the date nicely } else { subField = item.ToString(); gpsData.date += subField; } } break; default: break; } } else { break; } } //after the asterisk there's a few chars of checksum //checksum is the first char after the asterisk to the end checksumGNRMC = sentenceBuffer.Substring(sentenceBuffer.IndexOf('*') + 1); //return completed packet return(gpsData); }
private GPSPacket parseGNGGA(string sentenceBuffer, GPSPacket gpsData) { int sectionCount = 0; string subField = ""; foreach (var item in sentenceBuffer) { if (item.ToString() != "*") //the asterisk specifies the end of line { if (item.ToString() == ",") //increment counter for next segment { sectionCount++; subField = ""; } switch (sectionCount) //store the fields based on the expected section { //GPGGA section 1 = time in HHMMSS case 1: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.time = subField; } break; //GPGGA section 3 = Latitude DDMMSS.SSS case 2: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.latitude = subField; //parse double to a string for display } break; //GPGGA section 4 = Latitude Cardinal Heading case 3: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.latitude += subField; //add the cardinal heading to the latitude } break; //GPGGA section 5 = Longitude DDMMSS.SSS case 4: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.longitude = subField; //parse double to a string for display } break; //GPGGA section 6 = Longitude Cardinal Heading case 5: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.longitude += subField; //add the cardinal heading to the longitude } break; //GPGGA section 5 is is the fix quality case 6: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.fixqual = subField; //add the cardinal heading to the latitude gpsData.friendlyFlagString(gpsData.fixtype, gpsData.fixqual); //get the friendly name of the fix quality } break; //GGA section 7 is the number of satellites in view case 7: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.numsats = subField; } break; //section 8 is the accuracy of the GPS fix case 8: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.accuracy = subField; } break; //section 9 is the altitude ASL case 9: if (item.ToString() != ",") //make sure the comma isn't included { subField += item; gpsData.altitude = subField; } break; default: break; } } else { break; } } //after the asterisk there's a few chars of checksum //checksum is the first char after the asterisk to the end checksumGNGGA = sentenceBuffer.Substring(sentenceBuffer.IndexOf('*') + 1); return(gpsData); }
//-------------------------PARSING MEMBER METHODS---------------------------- public GPSPacket parseSelection(string sentenceBuffer, GPSPacket gpsDataForParsing, bool usingWebLogging, int refPackID) { GPSPacket updatedGpsData = new GPSPacket(); //sets up a new object which methods return with updated values if (usingWebLogging == true) //we've got the webserver response OR a failed packet { if (!sentenceBuffer.Contains(";")) { return(updatedGpsData); //the sentence is invalid } else { updatedGpsData = newParsingMethod(sentenceBuffer, gpsDataForParsing); //parse the incoming string if (updatedGpsData.packetID > refPackID || gpsDataForParsing.packetID == 0) { updatedGpsData.globalID = updatedGpsData.globalID + 1; return(updatedGpsData); } return(updatedGpsData); } } //-----------------original NMEA parsing------------------- else //this is a NMEA string and so it starts with a '$" { if (!(sentenceBuffer.StartsWith("$"))) //we've got the webserver response OR a failed packet { return(updatedGpsData); } if (sentenceBuffer.Contains("GNRMC")) //We assume that each "packet" of sentences begins with a GPRMC hence update the packet ID each time a GPRMC is found! { packetID++; updatedGpsData.packetID = packetID; updatedGpsData = parseGNRMC(sentenceBuffer, gpsDataForParsing); updatedGpsData = getChecksum(sentenceBuffer, updatedGpsData, 0); //checksum compute with GPRMC //do some last-minute formatting to the fields based on known issues updatedGpsData.date = updatedGpsData.date.TrimEnd('/'); //remove trailing "/" if (updatedGpsData.time.StartsWith("0") || updatedGpsData.longitude.StartsWith("0") || updatedGpsData.latitude.StartsWith("0")) { //updatedGpsData.time = updatedGpsData.time.TrimStart('0'); //remove leading zeroes // updatedGpsData.latitude = updatedGpsData.latitude.TrimStart('0'); // updatedGpsData.longitude = updatedGpsData.longitude.TrimStart('0'); } //convert the track angle in degrees true to a cardinal heading trackToCardinal(updatedGpsData); //convert the time from a horrible string to something nice timeNiceDisplay(updatedGpsData); //convert the latitude and longitude from DDMM.MMM(H) to decimal (for Maps and calculations) ///updatedGpsData = latLongConvertToDbl(updatedGpsData); return(updatedGpsData); } else if (sentenceBuffer.Contains("GPGGA")) { updatedGpsData = parseGNGGA(sentenceBuffer, gpsDataForParsing); updatedGpsData = getChecksum(sentenceBuffer, updatedGpsData, 1); //checksum compute with GPGGA return(updatedGpsData); } else if (sentenceBuffer.Contains("GPVTG")) { updatedGpsData = parseGNVTG(sentenceBuffer, gpsDataForParsing); updatedGpsData = getChecksum(sentenceBuffer, updatedGpsData, 2); //checksum compute with GPVTG //trim off leading zeroes from the speed if (updatedGpsData.grspd_kph.StartsWith("0")) { updatedGpsData.grspd_kph = updatedGpsData.grspd_kph.TrimStart('0'); } return(updatedGpsData); } else { return(updatedGpsData); //we don't consider all the other NMEA strings } } }
//-------------------NEW PARSING METHOD------------------------------ public GPSPacket newParsingMethod(string incomingBuffer, GPSPacket gpsData) { //incoming format //PID ; SID ; Date ; Time; Lat; Long Spd; Alt //7711; 1483; 2016 - 10 - 29; 17:20:21; -29.868922; 30.979895; 0.02; 152.2069 int sectionCount = 0; string subField = ""; //strip out incoming buffer spaces incomingBuffer = incomingBuffer.Replace(" ", ""); foreach (var item in incomingBuffer) { if (item.ToString() != "*") //the asterisk specifies the end of line { if (item.ToString() == ";") //increment counter for next segment { sectionCount++; subField = ""; } switch (sectionCount) //store the fields based on the expected section { //Section 1 is the global packet ID case 0: if (item.ToString() != ";") //make sure the comma isn't included { subField += item; gpsData.packetID = Convert.ToInt32(subField); //parse string to a string for display } break; //Section 2 is the GPS session packet ID case 1: if (item.ToString() != ";") //make sure the comma isn't included { subField += item; gpsData.gpsSessionID = Convert.ToInt32(subField); //parse string to a string for display } break; //Section 3 is the date case 2: if (item.ToString() != ";") //make sure the comma isn't included { subField += item; gpsData.date = subField; //parse string to a string for display } break; //Section 4 is the time case 3: if (item.ToString() != ";") //make sure the comma isn't included { subField += item; gpsData.time = subField; //parse string to a string for display } break; //Section 5 is the lat case 4: if (item.ToString() != ";") //make sure the comma isn't included { subField += item; gpsData.latitude = subField; //parse string to a string for display } break; //Section 6 is the long case 5: if (item.ToString() != ";") //make sure the comma isn't included { subField += item; gpsData.longitude = subField; //parse string to a string for display } break; case 6: if (item.ToString() != ";") //make sure the comma isn't included { subField += item; gpsData.grspd_kph = subField; //parse string to a string for display } break; case 7: if (item.ToString() != ";") //make sure the comma isn't included { subField += item; gpsData.altitude = subField; //parse string to a string for display } break; default: break; } } else { break; } } return(gpsData); }