專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

學(xué)以致用之GPS信息處理軟件

作者:黑馬   來(lái)源:黑馬程序員的空間   點(diǎn)擊數(shù):  更新時(shí)間:2014年05月23日   【字體:

最近學(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)題了。
關(guān)閉窗口

相關(guān)文章