WM--GPS開發

作者: AppleSeeker  來源: 博客園  發布時間: 2009-05-31 10:04  閱讀: 5133 次  推薦: 0   原文鏈接   [收藏]  
摘要:目前在一些移動設備中,都提供GPS功能,設備中都需要一個接收器,用來接收GPS信號。(類似于GPRS工作方式)。GPS一旦啟動后,會自動連接衛星,接收信號,通過算法計算出位置等信息,然后以NMEA data的格式輸出。

  前幾天,有朋友托我給他寫個GPS程序,就取經緯度坐標,以及將之轉換成高斯直角坐標。花了一些時間,給他做了個小程序。

  后來總結時,想起,很多網上朋友都會問及關于GPS開發的一些事。我這里先將我的程序解釋下,然后再總結下,相關經驗及個人看法。

  目前在一些移動設備中,都提供GPS功能,設備中都需要一個接收器,用來接收GPS信號。(類似于GPRS工作方式)。GPS一旦啟動后,會自動連接衛星,接收信號,通過算法計算出位置等信息,然后以NMEA data的格式輸出。GPS receiver就是接收衛星信號轉換成NMEA data的設備。

  開發GPS有3種選擇:
  1、直接使用串口連接GPS接收器
  2、GPS Intermediate Driver
  3、使用第三方類庫(目前opennetcf提供相應類庫)

  目前,WM5.0以上系統,都內置了GPS Intermediate Driver。通過它,我們能夠很方便的取道GPS數據。

  關于GPS方面的文章可以參考:
  1、30 Days of .NET [Windows Mobile Applications] - Day 03: GPS Compass(GPS指南針)
  2.NET Compact Framework下的GPS NMEA data數據分析

  雖然GPS Intermediate Driver提供了我們非常快捷的取得GPS信息,但同時也有一定的弊端。

  那下面我講介紹我如何在該項目中使用GPS的。

  我使用GPS Intermediate Driver,它能夠快速開發,MS也提供了很強大的例子來方便我們使用。
在微軟的WM SDK安裝目錄下有GPS工程。(Windows Mobile 6 SDK\Samples\PocketPC\CS\GPS)

  該Demo中
  GPS.cs:封裝了GPS的操作類,比如Open(),Close(),Connect()。可以很快捷的使用。
  GpsDeviceState.cs:用于取得目前GPS設備的狀態信息。
  GpsPosition.cs:每次GPS數據取得后,都會放入該類。
  LocationChangedEventArgs.cs:一旦位置改變,即可將新的GPSPosition取得到。

public void Open()
{
    
if (!Opened)
    {
         
// create handles for GPS events
         newLocationHandle = CreateEvent(IntPtr.Zero, 00null);
         deviceStateChangedHandle 
= CreateEvent(IntPtr.Zero, 00null);
         stopHandle 
= CreateEvent(IntPtr.Zero, 00null);

         gpsHandle 
= GPSOpenDevice(newLocationHandle, deviceStateChangedHan
dle, 
null0);

         
// if events were hooked up before the device was opened, we'll need
         
// to create the gps event thread.
         if (locationChanged != null || deviceStateChanged != null)
         {
             CreateGpsEventThread();
         }
    }
}

  通過調用CreateEvent,創建handles,然后調用GPSOpenDevice API,將handle傳入,取到gps設備的handle
得到handle后,再創建一個線程來監聽GPS數據及設備狀態。通過調用CreateGpsEventThread方法。

private void CreateGpsEventThread()
{
    
// we only want to create the thread if we don't have one created already 
    
// and we have opened the gps device
    if (gpsEventThread == null && gpsHandle != IntPtr.Zero)
    {
        
// Create and start thread to listen for GPS events
        gpsEventThread = new System.Threading.Thread(new System.Threading.
ThreadStart(WaitForGpsEvents));
        gpsEventThread.Start();
    }
}

  在WaitForGpsEvents方法中,就while不聽的監聽。
  當deviceStateChanged,就調用deviceStateChanged事件,然后取得當前設備狀態。
  當locationChanged,就調用locationChanged事件,取得當前坐標。
  這樣一個基本的GPS數據取得流程就算完成了。

