I am using the Google Distance Matrix https://developers.google.com/maps/documentation/distancematrix/
to calculate some delivery charges. When it outputs the results in the for loop it puts them onto a new line each time, so I end up with :
1
25
26
1
Is it possible to store each result in a variable so I can call each individual result elsewhere in the code for some maths to work out costs etc, so.....
$result1
$result2
$result3
$result4
As later on I would like to do things like result1 * result3 = etc etc.
<script>
var map;
var geocoder;
var bounds = new google.maps.LatLngBounds();
var markersArray = [];
var base = new google.maps.LatLng(55.930385, -3.118425);
var start = 'Greenwich, England';
var destinationA = 'Stockholm, Sweden';
var end = new google.maps.LatLng(55.930385, -3.118425);
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,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map'), opts);
geocoder = new google.maps.Geocoder();
calculateDistances();
}
function calculateDistances() {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [base],
destinations: [start, end],
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 = '<table border="1">';
deleteOverlays();
var stringArray = ['$runinPickup','$runinDestination'];
var htmlString = '<table border="1">';
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);
htmlString += '<tr><td>'+stringArray[j]+'</td><td>' + results[j].distance.text +'</td></tr>';
outputDiv.innerHTML += '<tr><td>'+stringArray[j]+'</td><td>' + results[j].distance.text +'</td></tr>';
}
}
htmlString += '</table>';
// outputDiv.innerHTML += '</table>';
outputDiv.innerHTML = htmlString;
// alert(htmlString);
}
}
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() {
if (markersArray) {
for (i in markersArray) {
markersArray[i].setMap(null);
}
markersArray.length = 0;
}
}
</script>
Well that shouldn't be too hard. Where you output the value, e.g.
htmlString += '<tr><td>'+stringArray[j]+'</td><td>' + results[j].distance.text +'</td></tr>';
Simply add an additional line assigning that value into a variable. I'd be inclined to add them into an array which you can loop over later.
arrResults.push(results[j].distance.text);
If you're confident you always know what each value will be, then you can simply refer to them like arrResults[0] * arrResults[2]
Related
Basically I want to use the Test.java to call the initMap method from index.js, in order to get the shortest distance from originlist to the destination.
However, when I run the Test.class,
it shows ReferenceError: "Google" is not defined in <eval> at line number 10.
The line is var bounds = new google.maps.LatLngBounds;
public class Test {
public static void main(String []args) throws ScriptException, IOException, NoSuchMethodException {
String[] addres = new String[3];
call("Airport Blvd, Singapore",new String[]{"50 Nanyang Ave, 639798 Singapore","21 Lower Kent Ridge Rd, 119077, Singapore","81 Victoria St, Singapore"});
}
public static void call(String s, String [] sarr)throws ScriptException, IOException, NoSuchMethodException{
StringBuilder sb = new StringBuilder();
sb.append(s+"*");
for(String element:sarr){
sb.append(element + "*");
}
System.out.println(sb.toString().substring(0, sb.toString().length()-1));
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
// read script file
engine.eval(Files.newBufferedReader(Paths.get("/Projects/GetShortestDistance/index.js"), StandardCharsets.UTF_8));
Invocable inv = (Invocable) engine;
// call function from script file
System.out.println("Testing:"+ inv.invokeFunction("initMap", sb.toString()));
}
}
Here is my javascript refer to the Google Developer
function initMap(longstr) {
var bounds = new google.maps.LatLngBounds;
var markersArray = [];
// longstr ='Airport Blvd, Singapore*21 Lower Kent Ridge Rd, 119077, Singapore*50 Nanyang Ave, 639798 Singapore*80 Mandai Lake Rd, 729826*551 bukit timah road'
var array = longstr.split('*');
var destination = array[0];
var origins1 = [];
for(var i =1; i<array.length;i++){
origins1.push(array[i]);
}
var min = "";
var minAddress = null;
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: 55.53, lng: 9.4},
zoom: 10
});
var geocoder = new google.maps.Geocoder;
var service = new google.maps.DistanceMatrixService;
service.getDistanceMatrix({
origins: [origin1, origin2],
destinations: [destinationA, destinationB],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
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 = '';
deleteMarkers(markersArray);
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>';
if(min > parseFloat(results[j].duration.text.slice(0, -5))){
min = parseFloat(results[j].duration.text.slice(0, -5));
minAddress = originList[i];
}
}
}
}
});
return longstr;
}
function deleteMarkers(markersArray) {
for (var i = 0; i < markersArray.length; i++) {
markersArray[i].setMap(null);
}
markersArray = [];
}
The js works fine in index.html which are able to show the distance and map.
I am working on a google maps project where I am populating the google maps with markers being read from a database (drawMarkers function). Along with that the google maps finds your current location and keeps refreshing it every couple of seconds to keep track of you on the map. My issue is that have a var closest which is also a function i am using the too find the closest marker then create directions to current locations from there. I did not know how to actually find the closest marker so i borrowed the code from another question from stack overflow and tried to adapt it to this project. I need help to get my closest function to find the closest marker and then to make it the destination in the direction service
$ionicSideMenuDelegate.canDragContent(false);
$scope.getTourMarkers = function () {
tourmarkers.getTourMarkers().success(function (data) {
$scope.tourmarkers = data;
console.log($scope.tourmarkers);
drawMarkers();
});
};
var drawMarkers = function () {
var markers;
var content;
var infoWindow;
for (var i = 0; i < $scope.tourmarkers.length; i++) {
content = '<h2>' + $scope.tourmarkers[i].title + '</h2>' +
'<br />' +
'<p>' +
'</p>';
infoWindow = new google.maps.InfoWindow({
content: content
});
var point = new google.maps.LatLng($scope.tourmarkers[i].lat, $scope.tourmarkers[i].lon);
markers = new google.maps.Marker({
label: "S",
animation: google.maps.Animation.DROP,
position: point,
map: map,
info: content
});
//SCOPE: 'this' refers to the current 'markers' object, we pass in the info and marker
google.maps.event.addListener(markers, 'click', function () {
infoWindow.setContent(this.info);
infoWindow.open(map, this);
});
}
};
var myLatlng = new google.maps.LatLng(38.5602, -121.4241);
var NAPA_HALL_LAT_LNG = new google.maps.LatLng(38.553801, -121.4212745); // just created this marker for testing purposes
var mapOptions = {
center: myLatlng,
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoomControl: true,
disableDefaultUI: true
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'SAC STATE'
});
var dest = new google.maps.Marker({
position: NAPA_HALL_LAT_LNG,
map: map,
title: 'NAPA HALL'
});
///////////////////Directions Display//////////////////////
var directionsDisplay = new google.maps.DirectionsRenderer;
var directionsService = new google.maps.DirectionsService;
//////////////////////////////////////////////////////////////////////////////////////////
//Goal of this function is to find closest marker to current location
//then to create directions to that marker.
//should be refreshed everytime in the onSuccess function
var closest = function (directionsService, directionsDisplay, marker, dest) {
var event;
function rad(x) {return x*Math.PI/180;}
function find_closest_marker( event ) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
var R = 6371; // radius of earth in km
var distances = [];
var shortest = -1;
for( i=0;i < $scope.tourmarkers.length; i++) {
content = '<h2>' + $scope.tourmarkers[i].title + '</h2>' +
'<br />' +
'<p>' +
'</p>';
infoWindow = new google.maps.InfoWindow({
var mlat = $scope.tourmarkers[i].position.lat();
var mlng = $scope.tourmarkers[i].position.lng();
var dLat = rad(mlat - lat);
var dLong = rad(mlng - lng);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(rad(lat)) * Math.cos(rad(lat)) * Math.sin(dLong/2) * Math.sin(dLong/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
distances[i] = d;
if ( shortest == -1 || d < distances[shortest] ) {
shortest = i;
}
}
alert(map.markers[shortest].title);
}
/////**directions feature should have the closest marker be the desitination//
directionsService.route({
origin: marker.position,
destination: dest.position, // i think the marker that should in here is shortest.
travelMode: google.maps.TravelMode.WALKING
}, function(response,status) {
if(status==google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
};
//////////////////////////////////////////////////////////////////////////////////////////
var onSuccess = function (position) {
marker.setPosition(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
directionsDisplay.setMap(map);
dest.setPosition(new google.maps.LatLng(38.553801, -121.4212745));
//dest.setPosition((closest(marker, $scope.tourmarkers)).position); // if you can get this line to work without commenting it out then you're set
closest(directionsService,directionsDisplay, marker,dest);
$scope.map = map;
//$scope.map.panTo(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
};
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
navigator.geolocation.watchPosition(onSuccess, onError, {
maximumAge: 3000,
timeout: 5000,
enableHighAccuracy: true
});
Everything in this project is working properly except that closest function. but even then i have already tested the directionservice and even that is working too. I just need help making the destination in the direction service to be the closest marker to current location.
i think this code is helpful for you i used this code in my project such that your requirement same as my requirement
in the below function 'data' means list of lat lng's from server
function initialize(data) {
size = 0;
counts = 0;
stops = data;
size = stops.length;
if (stops.length > 0) {
var map = new window.google.maps.Map(document
.getElementById("map"));
// new up complex objects before passing them around
var directionsDisplay = new window.google.maps.DirectionsRenderer(
{
suppressMarkers : true,
polylineOptions : {
strokeColor : "black"
}
});
var directionsService = new window.google.maps.DirectionsService();
Tour_startUp(stops);
window.tour.loadMap(map, directionsDisplay);
window.tour.fitBounds(map,stops);
/* if (stops.length > 1) */
window.tour.calcRoute(stops,directionsService,
directionsDisplay,size);
}
}
function Tour_startUp(stops) {
var stops=stops;
var counts=0;
if (!window.tour) window.tour = {
// map: google map object
// directionsDisplay: google directionsDisplay object (comes in empty)
loadMap: function (map, directionsDisplay) {
var myOptions = {
zoom:10,
center: new window.google.maps.LatLng(17.379818, 78.478542), // default to Hyderabad
mapTypeId: window.google.maps.MapTypeId.ROADMAP
};
map.setOptions(myOptions);
directionsDisplay.setMap(map);
},
fitBounds: function (map,stops) {
var bounds = new window.google.maps.LatLngBounds();
// extend bounds for each record
jQuery.each(stops, function (key, val) {
var myLatlng = new window.google.maps.LatLng(val.latitude, val.longitude);
bounds.extend(myLatlng);
});
map.fitBounds(bounds);
},
calcRoute: function (stops,directionsService, directionsDisplay,size) {
size=size;
var batches = [];
var itemsPerBatch = 10; // google API max = 10 - 1 start, 1 stop, and 8 waypoints
var itemsCounter = 0;
var wayptsExist = stops.length > 0;
var tempp=0;
while (wayptsExist) {
var subBatch = [];
var subitemsCounter = 0;
for (var j = itemsCounter; j < stops.length; j++) {
subitemsCounter++;
tempp++;
subBatch.push({
location: new window.google.maps.LatLng(stops[j].latitude, stops[j].longitude),
stopover: true
});
if (subitemsCounter == itemsPerBatch)
break;
}
itemsCounter += subitemsCounter;
batches.push(subBatch);
wayptsExist = itemsCounter < stops.length;
// If it runs again there are still points. Minus 1 before continuing to
// start up with end of previous tour leg
itemsCounter--;
}
// now we should have a 2 dimensional array with a list of a list of waypoints
var combinedResults;
var unsortedResults = [{}]; // to hold the counter and the results themselves as they come back, to later sort
var directionsResultsReturned = 0;
for (var k = 0; k < batches.length; k++) {
var lastIndex = batches[k].length - 1;
var start = batches[k][0].location;
//delay(600);
var end = batches[k][lastIndex].location;
// trim first and last entry from array
var waypts = [];
waypts = batches[k];
waypts.splice(0, 1);
waypts.splice(waypts.length - 1, 1);
var request = {
origin: start,
destination: end,
waypoints: waypts,
travelMode: window.google.maps.TravelMode.WALKING
};
(function (kk) {
directionsService.route(request, function (result, status) {
if (status == window.google.maps.DirectionsStatus.OK) {
var unsortedResult = { order: kk, result: result };
unsortedResults.push(unsortedResult);
//alert("count test");
directionsResultsReturned++;
if (directionsResultsReturned == batches.length) // we've received all the results. put to map
{
// sort the returned values into their correct order
unsortedResults.sort(function (a, b) { return parseFloat(a.order) - parseFloat(b.order); });
var count = 0;
for (var key in unsortedResults) {
if (unsortedResults[key].result != null) {
if (unsortedResults.hasOwnProperty(key)) {
if (count == 0) // first results. new up the combinedResults object
combinedResults = unsortedResults[key].result;
else {
// only building up legs, overview_path, and bounds in my consolidated object. This is not a complete
// directionResults object, but enough to draw a path on the map, which is all I need
combinedResults.routes[0].legs = combinedResults.routes[0].legs.concat(unsortedResults[key].result.routes[0].legs);
combinedResults.routes[0].overview_path = combinedResults.routes[0].overview_path.concat(unsortedResults[key].result.routes[0].overview_path);
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getNorthEast());
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getSouthWest());
}
count++;
}
}
}
directionsDisplay.setDirections(combinedResults);
var legs = combinedResults.routes[0].legs;
var summaryPanel = document.getElementById('directions_panel');
summaryPanel.innerHTML = '';
var totdist=0;
for (var i=0; i < legs.length;i++){
var markerletter = "A".charCodeAt(0);
var markerletter2= "B".charCodeAt(0)
markerletter += i;
markerletter2 += i;
markerletter = String.fromCharCode(markerletter);
markerletter2 = String.fromCharCode(markerletter2);
createMarker(directionsDisplay.getMap(),legs[i].start_location,legs[i].start_address,markerletter,size);//To display location address on the marker
var routeSegment = i + 1;
var point=+routeSegment+1;
summaryPanel.innerHTML += '<b>Route Segment: ' + routeSegment + '</b><br>';
summaryPanel.innerHTML += '<b>Point '+ routeSegment +' :</b>'+ ' ' +legs[i].start_address + ' <br> ';
summaryPanel.innerHTML += '<b>Point '+ point +' :</b>'+ ' '+legs[i].end_address + '<br>';
summaryPanel.innerHTML += '<b>Distance Covered '+' :</b>'+legs[i].distance.text + '<br><br>';
var test=legs[i].distance.text.split(' ');
var one=parseFloat(test[0]);
if(test[1]=="m"){
var one=parseFloat(test[0]/1000);
}
totdist=parseFloat(totdist)+parseFloat(one);
}
summaryPanel.innerHTML += '<b> Total Distance :'+totdist + 'km'+ '</b><br><br>';
var i=legs.length;
var markerletter = "A".charCodeAt(0);
markerletter += i;
markerletter = String.fromCharCode(markerletter);
createMarker(directionsDisplay.getMap(),legs[legs.length-1].end_location,legs[legs.length-1].end_address,markerletter,size);
}
}
});
})(k);
function delay(ms) {
ms += new Date().getTime();
while (new Date() < ms){}
}
}
}//calculate route end
};
}
//to show information on clicking marker
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50)
});
var icons = new Array();
icons["red"] = new google.maps.MarkerImage("mapIcons/marker_red.png",
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(20, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 9,34.
new google.maps.Point(9, 34));
function getMarkerImage(iconStr,size) {
counts++;
if(counts==size){
var markerimageLoc = "http://www.maps.google.com/mapfiles/ms/icons/blue.png";
counts = 0;
}else{
if (iconStr=="undefined") {
iconStr = "red";
var markerimageLoc = "http://www.maps.google.com/mapfiles/ms/icons/red.png";
}
else{
var markerimageLoc="http://www.google.com/mapfiles/marker"+ iconStr +".png";
// var markerimageLoc = "http://www.maps.google.com/mapfiles/ms/icons/red.png";
}
}
icons[iconStr] = new google.maps.MarkerImage(markerimageLoc,
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(25, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 6,20.
new google.maps.Point(9, 34));
return icons[iconStr];
}
// Marker sizes are expressed as a Size of X,Y
// where the origin of the image (0,0) is located
// in the top left of the image.
// Origins, anchor positions and coordinates of the marker
// increase in the X direction to the right and in
// the Y direction down.
var iconShadow = new google.maps.MarkerImage('http://www.google.com/mapfiles/shadow50.png',
// The shadow image is larger in the horizontal dimension
// while the position and offset are the same as for the main image.
new google.maps.Size(37, 34),
new google.maps.Point(0,0),
new google.maps.Point(9, 34));
// Shapes define the clickable region of the icon.
// The type defines an HTML <area> element 'poly' which
// traces out a polygon as a series of X,Y points. The final
// coordinate closes the poly by connecting to the first
// coordinate.
var iconShape = {
coord: [9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,20,12,20,8,18,4,16,2,15,1,13,0],
type: 'poly'
};
function createMarker(map, latlng, label, character,size) {
var markerletter = character;
var size=size;
if (/[^a-zA-Z]/.test(character)) {
var markerletter = "undefined";
}
var contentString = '<b>' + label + '</b><br>';
var marker = new google.maps.Marker({
position : latlng,
map : map,
shadow : iconShadow,
icon : getMarkerImage(markerletter,size),
shape : iconShape,
title : label,
zIndex : Math.round(latlng.lat() * -100000) << 5
});
marker.myname = label;
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
return marker;
}
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 am playing around with the Google Maps API v3 for a project I am building.The premise is the user can draw a route on the map however at any point can clear it and start again. The issue I am having is restarting the polyline after the map has been cleared. Whilst the markers appear the polyline does not.
I have discovered that the line poly.setMap(null); only hides the polyline that is draw and doesn't clear it therefore it is understandable why the line doesn't show. However on finding this out I now need to know how to clear it and how it can be restarted.
The code is below:
var poly;
var map, path = new google.maps.MVCArray(),
service = new google.maps.DirectionsService(), poly;
var removepolyline;
var geocoder;
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 count = 0;
var countname = 0;
var latitude_start;
var longitude_start;
function initialize() {
var mapOptions = {
zoom: 16,
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
geocoder = new google.maps.Geocoder();
///Geolocation
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
var infowindow = new google.maps.InfoWindow({
map: map,
position: pos,
content: 'Current Location'
});
map.setCenter(pos);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
///Place fallback loop
}
///Allows the polyline to follow the road
poly = new google.maps.Polyline({ map: map });
google.maps.event.addListener(map, "click", function(evt) {
if (path.getLength() === 0) {
//Enters on first click
path.push(evt.latLng);
poly.setPath(path);
} else {
//Enters on second click
service.route({
origin: path.getAt(path.getLength() - 1),
destination: evt.latLng,
travelMode: google.maps.DirectionsTravelMode.DRIVING
}, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
for (var i = 0, len = result.routes[0].overview_path.length;
i < len; i++) {
path.push(result.routes[0].overview_path[i]);
}
}
});
}
var latitude_longitude = evt.latLng;
var latitude = evt.latLng.lat();
var longitude = evt.latLng.lng();
//alert(latitude_longitude);
//alert(latitude);
// alert(longitude);
///Saves the first click location
if(count === 0){
var latitude_start = evt.latLng.lat();
var longitude_start = evt.latLng.lng();
var firstlat = latitude_start;
var firstlng = longitude_start;
/////Trying to calculate distance
var origin1 = new google.maps.LatLng(firstlat, firstlng);///1st click - never changes
document.getElementById("origin1").value = origin1;
document.getElementById("startpoint").value = origin1;
////Calculate distance
var destinationA = new google.maps.LatLng(latitude, longitude); ///Most recent click
document.getElementById("destination").value = destinationA; ////Stores Destination
var origin1 = document.getElementsByName('origin1')[0].value ////Retrieves value from text box
count ++;
}else{
var origin1 = document.getElementsByName('destination')[0].value ////Retrieves value from text box
////Calculate distance
var destinationA = new google.maps.LatLng(latitude, longitude); ///Most recent click
document.getElementById("destination").value = destinationA; ////Stores Destination
}
////Calculate distance
var servicetime = new google.maps.DistanceMatrixService();
servicetime.getDistanceMatrix(
{
origins: [origin1],
destinations: [destinationA],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
}, callback);
});
function callback(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
var origins = response.originAddresses;
///Enters the if it is the first loop round/first click
if(countname === 0){
document.getElementById("startpointname").value = origins;
countname ++;
}
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++) {
outputDiv.innerHTML += start + ' to ' + destinations[j]
+ ': ' + miles + ' miles in '
+ overalltime + ' minutes <br>';
}
}
}
}
// Add a listener for the click event
google.maps.event.addListener(map, 'click', addLatLng);
}////Function initialize ends here
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = 'Error: The Geolocation service failed.';
} else {
var content = 'Error: Your browser doesn\'t support geolocation.';
}
var options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
var infowindow = new google.maps.InfoWindow(options);
map.setCenter(options.position);
}
/**
* Handles click events on a map, and adds a new point to the Polyline.
* #param {google.maps.MouseEvent} event
*/
function addLatLng(event) {
// Add a new marker at the new plotted point on the polyline.
var marker = new google.maps.Marker({
position: event.latLng,
title: '#' + path.getLength(),
map: map
});
markersArray.push(marker);
}///Function addLatLng ends here
// Removes the markers from the map, but keeps them in the array.
function clearMarkers() {
for (var i = 0; i < markersArray.length; i++) {
markersArray[i].setMap(null);
}
}
function clearall() {
poly.setMap(null);//Just hiding them
clearMarkers();
markersArray = [];
///////////////////CLEAR ALL VALUES IN HERE i.e. miles, time etc and CLEAR MARKERS
restartpolyline();
}
//////////////////////////////////////////WHEN CLEARED THE CODE NEEDS INTITALISING AGAIN
function restartpolyline(){
//alert("Restart");
}
//https://developers.google.com/maps/documentation/javascript/reference#Polyline
google.maps.event.addDomListener(window, 'load', initialize);
To view what currently happens view the following link: http://kitlocker.com/sotest.php
Instead of poly.setMap(null); call path.clear();
Polyline is just an array of LatLng objects, not individual Polylines, which you can then loop over to remove them all.
You can make it invisible or remove it from the map by looping it like this:
var size = poly.length;
for (i=0; i<size; i++)
{
poly[i].setMap(null);
}
I am new to AJAX and JavaScript so please forgive me if I am acting stupid but I am trying to pass the variable routeMid to the php page processing.php(preferable automatically one routeMid has been calculated) I tried out this code but it breaks the entire webpage. I attached the snippet with the ajax part I am having trouble with and the php code on the next page so any help would be greatly appreciated. Thanks again in advance!
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false">
</script>
<script type ="text/javascript" src="http://www.geocodezip.com/scripts/v3_epoly.js"></script>
<script type="text/javascript">
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var polyline = null;
var infowindow = new google.maps.InfoWindow();
var addresses = <?php echo json_encode($addresses); ?>;
function createMarker(latlng, label, html) {
var contentString = '<b>'+label+'</b><br>'+html;
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: label,
zIndex: Math.round(latlng.lat()*-100000)<<5
});
marker.myname = label;
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString+"<br>"+marker.getPosition().toUrlValue(6));
infowindow.open(map,marker);
});
return marker;
}
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer({suppressMarkers:true});
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);
polyline = new google.maps.Polyline({
path: [],
strokeColor: '#FF0000',
strokeWeight: 3
});
directionsDisplay.setMap(map);
calcRoute();
}
function calcRoute() {
var start = addresses[0];
var end = addresses[1];
var travelMode = google.maps.DirectionsTravelMode.DRIVING
var request = {
origin: start,
destination: end,
travelMode: travelMode
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
polyline.setPath([]);
var bounds = new google.maps.LatLngBounds();
startLocation = new Object();
endLocation = new Object();
directionsDisplay.setDirections(response);
var route = response.routes[0];
var summaryPanel = document.getElementById("directions_panel");
summaryPanel.innerHTML = "";
// For each route, display summary information.
var path = response.routes[0].overview_path;
var legs = response.routes[0].legs;
for (i=0;i<legs.length;i++) {
if (i == 0) {
startLocation.latlng = legs[i].start_location;
startLocation.address = legs[i].start_address;
marker = createMarker(legs[i].start_location,"midpoint","","green");
}
endLocation.latlng = legs[i].end_location;
endLocation.address = legs[i].end_address;
var steps = legs[i].steps;
for (j=0;j<steps.length;j++) {
var nextSegment = steps[j].path;
for (k=0;k<nextSegment.length;k++) {
polyline.getPath().push(nextSegment[k]);
bounds.extend(nextSegment[k]);
}
}
}
polyline.setMap(map);
computeTotalDistance(response);
} else {
alert("directions response "+status);
}
});
}
var totalDist = 0;
var totalTime = 0;
function computeTotalDistance(result) {
totalDist = 0;
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;
}
putMarkerOnRoute(50);
var routeMid = putMarkerOnRoute(50);
document.getElementById("hiddenVal").value = routeMid;
$(".clickable").click(function() {
//alert($(this).attr('id'));
$.ajax({
type: "POST",
url: 'processing.php',
data: { value : routeMid }
});
});
});
totalDist = totalDist / 1000.
}
function putMarkerOnRoute(percentage) {
var distance = (percentage/100) * totalDist;
var time = ((percentage/100) * totalTime/60).toFixed(2);
var routeMidpoint;
if (!marker) {
marker = createMarker(polyline.GetPointAtDistance(distance),"time: "+time,"marker");
routeMidpoint = polyline.GetPointAtDistance(distance);
} else {
marker.setPosition(polyline.GetPointAtDistance(distance));
marker.setTitle("time:"+time);
routeMidpoint = polyline.GetPointAtDistance(distance);
}
return routeMidpoint;
}
</script>
processing.php
<?php
echo $_POST["value"];
?>
I think this is what you are trying to accomplish:
$(document).ready(function() {
function computeTotalDistance() {
totalDist = 0;
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;
}
putMarkerOnRoute(50);
var routeMid = putMarkerOnRoute(50);
document.getElementById("hiddenVal").value = routeMid;
$.ajax({
type: "POST",
url: 'processing.php',
data: { value : routeMid },
success:function(result){
alert("returned from php page: " + result);
}
});
totalDist = totalDist / 1000.
}
});
And then you can do what you want with the ajax result. I'm not sure what you are trying to accomplish with the click(). If you are trying to call the above function then this will work:
$(".clickable").click(function() {
computeTotalDistance();
});