View Full Version : (Interesting problem) Help with distance matrix in javascript Google maps API

02-07-2012, 08:47 AM

I am trying to create a function using the google API that takes the visitor's location as input (typed into a form) and returns the route between that location and a point closest to them from an set of predefined possible locations.

To do this, I try to use the distance matrix to get the distances between the single origin and the array of multiple endpoints. Then, I copy the array of distances, sort it from largest to smallest, pick out the lowest value, and get the index of that value in the original distance array using .indexOf. After that, I get the endpoint location by getting the city with the same index. I try to feed this through to a function called calcRoute(), which takes two locations and calculates the route.

The problem is that I can't get this to work at all. I have only really been learning the google javascript API for about 1-2 days. I am really hoping that I could get somebody more experienced to help out.

Thank you very much for your help!

Here is the code:

<!DOCTYPE html>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }

#control {
background: #fff;
padding: 10px;
font-size: 14px;
font-family: Arial;
border: 1px solid #ccc;
box-shadow: 0 2px 2px rgba(33, 33, 33, 0.4);
display: none;

background: #e1e1e1;
-moz-border-radius: 6px;
border-radius: 6px;
padding: 5px;
padding-top: 2px;
padding-bottom: 2px;
<script type="text/javascript"
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var markers=["Whistler, BC", "Hope, BC", "Penticton, BC", "Grand Forks, BC"]; /* This is an example array of locations in BC, Canada */

/* Initialize map, centered on Vancouver, BC */
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var vancouver = new google.maps.LatLng(49.26174972436721, -123.09031202392578);
var myOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: vancouver
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
trafficLayer = new google.maps.TrafficLayer(); /*For overlay of traffic information. */

directionsDisplay.setMap(map); /*For display of detailed driving directions between origin and destination. */

var control = document.getElementById('control'); /* This is just for displaying the form in a neat box on the map */
control.style.display = 'block';

/* Show the 'Show directions' button after search button is clicked */
function ToggleDirButton() {
var dirbutton=document.getElementById("hideshowdirs");
var trafbutton=document.getElementById("traffictoggle");
var line=document.getElementById("line");

/* Toggle the traffic feed on/off after the 'Show traffic' button is clicked */
function TrafficToggle() {
var trafficvalue=document.getElementById("traffictoggle").value;
if(trafficvalue=="Show traffic") {
document.getElementById("traffictoggle").value="Hide traffic";
else {
document.getElementById("traffictoggle").value="Show traffic";
/* Show hide the directions panel and toggle the button text */
function ToggleWidth() {
var dirbutton=document.getElementById("hideshowdirs");
var mapwidth=document.getElementById("map_canvas");
var dirwidth=document.getElementById("directionsPanel");
if(dirbutton.value=="Show driving directions") {
dirbutton.value="Hide driving directions";
else {
dirbutton.value="Show driving directions";

/* Distance Matrix to calculate distances between origin (from form, id="start"), and the locations in the array 'markers' */
function calculateDistances() {
var service = new google.maps.DistanceMatrixService();
origins: document.getElementById("start").value,
destinations: markers,
travelMode: google.maps.TravelMode.DRIVING,
avoidHighways: false,
avoidTolls: false
}, callback);
function callback(response, status) {
if (status == google.maps.DistanceMatrixStatus.OK) {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
/* array of distances (as numbers) */
for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++) {
var element = results[j];
var distance = element.distance;
/* Insert distances into global array 'distancearray' at each iteration of the for loop, across the columns j. In the distance matrix, each row corresponds to the origin, and each column corresponds to the destination. Here, 'distancearray' holds the distances between the single origin and the multiple destinations, in the correct order. */
/* Calculate shortest distance, and get array index */

function calcShortestDist() {
/* Sort distancearray from smallest to largest value (corresponding to distances) */
var distancearray2=distancearray.slice(0); /* Copy distance array and sort it from largest to smallest */
var shortest=distancearray2.sort(function(a,b){return a - b});
short=distancearray.indexOf(shortest[0]); /* Get array index of location corresponding to shortest distance */
ending=markers[short]; /* Get the city corresponding to this index. Since the array 'distancearray' corresponds to distances between the input location and the locations at the markers, this city is the closest point. */

/* Calculate Route */
function calcRoute() {
var start = document.getElementById("start").value;
var end=ending; /* Use location of closest point as the end point */
var request = {
provideRouteAlternatives: true,
travelMode: google.maps.TravelMode.DRIVING
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
<body onload="initialize()">
<div id="control" style="float:left;">
<input type="text" id="start" value="Search" onfocus="if(this.value=='Search') this.value=''" onBlur="if(this.value=='') this.value='Search'" autocomplete="off"/>
<input type="button" value="Search" class="subres" onClick="calcRoute(); ToggleDirButton();"/>
<div id="line" style="visibility: hidden"></div>
<div align="center"><hr />
<input type="hidden" id="traffictoggle" value="Show traffic" class="subres" onClick="TrafficToggle();" />
<input type="hidden" id="hideshowdirs" value="Show driving directions" class="subres" onClick="ToggleWidth();"/>
<div id="map_canvas" style="float:left;width:100%;height:100%"></div>
<div id="directionsPanel" style="float:right;overflow:inherit"></div>