Using TransitOptions Literal in GoogleMaps DistanceMatrix API - google-maps

Good day!
I am very new to JavaScript, and have come to it as I think it can help automate a project I am working on. Essentially, I am mapping two Brazilian cities (Vitoria and Florianapolis) and looking for the transit times between an array of points. GIS tools are suitable for driving distance/time, but these cities do not have transit options (the TravelTime platform does not work in Brazil yet).
What I believe I can do is utilise the Google Maps JavaScript API and the Distance Matrix Service to build an array of Origin/Destination (O/D) pairs. And I think I have done that part with some introductory learning and the help of the Google Maps example. My plan is to expand both the Origin and Destination variables with the figures I need once I have this item sorted out.
Where I'd like to go next is to use the TransitOptions literal to always have the departure time set to 8 AM (i.e. rush hour). I don't want the data to change based on what time of day I run the script.
Attached is where I've got to so far, but I am 99% sure I am using the TransitOptions incorrectly:
<body>
<div id="right-panel">
<div id="inputs">
<pre>
var origin1 = {lat: -27.524, lng: -48.642};
var destinationA = {lat: -27.594, lng: -48.554};
</pre>
</div>
<div>
<strong>Results</strong>
</div>
<div id="output"></div>
</div>
<div id="map"></div>
<script>
let departurewindow = new Date('2020-03-10T08:00:00')
function initMap() {
var bounds = new google.maps.LatLngBounds;
var markersArray = [];
var origin1 = {lat: -27.524, lng: -48.642};
var destinationA = {lat: -27.594, lng: -48.554};
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: -27.50, lng: -48.5},
zoom: 10
});
var geocoder = new google.maps.Geocoder;
var service = new google.maps.DistanceMatrixService;
service.getDistanceMatrix({
origins: [origin1],
destinations: [destinationA],
travelMode: 'TRANSIT',
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false,
departureTime: departurewindow,
}, function(response, status) {
if (status !== '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 === '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>';
}
}
}
});
}
function deleteMarkers(markersArray) {
for (var i = 0; i < markersArray.length; i++) {
markersArray[i].setMap(null);
}
markersArray = [];
}
</script>

departureTime: should be a field in TransitOptions object literal and not a field in DistanceMatrixRequest object literal.
var transitOptions = {departureTime: departurewindow};
service.getDistanceMatrix({
origins: [origin1],
destinations: [destinationA],
travelMode: 'TRANSIT',
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false,
transitOptions: transitOptions
}, function(response, status) {});
Here's a sample code of the snippet above.

Related

How to assign info window in polyline using google map api

My Scenario. I have five markers and connecting to the polyline. When I click marker a to marker b between polyline it will show an info window. In the info, the window has marker a address and marker b address. I achieved this scenario using islocationedge concept in google Maps API. but this concept I facing an issue. when I click marker a to marker b polyline it will show marker b and marker c address because segment polyline I used. I need how to assign an info window in an individual polyline.
My code
<!DOCTYPE html>
<html>
<body>
<h1>My First Google Map</h1>
<div id="googleMap" style="width:100%;height:400px;"></div>
<script>
function myMap() {
var mapProp= {
center:new google.maps.LatLng(51.508742,-0.120850),
zoom:5,
};
var map = new google.maps.Map(document.getElementById("googleMap"),mapProp);
var goldenGatePosition = [{lat: 30.2179130,lng: -81.5628150, address: 'Tamil Nadu'},{lat: 30.2179140,lng: -81.5627480, address: 'India'},{lat:30.2177650,lng:-81.5629100,address: 'America'},{lat: 30.2844080,lng: -81.5633900, address: 'Tamil Nadu'},{lat: 30.2843840,lng: -81.5633890, address: 'Tamil Nadu'}];
for(let i=0;i<goldenGatePosition.length;i++){
var marker = new google.maps.Marker({
position: goldenGatePosition[i],
map: map,
title: 'Golden Gate Bridge'
});
}
var flightPath = new google.maps.Polyline({
path:goldenGatePosition,
strokeColor:"#0000FF",
strokeOpacity:0.8,
strokeWeight:2
});
flightPath.setMap(map);
let poly, geodesicPoly;
var infowindow = new google.maps.InfoWindow();
var codeStr=''
google.maps.event.addListener(flightPath, 'click', function(event) {
// make polyline for each segment of the input line
for (var i = 0; i < this.getPath().getLength() - 1; i++) {
var segmentPolyline = new google.maps.Polyline({
path: [this.getPath().getAt(i), this.getPath().getAt(i + 1)]
});
console.log(segmentPolyline)
// check to see if the clicked point is along that segment
if (google.maps.geometry.poly.isLocationOnEdge(event.latLng, segmentPolyline, 10e-3)) {
console.log(' I ', i)
// output the segment number and endpoints in the InfoWindow
var origin = new Array()
var destination = new Array()
console.log('****************')
for(let i=0;i<goldenGatePosition.length; i++){
console.log(goldenGatePosition[i])
}
console.log('****************')
console.log(segmentPolyline.getPath().getAt(0).address)
origin.push(segmentPolyline.getPath().getAt(0).toUrlValue(6))
destination.push(segmentPolyline.getPath().getAt(1).toUrlValue(6))
const service = new google.maps.DistanceMatrixService(); // instantiate Distance Matrix service
const matrixOptions = {
origins: origin, // technician locations
destinations: destination, // customer address
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.IMPERIAL
};
// Call Distance Matrix service
service.getDistanceMatrix(matrixOptions, callback);
// Callback function used to process Distance Matrix response
function callback(response, status) {
console.log(response)
console.log(status)
if (status !== "OK") {
alert("Error with distance matrix");
return;
}
console.log(response);
}
var content = "segment " + i + "<br>";
content += "start of segment=" + segmentPolyline.getPath().getAt(0).toUrlValue(6) + "<br>";
content += "end of segment=" + segmentPolyline.getPath().getAt(1).toUrlValue(6) + "<br>";
infowindow.setContent(content);
infowindow.setPosition(event.latLng);
infowindow.open(map);
}
}
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAiybKuHI544-t5XPZzBGjQOBCO4MZFCwM&callback=myMap&libraries=geometry"></script>
</body>
</html>
When i click the polyline. How to get marker coordinates from polyline one end to another end.
The tolerance in your call to isLocationOnEdge is too small.
isLocationOnEdge
isLocationOnEdge(point, poly[, tolerance])
Parameters:
point: LatLng
poly: Polygon|Polyline
tolerance: number optional
Return Value:* boolean
Computes whether the given point lies on or near to a polyline, or the edge of a polygon, within a specified tolerance. Returns true when the difference between the latitude and longitude of the supplied point, and the closest point on the edge, is less than the tolerance. The tolerance defaults to 10-9 degrees.
Your code:
if (google.maps.geometry.poly.isLocationOnEdge(event.latLng, segmentPolyline, 10e-3)) {
Working value:
if (google.maps.geometry.poly.isLocationOnEdge(event.latLng, segmentPolyline, 10e-7)) {
(when it is too large, it is picking up segment 1 for all locations on segment 0, as far as I can tell, all the other segments work correctly with your value)
proof of concept fiddle
code snippet:
function myMap() {
var mapProp = {
center: new google.maps.LatLng(51.508742, -0.120850),
zoom: 5,
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var bounds = new google.maps.LatLngBounds();
for (let i = 0; i < goldenGatePosition.length; i++) {
var marker = new google.maps.Marker({
position: goldenGatePosition[i],
map: map,
title: goldenGatePosition[i].address
});
if (i == 0 || i == 1) bounds.extend(marker.getPosition());
}
map.fitBounds(bounds);
var flightPath = new google.maps.Polyline({
path: goldenGatePosition,
strokeColor: "#0000FF",
strokeOpacity: 0.8,
strokeWeight: 2
});
flightPath.setMap(map);
let poly, geodesicPoly;
var infowindow = new google.maps.InfoWindow();
var codeStr = ''
google.maps.event.addListener(flightPath, 'click', function(event) {
// make polyline for each segment of the input line
for (var i = 0; i < this.getPath().getLength() - 1; i++) {
var segmentPolyline = new google.maps.Polyline({
path: [this.getPath().getAt(i), this.getPath().getAt(i + 1)]
});
console.log(segmentPolyline)
// check to see if the clicked point is along that segment
if (google.maps.geometry.poly.isLocationOnEdge(event.latLng, segmentPolyline, 10e-7)) {
console.log(' I ', i)
// output the segment number and endpoints in the InfoWindow
var origin = new Array()
var destination = new Array()
console.log('****************')
for (let i = 0; i < goldenGatePosition.length; i++) {
console.log(goldenGatePosition[i])
}
console.log('****************')
console.log(segmentPolyline.getPath().getAt(0).address)
origin.push(segmentPolyline.getPath().getAt(0).toUrlValue(6))
destination.push(segmentPolyline.getPath().getAt(1).toUrlValue(6))
const service = new google.maps.DistanceMatrixService(); // instantiate Distance Matrix service
const matrixOptions = {
origins: origin, // technician locations
destinations: destination, // customer address
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.IMPERIAL
};
// Call Distance Matrix service
service.getDistanceMatrix(matrixOptions, callback);
console.log("break")
// Callback function used to process Distance Matrix response
function callback(response, status) {
console.log(response)
console.log(status)
if (status !== "OK") {
alert("Error with distance matrix");
return;
}
console.log(response);
}
var content = "segment " + i + "<br>";
content += "start of segment=" + segmentPolyline.getPath().getAt(0).toUrlValue(6) + "<br>";
content += "end of segment=" + segmentPolyline.getPath().getAt(1).toUrlValue(6) + "<br>";
infowindow.setContent(content);
infowindow.setPosition(event.latLng);
infowindow.open(map);
}
}
});
}
var goldenGatePosition = [{
lat: 30.2179130,
lng: -81.5628150,
address: 'Tamil Nadu'
}, {
lat: 30.2179140,
lng: -81.5627480,
address: 'India'
}, {
lat: 30.2177650,
lng: -81.5629100,
address: 'America'
}, {
lat: 30.2844080,
lng: -81.5633900,
address: 'Tamil Nadu'
}, {
lat: 30.2843840,
lng: -81.5633890,
address: 'Tamil Nadu'
}];
html,
body,
#googleMap {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
<div id="googleMap"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=myMap&libraries=geometry" defer></script>

How to draw line between two points in JavaScript - Google Maps Api Route

I have two points on the map, I was able to take the distance using the API, now I need to draw a line between the points so that the user sees all the way. I read that you need to use the polyline, but I unfortunately can not. I take the user's GPS coordinates as point A - and on the map, in the drag event I take the coordinates of point B. You can see an example on the following page: https://tojweb.tj/abb.php
Can you help?
I read that you need to use the polyline, but I unfortunately can not.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
console.log("Geolocation is not supported by this browser.");
}
function showPosition(position) {
document.getElementById('mypos_lat').value=position.coords.latitude;
document.getElementById('mypos_lon').value=position.coords.longitude;
//alert("Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude);
}
var darection = new google.maps.DirectionsRenderer;
function initialize() {
var mapOptions = {
zoom: 13,
center: new google.maps.LatLng(38.583958, 68.780528),
mapTypeId: google.maps.MapTypeId.ROADMAP,
gestureHandling: "greedy",
fullscreenControl: false,
disableDefaultUI: true,
zoomControl: true,
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
darection.setMap(map);
google.maps.event.addListener(map, 'dragend', function() {
var centeral = map.getCenter();
//alert(centeral);
var names = centeral.toString();
var names =names.substr(1);
names = names.substring(0, names.length - 1);
console.log(names);
var re = /\s*,\s*/;
var nameList = names.split(re);
document.getElementById('bpos_lat').value=nameList[0];
document.getElementById('bpos_lon').value=nameList[1];
source_a = document.getElementById("mypos_lat").value;
source_b = document.getElementById("mypos_lon").value;
source_d = document.getElementById("bpos_lat").value;
source_e = document.getElementById("bpos_lon").value;
var darection = new google.maps.DirectionsRenderer;
var directionsService = new google.maps.DirectionsService;
//darection.setPanel(document.getElementById('panallocation'));
source = source_a + "," + source_b;
destination = source_d + "," + source_e;
var request = {
origin: source,
destination: destination,
travelMode: google.maps.TravelMode.DRIVING,
//Показ алтернативных дорог
provideRouteAlternatives: true
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
darection.setDirections(response);
}
});
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: [source],
destinations: [destination],
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;
distancefinel = distance.split(" ");
//start_addressfinel = start_address.split(" ");
// $('#distance').val(distancefinel[0]);
console.log(distancefinel[0]);
document.getElementById("distancesa").value = distancefinel[0];
////////// IN THIS STATE I WANT DRAW LINE ///////////////////
} else {
alert("Unable to find the distance between selected locations");
}
});
}
);
$('<div/>').addClass('centerMarker').appendTo(map.getDiv())
//do something onclick
.click(function(){
var that=$(this);
if(!that.data('win')){
that.data('win',new google.maps.InfoWindow({content:'this is the center'}));
that.data('win').bindTo('position',map,'center');
}
that.data('win').open(map);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
You can use the Directions Service of Google Maps JavaScript API to get the directions between 2 points and pass the DirectionsResult to the DirectionsRenderer, which can automatically handle the display in the map.
Here is the code I made which handles the use-case (Geolocating Point A, Draggable Marker B, then having a route between 2 points) from your description. You can also check it here.
Hope this helps!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style>
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var map, infoWindow, markerA, markerB, drag_pos;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -34.397,
lng: 150.644
},
zoom: 6
});
markerA = new google.maps.Marker({
map: map
});
markerB = new google.maps.Marker({
map: map
});
infoWindow = new google.maps.InfoWindow;
var directionsService = new google.maps.DirectionsService();
var directionsRenderer1 = new google.maps.DirectionsRenderer({
map: map,
suppressMarkers: true
});
var directionsRenderer2 = new google.maps.DirectionsRenderer({
map: map,
suppressMarkers: true,
polylineOptions: {
strokeColor: "gray"
}
});
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
map.setCenter(pos);
map.setZoom(15);
//Put markers on the place
infoWindow.setContent('Your Location');
markerA.setPosition(pos);
markerA.setVisible(true);
markerA.setLabel('A');
markerA.addListener('click', function() {
infoWindow.open(map, markerA);
});
//Get new lat long to put marker B 500m above Marker A
var earth = 6378.137, //radius of the earth in kilometer
pi = Math.PI,
m = (1 / ((2 * pi / 360) * earth)) / 1000; //1 meter in degree
var new_latitude = pos.lat + (500 * m);
var new_pos = {
lat: new_latitude,
lng: position.coords.longitude
};
markerB.setPosition(new_pos, );
markerB.setVisible(true);
markerB.setLabel('B');
markerB.setDraggable(true);
//Everytime MarkerB is drag Directions Service is use to get all the route
google.maps.event.addListener(markerB, 'dragend', function(evt) {
var drag_pos1 = {
lat: evt.latLng.lat(),
lng: evt.latLng.lng()
};
directionsService.route({
origin: pos,
destination: drag_pos1,
travelMode: 'DRIVING',
provideRouteAlternatives: true
},
function(response, status) {
if (status === 'OK') {
for (var i = 0, len = response.routes.length; i < len; i++) {
if (i === 0) {
directionsRenderer1.setDirections(response);
directionsRenderer1.setRouteIndex(i);
} else {
directionsRenderer2.setDirections(response);
directionsRenderer2.setRouteIndex(i);
}
}
console.log(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
});
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}
function handleLocationError(browserHasGeolocation, infoWindow, pos) {
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Error: The Geolocation service failed.' :
'Error: Your browser doesn\'t support geolocation.');
infoWindow.open(map);
}
</script>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
</body>
</html>
Here is my code. The first commented code does not draw and does not produce any errors. The second code throws an error:
InvalidValueError: at index 0: not a LatLng or LatLngLiteral with finite coordinates: in property lat: NaN is not an accepted value
I know that I am wrong and I am writing my code in the wrong place. I need help to show where the error is and how to fix it so that I understand.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
console.log("Geolocation is not supported by this browser.");
}
function showPosition(position) {
document.getElementById('mypos_lat').value=position.coords.latitude;
document.getElementById('mypos_lon').value=position.coords.longitude;
//alert("Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude);
}
var darection = new google.maps.DirectionsRenderer;
function initialize() {
var mapOptions = {
zoom: 13,
center: new google.maps.LatLng(38.583958, 68.780528),
mapTypeId: google.maps.MapTypeId.ROADMAP,
gestureHandling: "greedy",
fullscreenControl: false,
disableDefaultUI: true,
zoomControl: true,
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
darection.setMap(map);
google.maps.event.addListener(map, 'dragend', function() {
var centeral = map.getCenter();
//alert(centeral);
var names = centeral.toString();
var names =names.substr(1);
names = names.substring(0, names.length - 1);
console.log(names);
var re = /\s*,\s*/;
var nameList = names.split(re);
document.getElementById('bpos_lat').value=nameList[0];
document.getElementById('bpos_lon').value=nameList[1];
source_a = document.getElementById("mypos_lat").value;
source_b = document.getElementById("mypos_lon").value;
source_d = document.getElementById("bpos_lat").value;
source_e = document.getElementById("bpos_lon").value;
var darection = new google.maps.DirectionsRenderer;
var directionsService = new google.maps.DirectionsService;
//darection.setPanel(document.getElementById('panallocation'));
source = source_a + "," + source_b;
destination = source_d + "," + source_e;
var request = {
origin: source,
destination: destination,
travelMode: google.maps.TravelMode.DRIVING,
//Показ алтернативных дорог
provideRouteAlternatives: true
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
darection.setDirections(response);
}
});
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: [source],
destinations: [destination],
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;
distancefinel = distance.split(" ");
//start_addressfinel = start_address.split(" ");
// $('#distance').val(distancefinel[0]);
console.log(distancefinel[0]);
document.getElementById("distancesa").value = distancefinel[0];
////////// IN THIS STATE I WANT DRAW LINE ///////////////////
/*
function poliLines(map, source_a, source_b, source_d, source_e){
var routes = [
new google.maps.LatLng(source_a, source_b)
,new google.maps.LatLng(source_d, source_e)
];
var polyline = new google.maps.Polyline({
path: routes
, map: map
, strokeColor: '#ff0000'
, strokeWeight: 5
, strokeOpacity: 0.5
, clickable: false
});
*/
console.log(source);
console.log(destination);
var flightPlanCoordinates = [new google.maps.LatLng(source), new google.maps.LatLng(destination) ];
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2
});
flightPath.setMap(map);
} else {
alert("Unable to find the distance between selected locations");
}
});
}
);
$('<div/>').addClass('centerMarker').appendTo(map.getDiv())
//do something onclick
.click(function(){
var that=$(this);
if(!that.data('win')){
that.data('win',new google.maps.InfoWindow({content:'this is the center'}));
that.data('win').bindTo('position',map,'center');
}
that.data('win').open(map);
});
}
google.maps.event.addDomListener(window, 'load', initialize);

