/// <summary> /// Reads the current latitude and longitude from the next available sentence. /// </summary> /// <returns></returns> public Position ReadPosition() { // Does it support the value we want? IPositionSentence sentence = ReadTypedSentence() as IPositionSentence; // If not, start over (recursive) while (sentence == null) { sentence = ReadTypedSentence() as IPositionSentence; } // Return the location return(sentence.Position); }
public void Parse(NmeaSentence sentence) { /* NMEA data is parsed in a specific order to maximize data quality and also to reduce latency * problems. The date/time is processed first to minimize latency. Then, dilution of precision * values are processed. Finally, if precision is good enough to work with, remaining values are * processed. */ // Is this a fix method message? IFixMethodSentence fixMethodSentence = sentence as IFixMethodSentence; if (fixMethodSentence != null) { SetFixMethod(fixMethodSentence.FixMethod); } // Is this a fix quality message? IFixQualitySentence fixQualitySentence = sentence as IFixQualitySentence; if (fixQualitySentence != null) { SetFixQuality(fixQualitySentence.FixQuality); } #region Process common GPS information // If a fix is required, don't process time if (!IsFixRequired || (IsFixRequired && IsFixed)) { // Does this sentence support the UTC date and time? IUtcDateTimeSentence dateTimeSentence = sentence as IUtcDateTimeSentence; if (dateTimeSentence != null) { SetDateTimes(dateTimeSentence.UtcDateTime); } /* Some NMEA sentences provide UTC time information, but no date! To make this work, * we must combine the time report with the current UTC date. */ IUtcTimeSentence timeSentence = sentence as IUtcTimeSentence; if (timeSentence != null && !timeSentence.UtcTime.Equals(TimeSpan.MinValue) && !timeSentence.UtcTime.Equals(TimeSpan.Zero)) { SetDateTimes(new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, timeSentence.UtcTime.Hours, timeSentence.UtcTime.Minutes, timeSentence.UtcTime.Seconds, timeSentence.UtcTime.Milliseconds, DateTimeKind.Utc)); } } // Does this sentence support horizontal DOP? IHorizontalDilutionOfPrecisionSentence hdopSentence = sentence as IHorizontalDilutionOfPrecisionSentence; if (hdopSentence != null) { SetHorizontalDilutionOfPrecision(hdopSentence.HorizontalDilutionOfPrecision); } // Does the sentence support vertical DOP? IVerticalDilutionOfPrecisionSentence vdopSentence = sentence as IVerticalDilutionOfPrecisionSentence; if (vdopSentence != null) { SetVerticalDilutionOfPrecision(vdopSentence.VerticalDilutionOfPrecision); } // Does the sentence support mean DOP? IPositionDilutionOfPrecisionSentence mdopSentence = sentence as IPositionDilutionOfPrecisionSentence; if (mdopSentence != null) { SetMeanDilutionOfPrecision(mdopSentence.PositionDilutionOfPrecision); } #endregion // If a fix is required, don't process time if (!IsFixRequired || (IsFixRequired && IsFixed)) { // Is precision good enough to work with? if (this.HorizontalDilutionOfPrecision.Value <= this.MaximumHorizontalDilutionOfPrecision.Value) { #region Process real-time positional data // Does this sentence support lat/long info? IPositionSentence positionSentence = sentence as IPositionSentence; if (positionSentence != null) { SetPosition(positionSentence.Position); } // Does this sentence support bearing? IBearingSentence bearingSentence = sentence as IBearingSentence; if (bearingSentence != null) { SetBearing(bearingSentence.Bearing); } // Does this sentence support speed? ISpeedSentence speedSentence = sentence as ISpeedSentence; if (speedSentence != null) { SetSpeed(speedSentence.Speed); } #endregion } // Is the vertical DOP low enough to be worth processing? if (this.VerticalDilutionOfPrecision.Value <= this.MaximumVerticalDilutionOfPrecision.Value) { #region Process altitude data // Does this sentence support altitude? IAltitudeSentence altitudeSentence = sentence as IAltitudeSentence; if (altitudeSentence != null) { SetAltitude(altitudeSentence.Altitude); } // Does this sentence support altitude? IAltitudeAboveEllipsoidSentence altitudeAboveEllipsoidSentence = sentence as IAltitudeAboveEllipsoidSentence; if (altitudeAboveEllipsoidSentence != null) { SetAltitude(altitudeAboveEllipsoidSentence.AltitudeAboveEllipsoid); } // Does this sentence support geoidal separation? IGeoidalSeparationSentence geoidSeparationSentence = sentence as IGeoidalSeparationSentence; if (geoidSeparationSentence != null) { SetGeoidalSeparation(geoidSeparationSentence.GeoidalSeparation); } #endregion } } #region Lower-priority information // Is this a fix mode sentence? IFixModeSentence fixModeSentence = sentence as IFixModeSentence; if (fixModeSentence != null) { SetFixMode(fixModeSentence.FixMode); } // Does this sentence have fix status? IFixStatusSentence fixedSentence = sentence as IFixStatusSentence; if (fixedSentence != null) { SetFixStatus(fixedSentence.FixStatus); } // Does this sentence support magnetic variation? IMagneticVariationSentence magVarSentence = sentence as IMagneticVariationSentence; if (magVarSentence != null) { SetMagneticVariation(magVarSentence.MagneticVariation); } // Process satellite data ISatelliteCollectionSentence satelliteSentence = sentence as ISatelliteCollectionSentence; if (satelliteSentence != null) { /* GPS.NET 2.0 performed thorough comparison of satellites in order to update * an *existing* instance of Satellite objects. I think now that this was overkill. * For performance and limited memory use, satellites are just overwritten. */ AppendSatellites(satelliteSentence.Satellites); } // Fixed satellite count IFixedSatelliteCountSentence fixedCountSentence = sentence as IFixedSatelliteCountSentence; if (fixedCountSentence != null) { SetFixedSatelliteCount(fixedCountSentence.FixedSatelliteCount); } // Process fixed satellites IFixedSatellitesSentence fixedSatellitesSentence = sentence as IFixedSatellitesSentence; if (fixedSatellitesSentence != null) { SetFixedSatellites(fixedSatellitesSentence.FixedSatellites); } #endregion }
private void menuAnalyze_Click(object sender, EventArgs e) { // Make a log file name from the name of the device string logName = _CurrentDevice.Name + ".txt"; // Remove any invalid characters foreach (char badChar in Path.GetInvalidPathChars()) { logName = logName.Replace(badChar, '_'); } // Also remove colons logName = logName.Replace(":", String.Empty); // Are they requesting a log? if (menuAnalyze.Text == "View Log") { // Yes. Create a form for the log LogForm form = new LogForm(); // Tell the form which device to use form.Device = _CurrentDevice; // Read in the log file StreamReader reader = File.OpenText(logName); form.Body = reader.ReadToEnd(); reader.Close(); // Show the log file form form.Show(); Application.DoEvents(); return; } /* This feature will examine the NMEA data from a device and * report on what features it supports. */ menuAnalyze.Enabled = false; tabControl1.SelectedIndex = 1; // Show a busy cursor until analysis completes Cursor.Current = Cursors.WaitCursor; Application.DoEvents(); StreamWriter logWriter = null; try { // Open the device _CurrentDevice.Open(); // Create a log file for this device logWriter = new StreamWriter(logName); // Write a header logWriter.WriteLine("------------------------------------------------------------------------------------------------------------------------------"); logWriter.WriteLine("GPS.NET 3.0 Diagnostics Copyright © 2009 GeoFrameworks, LLC"); logWriter.WriteLine(" http://www.geoframeworks.com"); logWriter.WriteLine(""); logWriter.WriteLine("A. RAW NMEA DATA FOR " + _CurrentDevice.Name.ToUpper()); logWriter.WriteLine(""); // Wrap the device's raw data stream in an NmeaReader NmeaReader stream = new NmeaReader(_CurrentDevice.BaseStream); bool isPositionSupported = false; bool isAltitudeSupported = false; bool isBearingSupported = false; bool isPrecisionSupported = false; bool isSpeedSupported = false; bool isSatellitesSupported = false; // Now analyze it for up to 100 sentences for (int index = 0; index < 100; index++) { // Read a valid sentence NmeaSentence sentence = stream.ReadTypedSentence(); // Write it to the log file logWriter.WriteLine(sentence.Sentence); // Get the command word for the sentence if (!sentenceListBox.Items.Contains(sentence.CommandWord)) { sentenceListBox.Items.Add(sentence.CommandWord); } // What features are supported? IPositionSentence positionSentence = sentence as IPositionSentence; if (positionSentence != null) { isPositionSupported = true; } IAltitudeSentence altitudeSentence = sentence as IAltitudeSentence; if (altitudeSentence != null) { isAltitudeSupported = true; } IBearingSentence bearingSentence = sentence as IBearingSentence; if (bearingSentence != null) { isBearingSupported = true; } IHorizontalDilutionOfPrecisionSentence hdopSentence = sentence as IHorizontalDilutionOfPrecisionSentence; if (hdopSentence != null) { isPrecisionSupported = true; } ISpeedSentence speedSentence = sentence as ISpeedSentence; if (speedSentence != null) { isSpeedSupported = true; } ISatelliteCollectionSentence satellitesSentence = sentence as ISatelliteCollectionSentence; if (satellitesSentence != null) { isSatellitesSupported = true; } // Is everything supported? If so, we have a healthy GPS device. It's okay to exit if (isPositionSupported && isAltitudeSupported && isBearingSupported && isPrecisionSupported && isSatellitesSupported && isSpeedSupported) { break; } } // Summarize the log logWriter.WriteLine(""); logWriter.WriteLine("B. SUMMARY"); logWriter.WriteLine(""); // Set images based on supported features if (isPositionSupported) { logWriter.WriteLine(" Latitude and longitude are supported."); pictureBoxPosition.Image = imageList1.Images[0]; } else { logWriter.WriteLine("WARNING Latitude and longitude are not supported."); pictureBoxPosition.Image = imageList1.Images[1]; } if (isAltitudeSupported) { logWriter.WriteLine(" Altitude is supported."); pictureBoxAltitude.Image = imageList1.Images[0]; } else { logWriter.WriteLine("WARNING Altitude is not supported."); pictureBoxAltitude.Image = imageList1.Images[1]; } if (isBearingSupported) { logWriter.WriteLine(" Bearing is supported."); pictureBoxBearing.Image = imageList1.Images[0]; } else { logWriter.WriteLine("WARNING Bearing is not supported."); pictureBoxBearing.Image = imageList1.Images[1]; } if (isPrecisionSupported) { logWriter.WriteLine(" Dilution of Precision is supported."); pictureBoxPrecision.Image = imageList1.Images[0]; } else { logWriter.WriteLine("WARNING Dilution of Precision is not supported."); pictureBoxPrecision.Image = imageList1.Images[1]; } if (isSpeedSupported) { logWriter.WriteLine(" Speed is supported."); pictureBoxSpeed.Image = imageList1.Images[0]; } else { logWriter.WriteLine("WARNING Speed is not supported."); pictureBoxSpeed.Image = imageList1.Images[1]; } if (isSatellitesSupported) { logWriter.WriteLine(" GPS satellite data is supported."); pictureBoxSatellites.Image = imageList1.Images[0]; } else { logWriter.WriteLine("WARNING GPS satellite data is not supported."); pictureBoxSatellites.Image = imageList1.Images[1]; } logWriter.WriteLine("------------------------------------------------------------------------------------------------------------------------------"); logWriter.Close(); // Close the device _CurrentDevice.Close(); // Restore the cursor Cursor.Current = Cursors.Default; // change "Analyze" to "View Log" menuAnalyze.Text = "View Log"; // Let them know which features are supported by their device if (isPositionSupported && isAltitudeSupported && isBearingSupported && isPrecisionSupported && isSatellitesSupported && isSpeedSupported) { MessageBox.Show(_CurrentDevice.Name + " fully supports all real-time GPS data.", "No Problems", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1); } else { MessageBox.Show(_CurrentDevice.Name + " does not appear to fully support real-time GPS data. Try another analysis. If the same problem persists, some NMEA sentences may need to be activated on the device.", "Problems Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1); } } catch (Exception ex) { // Close the device _CurrentDevice.Close(); if (logWriter != null) { logWriter.Close(); } // Restore the cursor Cursor.Current = Cursors.Default; // Explain the error MessageBox.Show(ex.Message, "Cannot Analyze", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1); } finally { // Re-enable the menu menuAnalyze.Enabled = true; } }
/// <summary> /// Decode the NMEA data. /// </summary> /// <param name="nmeaStrings">String array containing NMEA sentences.</param> /// <returns>Gps Data.</returns> public static GpsData DecodeNmea(string[] nmeaStrings) { GpsData gpsData = new GpsData(); try { for (int x = 0; x < nmeaStrings.Length; x++) { // Parse all the nmea setences found NmeaSentence sentence = new NmeaSentence(nmeaStrings[x]); // Is this a GPRMC sentence? if (sentence.CommandWord.EndsWith("RMC", StringComparison.Ordinal)) { gpsData.GPRMC = new GprmcSentence(sentence.Sentence); } // Is this a GPHDT sentence? if (sentence.CommandWord.EndsWith("HDT", StringComparison.Ordinal)) { gpsData.GPHDT = new GphdtSentence(sentence.Sentence); } // Is this a GPVTG sentence? if (sentence.CommandWord.EndsWith("VTG", StringComparison.Ordinal)) { gpsData.GPVTG = new GpvtgSentence(sentence.Sentence); } // Is this a GPGGA sentence? if (sentence.CommandWord.EndsWith("GGA", StringComparison.Ordinal)) { gpsData.GPGGA = new GpggaSentence(sentence.Sentence); } // Does this sentence support lat/long info? IPositionSentence positionSentence = sentence as IPositionSentence; if (positionSentence != null) { gpsData.Position = positionSentence.Position; } // Does this sentence support bearing? IBearingSentence bearingSentence = sentence as IBearingSentence; if (bearingSentence != null) { gpsData.Bearing = bearingSentence.Bearing; } // Does this sentence support heading? IHeadingSentence headingSentence = sentence as IHeadingSentence; if (headingSentence != null) { gpsData.Heading = headingSentence.Heading; } // Does this sentence support speed? ISpeedSentence speedSentence = sentence as ISpeedSentence; if (speedSentence != null) { gpsData.Speed = speedSentence.Speed; } } } catch (Exception e) { Debug.WriteLine("Error decoding GPS data.", e); } return(gpsData); }