WM--GPS開發

Nikey001發表於2009-06-09

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

開發GPS有3種選擇:
1。直接使用串列埠連線GPS接收器
2。GPS Intermediate Driver
2。使用第三方類庫(目前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取得到。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtpublic 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, deviceStateChangedHandle, 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方法。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtprivate 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的函式宣告。

WM--GPS開發Code

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

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

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtif (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;
        t2 
= x;
        s2 
= 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不穩定導致。

程式下載:GPSSystem.rar
執行環境:VS2008
+ WM6.0 + .net cf2.0

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21255398/viewspace-605616/,如需轉載,請註明出處,否則將追究法律責任。

相關文章