HTML5 Geolocation API : 实时跟踪应用

getCurrentPosition与watchPosition

 

watchPosition会监视你的移动,并在位置改变时向你报告位置。watchPPosition方法看上去确实与getCurrentPosition方法很像,不过行为稍有不同,每次位置比阿奴啊时会重复调用你的成功处理程序

watchPosition调用步骤:

  1. 你的应用watchPosition,传入一个成功处理函数
  2. watchPosition在后台不断监视你的位置
  3. 你的位置改变时,watchPostion调用成功处理函数来报告你的新位置
  4. watchPostion继续监视你的位置(并向成功处理程序报告),直至你调用clearWatch将它清除

 

HTML代码

 

我们已HTML5COL学院中级课程相关章节的课程为基础,再向HTML增加几个按钮,从而能开始和结束跟踪你的位置;我们设置开始按钮是因为用户不想一直被跟踪,他们通常希望对此有些控制;设置结束按钮,是考虑到对于移动设备来说,不停检查用户的位置是一个相当耗费电的操作,如果一直打开跟踪,会严重影响电池寿命:

注: 实时跟踪用户可能非常耗电。一定要为用户提供信息,指出日前正在跟踪,另外还要提供相应的一些控件

<!DOCTYPE html>
<html>
<head>
<meta='keywords' content='HTML5COL学院,HTML5COL,CSS3,HTML5COL,编码社区'>
<script>
<!--script代码,见HTML5COL学院的应用课程:Geolocation API应用:计算两地距离--->
</script>
</head>

<body>
   
   <form>
   <input type="button" id="watch" value="Watch%20me">
   <input type="button" id="clearWatch" value="Clear%20watch">
   </form>

   <p>position:</p>
   <div id="location" >
   </div>
   
   <div id="distance" >
   </div>
</body>

</html>

代码释义: 我们增加了一个表单元素,其中包括两个按钮,一个用来启动监视,id为’watch’,另一个用来清除监视,id为’clearwatch’;并且 我们用原来的

报告实时位置

为按钮添加程序

只有在支持地理定位情况下我们才会在getMyLocation函数中增加按钮点击处理程序。另外,由于要用两个按钮控制所有地理位置定位跟踪,所以要从getMyLocation删除现在的getCurrentPosition调用。下面删除这个代码,再增加两个处理程序:watchPostion对应监视按钮,clearWatch对应清除按钮:

function getMyLocation() {
	if (navigator.geolocation) {
		var watchButton = document.getElementById("watch");
		watchButton.onclick = watchLocation;
		var clearWatchButton = document.getElementById("clearWatch");
		clearWatchButton.onclick = clearWatch;
	}
	else {
		alert("Oops, no geolocation support");
	}
}

代码释义: 如果浏览器支持地理定位,则我们会增加按钮点击处理程序;如果不支持地理定位,则增加这些处理程序毫无意义;上述代码中我们调用watchLocation来启动监视,调用clearWatch停止监视

 

编写watchLocation处理程序

 

目前,我们要做的工作是:用户点击监视按钮时,他们希望开始跟踪他们的位置。所以我们将使用geolocation.watchPosition方法开始监视他们的位置。geolocation.watchPosition方法有有两个参数程序:一个成功处理程序和一个错误处理程序,所以我们将使用原来已有的两个处理程序。它还会返回一个watchId,可以在任何时刻使用这个id取消监视行为。我们把这个watchId放在一个全局变量中,为清除按钮编写点击处理程序时会用到这个变量。一下是watchLocation函数和watchId的代码:

var watchId = null;
function watchLocation() {
	watchId = navigator.geolocation.watchPosition(
					displayLocation, 
					displayError);
}

代码释义: 在文件最上面增加watchId作为一个全局变量。我们把它初始化为null,以后还需要把这个变量清除监视;调用watchLocation方法,传入前面编写的成功处理程序displayLocation和现有的错误处理程序displayError

 

编写watchLocation处理程序

 

现在来编写处理程序清除监视行为。为此需要得到watchId,并把它传递到geolocation.clearWatch方法

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

最后,对displayLocation做小的修改

 

还需要做一个很小的修改,设计前面编写的Google Maps代码。在这代码中,我们调用了showMap来显示Google Map。showMap会在页面中创建一个地图,这件事你只希望做一次。不过,要记住,开始用watchPosition监视你的位置时,每次位置有更新时都会调用displayLocation

要确保只调用一次showMap,首先查看这个地图是否存在,如果不存在,则调用showMap。否则,说明showMap已经调用过(而且已经创建了地图),所以不需要再调用这个函数了:

function displayLocation(position) {
	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)";

	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); 
		//如果还没有调用showMap,则调用这个函数,否则不需要每次调用displayLocation时都调用showMap
	}
}

确保您使用的是移动设备

 

当您离开HTML5COL学院大门时,您一直在移动,所以为了监控您的行踪,一台设备是必须的;

综合代码展示;

 

基本HTML代码;

<!doctype html>
<html>
<head>
<title>Wherever you go, there you are</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
<meta charset="utf-8">
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="myLoc.js"></script>
<link rel="stylesheet" href="myLoc.css">
</head>
<body>

<form>
<input type="button" id="watch" value="Watch%20me">
<input type="button" id="clearWatch" value="Clear%20watch">
</form>

<div id="location">
Your location will go here.
</div>

<div id="distance">
Distance from HTML5COL OFFICE will go here.
</div>

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

</body>
</html>

myLoc.js代码;

/* myLoc.js */

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

window.onload = getMyLocation;

function getMyLocation() {
	if (navigator.geolocation) {
		var watchButton = document.getElementById("watch");
		watchButton.onclick = watchLocation;
		var clearWatchButton = document.getElementById("clearWatch");
		clearWatchButton.onclick = clearWatch;
	}
	else {
		alert("Oops, no geolocation support");
	}
}

function displayLocation(position) {
	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)";

	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);
	}
}


// --------------------- Ready Bake ------------------
//
// Uses the Spherical Law of Cosines to find the distance
// between two lat/long points
//
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 = 6371; // radius of the Earth in km
	var distance = Math.acos(Math.sin(startLatRads) * Math.sin(destLatRads) + 
					Math.cos(startLatRads) * Math.cos(destLatRads) *
					Math.cos(startLongRads - destLongRads)) * Radius;

	return distance;
}

function degreesToRadians(degrees) {
	radians = (degrees * Math.PI)/180;
	return radians;
}

// ------------------ End Ready Bake -----------------

function showMap(coords) {
	var googleLatAndLong = new google.maps.LatLng(coords.latitude, 
												  coords.longitude);
	var mapOptions = {
		zoom: 10,
		center: googleLatAndLong,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};
	var mapDiv = document.getElementById("map");
	map = new google.maps.Map(mapDiv, mapOptions);

	// add the user marker
	var title = "Your Location";
	var content = "You are here: " + coords.latitude + ", " + coords.longitude;
	addMarker(map, googleLatAndLong, title, content);
}

function addMarker(map, latlong, title, content) {
	var markerOptions = {
		position: latlong,
		map: map,
		title: title,
		clickable: true
	};
	var marker = new google.maps.Marker(markerOptions);

	var infoWindowOptions = {
		content: content,
		position: latlong
	};

	var infoWindow = new google.maps.InfoWindow(infoWindowOptions);

	google.maps.event.addListener(marker, 'click', function() {
		infoWindow.open(map);
	});
}


function displayError(error) {
	var errorTypes = {
		0: "Unknown error",
		1: "Permission denied",
		2: "Position is not available",
		3: "Request timeout"
	};
	var errorMessage = errorTypes[error.code];
	if (error.code == 0 || error.code == 2) {
		errorMessage = errorMessage + " " + error.message;
	}
	var div = document.getElementById("location");
	div.innerHTML = errorMessage;
}

//
// Code to watch the user's location
//
function watchLocation() {
	watchId = navigator.geolocation.watchPosition(
					displayLocation, 
					displayError);
}

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

测试地址: 在线测试

原文:http://www.html5col.com/watchposition_apply/