將地理定位整合至 Web 應用程式
如果您擁有一部智慧手機,可能已經得到指示你在哪裡到所需位置要轉,或在一些陌生的市鎮中查找附近的餐廳、 酒店或加油站使用的應用程式或內置功能。這項設施的技術術語是地理定位,同時還描述了設備,可以使用外部位置資料 (全球定位系統 [GPS],儲存格塔三角和 Wi-fi 資料),找出你哪裡都和提供這一資訊的應用程式或服務請求此資料的能力。您所在的位置通常是使用資料如緯度和經度、 標題、 速度、 方向和類似表示的。有了這些資訊,設備可以提供功能,如轉由轉向導航或附近發生在 2 上午開放 taco 卡車的位置
定位就是一些我們認為是理所當然,我們在移動設備上,但其使用快速蔓延本機的移動應用程式。越來越多的筆記型電腦和移動 Pc 現在裝有 GPS 晶片和網路的爆炸,一個可行的平臺,為移動應用程式開發已激起對在流覽器中,右地理定位服務的需求。
幸運的是對我們來說,W3C 早拿上這一趨勢,以及創建規範,描述了一種標準的方式使用 Web 應用程式中的從全球定位服務。規範,可以在 bit.ly/3r737c,並不是"正式"的 HTML5 的一部分,但因為我正在本系列中使用這個詞來描述一組打開 Web 技術 — — W3C 一樣 — — 不能錯過的機會給你簡要參觀這令人興奮的技術。
這個月的文章會給你的地理定位 API 概述和顯示您如何你可以開始使用它,以及如何處理地理定位請求期間發生的錯誤的最常見類型。我討論地理定位如何執行的桌上型電腦和移動流覽器,並總結與簡單介紹一下如何使用 polyfilling 圖書館與較舊的流覽器,為使用者提供基本地理定位的支援。
入門定位
W3C 規範,定位就是一個"… …提供與宿主設備相關的地理位置資訊的腳本的訪問的 API。"因為定位就是一個內置的 API,你要開始是支援它的流覽器。這次寫作、 互聯網資源管理器 9 (包括互聯網資源管理器 9 Windows Phone 7.5,代號為"芒果"上),以及當前版本的 Chrome、 火狐、 Safari 和 Opera,所有支援地理定位,所以該規範是不僅得到廣泛支援,但可能可用以相當大的一部分,您的使用者群。
地理定位 API 住在全球的"導航器"物件在 JavaScript (視窗。navigator.geolocation)。它提供了兩種方法可以使用定位服務: 一次性位置請求和重複的位置更新。對於一次性請求,使用 getCurrentPosition 方法,如下所示:
navigator.geolocation.getCurrentPosition(function(position) {
var coordinates = position.coords;
console.log("Your latitude: " + coordinates.latitude + " and longitude:
" + coordinates.longitude + " (Accuracy of:
" + coordinates.accuracy + " meters)");
}, errorHandler, { maximumAge: 100, timeout: 6000, enableHighAccuracy: true});
方法 getCurrentPosition 接受三個參數。 第一個是一個回呼函數,將觸發時流覽器成功確定當前設備的位置。 第二是火災發生錯誤的回呼函數 (詳細介紹,一會兒)。 第三是物件文本用於指定地理定位選項。 列出可用的選項和它們的預設值圖 1。
圖 1 地理定位選項
工具 | 描述 | 值 |
maximumAge | 緩存的報告的位置 (以毫秒為單位) 的時間長度。 | 0 (預設值),則無限 |
逾時 | 長時間 (以毫秒為單位),等待位置服務回應。 | 0 到無窮大 (預設值) |
enableHighAccuracy | 是否應該嘗試使用高精度定位服務 (例如,GPS),在流覽器支援的流覽器和設備。 | 為 true,false (預設值) |
成功處理常式提供了一個位置的物件包含有關當前使用者的位置的重要屬性。 地理定位規範定義了幾個屬性,但只有三都一致地執行不同的流覽器: 經度、 緯度和準確性。 其他屬性如標題、 方向和高度可用於流覽器來執行,並在將來可能是非常有用的移動流覽方案。
對於重複的位置請求,地理定位物件提供了兩個公共方法、 watchPosition 和 clearWatch ; watchPosition 可以使用像這樣:
var watchId = navigator.geolocation.watchPosition(function(position) {
var coordinates = position.coords;
console.log("Your latitude: " + coordinates.latitude + " and longitude:
" + coordinates.longitude + " (Accuracy of:
" + coordinates.accuracy + " meters)");
}, errorHandler, {maximumAge: 100, timeout: 6000, enableHighAccuracy: true});
WatchPostion 方法相同的參數為 getCurrentPosition,成功處理常式、 錯誤處理常式和選項。 關鍵的區別是,watchPosition 立即返回 ID,用於標識功能問題。 WatchPosition 是一個重複的函數,因為流覽器將調用它每次它檢測到更改的使用者的位置,直到關閉視窗或腳本顯式取消手錶。 若要取消 watchPosition,您只需 watchPosition,所返回的 ID 與調用 clearWatch,如下所示:
clearWatch(watchId);
讓我們看一個示例應用程式中使用 getCurrentPosition。 對於此示例,將繼續使用 WebMatrix (https://aka.ms/webm) 麵包我在我的上一篇文章中使用的示例。 該網站是一個使用者可以訂購烘烤和有其發送,但我想延長這一功能允許使用者指定一個附近的磚和砂漿位置,他們會在哪裡取順序的地方。 百思買做店內的電子取貨,我想做為繁華烘焙業。
我開始用我穿上了 HTML5 形式特色我 11 月文章修改的麵包房示例應用程式 (msdn.microsoft.com/magazine/hh547102),然後添加一項功能,允許使用者通過按一下表單上的連結選擇附近的麵包店取貨。 我使用 Bing 地圖 AJAX 控制項 (你可以下載它在 msdn.microsoft.com/library/gg427610),和代表回升和航運節表單的頁添加適當的引用,並創建 HTML 元素包含我的地圖後, 添加幾個 div。 每個 div 包含連結,使使用者可以在這兩個選項之間進行切換。 當按一下"興趣撿您的訂單,在我們的商店之一?"連結時,一個稱為 locateBakery.js 的 JavaScript 檔執行的功能。 該函數的主要方法顯示在圖 2。
圖 2 locateBakery.js
var mapDiv = document.getElementById("map");
var _map = new Microsoft.Maps.Map(mapDiv, { credentials: myCredentials });
function hideMap() {
$('#pickup').hide();
$('#map').hide();
$('#ship').show();
}
function displayError(msg) {
$('#error').val(msg);
}
function placeLocationOnMap(latitude, longitude) {
var location = new Microsoft.Maps.Location(latitude, longitude);
var bakeries = lookupNearbyBakeries(latitude, longitude);
_map.setView({ zoom: 12, center: location });
// Add a pushpin to the map representing the current location
var pin = new Microsoft.Maps.Pushpin(location);
_map.entities.push(pin);
for (var i=0;i<bakeries.length;i++) {
_map.entities.push(bakeries[i]);
}
}
function errorHandler(e) {
if (e === 1) { // PERMISSION_DENIED
hideMap();
} else if (e === 2) { //POSITION_UNAVAILABLE
displayError('Cannot find your location.
Make sure your network
connection is active and click the link to try again.');
hideMap();
} else if (e === 3) { //TIMEOUT
displayError('Cannot find your location.
Click the link to try again.');
hideMap();
}
}
function locate() {
navigator.geolocation.getCurrentPosition(function (position) {
var coordinates = position.coords;
placeLocationOnMap(coordinates.latitude, coordinates.longitude);
}, errorHandler);
}
查找函式呼叫 navigator.geolocation.getCurrentPosition 和提供的座標的地方如果該調用成功,LocationOnMap 函數,它可以放上一張地圖,連同附近的麵包店 (烘焙查找邏輯被省略的空間) 的清單的使用者的位置。這允許使用者查找附近的麵包店從中拿起她的命令。結果所示圖 3。
圖 3 使用地理定位與麵包中應用
當然,定位就是依賴于網路的服務,所以你做什麼地理定位失敗時?也許你也注意到 getCurrentPosition 和 watchPosition 函數指定稱為 errorHandler 的第二個參數。地理定位規範,對 getCurrentPosition 和 watchPosition 的調用應調用成功處理常式和錯誤處理常式。當調用地理定位服務,有三個可能的錯誤:
- 使用者可以拒絕跟蹤位置資訊的流覽器的請求
- 位置請求可能超時
- 超時時間到期之前,可能會失敗的位置請求
時將地理支援添加到您的應用程式中,您應務必處理所有三例。在源中可以找到這樣一個示例圖 2,凡我顯示一條錯誤消息和地理定位調用任何原因失敗時,重新顯示航運資訊部分。
地理定位是如何工作的
儘管地理定位規範是相當規範中定義的每個流覽器必須向開發人員提供的公共 API,它沒有什麼可說關於準確定位應如何落實在流覽器中。在一般的指導是每個流覽器應設法平衡精度的電力消耗的考慮,提供具有相當準確的座標集的應用程式的目標。
桌上型電腦或筆記型電腦的情況下,大多數流覽器都使用相同的機制,提供地理資料,儘管不同取決於他們的後臺服務。在互聯網流覽器 9 的情況下,到後來流覽器將收集您的 IP 位址或附近的 Wi-fi 熱點的清單,然後將該資訊傳遞給微軟位置服務 (相同服務的內置位置設施 Windows Phone 設備使用) 為一組的座標。谷歌流覽器和 Mozilla 的火狐流覽器均還使用 IP 和 Wi-fi 熱點資料,但依靠 Google 位置服務的實際的請求。查找使用者的位置定位服務方法犧牲一些準確性的速度 (和低功耗),和作為備份,或設備缺乏一個內置的 GPS 晶片時非常有用。
對於移動流覽器,情況是有點複雜,和同樣是到流覽器的問題。因為大多數現代智慧手機 GPS 晶片,流覽器可以自由地使用在嘗試移動作業系統所提供的 GPS 定位服務來獲取更準確的座標。Windows Phone 7.5 上互聯網流覽器 9、 Safari 對 iOS 的情況下,正是這些流覽器做些什麼。結果是,額外的電力消耗,通常是可接受的權衡,大多數移動的定位方案例如,轉由轉向導航中犧牲的更準確的位置。很重要,但是請注意,只需使用 gps 全球定位保證移動設備的流覽器並不是因為晶片可用。規範的葉子到流覽器上執行,因為流覽器或移動的底層 OS 服務可以選擇回退到儲存格塔三角或 IP 查找,或使用儲存格三角剖分與 GPS 相結合。(許多移動作業系統已經這麼做本機應用程式,如其內置的位置服務的一部分)
對於 Web 應用程式開發人員,這是好消息,因為這意味著與地理定位,您可以構建跨平臺的移動應用程式可以依賴位置設施本機設備,就像本機應用程式開發人員。
檢測和 Polyfilling 地理支援
當將地理支援添加到您的應用程式,您需要考慮你的方法將為這些使用者訪問您的網站使用不受支援的流覽器。我已經過討論一系列,您確定在給定的流覽器是否支援地理定位的方法是通過執行手動功能檢測 ("如果 (!!navigator.geolocation)") 或使用像 Modernizr 的庫 (modernizr.com)。對於沒有地理支援的使用者,有兩個課程的行動: 優雅地降低通過外部庫的應用程式或 polyfill 的支援。第一個選項,您可以降低了您的應用程式,顯示一個表單,讓你給它們的位置,然後使用 (通過服務呼叫) 以確定的緯度和經度的該使用者的使用者。我涵蓋這種情況下,在這一系列,我 9 月的文章,所以我就不重複了。這種情況下,並在線上代碼示例,您可以查看 (msdn.microsoft.com/magazine/hh394148)。
我將涵蓋這次有點更深入的第二個選項。正如我在前面的文章中,提到過當你發現自己在市場的跨流覽器 polyfill HTML5 技術時,第一個去的地方是的 GitHub,他們已經在其中發佈非常全面的清單的可用 polyfills Modernizr 的家 (bit.ly/eBMoLW)。在撰寫本文時,有三個地理定位 polyfills 列出。我選擇使用提供的保羅 · 愛爾蘭 (bit.ly/q20TOl) 純粹為例,這篇文章。
你可以從我 9 月的文章回顧 polyfill 是一個庫,它提供了基於腳本的執行情況,對於 HTML5 的功能,並經常堅持記錄的 API,該過程中的規範。後一點很關鍵,因為這意味著我這樣一個庫添加到我的應用程式,一旦可以繼續進行交互的功能,該功能的好像它完全支援在流覽器中,和我不必叉流我的程式和條件邏輯來支援較舊的流覽器。
像我剛做之前,本系列中,我用 Modernizr 幫我檢測地理定位功能的支援,如果沒有這種支援的存在,非同步載入的 geolocationShim.js 指令檔:
Modernizr.load({
test: Modernizr.geolocation,
nope: '../js/geolocationShim.js',
complete: function() {
locate();
}
});
如果支援地理定位,則執行將繼續查找功能。 如果不是,地理定位 polyfill 將載入並執行完成後,然後將繼續查找功能。 當我運行該示例在互聯網流覽器 9 這個邏輯時,一切正常工作,調用本機地理定位功能。
要測試什麼這看起來像在較舊的流覽器中,我可以開放的互聯網流覽器 9 F12 開發工具,並將流覽器模式切換為互聯網流覽器 8。 當我這樣做,並再次執行該頁面時,Modernizr 將檢測,地理定位不支援和載入我墊片。 然後,我 shim 的 getCurrentPosition 方法調用時,代碼圖 4 ,將會執行。
圖 4 方法實現通過 Shim 的 getCurrentPosition
geolocation.getCurrentPosition = function(callback){
if (cache) callback(cache);
$.getScript('//www.google.com/jsapi',function(){
cache = {
coords : {
"latitude": google.loader.ClientLocation.latitude,
"longitude": google.loader.ClientLocation.longitude
}
};
callback(cache);
});
};
因為此 polyfilling 庫堅守地理定位 API 規範,並提供 getCurrentPosition 和手錶位置的方法,我不需要我主要的 getLocation 函數中執行的任何額外的檢查或條件邏輯。
無論您選擇優雅會降低您的應用程式,允許使用者手動提供它們的位置,或嘗試執行 shim,它在採用地理定位在您的應用程式,同時確保您的網站繼續提供更完美的體驗,但不要使用現代流覽器的人有選項。
很多世界所叫的 HTML5 或打開的 Web 技術,是一套面向實際的應用程式開發使得在 Web 上的技術。 Web 和桌面之間的差距正在縮小,並定位就是很好的例子是今天可能與 Web 應用程式。 在本文中,我介紹地理定位規範的基本知識。 我展示了如何你可以開始,地理定位實施跨桌面和移動流覽器,以及如何在較舊的流覽器支援 polyfill 地理定位。 現在是時候要將這個令人興奮的功能添加到您的 Web 應用程式,所以,去今天做出一些令人敬畏的應用程式 !
如果您正在尋找在互聯網流覽器 9 地理支援的詳細資訊,簽出互聯網流覽器 9 指南對於開發人員來說,在 msdn.microsoft.com/ie/ff468705。 地理定位為其他跨流覽器 polyfills,為簽出的完整清單,在 bit.ly/qNE92g。
最後,所有的這篇文章的演示 — — 可線上 — — 建成使用 WebMatrix,從微軟免費的羽量級的 Web 開發工具。 您可以為自己在嘗試 WebMatrix aka.ms/webm。
Brandon Satrom 工程作為開發人員宣傳員微軟以外的奧斯丁。在他的博客 userinexperience.com ,可以發現在 Twitter 上 twitter.com/BrandonSatrom。
多虧了以下技術專家,檢討這篇文章: Jon Box, John Hrvatin, Clark Sell 和 Andy Zeigler