使用javaScript API實(shí)現(xiàn)地理定位

1. 使用地理定位確定位置
  • IP地址定位
  • CPS定位
  • 蜂窩電話基站定位
  • wifi定位

一個(gè)聰明的瀏覽器可能會(huì)首先使用蜂窩電話三角定位渠旁,如果這個(gè)方法可行悯衬,你會(huì)得到一個(gè)大致的位置澈侠,然后使用Wi-Fi或GPS提供一個(gè)更精確的位置学歧。

2.使用javascrip API實(shí)現(xiàn)定位
  1. 首先創(chuàng)建location.html頁面
<!DOCTYPE html>
<html>
<head>
    <title>Where am I ?</title>
    <meta charset="utf-8">
    <script src = "myLoc.js"></script>
    <script src="http://maps.google.com/maps/api/js?sensor=true"></script>  
    <link type="text/css" rel="stylesheet" href="js.css">
</head>
<body>
    <form>
        <input type="button" id="watch" value="Watch me">
        <input type="button" id="clearWatch" value="Clear watch">
    </form>
    <div id="location">
        Your location will go here.
    </div>
    <div id="distance">
    Distance from WickedlySmart HQ will go here.
    </div>
    <div id="map">
       
    </div>
</body>
</html>
  1. 使用javascrip API 的getCurrentPosition方法獲取經(jīng)緯度和錯(cuò)誤值腻菇。
//location.js
var options = {
    enableHighAccuracy:true,  //是否啟動(dòng)高精度耗式,啟用后會(huì)很費(fèi)電
    timeout:100,     //timeout 會(huì)控制瀏覽器確定位置的時(shí)間,默認(rèn)是毫秒五芝。
    maximumAge: 0    //這個(gè)值是保存緩存的時(shí)間痘儡,如果在時(shí)間之內(nèi)請(qǐng)求定位,會(huì)用緩存的值枢步,如果超過時(shí)間沉删,請(qǐng)求現(xiàn)在的位置信息
};

window.onload = function() {
    if(navigator.geolocation) {   //查看是否支持定位,如果不支持醉途,則navigator.geolocation返回null
        navigator.geolocation.getCurrentPosition(displayLocation, displayError, options);  //getCurrentPosition有三個(gè)參數(shù) 1.successHanlder 2.errorHanlder 3.options,這里我們只輸入了successHandler 后兩個(gè)是可選的
        // var watchButton = document.getElementById("watch");
        // watchButton.onclick = watchLocation;
        // var clearWatchButton = document.getElementById("clearWatch");
        // clearWatchButton.onclick = clearWatch;
    } else {
        alert("Oops, no geolocation support");
    }
}

//successHandler
function displayLocation (position){  //position是地理定位API向它傳入一個(gè)position對(duì)象矾瑰,其中包含有關(guān)瀏覽器位置的信息
    var latitude = position.coords.latitude;
    var longitude = position.coords.longitude;

    var div = document.getElementById("location");
    div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: " + longitude;
    div.innerHTML += " (fonud in " + options.timeout + "milliseconse)";  //瀏覽器成功得到你的位置時(shí),我們會(huì)讓用戶知道花了多長(zhǎng)時(shí)間
}

function displayError(error) {
    var errorTypes = {  //error對(duì)象有一個(gè)code屬性结蟋,其中包含一個(gè)0-3的數(shù)
        0: "Unknown error",
        1: "Permission denied by user",
        2: "Position is not available",
        3: "Request timed out"
    };

    var errorMessage = errorTypes[error.code];
    if(error.code == 0 || error.code == 2) {
        errorMessage = errorMessage + " " + error.message;
    }

    var div = document.getElementById("location");
    div.innerHTML = errorMessage;

    //如果第一次定位失敗脯倚,我們會(huì)把titmeout時(shí)間增加100ms,然后再試
    options.timeout += 100;
    navigator.geolocation.getCurrentPosition(
        displayLocation,
        displayError,
        options
        );
    div.innerHTML += "........ checking again with timeout=" +  options.timeout;
}

