Brian Cray ··· Home > Blog > Javascript > How to calculate distance with javascript and Google Maps API

How to calculate distance with javascript and Google Maps API

This article focuses on straight line distance. If you're looking for driving distance then read my newest tutorial: How to calculate driving distance with Google Maps API.

To make your location-sensitive web app truly valuable, you'll need to be ready to answer these questions:

Unfortunately, how to actually calculate distances has been somewhat elusive for many developers.

Until now.

What I've built for you here is a javascript/Google Maps-driven web app that will take two fuzzy locations/addresses, turn them into full addresses and coordinates, and calculate the distance in miles and kilometers between them. So again, input two fuzzy address and output full addresses and distance. Sounds like a win for the you and your users.

Let's step through the code to see how I did it. If you don't want to learn about the code, go ahead and see the end result with source code.

The HTML

The HTML is pretty basic, but there are a few things to note:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Google Maps JavaScript API Example: Extraction of Geocoding Data</title>
    <script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAA7j_Q-rshuWkc8HyFI4V2HxQYPm-xtd00hTQOC0OXpAMO40FHAxT29dNBGfxqMPq5zwdeiDSHEPL89A" type="text/javascript"></script>
<!-- According to the Google Maps API Terms of Service you are required display a Google map when using the Google Maps API. see: http://code.google.com/apis/maps/terms.html -->
  </head>

  <body onload="initialize()">

    <form action="#" onsubmit="showLocation(); return false;">
      <p>
        <input type="text" name="address1" value="Address 1" class="address_input" size="40" />
        <input type="text" name="address2" value="Address 2" class="address_input" size="40" />
        <input type="submit" name="find" value="Search" />
      </p>
    </form>
    <p id="results"></p>

  </body>
</html>

Now let's look at the javascript, where the real magic happens. We'll look at the javascript in more detail than we did with the HTML.

Stepping through the Javascript

If you'd like skip the steps to the complete javascript code

First we'll define global variables used in more than one function

var geocoder, location1, location2;

Next we'll define our <body> onload event which prepares the Google Maps API for our requests.

function initialize() {
    geocoder = new GClientGeocoder();
}

Next we'll define showLocation(), which is called when the user submits the form with the two fuzzy addresses. Here's the steps it goes through:

  1. Attempt to get the first location's information from the Google Maps API;
  2. Put the first location's information including lat, lon, and full address into an object called location1;
  3. Attempt to get the second location's information from the Google Maps API;
  4. Put the second location's information including lat, lon, and full address into an object called location2;
  5. Call calculateDistance()
function showLocation() {
    geocoder.getLocations(document.forms[0].address1.value, function (response) {
        if (!response || response.Status.code != 200)
        {
            alert("Sorry, we were unable to geocode the first address");
        }
        else
        {
            location1 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
            geocoder.getLocations(document.forms[0].address2.value, function (response) {
                if (!response || response.Status.code != 200)
                {
                    alert("Sorry, we were unable to geocode the second address");
                }
                else
                {
                    location2 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
                    calculateDistance();
                }
            });
        }
    });
}

Finally calculateDistance() calculates the distance based on the Great Circle Distance uses Google's distanceFrom() method to calculate the distance in miles and kilometers between the two latitude and longitudes. Then it outputs the full addresses and distances to <p id="results">.

function calculateDistance()
{
    try
    {
        var glatlng1 = new GLatLng(location1.lat, location1.lon);
        var glatlng2 = new GLatLng(location2.lat, location2.lon);
        var miledistance = glatlng1.distanceFrom(glatlng2, 3959).toFixed(1);
        var kmdistance = (miledistance * 1.609344).toFixed(1);

        document.getElementById('results').innerHTML = '<strong>Address 1: </strong>' + location1.address + '<br /><strong>Address 2: </strong>' + location2.address + '<br /><strong>Distance: </strong>' + miledistance + ' miles (or ' + kmdistance + ' kilometers)';
    }
    catch (error)
    {
        alert(error);
    }
}

