Windows Mobile: 將 GPS 和網站地圖用於能感知位置的應用程式

來源:互聯網
上載者:User
我們介紹了如何為 Windows Mobile 裝置構建位置感知工作清單應用程式,它使用 GPS 在適合的時間和地點向您發出任務提醒。

  本文樣本原始碼或素材下載

  本文使用了以下技術:

  Windows Mobile 6、MapPoint

  本文將介紹以下內容:

  MapPoint Web 服務

  緩衝任務和地圖

  擷取所需的鄰近點

  建立任務

  目錄

  使用 MapPoint 進行定位

  任務和 Pocket Outlook

  應用程式體繫結構

  擷取鄰近點

  新增工作

  一路前行

  最近我喬遷新居,一些要好的朋友花費了一整天的時間幫我裝箱拆箱、擺放物品和處理其他乏味卻又不得不做的搬遷工作。回老房子取最後一個箱子的路上,我差點忘記為他們準備晚餐。我在自己的 Windows Mobile 電話上設定了提醒,但它不能在我正好駕車經過最方便的外賣店時告訴我。

  我希望電話能在我到達合適的目標附近時通知我。如果能在合適的時間和地點得到提醒,我們就可以在勞累一天后大飽口福,而不是還要駕車在陌生的地段來回尋覓。

  Windows Mobile 提供了許多能夠協助裝置瞭解其環境的介面和功能——所處位置、是否有訊號、訊號量等。但如何才能將這些功能用於您的應用程式呢?在這些功能中,最突出和最有用的無疑是位置感知。您可以建立各種位置感知應用程式,從目的明確的衛星導航程式到本文將討論的更為複雜的工作清單。

  本文將主要介紹使用此功能時所涉及的問題,以及為開發有用應用程式需要編寫的其他代碼。在本文中,我將討論行動裝置 App程式開發環境和工具 + 生產力,並向您展示如何構建可以在適合的時間和地點提醒您注意的位置感知工作清單應用程式。

  使用 MapPoint 進行定位
