HTML5 -- 地理定位

如果你想开发一款在线天气预报系统,那你可能想知道用户所在的位置,利用 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...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容

  • 基本示例 html基础代码: js代码: 地理定位中概要知识点 与蜂窝基站三角定位或网络IP相比,GPS是获取位置...
    lincimy阅读 912评论 0 1
  • 一:定位用户的位置 HTML5 Geolocation API 用于获得用户的地理位置。 鉴于该特性可能侵犯用户的...
    GreenHand1阅读 564评论 1 0
  • 当今技术定位的方式,有位置信息来源定位,IP定位,GPS定位,WIFI定位,手机定位和自定义定位。本文通过获取经纬...
    dovlie阅读 6,185评论 0 8
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,092评论 4 62
  • 十年之前/我不认识你你不属于我/我们还是一样陪在一个陌生人左右/走过渐渐熟悉的街头/十年之后/我们是朋友还可以问候...
    苋巷阅读 280评论 0 3