So I have dynamic text inputs which i require to give it access to google maps (places) autocomplete api.
The "start", "end" and 1st "waypoint"(not dynamic) works well, but after 4 hours, i am still struggling to get my dynamic text inputs to autocomplete. And can not find anything resembling the answer on google.
This is what i have so far:
Javascript:
function initialize() {
var options = {
componentRestrictions: {
country: "au"
}
};
var inputs = document.getElementById('start');
var autocompletes = new google.maps.places.Autocomplete(inputs, options);
var inpute = document.getElementById('end');
var autocompletee = new google.maps.places.Autocomplete(inpute, options);
var waypoints = document.getElementsByName("waypoints[]");
for (var i = 0; i < waypoints.length; i++) {
var inputw = waypoints[i];
var autocompletew = new google.maps.places.Autocomplete(inputw, options);
}
directionsDisplay = new google.maps.DirectionsRenderer();
var melbourne = new google.maps.LatLng(-31.953512, 115.857048);
var myOptions = {
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: melbourne
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
directionsDisplay.setMap(map);
}
HTML:
var counter = 1;
var limit = 10;
var i = 1;
function addInput(divName){
if (counter == limit) {
alert("You have reached the limit of adding " + counter + " inputs");
}
else {
var newdiv = document.createElement('div');
newdiv.innerHTML = (counter + 1) + "<input type=text name=waypoints[] autocomplete=on>";
document.getElementById(divName).appendChild(newdiv);
counter++;
i++;
var inputw = waypoints[i];
var autocompletew = new google.maps.places.Autocomplete(inputw, options);
}
}
Dynamically creating the content, then using the reference to that works for me:
function addInput(divName) {
if (counter == limit) {
alert("You have reached the limit of adding " + counter + " inputs");
} else {
var newbr = document.createElement('br');
var newtxt = document.createTextNode(""+(counter+1));
var newinput = document.createElement("input");
newinput.setAttribute("name","waypoints[]");
newinput.setAttribute("autocompute","on");
newinput.setAttribute("type", "text");
document.getElementById(divName).appendChild(newbr);
document.getElementById(divName).appendChild(newtxt);
document.getElementById(divName).appendChild(newinput);
counter++;
i++;
var autocompletew = new google.maps.places.Autocomplete(newinput, ACoptions);
}
proof of concept fiddle
code snippet:
var counter = 1;
var limit = 10;
var i = 0;
var ACoptions = {
componentRestrictions: {
country: "au"
}
};
function initialize() {
var inputs = document.getElementById('start');
var autocompletes = new google.maps.places.Autocomplete(inputs, ACoptions);
var inpute = document.getElementById('end');
var autocompletee = new google.maps.places.Autocomplete(inpute, ACoptions);
var waypoints = document.getElementsByName("waypoints[]");
for (var i = 0; i < waypoints.length; i++) {
var inputw = waypoints[i];
var autocompletew = new google.maps.places.Autocomplete(inputw, ACoptions);
}
directionsDisplay = new google.maps.DirectionsRenderer();
directionsService = new google.maps.DirectionsService();
var melbourne = new google.maps.LatLng(-31.953512, 115.857048);
var myOptions = {
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: melbourne
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
directionsDisplay.setMap(map);
google.maps.event.addDomListener(document.getElementById('getdir'), 'click', function() {
calculateAndDisplayRoute(directionsService, directionsDisplay);
});
}
google.maps.event.addDomListener(window, "load", initialize);
function addInput(divName) {
if (counter == limit) {
alert("You have reached the limit of adding " + counter + " inputs");
} else {
var newbr = document.createElement('br');
var newtxt = document.createTextNode("" + (counter + 1));
var newinput = document.createElement("input");
newinput.setAttribute("name", "waypoints[]");
newinput.setAttribute("autocompute", "on");
newinput.setAttribute("type", "text");
// newin = (counter + 1) + "<input type=text name=waypoints[] autocomplete=on>";
document.getElementById(divName).appendChild(newbr);
document.getElementById(divName).appendChild(newtxt);
document.getElementById(divName).appendChild(newinput);
counter++;
i++;
console.log("cntr=" + counter + " i=" + i + " waypoints[].length=" + document.getElementsByName("waypoints[]"));
// var inputw = waypoints[i];
var autocompletew = new google.maps.places.Autocomplete(newinput, ACoptions);
}
}
function calculateAndDisplayRoute(directionsService, directionsDisplay) {
var waypts = [];
var checkboxArray = document.getElementById('dynamicInput');
var waypointElmts = document.getElementsByName('waypoints[]');
for (var i = 0; i < waypointElmts.length; i++) {
if (waypointElmts[i].value.length > 0) {
waypts.push({
location: waypointElmts[i].value,
stopover: true
});
}
}
directionsService.route({
origin: document.getElementById('start').value,
destination: document.getElementById('end').value,
waypoints: waypts,
optimizeWaypoints: true,
travelMode: 'DRIVING'
}, function(response, status) {
if (status === 'OK') {
directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk">
</script>
<input id="start" value="Margaret River, AU" />
<input id="end" value="Perth, AU" />
<div id="dynamicInput">
<br>1
<input type="text" name="waypoints[]" autocomplete="on">
</div>
<input type="button" value="Another Delivery" onClick="addInput('dynamicInput');">
<input id="getdir" type="button" value="get route" />
<div id="map_canvas"></div>
Related
I'm trying to make origin SearchBox destination be string with legit direction, but when I do so I still need to select the first option for it to work (to calculate distance).
Got the this searching around to calculate distance between 2 points and it works perfectly:
How can I add multiple searchBoxes in my google maps api web?
I got a string for example :albrook mall which i know exist( this string is dynamic is coming from a variable and all address are validated. get the needed address pass it to a variable so I can read it on the frontEnd, and set the value of search box in the html. the value is updated with jquery
But what happens is that I still have to click on the origin search box then this list all possible locations which in my case is the first one, how can I make the map either auto select the first option or recognize the address that is set in the input value?
<script>
function initMap() {
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: {
lat: 9.0271554,
lng: 79.4816371
},
zoom: 15
});
var marker = new google.maps.Marker({
map: map,
draggable: false
});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(initialLocation);
/*marker.setPosition(initialLocation); */
});
}
new AutocompleteDirectionsHandler(map);
}
/**
* #constructor
*/
function AutocompleteDirectionsHandler(map) {
this.map = map;
this.originPlaceId = null;
this.destinationPlaceId = null;
this.travelMode = 'DRIVING';
this.avoidTolls = true;
this.avoidHighways= true;
//this.provideRouteAlternatives= true,
this.avoidFerries= true;
this.directionsService = new google.maps.DirectionsService();
this.directionsRenderer = new google.maps.DirectionsRenderer();
this.directionsRenderer.setMap(map);
var originInput = document.getElementById('orign');
var destinationInput = document.getElementById('destn');
var originAutocomplete = new google.maps.places.SearchBox(originInput);
var destinationAutocomplete =
new google.maps.places.SearchBox(destinationInput);
this.setupPlaceChangedListener(originAutocomplete, 'ORIG');
this.setupPlaceChangedListener(destinationAutocomplete, 'DEST');
}
AutocompleteDirectionsHandler.prototype.setupPlaceChangedListener = function(
autocomplete, mode) {
var me = this;
autocomplete.bindTo('bounds', this.map);
autocomplete.addListener('places_changed', function() {
var places = autocomplete.getPlaces();
var place = places[0];
if (!place.place_id) {
window.alert('Please select an option from the dropdown list.');
return;
}
if (mode === 'ORIG') {
me.originPlaceId = place.place_id;
} else {
me.destinationPlaceId = place.place_id;
}
me.route();
});
};
AutocompleteDirectionsHandler.prototype.route = function() {
if (!this.originPlaceId || !this.destinationPlaceId) {
return;
}
var me = this;
this.directionsService.route({
origin: {
'placeId': this.originPlaceId
},
destination: {
'placeId': this.destinationPlaceId
},
travelMode: this.travelMode,
avoidTolls: this.avoidTolls
},
function(response, status) {
if (status === 'OK') {
me.directionsRenderer.setDirections(response);
computeTotalDistance(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
};
// from Google Maps API: Total distance with waypoints
// https://stackoverflow.com/questions/12802202/google-maps-api-total-distance-with-waypoints
function computeTotalDistance(result) {
var totalDist = 0;
var 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;
}
totalDist = totalDist / 1000.
time = (totalTime / 60).toFixed(2)
document.getElementById("totalkm").innerHTML ="" + totalDist + "km" ;
document.getElementById("totaltime").innerHTML ="" + time + " minutos";
if(totalDist <= 5){
document.getElementById("totalCost").innerHTML =" $3.50";
}
else{
kmPrice = (totalDist - 5) * 0.75;
document.getElementById("totalCost").innerHTML ="$" +(kmPrice + 3.50).toFixed(2)+ "";
}
}
function send_handle(){
let name=document.getElementById("name").value;
///let lastname= document.getElementById("lastname").value;
let inst= document.getElementById("instructions").value;
let origin= document.querySelector(".selectButtons input#orign").value;
let destination= document.querySelector(".selectButtons input#destn").value;
let cost= document.getElementById("totalCost").innerHTML;
let distance= document.getElementById("totalkm").innerHTML;
// win.focus();
}
</script>
<html>
<div class="selectButtons" >
<input type="text" id="orign" placeholder="origen">
<input type="text" id="destn" placeholder="destino">
<span> Distancia en KM <div id="totalkm">0km</div> </span>
<span> Distancia en tiempo <div id="totaltime">o.oo</div> </span>
<span> costo por envio<div id="totalCost">$0</div></div> </span>
</div>
</html>
You can call the places service to get the PlaceId (with your string), then pass that placeId into the constructor for your AutocompleteDirectionsHandler or if you already have the PlaceId (you are allowed to store those), just use it, although you probably want to initialize the origin input with the string.
var origin = "Allbrook, Panama";
var originInput = document.getElementById('orign');
originInput.value = origin;
const request = {
query: origin,
fields: ["name", "geometry", "place_id"],
};
var originPlaceId;
var service = new google.maps.places.PlacesService(map);
service.findPlaceFromQuery(request, (results, status) => {
if (status === google.maps.places.PlacesServiceStatus.OK && results) {
originPlaceId = results[0].place_id;
console.log("placeId="+originPlaceId+" coords="+results[0].geometry.location.toUrlValue(6));
new AutocompleteDirectionsHandler(map, originPlaceId);
map.setCenter(results[0].geometry.location);
}
});
Add the initial origin placeId to the AutocompleteDirectionsHandler constructor:
function AutocompleteDirectionsHandler(map, originPlaceId) {
this.map = map;
this.originPlaceId = originPlaceId;
// ...
on load:
after selecting destination from dropdown:
code snippet:
let map;
function initMap() {
map = new google.maps.Map(document.getElementById('map-canvas'), {
center: {
lat: 9.0271554,
lng: 79.4816371
},
zoom: 15
});
var origin = "Allbrook, Panama";
var originInput = document.getElementById('orign');
originInput.value = origin;
const request = {
query: origin,
fields: ["name", "geometry", "place_id"],
};
var originPlaceId;
var service = new google.maps.places.PlacesService(map);
service.findPlaceFromQuery(request, (results, status) => {
if (status === google.maps.places.PlacesServiceStatus.OK && results) {
originPlaceId = results[0].place_id;
console.log("placeId="+originPlaceId+" coords="+results[0].geometry.location.toUrlValue(6));
new AutocompleteDirectionsHandler(map, originPlaceId);
map.setCenter(results[0].geometry.location);
}
});
var marker = new google.maps.Marker({
map: map,
draggable: false
});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(initialLocation);
/*marker.setPosition(initialLocation); */
});
}
}
/**
* #constructor
*/
function AutocompleteDirectionsHandler(map, originPlaceId) {
this.map = map;
this.originPlaceId = originPlaceId;
this.destinationPlaceId = null;
this.travelMode = 'DRIVING';
this.avoidTolls = true;
this.avoidHighways = true;
//this.provideRouteAlternatives= true,
this.avoidFerries = true;
this.directionsService = new google.maps.DirectionsService();
this.directionsRenderer = new google.maps.DirectionsRenderer();
this.directionsRenderer.setMap(map);
var originInput = document.getElementById('orign');
var destinationInput = document.getElementById('destn');
var originAutocomplete = new google.maps.places.SearchBox(originInput);
var destinationAutocomplete =
new google.maps.places.SearchBox(destinationInput);
this.setupPlaceChangedListener(originAutocomplete, 'ORIG');
this.setupPlaceChangedListener(destinationAutocomplete, 'DEST');
}
AutocompleteDirectionsHandler.prototype.setupPlaceChangedListener = function(
autocomplete, mode) {
var me = this;
autocomplete.bindTo('bounds', this.map);
autocomplete.addListener('places_changed', function() {
var places = autocomplete.getPlaces();
var place = places[0];
if (!place.place_id) {
window.alert('Please select an option from the dropdown list.');
return;
}
if (mode === 'ORIG') {
me.originPlaceId = place.place_id;
} else {
me.destinationPlaceId = place.place_id;
}
me.route();
});
};
AutocompleteDirectionsHandler.prototype.route = function() {
if (!this.originPlaceId || !this.destinationPlaceId) {
return;
}
var me = this;
this.directionsService.route({
origin: {
'placeId': this.originPlaceId
},
destination: {
'placeId': this.destinationPlaceId
},
travelMode: this.travelMode,
avoidTolls: this.avoidTolls
},
function(response, status) {
if (status === 'OK') {
me.directionsRenderer.setDirections(response);
computeTotalDistance(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
};
// from Google Maps API: Total distance with waypoints
// https://stackoverflow.com/questions/12802202/google-maps-api-total-distance-with-waypoints
function computeTotalDistance(result) {
var totalDist = 0;
var 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;
}
totalDist = totalDist / 1000.
time = (totalTime / 60).toFixed(2)
document.getElementById("totalkm").innerHTML = "" + totalDist + "km";
document.getElementById("totaltime").innerHTML = "" + time + " minutos";
if (totalDist <= 5) {
document.getElementById("totalCost").innerHTML = " $3.50";
} else {
kmPrice = (totalDist - 5) * 0.75;
document.getElementById("totalCost").innerHTML = "$" + (kmPrice + 3.50).toFixed(2) + "";
}
}
function send_handle() {
let name = document.getElementById("name").value;
///let lastname= document.getElementById("lastname").value;
let inst = document.getElementById("instructions").value;
let origin = document.querySelector(".selectButtons input#orign").value;
let destination = document.querySelector(".selectButtons input#destn").value;
let cost = document.getElementById("totalCost").innerHTML;
let distance = document.getElementById("totalkm").innerHTML;
// win.focus();
}
function createMarker(place) {
if (!place.geometry || !place.geometry.location) return;
const marker = new google.maps.Marker({
map,
position: place.geometry.location,
});
google.maps.event.addListener(marker, "click", () => {
infowindow.setContent(place.name || "");
infowindow.open(map);
});
}
window.initMap = initMap;
#map-canvas {
height: 80%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<html>
<div class="selectButtons">
<input type="text" id="orign" placeholder="origen" />
<input type="text" id="destn" placeholder="destino" />
<span> Distancia en KM <div id="totalkm">0km</div> </span>
<span> Distancia en tiempo <div id="totaltime">o.oo</div> </span>
<span> costo por envio<div id="totalCost">$0</div> </span>
</div>
<div id="map-canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initMap" async defer></script>
</html>
I need to find all the locations near by the lat long and radius provided.I think I can achieve this by using geofence but I don't know how to proceed.I have the following data.
set of lat long and to get the location for radius within 5km for all the lat long by each.
Any one help how to start this.
Inputs I have:
lat long
33.450909, -112.073196
33.466210, -112.064620
33.451640, -112.099130
33.437160, -112.048400
33.480860, -112.082130
33.489950, -112.074700
Tried so far:
<!DOCTYPE html >
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<title>Creating a Store Locator on Google Maps</title>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body style="margin:0px; padding:0px;" onload="initMap()">
<div>
<label for="raddressInput">Search location:</label>
<input type="text" id="addressInput" size="15"/>
<label for="radiusSelect">Radius:</label>
<select id="radiusSelect" label="Radius">
<option value="50" selected>50 kms</option>
<option value="30">30 kms</option>
<option value="20">20 kms</option>
<option value="10">10 kms</option>
</select>
<input type="button" id="searchButton" value="Search"/>
</div>
<div><select id="locationSelect" style="width: 10%; visibility: hidden"></select></div>
<div id="map" style="width: 100%; height: 90%"></div>
<script>
var map;
var markers = [];
var infoWindow;
var locationSelect;
function initMap() {
var sydney = {lat: 33.450909, lng: -112.073196};
map = new google.maps.Map(document.getElementById('map'), {
center: sydney,
zoom: 11,
mapTypeId: 'roadmap',
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
});
infoWindow = new google.maps.InfoWindow();
searchButton = document.getElementById("searchButton").onclick = searchLocations;
locationSelect = document.getElementById("locationSelect");
locationSelect.onchange = function() {
var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
if (markerNum != "none"){
google.maps.event.trigger(markers[markerNum], 'click');
}
};
}
function searchLocations() {
var address = document.getElementById("addressInput").value;
var geocoder = new google.maps.Geocoder();
geocoder.geocode({address: address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
searchLocationsNear(results[0].geometry.location);
} else {
alert(address + ' not found');
}
});
}
function clearLocations() {
infoWindow.close();
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers.length = 0;
locationSelect.innerHTML = "";
var option = document.createElement("option");
option.value = "none";
option.innerHTML = "See all results:";
locationSelect.appendChild(option);
}
function searchLocationsNear(center) {
clearLocations();
var radius = document.getElementById('radiusSelect').value;
var searchUrl = 'storelocator.php?lat=' + center.lat() + '&lng=' + center.lng() + '&radius=' + radius;
downloadUrl(searchUrl, function(data) {
var xml = parseXml(data);
var markerNodes = xml.documentElement.getElementsByTagName("marker");
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markerNodes.length; i++) {
var id = markerNodes[i].getAttribute("id");
var name = markerNodes[i].getAttribute("name");
var address = markerNodes[i].getAttribute("address");
var distance = parseFloat(markerNodes[i].getAttribute("distance"));
var latlng = new google.maps.LatLng(
parseFloat(markerNodes[i].getAttribute("lat")),
parseFloat(markerNodes[i].getAttribute("lng")));
createOption(name, distance, i);
createMarker(latlng, name, address);
bounds.extend(latlng);
}
map.fitBounds(bounds);
locationSelect.style.visibility = "visible";
locationSelect.onchange = function() {
var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
google.maps.event.trigger(markers[markerNum], 'click');
};
});
}
function createMarker(latlng, name, address) {
var html = "<b>" + name + "</b> <br/>" + address;
var marker = new google.maps.Marker({
map: map,
position: latlng
});
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
markers.push(marker);
}
function createOption(name, distance, num) {
var option = document.createElement("option");
option.value = num;
option.innerHTML = name;
locationSelect.appendChild(option);
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request.responseText, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function parseXml(str) {
if (window.ActiveXObject) {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
} else if (window.DOMParser) {
return (new DOMParser).parseFromString(str, 'text/xml');
}
}
function doNothing() {}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAVD0ngfhOFs5rnww7UFyz9rN6UznOIZ1U&callback=initMap">
</script>
</body>
</html>
Using the above I can able to point single point,But what I want is to get the location around each lat long provided above radius is 5 km
If you are already using Google Maps, then I think you can try with computeDistanceBetween.
This is a short example of how to use it. You just need to eliminate those distances greater than the radius you set.
var home = ['Store', new google.maps.LatLng(29.520130, -98.415542)];
var pts = [
['Client A', new google.maps.LatLng(29.5197902, -98.3867079)],
['Client B', new google.maps.LatLng(29.5165967, -98.4235714)],
['Client C', new google.maps.LatLng(29.5198805, -98.3676648)]
];
var dist = google.maps.geometry.spherical.computeDistanceBetween;
pts.forEach(function(pt) {
console.log(home[0] + ' to ' + pt[0] + ': ' + (dist(home[1], pt[1])).toFixed(10));
});
I'm trying to make a origin and destination menu, so the user will choose the locations in each input, and each input will add a marker to the map and then it will calculate the distance, this is my progress so far: I've successfully added a map with a search box, but I can't create another one and I don't know how to do this.
This is my code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&libraries=places"></script>
<div style="background-color: #FFC012">
<input type="text" id="orign" placeholder="origin">
<input type="text" id="destn" placeholder="destination">
<br>
<div id="map-canvas">
<script>
var map = new google.maps.Map(document.getElementById('map-canvas'),{
center:{
lat: 19.4978,
lng: -99.1269
},
zoom:15
});
var marker = new google.maps.Marker({
map:map,
draggable: false
});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(initialLocation);
/*marker.setPosition(initialLocation); */
});
}
var searchBox = new google.maps.places.SearchBox(document.getElementById('orign'));
google.maps.event.addListener(searchBox, 'places_changed',function(){
var places = searchBox.getPlaces();
var bounds = new google.maps.LatLngBounds();
var i, place;
for(i=0; place=places[i];i++){
bounds.extend(place.geometry.location);
marker.setPosition(place.geometry.location);
}
map.fitBounds(bounds);
map.setZoom(15);
})
</script>
</div>
</div>
One option would be to start from the Autocomplete Directions Example in the documentation, change the Autocomplete objects to SearchBox objects, and the associated code to account for the differences (SearchBox has a places_changed event, Autocomplete has place_changed (singular); the routine to get the results also has a different name (singular vs. plural).
/**
* #constructor
*/
function AutocompleteDirectionsHandler(map) {
this.map = map;
this.originPlaceId = null;
this.destinationPlaceId = null;
this.travelMode = 'DRIVING';
this.directionsService = new google.maps.DirectionsService();
this.directionsRenderer = new google.maps.DirectionsRenderer();
this.directionsRenderer.setMap(map);
var originInput = document.getElementById('orign');
var destinationInput = document.getElementById('destn');
var originAutocomplete = new google.maps.places.SearchBox(originInput);
var destinationAutocomplete =
new google.maps.places.SearchBox(destinationInput);
this.setupPlaceChangedListener(originAutocomplete, 'ORIG');
this.setupPlaceChangedListener(destinationAutocomplete, 'DEST');
}
AutocompleteDirectionsHandler.prototype.setupPlaceChangedListener = function(
autocomplete, mode) {
var me = this;
autocomplete.bindTo('bounds', this.map);
autocomplete.addListener('places_changed', function() {
var places = autocomplete.getPlaces();
var place = places[0];
if (!place.place_id) {
window.alert('Please select an option from the dropdown list.');
return;
}
if (mode === 'ORIG') {
me.originPlaceId = place.place_id;
} else {
me.destinationPlaceId = place.place_id;
}
me.route();
});
};
Add a function to calculate the length of the returned route (from the question: Google Maps API: Total distance with waypoints):
function computeTotalDistance(result) {
var totalDist = 0;
var 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;
}
totalDist = totalDist / 1000.
document.getElementById("total").innerHTML = "total distance is: " + totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes";
}
proof of concept fiddle
code snippet:
// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script
// src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">
function initMap() {
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: {
lat: 19.4978,
lng: -99.1269
},
zoom: 15
});
var marker = new google.maps.Marker({
map: map,
draggable: false
});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(initialLocation);
/*marker.setPosition(initialLocation); */
});
}
new AutocompleteDirectionsHandler(map);
}
/**
* #constructor
*/
function AutocompleteDirectionsHandler(map) {
this.map = map;
this.originPlaceId = null;
this.destinationPlaceId = null;
this.travelMode = 'DRIVING';
this.directionsService = new google.maps.DirectionsService();
this.directionsRenderer = new google.maps.DirectionsRenderer();
this.directionsRenderer.setMap(map);
var originInput = document.getElementById('orign');
var destinationInput = document.getElementById('destn');
var originAutocomplete = new google.maps.places.SearchBox(originInput);
var destinationAutocomplete =
new google.maps.places.SearchBox(destinationInput);
this.setupPlaceChangedListener(originAutocomplete, 'ORIG');
this.setupPlaceChangedListener(destinationAutocomplete, 'DEST');
}
AutocompleteDirectionsHandler.prototype.setupPlaceChangedListener = function(
autocomplete, mode) {
var me = this;
autocomplete.bindTo('bounds', this.map);
autocomplete.addListener('places_changed', function() {
var places = autocomplete.getPlaces();
var place = places[0];
if (!place.place_id) {
window.alert('Please select an option from the dropdown list.');
return;
}
if (mode === 'ORIG') {
me.originPlaceId = place.place_id;
} else {
me.destinationPlaceId = place.place_id;
}
me.route();
});
};
AutocompleteDirectionsHandler.prototype.route = function() {
if (!this.originPlaceId || !this.destinationPlaceId) {
return;
}
var me = this;
this.directionsService.route({
origin: {
'placeId': this.originPlaceId
},
destination: {
'placeId': this.destinationPlaceId
},
travelMode: this.travelMode
},
function(response, status) {
if (status === 'OK') {
me.directionsRenderer.setDirections(response);
computeTotalDistance(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
};
// from Google Maps API: Total distance with waypoints
// https://stackoverflow.com/questions/12802202/google-maps-api-total-distance-with-waypoints
function computeTotalDistance(result) {
var totalDist = 0;
var 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;
}
totalDist = totalDist / 1000.
document.getElementById("total").innerHTML = "total distance is: " + totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes";
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map-canvas {
height: 80%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<div style="background-color: #FFC012; height:100%; width:100%;">
<input type="text" id="orign" placeholder="origin" value="Lindavista Vallejo III Secc">
<input type="text" id="destn" placeholder="destination" value="Lienzo Charro de La Villa">
<div id="total"></div>
<br>
<div id="map-canvas"></div>
</div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initMap" async defer></script>
I have a java script function that return a string value, when i call this function on button click it return nothing.
Here is my function code:
function PlotMap(StartLat, StartLog, EndLat, EndLog) {
var map;
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var llList = "";
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: { lat: StartLat, lng: StartLog },
zoom: 15
});
directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
calcRoute();
} //End function initMap
function calcRoute() {
var start = new google.maps.LatLng(StartLat, StartLog);
var end = new google.maps.LatLng(EndLat, EndLog);
var bounds = new google.maps.LatLngBounds();
bounds.extend(start);
bounds.extend(end);
map.fitBounds(bounds);
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);
directionsDisplay.setMap(map);
if (response.routes && response.routes.length > 0) {
var routes = response.routes;
for (var j = 0; j < routes.length; j++) {
var points = routes[j].overview_path;
var ul = document.getElementById("vertex");
for (var i = 0; i < points.length; i++) {
var li = document.createElement('li');
li.innerHTML = getLiText(points[i]);
ul.appendChild(li);
llList = llList + getLiText(points[i]) + " / ";
}
}
}
} else {
alert("Directions Request from " + start.toUrlValue(6) + " to " + end.toUrlValue(6) + " failed: " + status);
}
});
} //End function calcRoute
function getLiText(point) {
var lat = point.lat(),
lng = point.lng();
return "lat: " + lat + " lng: " + lng;
}
initMap();
return llList;}
And Here i am calling this function on button click in asp.net page.
<script>
function ii() {
var tt = PlotMap(26.547648, 81.529472, 26.612515, 81.354248);
alert(tt);
}</script>
Asp.net page code:
<body>
<input id="Button1" type="button" value="button" onclick="ii();"/>
<div id="map" style="float: left; width: 70%; height: 400px;"></div>
<ul id="vertex">
<li></li>
</ul>
Everything works fine but function not returning any value. Please help i am new in web development. Thanks.
I tested the logic in your code and it looks sound. As I was able to get it to return a sting as you wanted but had to comment out all the google map logic.
Although, I noticed, the below if statement has no else statement therefore if this statement returns false then the string will be empty and you wont be alerted.
if (response.routes && response.routes.length > 0) {
Maybe try adding a matching else statement:
} else { alert("No Routes"); }
This should at least give you some more insight into what is going on.
Here is the new logic in your calcRoute function:
function calcRoute() {
var start = new google.maps.LatLng(StartLat, StartLog);
var end = new google.maps.LatLng(EndLat, EndLog);
var bounds = new google.maps.LatLngBounds();
bounds.extend(start);
bounds.extend(end);
map.fitBounds(bounds);
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);
directionsDisplay.setMap(map);
if (response.routes && response.routes.length > 0) {
var routes = response.routes;
for (var j = 0; j < routes.length; j++) {
var points = routes[j].overview_path;
var ul = document.getElementById("vertex");
for (var i = 0; i < points.length; i++) {
var li = document.createElement('li');
li.innerHTML = getLiText(points[i]);
ul.appendChild(li);
llList = llList + getLiText(points[i]) + " / ";
}
}
} else { alert("No Routes"); }
} else {
alert("Directions Request from " + start.toUrlValue(6) + " to " + end.toUrlValue(6) + " failed: " + status);
}
});
} //End function calcRoute
I have a demo1 Here and have another demo2 here. I want to include demo 2 output exactly between html form and the Google map. I am new to js. When I tried it by pasting the specific function of demo 2 into demo 1, it didn't work. How do I do that?
var map;
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
function initialize() {
//INITIALIZE GLOBAL VARIABLES
var zipCodesToLookup1 = new Array(document.getElementById("PortZip").value, document.getElementById("ImporterZip").value, document.getElementById("ExporterZip").value, document.getElementById("PortZip").value);
var output = '<tr><th scope="col">From</th><th scope="col">To</th><th scope="col">Miles</th></tr>';
var output = '<tr><th scope="col">From</th><th scope="col">To</th><th scope="col">Miles</th></tr>';
var difference = "0";
var totalDist = 0;
// document.write(difference);
//EXECUTE THE DISTANCE MATRIX QUERY
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: zipCodesToLookup1,
destinations: zipCodesToLookup1,
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL
}, function (response, status) {
if (status == google.maps.DistanceMatrixStatus.OK) {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
for (var i = 0; i < origins.length - 1; i++) {
var results = response.rows[i].elements;
output += '<tr><td>' + origins[i] + '</td><td>' + destinations[i + 1] + '</td><td>' + results[i + 1].distance.text + '</td></tr>';
if (i != 0) {
totalDist += results[i + 1].distance.value;
} else {
totalDist -= results[i + 1].distance.value;
}
}
output += '<tr><td></td><td>OUT OF ROUTE DISTANCE -</td><td>' + (totalDist / 1000 * 0.621371).toFixed(0) + ' mi</td></tr>';
document.getElementById('zip_code_output').innerHTML = '<table cellpadding="5">' + output + '</table>';
}
});
}
//FUNCTION TO LOAD THE GOOGLE MAPS API
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyCDZpAoR25KSkPTRIvI3MZoAg1NL6f0JV0&sensor=false&callback=initialize";
document.body.appendChild(script);
}
<form>
Calculation of OUT OF ROUTE DISTANCE.<br>
Enter 5 digit VALID US ZipCodes<br>
Port ZipCode:<br>
<input type="text" id="PortZip" value="31402"><br>
Importer ZipCode:<br>
<input type="text" id="ImporterZip" value="30308"><br>
Exporter ZipCode:<br>
<input type="text" id="ExporterZip" value="30901"><br>
<input type="button" value="Calculate" onclick="loadScript()" />
</form>
<div id="zip_code_output"></div>
<div id="map_canvas" style="width:650px; height:600px;"></div>
You have 2 different results, from 2 differents asynchronous methods (functions).
You need to obtain the twice results and show it at the same time, I recomend you to use async library. This has a method called parallel to exec a callback when the two proccess must end:
For ex:
function calculeRouteAndShow () {
var service = new google.maps.DistanceMatrixService();
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
var zipCodeOutput = document.getElementById('zip_code_output');
var importZip = document.getElementById('ImporterZip').value;
var exportZip = document.getElementById('ExporterZip').value;
var portZip = document.getElementById("PortZip").value;
async.parallel({
getDistance: funcion (done) {
service.getDistanceMatrix({
origins: [PortZip, ImportZip, exportZip],
destinations: [PortZip, ImportZip, exportZip],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL
}, function(response, status) {
if (status !== google.maps.DistanceMatrixStatus.OK) {
return done(null, response);
}
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var output = "";
for(var i=0; i < origins.length-1; i++) {
var results = response.rows[i].elements;
output += '<tr><td>' + origins[i] + '</td><td>' + destinations[i+1] + '</td><td>' + results[i+1].distance.text + '</td></tr>';
if (i != 0){
totalDist += results[i+1].distance.value;
}
else {
totalDist -= results[i+1].distance.value;
}
}
output += '<tr><td></td><td>OUT OF ROUTE DISTANCE -</td><td>'+(totalDist/1000*0.621371).toFixed(0)+ ' mi</td></tr>';
return done(null, output);
});
},
calculateRoute: function (done) {
var waypts = [{
location: ImportZip
},{
location: exportZip
}];;
var request = {
origin: portZip,
destination: portZip,
waypoints: waypts,
optimizeWaypoints: true,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status !== google.maps.DirectionsStatus.OK) {
return done(status);
}
return done(null, response);
});
}
}, function (err, responses) {
if (err) {
alert("We have an error here :(");
return;
}
zipCodeOutput.innerHTML = '<table cellpadding="5">' + responses.getDistance + '</table>';
directionsDisplay.setDirections(responses.calculateRoute);
});
}
I hope this help you, sorry my poor english.
#Exos My code below:
<body onload="initialize()">
<script type="text/javascript">
function initialize() {
//CONVERT THE MAP DIV TO A FULLY-FUNCTIONAL GOOGLE MAP
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var rendererOptions = { map: map };
directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
var point1 = document.getElementById('PortZip').value;
var point2 = document.getElementById('ImporterZip').value;
var point3 = document.getElementById('ExporterZip').value;
var point4 = document.getElementById('ExporterZip').value;
var wps = [{ location: point2 }, { location: point3 }];
var org = document.getElementById('PortZip').value;
var dest = document.getElementById('PortZip').value;
var request = {
origin: org,
destination: dest,
waypoints: wps,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService = new google.maps.DirectionsService();
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
else
alert ('failed to get directions');
});
//INITIALIZE GLOBAL VARIABLES
var zipCodesToLookup1 = new Array(document.getElementById("PortZip").value, document.getElementById("ImporterZip").value, document.getElementById("ExporterZip").value, document.getElementById("PortZip").value);
var output = '<tr><th scope="col">Leg</th><th scope="col">From</th><th scope="col">To</th><th scope="col">Miles</th></tr>';
var difference = "0";
var totalDist = 0;
// document.write(difference);
//EXECUTE THE DISTANCE MATRIX QUERY
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: zipCodesToLookup1,
destinations: zipCodesToLookup1,
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL
}, function(response, status) {
if(status == google.maps.DistanceMatrixStatus.OK) {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var customText = ["<i>From Port to Exporter</i>",
"<i>From Exporter to Importer</i>",
"<i>From Importer back to Port</i>"];
for(var i=0; i < origins.length-1; i++) {
var results = response.rows[i].elements;
output += '<tr><td>' + customText[i] + '</td><td>' + origins[i] + '</td><td>' + destinations[i+1] + '</td><td>' + results[i+1].distance.text + '</td></tr>';
if (i != 0){
totalDist += results[i+1].distance.value;
}
else {
totalDist -= results[i+1].distance.value;
}
}
output += '<tr><td></td><td></td><td><b>OUT OF ROUTE DISTANCE</b></td><td><b>'+(totalDist/1000*0.621371).toFixed(0)+ ' mi</b></td></tr>';
document.getElementById('zip_code_output').innerHTML = '<table border = "2px" cellpadding="5">' + output + '</table><br>';
}
});
function scrollWin() {
window.scrollBy(0, 580);
}
scrollWin();
}
//FUNCTION TO LOAD THE GOOGLE MAPS API
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=KEY&sensor=false&callback=initialize";
document.body.appendChild(script);
}
</script>
</body>