我的位置感知工作清單應用程式(名為 wheretodo)需要執行幾個核心任務。它需要擷取電話地理位置的資訊。還需要儲存和監視任務。此外,應用程式還需要知道電話的當前位置附近有哪些合用的商店和服務,可以用於解決當前任務。最後,它需要給予電話提醒。應用程式介面 1 所示。

  圖 1 Wheretodo 應用程式

  應用程式首先需要地理資料。考慮本文的目的,我選擇使用Microsoft MapPoint Web 服務。此 Web 服務是 Live Search 地圖和 Virtual Earth 的基礎技術,可為歐洲和美國提供就近搜尋服務。提供的範例程式碼使用歐洲地圖資料設定;您需要根據工作地點來更改此設定。

  MapPoint 將 GPS 維度、經度以及特定儲存類型的搜尋代碼作為其參數。安裝在模擬器或智能手機上的 FakeGPS 工具 + 生產力可提供位置資訊。(有關此工具 + 生產力的詳細資料,請參閱“FakeGPS”側欄。)

  MapPoint 為 XML Web 服務提供了 SOAP API。Web 服務分為四種主要服務:公用服務、尋找服務、呈現服務和路線服務。此應用程式最受關注的服務是尋找服務,但如果您想為使用者或地圖指引方向,也可以使用其他服務來擴充功能。

  公用服務 (CommonServiceSoap) 包含尋找服務、路線服務、呈現服務通用的類、方法和屬性,或基本工具 + 生產力函數。

  您可以使用尋找服務 (FindServiceSoap) 找到地址、地理實體、維度和經度座標以及 MapPoint Web 服務資料的興趣點 (POI)。您還可以解析地址並針對指定的維度和經度返回位置資訊。

  您可以使用呈現服務 (RenderServiceSoap) 繪製路線圖和位置圖、放置圖釘、繪製多邊形地區、設定地圖大小和地圖視圖、在地圖上選點、擷取地圖上相關點和多邊形的位置資訊、平移和縮放呈現的地圖。
 路線服務 (RouteServiceSoap) 可產生路線、行駛方向、根據位置或路標計算出的路線表示(用於在地圖上呈現反白的路線)、設定路段和首選路線、產生路段和方向的地圖視圖。

  MSDN 上有一整套物件模型類別關係圖。MapPoint 根據地理地區或所需的資訊類型將用於尋找服務、路線服務和呈現服務的資料儲存在多個不同的資料來源中。您在 MSDN 雜誌上能夠找到全部有關使用服務的 MapPoint 技術文章。

  任務和 Pocket Outlook

  Pocket Outlook 物件模型 (POOM) 允許您將菜單和功能添加至 Windows Mobile 的“任務”和“連絡人”應用程式中,並允許處理其關聯項和資料。位置感知應用程式有三個主要介面:Iappointment、Itask 和 Icontact。

  IAppointment 代表 Calendar 檔案夾中的一個約會。一個約會對象可以代表一個會議、一次約會,也可以代表定期約會或會議。

  ITask 代表一項在指定時間範圍內要完成的已指派、已委派或自派任務。任務項包含在 Tasks 檔案夾內。

  Icontact 代表 Contacts 檔案夾內的連絡人。使用其方法可以儲存、刪除、複製或顯示連絡人。IPOutlookItemCollection 介面可用於添加新連絡人或檢索現有連絡人。

  應用程式範例將使用 Itask。(從功能上來講,可以使用 Iappointmen,但該介面不太適合於應用程式的直接需要。)POOM 類似於案頭 Outlook 物件模型,您可以在 MSDN 上的“Pocket Outlook 物件模型與 Outlook 物件模型之間的差異”一文中瞭解更多相關資訊。

  應用程式體繫結構

  位置感知應用程式由兩個函數鏈組成。第一個是監視當前任務和問題的系統, 2 所示。任務儲存在 SQL ServerCompact 資料庫表中。此外,還有一組輔助資料存放區在另一個名為 geocache 的表中。使用單獨的表可限制所需的串連數,我將在本文的稍後部分中加以介紹。

  圖 2 監視位置感知任務並發出警報

  Microsoft MapPoint Web 服務可提供鄰近點的資訊。世界不同地區的 MapPoint Web 服務中有不同的資料來源,資料來源的功能也各不相同。應用程式範例使用的資料來源是 NavTech.EU。收集完此類資訊後,即可執行一些距離計算並發出警報(如適用)。

  第二個是事件鏈(請參見圖 3),可通過 POOM 將任務添加至 Windows Mobile 裝置上的工作清單中。該架構還允許訪問日曆和 SMS 函數。

  圖 3 用於向 Wheretodo 應用程式新增工作的系統流

  “Tasks and Cache”(任務和緩衝)代表事件監視和警報鏈的第一部分。工作管理員只需從 POOM 獲得一個工作清單。它還能管理 geocache,解決對串連有局限性的裝置使用 Web 裝置時產生的問題。裝置串連的層級分為永久性串連、偶爾串連或根本無串連。

  為適應多種串連情況,您需要一個合適的 Web 服務資料緩衝策略以及一個能夠瞭解如何充分利用串連的簡單系統。儘管可以輕鬆想象出非常複雜的情形,但在本文中制定的是簡單的半徑緩衝策略。例如,向 MapPoint Web 服務發出一個查詢,以現在的位置為中心、在給定半徑(比如說 80 公裡 (km))內搜尋所有中餐外賣店。在您朝任一方向走了 40 km 後,發出一條新的搜尋。它遵循的原則是:向 Web 服務發出每一條查詢的成本都很高。
 它還假設您離開任務輸入焦點的距離不太可能超出 40 km。由於用來控制緩衝操作的距離可能因人和省/地區而異,因此它被設計為由使用者輸入。

  查詢已運行位置的日誌儲存在 geocachelog 資料庫中,在執行任何其他查詢之前會檢查該日誌,以防從 Web 服務請求重複的資訊。它還為使用大量資訊預填充系統提供了機會。

  FakeGPS

  FakeGPS 應用程式

  Windows Mobile 6 SDK 包含名為 FakeGPS 的工具 + 生產力,此工具允許您使用類比的 GPS 資料測試應用程式。有關使用 FakeGPS 執行安裝和測試的資訊,請參閱 MSDN 庫文章“使用 FakeGPS 工具 + 生產力”。

  FakeGPS 讀取一組預先記錄的 GPS 指令。GPS 資料可以使用原始 GPS 資料記錄器從真實的 GPS 裝置獲得。FakeGPS 裝置讀取產生的檔案並重新運行該檔案,類比已變更位元置資料,供測試之用。例如,我記錄了一次倫敦之行來為我的應用程式收集資料,然後通過 FakeGPS 重新規划了旅程。

  擷取鄰近點

  下一個組件定義如何填充 geocache。當應用程式需要尋找某個位置時,會調用 GetNearByPOI 函數(請參見圖 4)。代碼會查詢 MapPoint Web 服務。請注意,此處顯示的代碼為清晰起見做了簡化處理,與代碼下載中的有所不同。

圖 4 擷取所需的鄰近點

private void GetNearByPOI(
 string KeyWord, LatLong CurrentPosition) {
 FindServiceSoap findService = new FindServiceSoap();
 FindNearbySpecification findNearBySpec = new FindNearbySpecification();
 findService.Credentials =
  new System.Net.NetworkCredential(myUserName, myPassword);
 findService.PreAuthenticate = true;
 findNearBySpec.Distance = Convert.ToDouble(inputdistance.Text);
 findNearBySpec.LatLong = new LatLong();
 findNearBySpec.LatLong.Latitude = CurrentPosition.Latitude;
 findNearBySpec.LatLong.Longitude = CurrentPosition.Longitude;
 findNearBySpec.Filter = new FindFilter();
 //findNearBySpec.Filter.EntityTypeName = KeyWord;
 findNearBySpec.Filter.EntityTypeName = "FoodType3"; // SIC CODE
 findNearBySpec.DataSourceName = "NavTech.EU";
 FindResults foundResults;
 foundResults = findService.FindNearby(findNearBySpec);
 string connectionString;
 string fileName = System.IO.Path.GetDirectoryName(
  System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) +
  "wheretodo.sdf";
 string password = "sa";
 connectionString = string.Format("DataSource="{0}"; Password='{1}'",
  fileName, password);
 SqlCeConnection cn = new SqlCeConnection(connectionString);
 cn.Open();
 SqlCeCommand cmd;
 //Loop Round and add it to the geocache
 foreach (FindResult fr in foundResults.Results) {
  //This needs to include LongLat in geocache
  string sql =
   "insert into geocache2 (POI_Name, POI_Address, POI_Tel, POI_Web, " +
   "POI_POST_ZIP, POI_Lat, POI_Long, POI_KeyWord) " +
   "values (@Name, @Address, @Tel, @Web, @POST_ZIP, '" +
   fr.FoundLocation.LatLong.Latitude.ToString() +
   "', '" + fr.FoundLocation.LatLong.Longitude.ToString() + "', '" +
   KeyWord.ToString() + "')";
  cmd = new SqlCeCommand(sql, cn);
  cmd.Parameters.Add("@Name", SqlDbType.NVarChar, 255, "Name").Value =
   fr.FoundLocation.Entity.Properties[0].Value.ToString();
  cmd.Parameters.Add("@Address", SqlDbType.NVarChar, 255, "Address").Value =
   fr.FoundLocation.Entity.Properties[1].Value.ToString() +
   fr.FoundLocation.Entity.Properties[2].Value.ToString();
  cmd.Parameters.Add("@Tel", SqlDbType.NVarChar, 255, "Tel").Value =
   fr.FoundLocation.Entity.Properties[9].Value.ToString();
  cmd.Parameters.Add("@Web", SqlDbType.NVarChar, 255, "Web").Value =
   "http://m.live.com";
  cmd.Parameters.Add("@POST_ZIP", SqlDbType.NVarChar, 255, "POST_ZIP").Value =
   fr.FoundLocation.Entity.Properties[7].Value.ToString();
  cmd.ExecuteNonQuery();
  //Update geocachelog
  sql = "insert into GeoCodeLog (Keyword, Lat, Long ) values ('" + KeyWord +
   "', '" + fr.FoundLocation.LatLong.Latitude.ToString() + "', '" +
   fr.FoundLocation.LatLong.Longitude.ToString() + "' )";
  cmd = new SqlCeCommand(sql, cn);
  cmd.ExecuteNonQuery();
 }
}

  請看調用了 CurrentPosition.Latitude 和 CurrentPosition.Longitude 的程式碼片段。它基本上衍生自 GPS Intermediate Driver,一個介於應用程式和 GPS 硬體裝置驅動程式之間的軟體層。該抽象層允許一次性編寫應用程式並使之能與多個 GPS 裝置結合使用。GPS Intermediate Driver API 通過機器碼庫公開。您可以通過使用 Windows Mobile 6 Professional SDK 附帶的樣本獲得從Managed 程式碼訪問該庫的許可權,(請參閱“通過Managed 程式碼使用 GPS Intermediate Driver)”。
 現在有了與任務相關的當前位置和附近的 POI,在此它們由 Navtech.EU 資料來源中使用的標準工業分類碼 (SIC) 標識,您需要準確地確定出這些點離您當前所在位置的距離。我使用從 Web 服務和 GPS(本例中為 FakeGPS)返回的經度和維度值;圖 5 顯示了如何將這些值轉換成距離。

