您的位置:首页 > 编程语言 > C#

C# 中GPS数据的获取的基类

2010-03-19 13:58 381 查看
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace BaseStationPDA
{
  class GPs
  {
    public string PortNum;

    public int BaudRate;

    public byte ByteSize;

    public byte Parity;
    // 0-4=no,odd,even,mark,space
    public byte StopBits;
    // 0,1,2 = 1, 1.5, 2
    public int ReadTimeout;
    //comm port win32 file handle
    private int hComm = -1;

    public bool Opened = false;
    //win32 api constants
    private const u
    int GENERIC_READ = 0x80000000;

    private const u
    int GENERIC_WRITE = 0x40000000; private const
    int OPEN_EXISTING = 3;

    private const
    int INVALID_HANDLE_VALUE = -1;
    [StructLayout( LayoutKind.Sequential )]
    public struct DCB
    {
      //taken from c struct in platform sdk
      public int DCBlength;
      // sizeof( DCB )
      public int BaudRate;
      // 指定当前波特率 current baud rate
      // these are the c struct bit fields, bit twiddle flag to set
      public int fBinary;
      // 指定是否允许二进制模式,在windows95中必须主TRUE binary mode, no EOF check
      public int fParity;
      // 指定是否允许奇偶校验 enable parity checking
      public int fOutxCtsFlow;
      // 指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起. CTS output flow control
      public int fOutxDsrFlow;
      // 指定CTS是否用于检测发送控制 DSR output flow control
      public int fDtrControl;
      // DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON,DTR_CONTROL_HANDSHAKE允许DTR"握手" DTR flow control type
      public
      int fDsrSensitivity;
      // 当该值为TRUE时DSR为OFF时接收的字节被忽略 DSR sensitivity
      public
      int fTXContinueOnXoff;
      // 指定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止.TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出XoffChar字符中止接收字节之后,发送继续进行. FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之后,发送继续进行.XOFF continues Tx
      public
      int fOutX;
      // TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始 XON/XOFF out flow control
      public int fInX;
      // TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去 XON/XOFF in flow control
      public int fErrorChar;
      // 该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误的接收字符 enable error replacement
      public int fNull;
      // eTRUE时,接收时去掉空(0值)字节 enable null stripping
      public int fRtsControl;
      // RTS flow control
      /*RTS_CONTROL_DISABLE时,RTS置为OFF
      RTS_CONTROL_ENABLE时, RTS置为ON
      RTS_CONTROL_HANDSHAKE时,
       当接收缓冲区小于半满时RTS为ON
        当接收缓冲区超过四分之三满时RTS为OFF
      RTS_CONTROL_TOGGLE时,
       当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF*/
      public int fAbortOnError;
      // TRUE时,有错误发生时中止读和写操作 abort on error
      public int fDummy2;
      // 未使用 reserved
      public u int flags;

      public ushort wReserved;
      // 未使用,必须为0 not currently used
      public ushort XonLim;
      // 指定在XON字符发送这前接收缓冲区中可允许的最小字节数 transmit XON threshold
      public ushort XoffLim;
      // 指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数 transmit XOFF threshold
      public byte ByteSize;
      // 指定端口当前使用的数据位 number of bits/byte, 4-8
      public byte Parity;
      // 指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space
      public byte StopBits;
      // 指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2 = 1, 1.5, 2
      public char XonChar;
      // 指定用于发送和接收字符XON的值 Tx and Rx XON
      character
      public char XoffChar;
      // 指定用于发送和接收字符XOFF值 Tx and Rx XOFF
      character
      public char ErrorChar;
      // 本字符用来代替接收到的奇偶校验发生错误时的值 error replacement
      character
      public char EofChar;
      // 当没有使用二进制模式时,本字符可用来指示数据的结束 end of input
      character
      public char EvtChar;
      // 当接收到此字符时,会产生一个事件 received event
      character
      public ushort wReserved1;
      // 未使用 reserved;
      do not use
    }
    [StructLayout( LayoutKind.Sequential )]
    private struct COMMTIMEOUTs
    {
      public int ReadIntervalTimeout;

      public int ReadTotalTimeoutMultiplier;

      public int ReadTotalTimeoutConstant;

      public int WriteTotalTimeoutMultiplier;

      public int WriteTotalTimeoutConstant;
    }

    [StructLayout( LayoutKind.Sequential )]
    private struct OVERLAPPED
    {
      public int Internal;

      public int InternalHigh;

      public int Offset;

      public int OffsetHigh;

      public int hEvent;
    }
    [DllImport( "coredll.dll" )]
    private static extern
    int CreateFile(
    string lpFileName,
    // 要打开的串口名称
    
    int dwDesiredAccess,
    // 指定串口的访问方式,一般设置为可读可写方式
    int dwShareMode,
    // 指定串口的共享模式,串口不能共享,所以设置为0
    int lpSecurityAttributes, // 设置串口的安全属性,WIN9X下不支持,应设为NULL
    int dwCreationDisposition,
    // 对于串口通信,创建方式只能为OPEN_EXISTING
    int dwFlagsAndAttributes,
    // 指定串口属性与标志,设置为FILE_FLAG_OVERLAPPED( 重叠I/O操作 ),指定串口以异步方式通信
    int hTemplateFile
    // 对于串口通信必须设置为NULL
    );
    [DllImport( "coredll.dll" )]
    private static extern bool GetCommState(
    int hFile, //通信设备句柄
    ref DCB lpDCB
    // 设备控制块DCB
    );
    [DllImport( "coredll.dll" )]
    private static extern bool BuildCommDCB(
    string lpDef, // 设备控制字符串
    ref DCB lpDCB
    // 设备控制块
    );
    [DllImport( "coredll.dll" )]
    private static extern bool SetCommState(
    int hFile, // 通信设备句柄
    ref DCB lpDCB
    // 设备控制块
    );
    [DllImport( "coredll.dll" )]
    private static extern bool GetCommTimeouts(
    int hFile,
    // 通信设备句柄 handle to comm device
    ref COMMTIMEOUTS lpCommTimeouts // 超时时间 time-out values
    );
    [DllImport( "coredll.dll" )]
    private static extern bool SetCommTimeouts(
    int hFile,
    // 通信设备句柄 handle to comm device
    ref COMMTIMEOUTS lpCommTimeouts // 超时时间 time-out values
    );
    [DllImport( "coredll.dll" )]
    private static extern bool ReadFile(
    int hFile,
    // 通信设备句柄 handle to file
    byte[] lpBuffer,
    // 数据缓冲区 data buffer
    int nNumberOfBytesToRead, // 多少字节等待读取 number of bytes to read
    ref
    int lpNumberOfBytesRead, // 读取多少字节 number of bytes read
    ref OVERLAPPED lpOverlapped
    // 溢出缓冲区 overlapped buffer
    );
    [DllImport( "coredll.dll" )]
    private static extern bool WriteFile(
    int hFile,
    // 通信设备句柄 handle to file
    byte[] lpBuffer,
    // 数据缓冲区 data buffer
    int nNumberOfBytesToWrite,
    // 多少字节等待写入 number of bytes to write
    ref
    int lpNumberOfBytesWritten, // 已经写入多少字节 number of bytes written
    ref OVERLAPPED lpOverlapped
    // 溢出缓冲区 overlapped buffer
    );
    [DllImport( "coredll.dll" )]
    private static extern bool CloseHandle(
    int hObject
    // handle to object
    );
    [DllImport( "coredll.dll" )]
    private static extern u
    int GetLastError( );

    public void Open( )
    {
      DCB dcbCommPort = new DCB( );
      COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS( );
      // 打开串口 OPEN THE COMM PORT.
      hComm = CreateFile( PortNum ,GENERIC_READ | GENERIC_WRITE,0, 0,OPEN_EXISTING,0,0 );
      // 如果串口没有打开,就打开 IF THE PORT CANNOT BE OPENED, BAIL OUT.
      if( hComm == INVALID_HANDLE_VALUE )
      {
        throw( new ApplicationException( "非法操作,不能打开串口!" ) );
      }
      // 设置通信超时时间 SET THE COMM TIMEOUTS.
      GetCommTimeouts( hComm,ref ctoCommPort );
      ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;
      ctoCommPort.ReadTotalTimeoutMultiplier = 0;
      ctoCommPort.WriteTotalTimeoutMultiplier = 0;
      ctoCommPort.WriteTotalTimeoutConstant = 0;
      SetCommTimeouts( hComm,ref ctoCommPort );
      // 设置串口 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
      GetCommState( hComm, ref dcbCommPort );
      dcbCommPort.BaudRate=BaudRate;
      dcbCommPort.flags=0;
      //dcb.fBinary=1;
      dcbCommPort.flags|=1;
      if ( Parity>0 )
      {
        //dcb.fParity=1
        dcbCommPort.flags|=2;
      }
      dcbCommPort.Parity=Parity;
      dcbCommPort.ByteSize=ByteSize;
      dcbCommPort.StopBits=StopBits;
      if ( !SetCommState( hComm, ref dcbCommPort ) )
      {
        //u
        int ErrorNum=GetLastError( );
        throw( new ApplicationException( "非法操作,不能打开串口!" ) );
      }
      //unremark to see if setting took correctly
      //DCB dcbCommPort2 = new DCB( );
      //GetCommState( hComm, ref dcbCommPort2 );
      Opened = true;
    }

    public void Close( )
    {
      if ( hComm!=INVALID_HANDLE_VALUE )
      {
        CloseHandle( hComm );
      }
    }

    public byte[] Read( int NumBytes )
    {
      byte[] BufBytes;
      byte[] OutBytes;
      BufBytes = new byte[NumBytes];
      if ( hComm!=INVALID_HANDLE_VALUE )
      {
        OVERLAPPED ovlCommPort = new OVERLAPPED( );

        int BytesRead=0;
        ReadFile( hComm,BufBytes,NumBytes,ref BytesRead,ref ovlCommPort );
        try
        {
          OutBytes = new byte[BytesRead];
          Array.Copy( BufBytes,0,OutBytes,0,BytesRead );
        }
        catch
        {
          return BufBytes;
        }
      }
      else
      {
        throw( new ApplicationException( "串口未打开!" ) );
      }
      return OutBytes;
      //
      return BufBytes;
    }

    public void Write( byte[] WriteBytes )
    {
      if ( hComm!=INVALID_HANDLE_VALUE )
      {
        OVERLAPPED ovlCommPort = new OVERLAPPED( );

        int BytesWritten = 0;
        WriteFile( hComm,WriteBytes,WriteBytes.Length,ref BytesWritten,ref ovlCommPort );
      }
      else
      {
        throw( new ApplicationException( "串口未打开!" ) );
      }
    }

    public string GetGPS( string strGPS,string strFind )
    {
      ///从GPS中读取的数据中,找出想要的数据
      ///GPs
      string原始字符串,
      ///strFind要查找的内容,X:经度,Y:纬度,T:时间,V:速度,是数字从1开始,即以“,”分隔的位置
      ///返回查找到指定位置的字符串
      string handerStr="$GPRMC";
      //GPS串头
      int findHander=strGPS.IndexOf( handerStr );
      //看是否含有GPS串头
      if ( findHander<0 )
      {
        return "-1";
      }
      else
      {
        strGPS=strGPS.Sub
        string( findHander,strGPS.Length-findHander );

        string[] ArryTmp=strGPS.Split( ",".ToCharArray( ) );
        try
        {
          if( ArryTmp[2]=="V" )
          {
            return "V";
            //没有信号
          }
          else
          {
            switch( strFind )
            {
              case "X":
              return DM2DD( ArryTmp[5] );
              case "Y":
              return DM2DD( ArryTmp[3] );
              case "T":
              return T2Time( ArryTmp[9],ArryTmp[1] );
              case "V":
              return Convert.ToString( Convert.ToDouble( ArryTmp[7] )* 1.852 );
              default:
              return "V";
            }
          }
        }
        catch
        {
          return "V";
        }
      }
    }

    public string T2Time( string strDate,string strTime )
    {
      string dT="20"+strDate.Sub
      string( 4,2 )+"-"+strDate.Sub
      string( 2,2 )+"-"+strDate.Sub
      string( 0,2 );

      string TT=Convert.ToString( Convert.ToInt32( strTime.Sub
      string( 0,2 ) ) )+":"+strTime.Sub
      string( 2,2 )+":"+strTime.Sub
      string( 4,2 );
      DateTime T=Convert.ToDateTime( dT+" "+TT );
      T=T.AddHours( 8 );
      return T.ToString( );
    }

    public
    string DM2DD( string DegreeMinutes )
    {
      //转换NMEA协议的“度分”格式为十进制“度度”格式
      string sDegree;

      string sMinute;

      string sReturn="";
      if( DegreeMinutes.IndexOf( "." )==4 )
      {
        //DegreeMinutes = Replace( DegreeMinutes, ".", "" )
        //DM2DD = CDbl( Left( DegreeMinutes, 2 ) ) + CDbl( Left( CStr( CDbl( Right( DegreeMinutes, Len( DegreeMinutes ) - 2 ) ) / 60 ), 8 ) ) / 10000
        DegreeMinutes=DegreeMinutes.Replace( ".","" );
        double sDegree1=Convert.ToDouble( DegreeMinutes.Sub
        string( 0,2 ) );
        double sDegree2=Convert.ToDouble( DegreeMinutes.Sub
        string( 2,DegreeMinutes.Length-2 ) );

        string sTmp=Convert.ToString( sDegree2/60 );
        sDegree2=Convert.ToDouble( sTmp.Sub
        string( 0,sTmp.Length ) );
        sDegree2=sDegree2/10000;
        sDegree=Convert.ToString( sDegree1+sDegree2 );
        if( sDegree.Length>11 )
        sDegree=sDegree.Sub
        string( 0,11 );
        sReturn=sDegree;
      }
      else if( DegreeMinutes.IndexOf( "." )==5 )
      {
        //DegreeMinutes = Replace( DegreeMinutes, ".", "" )
        //DM2DD = CDbl( Left( DegreeMinutes, 2 ) ) + CDbl( Left( CStr( CDbl( Right( DegreeMinutes, Len( DegreeMinutes ) - 2 ) ) / 60 ), 8 ) ) / 10000
        DegreeMinutes=DegreeMinutes.Replace( ".","" );
        double sMinute1=Convert.ToDouble( DegreeMinutes.Sub
        string( 0,3 ) );
        double sMinute2=Convert.ToDouble( DegreeMinutes.Sub
        string( 3,DegreeMinutes.Length-2 ) );

        string sTmp=Convert.ToString( sMinute2/60 );
        sMinute2=Convert.ToDouble( sTmp.Sub
        string( 0,sTmp.Length ) );
        sMinute2=sMinute2/10000;
        sMinute=Convert.ToString( sMinute1+sMinute2 );
        if( sMinute.Length>10 )
        sMinute=sMinute.Sub
        string( 0,10 );
        sReturn=sMinute;
      }
      return sReturn;
    }

    public bool ScanPort( )
    {
      try
      {
        if ( Opened )
        {
          Close( );
          Open( );
        }
        else
        {
          Open( );
          //打开串口
        }
        byte[] bytRead=Read( 512 );
        Close( );
        if( Encoding.ASCII.GetString( bytRead,0,bytRead.Length ).IndexOf( "$GP" )>=0 )
        return true;
        else
        return false;
      }
      catch
      {
        return false;
      }
    }
  }
  class HexCon 
  {
    // 把十六进制字符串转换成字节型和把字节型转换成十六进制字符串 converter hex
    string to byte and byte to hex
    string 
    public static
    string ByteToString( byte[] InBytes )
    {
      string StringOut="";
      foreach ( byte InByte in InBytes )
      {
        StringOut=StringOut + String.Format( "
        {
          0:X2
        }
        ",InByte );
      }
      return StringOut;
    }

    public static byte[] StringToByte( string InString )
    {
      string[] ByteStrings;
      ByteStrings = InString.Split( " ".ToCharArray( ) );
      byte[] ByteOut;
      ByteOut = new byte[ByteStrings.Length-1];
      for ( int i = 0;
      i==ByteStrings.Length-1;
      i++ )
      {
        ByteOut[i] = Convert.ToByte( ( "0x" + ByteStrings[i] ) );
      }
      return ByteOut;
    }
  }
}

public class Frmlogin : System.Windows.Forms.Form
{
  private GPS ss_port=new GPS( );
}
#region 读取GPs
private void opengps( string ComPo
int )
{
  ss_port.PortNum = ComPo
  int;
  ss_port.BaudRate = 4800;
  ss_port.ByteSize = 8;
  ss_port.Parity = 0;
  ss_port.StopBits = 1;
  ss_port.ReadTimeout = 1000;
  try
  {
    if ( ss_port.Opened )
    {
      ss_port.Close( );
      ss_port.Open( );
      timer1.Enabled=true;
    }
    else
    {
      ss_port.Open( );
      //打开串口
      timer1.Enabled=true;
    }
  }
  catch
  {
    //
    MessageBox.Show( "读取GPS错误!" ,"系统提示" );
  }
}
private void timer1_Tick( object sender, System.EventArgs e )
{
  if ( ss_port.Opened )
  gpsread( );
  else
  ss_port.Open( );
  //打开串口 
}
private void gpsread( )
{
  byte[] aa=ss_port.Read( 512 );

  string gpsinfo =System.Text.Encoding.ASCII.GetString( aa,0,aa.Length );
  GetParam.GpsLongitude=ss_port.GetGPS( gpsinfo,"X" );
  GetParam.GpsLatitude=ss_port.GetGPS( gpsinfo,"Y" );
  GetParam.GpsSpeed=ss_port.GetGPS( gpsinfo,"V" );
  GetParam.GpsTime=ss_port.GetGPS( gpsinfo,"T" );
  if( GetParam.GpsLongitude=="-1" )
  GetParam.GpsState="0";
  if( GetParam.GpsLongitude=="V" && GetParam.GpsLatitude=="V" )
  GetParam.GpsState="0";
  if( GetParam.GpsLongitude!="-1" && GetParam.GpsLongitude!="V" )
  GetParam.GpsState="1";
  GetParam.GpsLongitude=( GetParam.GpsLongitude=="V" ) ? "0" : GetParam.GpsLongitude;
  GetParam.GpsLatitude=( GetParam.GpsLatitude=="V" ) ? "0" : GetParam.GpsLatitude;
  GetParam.GpsSpeed=( GetParam.GpsSpeed=="V" ) ? "0" : GetParam.GpsSpeed;
  GetParam.GpsTime=( GetParam.GpsTime=="V" ) ? "0" :GetParam.GpsTime;
}
private void GpsClose( )
{
  timer1.Enabled=false;
  if ( ss_port.Opened )
  ss_port.Close( );
}
#endregion
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: