Determining Geological Position Using HTML5 and JavaScriptThis tutorial will teach you a quick way to determine how far you've traveled in a certain amount of time, without the use of a GPS navigation system or satellites. Using the power of the HTML5 Geolocation service, you can create a website that tracks how far you have traveled from where the site was originally loaded. Although less useful on a desktop computer, this page is ideal for the millions of web-enabled phones that ship with HTML5 enabled browsers today.

This script works by using the watchPosition() capability. Every time a new position is sent to the script, we will compare it to the last known position and calculate the distance traveled. This is accomplished using a well-known calculation known as the Haversine formula, which allows us to calculate distance between two longitude and latitude positions on a sphere. If you're hoping to learn how the Haversine formula works, you'll be fairly disappointed. Instead, we'll present you a JavaScript implementation of the formula, which is shown below:

function toRadians(degree) { 
 return degree * Math.PI / 180; 
} 
 
function distance(latitude1, longitude1, latitude2, longitude2) { 
 // R is the radius of the earth in kilometers 
 var R = 6371;  
 
 var deltaLatitude = toRadians(latitude2-latitude1); 
 var deltaLongitude = toRadians(longitude2-longitude1); 
 latitude1 =toRadians(latitude1); 
 latitude2 =toRadians(latitude2); 
 
 var a = Math.sin(deltaLatitude/2) * 
   Math.sin(deltaLatitude/2) + 
   Math.cos(latitude1) * 
   Math.cos(latitude2) * 
   Math.sin(deltaLongitude/2) * 
   Math.sin(deltaLongitude/2); 
 
 var c = 2 * Math.atan2(Math.sqrt(a), 
 Math.sqrt(1-a)); 
 var d = R * c; 
 return d; 
}

For the sake of simplicity, we have written a conversion from degrees to radians, and we provided a distance() function to calculate the distance between two latitude and longitude position values. If we check the user's position and calculate the distance traveled at frequent and regular intervals it gives a reasonable approximation of distance traveled over time. This assumes that the user is moving in a straight direction during each interval, but we'll make that assumption for the sake of this tutorial.

Let's create the HTML display. We will keep it simple for this exercise because the real interest is in the script driving the data. We display a simple table with rows for latitude, longitude, accuracy, and a timestamp in milliseconds. In addition, we'll put a few status text indicators in place so that the user can see the summary of distance traveled

HTML 5 Code

<h1>HTML5 Geolocation Distance Tracker</h1>
 
 <p id="status">HTML5 Geolocation is <strong>not</strong> supported in your browser.</p>
 
<h2>Current Position:</h2>

<table border="1">

 <tr>
  <th width="40" scope="col">Latitude</th>
  <td width="114" id="latitude">?</td>
 </tr>

 <tr>
  <td> Longitude</td>
  <td id="longitude">?</td>
 </tr>

 <tr>
  <td>Accuracy</td>
  <td id="accuracy">?</td>
 </tr>

 <tr>
  <td>Last Timestamp</td>
  <td id="timestamp">?</td>
 </tr>
 
</table> 
 
<h4 id="currDist">Current distance traveled: 0.0 km</h4>
<h4 id="totalDist">Total distance traveled: 0.0 km</h4>

These table values are all set to default for now and are populated once data starts flowing into the application. In our first JavaScript code section we've set a handler—loadDemo() - that will execute as soon as the page completes loading. This script will detect if HTML5 Geolocation is supported in the browser and use a handy utility to change the status message on the page to indicate what it finds. It will then request a watch of the user's position, as shown below:

The Script

var totalDistance = 0.0; 
var lastLat; 
var lastLong; 
function updateStatus(message) { 
 document.getElementById("status").innerHTML = message; 
} 
 
function loadDemo() { 
 if(navigator.geolocation) { 
  updateStatus("HTML5 Geolocation is supported in your browser."); 
  navigator.geolocation.watchPosition(updateLocation, 
  handleLocationError, 
  {maximumAge:20000}); 
 } 
} 
 
window.addEventListener("load", loadDemo, true);

For error handling, we'll use the same routine we identified earlier, as it is generic enough to work for our distance tracker in it, we will check the error code of any error we receive and update the status message on the page:

function handleLocationError(error) { 
 switch (error.code) { 
  case 0: 
   updateStatus("There was an error while retrieving your location: " + error.message); 
   break; 

  case 1: 
   updateStatus("The user prevented this page from retrieving a location."); 
   break; 

  case 2: 
   updateStatus("The browser was unable to determine your location: " + error.message);
   break; 

  case 3: 
   updateStatus("The browser timed out before retrieving the location."); 
   break; 
 }
} 

Note also that we are setting a maximumAge option on our position watch: {maximumAge:20000}. This will tell the location service that we don't want any cached location values that are greater than 20 seconds (or 20000 milliseconds) old. Setting this option will keep our page updating at regular intervals, but feel free to adjust this number and experiment with larger and smaller cache sizes. The bulk of our work will be done in our updateLocation() function. Here we will update the page with our most recent values and calculate the distance traveled:

function updateLocation(position) { 
        var latitude = position.coords.latitude; 
        var longitude = position.coords.longitude; 
        var accuracy = position.coords.accuracy; 
        var timestamp = position.timestamp; 
 
        document.getElementById("latitude").innerHTML = latitude; 
        document.getElementById("longitude").innerHTML = longitude; 
        document.getElementById("accuracy").innerHTML = accuracy; 
  document.getElementById("timestamp").innerHTML = timestamp;                         

As you might expect, the first thing we will do when we receive an updated set of position coordinates is to record all the information. We gather the latitude, longitude, accuracy, and timestamp, and then update the table values with the new data.

You might not choose to display a timestamp in your own application. The timestamp number used here is in a form primarily useful to computers, which won't be meaningful to an end user. Feel free to replace it with a more user-friendly time indicator or remove it altogether. The accuracy value is given to us in meters and might at first seem unnecessary. However, any data depends on its accuracy. Even if you don't present the user with the accuracy values, you should take them into account in your own code. Presenting inaccurate values could give the user a skewed idea of his or her location. Therefore, we will throw out any position updates with an unreasonably low accuracy. Insert the script portion below to do just that:

// sanity test... don't calculate distance if accuracy 
  // value too large 
  if (accuracy >= 500) { 
   updateStatus("Need more accurate values to calculate distance."); 
   return; 
  }


Finally, we will calculate the distance traveled, assuming that we have already received at least one accurate position value before. We will update the totals of travel distance and display them for the user, and we will store the current values for future comparison. To keep our interface a little less cluttered, it is a good idea to round or truncate the calculated values using this code:

// calculate distance 

 if ((lastLat !== null) && (lastLong !== null)) {
  var currentDistance = distance(latitude, longitude, lastLat, lastLong); 
  document.getElementById("currDist").innerHTML = "Current distance traveled: " + currentDistance.toFixed(4) + " km"; 
  totalDistance += currentDistance; 
  document.getElementById("totalDist").innerHTML = "Total distance traveled: " + totalDistance.toFixed(4) + " km"; 
 } 
 
 lastLat = latitude; 
 lastLong = longitude; 
 updateStatus("Location successfully updated."); 

} // end of updateLocation


The Final code should look similar to:

<!DOCTYPE html>
<html>
 <title>HTML5 Geolocation Odometer</title>
 
 <h1>HTML5 Geolocation Distance Tracker</h1>
 
 <p id="status">HTML5 Geolocation is not supported in your browser.</p>
 
 <h2>Current Position:</h2>
 
 <table border="1">
  <tr>
   <th width="40" scope="col">Latitude</th>
   <td width="114" id="latitude">?</td>
  </tr>
  
  <tr>
   <td>Longitude</td> 
   <td id="longitude">?</td>
  </tr>

  <tr>
   <td>Accuracy</td>
   <td id="accuracy">?</td>
  </tr>

  <tr>
   <td>Last Timestamp</td>
   <td id="timestamp">?</td>
  </tr>
 </table>
 
 <h4 id="currDist">Current distance traveled: 0.0 km</h4>
 <h4 id="totalDist">Total distance traveled: 0.0 km</h4>
 
 <script type="text/javascript">
  var totalDistance = 0.0; 
  var lastLat; 
  var lastLong; 
 
  function toRadians(degree) { 
   return degree * Math.PI / 180; 
  } 
 
  function distance(latitude1, longitude1, latitude2, longitude2) { 
   // R is the radius of the earth in kilometers 
   var R = 6371;  
   var deltaLatitude = toRadians(latitude2-latitude1); 
   var deltaLongitude = toRadians(longitude2-longitude1); 
   latitude1 = toRadians(latitude1); 
   latitude2 = toRadians(latitude2); 
 
   var a = Math.sin(deltaLatitude/2) * 
    Math.sin(deltaLatitude/2) + 
    Math.cos(latitude1) * 
    Math.cos(latitude2) * 
    Math.sin(deltaLongitude/2) * 
    Math.sin(deltaLongitude/2); 
 
   var c = 2 * Math.atan2(Math.sqrt(a), 
   Math.sqrt(1-a)); 
   var d = R * c; 
   return d; 
  } 
 
 
  function updateStatus(message) { 
   document.getElementById("status").innerHTML = message; 
  } 
 
  function loadDemo() { 
   if(navigator.geolocation) { 
    updateStatus("HTML5 Geolocation is supported in your browser."); 
    navigator.geolocation.watchPosition(updateLocation, 
      handleLocationError, 
      {maximumAge:20000}); 
   } 
  } 
 
  window.addEventListener("load", loadDemo, true); 
 
  function updateLocation(position) { 
   var latitude = position.coords.latitude; 
   var longitude = position.coords.longitude; 
   var accuracy = position.coords.accuracy; 
   var timestamp = position.timestamp; 
 
   document.getElementById("latitude").innerHTML = latitude; 
   document.getElementById("longitude").innerHTML = longitude; 
   document.getElementById("accuracy").innerHTML = accuracy; 
   document.getElementById("timestamp").innerHTML = timestamp; 
 
   // sanity test... don't calculate distance if accuracy 
   // value too large 
   if (accuracy >= 500) { 
    updateStatus("Need more accurate values to calculate distance."); 
    return; 
   } 
   
   // calculate distance 
   if ((lastLat !== null) && (lastLong !== null)) { 
    var currentDistance = distance(latitude, longitude, lastLat, lastLong); 
    document.getElementById("currDist").innerHTML = "Current distance traveled: " 
     + currentDistance.toFixed(4) + " km";
    totalDistance += currentDistance; 
  
    document.getElementById("totalDist").innerHTML = 
     "Total distance traveled: " + totalDistance.toFixed(4) + " km"; 
   } 
  
   lastLat = latitude; 
   lastLong = longitude; 
  
   updateStatus("Location successfully updated."); 
  } 
 
  function handleLocationError(error) { 
   switch (error.code) { 
    case 0: 
     updateStatus("There was an error while retrieving your location: " +  
     error.message); 
     break; 

    case 1: 
     updateStatus("The user prevented this page from retrieving a location."); 
     break; 

    case 2: 
     updateStatus("The browser was unable to determine your location: " +  
     error.message); 
     break; 

    case 3: 
     updateStatus("The browser timed out before retrieving the location."); 
    break; 
   } 
  } 
 </script>
</html>

Save to a HTML file, upload to a web server and load that page from your IPhone for example, as you change location you will see the update, and the great thing about it, it will work as long as you have internet access, in places where GPS don't work.

Demo - Geolocation Distance Tracker

HTML5 Geolocation Distance Tracker
HTML5 Geolocation is not supported in your browser.

Current Position:

Latitude ?
Longitude ?
Accuracy ?
Last Timestamp ?

Current distance traveled: 0.0 km

Total distance traveled: 0.0 km


Guest Author
Bill KilpatrickThis post was provided by Bill Kilpatrick, Marketing Manager at Spotted Frog Design, a web design and SEO company in Philadelphia.

No comments :

Post a Comment