在PDA中获取GPS信息。

http://www.cnblogs.com/anhlyiling/archive/2008/12/04/1347623.html
在PDA中获取GPS信息。

近日一个项目需要用在PDA上读

 

 

取GPS卫星信号,在网上搜了一圈,整理出一个GPS的类,大家可以直接加入项目

使用。可以获得当前的经纬度、海拔、速度、连接卫星数等信息


  1 using  System;
  2 using  System.Collections.Generic;
  3 using  System.Text;
  4 using  System.Runtime.InteropServices;
  5
  6 namespace  AnhlYiling
  7 {
  8   public    class  GPS 
  9   {
 10
 11    public   string  PortNum; 
 12    public   int  BaudRate;
 13    public   byte  ByteSize;
 14    public   byte  Parity;  //  0-4=no,odd,even,mark,space 
 15    public   byte  StopBits;  //  0,1,2 = 1, 1.5, 2 
 16    public   int  ReadTimeout;
 17   
 18    // comm port win32 file handle
 19    private   int  hComm  =   - 1 ;
 20   
 21    public   bool  Opened  =   false ;
 22    
 23    // win32 api constants
 24    private   const   uint  GENERIC_READ  =   0x80000000 ;
 25    private   const   uint  GENERIC_WRITE  =   0x40000000 ;
 26    private   const   int  OPEN_EXISTING  =   3 ;  
 27    private   const   int  INVALID_HANDLE_VALUE  =   - 1 ;
 28   
 29   [StructLayout(LayoutKind.Sequential)]
 30     public   struct  DCB 
 31    {
 32     // taken from c struct in platform sdk 
 33     public   int  DCBlength;            //  sizeof(DCB) 
 34     public   int  BaudRate;             //  指定当前波特率 current baud rate
 35     //  these are the c struct bit fields, bit twiddle flag to set
 36     public   int  fBinary;           //  指定是否允许二进制模式,在windows95中必须主TRUE binary mode, no EOF check 
 37     public   int  fParity;           //  指定是否允许奇偶校验 enable parity checking 
 38     public   int  fOutxCtsFlow;       //  指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起。 CTS output flow control 
 39     public   int  fOutxDsrFlow;       //  指定CTS是否用于检测发送控制 DSR output flow control 
 40     public   int  fDtrControl;        //  DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON, DTR_CONTROL_HANDSHAKE允许DTR"握手" DTR flow control type 
 41     public   int  fDsrSensitivity;    //  当该值为TRUE时DSR为OFF时接收的字节被忽略 DSR sensitivity 
 42     public   int  fTXContinueOnXoff;  //  指 定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止。TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动 程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。 FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序 已经发送出恢复发送的XonChar之后,发送继续进行。XOFF continues Tx 
 43     public   int  fOutX;           //  TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始 XON/XOFF out flow control 
 44     public   int  fInX;            //  TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去 XON/XOFF in flow control 
 45     public   int  fErrorChar;      //  该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误的接收字符 enable error replacement 
 46     public   int  fNull;           //  eTRUE时,接收时去掉空(0值)字节 enable null stripping 
 47     public   int  fRtsControl;      //  RTS flow control 
 48     /* RTS_CONTROL_DISABLE时,RTS置为OFF
 49             RTS_CONTROL_ENABLE时, RTS置为ON
 50             RTS_CONTROL_HANDSHAKE时,
 51             当接收缓冲区小于半满时RTS为ON
 52              当接收缓冲区超过四分之三满时RTS为OFF
 53             RTS_CONTROL_TOGGLE时,
 54             当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF */

 55
 56     public   int  fAbortOnError;    //  TRUE时,有错误发生时中止读和写操作 abort on error 
 57     public   int  fDummy2;         //  未使用 reserved 
 58    
 59     public   uint  flags;
 60     public   ushort  wReserved;           //  未使用,必须为0 not currently used 
 61     public   ushort  XonLim;              //  指定在XON字符发送这前接收缓冲区中可允许的最小字节数 transmit XON threshold 
 62     public   ushort  XoffLim;             //  指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数 transmit XOFF threshold 
 63     public   byte  ByteSize;            //  指定端口当前使用的数据位 number of bits/byte, 4-8 
 64     public   byte  Parity;              //  指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY  0-4=no,odd,even,mark,space 
 65     public   byte  StopBits;            //  指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS  0,1,2 = 1, 1.5, 2 
 66     public   char  XonChar;             //  指定用于发送和接收字符XON的值 Tx and Rx XON character 
 67     public   char  XoffChar;            //  指定用于发送和接收字符XOFF值 Tx and Rx XOFF character 
 68     public   char  ErrorChar;           //  本字符用来代替接收到的奇偶校验发生错误时的值 error replacement character 
 69     public   char  EofChar;             //  当没有使用二进制模式时,本字符可用来指示数据的结束 end of input character 
 70     public   char  EvtChar;             //  当接收到此字符时,会产生一个事件 received event character 
 71     public   ushort  wReserved1;          //  未使用 reserved; do not use 
 72   }

 73
 74   [StructLayout(LayoutKind.Sequential)]
 75     private   struct  COMMTIMEOUTS 
 76    {  
 77     public   int  ReadIntervalTimeout; 
 78     public   int  ReadTotalTimeoutMultiplier; 
 79     public   int  ReadTotalTimeoutConstant; 
 80     public   int  WriteTotalTimeoutMultiplier; 
 81     public   int  WriteTotalTimeoutConstant; 
 82   }
  
 83
 84   [StructLayout(LayoutKind.Sequential)] 
 85     private   struct  OVERLAPPED 
 86   
 87     public   int   Internal; 
 88     public   int   InternalHigh; 
 89     public   int   Offset; 
 90     public   int   OffsetHigh; 
 91     public   int  hEvent; 
 92   }
  
 93   
 94   [DllImport( " coredll.dll " )]
 95    private   static   extern   int  CreateFile(
 96     string  lpFileName,                          //  要打开的串口名称
 97     uint  dwDesiredAccess,                       //  指定串口的访问方式,一般设置为可读可写方式
 98     int  dwShareMode,                           //  指定串口的共享模式,串口不能共享,所以设置为0
 99     int  lpSecurityAttributes,  //  设置串口的安全属性,WIN9X下不支持,应设为NULL
100     int  dwCreationDisposition,                 //  对于串口通信,创建方式只能为OPEN_EXISTING
101     int  dwFlagsAndAttributes,                  //  指定串口属性与标志,设置为FILE_FLAG_OVERLAPPED(重叠I/O操作),指定串口以异步方式通信
102     int  hTemplateFile                         //  对于串口通信必须设置为NULL
103    );
104   [DllImport( " coredll.dll " )]
105    private   static   extern   bool  GetCommState(
106     int  hFile,   // 通信设备句柄
107     ref  DCB lpDCB     //  设备控制块DCB
108    ); 
109   [DllImport( " coredll.dll " )]
110    private   static   extern   bool  BuildCommDCB(
111     string  lpDef,   //  设备控制字符串
112     ref  DCB lpDCB      //  设备控制块
113    );
114   [DllImport( " coredll.dll " )]
115    private   static   extern   bool  SetCommState(
116     int  hFile,   //  通信设备句柄
117     ref  DCB lpDCB     //  设备控制块
118    );
119   [DllImport( " coredll.dll " )]
120    private   static   extern   bool  GetCommTimeouts(
121     int  hFile,                   //  通信设备句柄 handle to comm device
122     ref  COMMTIMEOUTS lpCommTimeouts   //  超时时间 time-out values
123    ); 
124   [DllImport( " coredll.dll " )] 
125    private   static   extern   bool  SetCommTimeouts(
126     int  hFile,                   //  通信设备句柄 handle to comm device
127     ref  COMMTIMEOUTS lpCommTimeouts   //  超时时间 time-out values
128    );
129   [DllImport( " coredll.dll " )]
130    private   static   extern   bool  ReadFile(
131     int  hFile,                 //  通信设备句柄 handle to file
132     byte [] lpBuffer,              //  数据缓冲区 data buffer
133     int  nNumberOfBytesToRead,   //  多少字节等待读取 number of bytes to read
134     ref   int  lpNumberOfBytesRead,  //  读取多少字节 number of bytes read
135     ref  OVERLAPPED lpOverlapped     //  溢出缓冲区 overlapped buffer
136    );
137   [DllImport( " coredll.dll " )] 
138    private   static   extern   bool  WriteFile(
139     int  hFile,                     //  通信设备句柄 handle to file
140     byte [] lpBuffer,                 //  数据缓冲区 data buffer
141     int  nNumberOfBytesToWrite,      //  多少字节等待写入 number of bytes to write
142     ref   int  lpNumberOfBytesWritten,   //  已经写入多少字节 number of bytes written
143     ref  OVERLAPPED lpOverlapped         //  溢出缓冲区 overlapped buffer
144    );
145   [DllImport( " coredll.dll " )]
146    private   static   extern   bool  CloseHandle(
147     int  hObject    //  handle to object
148    );
149   [DllImport( " coredll.dll " )]
150    private   static   extern   uint  GetLastError();
151   
152    public   void  Open()
153    {
154   
155    DCB dcbCommPort  =   new  DCB();
156    COMMTIMEOUTS ctoCommPort  =   new  COMMTIMEOUTS(); 
157      
158     //  打开串口 OPEN THE COMM PORT.
159    hComm  =  CreateFile(PortNum ,GENERIC_READ  |  GENERIC_WRITE, 0 0 ,OPEN_EXISTING, 0 , 0 );
160     //  如果串口没有打开,就打开 IF THE PORT CANNOT BE OPENED, BAIL OUT.
161     if (hComm  ==  INVALID_HANDLE_VALUE) 
162     {
163      throw ( new  ApplicationException( " 非法操作,不能打开串口! " ));
164    }

165   
166     //  设置通信超时时间 SET THE COMM TIMEOUTS.
167    GetCommTimeouts(hComm, ref  ctoCommPort);
168    ctoCommPort.ReadTotalTimeoutConstant  =  ReadTimeout;
169    ctoCommPort.ReadTotalTimeoutMultiplier  =   0 ;
170    ctoCommPort.WriteTotalTimeoutMultiplier  =   0 ;
171    ctoCommPort.WriteTotalTimeoutConstant  =   0 ;  
172    SetCommTimeouts(hComm, ref  ctoCommPort);
173   
174     //  设置串口 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
175    GetCommState(hComm,  ref  dcbCommPort);
176    dcbCommPort.BaudRate = BaudRate;
177    dcbCommPort.flags = 0 ;
178     // dcb.fBinary=1;
179    dcbCommPort.flags |= 1 ;
180     if  (Parity > 0 )
181     {
182      // dcb.fParity=1
183     dcbCommPort.flags |= 2 ;
184    }

185    dcbCommPort.Parity = Parity;
186    dcbCommPort.ByteSize = ByteSize;
187    dcbCommPort.StopBits = StopBits;
188     if  ( ! SetCommState(hComm,  ref  dcbCommPort))
189     {
190      // uint ErrorNum=GetLastError();
191      throw ( new  ApplicationException( " 非法操作,不能打开串口! " ));
192    }

193     // unremark to see if setting took correctly
194     // DCB dcbCommPort2 = new DCB();
195     // GetCommState(hComm, ref dcbCommPort2);
196    Opened  =   true ;
197   }

198   
199    public   void  Close() 
200    {
201     if  (hComm != INVALID_HANDLE_VALUE) 
202     {
203     CloseHandle(hComm);
204    }

205   }

206   
207    public   byte [] Read( int  NumBytes) 
208    {
209     byte [] BufBytes;
210     byte [] OutBytes;
211    BufBytes  =   new   byte [NumBytes];
212     if  (hComm != INVALID_HANDLE_VALUE) 
213     {
214     OVERLAPPED ovlCommPort  =   new  OVERLAPPED();
215      int  BytesRead = 0 ;
216     ReadFile(hComm,BufBytes,NumBytes, ref  BytesRead, ref  ovlCommPort);
217      try
218      {
219      OutBytes  =   new   byte [BytesRead];
220      Array.Copy(BufBytes, 0 ,OutBytes, 0 ,BytesRead);
221     }

222      catch
223      {
224       return  BufBytes;
225     }

226     
227    }
 
228     else  
229     {
230      throw ( new  ApplicationException( " 串口未打开! " ));
231    }

232     return  OutBytes;
233     //    return BufBytes;
234   }

235   
236    public   void  Write( byte [] WriteBytes) 
237    {
238     if  (hComm != INVALID_HANDLE_VALUE) 
239     {
240     OVERLAPPED ovlCommPort  =   new  OVERLAPPED();
241      int  BytesWritten  =   0 ;
242     WriteFile(hComm,WriteBytes,WriteBytes.Length, ref  BytesWritten, ref  ovlCommPort);
243    }

244     else  
245     {
246      throw ( new  ApplicationException( " 串口未打开! " ));
247    }
  
248   }

249
250    public   string  GetGPS( string  hander, string  strGPS, string  strFind)
251    {
252     /// 从GPS中读取的数据中,找出想要的数据
253     /// GPSstring原始字符串,
254     /// strFind要查找的内容,X:经度,Y:纬度,T:时间,V:速度,N 当前可用卫星数量,H 当前海拔
255     /// 返回查找到指定位置的字符串

256        if  (hander.Equals( " $GPRMC " ))
257        {
258            string  handerStr  =  hander; // GPS串头
259            int  findHander  =  strGPS.IndexOf(handerStr); // 看是否含有GPS串头
260            if  (findHander  <   0 )
261            {
262                return   " -1 " ;
263           }

264            else
265            {
266               strGPS  =  strGPS.Substring(findHander, strGPS.Length  -  findHander);
267                string [] ArryTmp  =  strGPS.Split( " , " .ToCharArray());
268                try
269                {
270                    if  (ArryTmp[ 2 ==   " V " )
271                    {
272                        return   " GPS没有信号 " ; // 没有信号
273                   }

274                    else
275                    {
276                        switch  (strFind)
277                        {
278                            case   " X " :
279                                return  DM2DD(ArryTmp[ 5 ]);
280
281                            case   " Y " :
282                                return  DM2DD(ArryTmp[ 3 ]);
283
284                            case   " T " :
285                                return  T2Time(ArryTmp[ 9 ], ArryTmp[ 1 ]);
286
287                            case   " V " :
288                                return  Convert.ToString(Convert.ToDouble(ArryTmp[ 7 ])  *   1.852 );
289
290                            case   " K " :
291                                return  ArryTmp[ 7 ];
292                            default :
293                                return   " V " ;
294
295                       }

296                   }

297               }

298                catch
299                {
300                    return   " V " ;
301               }

302           }

303       }

304        else   if  (hander.Equals( " $GPGGA " ))
305        {
306            string  handerStr  =  hander; // GPS串头
307            int  findHander  =  strGPS.IndexOf(handerStr); // 看是否含有GPS串头
308            if  (findHander  <   0 )
309            {
310                return   " -1 " ;
311           }

312            else
313            {
314               strGPS  =  strGPS.Substring(findHander, strGPS.Length  -  findHander);
315                string [] ArryTmp  =  strGPS.Split( " , " .ToCharArray());
316                switch  (strFind)
317                {
318                    case   " N " :
319                        return  ArryTmp[ 7 ];
320                    case   " H " :
321                        return  ArryTmp[ 9 ];
322                    default :
323                        return   " 无法解析的命令. " ;
324               }

325           }

326       }

327
328        return   null ;
329
330   }

331
332    public   string  T2Time( string  strDate, string  strTime)
333    {
334     string  dT = " 20 " + strDate.Substring( 4 , 2 ) + " - " + strDate.Substring( 2 , 2 ) + " - " + strDate.Substring( 0 , 2 );
335     string  TT = Convert.ToString(Convert.ToInt32(strTime.Substring( 0 , 2 ))) + " : " + strTime.Substring( 2 , 2 ) + " : " + strTime.Substring( 4 , 2 );
336    DateTime T = Convert.ToDateTime(dT + "   " + TT);
337    T = T.AddHours( 8 );
338     return  T.ToString();
339   }

340
341    public   string  DM2DD( string  DegreeMinutes)
342    {
343     // 转换NMEA协议的“度分”格式为十进制“度度”格式
344     string  sDegree;
345     string  sMinute;
346     string  sReturn = "" ;
347     if (DegreeMinutes.IndexOf( " . " ) == 4 )
348     {
349      // DegreeMinutes = Replace(DegreeMinutes, ".", "")
350      // DM2DD = CDbl(Left(DegreeMinutes, 2)) + CDbl(Left(CStr(CDbl(Right(DegreeMinutes, Len(DegreeMinutes) - 2)) / 60), 8)) / 10000
351     DegreeMinutes = DegreeMinutes.Replace( " . " , "" );
352      double  sDegree1 = Convert.ToDouble(DegreeMinutes.Substring( 0 , 2 ));
353      double  sDegree2 = Convert.ToDouble(DegreeMinutes.Substring( 2 ,DegreeMinutes.Length - 2 ));
354      string  sTmp = Convert.ToString(sDegree2 / 60 );
355     sDegree2 = Convert.ToDouble(sTmp.Substring( 0 ,sTmp.Length));
356     sDegree2 = sDegree2 / 10000 ;
357     sDegree = Convert.ToString(sDegree1 + sDegree2);
358      if (sDegree.Length > 11 )
359      sDegree = sDegree.Substring( 0 , 11 );
360     sReturn = sDegree;
361    }

362     else   if (DegreeMinutes.IndexOf( " . " ) == 5 )
363     {
364      // DegreeMinutes = Replace(DegreeMinutes, ".", "")
365      // DM2DD = CDbl(Left(DegreeMinutes, 2)) + CDbl(Left(CStr(CDbl(Right(DegreeMinutes, Len(DegreeMinutes) - 2)) / 60), 8)) / 10000
366     DegreeMinutes = DegreeMinutes.Replace( " . " , "" );
367      double  sMinute1 = Convert.ToDouble(DegreeMinutes.Substring( 0 , 3 ));
368      double  sMinute2 = Convert.ToDouble(DegreeMinutes.Substring( 3 ,DegreeMinutes.Length - 3 ));
369      string  sTmp = Convert.ToString(sMinute2 / 60 );
370     sMinute2 = Convert.ToDouble(sTmp.Substring( 0 ,sTmp.Length));
371     sMinute2 = sMinute2 / 10000 ;
372     sMinute = Convert.ToString(sMinute1 + sMinute2);
373      if (sMinute.Length > 10 )
374      sMinute = sMinute.Substring( 0 , 10 );
375     sReturn = sMinute;
376    }

377     return  sReturn;
378   }

379
380    public   bool  ScanPort()
381    {
382    
383     try
384     {
385      if  (Opened)
386      {
387      Close();
388      Open();
389     }

390      else
391      {
392      Open(); // 打开串口
393      
394     }

395      byte [] bytRead = Read( 512 );
396     Close();
397      if (Encoding.ASCII.GetString(bytRead, 0 ,bytRead.Length).IndexOf( " $GP " ) >= 0 )
398       return   true ;
399      else
400       return   false ;
401    }

402     catch
403     {
404      return   false ;
405    }

406
407   }

408  }

409
410   class  HexCon 
411   {
412    //  把十六进制字符串转换成字节型和把字节型转换成十六进制字符串 converter hex string to byte and byte to hex string
413    public   static   string  ByteToString( byte [] InBytes) 
414    {
415     string  StringOut = "" ;
416     foreach  ( byte  InByte  in  InBytes) 
417     {
418     StringOut = StringOut  +  String.Format( " {0:X2}  " ,InByte);
419    }

420     return  StringOut; 
421   }

422    public   static   byte [] StringToByte( string  InString) 
423    {
424     string [] ByteStrings;
425    ByteStrings  =  InString.Split( "   " .ToCharArray());
426     byte [] ByteOut;
427    ByteOut  =   new   byte [ByteStrings.Length - 1 ];
428     for  ( int  i  =   0 ;i == ByteStrings.Length - 1 ;i ++
429     {
430     ByteOut[i]  =  Convert.ToByte(( " 0x "   +  ByteStrings[i]));
431    }
 
432     return  ByteOut;
433   }

434
435  }

436 }

437

 

调用很简单:

 1    GPS ss_port  =   new  GPS();
 2               ss_port.PortNum  =   " COM4: " ;   // 串口号.后面一定要有':'
 3               ss_port.BaudRate  =   4800
 4               ss_port.ByteSize  =   8 ;
 5               ss_port.Parity  =   0 ;
 6               ss_port.StopBits  =   1 ;
 7               ss_port.ReadTimeout  =   1000 ;
 8  
 9                try
10               {
11                    if  (ss_port.Opened)
12                   {
13                       ss_port.Close();
14                       ss_port.Open();
15                       timer1.Enabled  =   true ;
16                   }
17                    else
18                   {
19                       ss_port.Open(); // 打开串口
20                       label1.Text  =   " 已打开 " ;
21                       timer1.Enabled  =   true ;
22                   }
23  
24               }
25                catch  (Exception e1)
26               {
27                   label1.Text  =  e1.Message;
28  
29               }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值