How to optimize route using the google direction API - google-maps

I am using the google direction api to solve the travelling salesman problem.
Apparently the api takes a param called optimize:true and then return a "waypoint_order": [ 1, 0, 2, 3 ] telling you the best order of waypoints that optimizes the route.
Thing is, when you try to optimize the route, the API just does not work and you get NO_RESULTS.
For instance use this url to see how the API fails when the optimize:true| bit gets added.
NOT working (NO_RESULTS error):
https://maps.googleapis.com/maps/api/directions/json?origin=place_id:ChIJdd4hrwug2EcRmSrV3Vo6llI&destination=place_id:ChIJh1a5WhEMa0gRY1JU4PEam8Q&waypoints=optimize:true|place_id:ChIJPeqVDlONbEgRk4X1zrUsKDs|place_id:ChIJ_WegsaCYc0gRlCypaxXgLjs|&key=YOUR_KEY
WORKING (but not optimizing):
NOT optimizing url: https://maps.googleapis.com/maps/api/directions/json?origin=place_id:ChIJdd4hrwug2EcRmSrV3Vo6llI&destination=place_id:ChIJh1a5WhEMa0gRY1JU4PEam8Q&waypoints=place_id:ChIJPeqVDlONbEgRk4X1zrUsKDs|place_id:ChIJ_WegsaCYc0gRlCypaxXgLjs|&key=YOUR_KEY
Does anyone know if they stopped supporting routes optimization?
Thanks

Looks to me like that is a bug in the DirectionsService when you pass in PlaceIds. I replicated it with the Javascript API. Using addresses works:
waypts = [];
waypts.push({
location: "Plymouth, UK", // {placeId:"ChIJPeqVDlONbEgRk4X1zrUsKDs"},
stopover: true
});
waypts.push({
location: "Bournemouth, UK", // {placeId:"ChIJ_WegsaCYc0gRlCypaxXgLjs"},
stopover: true
});
var request = {
origin: "London, UK", //{placeId:"ChIJdd4hrwug2EcRmSrV3Vo6llI"},
destination: "Newquay, UK", //{placeId: "ChIJh1a5WhEMa0gRY1JU4PEam8Q"},
waypoints: waypts,
optimizeWaypoints: true,
travelMode: 'DRIVING'
};
fiddle using addresses (returns waypoint order=1,0)
But the same locations (I used these placeIds to get the addresses above) doesn't work using placeIds:
waypts = [];
waypts.push({
location: {placeId:"ChIJPeqVDlONbEgRk4X1zrUsKDs"},
stopover: true
});
waypts.push({
location: {placeId:"ChIJ_WegsaCYc0gRlCypaxXgLjs"},
stopover: true
});
var request = {
origin: {placeId:"ChIJdd4hrwug2EcRmSrV3Vo6llI"},
destination: {placeId: "ChIJh1a5WhEMa0gRY1JU4PEam8Q"},
waypoints: waypts,
optimizeWaypoints: true,
travelMode: 'DRIVING'
};
fiddle using placeId (returns ZERO_RESULTS)
might be related to this issue in the issue tracker: Issue 8979: Bug: Can't use combination of placeId and String for origin/destination

Related

Google Maps Route API V3: Bug for specific location, only when set as destination?

I'm currently using the Google Maps API to find transit routes between two locations. It works fine on almost all occassions, except when the destination is Schiphol, Netherlands (the national Dutch airport).
No matter what the starting location is, the Google Maps API won't find any transit routes that lead to Schiphol. Strange, because when I enter the exact same locations on http://maps.google.com, Google finds plenty of routes. Also, everything works fine when Schiphol, Netherlands is the starting point.
Please refer to this JSFiddle, or the code below.
var directionsService = new google.maps.DirectionsService;
directionsService.route({
origin: 'Rotterdam, Netherlands',
destination: 'Schiphol, Netherlands', // Change this to e.g. 'The Hague, Netherlands' and it works.
travelMode: google.maps.TravelMode.TRANSIT,
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
var route = response.routes[0].legs[0];
window.alert('When Schiphol is destination: noute found!')
} else {
window.alert('When Schiphol is destination: no transit routes found.')
}
});
directionsService.route({
origin: 'Schiphol, Netherlands',
destination: 'Rotterdam, Netherlands',
travelMode: google.maps.TravelMode.TRANSIT,
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
var route = response.routes[0].legs[0];
window.alert('When Schiphol is origin: route found!')
} else {
window.alert('When Schiphol is origin: no transit routes found.')
}
});

Plotting more than 8 waypoints in Google Maps v3

