Using TRANSIT as my travel mode in Google Map api v3 - google-maps

When I was using TRANSIT as my travel mode in Google Map api V3, I defined the origin, destination and some waypoints in DirectionsRequest. However when DirectionsResult came back, DirectionsLeg only started with my origin and ended with my destination, it skipped all my waypoints.
My codes are shown as below
Does anyone get the same problem here?
function calcRoute(waypts, mode) {
var sites = [];
var mode;
//Add waypoints to array, the first and last one are not added in waypoints
for (var i = 1; i < waypts.length-2; i++) {
sites.push({
location:waypts[i],
stopover:true}); //Set true to show that stop is required
}
var request = {
origin: waypts[0], //Set the first one as origin
destination:waypts[waypts.length-1],//Set the last one as destination
waypoints:sites,//Set waypoints
optimizeWaypoints:false,
travelMode: google.maps.TravelMode[mode]
};
//Send to Google
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var route = response.routes[0];
var HTMLContent = "";
//Get response and show on my HTML
for(var i =0; i < route.legs.length; i++){
HTMLContent = "From " + route.legs[i].start_address + "To " + route.legs[i].end_address + "<br>";
HTMLContent = HTMLContent + "Distance:" + route.legs[i].distance.text + "<br>";
}
$("#route_Scroll").append(HTMLContent);
}else{
alert(status);
}
});
}

Yup,
https://developers.google.com/maps/documentation/javascript/directions#TransitOptions
"The available options for a directions request vary between travel modes. When requesting transit directions, the avoidHighways, avoidTolls, waypoints[] and optimizeWaypoints options will be ignored. You can specify transit specific routing options through the TransitOptions object literal."
If you want to use it you would have to split the request.

You can't specify waypoints when TravelMode is TRANSIT.
the documentation (now) states:
Waypoints are not supported for transit directions.
The directions service always returns INVALID_REQUEST in that case.
Example

Related

google maps direction api taking traffic in account

I am trying to write a simple script in order to calculate in a google sheet the travelling time between two locations, by taking in account the traffic.
I am using the class DirectionFinder of the google Maps API.
I have managed to calculate the time necessary for a trip, but whatever departure time I enter, my travelling time stays the same. Any idea on what am I doing wrong ? Is it even possible to take traffic into account using this class ? Do I need to be a business user to have access to this ?
Here is my code :
function DrivingSeconds(origin, destination, Y, M, D, H, S) {
Utilities.sleep(1000);
var time= new Date(Y,M,D,H,S);
var directions = Maps.newDirectionFinder()
.setDepart(time)
.setOrigin(origin)
.setDestination(destination)
.setMode(Maps.DirectionFinder.Mode.DRIVING)
.getDirections();
return directions.routes[0].legs[0].duration.value;
}
Thanks for any advice that you might have ! :)
From Google documentation:
For requests where the travel mode is driving: You can specify the departure_time to receive a route and trip duration (response field: duration_in_traffic) that take traffic conditions into account. This option is only available if the request contains a valid API key, or a valid Google Maps APIs Premium Plan client ID and signature. The departure_time must be set to the current time or some time in the future. It cannot be in the past.
https://developers.google.com/maps/documentation/directions/intro#RequestParameters
So yes, only for Premium users.Then your request should look like this:
var request = {
origin: origin,
destination: destination,
drivingOptions: {
departureTime: new Date(),
},
travelMode: google.maps.TravelMode[DRIVING]
};
var directionsService = new google.maps.DirectionsService();
directionsService.route(request, function(response,status) {
if(status == google.maps.DirectionsStatus.OK) {
console.log(response.routes[0].legs[0].duration_in_traffic);
}
});
directions.routes[0].legs[0].duration_in_traffic may be what you need.
E.g. this code:
function traffic_test() {
var threeAM = new Date();
threeAM.setDate(threeAM.getDate() + 1);
threeAM.setHours(3, 0, 0);
var eightAM = new Date(threeAM);
eightAM.setHours(8, 0, 0);
var directionFinder = Maps.newDirectionFinder()
.setOrigin('Union Square, San Francisco')
.setDestination('Golden Gate Park, San Francisco')
.setMode(Maps.DirectionFinder.Mode.DRIVING);
var directions = directionFinder.setDepart(threeAM).getDirections();
var leg = directions.routes[0].legs[0];
Logger.log('3AM: leg.duration=' + leg.duration.text +
'; leg.duration_in_traffic=' + leg.duration_in_traffic.text);
directions = directionFinder.setDepart(eightAM).getDirections();
leg = directions.routes[0].legs[0];
Logger.log('8AM: leg.duration=' + leg.duration.text +
'; leg.duration_in_traffic=' + leg.duration_in_traffic.text);
}
logs this:
[19-07-21 08:39:54:606 PDT] 3AM: leg.duration=16 mins; leg.duration_in_traffic=12 mins
[19-07-21 08:39:54:795 PDT] 8AM: leg.duration=16 mins; leg.duration_in_traffic=16 mins

