1、須知git
1.手持機(PDA)必須有GPS模塊,才能經過代碼使用串口通訊獲取GPS相關信息windows
2.要清楚本身手持機(PDA)固定的GPS通訊串口號,如咱們公司的手持機獲取GPS信息的串口爲COM4api
3.測試手持機(PDA)是否獲取到GPS相關信息,要到室外才能測試出來。安全
2、製做步驟app
(1)新建好win ce項目異步
(2)封裝類ide
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 }
2.CLR_Regex類ui
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; } }
3.GPS類this
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; } }
(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 }