Completed Javascript

var geocoder, location1, location2;

function initialize() {
    geocoder = new GClientGeocoder();
}

function showLocation() {
    geocoder.getLocations(document.forms[0].address1.value, function (response) {
        if (!response || response.Status.code != 200)
        {
            alert("Sorry, we were unable to geocode the first address");
        }
        else
        {
            location1 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
            geocoder.getLocations(document.forms[0].address2.value, function (response) {
                if (!response || response.Status.code != 200)
                {
                    alert("Sorry, we were unable to geocode the second address");
                }
                else
                {
                    location2 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
                    calculateDistance();
                }
            });
        }
    });
}
    
function calculateDistance()
{
    try
    {
        var glatlng1 = new GLatLng(location1.lat, location1.lon);
        var glatlng2 = new GLatLng(location2.lat, location2.lon);
        var miledistance = glatlng1.distanceFrom(glatlng2, 3959).toFixed(1);
        var kmdistance = (miledistance * 1.609344).toFixed(1);

        document.getElementById('results').innerHTML = '<strong>Address 1: </strong>' + location1.address + '<br /><strong>Address 2: </strong>' + location2.address + '<br /><strong>Distance: </strong>' + miledistance + ' miles (or ' + kmdistance + ' kilometers)';
    }
    catch (error)
    {
        alert(error);
    }
}

Advanced javascript developers: If you want to, feel free to put the above code into an external javascript file.

All of the source code together in one working file

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Google Maps JavaScript API Example: Extraction of Geocoding Data</title>
    <script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAA7j_Q-rshuWkc8HyFI4V2HxQYPm-xtd00hTQOC0OXpAMO40FHAxT29dNBGfxqMPq5zwdeiDSHEPL89A" type="text/javascript"></script>
<!-- According to the Google Maps API Terms of Service you are required display a Google map when using the Google Maps API. see: http://code.google.com/apis/maps/terms.html -->
    <script type="text/javascript">

    var geocoder, location1, location2;

    function initialize() {
        geocoder = new GClientGeocoder();
    }

    function showLocation() {
        geocoder.getLocations(document.forms[0].address1.value, function (response) {
            if (!response || response.Status.code != 200)
            {
                alert("Sorry, we were unable to geocode the first address");
            }
            else
            {
                location1 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
                geocoder.getLocations(document.forms[0].address2.value, function (response) {
                    if (!response || response.Status.code != 200)
                    {
                        alert("Sorry, we were unable to geocode the second address");
                    }
                    else
                    {
                        location2 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
                        calculateDistance();
                    }
                });
            }
        });
    }
    
    function calculateDistance()
    {
        try
        {
            var glatlng1 = new GLatLng(location1.lat, location1.lon);
            var glatlng2 = new GLatLng(location2.lat, location2.lon);
            var miledistance = glatlng1.distanceFrom(glatlng2, 3959).toFixed(1);
            var kmdistance = (miledistance * 1.609344).toFixed(1);

            document.getElementById('results').innerHTML = '<strong>Address 1: </strong>' + location1.address + '<br /><strong>Address 2: </strong>' + location2.address + '<br /><strong>Distance: </strong>' + miledistance + ' miles (or ' + kmdistance + ' kilometers)';
        }
        catch (error)
        {
            alert(error);
        }
    }

    </script>
  </head>

  <body onload="initialize()">

    <form action="#" onsubmit="showLocation(); return false;">
      <p>
        <input type="text" name="address1" value="Address 1" class="address_input" size="40" />
        <input type="text" name="address2" value="Address 2" class="address_input" size="40" />
        <input type="submit" name="find" value="Search" />
      </p>
    </form>
    <p id="results"></p>

  </body>
</html>

The end result

Your hard work has paid off! See the end result with source code

Google Terms of Service Warning: According to the Google Maps API Terms of Service you are required display a Google map when using the Google Maps API.