一、须知

1.手持机(PDA)必须有GPS模块,才能通过代码使用串口通信获取GPS相关信息

2.要清楚自己手持机(PDA)固定的GPS通信串口号,如我们公司的手持机获取GPS信息的串口为COM4

3.测试手持机(PDA)是否获取到GPS相关信息,要到室外才能测试出来。

 

二、制作步骤

(1)新建好win ce项目

 

(2)封装类

1.CLR_GPS类

  1 class CLR_GPS
  2     {
  3 
  4         public  float latitude = 0; //纬度
  5 
  6         public  float longitude = 0;    //经度
  7 
  8         public  float speed = 0;
  9 
 10         public  float status = 0;
 11 
 12         public  float direction = 0;
 13 
 14         public  float geoideAltitude = 0;
 15 
 16         private System.IO.Ports.SerialPort serialPort;
 17 
 18         CLR_Regex gpsRegex=new CLR_Regex();
 19 
 20         private bool isOpen = false;
 21         
 22         
 23 #region 
 24         private delegate void myTestEventHandler();
 25         public delegate void LocationEventHandler(string Latitude, string Longitude,string status,bool isNorth,bool isEast,string time);
 26         public delegate void serialEventHandler(string data);
 27         public delegate void TimeEventHandler(string time);
 28         public delegate void DateEventHandler(string date);
 29         public delegate void satelliteEventHandlde(string n);
 30         public delegate void altitudeEventHandler(string altitude);
 31         public delegate void satelliteNumberEventHandler(string num);
 32 
 33 
 34         private string serialData = string.Empty;
 35 
 36         /// <summary>
 37         /// refresh serial data       更新串口数据
 38         /// </summary>
 39         public event serialEventHandler serialportData;   
 40       
 41         /// <summary>
 42         ///  Refresh Location   更新经纬度
 43         /// </summary>
 44         public event LocationEventHandler refreshLocation;     
 45 
 46 
 47         /// <summary>
 48         /// Refresh Time    更新时间
 49         /// </summary>
 50         public event TimeEventHandler refreshTime;              
 51 
 52 
 53         /// <summary>
 54         /// Refresh Date       更新日期
 55         /// </summary>
 56         public event DateEventHandler refreshDate;              
 57 
 58 
 59         /// <summary>
 60         /// Satellite Total     可视卫星数量
 61         /// </summary>
 62         public event satelliteNumberEventHandler refreshAllNumber;
 63 
 64         /// <summary>
 65         /// Refresh effective satellite 更新卫星数量
 66         /// </summary>
 67         public event satelliteEventHandlde refreshSatellite;    
 68 
 69 
 70         /// <summary>
 71         /// Refresh Altitude  更新海拔
 72         /// </summary>
 73         public event altitudeEventHandler refreshAltitude;     
 74 
 75 
 76 
 77 #endregion
 78     
 79 
 80 
 81         public CLR_GPS()
 82         {
 83             serialPort = new System.IO.Ports.SerialPort("COM4", 115200);      //此处可根据实际情况设置串口
 84             serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort_DataReceived);
 85            
 86         }
 87 
 88         public CLR_GPS(string portName)
 89         {
 90             serialPort = new System.IO.Ports.SerialPort(portName, 115200);  //此处可根据实际情况设置串口
 91             serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort_DataReceived);
 92            
 93         }
 94 
 95 
 96         /// <summary>
 97         /// stop Receive data   停止接收数据
 98         /// </summary>
 99         public void stopReceive()
