DOC

MobileGPSReader

By Margaret Gordon,2014-06-20 16:28
12 views 0
MobileGPSReader

    核心GPSReader

    // GPSReader.cs

    //

    // Copyright (C) 2003 JW Hedgehog, Inc. All rights reserved//

    // JW Hedgehog, Inc

    // http://www.jwhh.com

    //

    // Direct questions to mailto:jimw@jwhh.com

    //

    // This code, comments and information are provided "AS IS" with// no warrenty of any kind, either expressed or implied, including// but not limited to the implied warranties of merchentability and/or// fitness for a particular purpose

    // ---------------------------------------------------------------------using System;

    using System.Data;

    using System.Windows.Forms ;

    using System.Runtime.InteropServices ;

    using System.Text ;

    using System.Collections ;

    using System.Threading ;

    using System.IO ;

    namespace GPSExample.Util

    {

    ///

    /// Class that manages the GPS reading process.

    ///

    /// To get started using the class do the following

    /// 1) Construct GPSReader passing the port name and baud rate of the GPS device

    ///C#: GPSReader gps = new GPSReader("COM4:", 4800) ;

    ///VB: Dim WithEvents gps As New GPSReader("COM4:", 4800)

    ///2) Handle the OnGPSMessage event

    ///This event will fire each time the GPS sends an update

    ///3) Call gps.StartRead()

    ///Launches the GPS reading process on a background thread

    ///

    /// Use the StartRead and StopRead methods to control the GPS reading process. Before calling

    /// StartRead you must provide at least the port name in the form "COMx" (x is the port number) and

    /// the baud rate. You can do this using either a constructor or the PortName and BaudRate properties.

    /// Each time a GPS message is received, the OnGPSMessage event will fire passing an instance of the

    /// GPSEventArgs class containing the raw GPS sentence along with some of the values already parsed into

    /// read-only fields.

    ///

    /// This class does the actual GPS reading work on a background thread. The individual OnGPSMessage events

    /// are raised in a UI thread safe manner so no special handling is required. Because it is considered unsafe

    /// to interact with UI elements (TextBox, ListBox, etc.) from a thread other then the thread on which they were

    /// created, the GPS reader thread raises the OnGPSMessage event on the UI thread. These is acheived by deriving

    /// the GPSReader class from Control and then using the inherited Invoke method. Calling this.Invoke causes the

    /// event to be raised on the same thread on which the GPSReader was created. Since the GPSReader is usually

    /// created as a member of either a Form or a method on a Form, it is safe to assume that the GPSReader was

    /// created on the same thread as the Form and the Form's associated UI elements.

    ///

    /// Because there can sometimes be a short delay between when StartRead/StopRead are called and when the

    /// action actually occurs on the background thread, OnGPSStartRead and OnGPSStopRead events are provided.

    /// Each fires when the background thread actually performs the action. Like the OnGPSMessage event,

    /// these are raised in a UI thread safe manner.

    ///

    /// To support the broadest number of GPS devices, the class actually supports two different read modes.

    /// The preferred read mode is "MesssageMode". In MessageMode, we let the COMM port driver monitor the

    /// GPS stream watching for the arrival of the carriage-return (\n). Our code blocks until the COMM port

    /// driver notifies us of the carriage-return, at which time we then go read the entire GPS sentence from

    /// the COMM port driver.

    /// The alternative read mode is "CharacterMode". In CharacterMode we read the data character-by-character

    /// from the COMM port driver manually building the GPS sentence and watching for the carriage-return. This

    /// mode was added because experimentation showed that some GPS devices that simulate COMM ports(i.e. the GPS

    /// might be an expansion pack of compact flash card but appears as a COMM port to the device) do not

    /// support letting the COMM port driver monitor for the carriage-return.

    /// Using the PreferredReadMode property, you can set which mode the GPSReader uses If you choose MessageMode

    /// or Auto (the default) The GPSReader class tests to see if the driver supports MessageMode and if so use it.

    /// Otherwise it will downgrade to CharacterMode. The ActiveReadMode property indicates which read mode is

    /// actually being used.

    /// The code that tests for MessageMode support is in the

    "DriverSupportsMessageMode method. Because its not

    /// possible to test every GPS in existence there is no way to be 100% sure that this test will always work but

    /// on the devices tested it has been reliable.

    ///

    ***************************************************************************************************************

    /// Note

    ***********************************************************

    /// If you try reading from a device and the GPSReader never returns any data, the cause may be that MessageMode

    /// support has been falsly indicated as supported. Setting the GPSReader PreferredReadMode to ReadMode.Character

/// should over come the problem. The need to do this has never been

    observered but since its not possible to test

    /// every GPS device the possibility always exists.///

    ********************************************************************

    *******************************************

    ///

    public class GPSReader : Control

    {

    //

    *************************************************************

    // Constructors

    //

    *************************************************************

    ///

    /// Default constructor

    /// At a minimum, will need to set the PortName and BaudRate

    properties before calling StartRead

    ///

    public GPSReader()

    {

    }

    ///

    /// Constructor - Accepts COMM port name (COMx:)

    /// Will need to set the BaudRate properties before calling StartRead

    ///

    ///

    public GPSReader(string portName)

    : this()

    {

    _portName = portName ;

    }

    ///

    /// Constructor - Accepts COMM port name (COMx:) and BaudRate

    /// If default COMM port settings (NoParity, 8 bits/byte and

    OneStopBit) are acceptable,

    /// can call StartRead without setting any of the configuration

    properties

    ///

    ///

    ///

    public GPSReader(string portName, int baudRate)

    : this(portName)

    {

    _baudRate = baudRate ;

    }

    ///

    /// Constructor - verbose

    /// Provides full control over all COMM port settings

    ///

    ///

    ///

    ///

    ///

    ///

    public GPSReader(string portName, int baudRate, ParitySetting parity, byte byteSize, StopBitsSetting stopBits)

    : this(portName, baudRate)

    {

    _parity = parity ;

    _byteSize = byteSize ;

    _stopBits = stopBits ;

    }

    //

    *************************************************************

    // Events

    //

    *************************************************************

    ///

    /// Fires each time a GPS message is received

    ///

    public event GPSEventHandler OnGPSMessage ;

    ///

    /// Fires when the background thread begins the read process

    ///

    public event EventHandler OnGPSReadStart ;

    ///

    /// Fires when the background thread exits the read process

    ///

    public event EventHandler OnGPSReadStop ;

    //

    *************************************************************

    // Start/Stop Reading

    //

    *************************************************************

    ///

    /// Initiate GPS Reading

    /// Actual reading done on a background thread - this method returns

    immediatly

    ///

    /// Throws an error if either PortName or BaudRate not set

    ///

    public void StartRead()

    {

    // Verify that we know the port name and baud rate

    if (_baudRate == baudRateNotSet || _portName == portNameNotSet)

    throw new ApplicationException(" Must set Baud Rate & Port Name before opening the port"