How to find whether traffic is in given path or not using google maps api

geocomplete = "<?php echo $source ?>";
autocomplete = "<?php echo $destination ?>";
var request = {
origin: geocomplete,
destination: autocomplete,
travelMode: google.maps.DirectionsTravelMode.DRIVING,
provideRouteAlternatives: true,
};
directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
if (true) {
size = result.routes.length;
for (i = 0; i < result.routes.length; i++) {
// alert("Route "+ (i+1)+" is "+result.routes[i].summary);
summary[i] = result.routes[i].summary;
distance[i] = result.routes[i].legs[0].distance.text;
duration[i] = result.routes[i].legs[0].duration.text;
};
}
}
}
This is my code I can get the distance ,time and summary for given route using Google maps API , i need to check whether is there any traffic in given route? how to traffic details? i do not want whole traffic details . i just wanted to know . Traffic is there or not like Boolean option. Thanks in advance
Directions Service
durationInTraffic (optional) specifies whether the DirectionsLeg result should include a duration that takes into account current traffic conditions. This feature is only available for Google Maps API for Work customers. The time in current traffic will only be returned if traffic information is available in the requested area.
You also have the Traffic Layer but there is no documented method to retrieve detailed information.

Google Maps Route Generation with Waypoints

I've got an existing app that tracks vehicles and renders their polyline on a map, and I want to be able to import these polylines into another app using the routing service (so that the imported polyline snaps to the road and can be dragged around etc).
What I'm currently doing is encoding:
var encoded_path = google.maps.geometry.encoding.encodePath(coordinate_array)
The lat lng coordinates array that draws the line (inside the polyline app), and passing this into the directions service route like so (inside the other app):
var coordinates = google.maps.geometry.encoding.decodePath(encoded_path);
var request = {
origin: coordinates[0],
destination: coordinates[coordinates.length - 1],
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
MapService.directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
MapService.directionsDisplay.setDirections(response);
}
});
The problem with this approach is that it's only using the start and end of the polyline to draw the route, so all of the diversions along the route are not shown. So I tried to add waypoints (Google has a limit of 8) to try and get a slightly more accurate route like so:
var waypoints = [];
if (coordinates.length <= 8) {
waypoints = coordinates;
}
else {
for (var i = 0; i < 8; i++) {
var index = Math.floor((coordinates.length/8) * i);
// Break if there's no more waypoints to be added
if (index > coordinates.length - 1)
break;
waypoints.push(new google.maps.LatLng(coordinates[index].lat(), coordinates[index].lng()));
// Break if we've just added the last waypoint
if (index == coordinates.length - 1)
break;
}
}
This way it gets waypoints evenly across the coordinates array. And then I'm trying to display them like so on my call to route:
var request = {
origin: coordinates[0],
destination: coordinates[coordinates.length - 1],
waypoints: waypoints
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
But I'm getting this error: Error: in property waypoints: at index 0: unknown property lb
Does anyone know what could be happening, or how to do this waypoint stuff? I can confirm that the array is correctly generated through the console, here's an example of the first array element:
Array[8]
0: N
lb: -22.39019
mb: 143.04560000000004
__prot__: N
1:...etc etc
Thank you.
waypoints.push(new google.maps.LatLng(coordinates[index].lat(), coordinates[index].lng()));
the 'waypoints' property of the DirectionsRequest object definition should be an Array of google.maps.DirectionsWaypoint object definitions https://developers.google.com/maps/documentation/javascript/3.exp/reference#DirectionsWaypoint
So, try:
waypoints.push(
{
location: new google.maps.LatLng(coordinates[index].lat(), coordinates[index].lng())
}
);

Latitude and longitude can find zip code?

I am using Google geocoder for lat and lon and my question is, is there a way you can find out zipcode with latitude and longitude?
It's good to note that Google Maps has a new version since this solultion was presented.
Reference: https://developers.google.com/maps/documentation/geocoding/?csw=1#ReverseGeocoding
Here's an updated example for Google Maps v3. It makes use of the Address Components that JIssak mentions above. I should note that there is no fallback. If it fails to find a zip code, it does nothing. This may or may not be important to your script.
var latlng = new google.maps.LatLng(p.coords.latitude, p.coords.longitude);
geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
for (j = 0; j < results[0].address_components.length; j++) {
if (results[0].address_components[j].types[0] == 'postal_code')
alert("Zip Code: " + results[0].address_components[j].short_name);
}
}
} else {
alert("Geocoder failed due to: " + status);
}
});
I think what you are looking for is the address_components[] in the results array. Maybe something like this would work, just typing the below so it might have errors in it but I think you will get the idea.
http://code.google.com/apis/maps/documentation/geocoding/#Results
function (request, response) {
geocoder.geocode({ 'address': request.term, 'latLng': centLatLng, 'region': 'US' }, function (results, status) {
response($.map(results, function (item) {
return {
item.address_components.postal_code;//This is what you want to look at
}
}
[Removed non-working solution for google - see #hblackorby's solution.]
Here's a version that uses openstreetmap.org, much simpler than google's api - coffeescript, then javascript:
getZip = (cb) ->
# try to populate zip from geolocation/google geocode api
if document.location.protocol == 'http:' && navigator.geolocation?
navigator.geolocation.getCurrentPosition (pos) ->
coords = pos.coords
url = "http://nominatim.openstreetmap.org/reverse?format=json&lat=#{ coords.latitude }&lon=#{ coords.longitude }&addressdetails=1"
$.ajax({
url: url,
dataType: 'jsonp',
jsonp: 'json_callback',
cache: true,
}).success (data) ->
cb(data.address.postcode)
Here's the compiled javascript:
getZip = function(cb) {
if (document.location.protocol === 'http:' && (navigator.geolocation != null)) {
return navigator.geolocation.getCurrentPosition(function(pos) {
var coords, url;
coords = pos.coords;
url = "http://nominatim.openstreetmap.org/reverse?format=json&lat=" + coords.latitude + "&lon=" + coords.longitude + "&addressdetails=1";
return $.ajax({
url: url,
dataType: 'jsonp',
jsonp: 'json_callback',
cache: true
}).success(function(data) {
return cb(data.address.postcode);
});
});
}
};
Use it like this:
getZip(function(zipcode){ console.log("zip code found:" + zipcode); });
Yahoo's PlaceFinder API provides a good wat to lookup location data by lat/lng:
http://developer.yahoo.com/geo/placefinder/
Here's an example url that they use:
http://where.yahooapis.com/geocode?q=38.898717,+-77.035974&gflags=R
It would seem so:
Source: Google Maps API Service
Geocoding is the process of converting addresses (like "1600
Amphitheatre Parkway, Mountain View, CA") into geographic coordinates
(like latitude 37.423021 and longitude -122.083739), which you can use
to place markers or position the map. The Google Geocoding API
provides a direct way to access a geocoder via an HTTP request.
Additionally, the service allows you to perform the converse operation
(turning coordinates into addresses); this process is known as
"reverse geocoding."
You should also check out this documentation which has some sample code:
Reverse Geocoding
I made a generic function to look for the type that you want. Not always the address_component has zipcode, country, etc and if they do not always are in the same index. Sometimes your array is lenght 8, 6 or whatever. I did it in Typescript, just change a few things to make it vanilla JS.
getPlaceTypeValue(addressComponents: Places[], type: string): string {
let value = null;
for (const [i] of addressComponents.entries()) {
if (addressComponents[i].types.includes(type)) {
value = addressComponents[i].long_name;
break;
}
}
return value;
}
OR
getPlaceTypeValue(addressComponents: any[], type: string): string {
return (addressComponents.find(({ types }) => types.includes(type)) || {}).long_name || null;
}
Example of usage:
this.placesService.getPlaceTypeValue(address.address_components, 'postal_code');
this.placesService.getPlaceTypeValue(address.address_components, 'country');

Google Maps geocode: undefined latitude

Hitting a page with the follow script displays:
lat: undefined
lon: 51.5001524
Why is it that while lat is undefined, lon is not?
A working example can be found here.
Pull up your web console and see for yourself!
$(document).ready(function(){
var geocoder;
function codeAddress()
{
geocoder = new google.maps.Geocoder();
var address = 'London, England';
geocoder.geocode({'address': address}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
lat = results[0].geometry.location.Ia;
lon = results[0].geometry.location.Ja;
console.log("lat: " + lat);
console.log("lon: " + lon);
}
});
}
codeAddress();
});
</script>
</head>
<body>
</body>
</html>
While we're at it - what is the historical significance of Ia and Ja? I presume it relates to the Cartesian unit vectors i and j (predominately used in Engineering) though I'm not sure.
I found other examples online who use .lat for .Ia and .lng for .Ja
These, however, are returning in the console:
function () {
return this[a];
}
Just need a kick in the right direction.
Thank you.
I would use lat() and lng():
var lat = results[0].geometry.location.lat();
var lng = results[0].geometry.location.lng();
This is a designed behaviour of the geocoder: google shifts the identifiers in
geometry.location.Ia;
geometry.location.Ja;
on a weekly basis, i.e. from above to
geometry.location.Ja;
geometry.location.Ka;
and so on, so it is not possible to refer by id to the geocoder result object.
Chances are Google are using a javascript minifier (e.g. http://jscompress.com/) which renames all variables - hence they're subject to change on every build.