Migrating code from Javascript API 2 to 3. I have a list of locations which i need to plot in the form of a driving directions. This was done in v2 using the following code
directions = new GDirections(map);
directions.loadFromWaypoints(waypoints, {preserveViewport: true});
Here is my attempt at converting this to V3
var request = {
origin: startLoc,
destination: endLoc,
waypoints: waypoints,
optimizeWaypoints: true,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
Not the whole code, but the general idea. Seems to work fine, with one little issue. When there are more than 8 waypoints, the call fails. This is expected since Google Maps API v3 Docs states
The maximum allowed waypoints is 8, plus the origin, and destination. Maps API for Business customers are allowed 23 waypoints, plus the origin, and destination. Waypoints are not supported for transit directions.
Since i didn't run in to this issue in v2, is this a new restriction with v3? I wonder if i am using something that was not designed for what i need. This is a very lightly used applicaton with 2 users, so i am not sure if an expensive business license is worth the return. Emails to Google maps team have not yet been returned. Any workarounds/pointers will be of great help. Thanks.
One possible work around (particularly for a lightly used site) is to use multiple DirectionsService requests.
example 1 (addresses)
example 2 (coordinates)
Use Should need to Use array concept like these...
directionsService[i].route({
'origin': start,
'destination': end
'waypoints': waypts,
'travelMode': 'DRIVING'
},
function (directions, status){
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay[j].setDirections(directions);
}
});
in these directionservice and directiondisplay are should be in array logic
and using looping concepts use should need to assign start,end and waypoints dynamically and
try sending multiple request means u ll get the route for n number of latlon's ...but the markers ll be repeat with same name after 8 waypoints for that we remove the default markers by using supressmarkers false property...
As others said, it's imposable to do it using Google's JavaScript API. However, Google does allow up to 23 waypoints with a server-side request. So using PHP and JavaScript, I was able to make a workaround.
What you have to do is get the "waypoint order" from the server side request and then have JavaScript give you directions between each location.
<?php
$startLocation = "40.713,-74.0135";
$endLocation = "40.75773,-73.985708";
$waypoints = array("40.748433,-73.985656|", "40.689167,-74.044444|");
$apiKey = "";
$routeData = json_decode(file_get_contents("https://maps.googleapis.com/maps/api/directions/json?origin=".$startLoc."&destination=".$endLoc."&waypoints=optimize:true|".$waypoints."&key=".$apiKey));
echo "var waypointsOrder = ". json_encode($routeData->routes[0]->waypoint_order) . ";\n";
?>
var startLocation = {lat: 40.713, lng: -74.0135};
var endLocation = {lat: 40.75773, lng: -73.985708};
//get directions from the origin to the first waypoint
var request = {
origin: startLocation,
destination: JSON.parse(places[waypointsOrder[0]][1]),
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
renderDirections(result, map);
}
});
//get directions from the last waypoint to the destination
var request = {
origin: JSON.parse(places[waypointsOrder[waypointsOrder.length-1]][1]),
destination: endLocation,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
renderDirections(result, map);
}
});
//get directions between each waypoint
for (i = 1; i < waypointsOrder.length; i++) {
var request = {
origin: JSON.parse(places[waypointsOrder[i-1]][1]),
destination: JSON.parse(places[waypointsOrder[i]][1]),
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
renderDirections(result, map);
}
});
}
function renderDirections(result, map) {
var directionsDisplay = new google.maps.DirectionsRenderer ({
map: map
});
directionsDisplay.setMap(map);
directionsDisplay.setDirections(result);
}

Google Maps Api straight (shortest) route

