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

📄 gpsreader.cs

📁 Windows CE下的GPS接收程序 Windows CE下的GPS接收程序
💻 CS
📖 第 1 页 / 共 3 页
字号:
		/// <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 + -