以下為調用API的函數聲明。

Code

  有時候,我們往往不需要簡單的GPS的經緯度,我們或許需要更多的數據。這時候就需要轉換。
比如,在我這個應用中,需要取得對應的高斯直角坐標。

  當然我們需要通過一系列的數學運算得到。
  我們需要設置一個重要子午線的坐標,然后根據該坐標計算得到。

public static void ConvertBLToXY(double bl1, double bl2, ref double x, ref double y)
{
    
if (enableBLToXY)
    {
        
try
        {
            
//a2 輸入中央子午線,以度.分形式輸入,如115度30分則輸入115.30; 起算數據l0 
            
//f2 以度小數形式輸入經度值, l 
            
//e2 以度小數形式輸入緯度值,b 
            
//s2 計算結果,橫坐標y 
            
//t2 計算結果,縱坐標x 
            
//投影帶號計算 n=[l/6]+1 如:測得經度103.xxxx,故n=[103.x/6]+1=17+1=18 
            
//中央經線經度 l0 = n*6-3 = [l/6]*6+3 
            double a2, f2, e2, s2, t2;
            a2 
= centerLine;
            f2 
= bl1;
            e2 
= bl2;
            e2 
= x;
            t2 
= y;
            
double b2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2;

            b2 
= (int)(a2) + ((int)(a2 * 100- (int)(a2) * 100/ 60 + (a2 * 10000 -
(int)(a2 * 100* 100/ 3600;
            
//把l0化成度(a2) 
            
//g2 = f2 - b2 ' l -l0 
            
//h2 = g2 / 57.2957795130823 '化作弧度
            
//將經差的單位化為弧度
            h2 = (f2 - b2) / 57.2957795130823;
            i2 
= Math.Tan(e2 / 57.2957795130823);
            j2 
= Math.Cos(e2 / 57.2957795130823);
            k2 
= 0.006738525415 * j2 * j2;
            l2 
= i2 * i2;
            m2 
= 1 + k2;
            n2 
= 6399698.9018 / Math.Sqrt(m2);
            o2 
= h2 * h2 * j2 * j2;
            p2 
= i2 * j2;
            q2 
= p2 * p2;
            r2 
= (32005.78006 + q2 * (133.92133 + q2 * 0.7031));
            s2 
= ((((l2 - 18* l2 - (58 * l2 - 14* k2 + 5* o2 / 20 + m2 - l2) *
o2 / 6 + 1* n2 * (h2 * j2);
            
//在計算的基礎上加上了“帶號”(18)和“東移”(500km) 
            s2 = s2 + 18500000;
            
//計算結果,橫坐標y 
            t2 = 6367558.49686 * e2 / 57.29577951308 - p2 * j2 * r2 + ((((l2 - 58)
 
* l2 + 61* o2 / 30 + (4 * k2 + 5* m2 - l2) * o2 / 12 + 1* n2 * i2 * o2 / 2;
            
//計算結果,縱坐標x 

            x = s2;
            y 
= t2;
        }
        
catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            x 
= 0;
            y 
= 0;
        }
    }
}

 

  以上就是我的GPS應用程序的主體代碼介紹。希望對大家有用。

  可能根據每個項目的實際狀況不一致,我的個人意見如下:
  1、項目中GPS部分取得的數據簡單的話,可以直接采用GPS Intermediate Driver
  2、最好自己封裝下直接使用串口連接GPS接收器的功能。
  3、地圖定位,可以借助Google。
  4、注意釋放內存,因為多數都需要調用非托管
  5、一定要用線程處理。

  最后,附上應用程序CAB包。很多人寫打包程序覺得有時候有困難,其實,一個簡單的打包CAB程序相對很簡單。現在很多WM設備,基本穩妥地還是用基于.net cf2.0為主。所以大家工程發布最好還是以.net cf2.0吧,因為有些設備安裝.net cf3.5不穩定導致。

0
0
 
標簽:Mobile
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()