Calculate Distance Using Javascript and Google Maps To Create A RealTime Quote Based On Distance

Calculate Distance Using Javascript and Google Maps To Create A RealTime Quote Based On Distance

Filed under News Blog, Tutorials

Written By : Kyle Bahr

EnlightenMental Productions was recently hired to create some custom quote functionality for a major international moving company.

Features:

  • Calculate distance from point A to point B (actual driving distance VS ‘as the crow flies‘)
  • Do some basic math to calculate an actual quote:
    • take distance and multiply by Price-Per-Mile depending on the size of the dwelling
    • add a one-time  administrative fee.
  • Calculate quickly and without redirecting the user to another page
  • Ability to scale and collect the data to a database or webform

Our first reaction was to explore current solutions and technologies that would help us achieve this without re-inventing the wheel, and once again, Google and their Maps API saves the day.

Setting up the code:

Since we’ll be using the Google Maps API to calculate the distance from two locations, first you’ll need to make sure you have an API Key. Note: Last we heard, Google requires that you display an actual map when using their API, so you can’t just use them for calculations.

The Javascript:

First we include the necessary libraries to run our API functions


<script src="http:/maps.google.com/maps?file=api&v=2&key=YOU_API_KEY_GOES_HERE" type="text/javascript"></script>

<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>

Next we setup the basic functions we will need to

  • Calculate Distance
  • Generate A Map from 2 Locations
  • Output out data and format for currencies if needed
  • Calculate price based on the data used

First we setup the variables we will use within our script


// setup the variables that encode and display the two locations
// this is for calculating distance between two points

    var geocoder, location1, location2;

// setup the map variables
// this is for displaying the two points on the map using the DirectionService() API Call

    var directionDisplay;
    var directionsService = new google.maps.DirectionsService();
    var map;

Next we create our initialize() function which displays our initial map location, and creates the canvas used to display our start and end location.


function initialize() {

// Initial map function
// this initiates the first map seen prior to calculating your selected locations

      directionsDisplay = new google.maps.DirectionsRenderer();

// default location is Chicago USA, perhaps change to your place of business?

      var chicago = new google.maps.LatLng(41.850033, -87.6500523);
      var myOptions = {
        zoom:7,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        center: chicago
      }
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    directionsDisplay.setMap(map);

    geocoder = new GClientGeocoder();

}

Now that our map is created, we can pass addresses to it and geo-encode the data to get proper latitude longitude data and render our map. Once we have the geo-encoded data, we can calculate an exact distance between the two locations.


function showLocation() {
		geocoder.getLocations(document.forms[0].address1.value, function (response) {
			if (!response || response.Status.code != 200) {
				alert("Sorry, your start addess is required");
			} 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, your end address is required");
					} else {
						location2 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
						calculateDistance();

					}
				});
			}
		});
	}

With our two geo-encoded locations, we now use those to calculate a route and send that to the maps canvas.


function calcRoute() {
    var start = document.getElementById("start").value;
    var end = document.getElementById("end").value;
    var request = {
        origin:start,
        destination:end,
        travelMode: google.maps.DirectionsTravelMode.DRIVING
    };
    directionsService.route(request, function(response, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
      }
    });
}

Our basic map and geo-encoding functions are now complete, and we can take that data and display it on the page and do some calculations to create our live quote.

First we setup a function to format a number as a currency.


// function to format currency

function CurrencyFormatted(amount) {
	var i = parseFloat(amount);
	if(isNaN(i)) { i = 0.00; }
	var minus = '';
	if(i < 0) { minus = '-'; }
	i = Math.abs(i);
	i = parseInt((i + .005) * 100);
	i = i / 100;
	s = new String(i);
	if(s.indexOf('.') < 0) { s += '.00'; }
	if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
	s = minus + s;
	return s;
}

Finally, we calculate the distance between our two locations and display it on the page along with our price or rate calculations used for the actual quoting.


// function to calculate distance

	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 = 'Address 1: ' + location1.address + ' (' + location1.lat + ':' + location1.lon + ')<br />Address 2: ' + location2.address + ' (' + location2.lat + ':' + location2.lon + ')<br />Distance: ' + miledistance + ' miles (or ' + kmdistance + ' kilometers)<br/>';

After our distance values are creates (kmdistance, miledistance) we can multiple that by our price-per-mile to give an estimated cost.


// do our JS math here

    var rate = CurrencyFormatted(document.getElementById("price_per_mile").value);
    var fee = CurrencyFormatted(document.getElementById("admin_fee").value);
    var price = CurrencyFormatted(miledistance * rate);
    var total = CurrencyFormatted(Number(price) + Number(fee));

			document.getElementById('price').innerHTML = miledistance +' multiplied by ' + rate + ' equals ' + price + '<br/> Price Amount Rounded to nearest digit equals: $' + Math.round(price*100)/100 + ' Dollars<br/><br/> Admin Fee of $' + fee + ' Dollars Plus Shipping Price of $' + price + ' Dollars equals $' + total +' Total';
		}
		catch (error)
		{
			alert(error);
		}
	}

The HTML:


<body onload="initialize()">

<form action="#" onsubmit="showLocation();calcRoute(); return false;">

Start: <input id="start" type="text" name="address1" value="55423" class="address_input" size="5" />

End: <input id="end" type="text" name="address2" value="55404" class="address_input" size="5" />