getCurrentPosition有三個(gè)參數(shù)

  • displayLocation是一個(gè)函數(shù),如果瀏覽器能成功確定你的位置,則會(huì)調(diào)用這個(gè)函數(shù)推正,并且會(huì)傳一個(gè)position的對(duì)象恍涂,這個(gè)對(duì)象包含兩個(gè)兩個(gè)屬性coords和timestamp。
    coords中又包含 latitude, longitude植榕,accuracy這幾個(gè)屬性再沧,還有其他屬性在這里就不寫了。

  • 另外兩個(gè)屬性是可選的尊残。displayError是第二個(gè)函數(shù)炒瘸,當(dāng)獲取定位信息失敗時(shí),會(huì)在函數(shù)內(nèi)部傳入一個(gè)錯(cuò)誤的對(duì)象寝衫。

  • 第三個(gè)參數(shù)是positionOptions參數(shù)顷扩。利用這個(gè)參數(shù),可以控制地理定位如何計(jì)算他的值慰毅。

3. 利用兩個(gè)坐標(biāo)值來獲取距離
//回去兩個(gè)坐標(biāo)值的距離
function computeDistance(startCoords, destCoords) {
    var startLatRads = degreesToRadians(startCoords.latitude);
    var startLongRads = degreesToRadians(startCoords.longitude);
    var destLatRads = degreesToRadians(destCoords.latitude);
    var destLongRads = degreesToRadians(destCoords.longitude);

    var Radius = 7371;  //radius of the Earth in km
    var distance = (Math.sin(startLatRads) * Math.sin(destLatRads) + 
        Math.cos(startLatRads) * Math.cos(destLatRads) * 
        Math.cos(startLongRads - destLongRads)) * Radius;

    return distance;
}

//把經(jīng)緯度轉(zhuǎn)化為度數(shù)
function degreesToRadians(degrees) {
    var radians = (degrees * Math.PI)/180;
    return radians;
}
4.把地圖添加到瀏覽器網(wǎng)頁中
// //谷歌地圖
var map = null;

function showMap(coords)  
{  
    var googleLatAndLong = new google.maps.LatLng(coords.latitude, coords.longitude);  //googlemaps API所有方法前面都有g(shù)oogle.maps隘截,并且構(gòu)造函數(shù)注意大寫,LatLng                                                                                                                                                                 取我們的經(jīng)度和緯度  
    var mapOptions = {  
        zoom:10,    //可以指定0-21的值汹胃,數(shù)值越大越顯示更多細(xì)節(jié)婶芭,10大概是城市規(guī)模  
        center:googleLatAndLong,    //中心點(diǎn)  
        mapTypeId:google.maps.MapTypeId.ROADMAP   //還有SATELLITE和HYBIRD  
    };  
    var mapDiv = document.getElementById("map");  
    map = new google.maps.Map(mapDiv, mapOptions);   //全局map在這里使用
}
5.在地圖中添加大頭針
//在地圖上添加大頭針
function addMarker (map, latlong, title, content)  //添加標(biāo)記的函數(shù),參數(shù)分別是着饥,地圖犀农,經(jīng)緯,窗口標(biāo)題和窗口內(nèi)容  
{  
    var markerOptions =    //定義對(duì)象宰掉,屬性為google固定指定的  
    {  
        position:latlong,     
        map:map,  
        title:title,  
        clickable:true  
    };  
    var marker = new google.maps.Marker(markerOptions);  //google的標(biāo)記構(gòu)造函數(shù)  
      
    var infoWindowOptions =  //彈出窗口設(shè)置  
    {  
        content:content,  
        position:latlong  
    };  
    var infoWindow = new google.maps.InfoWindow(infoWindowOptions);  
      
    google.maps.event.addListener(marker, "click", function ()  //google.maps.event.addListener為點(diǎn)擊事件增加監(jiān)聽者呵哨,監(jiān)聽者就像一個(gè)處理程序,類似onclick onload  
    {  
        infoWindow.open(map);  
    });  
}  
6.實(shí)時(shí)監(jiān)控
//實(shí)時(shí)監(jiān)控
var watchId = null;
function watchLocation() {
    watchId = navigator.geolocation.watchPosition(displayLocation, displayError);
}

