HTML5 -- 地理定位

作者: ghwaphon | 来源:发表于2016-12-13 20:30 被阅读673次

    如果你想开发一款在线天气预报系统,那你可能想知道用户所在的位置,利用 HTML5 你可以轻易的实现这一点。当然,我们不一定要求你必须使用手持设备,即使是桌面浏览器也可以取得地理位置。

    如果你是手持设备,那么可以利用 GPS 或者蜂窝电话基站获取你的地理位置,如果你用的是桌面浏览器,可以利用 IP 地址获取你的地理位置。

    值得注意的是,由于获取地理位置的方式不同,所以在不同的设备上即使在同一地点获取的地理位置也有偏差,甚至当你利用不同的浏览器在同一设备上获取到的信息也会有所不同,这都是正常现象。

    在本篇文章中,我将对 HTML5 中的地理位置 API 作详细的介绍,并且会利用获取到的地理信息将你的位置在谷歌地图中标记出来。下面就让我们开始吧~


    使用地理定位 API

    下面我们创建一个页面,用于显示我们的地理位置 :

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
        </head>
        <body>
            <div id="location"></div>
        </body>
    </html>
    

    可见,我们声明了一个 <div> , 并为其指定了 id

    下面就可以用地理定位 API 去获取位置信息,不过不要忘记检测你的浏览器是否支持这个 API

    window.onload = getLocation;
    
    function getLocation() {
        var locationElement = document.getElementById("location");
    
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function(position) {
                var latitude = position.coords.latitude;
                var longitude = position.coords.longitude;
    
                locationElement.innerHTML = "Latitude: " + latitude +
                    ", Longitude: " + longitude;
            });
    
        } else {
            location.innerHTML = "No geolocation support";
        }
    }
    

    首先检测浏览器是否支持 navigator.geolocation, 如果支持,就可以调用 getCurrentPosition() 方法,用于获取到具体的信息。那么这个 position 属性是从哪里来的呢?说到这里,我们就不得不深入去了解 getCurrentPosition() 这个函数了。

    getCurrentPosition(successHandler, errorHandler, options)
    

    这个函数其实有三个参数,如果浏览器成功的确定了你的位置,就会调用 successHandler, 如果浏览器无法获取你的地理位置,则会调用 errorHandleroptions 用于定制地理定位方法。

    实践出真知,让我们在使用的过程中详细的介绍这三个参数。不过在这之前,我想对上面已经写好的代码进行改写,因为上述代码中我们将 successHandler 写成了匿名函数,说实话,我不经常用匿名函数,虽然它很方便,但是如果代码出现了问题,会给调试带来很大的麻烦,因为它身为一个函数,竟连能标记自己的证据都没有。

    下面将匿名函数提出来,改写之后的代码如下所示

    window.onload = getLocation;
    
    function getLocation() {
        var locationElement = document.getElementById("location");
    
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(successHandler);
    
        } else {
            location.innerHTML = "No geolocation support";
        }
    }
    
    function successHandler(position) {
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
    
        document.getElementById("location").innerHTML = "Latitude: " + latitude +
            ", Longitude: " + longitude;
    }
    

    当浏览器成功的获取到你的地理信息,会将信息保存在 position 中,传入你的函数,那么这个 position 到底包含哪些信息呢?

    为了清晰的看到,我用 Dia 画了一个简易类图。

    position.png

    值得注意的是,高度( altitude), 速度( speed), 朝向( heading) 是否支持,取决于你的设备,不过可以肯定的是,无论如何,你都会获取到 纬度( latitude), 经度( longitude), 精度( accuracy)。

    好了,介绍完了成功的情况,下面就得去看看如果获取地理位置信息失败了,我们改怎么办呢?

    其实和 successHandler 类似,如果浏览器调用 errorHandler 会传入一个 error 对象,这个对象中包含一个 0-3 之间的数值码,描述了它未能确定位置的原因。这个对象中还包含了一个 message 属性,用于提供错误信息。

    好了,介绍完了,那么下面来看看代码吧

    function errorHandler(error) {
        var errorTypes = {
            0: "Unkown error",
            1: "Permission denied by user",
            2: "Position is not avaliable",
            3: "Request time out"
        };
    
        var errorMessage = errorTypes[error.code];
        if (error.code == 0 || error.code == 2) {
            errorMessage = errorMessage + " " + error.message;
        }
    
        document.getElementById("location")
                .innerHTML = errorMessage;
    }
    

    当然,我们还需要将这个函数传入到 getCurrentPosition() 方法中。

    navigator.geolocation.getCurrentPosition(successHandler, errorHandler);
    

    下面就只剩下一个 options 参数了,来看看它的组成。

    options.png
    • enableHighAccuracy - 这个属性用于提示地理定位 API, 不管利用什么手段,花费什么代价,都要提供一个尽可能精确的结果, 当然启用这个选项并不能保证你会获取到一个更精确的位置。

    • timeout - 这个选项告诉浏览器确定用户的位置要多长时间,如果在这个值的时间内还没有获取到用户的地址,那就放弃尝试,并调用 errorHandler,这个值的默认选项是 Infinity.

    • maximumAge - 用户设置一个位置可以保存多长时间。如果浏览器在 30s 前利用 getCurrentPosition() 获取了一个位置, maximumAge 被设置为 90000(90秒),那么如果现在调用 getCurrentPosition(), 则会返回已经缓存的位置。

    现在你已经知道了所有 getCurrentPosition() 的参数,那么下面我们可以这么调用。

    navigator.geolocation.getCurrentPosition(successHandler, errorHandler,
                {enableHighAccuracy: true, timeout: 1000, maximumAge: 60000});
    

    意思是,我想要一个年龄不超过 6 分钟的位置,而且我想一秒得到这个位置,还有,这个位置要尽可能精确~

    事实上,有一个和 getCurrentPosition() 类似的函数,它也可以获取到用户的位置,而且它的功能更强大,它会在你的位置改变时自动调用 successHandler,这也就意味着你可以利用这个函数写一个实时跟踪应用,这个函数就是 watchLocation(), 这个函数只接受两个参数,也就是 successHandlererrorHandler, 使用方式和 getCurrentPosition() 一样。当然这个方法在调用的时候会返回一个 watchId, 你可以使用 clearWatch(watchId) 清除掉监视行为。


    将位置显示在谷歌地图上

    为了使用谷歌地图,我们首先要在页面中加入 Google Maps 的引用 :

    <script src="http://maps.google.com/maps/api/js?sensor=true"></script>
    

    然后,在页面中加入一个 <div> ,为其设置宽度和高度,用于装载地图信息。

    <div id="map"></div>
    

    CSS 如下:

    div#map {
        width: 640px;
        height: 480px;
        border: 1px solid #000;
    }
    

    想要显示一个谷歌地图,那么需要下面三步:

    1. 将利用地理定位 API 获取到的经纬度封装在 Google API 中,如下所示:

       var googleLatAndLong = new google.maps.LatLng(latitude, longitude);
      
    2. 指定选项,用于控制地图的创建,zoom 用于控制视图的缩放程度,可以设置为 0 - 21 之间的任何值, center 用于设置地图中间位置的经纬度,mapTypeId 用于设置地图的类型,可以设置为道路地图或卫星地图。

       var mapOptions = {
           zoom: 15,
           center: googleLatAndLong,
           mapTypeId: google.maps.MapTypeId.ROADMAP
       };
      
    3. 利用构造函数创建地图对象,有两个参数,第一个是用于装载地图的 DOM 元素,第二个是 mapOptions

       var element = document.getElementById("map");
       var map = new google.maps.Map(element,mapOptions);
      

    设置完之后,用浏览器打开就可以看到效果图,像下面这样。

    location.png

    看着很不错,不过一般我们看地图的时候,不是都有一个标记,用于显示我所在的位置吗?当然,我们也可以地图上添加标记。

    制作这么一个 标记需要三步,下面来逐一介绍。

    1. 制作 Marker

       var markerOptions = {
           position: latlong,
           map: map,
           title: title,
           clickable: true
       };
      
       var marker = new google.maps.Marker(markerOptions);
      
    2. 制作信息窗口

       var infoWindowOptions = {
           content: content,
           position: latlong
       };
      
       var infoWindow = new google.maps.InfoWindow(infoWindowOptions);
      
    3. 添加到地图中去

       var infoWindow = new google.maps.InfoWindow(infoWindowOptions);
      
       google.maps.event.addListener(marker, "click", function() {
           infoWindow.open(map);
       });
      

    看看实现的效果

    locationwithmarker.png

    你可以在 我的 Github 下载源码

    Ending...

    相关文章

      网友评论

      • 0c9bbdbc7287:赞~!
      • 前端收藏家:我试了下,谷歌地图的js文件下载不了,请问是怎么弄的啊?
        ghwaphon:@Tokenl 对的,确实要翻墙
        前端收藏家:我引用了,但是控制台报错了,说那个文件没有成功加载,是有翻墙的
        ghwaphon:@Tokenl 这个是不用下载的,直接像我那样引用就可以了
      • stois:可以。不过一直watch的话不知会对性能产生怎样的影响
        ghwaphon:@stois 非常耗电,所以最好提供开关按钮,让用户选择是否开启
      • c9875768a65a:Mark一下,起床试试
      • 320495f17609:挺有意思的哈。
      • 7ddc14d237ac:棒棒的!

      本文标题:HTML5 -- 地理定位

      本文链接:https://www.haomeiwen.com/subject/wisbmttx.html