⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpsreader.cs

📁 功能:基于windows mobile 的地图查看器。使用vs2005开发
💻 CS
📖 第 1 页 / 共 3 页
字号:
		/// Wrapper method to simplify reading a GPS sentence from the COMM port
		///  Method blocks until the COMM port driver receives a CR ('\n') or the COMM port is closed
		///  Return value indicates if any data was read - A 'false' return value occurs in one of 3 scenarios
		///  1. COMM port was closed, which usually indicates that StopRead has been called
		///  2. An error has occurred on the COMM port
		///  3. The read has timed out - this should never happen because we don't read until
		///     were notified by the COMM port driver that the carriage-return ('\n') has arrived
		/// </summary>
		/// <param name="hPort"></param>
		/// <param name="numBytes"></param>
		/// <param name="buffer"></param>
		/// <param name="numBytesRead"></param>
		/// <returns></returns>
		private bool ReadPort_Message(int numBytes, out Byte[] buffer, out int numBytesRead)
		{
			numBytesRead	= 0;
			buffer = new Byte[numBytes];
			uint eventMask = 0 ;
			int readRetVal = 0 ;
			bool retVal = false;

			SetCommMask(_portHandle, EV_RXFLAG) ;					// Indicate that we want to wait for the '\n'
			WaitCommEvent(_portHandle, out eventMask, IntPtr.Zero) ;// Wait...

			if ((eventMask & EV_RXFLAG) != 0)						// If received '\n' - do the read
			{														//  only other reason we'd be here is if the port was closed
				readRetVal = ReadFile(_portHandle, buffer, numBytes, ref numBytesRead, IntPtr.Zero) ;
				retVal = readRetVal != 0 && numBytesRead > 0 ;		// success only if non-zero return value and 
			}														// at least one byte read

			return retVal ;
		}

		/// <summary>
		/// Perform a single character read
		/// Internally manages timeouts & null characters
		/// Only returns 0 when StopRead is called.  Unline ReadPort_Message, it is reasonable to 
		/// expect that the ReadFile may occasionally timeout if there is a long delay between
		/// GPS messages.
		/// </summary>
		/// <returns>the character read or 0 if _readData is set to false</returns>
		private byte ReadPort_Character()
		{
			int		numBytesRead	= 0;
			Byte[]	buffer = new Byte[1];

			int retVal = ReadFile(_portHandle, buffer, 1, ref numBytesRead, IntPtr.Zero) ;
			while ( _readData && (ReadTimedOut(retVal, numBytesRead) || buffer[0] == 0) )
			{
				retVal = ReadFile(_portHandle, buffer, 1, ref numBytesRead, IntPtr.Zero) ;
			}

			return _readData ? buffer[0] : (byte)0 ;
		}

		/// <summary>
		/// Checks to see if ReadFile returned due to a timeout
		/// a ReadFile return value of non-zero (true) with number of bytes read of zero indicates timeout
		/// This method is used only by ReadPortCharacter
		/// </summary>
		/// <param name="readRetVal"></param>
		/// <param name="numBytesRead"></param>
		/// <returns></returns>
		private static bool ReadTimedOut(int readRetVal, int numBytesRead)
		{
			return readRetVal != 0 && numBytesRead == 0 ;
		}

		#endregion

		#region DllImports for Win32 methods
		/// <summary>
		/// Win32 method used to determine the COMM port's current settings
		/// </summary>
		/// <param name="hCommDev"></param>
		/// <param name="lpDCB"></param>
		/// <returns></returns>
		[DllImport("coredll.dll")] 
		private static extern int GetCommState(uint hCommDev, DCB lpDCB) ;

		/// <summary>
		/// Win32 method used update the COMM portsettings 
		/// </summary>
		/// <param name="hCommDev"></param>
		/// <param name="lpDCB"></param>
		/// <returns></returns>
		[DllImport("coredll.dll")] 
		private static extern int SetCommState(uint hCommDev, DCB lpDCB);

		/// <summary>
		/// Win32 method to read data from the COMM port
		/// </summary>
		/// <param name="hFile"></param>
		/// <param name="Buffer"></param>
		/// <param name="nNumberOfBytesToRead"></param>
		/// <param name="lpNumberOfBytesRead"></param>
		/// <param name="notUsedPassZero"></param>
		/// <returns></returns>
		[DllImport("coredll.dll")] 
		static extern int ReadFile(uint hFile, Byte[] Buffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, IntPtr notUsedPassZero ) ;

		/// <summary>
		/// Win32 method to open the COMM port
		/// </summary>
		/// <param name="lpFileName"></param>
		/// <param name="dwDesiredAccess"></param>
		/// <param name="dwShareMode"></param>
		/// <param name="lpSecurityAttributes"></param>
		/// <param name="dwCreationDisposition"></param>
		/// <param name="dwFlagsAndAttributes"></param>
		/// <param name="notUsedPassZero"></param>
		/// <returns></returns>
		[DllImport("coredll.dll")] 
		static extern uint CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, uint lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr notUsedPassZero) ;

		/// <summary>
		/// Win32 method to close the COMM port
		/// </summary>
		/// <param name="hObject"></param>
		/// <returns></returns>
		[DllImport("coredll.dll")] 
		static extern int CloseHandle(uint hObject);

		/// <summary>
		/// Win32 method used to sets read timeouts
		/// </summary>
		/// <param name="hFile"></param>
		/// <param name="lpCommTimeouts"></param>
		/// <returns></returns>
		[DllImport("coredll.dll")] 
		static extern int SetCommTimeouts(uint hFile, COMMTIMEOUTS lpCommTimeouts);

		/// <summary>
		/// Win32 method used to set COMM port event masks
		///  In our code it is specifically used to identify that we want to be notified when
		///  the '\n' character is received
		/// </summary>
		/// <param name="hFile"></param>
		/// <param name="dwEvtMask"></param>
		/// <returns></returns>
		[DllImport("coredll.dll")] 
		static extern int SetCommMask(uint hFile, uint dwEvtMask);

		/// <summary>
		/// Win32 method used to wait for COMM port events to signal
		///  In our code it is used to wait for the arrival of the '\n' character
		/// </summary>
		/// <param name="hFile"></param>
		/// <param name="lpEvtMask"></param>
		/// <param name="notUsedPassZero"></param>
		/// <returns></returns>
		[DllImport("coredll.dll")] 
		static extern int WaitCommEvent(uint hFile, out uint lpEvtMask, IntPtr notUsedPassZero);

		#endregion
	}

	/// <summary>
	/// GPS Message Structure
	///  Sent each time a GPS Message is received
	/// </summary>
	public class GPSEventArgs : EventArgs
	{
		// ** GPGGA Message Info **
		// Raw Message
		public readonly string MessageText  ;
		// Message Identifier (GPGGA, etc..)
		public readonly string MessageType ;
		// GMT Time
		public readonly double Time ;
		// Lat Stuff
		public readonly double Lat ;
		public readonly double LatOriginal ;
		public readonly string LatDirection ;
		// Lon Stuff
		public readonly double Lon ;
		public readonly double LonOriginal ;
		public readonly string LonDirection ;
		// Quality
		public readonly int Quality ;
		// Sat Count
		public readonly int NumSats ;

		// ** GPGSA Message Info **
		public readonly int FixType ;

		// ** GPRMC & GPVTG Message Info **
		public readonly double Bearing ;

		#region Sentence Parsing Methods
		/// <summary>
		/// Internal constructor which automatically parses the GPS sentence
		/// and populates the appropriate fields
		/// </summary>
		/// <param name="messageText"></param>
		internal GPSEventArgs(string messageText)
		{
			MessageText = messageText ;
				// Parse Message
				string[] tokens = MessageText.Split(new char[] { ',' });
				if (tokens.Length > 0)
				{
					MessageType = tokens[0].Substring(1); // Strip leading $
					if (MessageType == "GPGGA")
					{
						// Time
						if (tokens[1].Length > 0)
							Time = Convert.ToDouble(tokens[1]);
						// Lat Stuff
						if (tokens[2].Length > 0)
							LatOriginal = Convert.ToDouble(tokens[2]);
						LatDirection = tokens[3].ToUpper();
						Lat = LonLatToDegrees(LatOriginal, LatDirection);
						// Lon Stuff
						if (tokens[4].Length > 0)
							LonOriginal = Convert.ToDouble(tokens[4]);
						LonDirection = tokens[5].ToUpper();
						Lon = LonLatToDegrees(LonOriginal, LonDirection);
						// Quality
						if (tokens[6].Length > 0)
							Quality = Convert.ToInt32(6);
						// Sat Count
						if (tokens[7].Length > 0)
							NumSats = Convert.ToInt32(tokens[7]);
					}
					else if (MessageType == "GPGSA")
					{
						if (tokens[2].Length > 0)
							FixType = Convert.ToInt32(tokens[2]);
					}
					else if (MessageType == "GPRMC")
					{
						if (tokens[8].Length > 0)
							Bearing = Convert.ToDouble(tokens[8]);
					}
					else if (MessageType == "GPVTG")
					{
						if (tokens[1].Length > 0)
							Bearing = Convert.ToDouble(tokens[1]);
					}
				}

		}

		/// <summary>
		/// Converts Longitude and Latitude to Degrees
		/// </summary>
		/// <param name="original"></param>
		/// <param name="direction"></param>
		/// <returns></returns>
		private double LonLatToDegrees(double original, string direction)
		{
			//	 y = m_dLatOrig / 100
			//   m_dLat = (((y - Int(y)) * 100) / 60) + Int(y)
			double temp = original / 100 ;
			int tempAsInt = (int) temp ;
			double result = (((temp - tempAsInt) * 100) / 60) + tempAsInt ;

			return direction == "S" || direction == "W" ? -result : result ;
		}

		#endregion
	}

	#region Port Configuration Enums - ParitySetting, StopBitsSetting and ReadMode
	/// <summary>
	/// Used to identify valid COMM port Parity Settings
	/// </summary>
	public enum ParitySetting
	{
		NoParity = 0,
		OddParity = 1,
		EvenParity = 2,
		MarkParity = 3,
		SpaceParity = 4
	}

	/// <summary>
	/// Used to identify COMM port Stop Bit Settings
	/// </summary>
	public enum StopBitsSetting
	{
		OneStopBit = 0,
		One5StopBits = 1,
		TwoStopBits = 2
	}

	/// <summary>
	/// Used to identify GPS driver read mode.  Used for both to indicate to the GPSReader
	/// the preferred read mode and also for the GPSReader to indicate what read mode it 
	/// is using.
	/// In the implementation setting a PreferredReadMode of Auto amd Message are basically
	/// equivalent because the GPSReader class will always verify that MessageMode is supported
	/// before attempting to use it. 
	/// </summary>
	public enum ReadMode
	{
		Undefined = 0,	// Only used to indicate that the GPSReader has not yet determined which mode to use
		Message,		// Indicates to read entire messages from the driver, if supported
		Character,		// Indicates to build messages character-by-character
		Auto			// Indicates the GPSReader should choose the read mode based on driver ability
	}
	#endregion

	#region GPSEventHandler decleration
	/// <summary>
	/// Delegate definition for the GPSMessage event
	/// </summary>
	public delegate void GPSEventHandler(object sender, GPSEventArgs arg) ;
	#endregion

	#region COMMTIMEOUTS definition
	[StructLayout(LayoutKind.Sequential)]
	internal class COMMTIMEOUTS
	{
		public uint ReadIntervalTimeout = 0 ;
		public uint ReadTotalTimeoutMultiplier = 0 ;
		public uint ReadTotalTimeoutConstant = 0 ;
		public uint WriteTotalTimeoutMultiplier = 0 ;
		public uint WriteTotalTimeoutConstant = 0 ;
	}
	#endregion

	#region DCB definition
	[StructLayout(LayoutKind.Sequential)]
	internal class DCB 
	{
		public DCB()
		{
			// Initialize the length of the structure.
			this.DCBlength = (uint)Marshal.SizeOf(this);
		}

		public   uint DCBlength = 0 ;
		public   uint BaudRate = 0 ;
		public   uint Control = 0 ;
		public   ushort wReserved = 0 ;
		public   ushort XonLim = 0 ;
		public   ushort XoffLim = 0 ;
		public   byte   ByteSize = 0 ;
		private  byte   _parity = 0 ;
		private  byte   _stopBits = 0 ;
		public   sbyte  XonChar = 0 ;
		public   sbyte  XoffChar = 0 ;
		public   sbyte  ErrorChar = 0 ;
		public   sbyte  EofChar = 0 ;
		public   sbyte  EvtChar = 0 ;
		public   ushort wReserved1 = 0 ;

		public ParitySetting Parity
		{
			get {return (ParitySetting) _parity;}
			set {_parity = (byte) value;}
		}

		public StopBitsSetting StopBits
		{
			get {return (StopBitsSetting) _stopBits;}
			set {_stopBits = (byte) value;}
		}
	}
	#endregion

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -