How do I match destinations in the google maps Distance Matrix - javascript

I've got a web app that needs 'distance from me' information for properties displayed on a map.
I'm using googles Distance Matrix Service
distanceService = new google.maps.DistanceMatrixService();
I'm calling the service with one origin and multiple destinations.
var params = {
origins: [currentLocation],
destinations: endPoints,
travelMode: google.maps.TravelMode.DRIVING
}
distanceService.getDistanceMatrix(params, saveDistances);
My endPoints are an array of google.maps.LatLng objects taken from my properties. However when the results are returned they've changed these to addresses, and there's no longer any reference to the LatLng's.
Does anyone know if the Distance Matrix Service guarantees to return results in the same order I sent them? I couldn't see anything in the docs. I really don't want to start calling the geocoding services just to match back to my properties (especially as the LatLng's return won't be an exact match)

They are returned in the same order they are sent.
That isn't specifically stated, but the way I read the documentation it is implied.
quick test fiddle
code snippet:
var service = new google.maps.DistanceMatrixService();
var places = [{
address: "New York, NY",
lat: 40.7143528,
lng: -74.0059731
}, {
address: "Tampa, FL",
lat: 27.950575,
lng: -82.4571776
}, {
address: "Newark, NJ",
lat: 40.735657,
lng: -74.1723667
}, {
address: "Boston, MA",
lat: 42.3584308,
lng: -71.0597732
}, {
address: "Baltimore, MD",
lat: 39.2903848,
lng: -76.6121893
}];
var foundlatlng = new google.maps.LatLng(40.65, -73.95); // Brooklyn, NY
var gotoLoc = [];
for (var i = 0; i < places.length; i++) {
gotoLoc.push(new google.maps.LatLng(places[i].lat, places[i].lng));
}
var service = new google.maps.DistanceMatrixService(); //request distance matrix
var outputdiv = document.getElementById('info');
// var goto = new google.maps.LatLng(places[i].lat, places[i].lng);
function callback(response, status) {
var distancefield = distancefield;
if (status == google.maps.DistanceMatrixStatus.OK) {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var htmlString = "<table border='1'>";
var bounds = new google.maps.LatLngBounds();
for (var c = 0; c < response.rows.length; c++) {
var results = response.rows[c].elements;
for (var r = 0; r < results.length; r++) {
var element = results[r];
var distancetext = element.distance.text;
var durationtext = element.duration.text;
var to = destinations[r];
htmlString += "<tr><td>" + (r + 1) + "</td><td>" + places[r].address + "</td><td>" + response.originAddresses[c] + "</td><td>" + to + "</td><td>" + distancetext + "</td><td>" + durationtext + "</td></tr>";
var marker = new google.maps.Marker({
icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/blue/marker' + (r + 1) + '.png',
position: {
lat: places[r].lat,
lng: places[r].lng
},
map: map
});
bounds.extend(marker.getPosition());
} //end for r
} // end for c
map.fitBounds(bounds);
htmlString += "</table>";
document.getElementById('info').innerHTML = htmlString;
} //end if status=ok
} //end callback
// console.log(places);
var map;
var geocoder = new google.maps.Geocoder();
function initialize() {
var mapOptions = {
zoom: 8,
center: foundlatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);
service.getDistanceMatrix({
origins: ["San Diego, CA", foundlatlng],
destinations: gotoLoc,
travelMode: google.maps.TravelMode.WALKING,
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false,
}, callback); //end service.getdistancematrix()
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body {
margin: 0;
padding: 0;
height: 100%;
width: 100%
}
#map_canvas {
height: 400px;
width: 100%;
}
tr,
td,
tbody,
table {
height: 100%;
width: 100%;
}
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<table border="1">
<tr>
<td>
<div id="map_canvas"></div>
</td>
</tr>
<tr>
<td>
<div id="info"></div>
</td>
</tr>
</table>

Wouldn't it be so much more helpful if you could provide an Index/ID with each Origin and Destination that would be returned in the API response?
If the order is guaranteed to be the exact same as sent, I agree that this should work fine. But this is not stated as guaranteed and it seems to arbitrarily limit Google's ability to order the results in a way that suits them better.

Related