function clearWatch() {
    if(watchId) {
        navigator.geolocation.clearWatch(watchId);
        watchId = null;
    }
}

//記錄路徑
function scrollMapToPosition(coords) {
    var latitude = coords.latitude;
    var longitude = coords.longitude;
    var latlong = new google.maps.LatLng(latlong, longitude);

    map.panTo(latlong);  //地圖的panTo方法取這個(gè)LagLng對(duì)象并滾動(dòng)地圖贵扰,是你的新位置位于地圖中心
    addMarker(map, latlong, "Your new location", "you moved to: " + latitude + ", " + longitude);

}

全部代碼如下
myLoc.js

var options = {
    enableHighAccuracy:true,  //是否啟動(dòng)高精度仇穗,啟用后會(huì)很費(fèi)電
    timeout:100,     //timeout 會(huì)控制瀏覽器確定位置的時(shí)間,默認(rèn)是毫秒戚绕。
    maximumAge: 0    //這個(gè)值是保存緩存的時(shí)間,如果在時(shí)間之內(nèi)請(qǐng)求定位枝冀,會(huì)用緩存的值舞丛,如果超過時(shí)間,請(qǐng)求現(xiàn)在的位置信息
};
window.onload = function() {
    if(navigator.geolocation) {   //查看是否支持定位果漾,如果不支持球切,則navigator.geolocation返回null
        navigator.geolocation.getCurrentPosition(displayLocation, displayError, options);  //getCurrentPosition有三個(gè)參數(shù) 1.successHanlder 2.errorHanlder 3.options,這里我們只輸入了successHandler 后兩個(gè)是可選的
        // var watchButton = document.getElementById("watch");
        // watchButton.onclick = watchLocation;
        // var clearWatchButton = document.getElementById("clearWatch");
        // clearWatchButton.onclick = clearWatch;
    } else {
        alert("Oops, no geolocation support");
    }
}

//successHandler
function displayLocation (position){  //position是地理定位API向它傳入一個(gè)position對(duì)象,其中包含有關(guān)瀏覽器位置的信息
    var latitude = position.coords.latitude;
    var longitude = position.coords.longitude;

    var div = document.getElementById("location");
    div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: " + longitude;
    // div.innerHTML += " (with " + position.coords.accuracy + " meters accuracy)";  //這里用到position的accuracy屬性绒障,并追加到<div>的innerHTML的末尾
    div.innerHTML += " (fonud in " + options.timeout + "milliseconse)";  //瀏覽器成功得到你的位置時(shí)吨凑,我們會(huì)讓用戶知道花了多長(zhǎng)時(shí)間

    var km = computeDistance(position.coords, ourCoords);
    var distance = document.getElementById("distance");
    distance.innerHTML = "You are " + km + " km from the WickedlySmart HQ";

    if(map == null){
       showMap(position.coords);
    }else {
        scrollMapToPosition(position.coords)
    }
}

function displayError(error) {
    var errorTypes = {  //error對(duì)象有一個(gè)code屬性,其中包含一個(gè)0-3的數(shù)
        0: "Unknown error",
        1: "Permission denied by user",
        2: "Position is not available",
        3: "Request timed out"
    };

    var errorMessage = errorTypes[error.code];
    if(error.code == 0 || error.code == 2) {
        errorMessage = errorMessage + " " + error.message;
    }

    var div = document.getElementById("location");
    div.innerHTML = errorMessage;

    //如果第一次定位失敗,我們會(huì)把titmeout時(shí)間增加100ms,然后再試
    options.timeout += 100;
    navigator.geolocation.getCurrentPosition(
        displayLocation,
        displayError,
        options
        );
    div.innerHTML += "........ checking again with timeout=" + options.timeout;
}