Dwelling:
<select id="price_per_mile">
          <option value="1.00">1 Bedroom Apartment</option>
          <option value="1.50">2 Bedroom Apartment</option>
          <option value="2.00">3 Bedroom Apartment</option>
          <option value="2.50">1 Bedroom Home</option>
          <option value="3.00">2 Bedroom Home</option>
          <option value="4.00">3 Bedroom Home</option>
          <option value="4.50">Small Office Space</option>
          <option value="5.00">Medium Office Space</option>
          <option value="5.50">Large Office Space</option>
</select>

Fee: <input id="admin_fee" type="text" name="admin-fee" value="" class="address_input" size="5" />

<input type="submit" name="find" value="Search" />

</form>

    <p><strong>Distance Results:</strong><br/><span id="results"></span></p>
    <p><strong>Price Results:</strong><br/><span id="price"></span></p>

    <div id="map_canvas" style="top:265px;"></div>

</body>

The form code in the live example controls the actual values used withing the javascript to define locations, prices and fees.

Live Demo:

Written By : Kyle Bahr

With nearly ten years experience in digital media, graphic design, front-end development and creative direction, Kyle Bahr has spent the last several years growing an online presence and portfolio with EnlightenMental Productions with the hope to build continued success online and in life. A strong...

has written 9 articles

20 Responses to “Calculate Distance Using Javascript and Google Maps To Create A RealTime Quote Based On Distance”

  1. ronald says:

    Hi, this looks good, I assume that you include the javascript libraries without the anchor tags?

  2. Priya says:

    I tried this code. I am able to see the distance calculated but map is not coming.
    What could be the possible reason for this…

    • Joset says:

      Hi Priya,

      I had the same experience.

      Modify the div with id ‘map_canvas’ as follows (for example), then you should be fine.

      As you can see, what is missing is width and height!

      • Joset says:

        Sorry the html parser swallowed the line below:

        id=”map_canvas” style=”width: 525px; height: 350px;”

  3. Joset says:

    Thanks for saving me weeks of pains!

  4. Hi, when i enter 2 postcodes like ‘CV57BN’ and ‘BB19SN’ i get a distance of 100.7miles, yet in google maps i get over 130.7miles? Is this a the crow flies?

  5. Paul John says:

    Hi
    I have followed your great post, (thank you for sharing it) it does work, however it seems to only calculate distance on as the crow flies and not by road distance, please can you let me know how to fix this? I am not a programmer but have tries to have a go without any joy.
    I really appreciate your help!
    Thank you
    Paul

  6. Sadee says:

    Thanx Kyle! I was hardly try this in last few days. Gud Luck!

  7. veera says:

    hi
    i want to calculate distance between two places and that distance value add with some integer value. can u any one know that..

  8. Adrienne Boswell says:

    This is a great tutorial, thank you so much for posting it. However, there is a problem.

    The distance is off by quite a lot, and, of course, it’s affecting the total. The distance between 9465 Wilshire Blvd Beverly Hills CA 90212 and 5959 Franklin Ave Los Angeles CA 90028 according to Google Maps is 6.7 miles, but according to this it is 5.3 miles. It’s not an “as the crow flies” problem, as even with just using the two zipcodes, the distance is still 6.6 according to Google, and yours is 5.1 miles, so it is still off.

    Link to Google Maps: http://goo.gl/maps/buCtn (with street addresses)
    Link to Google Maps: http://goo.gl/maps/c8y3z (just zipcodes)

  9. victor Dias says:

    I am trying to do something like this, but i have a question… the new google directions ver.3 includes the distance and time in the results. Why can you not just grab the distance variable from the results and use it to do your calculations to get rate? here is the code which is exceedingly spartan:

    var directionsService = new google.maps.DirectionsService();
    var directionsDisplay = new google.maps.DirectionsRenderer();

    var map = new google.maps.Map(document.getElementById(‘map’), {
    zoom:11,
    mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    directionsDisplay.setMap(map);
    directionsDisplay.setPanel(document.getElementById(‘panel’));

    var request = {
    origin: ‘3200 Montgomery Highway Dothan, Alabama 36303’,
    destination: ‘800 Airport Drive Dothan, Alabama 36303’,
    travelMode: google.maps.DirectionsTravelMode.DRIVING
    };

    directionsService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
    directionsDisplay.setDirections(response);
    }

    });

  10. James L. says:

    Hi. I am lost here. Where do I put the code that controls everything? Do I need to create a javascript file?

  11. SAM says:

    Hi i cant get the appropriate output….can anyone send me html file that works well….please….send me as early as possible…mailtourfriend21@gmail.com is my maild id…its very urgent for my project…please

  12. cyro says:

    I would like to know if it is possible to get the total miles traveled (via road/interstate) in each state instead of the total miles only.

    For example: From Chicago, IL to Atlanta, GA the total miles traveled in each state would be: IL=16 miles IN=284 miles KY=137 miles TN=152 miles GA=128 miles

    From what I understand this is not possible in google maps api but I wanted to see if it is possible using anything else, Bing, YAhoo, Mapquest ???

    Thanks for any help…

  13. tony says:

    It would have been really helpful/convinient if you published the complete code at the end of the blog

  14. chris says:

    any help with getting this to calculate the distance using roads rather than straight line?? has anyone got this working?

  15. Simon says:

    Just a question, has anyone migrated this to API v3

  16. Ray says:

    I’m coding with notepad++ and i copied this into my worksite of notapad++and it does not count miles or show the distance, is any mistakes in there or anythink else. Thanks