圖 5 計算距離

private double GetLatLongTuppleDistance(
 double Lat1, double Long1, double Lat2, double Long2) {
 //Convert Degress to Radians for Calculations
 double Lat1r = ConvertDegreesToRadians(Lat1);
 double Lat2r = ConvertDegreesToRadians(Lat2);
 double Long1r = ConvertDegreesToRadians(Long1);
 double Long2r = ConvertDegreesToRadians(Long2);
 // Spherical law of cosines formula—ignores the effect of hills
 double R = 6371; // Earth's radius (km)
 double d = Math.Acos(Math.Sin(Lat1r) * Math.Sin(Lat2r) +
  Math.Cos(Lat1r) * Math.Cos(Lat2r) *
  Math.Cos(Long2r—Long1r)) * R;
 //Returns distances in km
 return d;
}

  基於球面餘弦定律(它可推論出勾股定理)的球面三角函數提供了可將維度和經度轉換成距離(單位 km)的函數。要計算您與所尋找位置之間的距離,其中涉及很多複雜的因素,而上述函數明顯對這些因素做出了相當程度的假設。因為地球不是一個標準的球體,因此使用這些公式時會存在誤差。陸地上的 1 英裡 = 1.609344 公裡,而海上的 1 海裡 = 1.852 公裡。
 該事件鏈的最後一部分是在距當前位置一定距離內找到任務的解決方案時向使用者發出警報。由於此距離視交通方式(駕車、步行、騎單車等)而定,因此留給使用者自行輸入。

  新增工作

  當然,使用者必須先向行動裝置新增工作,應用程式才能尋找位置。POOM 鏡像 Outlook 物件模型,但為適應行動裝置的實際情況,縮小了其功能範圍。

  使用 POOM 可輕鬆修改和顯示約會、任務和連絡人項,並能操控包含這些內容的檔案夾。建立任務項的代碼如下:

OutlookSession outlooksession = new OutlookSession();
Task NewTask = new Task();
NewTask.Body = textBox2.Text.ToString();
string MyString = dateTimePicker2.Value.ToShortDateString() + " " + dateTimePicker1.Text.ToString();
DateTime MyDateTime = new DateTime();
MyDateTime = DateTime.ParseExact(MyString, "M/d/yy h:mm:ss tt", null);
NewTask.DueDate = MyDateTime.ToUniversalTime();
NewTask.Subject = textBox1.Text.ToString();
outlooksession.Tasks.Items.Add(NewTask);

  可以通過更改各種參數來設定結束日期和任務本文,然後將其添加至 POOM。

  該組件是用於提供 wheretodo 應用程式功能的兩個組件鏈的後一個。系統 UI 本身非常簡單,利用它可設定所有相關資訊並確定應用程式將找到的 SIC 代碼。整個應用程式封裝到一個無限迴圈中,它的作用就是說明如何使用位置感知應用程式。您可以非常輕鬆地將它作為背景服務添加至行動裝置,使其更高效簡潔地整合到 Windows Mobile 6 或 Windows Mobile 5 環境中。

  移動資料資源

  資料點:從行動裝置 App程式訪問資料

 

  一路前行

  您已看到了一種位置感知裝置和能輕鬆開發這些應用程式的工具。可針對 RFID 輕鬆擴充位置感知工作清單的這一基本概念。

  此代碼的改進可以應用於任何位置感知應用程式。以上內容可歸結為:位置感知如何與在大多數行動電話上啟動並執行其他上下文感知服務緊密地聯絡在一起。除了您的位置,任務對您還想嘗試的其他事情一無所知。您可為任務設定時間和位置,以便在某個特定時間(比如說,下班後駕車回家)接近某個位置時可以觸發它們。更棒的是,任務提醒會知道您 10 分鐘後有一個會議,還知道即便您在開會的路上會路過郵局,也沒有足夠的時間去買郵票。

http://tech.ddvip.com/2009-02/1233823276107398.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.