//回去兩個(gè)坐標(biāo)值的距離
function computeDistance(startCoords, destCoords) {
    var startLatRads = degreesToRadians(startCoords.latitude);
    var startLongRads = degreesToRadians(startCoords.longitude);
    var destLatRads = degreesToRadians(destCoords.latitude);
    var destLongRads = degreesToRadians(destCoords.longitude);

    var Radius = 7371;  //radius of the Earth in km
    var distance = (Math.sin(startLatRads) * Math.sin(destLatRads) + 
        Math.cos(startLatRads) * Math.cos(destLatRads) * 
        Math.cos(startLongRads - destLongRads)) * Radius;

    return distance;
}

//把經(jīng)緯度轉(zhuǎn)化為度數(shù)
function degreesToRadians(degrees) {
    var radians = (degrees * Math.PI)/180;
    return radians;
}

var ourCoords = {
    latitude: 47.624851,
    longitude: -122.52099
};


// //谷歌地圖
var map = null;

function showMap(coords)  
{  
    var googleLatAndLong = new google.maps.LatLng(coords.latitude, coords.longitude);  //googlemaps API所有方法前面都有g(shù)oogle.maps鸵钝,并且構(gòu)造函數(shù)注意大寫糙臼,LatLng                                                                                                                                                                 取我們的經(jīng)度和緯度  
    var mapOptions = {  
        zoom:10,    //可以指定0-21的值,數(shù)值越大越顯示更多細(xì)節(jié)恩商,10大概是城市規(guī)模  
        center:googleLatAndLong,    //中心點(diǎn)  
        mapTypeId:google.maps.MapTypeId.ROADMAP   //還有SATELLITE和HYBIRD  
    };  
    var mapDiv = document.getElementById("map");  
    map = new google.maps.Map(mapDiv, mapOptions);   //全局map在這里使用  


    var title = "Your Location";  
    var content = "You are here" + coords.latitude + coords.longitude;  
    addMarker(map, googleLatAndLong, title, content); 
}

//在地圖上添加大頭針
function addMarker (map, latlong, title, content)  //添加標(biāo)記的函數(shù)变逃,參數(shù)分別是,地圖怠堪,經(jīng)緯揽乱,窗口標(biāo)題和窗口內(nèi)容  
{  
    var markerOptions =    //定義對(duì)象,屬性為google固定指定的  
    {  
        position:latlong,     
        map:map,  
        title:title,  
        clickable:true  
    };  
    var marker = new google.maps.Marker(markerOptions);  //google的標(biāo)記構(gòu)造函數(shù)  
      
    var infoWindowOptions =  //彈出窗口設(shè)置  
    {  
        content:content,  
        position:latlong  
    };  
    var infoWindow = new google.maps.InfoWindow(infoWindowOptions);  
      
    google.maps.event.addListener(marker, "click", function ()  //google.maps.event.addListener為點(diǎn)擊事件增加監(jiān)聽者粟矿,監(jiān)聽者就像一個(gè)處理程序凰棉,類似onclick onload  
    {  
        infoWindow.open(map);  
    });  
}  


//實(shí)時(shí)監(jiān)控
var watchId = null;
function watchLocation() {
    watchId = navigator.geolocation.watchPosition(displayLocation, displayError);
}

function clearWatch() {
    if(watchId) {
        navigator.geolocation.clearWatch(watchId);
        watchId = null;
    }
}

//記錄路徑
function scrollMapToPosition(coords) {
    var latitude = coords.latitude;
    var longitude = coords.longitude;
    var latlong = new google.maps.LatLng(latlong, longitude);

    map.panTo(latlong);  //地圖的panTo方法取這個(gè)LagLng對(duì)象并滾動(dòng)地圖,是你的新位置位于地圖中心
    addMarker(map, latlong, "Your new location", "you moved to: " + latitude + ", " + longitude);

}

js.css

#map {
    width:400px;
    height: 400px;
    margin: 10px;
    background-color: #444432;
}