Google Maps Javascript API: Elevation Graph Along a Direction

I am using Google Maps API to build an website and I'm having trouble building the Elevation Graph. Google gives an example in their documentation but it refers to declaring some waypoints which is not my case. I am using Directions API so Google is automatically building the path.
Here is my code:
<script>
function initMap() {
var directionsDisplay = new google.maps.DirectionsRenderer;
var directionsService = new google.maps.DirectionsService;
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 14,
mapTypeId: 'terrain',
disableDefaultUI: true,
fullscreenControl: true,
scaleControl: true,
zoomControl: true
});
directionsDisplay.setMap(map);
calculateAndDisplayRoute(directionsService, directionsDisplay);
}
function calculateAndDisplayRoute(directionsService, directionsDisplay) {
var mapTravelMode = "DRIVING";
var mapOrigin = {lat: 46.573240, lng: 26.927229};
var mapDestination = {lat: 46.517151, lng: 27.081692};
var waypts = [
{location: {lat:46.5857174, lng: 26.9553385}, stopover: false},
{location: {lat:46.581699, lng: 26.999611}, stopover: false},
];
directionsService.route({
origin: mapOrigin, // Origin.
destination: mapDestination, // Destination.
waypoints: waypts, // Waypoints
travelMode: google.maps.TravelMode[mapTravelMode],
avoidHighways: true,
avoidTolls: true,
optimizeWaypoints: true
}, function(response, status) {
if (status == 'OK') {
directionsDisplay.setDirections(response);
console.log(response);
} else {
window.alert('[directionsService] A aparut o eroare: ' + status);
}
});
}
</script>
Someone can help me with this?
Pass the path returned from the directions service to the elevations service.
Inside the callback from the directions service, pass the overview_path in the returned result to the getElevationAlongPath function as the path.
if (status == 'OK') {
directionsDisplay.setDirections(response);
elevationService.getElevationAlongPath({
path: response.routes[0].overview_path,
samples: SAMPLES
}, plotElevation);
console.log(response);
} else {
window.alert('[directionsService] error: status: ' + status);
Where the callback to the elevations service is:
// Takes an array of ElevationResult objects
// and plots the elevation profile on a GViz ColumnChart
function plotElevation(results) {
elevations = results;
var path = [];
for (var i = 0; i < results.length; i++) {
path.push(elevations[i].location);
}
var data = new google.visualization.DataTable();
data.addColumn('string', 'Sample');
data.addColumn('number', 'Elevation');
for (var i = 0; i < results.length; i++) {
data.addRow(['', elevations[i].elevation]);
}
document.getElementById('chart_div').style.display = 'block';
chart.draw(data, {
width: 512,
height: 200,
legend: 'none',
titleY: 'Elevation (m)',
focusBorderColor: '#00ff00'
});
}
proof of concept fiddle
code snippet:
(doesn't quite work due to errors: Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.)
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 50%;
}
#chart_div {
height: 50%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<div id="chart_div"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<script>
var SAMPLES = 256;
var mousemarker = null;
var polyline = null;
// Load the Visualization API and the piechart package.
google.load("visualization", "1", {
packages: ["columnchart"]
});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(initMap);
function initMap() {
var directionsDisplay = new google.maps.DirectionsRenderer;
var directionsService = new google.maps.DirectionsService;
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 14,
mapTypeId: 'terrain',
disableDefaultUI: true,
fullscreenControl: true,
scaleControl: true,
zoomControl: true
});
chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
elevationService = new google.maps.ElevationService();
directionsDisplay.setMap(map);
calculateAndDisplayRoute(directionsService, directionsDisplay);
}
function calculateAndDisplayRoute(directionsService, directionsDisplay) {
var mapTravelMode = "DRIVING";
var mapOrigin = {
lat: 46.573240,
lng: 26.927229
};
var mapDestination = {
lat: 46.517151,
lng: 27.081692
};
var waypts = [{
location: {
lat: 46.5857174,
lng: 26.9553385
},
stopover: false
},
{
location: {
lat: 46.581699,
lng: 26.999611
},
stopover: false
},
];
directionsService.route({
origin: mapOrigin, // Origin.
destination: mapDestination, // Destination.
waypoints: waypts, // Waypoints
travelMode: google.maps.TravelMode[mapTravelMode],
avoidHighways: true,
avoidTolls: true,
optimizeWaypoints: true
}, function(response, status) {
if (status == 'OK') {
directionsDisplay.setDirections(response);
elevationService.getElevationAlongPath({
path: response.routes[0].overview_path,
samples: SAMPLES
}, plotElevation);
console.log(response);
} else {
window.alert('[directionsService] A aparut o eroare: ' + status);
}
});
}
// Takes an array of ElevationResult objects, draws the path on the map
// and plots the elevation profile on a GViz ColumnChart
function plotElevation(results) {
elevations = results;
var path = [];
for (var i = 0; i < results.length; i++) {
path.push(elevations[i].location);
}
var data = new google.visualization.DataTable();
data.addColumn('string', 'Sample');
data.addColumn('number', 'Elevation');
for (var i = 0; i < results.length; i++) {
data.addRow(['', elevations[i].elevation]);
}
document.getElementById('chart_div').style.display = 'block';
chart.draw(data, {
width: 512,
height: 200,
legend: 'none',
titleY: 'Elevation (m)',
focusBorderColor: '#00ff00'
});
}
</script>