100         {        
101             isOpen = false;
102             Thread.Sleep(300);
103         }
104 
105         /// <summary>
106         /// start Receiving     开始接收数据
107         /// </summary>
108         public bool startReceive()
109         {
110             try
111             {
112                 isOpen = true;            
113                 if (!serialPort.IsOpen)
114                 {
115                     serialPort.Open();
116                 }                                
117                 return true;
118             }
119             catch (System.Exception)
120             {
121                 isOpen = false;
122                 return false;
123             }          
124            
125         }
126 
127 
128         /// <summary>
129         /// initialization      初始化
130         /// </summary>
131         /// <returns></returns>
132         public bool InitModule()
133         {
134             return true;  //此处可根据实际情况进行GPS模块的上电
135 
136         }
137 
138 
139 
140         public void FreeModule()
141         {
142             try
143             {
144 
145                 isOpen = false;
146 
147 
148                 if (serialPort.IsOpen)
149                 {
150                     serialPort.Close();
151                 }
152 
153             }
154             catch (Exception)
155             {
156 
157             }
158             //此处可根据实际情况进行GPS模块的下电
159             
160         }
161 
162         void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
163         {
164             try
165             {
166                 serialData = serialData + serialPort.ReadExisting();
167                 if (serialData.Length > 300)
168                 {
169                     serialData = serialData.Substring(serialData.LastIndexOf('$'));
170                 }
171 
172                 if (isOpen)
173                 {
174                     if (serialportData != null)
175                     {
176                         serialportData(serialData);
177                     }
178                     AnalysisGPSData(serialData);
179 
180                 }
181             }
182             catch { }
183                           
184         }
185 
186        
187 
188 
189         private void AnalysisGPGGA(string scr)
190         {
191             string altitude = string.Empty;
192             string[] fields = scr.Split(',');
193 
194            
195             if (fields.Length>10)
196             {
197                 string num = fields[7].Trim();
198                 if (num.Length > 0 && gpsRegex.isNumber(num))
199                 {
200                     //satelliteNumber = Convert.ToInt32(fields[7].Trim());
201                     if (refreshSatellite != null)
202                     {
203                         //Effective Satellite 更新使用卫星数量
204                         refreshSatellite(num);
205                     }
206                 }
207 
208                 if (fields[9].Trim().Length > 0)
209                 {
210                     //refresh  Altitude   更新海拔
211                     if (refreshAltitude != null)
212                     {        
213                         refreshAltitude(fields[9].Trim());
214                     }
215                 }
216             }
217            
218                
219         }
220 
221 
222         private bool AnalysisGPRMC(string scr)
223         {
224             int latiDegree = 400, longiDegree = 400;
225             float latiMinute = 400, longiMinute = 400, speedTemp = 0, directionTemp = direction;
226             string statusTemp = string.Empty;
227             float latitudeTemp = 400, longitudeTemp = 400;
228             bool paramChanged = false;
229 
230             bool isNortHemisphere = true;
231             bool isEastHemisphere=true;
232             string time = string.Empty;
233 
234             string[] fields = scr.Split(',');
235 
236             if (fields.GetLength(0) < 12)
237                 return false;
238             // 状态
239 
240             string[] utc = fields[1].Trim().Split('.');
241 
242 
243             if (utc[0].Trim().Length == 6)
244             {
245                 time = utc[0].Trim();
246                 if (refreshTime!=null)
247                 {
248                     refreshTime(time);
249                 }
250             }
251 
252             if (fields[2]=="A")
253             {
254                 // //= Convert.ToChar(fields[2]);
255                 //char d = Convert.ToChar(fields[2]);
256                 statusTemp = fields[2];
257             }
258             // Lati 
259             if (fields[3].Length > 5)
260             {
261                 if (System.Text.RegularExpressions.Regex.Match(fields[3], @"^[0-9]+[.]?([\d]+)?").Value == fields[3])
262                 {
263                     latiDegree = Convert.ToInt32(fields[3].Substring(0, 2), 10);
264                     latiMinute = Convert.ToSingle(fields[3].Substring(2, fields[3].Length - 2));
265                     paramChanged = true;
266                 }
267             }
268             // NSHemisphere  NSHemisphere     南北半球
269             if (fields[4].Length == 1)
270             {
271                 //'s' 'S' 
272                 if (string.Equals(fields[4], "S", StringComparison.CurrentCultureIgnoreCase))
273                 {
274                     isNortHemisphere = false;   //南半球
275                     latitudeTemp = -latitudeTemp;
276                 }
277             }
278             // long 
279             if (fields[5].Length > 5)
280             {
281                 if (System.Text.RegularExpressions.Regex.Match(fields[5], @"^[0-9]+[.]?([\d]+)?").Value == fields[5])
282                 {
283                     longiDegree = Convert.ToInt32(fields[5].Substring(0, 3), 10);
284                     longiMinute = Convert.ToSingle(fields[5].Substring(3, fields[5].Length - 3));
285                     paramChanged = true;
286                 }
287             }
288             // EWHemisphere    东经 西经
289             if (fields[6].Length == 1)
290             {
291                 //'w' 'W' 
292                 if (string.Equals(fields[6], "W", StringComparison.CurrentCultureIgnoreCase))
293                 {
294                     isEastHemisphere=false; //西半球
295                     longitudeTemp = -longitudeTemp;
296                 }
297             }
298             // speed    速率
299             if (fields[7].Length > 2)
300             {
301                 if (System.Text.RegularExpressions.Regex.Match(fields[7], @"^[0-9]+[.]?([\d]+)?").Value == fields[7])
302                 {
303                     speedTemp = (float)(Convert.ToSingle(fields[7]) * 1.852);
304                     paramChanged = true;
305                 }
306             }
307             // direction   地面航向 正北为零度
308             if (fields[8].Length > 2)
309             {
310                 if (System.Text.RegularExpressions.Regex.Match(fields[8], @"^[0-9]+[.]?([\d]+)?").Value == fields[8])
311                 {
312                     directionTemp = Convert.ToSingle(fields[8]);
313                     paramChanged = true;
314                 }
315             }
316 
317             if (fields[9].Trim().Length==6)
318             {
319                 if (refreshDate!=null)
320                 {
321                     refreshDate(trandforDate(fields[9].Trim()));
322                 }
323             }
324             if ((latiDegree != 400) && (latiMinute != (float)400.0))
325             {
326                 latitudeTemp = (float)(latiDegree + latiMinute / 60.0);
327             }
328             if ((longiDegree != 400) && (longiMinute != (float)400.0))
329             {
330                 longitudeTemp = (float)(longiDegree + longiMinute / 60.0);
331             }
332             if (paramChanged)
333             {
334                 if (refreshLocation != null)
335                 {
336                     refreshLocation(fields[4]+":"+latitudeTemp.ToString(), fields[6]+":"+longitudeTemp.ToString(), statusTemp,isNortHemisphere,isEastHemisphere, time);
337                 }
338                     return true;            
339             }
340             else
341                 return false;
342         }
343 
344 
345         /// <summary>
346         /// data  for date  将GPS数据转换成日期
347         /// </summary>
348         /// <param name="date"></param>
349         /// <returns></returns>
350         string trandforDate(string date)
351         {
352             return "20"+date.Substring(4, 2) + "-" + date.Substring(2, 2) + "-" + date.Substring(0, 2);
353         }
354 
355 
356 
357 
358         void AnalysisGPGSV(string scr)
359         {
360             string[] fields = scr.Split(',');
361 
362             if (fields.Length>4)
363             {
364                 string AllNum = fields[3].Trim();
365 
366                 if (AllNum.Length > 0 && gpsRegex.isNumber(AllNum) && refreshAllNumber != null)
367                 {
368                     //Satellite Total
369                     refreshAllNumber(fields[3]);
370                 }
371             }
372 
373             // 状态
374         }
375 
376 
377         private void AnalysisGPSData(string sGpsData)
378         {
379             string[] gpsDataSplit = sGpsData.Trim().Split('$');
380 
381 
382             foreach (string gps in gpsDataSplit)
383             {
384                 if (gps.StartsWith("GPRMC"))
385                 {
386                     AnalysisGPRMC(gps);
387                 }
388                 else if (gps.StartsWith("GPVTG"))
389                 {
390                     AnalysisGPVTG(gps);
391                 }
392                 else if (gps.StartsWith("GPGGA"))
393                 {
394                     AnalysisGPGGA(gps);
395                 }
396                 else if (gps.StartsWith("GPGSV"))
397                 {
398                     AnalysisGPGSV(gps);
399                 }
400                 else if (gps.StartsWith("GPGLL"))
401                 {
402 
403                 }
404             }
405             return;
406         }
407 
408 
409          public void AnalysisGPVTG(string sGpsData)
410          {
411 
412          }
413 
414     }
View Code

 