#distance {
    color: blue;
}



知行辦公陌粹,專業(yè)移動(dòng)辦公平臺(tái)https://zx.naton.cn/
【總監(jiān)】十二春秋之撒犀,3483099@qq.com
【Master】zelo申屹,616701261@qq.com绘证;
【運(yùn)營(yíng)】運(yùn)維艄公哗讥,897221533@qq.com嚷那;****
【產(chǎn)品設(shè)計(jì)】流浪貓,364994559@qq.com杆煞;
【體驗(yàn)設(shè)計(jì)】兜兜魏宽,2435632247@qq.com
【iOS】淘碼小工决乎,492395860@qq.com队询;iMcG33K,imcg33k@gmail.com构诚;
【Android】人猿居士蚌斩,1059604515@qq.com;思路的頓悟范嘱,1217022114@qq.com送膳;
【java】首席工程師MR_W,feixue300@qq.com丑蛤;
【測(cè)試】土鏡問道叠聋,847071279@qq.com
【數(shù)據(jù)】fox009521受裹,42151960@qq.com碌补;
【安全】保密,你懂的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末厦章,一起剝皮案震驚了整個(gè)濱河市镇匀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闷袒,老刑警劉巖坑律,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異囊骤,居然都是意外死亡晃择,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門也物,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宫屠,“玉大人,你說我怎么就攤上這事滑蚯±缩澹” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵告材,是天一觀的道長(zhǎng)坤次。 經(jīng)常有香客問我,道長(zhǎng)斥赋,這世上最難降的妖魔是什么缰猴? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮疤剑,結(jié)果婚禮上滑绒,老公的妹妹穿的比我還像新娘。我一直安慰自己隘膘,他們只是感情好疑故,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著弯菊,像睡著了一般纵势。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上管钳,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天吨悍,我揣著相機(jī)與錄音,去河邊找鬼蹋嵌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛葫隙,可吹牛的內(nèi)容都是我干的栽烂。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼腺办!你這毒婦竟也來了焰手?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤怀喉,失蹤者是張志新(化名)和其女友劉穎书妻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體躬拢,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡躲履,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了聊闯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片工猜。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖菱蔬,靈堂內(nèi)的尸體忽然破棺而出篷帅,到底是詐尸還是另有隱情,我是刑警寧澤拴泌,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布魏身,位于F島的核電站,受9級(jí)特大地震影響蚪腐,放射性物質(zhì)發(fā)生泄漏箭昵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一削茁、第九天 我趴在偏房一處隱蔽的房頂上張望宙枷。 院中可真熱鬧,春花似錦茧跋、人聲如沸慰丛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诅病。三九已至,卻和暖如春粥烁,著一層夾襖步出監(jiān)牢的瞬間贤笆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工讨阻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留芥永,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓钝吮,卻偏偏與公主長(zhǎng)得像埋涧,于是被迫代替她去往敵國(guó)和親板辽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • 原文: https://github.com/ecomfe/spec/blob/master/javascript...
    zock閱讀 3,371評(píng)論 2 36
  • 當(dāng)今技術(shù)定位的方式棘催,有位置信息來源定位劲弦,IP定位,GPS定位醇坝,WIFI定位邑跪,手機(jī)定位和自定義定位。本文通過獲取經(jīng)緯...
    dovlie閱讀 6,174評(píng)論 0 8
  • 周六到校接孩子放學(xué)呼猪,直接到都江堰画畅,老公朋友結(jié)婚,我們商量早一天到郑叠,讓孩子放松一下夜赵,順便去看看聞名的都江堰水...
    記得祝福閱讀 171評(píng)論 0 2
  • 五一假期這幾天乡革,我從網(wǎng)絡(luò)上基本消失寇僧。手機(jī)只是必要的聯(lián)絡(luò)工具,不看朋友圈更新沸版,不看公眾號(hào)推送嘁傀,也沒來簡(jiǎn)書更新。...
    Linda愛美麗閱讀 447評(píng)論 3 3