I have the following code:
<script>
var rendererOptions = {
draggable: false
};
var directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);;
var directionsService = new google.maps.DirectionsService();
var map;
var England = new google.maps.LatLng(53.7415, 1.6860);
function initialize() {
var mapOptions = {
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: England
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
map.setTilt(45);
directionsDisplay.setMap(map)
directionsDisplay.setPanel(document.getElementById('directionsPanel'));
google.maps.event.addListener(directionsDisplay, 'directions_changed', function() {
computeTotalDistance(directionsDisplay.directions);
});
calcRoute();
}
function calcRoute() {
var request = {
origin: 'postcode',
destination: 'postcode',
waypoints:[{location: 'waypoint postcode'}, {location: 'waypoint postcode'}, {location: 'waypoint postcode'}],
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
function computeTotalDistance(result) {
var total = 0;
var myroute = result.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
}
total = total / 1000.
document.getElementById('total').innerHTML = total + ' km';
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="float:left;width:70%; height:100%"></div>
<div id="directionsPanel" style="float:right;width:30%;height 100%">
<p>Total Distance: <span id="total"></span></p>
</div>
The map, shows an origin and destination, with certain waypoints along the way, using google api's direction service. The directions panel shows all distances in metric units. How do I change it, so that all distances are shown in imperial units i.e miles,feet?
From the docs
Unit Systems
By default, directions are calculated and displayed using the unit
system of the origin's country or region. (Note: origins expressed
using latitude/longitude coordinates rather than addresses always
default to metric units.) For example, a route from "Chicago, IL" to
"Toronto, ONT" will display results in miles, while the reverse route
will display results in kilometers. You may override this unit system
by setting one explicitly within the request using one of the
following UnitSystem values:
UnitSystem.METRIC specifies usage of the metric system. Distances are shown using kilometers.
UnitSystem.IMPERIAL specifies usage of the Imperial (English) system. Distances are shown using miles.
Note: this unit system setting only affects the text displayed to the
user. The directions result also contains distance values, not shown
to the user, which are always expressed in meters.
Related
I'm playing around with Google Places API and I was wondering if it were possible to return just one closest result. In the example below I can return all the gyms within a 1km radius which is fine, but if I were to return the closest police station or hospital something for which I'd only want to know the closest one is there a way to do this. It seems the API is returning all the objects within a radius and it can't be altered. I can't seem to find any documentation that highlights this issue, and any attempts I've made still returns all the places in the area.
function GymReport(){
// Gets the latitude and longitude of a location searched by a user
$('.search_latitude').val(marker.getPosition().lat());
$('.search_longitude').val(marker.getPosition().lng());
var Lat = marker.getPosition().lat();
console.log(Lat);
var Long = marker.getPosition().lng();
console.log(Long);
var location = {lat: Lat, lng: Long};
var service = new google.maps.places.PlacesService(map);
service.nearbySearch({
location: location,
radius: 1000,
type: ['gym']
}, callback);
}
Callback Class
function callback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
if(marker)
marker.setMap(null)
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);<-- This calls the function that will create the markers for the array of results from the API.
}
}
}
Please note that you can order results of Places nearby search by Prominence or by Distance. By default it is ordered by prominence. You can use the rankBy parameter in your code to order by Distance:
rankBy - Specifies the ranking method to use when returning results. Defaults to PROMINENCE. Note that when rankBy is set to DISTANCE, you must specify a location but you cannot specify a radius or bounds.
source: https://developers.google.com/maps/documentation/javascript/3.exp/reference#PlaceSearchRequest
Once you get results ordered by distance just get the first element from array which is the nearest place. Have a look at my sample code
var map;
var infowindow;
function initMap() {
var pyrmont = {lat: -33.867, lng: 151.195};
map = new google.maps.Map(document.getElementById('map'), {
center: pyrmont,
zoom: 15
});
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.nearbySearch({
location: pyrmont,
rankBy: google.maps.places.RankBy.DISTANCE,
type: ['gym']
}, callback);
}
function callback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
//Get the first result, it's the closest one
createMarker(results[0]);
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
#map {
height: 100%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU&libraries=places&callback=initMap" async defer></script>
I hope this helps!
Really need some ideas on this. Been working on Google map API, which I'm using Geocoding, Reverse Geocoding and Geolocation. With this piece of code, below,I am able to use Direction API of Google map, which works perfectly.
var locations = [
{lat: 6.4261139, lng: 3.4363691}
];
var mapContainer = $('.map-container'),
map = new google.maps.Map(mapContainer[0], {
center: center,
zoom : 10
});
var markers = _(locations)
.map(function (loc) {
return new google.maps.Marker({
position: new google.maps.LatLng(loc.lat, loc.lng)
});
})
.each(function (marker) {
marker.setMap(map);
})
.value();
var mc = new MarkerClusterer(map, markers);
var directionsService = new google.maps.DirectionsService(),
directionsDisplay = new google.maps.DirectionsRenderer(),
displayRoute = function () {
directionsService.route({
origin: 'Akin Ogunlewe street VI',//6.512596400000001+','+3.3541297 Pass this in place of the address
destination: 'Falolu road Surulere',//'Falolu road Surulere',//6.4261139+','+3.4363691 Pass this in place of the address
travelMode : google.maps.TravelMode.DRIVING
}, function (response, status) {
if (status === google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
} else {
console.log('Directions request failed due to ' + status);
}
});
};
directionsDisplay.setMap(map);
displayRoute();
Is there a way I can pass Latitude and Longitude in Origin and Destination Instead of physical address (string)?
I tried it but did not work.
I need to pass the numeric (float) value like:6.512596400000001,3.3541297 Instead of Falolu road Surulere
Any help is appreciated thanks
The documentation for the v3 API says a google.maps.LatLng or a string. For geographic locations, create and pass in a google.maps.LatLng; for addresses, pass in a string.
origin: LatLng | String | google.maps.Place,
destination: LatLng | String | google.maps.Place,
And in the reference
destination | Type: Place | Location of destination. This can be specified as either a string to be geocoded, or a LatLng, or a Place. Required.
origin | Place | Location of origin. This can be specified as either a string to be geocoded, or a LatLng, or a Place. Required.
proof of concept fiddle
code snippet:
var map;
function initialize() {
var locations = [{
lat: 6.4261139,
lng: 3.4363691
}];
var mapContainer = $('.map-container'),
map = new google.maps.Map(mapContainer[0], {
center: locations[0],
zoom: 10
});
var directionsService = new google.maps.DirectionsService(),
directionsDisplay = new google.maps.DirectionsRenderer(),
displayRoute = function() {
directionsService.route({
origin: new google.maps.LatLng(6.512596400000001, 3.3541297), // Pass this in place of the address 'Akin Ogunlewe street VI'
destination: new google.maps.LatLng(6.4261139, 3.4363691), // Pass this in place of the address 'Falolu road Surulere'
travelMode: google.maps.TravelMode.DRIVING
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
} else {
console.log('Directions request failed due to ' + status);
}
});
};
directionsDisplay.setMap(map);
displayRoute();
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas" class="map-container"></div>
How can i get the total distance in KM in my javascript. It is shown already on top of the Panel, but i need this value also in my javascript. My javascript is as followed:
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
var map = new google.maps.Map(document.getElementById('map'), {
zoom:7,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('panel'));
var een = '52.3641205';
var twee = '4.905697000000032';
var drie = '52.6010666';
var vier = '4.73768229999996';
var p1 = new google.maps.LatLng(een, twee);
var p2 = new google.maps.LatLng(drie, vier);
var request = {
origin: p1,
destination: p2,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
alert('Total travel distance is:' + response);
directionsDisplay.setDirections(response);
}
});
The functionality is working but i would also like to alert the total distance. This is seen at the top of the panel. The panel will be invisible in the future so a getelementbyID function is not enough.
Can someone help me with this?
Thank You!
Sergio
The distance is available in each of the route legs
google.maps.Distance object specification
A representation of distance as a numeric value and a display string.
Properties Type Description
text string A string representation of the distance value, using the UnitSystem specified in the request.
value number The distance in meters.
proof of concept fiddle
code snippet:
var geocoder;
var map;
function initialize() {
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
map = new google.maps.Map(document.getElementById('map'), {
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('panel'));
var een = '52.3641205';
var twee = '4.905697000000032';
var drie = '52.6010666';
var vier = '4.73768229999996';
var p1 = new google.maps.LatLng(een, twee);
var p2 = new google.maps.LatLng(drie, vier);
var request = {
origin: p1,
destination: p2,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
document.getElementById('distance').innerHTML = 'Total travel distance is: ' + (response.routes[0].legs[0].distance.value / 1000).toFixed(2) + " km";
alert('Total travel distance is: ' + (response.routes[0].legs[0].distance.value / 1000).toFixed(2) + ' km');
directionsDisplay.setDirections(response);
}
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="distance"></div>
<div id="map" style="border: 2px solid #3872ac;"></div>
<div id="panel"></div>
As per the documentation:
unitSystem
Type: UnitSystem
Preferred unit system to use when displaying distance. Defaults to the unit system used in the country of origin.
So if you want to force it to METRIC:
var request = {
origin: p1,
destination: p2,
travelMode: google.maps.DirectionsTravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC
};
This will force the value of response.routes[0].legs[0].distance.text to use the metric system.
And as explained in #geocodezip answer, you can also rely on the response.routes[0].legs[0].distance.value which is always returned in meters, even if the country of origin uses the imperial system.
You can easily get the distance by getting:
directionsDisplay.directions.routes[0].legs[0].distance.text
The result, for example, would be text like "20,5 km".
In your request, set units=metric.
Then use: distance = response.routes[0].legs[0].distance.text; in your alert.
Im using below code to show a distance between two distances but zoom doesn't work it always will be in default zoom level. I tried setting lot of values but it's not working. Please help.
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var from = "";
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.preserveViewport = false;
var dallas = new google.maps.LatLng(32.8931567, -97.0402193);
var mapOptions = {
zoom: 15,
center: dallas
};
map = new google.maps.Map(document.getElementById('googleMap'), mapOptions);
map.setZoom(map.getZoom()+5);
directionsDisplay.setMap(map);
calcRoute();
}
function calcRoute() {
var start = 'dallas airport terminal a';
var end = 'SpringHill Suites';
console.log("HotelDetail: " + end);
var request = {
origin: start,
destination: end,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
For what you want to achieve, the preserveViewport property needs to be set to true like this.
directionsDisplay = new google.maps.DirectionsRenderer({
preserveViewport: true
});
//directionsDisplay.preserveViewport = false;
In addition, your code sets a zoom level of 20 which is too high to see anything on the map. Here is a working example with an initial zoom level of 12: JSFiddle
I'm trying to create multiple maps on the same page with different transit directions in each one.
I've been able to iteratively create multiple Google maps, but I can't get different directions to appear in each.
I’ve created a number of divs that hold the maps and gave them IDs map-canvas1, map-canvas2, map-canvas3…etc. After creating the maps with the below function, how would I then show different transit directions in each one? With the code as it is now, no directions appear in any of the maps (although each of the maps do show up).
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var coordinates;
function initialize(){
for (var i = 0; i < arrayOfObjects.length; i++){
var directionsDisplay = new google.maps.DirectionsRenderer();
var latitude = arrayOfObjects[i].latitude;
var longitude = arrayOfObjects[i].longitude;
coordinates = new google.maps.LatLng(latitude, longitude);
var mapOptions = {
zoom: 15,
center: coordinates
};
var numString = i.toString();
var thisMapID = "map-canvas" + numString;
map = new google.maps.Map(document.getElementById(thisMapID), mapOptions);
directionsDisplay.setMap(map);
calcRoute();
};
}
var startingLocation = new google.maps.LatLng(40.768211, -73.957721);
function calcRoute(){
var request = {
origin: startingLocation,
destination: coordinates,
travelMode: google.maps.TravelMode.TRANSIT
};
directionsService.route(request, function(response, status){
if(status == google.maps.DirectionsStatus.OK){
directionsDisplay.setDirections(response);
}
});
}
A unique DirectionsRenederer needs to be associated with each map. Note that the DirectionsService is subject to a quota and rate limits, if you have lots of these maps you will have to check the return status and handle OVER_QUERY_LIMIT errors appropriately (you may want to handle errors in general, so the service will tell you why some maps don't show a route).
working example (with 2 maps)
var directionsDisplay = [];
var directionsService = [];
var map = [];
var coordinates;
function initialize(){
for (var i = 0; i < arrayOfObjects.length; i++){
directionsService[i] = new google.maps.DirectionsService();
directionsDisplay[i] = new google.maps.DirectionsRenderer();
var latitude = arrayOfObjects[i].latitude;
var longitude = arrayOfObjects[i].longitude;
coordinates = new google.maps.LatLng(latitude, longitude);
var mapOptions = {
zoom: 15,
center: coordinates
};
var numString = i.toString();
var thisMapID = "map-canvas" + numString;
map[i] = new google.maps.Map(document.getElementById(thisMapID), mapOptions);
directionsDisplay[i].setMap(map[i]);
calcRoute(i);
};
}
var startingLocation = new google.maps.LatLng(40.768211, -73.957721);
function calcRoute(index){
var request = {
origin: startingLocation,
destination: map[index].getCenter(),
travelMode: google.maps.TravelMode.TRANSIT
};
directionsService[index].route(request, function(response, status){
if(status == google.maps.DirectionsStatus.OK){
directionsDisplay[index].setDirections(response);
} else { alert("Directions request failed: " + status); }
});
}