2.CLR_Regex类

class CLR_Regex
    {
        //public bool includeXing(string msg)
        //{           
        //    if (Regex.Match(msg, @"^[0-9]+[*]?([\d]+)?").Value == msg)
        //    {
        //        return true;
        //    }
        //    else
        //        return false;
        //}


        /// <summary>
        /// is number ?  是否全是数字
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool isNumber(string msg)
        {
          
            if (Regex.Match(msg, "^[0-9]*$").Value == msg)
            {
                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// is real   是否为实数
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool isRealData(string msg)
        {
            if (msg.StartsWith("-"))
            {
                msg = msg.Substring(1);
            }
            if (Regex.Match(msg, "^[0-9]+(.[0-9]+)$").Value == msg)
            {
                return true;
            }
            else
                return false;

        }


    }
View Code

 

3.GPS类

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 uint GENERIC_READ = 0x80000000;
        private const uint 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 uint 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, // 要打开的串口名称
        uint 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 uint 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))
            {
                //uint 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中读取的数据中,找出想要的数据
            ///GPSstring原始字符串,
            ///strFind要查找的内容,X:经度,Y:纬度,T:时间,V:速度,是数字从1开始,即以“,”分隔的位置
            ///返回查找到指定位置的字符串
            string handerStr = "$GPRMC";//GPS串头
            int findHander = strGPS.IndexOf(handerStr);//看是否含有GPS串头
            if (findHander < 0)
            {
                return "-1";
            }
            else
            {
                strGPS = strGPS.Substring(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.Substring(4, 2) + "-" + strDate.Substring(2, 2) + "-" + strDate.Substring(0, 2);
            string TT = Convert.ToString(Convert.ToInt32(strTime.Substring(0, 2))) + ":" + strTime.Substring(2, 2) + ":" + strTime.Substring(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.Substring(0, 2));
                double sDegree2 = Convert.ToDouble(DegreeMinutes.Substring(2, DegreeMinutes.Length - 2));
                string sTmp = Convert.ToString(sDegree2 / 60);
                sDegree2 = Convert.ToDouble(sTmp.Substring(0, sTmp.Length));
                sDegree2 = sDegree2 / 10000;
                sDegree = Convert.ToString(sDegree1 + sDegree2);
                if (sDegree.Length > 11)
                    sDegree = sDegree.Substring(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.Substring(0, 3));
                double sMinute2 = Convert.ToDouble(DegreeMinutes.Substring(3, DegreeMinutes.Length - 2));
                string sTmp = Convert.ToString(sMinute2 / 60);
                sMinute2 = Convert.ToDouble(sTmp.Substring(0, sTmp.Length));
                sMinute2 = sMinute2 / 10000;
                sMinute = Convert.ToString(sMinute1 + sMinute2);
                if (sMinute.Length > 10)
                    sMinute = sMinute.Substring(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;
        }
    }
View Code

 

(3)界面设计

 

(4)获取GPS相关信息

public partial class TestGps : Form
    {
        #region 
            private delegate void mySerial();
            private delegate void myTestEventHandler();
            //private event myTestEventHandler myTest();
            private string gprsData = string.Empty;
         
            private bool isClosed = false;

            public delegate void LocationShow(string Latitude, string Longitude, string status, bool isNorth, bool isEast, string time);

            public delegate void portDataShow(string data);

            double beginTime = 0;
            double endTime = 0;
            CLR_GPS gps;
            
            bool firstLocation = false;
        
        #endregion

        public TestGps()
        {
            InitializeComponent();
            gps = new CLR_GPS();
            gps.refreshLocation += gps_refreshLocation;
            gps.refreshTime += gps_refreshTime;
            gps.refreshDate += gps_refreshDate;
            //gps.refreshAltitude += new CLR_GPS.altitudeEventHandler(gps_refreshAltitude);
            gps.refreshSatellite += gps_refreshSatellite;
            gps.refreshAllNumber += gps_refreshAllNumber;
            gps.InitModule();
        }

        #region Satellite Total
        void gps_refreshAllNumber(string num)
        {
            if (isClosed)
            {
                return;
            }
            Invoke(new portDataShow(showNumber), num);
        }

        void showNumber(string num)
        {
            textBoxAll.Text = num;
        }
#endregion

        #region Refresh effective satellite
        void gps_refreshSatellite(string n)
        {
            if (isClosed)
            {
                return;
            }
            Invoke(new portDataShow(showSatellite), n);
        }

        void showSatellite(string n)
        {
            textBoxsatellite.Text = n;
        }
#endregion

        #region     refresh Altitude
        //void gps_refreshAltitude(string altitude)
        //{
        //    if (isClosed)
        //    {
        //        return;
        //    }
        //    this.Invoke(new portDataShow(showAltitude), altitude);
        //}

        //void showAltitude(string altitude)
        //{
        //    textBoxAltitude.Text = altitude;
        //}
        #endregion
     
        #region refresh date
        void gps_refreshDate(string date)
        {
            if (isClosed)
            {
                return;
            }
            Invoke(new portDataShow(showDate), date);
        }

        void showDate(string date)
        {
            textBoxDate.Text = date;
        }
#endregion

        #region  refresh time
        void gps_refreshTime(string time)
        {
            if (isClosed)
            {
                return;
            }
            Invoke(new portDataShow(showTime), time);
        }

        void showTime(string time)
        {
            textBoxTime.Text = time.Substring(0, 2) + ":" + time.Substring(2, 2) + ":" + time.Substring(4, 2);
        }
#endregion

        #region refresh location
        void gps_refreshLocation(string Latitude, string Longitude, string status, bool isNorth, bool isEast, string time)
        {
            if (isClosed)
            {
                return;
            }
            Invoke(new LocationShow(showLocation), Latitude, Longitude, status, isNorth, isEast, time);
        }  
        private void showLocation(string Latitude, string Longitude, string status, bool isNorth, bool isEast,string time)
        {
            if (!firstLocation)
            {
                firstLocation = true;
                endTime = DateTime.Now.Minute * 60 + DateTime.Now.Second;

                textBoxAccess.Text = Convert.ToString(DateTime.Now.TimeOfDay.ToString());

                textBoxSpend.Text = Convert.ToString(endTime - beginTime);
            }
            textBoxLa.Text = Latitude;
            textBoxLo.Text = Longitude;            
        }

#endregion


        #region 窗体加载事件 判断操作系统是中文还是英文 进行控件赋值
        private void MainForm_Load(object sender, EventArgs e)
        {
            int n = 0;
            if (isEnglish())
            {
                n = 1;
            }
            labelDate.Text = TextDate[n];
            labelTime.Text = TextTime[n];
            labelLa.Text = TextLatitude[n];
            labelLo.Text = TextLongitude[n];
            labelAll.Text = TextSatelliteTotal[n];
            labelUsed.Text = TextEffectiveSatellite[n];
            //labelAltitude.Text = TextAltitude[n];
            labelCurr.Text = TextCurr[n];
            labelBegin.Text = TextBegin[n];
            labelAccess.Text = TextAcees[n];
            labelSpend.Text = TextSpend[n];
            labelSecond.Text = TextSecond[n];
        } 
        #endregion

        #region 获取GPS相应信息
        private void btnGet_Click(object sender, EventArgs e)
        {
            //gps.InitModule();
            btnStop.Enabled = true;

            btnGet.Enabled = false;

            btnStop.Focus();


            if (!gps.startReceive())
            {
                MessageBox.Show("get data failure, the port is not open.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                return;
            }
            isClosed = false;
            firstLocation = false;
            beginTime = System.DateTime.Now.Minute * 60 + DateTime.Now.Second;
            textBoxBeginTime.Text = Convert.ToString(DateTime.Now.TimeOfDay.ToString());

        } 
        #endregion

        #region 读取注册表信息,判断是不是英文操作系统
        /// <summary>
        /// Read registry information, judge whether English OS  读取注册表信息,判断是不是英文操作系统    
        /// </summary>
        /// <returns></returns>
        public static bool isEnglish()
        {
            try
            {
                var RegKey = Registry.CurrentUser.OpenSubKey(@"ControlPanel\Appearance");
                if ("Windows 标准" == RegKey.GetValue("Current").ToString())
                    return false;
                return true;
            }
            catch (Exception)
            {
                return true;
            }
        } 
        #endregion

        #region 停止GPS接收
        private void btnStop_Click(object sender, EventArgs e)
        {
            gps.stopReceive();

            isClosed = true;
            btnGet.Enabled = true;

            btnStop.Enabled = false;

            btnGet.Focus();

        } 
        #endregion

        #region GPS下电操作
        private void MainForm_Closed(object sender, EventArgs e)
        {
            gps.FreeModule();
        } 
        #endregion

        #region Interface language 界面语言

        private string[] TextDate = new [] { "日期:", "Date:" };
        private string[] TextTime = new [] { "UTC时间:", "UTC time:" };
        private string[] TextLongitude = new [] { "经度:", "Longitude:" };
        private string[] TextLatitude = new [] { "纬度", "Latitude:" };
        private string[] TextSatelliteTotal =new []{"可视卫星数量:","Satellite Total:"};
        private string[] TextEffectiveSatellite =new []{"可用卫星数量:","Effective number:"};
        private string[] TextAltitude = new [] { "海拔:", "Altitude:" };
        private string[] TextCurr = new [] { "当前时间等于UTC时间加上当地所属时区", "current time=UTC time +local time zone" };
        private string[] TextBegin = new [] { "开始时间:", "Begin time:" };
        private string[] TextAcees = new [] { "获取时间", "Access time:" };
        private string[] TextSpend = new [] { "有效定位时间", "Spending time:" };

        private string[] TextSecond = new string[] { "", "second" };
        #endregion

        #region 关闭窗口按钮
        private void buttonClosed_Click(object sender, EventArgs e)
        {
            if (btnStop.Enabled)
            {
                btnStop_Click(sender, e);
            }
            Close();
        } 
        #endregion
    }
View Code

 

代码下载地址:http://download.csdn.net/detail/lzf137927/6041519

posted on 2013-08-30 23:29  撩撩浮云  阅读(598)  评论(0编辑  收藏  举报