Distance Matrix with dynamic origin or destination

I have this working, just one "origin" marker and multiple dynamic "destination" markers:
markerOrigin = place.geometry.location;
for (var i = 0; i < markers.length; i++) {
markersPosition = markers[i].getPosition();
alert(markersPosition); //give me all the markers latlng
}
service.getDistanceMatrix({
origins: [markerOrigin],
destinations: [markersPosition],
travelMode: 'DRIVING',
Why am i just getting one of the destination markers?
If you want multiple results, you need to pass an array with multiple entries in to the service for the destinations property. Currently you are passing in [markersPosition] (where markersPosition contains a single position).
Change markersPosition to an array:
var markersPosition = [];
Push each marker's location onto it:
for (var i = 0; i < markers.length; i++) {
markersPosition.push(markers[i].getPosition());
}
Then pass that into the service as the destinations property:
service.getDistanceMatrix({
origins: [markerOrigin],
destinations: markersPosition,
travelMode: 'DRIVING'
proof of concept fiddle
code snippet:
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#map {
height: 75%;
}
<div id="output"></div>
<div id="map"></div>
<script>
function initMap() {
var myLatLng = {
lat: 42.31391,
lng: -83.2032224
};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng,
mapTypeId: 'hybrid'
});
markerOrigin = myLatLng;
var locations = [
{address: "16099 Michigan Ave, Dearborn, MI 48126, USA", lat: 42.31391, lng: -83.2032224},
{address: "Dearborn, MI, USA", lat: 42.3222599, lng: -83.1763145},
{address: "Dearborn, MI 48126, USA", lat: 42.3382755, lng: -83.1756188},
{address: "Wayne County, MI, USA", lat: 42.2790746, lng: -83.336188},
{address: "Detroit Metropolitan Area, MI, USA", lat: 42.8105356, lng: -83.0790865},
{address: "Michigan, USA", lat: 44.3148443, lng: -85.6023643}
]
var markers = [];
for (var i = 0; i < locations.length; i++) {
var marker = new google.maps.Marker({
position: locations[i],
map: map
});
markers.push(marker);
}
var markersPosition = [];
for (var i = 0; i < markers.length; i++) {
markersPosition.push(markers[i].getPosition());
// alert(markersPosition); //give me all the markers latlng
}
var service = new google.maps.DistanceMatrixService;
service.getDistanceMatrix({
origins: [markerOrigin],
destinations: markersPosition,
travelMode: 'DRIVING'
}, function(response, status) {
if (status !== 'OK') {
alert('Error was: ' + status);
} else {
var originList = response.originAddresses;
var destinationList = response.destinationAddresses;
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = '';
};
for (var i = 0; i < originList.length; i++) {
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++) {
outputDiv.innerHTML += originList[i] + ' to ' + destinationList[j] +
': ' + results[j].distance.text + ' in ' +
results[j].duration.text + '<br>';
}
}
});
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>

Use locations with google distance matrix

I am a newbie ith google maps distance matrix. But I need it to calculate most effecient route between several locations.
However using a jsfiddle example I can even make it create a route with locations in my region:
My Js fiddle
Example js Fiddle tha I used as base
Basically changed destinations to:
var origin = "Aeroporto da Madeira"
var destinations = [
"Hotel Four Views Baía, Rua das Maravilhas, Funchal",
"R. José Joaquim da Costa 112, 9325-031 Estreito De Câmara, Portugal",
"Q.ta de São João, 2735-521, Portugal"];
These places exist and if I search at google maps appear.
This maybe a very stupid question but what am I doing wrong?
The fact that an address may be geocoded must not mean that a route may be calculated to another location.
In your case the origin is on madeira(an island), but the last destination isn't placed on madeira(a driving route may not be calculated....obviously there are no ferries available...., your function stops running because of the attempt to access a undefined variable routes.elements[i].duration.value)
check the status of the element before you access it's properties
var map;
var geocoder;
var origin = "Aeroporto da Madeira"
var destinations = [
"Hotel Four Views Baía, Rua das Maravilhas, Funchal",
"R. José Joaquim da Costa 112, 9325-031 Estreito De Câmara, Portugal",
"Q.ta de São João, 2735-521, Portugal"
];
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
function calculateDistances() {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: [origin], //array of origins
destinations: destinations, //array of destinations
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, callback);
}
function callback(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
//we only have one origin so there should only be one row
var routes = response.rows[0];
//need to find the shortest
var lowest = Number.POSITIVE_INFINITY;
var tmp;
var shortestRouteIdx = -1;
var resultText = "Possible Routes: <br/>";
for (var i = routes.elements.length - 1; i >= 0; i--) {
//do we got a result for the element?
if (routes.elements[i].status === google.maps.DistanceMatrixElementStatus.OK) {
tmp = routes.elements[i].duration.value;
resultText += "Route " + destinations[i] + ": " + tmp + "<br/>";
if (tmp < lowest) {
lowest = tmp;
shortestRouteIdx = i;
}
}
}
//log the routes and duration.
document.getElementById('results').innerHTML = resultText;
if (shortestRouteIdx > -1) {
//get the shortest route
var shortestRoute = destinations[shortestRouteIdx];
//now we need to map the route.
calculateRoute(origin, shortestRoute)
} else {
alert('no route available');
}
}
}
//Calculate the route of the shortest distance we found.
function calculateRoute(start, end) {
var request = {
origin: start,
destination: end,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
});
}
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var centerPosition = new google.maps.LatLng(32.670159, -16.978268);
var options = {
zoom: 12,
center: centerPosition,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map'), options);
directionsDisplay.setMap(map);
calculateDistances();
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#results {
position: fixed;
top: 0;
right: 0;
background: gold;
}
<div id="map"></div>
<div id="results"></div>
<script src="https://maps.googleapis.com/maps/api/js?v=3"></script>

