地理位置(Geolocation)是 HTML5 的重要特性之一,提供了肯定用戶位置的功能,藉助這個特性可以開發基於位置信息的應用。今天這篇文章向你們介紹一下 HTML5 地理位置定位的基本原理及各個瀏覽器的數據精度狀況。git
在 訪問位置信息前,瀏覽器都會詢問用戶是否共享其位置信息,以 Chrome 瀏覽器爲例,若是您容許 Chrome 瀏覽器與網站共享您的位置,Chrome 瀏覽器會向 Google 位置服務發送本地網絡信息,估計您所在的位置。而後,瀏覽器會與請求使用您位置的網站共享您的位置。chrome
HTML5 Geolocation API 使用很是簡單,基本調用方式以下:json
if (navigator.geolocation) { 瀏覽器
navigator.geolocation.getCurrentPosition(locationSuccess, locationError,{ 緩存
// 指示瀏覽器獲取高精度的位置,默認爲false 服務器
enableHighAcuracy: true, 網絡
// 指定獲取地理位置的超時時間,默認不限時,單位爲毫秒
timeout: 5000,
// 最長有效期,在重複獲取地理位置時,此參數指定多久再次獲取位置。
maximumAge: 3000
});
}else{
alert("Your browser does not support Geolocation!");
}
locationError爲獲取位置信息失敗的回調函數,能夠根據錯誤類型提示信息:
locationError: function(error){
switch(error.code) {
case error.TIMEOUT:
showError("A timeout occured! Please try again!");
break;
case error.POSITION_UNAVAILABLE:
showError('We can\'t detect your location. Sorry!');
break;
case error.PERMISSION_DENIED:
showError('Please allow geolocation access for this to work.');
break;
case error.UNKNOWN_ERROR:
showError('An unknown error occured!');
break;
}
}
locationSuccess爲獲取位置信息成功的回調函數,返回的數據中包含經緯度等信息,結合Google Map API 便可在地圖中顯示當前用戶的位置信息,以下:
locationSuccess: function(position){
var coords = position.coords;
var latlng = new google.maps.LatLng(
// 維度
coords.latitude,
// 精度
coords.longitude
);
var myOptions = {
// 地圖放大倍數
zoom: 12,
// 地圖中心設爲指定座標點
center: latlng,
// 地圖類型
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// 建立地圖並輸出到頁面
var myMap = new google.maps.Map(
document.getElementById("map"),myOptions
);
// 建立標記
var marker = new google.maps.Marker({
// 標註指定的經緯度座標點
position: latlng,
// 指定用於標註的地圖
map: myMap
});
//建立標註窗口
var infowindow = new google.maps.InfoWindow({
content:"您在這裏<br/>緯度:"+
coords.latitude+
"<br/>經度:"+coords.longitude
});
//打開標註窗口
infowindow.open(myMap,marker);
}
通過測試,Chrome/Firefox/Safari/Opera四個瀏覽器獲取到的位置信息都是一摸同樣的,估計都是用的同一個位置服務,數據以下:
位置服務用於估計您所在位置的本地網絡信息包括:有關可見 WiFi 接入點的信息(包括信號強度)、有關您本地路由器的信息、您計算機的 IP 地址。位置服務的準確度和覆蓋範圍因位置不一樣而異。
總的來講,在PC的瀏覽器中 HTML5 的地理位置功能獲取的位置精度不夠高,若是藉助這個 HTML5 特性作一個城市天氣預報是綽綽有餘,但若是是作一個地圖應用,那偏差仍是太大了。不過,若是是移動設備上的 HTML5 應用,能夠經過設置 enableHighAcuracy 參數爲 true,調用設備的 GPS 定位來獲取高精度的地理位置信息。
原文:http://www.cnblogs.com/lhb25/archive/2012/07/10/html5-geolocation-api-demo.html
navigator.geolocation.getCurrentPosition(on_success, on_error, options);
getCurrentPosition
包含三個參數,前兩個爲函數名,第三個爲一個對象。其中只有第一個是必須的。當你執行上面的 JavaScript 語句後,瀏覽器一般會彈出一個提示,詢問用戶是否容許網站跟蹤位置信息;同時getCurrentPosition
函數會當即返回。若是用戶選擇了容許,則會執行上述on_success
函數,這時你才真正獲得位置信息(這就是這件事情爲何要分兩步的緣由——用戶須要必定時間才能對請求做出反應,同時地理位置信息可能須要必定時間才能生成,而函數須要當即返回)。
其中error.code
爲一個枚舉類型,可能的取值以下:
PERMISSION_DENIED
:用戶拒絕
POSITION_UNAVAILABLE
:地理位置獲取失敗(多是用戶沒網或衛星搜不到等緣由)
TIMEOUT
:地理位置獲取超時
而error.message
則爲一個能夠幫助開發者調試的錯誤信息(此信息通常不適合直接顯示在網頁中給用戶查看)。
事實上,上述getCurrentPosition
函數還支持第三個可選的參數,是一個 Option Object,一共有三個選項能夠設定:
var options = {
enableHighAccuracy: false,
timeout: 5000,
maximumAge: 60000
}
其中timeout
是設定地理位置獲取的超時時間(單位爲毫秒,用戶選擇容許的時間不計算在內);而maximumAge
表示容許設備從緩存中讀取位置,緩存的過時時間,單位是毫秒,設爲0
來禁用緩存讀取。若是返回的是緩存中的時間,會在timestamp
中反映出來。
支持 Geolocation API 的瀏覽器/終端/操做系統:
Firefox 3.5+
Google Chrome 5.0+
Safari 5.0+
Opera 10.60+
Internet Explorer 9.0+
Android 2.0+
iOS 3.0+
Opera Mobile 10.1+
Blackberry OS 6
上週項目不忙,抽時間研究了一下HTML5的geolocation。
在HTML5中,geolocation做爲navigator的一個屬性出現,它自己是一個對象,擁有三個方法:
- getCurrentPosition
- watchPosition
- clearWatch
具體用法以下:
//判斷瀏覽器是否支持geolocation
if(navigator.geolocation){
// getCurrentPosition支持三個參數
// getSuccess是執行成功的回調函數
// getError是失敗的回調函數
// getOptions是一個對象,用於設置getCurrentPosition的參數
// 後兩個不是必要參數
var getOptions = {
//是否使用高精度設備,如GPS。默認是true
enableHighAccuracy:true,
//超時時間,單位毫秒,默認爲0
timeout:5000,
//使用設置時間內的緩存數據,單位毫秒
//默認爲0,即始終請求新數據
//如設爲Infinity,則始終使用緩存數據
maximumAge:0
};
//成功回調
function getSuccess(position){
// getCurrentPosition執行成功後,會把getSuccess傳一個position對象
// position有兩個屬性,coords和timeStamp
// timeStamp表示地理數據建立的時間??????
// coords是一個對象,包含了地理位置數據
console.log(position.timeStamp);
// 估算的緯度
console.log(position.coords.latitude);
// 估算的經度
console.log(position.coords.longitude);
// 估算的高度 (以米爲單位的海拔值)
console.log(position.coords.altitude);
// 所得經度和緯度的估算精度,以米爲單位
console.log(position.coords.accuracy);
// 所得高度的估算精度,以米爲單位
console.log(position.coords.altitudeAccuracy);
// 宿主設備的當前移動方向,以度爲單位,相對於正北方向順時針方向計算
console.log(position.coords.heading);
// 設備的當前對地速度,以米/秒爲單位
console.log(position.coords.speed);
// 除上述結果外,Firefox還提供了另一個屬性address
if(position.address){
//經過address,能夠得到國家、省份、城市
console.log(position.address.country);
console.log(position.address.province);
console.log(position.address.city);
}
}
//失敗回調
function getError(error){
// 執行失敗的回調函數,會接受一個error對象做爲參數
// error擁有一個code屬性和三個常量屬性TIMEOUT、PERMISSION_DENIED、POSITION_UNAVAILABLE
// 執行失敗時,code屬性會指向三個常量中的一個,從而指明錯誤緣由
switch(error.code){
case error.TIMEOUT:
console.log('超時');
break;
case error.PERMISSION_DENIED:
console.log('用戶拒絕提供地理位置');
break;
case error.POSITION_UNAVAILABLE:
console.log('地理位置不可用');
break;
default:
break;
}
}
navigator.geolocation.getCurrentPosition(getSuccess, getError, getOptions);
// watchPosition方法同樣能夠設置三個參數
// 使用方法和getCurrentPosition方法一致,只是執行效果不一樣。
// getCurrentPosition只執行一次
// watchPosition只要設備位置發生變化,就會執行
var watcher_id = navigator.geolocation.watchPosition(getSuccess, getError, getOptions);
//clearwatch用於終止watchPosition方法
navigator.geolocation.clearWatch(watcher_id);
}
geolocation的使用方法並不複雜,可是其實現原理比較有意思。
經過觀察geolocation的使用方法,能夠發現這個api能夠在用戶容許的狀況下調用不少系統設備,好比GPS、WIFI、藍牙等。
W3C對geolocation的定義是這樣的:
The Geolocation API defines a high-level interface to location information associated only with the device hosting the implementation, such as latitude and longitude. The API itself is agnostic of the underlying location information sources. Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs, as well as user input. No guarantee is given that the API returns the device's actual location.
這 裏提到了,geolocation的位置信息來源包括GPS、IP地址、RFID、WIFI和藍牙的MAC地址、以及GSM/CDMS的ID等等。規範 中沒有規定使用這些設備的前後順序,在HTML5的實現中,手機等移動設備固然優先使用GPS定位,而筆記本和部分平板,最準的定位是WIFI,至於網線 上網的臺式機,通常就只能使用IP來定位了,這個準確度最低。
在這些方法裏,GPS定位最好理解,衛星直接給出定 位數據。而WIFI和IP地址定位,都不是瀏覽器自己可以實現的。這兩種方式都必須將IP地址或 WIFI信號收集到的周圍路由信息,上傳到某個服務器,由服務器的查詢計算位置信息,而後返回給瀏覽器。那麼這些查詢服務由誰來提供呢?
首 先來看chrome,很明顯,確定是google本身提供的服務。經過chrome自帶的抓包方法(chrome://net-internals/) 能夠看到,在使用geolocation時,chrome向www.googleapis.com/geolocation/v1/geolocate的 接口發送了請求,因爲請求用spdy加密過,因此看不出具體內容,只有一點能夠肯定,即wifi上網時,是post方式傳數據,而使用網線時,使用的是 get。
firefox使用的也是google的服務,可是和chrome用的接口不一樣,這個是https://maps.googleapis.com/maps/api/browserlocation/json
請 求數據是:browser=firefox&sensor=true&wifi=mac:xx-xx-xx-xx-xx- xx%7Cssid:xxxxxxx%7Css:-43&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-43&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-43&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-44&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-60&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-61&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-62&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-63&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-63&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-67&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-67&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-67&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-67&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-74&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-82&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-84&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-85
這個就很清晰了,是周邊wifi設備的ssid、mac地址,以及信號強度。(公司網絡,路由名和mac地址隱去。)
opera用的也是google的服務,接口url沒弄到,不過從ip地址來看,也是google的ip。
對於不支持geolocation的瀏覽器,原本能夠調用google的gears項目提供的接口來查詢地理位置,可是該服務目前2011年已經中止,暫時也沒有出現更好的替代方案。