Geolocation和Web Sockets基于NodeJs的实战(2)

上一篇教程明河讲解了一些NodeJs的知识点,这一篇教程将给大家讲解前端方面的知识点。

Geolocation

Geolocation是html5中的主要内容,用于处理客户端的地理信息,特别在手持设备上有广泛的使用场景。

Geolocation的简单的demo

(PS:demo中虽然实现了位置定位,但不能随着你的移动,坐标也发生变化,借助NodeJs的socket.io模块即可实现。)

Geolocation的兼容性情况

Geolocation兼容性还算不错,不算IE9以下,你懂的….

Geolocation的地理信息精度问题

Geolocation的主要定位方式有如下几种:

  • ip地址:也是web端最常用的方式,精度基本符合日常使用场景,有时可能出现定位到ISP机房的情况
  • GPS :常见于移动设备,最为精确,定位需时较长。
  • WiFi基站的mac地址:适用范围窄
  • GSM或CDMA基站:精度一般

(《html5高级程序设计》中有详细的论述。)

Geolocation API的使用

先通过 navigator.geolocation的存在性,判断浏览器是否支持Geolocation;

    /**
     * 浏览器是否支持 geolocation api
     * @return Boolean
     */
    function isSupportGeo(){
        var isSupport = false;
        if (navigator.geolocation) {
            isSupport = true;
        } else {
            isSupport = false;
            console.log('浏览器不支持geolocation');
        }
        return isSupport;
    }

如何获取客户端当前地理位置?

navigator.geolocation.getCurrentPosition(successCallback, [errorCallback] , [positionOptions]),使用 getCurrentPosition()方法即可。

参数的含义如下:

  • successCallback:获取定位成功时执行的回调函数
  • errorCallback:可选,定位失败时执行的回调函数
  • positionOptions:可选,拥有三个可配置属性{enableHighAccuracy:boolean , timeout:long , maximumAge:long},用于控制定位精度,一般不用配置

demo代码如下:

        //获取用户当前位置
	if (isSupportGeo) {
		navigator.geolocation.getCurrentPosition(positionSuccess, positionError, { enableHighAccuracy: true });
	} else {
		$('.map').text('Your browser is out of fashion, there\'s no geolocation!');
	}

positionSuccess回调带有position数据,核心的数据有longitude(经度)、latitude(维度)、accuracy(精确度)。

来看下positionSuccess这个回调函数代码:

    /**
     * 获取地理信息成功后执行的回调函数
     * @param position 位置信息
     */
     function positionSuccess(position) {
                //纬度
		var lat = position.coords.latitude;
                //经度
	 	var lng = position.coords.longitude;
                 //以米为单位的经度和纬度的精确度
		var acr = position.coords.accuracy;
      }

想要把坐标定位到地图上还需要使用 leaflet的API(google map也是可以的)。

leaflet

leaflet是相当不错的地图库,使用起来非常简单。

在页面中引入leaflet.js


leaflet会添加 L全局变量,包含所有的API。

leaflet api的使用

点此进入API文档。内容很多,本文只用到核心的几个方法。

使用 L.marker()定位坐标

     function positionSuccess(position) {
                //纬度
		var lat = position.coords.latitude;
                //经度
	 	var lng = position.coords.longitude;
                 //以米为单位的经度和纬度的精确度
		var acr = position.coords.accuracy;

		// 定位用户坐标
		var userMarker = L.marker([lat, lng], {
			icon: redIcon
		});

		// demo
		// userMarker = L.marker([51.45, 30.050], { icon: redIcon });
      }

L.marker()第一个参数为坐标,第二个参数可选,demo中,我们自定义了定位坐标时使用的icon样式:

定义icon,比较麻烦,需要使用 L.Icon接口。

	// 自定义坐标定位样式
	var tinyIcon = L.Icon.extend({
		options: {
			shadowUrl: '../assets/marker-shadow.png',
			iconSize: [25, 39],
			iconAnchor:   [12, 36],
			shadowSize: [41, 41],
			shadowAnchor: [12, 38],
			popupAnchor: [0, -30]
		}
	});
	var redIcon = new tinyIcon({ iconUrl: '../assets/marker-red.png' });

通过 iconUrl配置icon图片的位置。

接下来加载leaflet的地图,使用 map()方法。

		// 加载地图
		map = L.map('map');

第一个参数为地图容器id,对应:

  
  
  
  
  

map()是最核心的方法,拥有丰富的配置项,详细可以看 文档,比如:

var map = L.map('map', {
    //地图中心点配置
    center: [51.505, -0.09],
    //放大倍数
    zoom: 13
});

使用 L.tileLayer()配置地图瓦片图层的图片地址。

一张地图并不是完整的一张图片,而是有多张图片拼接而成的,我们将这些小图片称为瓦片图层,即 tileLayer

L.tileLayer('http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png', { maxZoom: 18, detectRetina: true }).addTo(map);

重点解释下 http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png,这个路径其实是图片路径模版,可以通过调试工具看下地图图层的路径:

leaflet会自动将 {s}替换成a、b或c等组成2级域名, {z}为放大等级, {x}{y}为坐标。

接下来配置地图容器填充满整个世界。(容器内显示世界地图)

map.fitWorld();

将定位坐标添加到地图内:

		userMarker.addTo(map);

leaflet可以给定位坐标icon添加个弹出层,显示指定的内容:

		userMarker.bindPopup('你在这里,你的id是 ' + userId).openPopup();

userId为随机id。

完整的地图定位代码

html部分代码如下:


  
  
  
  
  

js部分代码如下:

	// 自定义坐标定位样式
	var tinyIcon = L.Icon.extend({
		options: {
			shadowUrl: '../assets/marker-shadow.png',
			iconSize: [25, 39],
			iconAnchor:   [12, 36],
			shadowSize: [41, 41],
			shadowAnchor: [12, 38],
			popupAnchor: [0, -30]
		}
	});
	var redIcon = new tinyIcon({ iconUrl: '../assets/marker-red.png' });
    /**
     * 浏览器是否支持 geolocation api
     * @return Boolean
     */
    function isSupportGeo(){
        var isSupport = false;
        if (navigator.geolocation) {
            isSupport = true;
        } else {
            isSupport = false;
            console.log('浏览器不支持geolocation');
        }
        return isSupport;
    }
    //获取用户当前位置
	if (isSupportGeo) {
		navigator.geolocation.getCurrentPosition(positionSuccess, positionError, { enableHighAccuracy: true });
	} else {
		$('.map').text('Your browser is out of fashion, there\'s no geolocation!');
	}
    /**
     * 获取地理信息成功后执行的回调函数
     * @param position 位置信息
     */
	function positionSuccess(position) {
        //纬度
		var lat = position.coords.latitude;
        //经度
		var lng = position.coords.longitude;
        //以米为单位的经度和纬度的精确度
		var acr = position.coords.accuracy;

		// 定位用户坐标
		var userMarker = L.marker([lat, lng], {
			icon: redIcon
		});
		// demo
		// userMarker = L.marker([51.45, 30.050], { icon: redIcon });

		// 加载地图
		map = L.map('map');

		// 配置地图瓦片图层的图片地址
		L.tileLayer('http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png', { maxZoom: 18, detectRetina: true }).addTo(map);

		// 配置地图容器填充满整个世界
		map.fitWorld();

		userMarker.addTo(map);
		userMarker.bindPopup('你在这里,你的id是 ' + userId).openPopup();
	}

你可能感兴趣的:(JavaScript,nodejs,geolocation)