The code in the fiddle below has 3 Fixed Locations. An address can then be inputted and the distance from that address to all three Fixed Locations will be calculated. The results are then sorted in order by distance in a sidebar on the right.
I'm trying to figure out how to assign lettered markers for each result. So each time the results are calculated, the first closest marker would be letter A, the second closest marker would be letter B and so on. I'd also like the letter A to appear in the sidebar next to the first closest result and letter B to appear in the sidebar next to the second closest results and so on.
I haven't been able to find any instructions how to do this? Can anyone help?
Thanks
http://jsfiddle.net/geocodezip/vj0cpv0c/2/
var locations = [
["John Doe", "145 Rock Ridge Road, Chester, NY ", "41.314926,-74.270134", "http://maps.google.com/mapfiles/ms/icons/blue.png"],
["Jim Smith", "12 Williams Rd, Montvale, NJ ", "41.041599,-74.019554", "http://maps.google.com/mapfiles/ms/icons/green.png"],
["John Jones", "689 Fern St Township of Washington, NJ ", "40.997704,-74.050598", "http://maps.google.com/mapfiles/ms/icons/yellow.png"],
What you where looking for was .set('label', letterMarkers); using int to char we can turn 0 into A, 1 into B and place this onto the markers and list.
in function calculateDistances you work out and sort the pins, which we can then draw the letters on, I also added the letter above the link in the right list
you should now see a,b,c in the list on the right
and pins in a,b,c order from distance
code changed:
closest[i].setMap(map);
var letterMarkers = String.fromCharCode(97 + i);
closest[i].set('label', letterMarkers);
outputDiv.innerHTML += letterMarkers + " <br>
all code:
var locations = [
["John Doe", "145 Rock Ridge Road, Chester, NY ", "41.314926,-74.270134", "http://maps.google.com/mapfiles/ms/icons/blue.png"],
["Jim Smith", "12 Williams Rd, Montvale, NJ ", "41.041599,-74.019554", "http://maps.google.com/mapfiles/ms/icons/green.png"],
["John Jones", "689 Fern St Township of Washington, NJ ", "40.997704,-74.050598", "http://maps.google.com/mapfiles/ms/icons/yellow.png"],
];
// alert(locations.length);
var geocoder = null;
var map = null;
var customerMarker = null;
var gmarkers = [];
var closest = [];
var directionsDisplay = new google.maps.DirectionsRenderer();;
var directionsService = new google.maps.DirectionsService();
var map;
function initialize() {
// alert("init");
geocoder = new google.maps.Geocoder();
map = new google.maps.Map(document.getElementById('map'), {
zoom: 9,
center: new google.maps.LatLng(52.6699927, -0.7274620),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
var bounds = new google.maps.LatLngBounds();
document.getElementById('info').innerHTML = "found " + locations.length + " locations<br>";
for (i = 0; i < locations.length; i++) {
var coordStr = locations[i][2];
var coords = coordStr.split(",");
var pt = new google.maps.LatLng(parseFloat(coords[0]), parseFloat(coords[1]));
bounds.extend(pt);
marker = new google.maps.Marker({
position: pt,
map: map,
icon: locations[i][3],
address: locations[i][1],
title: locations[i][0],
html: locations[i][0] + "<br>" + locations[i][1] + "<br><br><a href='javascript:getDirections(customerMarker.getPosition(),"" + locations[i][1] + "");'>Get Directions</a>"
});
gmarkers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(marker.html);
infowindow.open(map, marker);
}
})
(marker, i));
}
map.fitBounds(bounds);
}
function codeAddress() {
var address = document.getElementById('address').value;
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
if (customerMarker) customerMarker.setMap(null);
customerMarker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
closest = findClosestN(results[0].geometry.location, 12);
// get driving distance
closest = closest.splice(0, 12);
calculateDistances(results[0].geometry.location, closest, 12);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
function findClosestN(pt, numberOfResults) {
var closest = [];
document.getElementById('info').innerHTML += "processing " + gmarkers.length + "<br>";
for (var i = 0; i < gmarkers.length; i++) {
gmarkers[i].distance = google.maps.geometry.spherical.computeDistanceBetween(pt, gmarkers[i].getPosition());
document.getElementById('info').innerHTML += "process " + i + ":" + gmarkers[i].getPosition().toUrlValue(6) + ":" + gmarkers[i].distance.toFixed(2) + "<br>";
gmarkers[i].setMap(null);
closest.push(gmarkers[i]);
closest.sort(sortByDist);
}
return closest;
}
function sortByDist(a, b) {
return (a.distance - b.distance)
}
function calculateDistances(pt, closest, numberOfResults) {
var service = new google.maps.DistanceMatrixService();
var request = {
origins: [pt],
destinations: [],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
};
for (var i = 0; i < closest.length; i++) {
request.destinations.push(closest[i].getPosition());
}
service.getDistanceMatrix(request, function(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('side_bar');
outputDiv.innerHTML = '';
var results = response.rows[0].elements;
// save title and address in record for sorting
for (var i = 0; i < closest.length; i++) {
results[i].title = closest[i].title;
results[i].address = closest[i].address;
results[i].idx_closestMark = i;
}
results.sort(sortByDistDM);
for (var i = 0;
((i < numberOfResults) && (i < closest.length)); i++) {
closest[i].setMap(map);
var letterMarkers = String.fromCharCode(97 + i);
closest[i].set('label', letterMarkers);
outputDiv.innerHTML += letterMarkers + " <br><a href='javascript:google.maps.event.trigger(closest[" + results[i].idx_closestMark + "],\"click\");'>" + results[i].title + '</a><br>' + results[i].address + "<br>" + results[i].distance.text + ' approximately ' + results[i].duration.text + "<br><a href='javascript:getDirections(customerMarker.getPosition(),"" + results[i].address + "");'>Get Directions</a><br><hr>"
}
}
});
}
function getDirections(origin, destination) {
var request = {
origin: origin,
destination: destination,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setMap(map);
directionsDisplay.setDirections(response);
directionsDisplay.setPanel(document.getElementById('side_bar'));
}
});
}
function sortByDistDM(a, b) {
return (a.distance.value - b.distance.value)
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map_canvas {
margin: 0;
padding: 0;
height: 100%;
}
table,tr,td {
height: 100%;
}
.text {
width: 300px;
height: 600px;
background-color: white;
overflow: scroll;
overflow-x: hidden;
}
<table border="0">
<tr>
<td>
<div id="map" style="height: 100%; width:400px;"></div>
</td>
<td>
<div id="side_bar" class='text'> </div>
</td>
</tr>
</table>
<input id="address" type="text" value="Paramus, NJ" />
<input type="button" value="Search" onclick="codeAddress();" />
<div id="info"></div>
To follow up,sorted pins I used general javascript to make closest match results, there may be a better way of doing this with the API.
added code:
var pins = [];
results.forEach(function(result){
closest.forEach(function (addr){
if(result.address === addr.address){
pins.push(addr);
}
});
});
and used pins[i] instead of closest in the for loop.
all code:
var locations = [
["John Doe", "29 Buhl Lane, East Northport, NY ", "40.858924, -73.297327", "http://maps.google.com/mapfiles/ms/icons/blue.png"],
["Jim Smith", "12 Williams Rd, Montvale, NJ ", "41.041599,-74.019554", "http://maps.google.com/mapfiles/ms/icons/green.png"],
["John Jones", "689 Fern St Township of Washington, NJ ", "40.997704,-74.050598", "http://maps.google.com/mapfiles/ms/icons/yellow.png"],
];
// alert(locations.length);
var geocoder = null;
var map = null;
var customerMarker = null;
var gmarkers = [];
var closest = [];
var directionsDisplay = new google.maps.DirectionsRenderer();;
var directionsService = new google.maps.DirectionsService();
var map;
function initialize() {
// alert("init");
geocoder = new google.maps.Geocoder();
map = new google.maps.Map(document.getElementById('map'), {
zoom: 9,
center: new google.maps.LatLng(52.6699927, -0.7274620),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
var bounds = new google.maps.LatLngBounds();
document.getElementById('info').innerHTML = "found " + locations.length + " locations<br>";
for (i = 0; i < locations.length; i++) {
var coordStr = locations[i][2];
var coords = coordStr.split(",");
var pt = new google.maps.LatLng(parseFloat(coords[0]), parseFloat(coords[1]));
bounds.extend(pt);
marker = new google.maps.Marker({
position: pt,
map: map,
icon: locations[i][3],
address: locations[i][1],
title: locations[i][0],
html: locations[i][0] + "<br>" + locations[i][1] + "<br><br><a href='javascript:getDirections(customerMarker.getPosition(),"" + locations[i][1] + "");'>Get Directions</a>"
});
gmarkers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(marker.html);
infowindow.open(map, marker);
}
})
(marker, i));
}
map.fitBounds(bounds);
$("#mdiv").click(function() {
$("#side_bar").css({
"z-index": 100,
"top": "0px"
});
$("#panel").css("z-index", -100);
$("#mdiv").css("display", "none");
})
}
function codeAddress() {
var address = document.getElementById('address').value;
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
if (customerMarker) customerMarker.setMap(null);
customerMarker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
closest = findClosestN(results[0].geometry.location, 12);
// get driving distance
closest = closest.splice(0, 12);
calculateDistances(results[0].geometry.location, closest, 12);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
function findClosestN(pt, numberOfResults) {
var closest = [];
document.getElementById('info').innerHTML += "processing " + gmarkers.length + "<br>";
for (var i = 0; i < gmarkers.length; i++) {
gmarkers[i].distance = google.maps.geometry.spherical.computeDistanceBetween(pt, gmarkers[i].getPosition());
document.getElementById('info').innerHTML += "process " + i + ":" + gmarkers[i].getPosition().toUrlValue(6) + ":" + gmarkers[i].distance.toFixed(2) + "<br>";
gmarkers[i].setMap(null);
closest.push(gmarkers[i]);
closest.sort(sortByDist);
}
return closest;
}
function sortByDist(a, b) {
return (a.distance - b.distance)
}
function calculateDistances(pt, closest, numberOfResults) {
var service = new google.maps.DistanceMatrixService();
var request = {
origins: [pt],
destinations: [],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
};
for (var i = 0; i < closest.length; i++) {
request.destinations.push(closest[i].getPosition());
}
service.getDistanceMatrix(request, function(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('side_bar');
outputDiv.innerHTML = '';
var results = response.rows[0].elements;
// save title and address in record for sorting
for (var i = 0; i < closest.length; i++) {
results[i].title = closest[i].title;
results[i].address = closest[i].address;
results[i].idx_closestMark = i;
}
results.sort(sortByDistDM);
var pins = [];
results.forEach(function(result){
closest.forEach(function (addr){
if(result.address === addr.address){
pins.push(addr);
}
});
});
for (var i = 0;
((i < numberOfResults) && (i < closest.length)); i++) {
pins[i].setMap(map);
var letterMarkers = String.fromCharCode(97 + i);
pins[i].set('label', letterMarkers);
outputDiv.innerHTML += letterMarkers + " <br><a href='javascript:google.maps.event.trigger(closest[" + results[i].idx_closestMark + "],\"click\");'>" + results[i].title + '</a><br>' + results[i].address + "<br>" + results[i].distance.text + ' approximately ' + results[i].duration.text + "<br><a href='javascript:getDirections(customerMarker.getPosition(),"" + results[i].address + "");'>Get Directions</a><br><hr>"
}
}
});
}
function getDirections(origin, destination) {
var request = {
origin: origin,
destination: destination,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setMap(map);
directionsDisplay.setDirections(response);
$("#side_bar").css({
"z-index": -100,
"top": "25px"
});
$("#panel").css("z-index", 100);
$("#mdiv").css("display", "block");
directionsDisplay.setPanel(document.getElementById('panel'));
}
});
}
function sortByDistDM(a, b) {
return (a.distance.value - b.distance.value)
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map {
margin: 0;
padding: 0;
height: 600px;
width: 400px;
}
.text {
width: 300px;
height: 600px;
background-color: white;
overflow: scroll;
overflow-y: auto;
overflow-x: hidden;
}
#side_bar {
z-index: 100;
position: absolute;
top: 135px;
left: 400px;
}
#panel {
z-index: -100;
display: block;
position: absolute;
top: 135px;
left: 400px;
}
#mdiv {
z-index: 500;
width: 25px;
height: 25px;
display: none;
background-color: red;
border: 1px solid black;
position: absolute;
left: 660px;
top: 112px;
}
.mdiv {
height: 25px;
width: 2px;
margin-left: 12px;
background-color: black;
transform: rotate(45deg);
-ms-transform: rotate(45deg);
/* IE 9 */
-webkit-transform: rotate(45deg);
/* Safari and Chrome */
z-index: 1;
}
.md {
height: 25px;
width: 2px;
background-color: black;
transform: rotate(90deg);
-ms-transform: rotate(90deg);
/* IE 9 */
-webkit-transform: rotate(90deg);
/* Safari and Chrome */
z-index: 2;
}
tr:nth-child(even) {
background: #CCC
}
tr:nth-child(odd) {
background: #FFF
}
<div class="bh-sl-container">
<div id="page-header">
<h1 class="bh-sl-title">The Auditor Locator</h1>
</div>
<div class="bh-sl-form-container">
<form id="bh-sl-user-location" method="post" action="#">
<div class="form-input">
<label for="bh-sl-address">Enter Address or Zip Code:</label>
<input id="address" type="text" value="Danbury, CT" />
<input type="button" value="Submit" onclick="codeAddress();" />
</div>
</form>
</div>
<table border="0" style="height:100%">
<tr style="height:100%">
<td style="height:100%">
<div id="map"></div>
</td>
<td>
<div id="side_bar" class='text'></div>
<div id="panel" class='text'></div>
</td>
</tr>
</table>
<div id="info"></div>
<div id="mdiv">
<div class="mdiv">
<div class="md">
</div>
</div>
</div>
Related
I need to get total distance and travel time with service.getDistanceMatrix({, sum A + B + C + D = total distance.
The way that i try, only i get the first calculate, but I need to get the sum alls points for show to user total-distance
The below attach the image with sample of web
SAMPLE IMAGE
My JavaScript code
var source, destination;
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
google.maps.event.addDomListener(window, 'load', function () {
directionsDisplay = new google.maps.DirectionsRenderer({ 'draggable': true });
});
// P1
var stop;
var markers = [];
var waypts = [];
var pardas = ["6.347033,-75.559017","6.348764,-75.562970","6.334624,-75.556157"];
stop = new google.maps.LatLng(6.347033, -75.559017)
waypts.push({
location: stop,
stopover: true
});
stop = new google.maps.LatLng(6.348764, -75.562970)
waypts.push({
location: stop,
stopover: true
});
directionsDisplay = new google.maps.DirectionsRenderer({
suppressMarkers: false,
});
window.onload=function(){
function initialize() {
//P2
var mapOptions = {
zoom: 15,
//center: new google.maps.LatLng(6.3490548, -75.55802080000001),
mapTypeId: google.maps.MapTypeId.ROADMAP,
}
var map = new google.maps.Map(document.getElementById('dvMap'), mapOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('dvPanel'));
//calcRoute();
}
source = new google.maps.LatLng(6.3490548, -75.55802080000001);
destination = new google.maps.LatLng(6.334624, -75.556157);
//P3
function calcRoute() {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
createMarker(source, 'source', false);
createMarker(destination, 'destination', false);
var route = response.routes[0];
for (var i = 1; i < route['legs'].length; i++) {
console.log(route['legs'][i].start_location.toString(), waypts[i - 1].location.toString());
waypts[i - 1].location = route['legs'][i].start_location
}
for (var i = 0; i < waypts.length; i++) {
createMarker(waypts[i].location, i, true);
}
}
var request = {
origin: source,
destination: destination,
waypoints: waypts,
optimizeWaypoints: true,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: [source],
destinations: pardas,
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, function (response, status) {
if (status == google.maps.DistanceMatrixStatus.OK && response.rows[0].elements[0].status != "ZERO_RESULTS") {
var distance = response.rows[0].elements[0].distance.text;
var duration = response.rows[0].elements[0].duration.text;
var dvDistance = document.getElementById("dvDistance");
dvDistance.innerHTML = "";
dvDistance.innerHTML += "Distance: " + distance + "<br />";
dvDistance.innerHTML += "Duration:" + duration;
The DirectionsService returns all the information you need to calculate the total time and distance, you don't need to use the DistanceMatrix.
Per this related question: Google Maps API: Total distance with waypoints
function computeTotalDistance(result) {
var totalDist = 0;
var totalTime = 0;
var myroute = result.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
totalDist += myroute.legs[i].distance.value;
totalTime += myroute.legs[i].duration.value;
}
totalDist = totalDist / 1000.
document.getElementById("dvDistance").innerHTML = "total distance is: " + totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes";
}
proof of concept fiddle
code snippet:
var source, destination;
var directionsService = new google.maps.DirectionsService();
var stop;
var markers = [];
var waypts = [];
stop = new google.maps.LatLng(6.347033, -75.559017)
waypts.push({
location: stop,
stopover: true
});
stop = new google.maps.LatLng(6.348764, -75.562970)
waypts.push({
location: stop,
stopover: true
});
var directionsDisplay = new google.maps.DirectionsRenderer({
suppressMarkers: false,
});
window.onload = function() {
var mapOptions = {
zoom: 15,
//center: new google.maps.LatLng(6.3490548, -75.55802080000001),
mapTypeId: google.maps.MapTypeId.ROADMAP,
}
var map = new google.maps.Map(document.getElementById('dvMap'), mapOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('dvPanel'));
source = new google.maps.LatLng(6.3490548, -75.55802080000001);
destination = new google.maps.LatLng(6.334624, -75.556157);
var request = {
origin: source,
destination: destination,
waypoints: waypts,
optimizeWaypoints: true,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
computeTotalDistance(response);
}
});
}
function computeTotalDistance(result) {
var totalDist = 0;
var totalTime = 0;
var myroute = result.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
totalDist += myroute.legs[i].distance.value;
totalTime += myroute.legs[i].duration.value;
}
totalDist = totalDist / 1000.
document.getElementById("dvDistance").innerHTML = "total distance is: " + totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes";
}
html,
body {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px;
}
#dvMap {
height: 100%;
width: 50%;
margin: 0px;
padding: 0px;
}
#dvPanel {
height: 100%;
width: 50%;
margin: 0px;
padding: 0px;
float: right;
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="dvDistance"></div>
<div id="dvPanel"></div>
<div id="dvMap"></div>
I was following along with a tutorial involving the GoogleMaps API JS, and everything went well. When trying to building my own app I've come across an issue with displaying a route. The application I'm working on is mainly written in ruby on rails.
The "pseudo code" problem is when clicking on to "view route" button, the route is not displaying on the map.
Below is the HTML that triggers the first event when clicking on the search with in time button, and the CSS as requested.
<body>
<div>
<span class="text"> Within </span>
<select id='max-duration'>
<option value="10">10 min</option>
</select>
<select id="mode">
<option value="DRIVING">drive</option>
</select>
<span class="text">of</span>
<input id= 'search-within-time-text' type='text' placeholder='Your Location'>
<input id= 'search-within-time' type='button' value='Go'>
</div>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places,drawing,geometry&key=<%= ENV["MAP_API"] %>&v=3"></script>
</body>
<style>
#map {
bottom: 0px;
height: 500px;
left: 362px;
position: absolute;
right: 0px;
}
.container {
height: 500px;
position: relative;
}
.options-box {
background: #fff;
border: 1px solid black;
height: 91.75%;
line-height: 35px;
padding: 10px 10px 30px 10px;
text-align: left;
width: 340px;
}
#zoom-to-area-text{
width:200px;
}
</style>
The location array that is stroing the data is found in the maps controller, where we are pushing data from our SQLite DB.
def index
#test_array = []
#test.each do |h|
#test_array.push({lat: h.lat, lng: h.lng})
end
end
In particular I believe the problem lays within the function displayDirections. Which can be found at the bottom of the full code
The displayDirections function is written outside of the initMap function, because of a scoping issue when it is written inside of the initMap function. I've read the problem below
Maybe a similar issue
But had issues with displayDirections being defined at the click event, when it was written with in the initMap function, in the function displayMarkersWithinTime.
Any help is appreciated! Thanks!
function initMap() {
var map;
var markers = [];
var placeMarkers = [];
document.getElementById('search-within-time').addEventListener('click', function(){
searchWithinTime();
});
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 39.9523789, lng: -75.1635996},
zoom: 13,
mapTypeControl: false
});
var locations = <%= raw #test_array.to_json%>
for (var i = 0; i < locations.length; i++) {
var position = locations[i]
var marker = new google.maps.Marker({
position: position,
animation: google.maps.Animation.DROP,
id: i
});
markers.push(marker);
}
function hideMarkers(markers) {
for (var i = 0; i < markers.length; i++){
markers[i].setMap(null);
}
}
function searchWithinTime(){
var distanceMatrixService = new google.maps.DistanceMatrixService;
var address = document.getElementById('search-within-time-text').value;
if (address == ''){
window.alert('You must enter an address.');
} else {
hideMarkers(markers);
var origins = [];
for (var i = 0; i < markers.length; i++) {
origins[i] = markers[i].position;
}
var destination = address;
var mode = document.getElementById('mode').value;
distanceMatrixService.getDistanceMatrix({
origins: origins,
destinations: [destination],
travelMode: google.maps.TravelMode[mode],
unitSystem: google.maps.UnitSystem.IMPERIAL,
}, function(response, status) {
if (status !== google.maps.DistanceMatrixStatus.OK) {
window.alert('Error was: ' + status);
} else {
displayMarkersWithinTime(response);
}
});
}
}
function displayMarkersWithinTime(response){
var maxDuration = document.getElementById('max-duration').value;
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var atLeastOne = false;
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];
if (element.status === "OK") {
var distanceText = element.distance.text;
var duration = element.duration.value / 60;
var durationText = element.duration.text;
if (duration <= maxDuration) {
markers[i].setMap(map);
atLeastOne = true;
var infowindow = new google.maps.InfoWindow({
content : durationText + ' away, ' + distanceText + '<div><input type=\"button\" value=\"View Route\" onclick =' + '\"displayDirections("' + origins[i] + '");\"</input></div>'
});
infowindow.open(map, markers[i]);
// if user clicks on marker close the small info window to open a new
markers[i].infowindow = infowindow;
google.maps.event.addListener(markers[i], 'click', function (){
this.infowindow.close();
});
}
}
}
}
if(!atLeastOne) {
window.alert('We could not find any locations within that distance');
}
console.log("hello")
}
}
var map;
var markers = [];
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 39.9523789, lng: -75.1635996},
zoom: 13,
mapTypeControl: false
});
function hideMarkers(markers) {
for (var i = 0; i < markers.length; i++){
markers[i].setMap(null);
}
}
function displayDirections(origin) {
hideMarkers(markers);
var directionsService = new google.maps.DirectionsService;
var destinationAddress = document.getElementById('search-within-time-text').value;
var mode = document.getElementById('mode').value;
directionsService.route({
origin: origin,
destination: destinationAddress,
travelMode: google.maps.TravelMode[mode]
}, function(response, status) {
console.log(response)
console.log(status)
if (status === google.maps.DirectionsStatus.OK) {
var directionsDisplay = new google.maps.DirectionsRenderer({
map: map,
directions: response,
draggable: true,
polylineOptions: {
strokeColor: 'black'
}
}, console.log(map), console.log(response));
} else {
window.alert('Directions request failed due to ' + status);
}
});
console.log("testing")
}
google.maps.event.addDomListener(window, initMap())
Your (initialized) map variable is local to the initMap function. Make it global.
Change:
function initMap() {
var map;
// ...
To:
var map;
function initMap() {
proof of concept fiddle
code snippet:
var map;
function initMap() {
var markers = [];
var placeMarkers = [];
var titles;
var latitudes;
var longitudes;
var directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
document.getElementById('show-listings').addEventListener('click', showListings);
document.getElementById('hide-listings').addEventListener('click', function() {
hideMarkers(markers);
});
document.getElementById('search-within-time').addEventListener('click', function() {
searchWithinTime();
});
var timeAutocomplete = new google.maps.places.Autocomplete(
document.getElementById('search-within-time-text'));
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 39.9523789,
lng: -75.1635996
},
zoom: 13,
mapTypeControl: false
});
var locations = [{
lat: 39.952584,
lng: -75.165222
}, {
lat: 47.6062095,
lng: -122.3320708
},
{
lat: 34.0522342,
lng: -118.2436849
},
{
lat: 39.114053,
lng: -94.6274636
}, {
lat: 25.7616798,
lng: -80.1917902
}
];
for (var i = 0; i < locations.length; i++) {
var position = locations[i]
var marker = new google.maps.Marker({
position: position,
animation: google.maps.Animation.DROP,
id: i,
map: map
});
markers.push(marker);
}
function showListings() {
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(map);
bounds.extend(markers[i].position);
}
map.fitBounds(bounds);
}
function hideMarkers(markers) {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
}
function searchWithinTime() {
var distanceMatrixService = new google.maps.DistanceMatrixService();
var address = document.getElementById('search-within-time-text').value;
if (address == '') {
window.alert('You must enter an address.');
} else {
hideMarkers(markers);
var origins = [];
for (var i = 0; i < markers.length; i++) {
origins[i] = markers[i].position;
}
var destination = address;
var mode = document.getElementById('mode').value;
distanceMatrixService.getDistanceMatrix({
origins: origins,
destinations: [destination],
travelMode: google.maps.TravelMode[mode],
unitSystem: google.maps.UnitSystem.IMPERIAL,
}, function(response, status) {
if (status !== google.maps.DistanceMatrixStatus.OK) {
window.alert('Error was: ' + status);
} else {
displayMarkersWithinTime(response);
}
});
}
}
function displayMarkersWithinTime(response) {
var maxDuration = document.getElementById('max-duration').value;
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var atLeastOne = false;
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];
if (element.status === "OK") {
var distanceText = element.distance.text;
var duration = element.duration.value / 60;
var durationText = element.duration.text;
if (duration <= maxDuration) {
markers[i].setMap(map);
atLeastOne = true;
var infowindow = new google.maps.InfoWindow({
content: durationText + ' away, ' + distanceText + '<div><input type=\"button\" value=\"View Route\" onclick =' + '\"displayDirections("' + origins[i] + '");\"</input></div>'
});
infowindow.open(map, markers[i]);
// if user clicks on marker close the small info window to open a new
markers[i].infowindow = infowindow;
google.maps.event.addListener(markers[i], 'click', function() {
this.infowindow.close();
});
}
}
}
}
if (!atLeastOne) {
window.alert('We could not find any locations within that distance');
}
console.log("hello")
}
}
var map;
var markers = [];
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 39.9523789,
lng: -75.1635996
},
zoom: 13,
mapTypeControl: false
});
function hideMarkers(markers) {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
}
function displayDirections(origin) {
hideMarkers(markers);
var directionsService = new google.maps.DirectionsService();
var destinationAddress = document.getElementById('search-within-time-text').value;
var mode = document.getElementById('mode').value;
directionsService.route({
origin: origin,
destination: destinationAddress,
travelMode: google.maps.TravelMode[mode]
}, function(response, status) {
console.log(response)
console.log(status)
if (status === google.maps.DirectionsStatus.OK) {
var directionsDisplay = new google.maps.DirectionsRenderer({
map: map,
directions: response,
draggable: true,
polylineOptions: {
strokeColor: 'black'
}
}, console.log(map), console.log(response));
} else {
window.alert('Directions request failed due to ' + status);
}
});
console.log("testing")
}
google.maps.event.addDomListener(window, 'load', initMap)
html,
body,
#map {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
background-color: white;
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<input type="button" value="search" id="search-within-time" />
<input type="text" value="coffee" id="search-within-time-text" />
<input type="button" value="Show" id="show-listings" />
<input type="button" value="Hide" id="hide-listings" />
<input type="text" value="DRIVING" id="mode" />
<input type="text" value="1200" id="max-duration" />
<div id="map"></div>
I need to display the results of a distance matrix request without geocoding. The problem is my locations are too close together and thus the resultant geocoded addresses are the same.
If I could display the results with the variable names or even the original lat/lon coordinate pairs I would be able to distinguish between the locations.
I checked the documentation for the Distance Matrix Response Elements and I did not see this functionality.
The javascript is below.
function initMap() {
var bounds = new google.maps.LatLngBounds;
var markersArray = [];
var origin1 = {lat: 37.2692332704, lng: -81.7261622975};
var origin2 = {lat: 37.2625193371, lng: -81.7183645359};
var origin3 = {lat: 37.1315998981, lng: -81.8552666961};
var destinationA = {lat: 37.1854557602, lng: -81.7946133276};
var destinationB = {lat: 37.1751720467, lng: -81.792833926};
var destinationC = {lat: 37.1595851233, lng: -81.8570206921};
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';
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 37.2692332704, lng: -81.7261622975},
zoom: 8
});
var geocoder = new google.maps.Geocoder;
var service = new google.maps.DistanceMatrixService;
service.getDistanceMatrix({
origins: [origin1, origin2,origin3],
destinations: [destinationA, destinationB,destinationC],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
}, function(response, status) {
if (status !== google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
var originList = response.originAddresses;
var destinationList = response.destinationAddresses;
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = '';
var showGeocodedAddressOnMap = function(asDestination) {
var icon = asDestination ? destinationIcon : originIcon;
return function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
map.fitBounds(bounds.extend(results[0].geometry.location));
markersArray.push(new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: icon
}));
} else {
alert('Geocode was not successful due to: ' + status);
}
};
};
for (var i = 0; i < originList.length; i++) {
var results = response.rows[i].elements;
//geocoder.geocode({'address': originList[i]},
//showGeocodedAddressOnMap(false));
for (var j = 0; j < results.length; j++) {
//geocoder.geocode({'address': destinationList[j]},
//showGeocodedAddressOnMap(true));
outputDiv.innerHTML += originList[i] + ' to ' + destinationList[j] +
': ' + results[j].distance.text + ' in ' +
results[j].duration.text + '<br>';
}
}
}
});
}
Thanks in advance.
The results are returned in the order requested.
origin1 - destination1
origin1 - destination2
origin1 - destination3
origin2 - destination1
---
origin3 - destination3
You can use your original request to identify the exact coordinates used to calculate the result.
proof of concept fiddle
code snippet:
function initMap() {
var bounds = new google.maps.LatLngBounds();
var markersArray = [];
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';
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 37.2692332704,
lng: -81.7261622975
},
zoom: 8
});
var originArray = [origin1, origin2, origin3];
var destinationArray = [destinationA, destinationB, destinationC];
for (var i = 0; i < originArray.length; i++) {
var oMarker = new google.maps.Marker({
position: originArray[i],
map: map,
label: "" + i,
icon: originIcon
});
bounds.extend(oMarker.getPosition());
}
for (var i = 0; i < destinationArray.length; i++) {
var dMarker = new google.maps.Marker({
position: destinationArray[i],
map: map,
label: "" + i,
icon: destinationIcon
});
bounds.extend(dMarker.getPosition());
}
map.fitBounds(bounds);
var service = new google.maps.DistanceMatrixService;
service.getDistanceMatrix({
origins: originArray,
destinations: destinationArray,
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
}, function(response, status) {
if (status !== google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
var originList = response.originAddresses;
var destinationList = response.destinationAddresses;
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = '';
outputHTML = "";
outputHTML += "<table border='1'><thead><tr><th>Oi</th><th>origin</th><th></th><th>Di</th><th>destination</th><th>distance</th><th>duration</th></tr></thead><tbody>";
for (var i = 0; i < originList.length; i++) {
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++) {
outputHTML += "<tr><td>O" + i + "</td><td>" + originArray[i].lat + "," + originArray[i].lng + "</td><td> to </td><td>D" + j + "</td><td>" + destinationArray[j].lat + "," + destinationArray[j].lng +
"</td><td>" + results[j].distance.text + "</td><td> in " +
results[j].duration.text + "</td></tr>";
}
}
outputHTML += "</tbody></table>";
outputDiv.innerHTML = outputHTML;
}
});
}
google.maps.event.addDomListener(window, "load", initMap);
var origin1 = {
lat: 37.2692332704,
lng: -81.7261622975
};
var origin2 = {
lat: 37.2625193371,
lng: -81.7183645359
};
var origin3 = {
lat: 37.1315998981,
lng: -81.8552666961
};
var destinationA = {
lat: 37.1854557602,
lng: -81.7946133276
};
var destinationB = {
lat: 37.1751720467,
lng: -81.792833926
};
var destinationC = {
lat: 37.1595851233,
lng: -81.8570206921
};
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="output"></div>
<div id="map"></div>
I want to calculate driving distance between given latitudes and longitudes. On my project I'm displaying markers on road. And what I want is to calculate distance between those markers not all of the routes. Can some one explain to me how can I calculate that distance?
I know I should work on DistanceMatrixService but I couldn't figure out how to work on it.
Where I put Markers:
var pointsArray = response.routes[0].overview_path;
for (var i = 0; i < pointsArray.length; i++) {
var marker = new google.maps.Marker ({
position:pointsArray[i],
draggable:false,
map:map,
flat:true
});
}
If the pointsArray comes from the directions service, you can do something like this:
var pointsArray = response.routes[0].overview_path;
for (var i = 0; i < pointsArray.length; i++) {
var marker = new google.maps.Marker({
position: pointsArray[i],
draggable: false,
map: map,
flat: true
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function (evt) {
var html = "marker #" + i + "<br />";
if (i != (markers.length - 1)) {
html += "<a href='javascript: google.maps.event.trigger(markers[" + (i + 1) + "],\"click\");'>next</a> dist:" + google.maps.geometry.spherical.computeDistanceBetween(markers[i].getPosition(), markers[i + 1].getPosition()).toFixed(2) + " meters<br />";
}
if (i !== 0) {
html += "<a href='javascript: google.maps.event.trigger(markers[" + (i - 1) + "],\"click\");'>prev</a> dist:" + google.maps.geometry.spherical.computeDistanceBetween(markers[i].getPosition(), markers[i - 1].getPosition()).toFixed(2) + " meters";
}
infowindow.setContent(html);
infowindow.open(map, marker);
}
})(marker, i))
}
Another option would be to get the distances out of the directions response.
code snippet:
var infowindow = new google.maps.InfoWindow();
var markers = [];
function initMap() {
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 7,
center: {
lat: 37.4419,
lng: -122.1419
}
});
directionsDisplay.setMap(map);
calculateAndDisplayRoute(new google.maps.LatLng(37.4419, -122.1419), new google.maps.LatLng(37.447597, -122.159582),
directionsService, directionsDisplay, map);
}
function calculateAndDisplayRoute(start, end, directionsService, directionsDisplay, map) {
directionsService.route({
origin: start,
destination: end,
travelMode: google.maps.TravelMode.DRIVING
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
var pointsArray = response.routes[0].overview_path;
for (var i = 0; i < pointsArray.length; i++) {
var marker = new google.maps.Marker({
position: pointsArray[i],
draggable: false,
map: map,
flat: true
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function(evt) {
var html = "marker #" + i + "<br />";
if (i != (markers.length - 1)) {
html += "<a href='javascript: google.maps.event.trigger(markers[" + (i + 1) + "],\"click\");'>next</a> dist:" + google.maps.geometry.spherical.computeDistanceBetween(markers[i].getPosition(), markers[i + 1].getPosition()).toFixed(2) + " meters<br />";
}
if (i !== 0) {
html += "<a href='javascript: google.maps.event.trigger(markers[" + (i - 1) + "],\"click\");'>prev</a> dist:" + google.maps.geometry.spherical.computeDistanceBetween(markers[i].getPosition(), markers[i - 1].getPosition()).toFixed(2) + " meters";
}
infowindow.setContent(html);
infowindow.open(map, marker);
}
})(marker, i))
}
} else {
alert('Directions request failed due to ' + status);
}
});
}
google.maps.event.addDomListener(window, "load", initMap);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map"></div>
I'm trying to calculate the total distance for a route with a single waypoint in it, but somehow my code only returns the distance to the first waypoint instead of the total distance.
Here's my code:
function calcRoute(homebase,from,to,via){
var start = from;
var end = to;
var wypt = [ ];
wypt.push({
location:via,
stopover:true});
var request = {
origin:start,
destination:end,
waypoints:wypt,
optimizeWaypoints: true,
travelMode: google.maps.DirectionsTravelMode.DRIVING,
unitSystem: google.maps.DirectionsUnitSystem.METRIC
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var distance = response.routes[0].legs[0].distance.text;
var time_taken = response.routes[0].legs[0].duration.text;
var calc_distance = response.routes[0].legs[0].distance.value;
}
});
}
The reason you only get the distance for legs[0] is because that is what your code is calculating. You need to sum up the distances of all the legs:
http://www.geocodezip.com/v3_GoogleEx_directions-waypoints_totalDist.html
code snippet:
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var chicago = new google.maps.LatLng(41.850033, -87.6500523);
var myOptions = {
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: chicago
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
directionsDisplay.setMap(map);
calcRoute();
}
google.maps.event.addDomListener(window, 'load', initialize);
function calcRoute() {
var request = {
// from: Blackpool to: Preston to: Blackburn
origin: "Blackpool,UK",
destination: "Blackburn,UK",
waypoints: [{
location: "Preston,UK",
stopover: true
}],
optimizeWaypoints: true,
travelMode: google.maps.DirectionsTravelMode.WALKING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var route = response.routes[0];
var summaryPanel = document.getElementById("directions_panel");
summaryPanel.innerHTML = "";
// For each route, display summary information.
for (var i = 0; i < route.legs.length; i++) {
var routeSegment = i + 1;
summaryPanel.innerHTML += "<b>Route Segment: " + routeSegment + "</b><br />";
summaryPanel.innerHTML += route.legs[i].start_address + " to ";
summaryPanel.innerHTML += route.legs[i].end_address + "<br />";
summaryPanel.innerHTML += route.legs[i].distance.text + "<br /><br />";
}
computeTotalDistance(response);
} else {
alert("directions response " + status);
}
});
}
function computeTotalDistance(result) {
var totalDist = 0;
var totalTime = 0;
var myroute = result.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
totalDist += myroute.legs[i].distance.value;
totalTime += myroute.legs[i].duration.value;
}
totalDist = totalDist / 1000.
document.getElementById("total").innerHTML = "total distance is: " + totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes";
}
html {
height: 100%
}
body {
height: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.google.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas" style="float:left;width:70%;height:100%;"></div>
<div id="control_panel" style="float:right;width:30%;text-align:left;padding-top:20px">
<div id="directions_panel" style="margin:20px;background-color:#FFEE77;"></div>
<div id="total"></div>
</div>