若是說地理位置的感知已經成爲了一項成熟的技術,那麼緊接着的問題就是 Geolocation 存在的意義是什麼?就我目前對 Geolocation 的理解,我認爲它存在的理由至少包含如下兩點:
1. 公共數據:目前的地理位置探測,其資料每每來源於服務商各自的數據,而使用瀏覽器內置的統一接口,將高效整合這一信息。
2. 精肯定位:不管是谷歌仍是谷姐們,實現定位的原理無非是經過 IP 地址來探測用戶的所在位置,衆所周知,IP 的定位能力是比較差的,絕大多數狀況下,它的精確度能達到數十千米就已經不錯了,除此以外,沒有別的任何辦法,不管是服務器端語言仍是客戶端的 JavaScript 腳本,都沒法從用戶那裏獲取到更多對定位有所幫助的信息。然而做爲用戶機器上更爲底層的瀏覽器,它將有權利支配其餘有助於定位的設備,好比 GPS 和 WIFI。GPS 你們都已經很熟悉了,在信號良好的狀況下,它能夠精確到數米以內。而 WIFI 在國內基本上被廢了,對於這項技術普及的國家,WIFI 的定位基本上能夠精確到百米左右,聽說常常能夠見到一些公司的人,成天什麼都不幹,就開着小車處處晃,到一個熱點( Hot Spot ),就記錄下當前的地理位置,而後傳回到公司的數據庫。 javascript
該對象位於咱們很是熟悉的 Navigator 對象下面,能夠經過 navigator.geolocation 來訪問,固然前面也能夠加上 window.。不支持 geolocation 的瀏覽器並不包含這一對象,那麼能夠經過下面的代碼來作能力檢測,對不一樣的瀏覽器作不一樣的處理。 java
if (navigator.geolocation) { alert( ' 你的瀏覽器支持 geolocation ' ); }else{ alert( ' 你的瀏覽器不支持 geolocation ' ) }
在訪問 geolocation 對象時,即調用 geolocation 下面的方法時,瀏覽器會彈出提示,詢問用戶是否許可網站提供的位置服務,只有在獲得用戶許可事後,服務纔會繼續,不然將被中止,在稍後你將會了解到,咱們可以捕獲到用戶拒絕服務的動做。下面這張圖分別是 Chrome , Firefox 和 Opera 在初次訪問 geolocation 時,給用戶的提示: git
當得到用戶的許可事後,便一切就緒。咱們將經過 geolocation 下的 getCurrentPosition 方法來獲取用戶的信息,這個方法是今天整篇文章的核心部分,也是 geolocation 一個很是重要的方法。 web
navigator.geolocation.getCurrentPosition( getPositionSuccess , getPositionError );
在上面的代碼中,咱們調用了 getCurrentPosition 方法,併爲其傳遞了兩個參數,事實上這個方法能夠接受三個參數,前兩個參數是函數,最後一個是對象:第一個參數是成功獲取位置信息的回調函數,它是方法惟一必須的參數;第二個參數用於捕獲獲取位置信息出錯的狀況,第三個參數是配置項。 數據庫
當瀏覽器成功獲取到用戶的位置信息時,getCurrentPosition 的第一個函數類型的參數將被調用,一個 position 對象會被傳入到調用的函數中,這個對象中包含了瀏覽器傳回的數據,這很是重要。 api
function getPositionSuccess( position ){ var lat = position.coords.latitude; var lng = position.coords.longitude; document.write( "您所在的位置: 經度" + lat + ",緯度" + lng ); }
是的,position 對象包含了用戶的地理位置信息,該對象下面的 coords 子對象包含了用戶所在的緯度和經度信息,經過 position.coords.latitude 能夠訪問緯度,而 position.coords.longitude 中存放了經度的信息,用戶的位置信息越精確,這兩個數字後面的小數點越長。事實上,在 Firefox 中,position 對象下還附帶有另外一個 address 對象,這個對象包含這個經緯度下的國家名,城市名甚至街道名。 瀏覽器
function getPositionSuccess( position ){ var lat = position.coords.latitude; var lng = position.coords.longitude; alert( "您所在的位置: 經度" + lat + ",緯度" + lng ); if(typeof position.address !== "undefined"){ var country = position.address.country; var province = position.address.region; var city = position.address.city; alert(' 您位於 ' + country + province + '省' + city +'市'); } }
錯誤捕獲:上面都是成功獲取到用戶位置信息的處理,可是出現問題的狀況在所不免,當獲取用戶的位置信息出錯時,傳遞到 getCurrentPosition 的第二個函數類型參數被調用,一個包含具體出錯信息的對象會被傳遞進去,錯誤將被捕獲。 服務器
function getPositionError(error){ switch(error.code){ case error.TIMEOUT : alert( " 鏈接超時,請重試 " ); break; case error.PERMISSION_DENIED : alert( " 您拒絕了使用位置共享服務,查詢已取消 " ); break; case error.POSITION_UNAVAILABLE : alert( " 親愛的火星網友,很是抱歉,咱們暫時沒法爲您所在的星球提供位置服務 " ); break; } }
error 對象下面,存放了3個常量:
TIMEOUT 表示獲取信息超時。
PERMISSION_DENIED 表示用戶選擇了拒絕了位置服務。
POSITION_UNAVAILABLE 表示位置不可知。
而每一次出錯時 error.code 將指向3個常量之中的一個。 網絡
配置項:getCurrentPosition 方法的第三個參數是一個對象,該對象影響了獲取位置時的一些細節。
enableHighAccuracy,它將告訴瀏覽器是否啓用高精度設備,所謂的高精度設備包含但不侷限於前面所提到的 GPS 和 WIFI,值爲 true 的時候,瀏覽器會嘗試啓用這些設備,默認指爲 true,在這種狀況下,瀏覽器會盡量地進行更爲精確的查詢,簡單地說,若是用戶有可用的 GPS 設備,會返回 GPS 設備的查詢結果,IP 是最後的選擇,對於移動設備來講,網絡接入點(基站)或許成爲另外一個選擇,對此我尚未徹底瞭解,但根據測試,即時沒有任何額外功能的手機,也可以獲得更爲精確的查詢結果。
timeout,超時,獲取位置信息時超出設定的這個時長,將會觸發錯誤,捕獲錯誤的函數將被調用,而且錯誤碼指向TIMEOUT。
這樣咱們嘗試修改調用 getCurrentPosition 時傳遞的參數 dom
navigator.geolocation.getCurrentPosition( getPositionSuccess , getPositionError,{ timeout : 5000 // 5 秒超時 } );
對於使用移動設備的用戶來講,位置並非固定的,W3C 固然也考慮到了這一點,watchPosition 是一個專門用來處理這一狀況的方法,watchPosition 被調用後,瀏覽器會跟蹤設備的位置,每一次位置的變化,watchPosition 中的代碼都將會被執行。對於致力於移動設備 web 開發的同窗來講,這個方法是及其重要的,它也許將會改變 web 移動客戶端的格局。
navigator.geolocation.watchPosition( refreshPosition );
上面的代碼表示,但設置位置發生改變時,refreshPosition 將會被調用。事實上 watchPosition 和 getCurrentPosition 幾乎如出一轍,一樣包含了一個成功獲取位置的回調函數,一個獲取失敗的回調函數和一個配置項,區別僅僅是在觸發的時機上。因此具體的方法就再也不重複了。上面的代碼表示在每一次位置發生改變時,調用 refreshPosition 函數。
接下來,咱們經過一個實例,來具體應用一下 Geolocation ,實例的最終效果是,獲取用戶的位置,並經過 Google Map 在地圖上標記出來,當用戶的位置發生改變後,更新以前在地圖上的標記到新的位置。首先咱們準備好 DOM,並加載 Google Map
<!-- 按鈕,被點擊時開始獲取用戶位置信息 --> <input type="button" id="getPos" value="獲取個人位置" /> <!-- 用來存放反饋給用戶信息的 div --> <div id="info"></div> <!-- 爲 Google Map 準備 --> <div id="map"></div> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false" ></script>
接下來咱們在 JavaScript 中獲取這些 DOM,併爲 Google Map 提供一個對象用來存放地圖和標記。這些都是準備工做,很煩,可是不得不作。
var dom = { btn : document.getElementById('getPos'), info : document.getElementById('info'), map : document.getElementById('map') }; var gmap = { map : null, marker : null }
接下來監聽按鈕的事件,當按鈕被點擊的時候,將觸發獲取用戶的位置信息。在這裏咱們對瀏覽器進行了檢測,若是不支持 Geolocation 接口,將提示用戶,並中止進一步的動做。
dom.btn.onclick = function(){ if (navigator.geolocation) { dom.info.innerHTML = "請等待查詢結果返回"; dom.info.className = "warn"; navigator.geolocation.getCurrentPosition(getPositionSuccess,getPositionError,{timeout:5000}); }else { dom.info.innerHTML = "抱歉,您所使用的瀏覽器不支持 Geolocation 接口"; dom.info.className = "warn"; } }
在上面咱們向 getCurrentPosition 傳遞了兩個函數,如今咱們來具體寫這兩個函數,首先是 getPositionSuccess ,當成功獲取到用戶的位置信息時,這個函數被調用,咱們將在這時更新頁面上的顯示值,並配置追蹤用戶的位置的函數,最後調用 Google Map 的 API 在 id 爲 map 的 div 中顯示地圖,並在地圖上標記出用戶的當前位置。
function getPositionSuccess(position){ var lat = position.coords.latitude; var lng = position.coords.longitude; dom.info.innerHTML = "您所在的位置: 經度" + lat + ",緯度" + lng; navigator.geolocation.watchPosition(refreshPosition); // 載入 Google 地圖 var latlng = new google.maps.LatLng(lat, lng); var myOptions = { zoom : 16, center : latlng, mapTypeId : google.maps.MapTypeId.ROADMAP }; gmap.map = new google.maps.Map(document.getElementById("map"), myOptions); // 向地圖中添加標記 gmap.marker = new google.maps.Marker({ position: latlng, map: gmap.map }); }
對於錯誤處理的函數,則很是簡單,能夠參看前面的內容。咱們來關注一下追蹤位置的函數,在這個函數中,咱們實時更新顯示信息,並更新地圖到用戶所處的位置。
function refreshPosition(position){ var lat = position.coords.latitude; var lng = position.coords.longitude; var latlng = new google.maps.LatLng(lat, lng); // 重設地圖位置 gmap.map.setCenter(latlng); dom.info.innerHTML = '您所在的位置: 經度' + lat ' + ',緯度' + lng; // 重設標記位置 gmap.marker.setOptions({ position: new google.maps.LatLng(lat, lng) }); }
以上關於 Google Map 的代碼不是很瞭解的同窗能夠到 Google Code 去看一下 手冊,這裏只是很簡單的應用,有興趣的同窗能夠進一步延伸。下面是這個 Demo 的最終效果。