I am currently trying to find a way how to get a straight route with Google Maps Api V3.
I already managed it to use geocode and the directions service to get a route from point A to point B, including two alternative routes. I also experimented with "No highways" and "No tolls" but nothing appears to solve this problem entirely...
At the moment I check the three given routes for lowest miles but this has to be proven not really to be the shortest route.
I am not searching the fastest or quickest route but just a straight route with as low miles as possible.
As I did not find any thread by using google explaining something like I need I ask you. Maybe somebody has a solution here...
P.S.: I also can't use the "Pedestrian Mode" as this is used as a navigation help for our local fire trucks when our mounted navigation systems do not work again.
This is also the reason why we need as low kilometers as possible - when driving a firetruck round here the fastest route is 99% the one with lowest miles but the Api won't let me decide that and insist on using principal roads
To obtain the shortest route from A to B I would suggest to make different queries with the “alternatives=true” parameter, playing with the “avoid” parameter between avoid=toll, avoid=highways, and then I would compare all results to pick the shortest route.
directionsService = new google.maps.DirectionsService;
//avoiding tolls
directionsService.route({
origin: {
'placeId': originId
},
destination: {
'placeId': destinationId
},
provideRouteAlternatives: true,
avoidTolls: true,
travelMode: google.maps.TravelMode.DRIVING
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
routesResponses.push(response);
}
else {
window.alert('Directions request failed due to ' + status);
}
});
//avoiding highways
directionsService.route({
origin: {
'placeId': originId
},
destination: {
'placeId': destinationId
},
provideRouteAlternatives: true,
avoidHighways: true,
travelMode: google.maps.TravelMode.DRIVING
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
routesResponses.push(response);
}
else {
window.alert('Directions request failed due to ' + status);
}
//Results analysis and drawing of routes
var fastest = Number.MAX_VALUE,
shortest = Number.MAX_VALUE;
routesResponses.forEach(function(res) {
res.routes.forEach(function(rou, index) {
console.log("distance of route " +index+": " , rou.legs[0].distance.value);
console.log("duration of route " +index+": " , rou.legs[0].duration.value);
if (rou.legs[0].distance.value < shortest) shortest = rou.legs[0].distance.value ;
if (rou.legs[0].duration.value < fastest) fastest = rou.legs[0].duration.value ;
})
})
console.log("shortest: ", shortest);
console.log("fastest: ", fastest);
//painting the routes in green blue and red
routesResponses.forEach(function(res) {
res.routes.forEach(function(rou, index) {
new google.maps.DirectionsRenderer({
map:map,
directions:res,
routeIndex:index,
polylineOptions:{
strokeColor: rou.legs[0].duration.value == fastest? "red":rou.legs[0].distance.value == shortest?"darkgreen":"blue",
strokeOpacity: rou.legs[0].duration.value == fastest? 0.8:rou.legs[0].distance.value == shortest? 0.9: 0.5,
strokeWeight: rou.legs[0].duration.value == fastest? 9:rou.legs[0].distance.value == shortest? 8: 3,
}
})
})
})
});
}
}
I use a solution, as I said here, that calls route service once and filters the results in a way that you find usefull. In my example, I'm calculating the shortest route.

Display multiple way points in route

Need help in Google Map V3
I want to display multiple points in the route.
Currently i have mentioned origin and destination, but how can I display all the points which I have in the waypoint (arrWaypoints) array?
Below is my code.
var origin = arrWaypoints[0];
var destination = arrWaypoints[1];
this.directions.route({
origin: origin,
destination: destination,
travelMode: google.maps.DirectionsTravelMode.DRIVING,
unitSystem: google.maps.DirectionsUnitSystem.METRIC
}, function(result, status) {
........
Thanks,
Sharath
In your example, there are no waypoints to display. If you have additional waypoints to include, the request would look something like this:
var origin = arrWaypoints[0];
var destination = arrWaypoints[arrWaypoints.length-1];
// Origin and destination don't need to be in the arrWaypoints anymore as they're listed separately in the request.
arrWaypoints.splice(arrWaypoints.length-1, 1);
arrWaypoints.splice(0, 1);
this.directions.route({
origin: origin,
destination: destination,
waypoints: arrWaypoints,
travelMode: google.maps.DirectionsTravelMode.DRIVING,
unitSystem: google.maps.DirectionsUnitSystem.METRIC
}, function(result, status) {
........

Google map with multiple waypoints repeatative

I tried something which is a bit out of norm on google map. What I am trying to achieve is to draw a route with multiple waypoints which are sometimes can be repeative. Let says, an Origin: A and Destination: B, and waypoints {1, 2, 3, 4, 5, 6, 7, 3, 2, 1}
From above, it will always failed. If I take out the repeat locations it will display the route.
Please help. Thanks in advanced.
wayPoints.push(
{location:new google.maps.LatLng(stepsWP[0], stepsWP[1]),
stopover: false
}
...
var request = {
origin: start,
destination: end,
waypoints: wayPoints,
optimizeWaypoints: false,
travelMode: google.maps.TravelMode.DRIVING
};
var directionsRen = new google.maps.DirectionsRenderer(rendererOptions);
directionsRen.setMap(map);
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsRen.setDirections(result);
}else{
console.debug('Something wrong with google...');
}
});
Thanks.
I did some google and found some of the suggestions on the workaround.
http://techquarries.blogspot.com/2010/08/using-more-than-8-waypoints-in-google.html
http://lemonharpy.wordpress.com/2011/12/15/working-around-8-waypoint-limit-in-google-maps-directions-api/
http://mostup.com/2011/02/15/google-map-api-v3-directionsservice-more-than-8-waypoints-workaround/
Here is what I got from Google Map Direction service page:
The maximum allowed waypoints is 8, plus the origin, and destination.
Google Maps API for Work customers are allowed 23 waypoints, plus the
origin, and destination. Waypoints are not supported for transit
directions.
So you basically need to break down your waypoints array into groups of 8 locations and use that to send requests to google direction service api.