您的位置:首页 > 其它

在PDA中获取GPS信息。

2009-08-31 09:46 246 查看
http://www.cnblogs.com/anhlyiling/archive/2008/12/04/1347623.html
在PDA中获取GPS信息。

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





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

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





Code

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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: