Getting direction from a location via HTML5 Geolocation


Getting direction from a location via HTML5 Geolocation

Recipe ID: hsts-r66


In this tutorial, our goal is to show you how to get directions from the user’s current location to a specific address. In doing so, we use the Google Maps API to display the route the same way the Google Maps website would, and give the user the option to output the distance in miles or kilometers.

Important: to follow through this tutorial, you may need to make minor adjustments to the JS codes as the latest version of Google API might be different.

 

Use the jQuery and Google Maps JavaScript API V3 libraries:
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="http://j.maxmind.com/app/geoip.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js">
</script>


In this tutorial, we have a simple HTML code with a drop-down box to select miles or kilometers. Also, instead of appending our results to the page body, we will add a div to hold the calculated distance and a div to hold the Google Map:

<div class="field">
<label for="address">Enter a Destination Address:</label>
<input type="text" id="address" />
</div>
<div class="field">
<label for="units">Units:</label>
<select id="units">
<option value="IMPERIAL">Miles</option>
<option value="METRIC">Kilometers</option>
</select>
</div>

<div>
<input type="button" id="go" value="Get Directions" />
</div>

<div id="distance"></div>

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

We now need some JavaScript to do the following:

// Google Maps globals:
var directionRenderer;
var directionsService  =  new  google.maps.DirectionsService();  var map;

$(document).ready(function () {

// Set up map starting point for Google Maps.
// Set initial coords to latitude −92 and longitude 32, which is somewhere
// around Kansas City in the center of the US, and then set the zoom to 4
// so the entire US  is visible  and  centered. var kansas = new google.maps.LatLng(32, −92); var myOptions = {
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP, center: kansas
}
map = new google.maps.Map(document.getElementById("map"), myOptions); directionsRenderer = new google.maps.DirectionsRenderer(); directionsRenderer.setMap(map);

// wire up button click
$('#go').click(function () {
// Use our new getLatLng with fallback and define an inline function to
// handle the callback.
getLatLng(function (latitude, longitude, isMaxMind) {
// set the starting point
var start = new google.maps.LatLng(latitude, longitude);

// get the address the user entered var address = $('#address').val(); if (address) {
// set end point
var end = $('#address').val();

// set the request options var request = {
origin: start, destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};

// make the directions request directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {

// Display the directions using Google's Directions
// Renderer. directionsRenderer.setDirections(result);

// output total distance separately
var distance = getTotalDistance(result);
// output either miles or km var units = $('#units').val(); if (units == 'IMPERIAL') {
$('#distance').html('Total Distance: <strong>' + metersToMiles(distance) + '</strong> miles');
} else {
$('#distance').html('Total Distance: <strong>' + metersToKilometers(distance) + '</strong> km');
}

}  else {
error("Directions failed due to: " + status);
}
});

}
else {
error('Please enter an address');
}

// if we used MaxMind for location, add attribution link if (isMaxMind) {
$('body').append('<p><a href="http://www.maxmind.com" target="_blank">IP to Location Service Provided by MaxMind</a></p>');

 

});
}
});

});

function getLatLng(callback) {
// test for presence of geolocation
if (navigator && navigator.geolocation) {
// make the request for the user's position navigator.geolocation.getCurrentPosition(function (position) {
// success handler
callback(position.coords.latitude, position.coords.longitude);
},
function (err) {
// handle the error by passing the callback the location from MaxMind callback(geoip_latitude(), geoip_longitude(), true);
});
} else {
// geolocation not available, so pass the callback the location from
// MaxMind
callback(geoip_latitude(), geoip_longitude(), true);
}
}

// return total distance in meters function getTotalDistance(result) {
var meters = 0;
var route = result.routes[0];
for (ii = 0; ii < route.legs.length; ii++) {
// Google stores distance value in meters meters += route.legs[ii].distance.value;
}
return meters;
}

function metersToKilometers(meters) { return Math.round(meters / 1000);
}

function metersToMiles(meters) {
// 1 mile = 1609.344 meters
return Math.round(meters / 1609.344);
}

function error(msg) { alert(msg);
}

 

How it Works

To build out the solution, start by defining three global variables that are used to communicate with the Google API and to update our map div.

When the document loads, set the map of the US to be displayed. The Google Map object represents a map on your web page (you can have more than one).

Create a Map object by calling new google.maps.Map(document.getElementById("map"), myOptions), passing in the HTML element where you want to display the map and a    Map options object.

There are many options that can be set, but the three used for this solution are zoom, mapTypeId, and center. The options are fairly descriptive as to their purpose. Set zoom  to 4 to allow the user to see the entire US. For the mapTypeId, use ROADMAP, which displays the normal, default 2D tiles of Google Maps. The other options are SATELLITE,  HYBRID, and TERRAIN. The center option indicates the location that is displayed in the center of the map.

The latitude and longitude of Kansas, which is a central location in the US, are hard- coded to create a LatLng object that can be used to set the center parameter. When the Map object is created using the new keyword it, automatically updates our map div.

The next line, directionsRenderer = new google.maps.DirectionsRenderer();, creates a new DirectionsRenderer object that can automatically update Maps for us. The line directionsRenderer.setMap(map); doesn’t do anything yet, but it tells the user to enter an address and click the button.

In this example, refactored logic does a geolocation fallback in order to be a little more compact and reusable:
function getLatLng(callback) {
// test for presence of geolocation
if (navigator && navigator.geolocation) {
// make the request for the user's position navigator.geolocation.getCurrentPosition(function (position) {
// success handler
callback(position.coords.latitude, position.coords.longitude);
},
function (err) {
// handle the error by passing the callback the location from MaxMind callback(geoip_latitude(), geoip_longitude(), true);
});
} else {
// geolocation not available, so pass the callback the location from
// MaxMind
callback(geoip_latitude(), geoip_longitude(), true);
}
}


The getLatLng() function takes a single callback parameter that returns the latitude, longitude, and isMaxMind variables.

We check for the existence of navigator.geolocation just like we did before, but this time we define the navigator.geolocation callback handlers inline to call our common callback function. That returns either the results of getCurrentPosition() or the Max-Mind latitude and longitude.

For the button-click handler in the main example, we start by using the new get LatLng() function to collect the user’s current location, which then is used to create a new LatLng object that we store in the start variable.

Next, we collect the address and store the text as a string in the end variable. To get the directions, we use the DirectionsService object that was created and stored into the global variable directionsService. The route() method of  the  DirectionsService  object takes a DirectionsRequest object parameter and a callback method. The DirectionsRequest object supports many options, but for this solution we only need to set the origin, destination, and travelMode options.

The origin and destination options can be either strings like the end variable, or the LatLng values. We set the travelMode option to DRIVING (the other options are WALKING or BICYCLING).

The route() method executes asynchronously, so we define a callback function that is passed a DirectionsResult object and a status code. We check the status variable to make sure the route() method finished successfully and then pass the result object to the DirectionsRenderer object, which updates the map with a highlighted driving route between our start and end locations.

To give you an idea of what is contained in the result variable, we pass it to the getTotalDistance() function, which is responsible for totaling the distance of the driving route. The result object contains a routes property, which is an array of Direc tionsRoute objects. Each route indicates a way to get from the start to the end location. Usually only one route is returned, unless you set the provideRouteAlternatives option to true.

Our getTotalDistance() function only looks at the first route. Each DirectionsRoute object contains multiple properties, but the property needed is legs, which is an array of DirectionsLeg objects that defines a single leg of the journey between the start and end locations.

If the route does not contain any waypoints, it only has a single leg. Since waypoints were not defined here, the results should have a single leg, but for good measure we loop through each leg anyway.

Like the route object, the leg object also contains multiple properties, but the only one we need to access is the distance property, which contains a DirectionsDistance object. The value property of the DirectionsDistance object gives the total distance of the leg in meters. The loop adds up the distance of each leg and returns the total in meters.

Finally, we check the value of the units drop-down to find out if the user wanted the total distance in miles or kilometers. Then we call one of our helper functions meter sToKilometers() or metersToMiles() to convert meters into kilometers or miles, respectively, and output the value to the distance div element.

 

Here is the list of other related tutorials that are highly recommended:



Here is the list of classes that are highly recommended:

 

Click here if you wish to learn more about training and career options available in the IT industry.


Private and Custom Tutoring

We provide private tutoring classes online and offline (at our DC site or your preferred location) with custom curriculum for almost all of our classes for $50 per hour online or $75 per hour in DC. Give us a call or submit our private tutoring registration form to discuss your needs.


View Other Classes!