Disable Waypoints on Google Maps Directions API

I am trying to create a service for the user to calculate the distance between two points using Google maps "draggable directions" as per this link.
Draggable Directions
I want to disable or disallow the user to add waypoints.
My code is as follows:
<script>
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: {lat: -24.345, lng: 134.46} // Australia.
});
var directionsService = new google.maps.DirectionsService;
var directionsDisplay = new google.maps.DirectionsRenderer({
draggable: true,
map: map,
panel: document.getElementById('right-panel')
});
directionsDisplay.addListener('directions_changed', function() {
computeTotalDistance(directionsDisplay.getDirections());
});
displayRoute('Perth, WA', 'Sydney, NSW', directionsService,
directionsDisplay);
}
function displayRoute(origin, destination, service, display) {
service.route({
origin: origin,
destination: destination,
travelMode: 'DRIVING',
avoidTolls: true
}, function(response, status) {
if (status === 'OK') {
display.setDirections(response);
} else {
alert('Could not display directions due to: ' + status);
}
});
}
function computeTotalDistance(result) {
var total = 0;
var myroute = result.routes[0];
for (var i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
}
total = total / 1000;
document.getElementById('total').innerHTML = total + ' km';
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>

Route between multiple markers

Is it possible to plot multiple markers as well show routes between these and origin? For example: I have one origin and four different destinations. I want the routes to be shown between the origin and the destinations, so that it is A to B, A to C, A to D, A to E. Can this be done? I have only seen the option to display the route between two points or to calculate distance between multiple. I want to be able to calculate the distance as well as showing the route on the map.
So far this is what my code looks like:
$("#submit").click(function() {
var values = $("#street").val();
var geocoder = new google.maps.Geocoder();
var address = values;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
}
service = new google.maps.DistanceMatrixService();
var origin = new google.maps.LatLng(latitude, longitude);
var destination = new google.maps.LatLng(48.856614, 2.352222);
var destinationb = new google.maps.LatLng(41.385064, 2.173403);
var destinationc = new google.maps.LatLng(44.584910, 5.133122);
var destinationd = new google.maps.LatLng(45.365187, 0.647394);
var destinationIcon = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2278%22%20height%3D%2238%22%20viewBox%3D%220%200%2038%2038%22%3E%3Cpath%20fill%3D%22%23333333%22%20stroke%3D%22%23ccc%22%20stroke-width%3D%22.5%22%20d%3D%22M34.305%2016.234c0%208.83-15.148%2019.158-15.148%2019.158S3.507%2025.065%203.507%2016.1c0-8.505%206.894-14.304%2015.4-14.304%208.504%200%2015.398%205.933%2015.398%2014.438z%22%2F%3E%3Ctext%20transform%3D%22translate(19%2018.5)%22%20fill%3D%22%23fff%22%20style%3D%22font-family%3A%20Arial%2C%20sans-serif%3Bfont-weight%3Abold%3Btext-align%3Acenter%3B%22%20font-size%3D%2212%22%20text-anchor%3D%22middle%22%3E' + "" + '%3C%2Ftext%3E%3C%2Fsvg%3E';
var originIcon = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2238%22%20height%3D%2238%22%20viewBox%3D%220%200%2038%2038%22%3E%3Cpath%20fill%3D%22%23808880%22%20stroke%3D%22%23ccc%22%20stroke-width%3D%22.5%22%20d%3D%22M34.305%2016.234c0%208.83-15.148%2019.158-15.148%2019.158S3.507%2025.065%203.507%2016.1c0-8.505%206.894-14.304%2015.4-14.304%208.504%200%2015.398%205.933%2015.398%2014.438z%22%2F%3E%3Ctext%20transform%3D%22translate%2819%2018.5%29%22%20fill%3D%22%23fff%22%20style%3D%22font-family%3A%20Arial%2C%20sans-serif%3Bfont-weight%3Abold%3Btext-align%3Acenter%3B%22%20font-size%3D%2212%22%20text-anchor%3D%22middle%22%3E' + "" + '%3C%2Ftext%3E%3C%2Fsvg%3E';
var infowindow = new google.maps.InfoWindow();
service.getDistanceMatrix(
{
origins: [origin],
destinations: [destination, destinationb, destinationc, destinationd],
travelMode: google.maps.TravelMode.DRIVING,
avoidHighways: false,
avoidTolls: false
},
callback
);
function callback(response, status) {
if(status=="OK") {
var originList = response.originAddresses;
var destinationList = response.destinationAddresses;
var bounds = new google.maps.LatLngBounds;
var outputDiv = document.getElementById('output');
var showGeocodedAddressOnMap = function(distance, asDestination) {
var icon = asDestination ? destinationIcon : originIcon;
return function(results, status) {
if (status === 'OK') {
map.fitBounds(bounds.extend(results[0].geometry.location));
var markersArray = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: icon
});
google.maps.event.addListener(markersArray, 'click', function (evt) {
infowindow.setContent('<strong>Avstånd:</strong> ' + distance);
infowindow.open(map, this);
});
} 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(results[i].distance.text, false));
for (var j = 0; j < results.length; j++) {
geocoder.geocode({'address': destinationList[j]}, showGeocodedAddressOnMap(results[j].distance.text, true));
outputDiv.innerHTML += originList[i] + ' to ' + destinationList[j] +
': ' + results[j].distance.text + '<br>';
}
}
} else {
alert("Error: " + status);
}
}
var map = new google.maps.Map(document.getElementById('map'), {
showTooltip: true,
showInfoWindow: true
});
});
});
</script>
<div id="output"></div>
<p></p>
<div id="map"></div>
To display the routes, call the directions service. Modified function from the example in the documentation:
function calculateAndDisplayRoute(start, end, map) {
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer({
map: map,
suppressMarkers: true,
preserveViewport: true
});
directionsService.route({
origin: start,
destination: end,
travelMode: 'DRIVING'
}, function(response, status) {
if (status === 'OK') {
directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
calculateAndDisplayRoute(origin, destination, map);
calculateAndDisplayRoute(origin, destinationb, map);
calculateAndDisplayRoute(origin, destinationc, map);
calculateAndDisplayRoute(origin, destinationd, map);
proof of concept fiddle
code snippet:
function calculateAndDisplayRoute(start, end, map) {
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer({
map: map,
suppressMarkers: true,
preserveViewport: true
});
directionsService.route({
origin: start,
destination: end,
travelMode: 'DRIVING'
}, function(response, status) {
if (status === 'OK') {
directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
var map = new google.maps.Map(document.getElementById('map'), {
showTooltip: true,
showInfoWindow: true
});
var values = $("#street").val();
var geocoder = new google.maps.Geocoder();
var address = values;
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
}
service = new google.maps.DistanceMatrixService();
var origin = new google.maps.LatLng(latitude, longitude);
var destination = new google.maps.LatLng(48.856614, 2.352222);
var destinationb = new google.maps.LatLng(41.385064, 2.173403);
var destinationc = new google.maps.LatLng(44.584910, 5.133122);
var destinationd = new google.maps.LatLng(45.365187, 0.647394);
var destinationIcon = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2278%22%20height%3D%2238%22%20viewBox%3D%220%200%2038%2038%22%3E%3Cpath%20fill%3D%22%23333333%22%20stroke%3D%22%23ccc%22%20stroke-width%3D%22.5%22%20d%3D%22M34.305%2016.234c0%208.83-15.148%2019.158-15.148%2019.158S3.507%2025.065%203.507%2016.1c0-8.505%206.894-14.304%2015.4-14.304%208.504%200%2015.398%205.933%2015.398%2014.438z%22%2F%3E%3Ctext%20transform%3D%22translate(19%2018.5)%22%20fill%3D%22%23fff%22%20style%3D%22font-family%3A%20Arial%2C%20sans-serif%3Bfont-weight%3Abold%3Btext-align%3Acenter%3B%22%20font-size%3D%2212%22%20text-anchor%3D%22middle%22%3E' + "" + '%3C%2Ftext%3E%3C%2Fsvg%3E';
var originIcon = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2238%22%20height%3D%2238%22%20viewBox%3D%220%200%2038%2038%22%3E%3Cpath%20fill%3D%22%23808880%22%20stroke%3D%22%23ccc%22%20stroke-width%3D%22.5%22%20d%3D%22M34.305%2016.234c0%208.83-15.148%2019.158-15.148%2019.158S3.507%2025.065%203.507%2016.1c0-8.505%206.894-14.304%2015.4-14.304%208.504%200%2015.398%205.933%2015.398%2014.438z%22%2F%3E%3Ctext%20transform%3D%22translate%2819%2018.5%29%22%20fill%3D%22%23fff%22%20style%3D%22font-family%3A%20Arial%2C%20sans-serif%3Bfont-weight%3Abold%3Btext-align%3Acenter%3B%22%20font-size%3D%2212%22%20text-anchor%3D%22middle%22%3E' + "" + '%3C%2Ftext%3E%3C%2Fsvg%3E';
var infowindow = new google.maps.InfoWindow();
calculateAndDisplayRoute(origin, destination, map);
calculateAndDisplayRoute(origin, destinationb, map);
calculateAndDisplayRoute(origin, destinationc, map);
calculateAndDisplayRoute(origin, destinationd, map);
service.getDistanceMatrix({
origins: [origin],
destinations: [destination, destinationb, destinationc, destinationd],
travelMode: google.maps.TravelMode.DRIVING,
avoidHighways: false,
avoidTolls: false
},
callback
);
function callback(response, status) {
if (status == "OK") {
var originList = response.originAddresses;
var destinationList = response.destinationAddresses;
var bounds = new google.maps.LatLngBounds;
var outputDiv = document.getElementById('output');
var showGeocodedAddressOnMap = function(distance, asDestination) {
var icon = asDestination ? destinationIcon : originIcon;
return function(results, status) {
if (status === 'OK') {
map.fitBounds(bounds.extend(results[0].geometry.location));
var markersArray = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: icon
});
google.maps.event.addListener(markersArray, 'click', function(evt) {
if (asDestination) {
infowindow.setContent('<strong>Avstånd:</strong> ' + distance);
} else {
infowindow.setContent('<strong>Origin</strong> ');
}
infowindow.open(map, this);
});
} else {
alert('Geocode was not successful due to: ' + status);
}
};
};
for (var i = 0; i < originList.length; i++) {
var results = response.rows[i].elements;
var text;
if (results[i].status != "OK") {
text = results[i].status;
} else {
results[i].distance.text;
}
geocoder.geocode({
'address': originList[i]
},
showGeocodedAddressOnMap(text, false));
for (var j = 0; j < results.length; j++) {
console.log("j=" + j + " destinationList[" + j + "]=" + destinationList[j] + " results[" + j + "]=" + results[j]);
geocoder.geocode({
'address': destinationList[j]
}, showGeocodedAddressOnMap(results[j].distance.text, true));
outputDiv.innerHTML += originList[i] + ' to ' + destinationList[j] +
': ' + results[j].distance.text + '<br>';
}
}
} else {
alert("Error: " + status);
}
}
});
html,
body,
#map {
height: 90%;
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="output"></div>
<input id="street" value="Orléans, France" />
<input id="submit" type="button" value="click" />
<p></p>
<div id="map"></div>