最近學(xué)了很多,也是時(shí)候自己做點(diǎn)東西來(lái)復(fù)習(xí)并且鞏固下之前的知識(shí)了。學(xué)以致用最重要。最近寫了個(gè)小軟件,用來(lái)處理處理從窗口發(fā)送過(guò)來(lái)的GPS信息。GPS是與STM32相連接任何STM32把GPS信息發(fā)到電腦的串口上。任何我寫了個(gè)C#的程序通過(guò)串口接收到信息,并對(duì)信息進(jìn)行處理得到我們需要的經(jīng)緯度,并通過(guò)經(jīng)緯度查找到具體的地址。可以表達(dá)的不太清晰,想來(lái)幾張圖來(lái)個(gè)大家看看具體的效果。任何在講講具體的程序。
這是通過(guò)別的串口接收軟件接收到的串口上的信息。
這是初始化狀態(tài)下的軟件界面

這是按了按鈕之后的。由于經(jīng)緯度查地址需要時(shí)間,所以地址不能馬上的顯示出來(lái)。

現(xiàn)在地址查詢結(jié)束了。
然后我來(lái)介紹下程序。
首先需要先寫程序來(lái)接收串口發(fā)過(guò)來(lái)的數(shù)據(jù)。
SerialPort sp = new SerialPort();首先我們可以實(shí)例化一個(gè)串口對(duì)象。
sp.PortName = "COM8"; //端口
sp.BaudRate = 38400; //波特率
sp.Open(); //打開串口
配置完端口和波特率后就可以打開串口來(lái)接收數(shù)據(jù)了
string message = sp.ReadLine();
message = message.Substring(0, message.Length - sp.NewLine.Length);
用這兩句可以獲得串口傳來(lái)的數(shù)據(jù)并且保持在message字符串中。
我們剛才已經(jīng)看過(guò)了傳過(guò)來(lái)的字符串是什么格式的。它采用的是NMEA0183 協(xié)議,如果想具體了解它的協(xié)議可以去百度下,這里就不再贅述了。
由于我們只是需要經(jīng)緯度,所以只需要對(duì)$GPGGA的數(shù)據(jù)進(jìn)行處理。
經(jīng)過(guò)觀察我們可以使用,做為分割符來(lái)使用Split方法進(jìn)行分割字符串
然后轉(zhuǎn)換成我們需要的信息。
這里附上程序:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
SerialPort sp = new SerialPort();
//private void button1_Click(object sender, EventArgs e)
//{
// //sp.Close();
// sp.PortName = "COM8";
// sp.BaudRate = 38400;
// sp.Open();
//}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
sp.PortName = "COM8"; //端口
sp.BaudRate = 38400; //波特率
sp.Open(); //打開串口
bool stop = false; //標(biāo)志位
string longitude = "0";//經(jīng)度
string latitude = "0";//緯度
while (!stop)
{
try
{
string message = sp.ReadLine();
message = message.Substring(0, message.Length - sp.NewLine.Length);
if (message.StartsWith("$GPGGA"))
{
//模擬定位
//message = "$GPGGA,012440.00,2232.458380,N,11356.91024,E,1,05,2.7,40.2,M,0.5,M,,*6F";
//message = "$GPGGA,012440.00,2232.301654,N,11402.058366,E,1,05,2.7,40.2,M,0.5,M,,*6F";
char[] separator = { ',' };
string[] data = message.Split(separator);
if (data[6].Equals("1"))
{
string s;
s = data[2];
int idx = s.IndexOf(".");
string d1 = s.Substring(0, idx - 2);
string d2 = s.Substring(idx - 2);
double degree = Double.Parse(d1) + Double.Parse(d2) / 60;
latitude = Convert.ToString(Convert.ToDouble(s) / 100);//緯度
string j;
j = data[4];
int idxj = j.IndexOf(".");
string d1j = j.Substring(0, idxj - 2);
string d2j = j.Substring(idxj - 2);
double degreej = Double.Parse(d1j) + Double.Parse(d2j) / 60;
longitude = Convert.ToString(Convert.ToDouble(j)/100);//經(jīng)度
textBox1.Text = longitude;
textBox2.Text = latitude;
stop = true;
}
else
{
sp.Close();
sp.PortName = "COM8";
sp.BaudRate = 38400;
sp.Open();
// button2_Click(button2,EventArgs e);
}
}
else if (message.StartsWith("$GPGGA"))
{
char[] separator = { ',' };
string[] data = message.Split(separator);
}
}
catch (TimeoutException) { }
}
sp.Close();
// sp = null;
//textBox4.Text = adrss();2
MessageBox.Show("GPS已停止,請(qǐng)等待地址信息的查詢!");
textBox4.Text = GPSadrss.adrss(latitude, longitude);
}
在獲得了經(jīng)緯度之后我們需要用經(jīng)緯度來(lái)查詢地址。我在這里定義了一個(gè)GPSadrss的類,并且在里面定義了一個(gè)static類型的adrss方法。這樣我們不需要實(shí)例化GPSadrss對(duì)象也可以調(diào)用adrss方法了。
adrss里我們使用來(lái)谷歌的接口來(lái)查詢地址。
class GPSadrss
{
public static string adrss(string latitude, string longitude)
{
WebClient client = new WebClient();//webclient客戶端對(duì)象
//string url = "http://maps.google.com/maps/api/geocode/xml?latlng=29.82121,121.55973&language=zh-CN&sensor=false";//請(qǐng)求地址
string url = "http://maps.google.com/maps/api/geocode/xml?latlng="+latitude+","+longitude
+"&language=zh-CN&sensor=false";//請(qǐng)求地址
client.Encoding = Encoding.UTF8;//編碼格式
string responseTest = client.DownloadString(url);//下載xml響應(yīng)數(shù)據(jù)
XmlDocument doc = new XmlDocument();//創(chuàng)建XML文檔對(duì)象
if (!string.IsNullOrEmpty(responseTest))
{
doc.LoadXml(responseTest);//加載xml字符串
//獲取狀態(tài)信息
string xpath = @"GeocodeResponse/status";
XmlNode node = doc.SelectSingleNode(xpath);
string status = node.InnerText.ToString();
if (status == "OK")
{
//獲取地址信息
xpath = @"GeocodeResponse/result/formatted_address";
node = doc.SelectSingleNode(xpath);
string address = node.InnerText.ToString();
string[]ad= address.Split();
return ad[0];
}
return "false";
}
return "false";
}
這是GPSadrss里面的代碼。這里用了webclient客戶端對(duì)象來(lái)訪問(wèn)谷歌的端口。
然后說(shuō)下界面的設(shè)計(jì),由于經(jīng)緯度和地址,我們都希望不能由用戶直接輸入使用我們需要把3個(gè)文本框的ReadOnly屬性設(shè)計(jì)為ture;

由于我們也不希望用戶任意的拉伸窗口所以我把邊框樣式設(shè)置成了Fixed


并且把窗口的最大化按鈕去掉了
現(xiàn)在的程序還很粗糙,離我的目標(biāo)還有些差距。比如這個(gè)版本的程序在點(diǎn)擊了按鈕只后等待查詢地址的時(shí)候程序假死在那里了,直到查到了地址我們才能繼續(xù)控制它,這里我覺得是因?yàn)樵诓榈刂返臅r(shí)候程序一直在等待網(wǎng)頁(yè)上傳來(lái)的數(shù)據(jù)。所以程序假死。下個(gè)版本的目標(biāo)是用線程來(lái)查詢地址,就可以解決這個(gè)問(wèn)題了。