Creating check boxes for each markers generated by xml GOOGLE MAPS

I already have a working map where it generates a valid xml and can generate a marker on my map. Now what I want to do is to upon generating of maps for each loop in the xml I can create asynchronously a check box for each name. here is the code that generates the xml
function searchNearLocations(radius){
clearLocations();
var searchUrl = './designIncludes/phpLogicIncludes/searchMarkers.php?lat=' + userLat +'&lng=' + userLng + '&radius=' + radius;
downloadUrl(searchUrl, function(data) {
var xml = parseXml(data);
var markerNodes = xml.documentElement.getElementsByTagName("marker");
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markerNodes.length; i++) {
var name = markerNodes[i].getAttribute("name");
var address = markerNodes[i].getAttribute("address");
var info = markerNodes[i].getAttribute("info");
var tts = markerNodes[i].getAttribute("tts");
var latlng = new google.maps.LatLng(
parseFloat(markerNodes[i].getAttribute("lat")),
parseFloat(markerNodes[i].getAttribute("lng")));
createMarker(latlng, name, address,info,tts);
createCheckboxes(name);
bounds.extend(latlng);
}
map.fitBounds(bounds);
});
}
My createMarker()
function createMarker(latlng, name, address,info,tts) {
var html = "<b>" + name + "</b></br><u>" + address + "</u></br>" + info + "</br>" + "Time allowance to spend: " + tts;
var marker = new google.maps.Marker({
map: map,
position: latlng
});
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
markers.push(marker);
}
I'm not that good in javascript but I have a marker=[] array global variable. Can I use that variable to generate a checkbox with it?by the way I also have a pre made marker before invoking the searchNearLocations function and I want to add it on the latlng bounds. Is it possible to insert it on the loop?
Okay
Everything not having to do with the checkboxes, I ignored. You'll have to put it back in your code.
I wrote a functioning example, you can copy/paste this as is.
<script src="http://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script type="text/javascript">
var markers = [];
var map;
/* I don't have that XML. I'll just insert a few locations hard coded. You can ignore this; it doesn't affect your question */
var markerNodes = [
{latlng: new google.maps.LatLng(50.896328544032805,4.4825010816688), name: 'Brussels Airport', address: 'A201, 1930 Zaventem', info: 'National airport of Brussels', tts: 'foo'},
{latlng: new google.maps.LatLng(50.8957080950929,4.334064952575659), name: 'Football stadion', address: 'Marathonlaan', info: 'Football stadion of the Red Devils', tts: 'foo'},
{latlng: new google.maps.LatLng(50.82302545625156,4.39255052014533), name: 'VUB campus', address: 'Pleinlaan 2', info: 'University of Brussels', tts: 'foo'}
];
function initialize() {
var position = new google.maps.LatLng(50.84499325563654,4.349978498661017);
var myOptions = {
zoom: 11,
center: position
};
map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
searchNearLocations(null); // I ignore the radius part. I presume this searches for locations in a DB, or something...
}
/* never mind most of the changes I made here, it's just to ignore the xml part of the code */
function searchNearLocations(radius) {
clearLocations();
var bounds = new google.maps.LatLngBounds();
for (var i=0; i<markerNodes.length; i++) {
var latlng = markerNodes[i].latlng,
name = markerNodes[i].name,
address = markerNodes[i].address,
info = markerNodes[i].info,
tts = markerNodes[i].tts;
createMarker(latlng, name, address, info, tts);
createCheckbox(name, i); // the most important thing is to pass the i; then markers[i] corresponds with checkboxes[i]
bounds.extend(latlng);
}
map.fitBounds(bounds);
}
function createMarker(latlng, name, address, info, tts) {
// var html = "<b>" + name + "</b></br><u>" + address + "</u></br>" + info + "</br>" + "Time allowance to spend: " + tts;
var marker = new google.maps.Marker({
map: map,
title: name, // You should add this
position: latlng
});
google.maps.event.addListener(marker, 'click', function() {
/* I'll ignore the infoWindow */
});
markers.push(marker);
}
function clearLocations() {
for (var i=0; i<markers.length; i++) {
markers[i].setMap(null);
}
markers=[];
}
function checkboxChanged(i, checked) {
if(checked) {
markers[i].setMap(map);
}
else {
markers[i].setMap(null);
}
}
function createCheckbox(name, i) {
document.getElementById('checkboxes').innerHTML +=
'<input type="checkbox" checked="checked" onclick="checkboxChanged(' + i + ', this.checked);"> ' + name + '<br>';
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<style>
#map-canvas {
width: 500px;
height: 400px;
}
</style>
<div id="map-canvas"></div>
<div id="checkboxes"></div>
Can you manage to include this in your code?
EDIT:
Here is an example of locations in a DB; I bypass xml and communicate through JSON.
It gives you (kind of) a combination of your questions;
I have a different table on my DB, but that shouldn't be a problem.
I add jQuery, just for ajax.
CREATE TABLE IF NOT EXISTS stations (
id bigint(15) NOT NULL AUTO_INCREMENT,
lat decimal(12,10) DEFAULT NULL,
lng decimal(12,10) DEFAULT NULL,
name varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
INSERT INTO stations (id, lat, lng, name) VALUES
(1, '50.8456035000', '4.3568658000', 'Brussel-Centraal'),
(2, '50.8413140000', '4.3490830000', 'Brussel-Kapellekerk'),
(3, '50.8517507000', '4.3623635000', 'Brussel-Congres'),
(4, '50.8604931000', '4.3607035000', 'Brussel-Noord'),
(5, '50.8348278000', '4.3365303000', 'Brussel-Zuid');
index.php
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script type="text/javascript">
var markers = [];
var map;
// settings, to pass to the DB
var lat = 50.84499325563654;
var lng = 4.349978498661017;
var radius = 1.5; /* set this to more than 1.5 to see more locations */
function initialize() {
var position = new google.maps.LatLng(50.84499325563654, 4.349978498661017);
var myOptions = {
zoom: 11,
center: position
};
map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
searchNearLocations(lat, lng, radius);
}
function searchNearLocations(lat, lng, radius) {
document.getElementById('checkboxes').innerHTML = '';
// we start an Ajax call.
$.ajax({
url: 'ajax.php',
data: {lat: lat, lng: lng, radius: radius},
dataType: 'json',
success: function(data) {
// the request has returned data. Now we can proceed
clearLocations();
var bounds = new google.maps.LatLngBounds();
for (var i=0; i<data.length; i++) {
var latlng = new google.maps.LatLng(data[i].lat, data[i].lng),
name = data[i].name;
/* add what ever extra data you need */
createMarker(latlng, name, null, null, null);
createCheckbox(name, i); // the most important thing is to pass the i; then markers[i] corresponds with checkboxes[i]
bounds.extend(latlng);
}
map.fitBounds(bounds);
}
});
}
function createMarker(latlng, name, address, info, tts) {
/* var html = "<b>" + name + "</b></br><u>" + address + "</u></br>" + info + "</br>" + "Time allowance to spend: " + tts; */
var marker = new google.maps.Marker({
map: map,
title: name, // You should add this
position: latlng
});
google.maps.event.addListener(marker, 'click', function() {
/* I'll ignore the infoWindow */
});
markers.push(marker);
}
function clearLocations() {
for (var i=0; i<markers.length; i++) {
markers[i].setMap(null);
}
markers=[];
}
function checkboxChanged(i, checked) {
if(checked) {
markers[i].setMap(map);
}
else {
markers[i].setMap(null);
}
}
function createCheckbox(name, i) {
document.getElementById('checkboxes').innerHTML +=
'<input type="checkbox" checked="checked" onclick="checkboxChanged(' + i + ', this.checked);"> ' + name + '<br>';
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<style>
#map-canvas {
width: 500px;
height: 400px;
}
</style>
<div id="map-canvas"></div>
<div id="checkboxes"></div>
ajax.php
<?php
$link = mysqli_connect('localhost', 'root', '', 'stackoverflow'); /* put your settings back */
if(!$link) {
die ('unable to connect to the database' . mysqli_connect_error());
}
//Get parameters from URL
$myLat = (isset ($_GET['lat']) ? $_GET['lat'] : 0.0); // give it some default
$myLng = (isset ($_GET['lng']) ? $_GET['lng'] : 0.0);
$calcDistance = (isset ($_GET['radius']) ? $_GET['radius'] : 1.0);
//Search the rows in the markers table
/* I have a slightly different table; I'll continue with mine; it's easy to put everything back */
// $query = sprintf("SELECT siteName,address,lat,lng,info,tts, (6371 * acos(cos(radians('%s')) * cos(radians(lat)) * cos(radians(lng) - radians ('%s')) + sin(radians('%s')) * sin(radians(lat))))AS distance FROM mapTable HAVING distance < '%s' ORDER BY distance LIMIT 0, 50",
$query = sprintf("SELECT id, lat, lng, name, (6371 * acos(cos(radians('%s')) * cos(radians(lat)) * cos(radians(lng) - radians ('%s')) + sin(radians('%s')) * sin(radians(lat)))) AS distance FROM stations HAVING distance < '%s' ORDER BY distance LIMIT 0, 50",
mysqli_real_escape_string($link, $myLat),
mysqli_real_escape_string($link, $myLng),
mysqli_real_escape_string($link,$myLat),
mysqli_real_escape_string($link, $calcDistance));
$result = mysqli_query($link, $query);
$row_cnt = mysqli_num_rows($result);
if(!$result) {
die("Invalid query: " . mysqli_error());
}
header("content-type: application/json; charset=utf-8");
$items = array();
//iterate through the rows,
while($row = mysqli_fetch_assoc($result)) {
$items[] = $row;
}
echo json_encode($items); // this can immediatly be read by javascript
exit;
?>
You can add links/buttons, whith something like
<div onclick="searchNearLocations(50.80, 4.35, 20)">click: 20 km radius from (50.80, 4.35)</div>
To add the position of the client, check out my answer here
google getLocation function not work in my script

Google Maps API OVER_QUERY_LIMIT 10 Destinations [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I've been researching this all day and still haven't come across a solution that works. I'm using the Google Maps Distance Matrix Service with 1 origin and 14 destinations. I modified the sample code from Google (https://developers.google.com/maps/documentation/javascript/examples/distance-matrix) and just added more destinations to test it out. With anything over 10 destinations, the OVER_QUERY_LIMIT error occurs and mis-places a marker.
From the usage limits I found (100 elements per 10 seconds), I shouldn't be hitting the limit at all. I have also tried inserting my API Key in this line, to no avail:
src="https://maps.googleapis.com/maps/api/js?v=3.exp"
Any help would be appreciated! Thanks.
Code changes to the sample code from Google:
var destinationA = new google.maps.LatLng(45.465422,9.185924);
var destinationB = new google.maps.LatLng(41.385064,2.173403);
var destinationC = new google.maps.LatLng(40.416775,-3.70379);
var destinationD = new google.maps.LatLng(51.507351,-0.127758);
var destinationE = new google.maps.LatLng(48.856614,2.352222);
var destinationF = new google.maps.LatLng(41.902784,12.496366);
var destinationG = new google.maps.LatLng(50.85034,4.35171);
var destinationH = new google.maps.LatLng(46.198392,6.142296);
var destinationI = new google.maps.LatLng(47.36865,8.539183);
var destinationJ = new google.maps.LatLng(53.408371,-2.991573);
var destinationK = new google.maps.LatLng(37.389092,-5.984459);
var destinationL = new google.maps.LatLng(53.349805,-6.26031);
var destinationM = new google.maps.LatLng(55.864237,-4.251806);
var destinationN = new google.maps.LatLng(51.92442,4.477733);
function calculateDistances() {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [origin],
destinations: [destinationA, destinationB,destinationC, destinationD,destinationE, destinationF,destinationG, destinationH,destinationI, destinationJ,destinationK, destinationL, destinationM, destinationN],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, callback);
}
The OVER_QUERY_ERROR is coming from the geocoder, not the DistanceMatrix call. Remove this line:
addMarker(destinations[j], true);
(you don't need the geocoder, you already have the coordinates for the markers)
working code snippet:
var map;
var geocoder;
var bounds = new google.maps.LatLngBounds();
var markersArray = [];
var origin = new google.maps.LatLng(55.930, -3.118);
var origin2 = 'Greenwich, England';
var destinationA = new google.maps.LatLng(45.465422, 9.185924);
var destinationB = new google.maps.LatLng(41.385064, 2.173403);
var destinationC = new google.maps.LatLng(40.416775, -3.70379);
var destinationD = new google.maps.LatLng(51.507351, -0.127758);
var destinationE = new google.maps.LatLng(48.856614, 2.352222);
var destinationF = new google.maps.LatLng(41.902784, 12.496366);
var destinationG = new google.maps.LatLng(50.85034, 4.35171);
var destinationH = new google.maps.LatLng(46.198392, 6.142296);
var destinationI = new google.maps.LatLng(47.36865, 8.539183);
var destinationJ = new google.maps.LatLng(53.408371, -2.991573);
var destinationK = new google.maps.LatLng(37.389092, -5.984459);
var destinationL = new google.maps.LatLng(53.349805, -6.26031);
var destinationM = new google.maps.LatLng(55.864237, -4.251806);
var destinationN = new google.maps.LatLng(51.92442, 4.477733);
var destinationIcon = 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=D|FF0000|000000';
var originIcon = 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=O|FFFF00|000000';
function initialize() {
var opts = {
center: new google.maps.LatLng(55.53, 9.4),
zoom: 10
};
map = new google.maps.Map(document.getElementById('map-canvas'), opts);
geocoder = new google.maps.Geocoder();
}
function calculateDistances() {
deleteOverlays();
var destinations = [destinationA, destinationB, destinationC, destinationD, destinationE, destinationF, destinationG, destinationH, destinationI, destinationJ, destinationK, destinationL, destinationM, destinationN];
for (var i = 0; i < destinations.length; i++) {
bounds.extend(destinations[i]);
var marker = new google.maps.Marker({
map: map,
position: destinations[i],
icon: destinationIcon
});
markersArray.push(marker);
}
map.fitBounds(bounds);
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: [origin],
destinations: destinations,
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, callback);
}
function callback(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var outputDiv = document.getElementById('outputDiv');
outputDiv.innerHTML = '';
for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
addMarker(origins[i], false);
for (var j = 0; j < results.length; j++) {
// addMarker(destinations[j], true);
outputDiv.innerHTML += "<b>"+j+":</b>"+origins[i] + ' to ' + destinations[j] + ': ' + results[j].distance.text + ' in ' + results[j].duration.text + '<br>';
}
}
}
}
function addMarker(location, isDestination) {
var icon;
if (isDestination) {
icon = destinationIcon;
} else {
icon = originIcon;
}
geocoder.geocode({
'address': location
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
bounds.extend(results[0].geometry.location);
map.fitBounds(bounds);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: icon
});
markersArray.push(marker);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
function deleteOverlays() {
for (var i = 0; i < markersArray.length; i++) {
markersArray[i].setMap(null);
}
markersArray = [];
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map-canvas {
height: 100%;
width: 50%;
}
#content-pane {
float: right;
width: 48%;
padding-left: 2%;
}
#outputDiv {
font-size: 11px;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<p>
<button type="button" onclick="calculateDistances();">Calculate distances</button>
</p>
</div>
<div id="outputDiv"></div>
</div>
<div id="map-canvas"></div>

Javascript, set variable from contents of text box

I am trying to adapt this Google Maps distance calculator to my needs, but am not overly familiar with plain Javascript, and only Jquery.
I am trying to modify one of the destination variables so that it pulls it from a text box instead.
Usually the line reads :
var destinationA = 'pe219px';
But I am trying to change it to the following, usually I would do this with a keyup function to update the value as the person types in jquery, but im not sure what im doing in plain javascript. This is what I have come up with so far, but it doesn't appear to do a lot :
function setValue() {
destinationA=parseInt(document.getElementById('deliverypostcode').value);
}
This is the example I am trying to modify
https://developers.google.com/maps/documentation/javascript/examples/distance-matrix
This is the whole code :
<!DOCTYPE html>
<html>
<head>
<title>Distance Matrix service</title>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map-canvas {
height: 100%;
width: 50%;
}
#content-pane {
float:right;
width:48%;
padding-left: 2%;
}
#outputDiv {
font-size: 11px;
}
</style>
<script>
var map;
var geocoder;
var bounds = new google.maps.LatLngBounds();
var markersArray = [];
var origin1 = new google.maps.LatLng(53.003604, -0.532764);
var origin2 = 'pe219px';
function setValue() {
destinationA=parseInt(document.getElementById('deliverypostcode').value);
}
var destinationB = new google.maps.LatLng(53.003604, -0.532764);
var destinationIcon = 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=D|FF0000|000000';
var originIcon = 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=O|FFFF00|000000';
function initialize() {
var opts = {
center: new google.maps.LatLng(53.003604, -0.532764),
zoom: 8
};
map = new google.maps.Map(document.getElementById('map-canvas'), opts);
geocoder = new google.maps.Geocoder();
}
function calculateDistances() {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [origin1, origin2],
destinations: [destinationA, destinationB],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
}, callback);
}
function callback(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var outputDiv = document.getElementById('outputDiv');
outputDiv.innerHTML = '';
deleteOverlays();
for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
addMarker(origins[i], false);
for (var j = 0; j < results.length; j++) {
addMarker(destinations[j], true);
outputDiv.innerHTML += origins[i] + ' to ' + destinations[j]
+ ': ' + results[j].distance.text + '<br>';
}
}
}
}
function addMarker(location, isDestination) {
var icon;
if (isDestination) {
icon = destinationIcon;
} else {
icon = originIcon;
}
geocoder.geocode({'address': location}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
bounds.extend(results[0].geometry.location);
map.fitBounds(bounds);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: icon
});
markersArray.push(marker);
} else {
alert('Geocode was not successful for the following reason: '
+ status);
}
});
}
function deleteOverlays() {
for (var i = 0; i < markersArray.length; i++) {
markersArray[i].setMap(null);
}
markersArray = [];
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="content-pane">
<div id="inputs">
<form name="form1" method="post" action="">
<label for="deliverypostcode">Your Postcode</label>
<input type="text" name="deliverypostcode" id="deliverypostcode">
</form>
<p><button type="button" onclick="calculateDistances();">Calculate
distances</button></p>
</div>
<div id="outputDiv"></div>
</div>
<div id="map-canvas"></div>
</body>
</html>
Your function setValue is never called.
What if you delete it and just place the following line at the begining of calculateDistances ?
var destinationA= document.getElementById('deliverypostcode').value;
This works for me. Also, you don't need to parseInt your text input. Geocoding converts strings to a lat/long coordinates.

Categories