I am currently working on a project about taxis. I want to display some taxis on Google Map but encountered the following problem. When the program turns into function print_taxi(), all data in taxilatlng[] will disappear! It seems that all of the data can only be kept inside directionsservice.route(){}. Need help.
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script>
onerror=handleErr
var txt=""
function handleErr(msg,url,l)
{
txt="There was an error on this page.\n\n"
txt+="Error: " + msg + "\n"
txt+="URL: " + url + "\n"
txt+="Line: " + l + "\n\n"
txt+="Click OK to continue.\n\n"
alert(txt)
return true
}
var centerlat=22.551622;
var centerlng=114.121178;
var taxi_num=10;
var taxiradius=0.005;
var taxilatlng = new Array();
var taximarker = new Array();
var taxilat = new Array();
var taxilng = new Array();
var map;
var RANDOM_DATA_INITIALIZED;
function get_random(lowerbound, upperbound){
return lowerbound+Math.floor((upperbound-lowerbound)*Math.random());
}
function get_random_loc(now, radius){
return now+radius-Math.random()*2*radius;
}
function get_random_latlng(taxiradius){
var tmp=new google.maps.LatLng(get_random_loc(centerlat,taxiradius), get_random_loc(centerlng,taxiradius));
return tmp;
}
function dump_obj(myObject) {
var s = "";
for (var property in myObject) {
s = s + "\n "+property +": " + myObject[property] ;
}
alert(s);
}
function init_map()
{
var latlng=new google.maps.LatLng(centerlat, centerlng);
var options={
zoom:16,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map=new google.maps.Map(document.getElementById("map_canvas"), options);
}
function print_taxi(){
image="taxi.gif";
for(var i=1;i<=taxi_num; ++i){
taximarker[i]=new google.maps.Marker({
position: taxilatlng[i],
icon: image,
map: map
});
}
}
function get_taxi_pos()
{
var cnt_generatedcar=0;
for(var i=1;i<=taxi_num; i++)
{
var from=get_random_latlng(taxiradius);
var to=get_random_latlng(taxiradius);
var directionsservice=new google.maps.DirectionsService();
var taxirenderer=new google.maps.DirectionsRenderer();
var DirReq={
origin: from,
destination: to,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsservice.route(DirReq, function(response, status){
if(status==google.maps.DirectionsStatus.OK)
{
var all_routes = response.routes;
for(curroute in all_routes)
{
++cnt_generatedcar;
var all_paths = all_routes[curroute].overview_path;
var cnt_paths = all_paths.length;
var id_path=get_random(0, cnt_paths-1);
taxilatlng[i] = all_paths[id_path];
if(cnt_generatedcar==taxi_num){
print_taxi();
}
}
}
});
}
}
function init(){
init_map();
get_taxi_pos();
}
</script>
</head>
<body onload="init();">
<div id="map_canvas" style="float:left; width:70%; height:100%"></div>
<div id="msg"></div>
</body>
</html>
directionsservice.route is a callback method and is called only after i >taxi_num. As a result the value in taxilatlng is getting set only once at index (taxi_num+1). You can modify the code to something like :
var ctr = -1; // added
directionsservice.route(DirReq, function(response, status){if(status==google.maps.DirectionsStatus.OK)
{
var all_routes = response.routes;
ctr++;
for(curroute in all_routes)
{
++cnt_generatedcar;
var all_paths = all_routes[curroute].overview_path;
var cnt_paths = all_paths.length;
var id_path=get_random(0, cnt_paths-1);
taxilatlng[ctr] = all_paths[id_path];
if(cnt_generatedcar==taxi_num){
print_taxi();
}
}
}
});
I've just used a new variable as a counter instead of i.
Related
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 coded the google map to display multiple in map with clickable icon.
The code is as follows
<html>
<head>
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
.container{width: auto; height: auto; }
.clear{clear: both;}
</style>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyB1tbIAqN0XqcgTR1-FxYoVTVq6Is6lD98&sensor=false">
</script>
<script type="text/javascript">
var locations = [
['abc', -31.987717, 115.814430, 'our place','image path', 'What is the work'],
['abc',-32.240765, 115.904158 , 'our place','image path', 'What is the work'],
];
function initialize() {
var myOptions = {
center: new google.maps.LatLng(-31.65,116.688),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("default"),
myOptions);
setMarkers(map,locations)
}
function setMarkers(map,locations){
var marker, i
for (i = 0; i < locations.length; i++)
{
var loan = locations[i][0]
var lat = locations[i][1]
var long = locations[i][2]
var add = locations[i][3]
var image = locations[i][4]
latlngset = new google.maps.LatLng(lat, long);
var marker = new google.maps.Marker({
map: map, title: loan , position: latlngset
});
map.setCenter(marker.getPosition())
var content = "<div class='container'>" + '<div style="float:left;">' +'<h2> Heading </h2>' + add +'</div>'+ '<div style="float:right;">' +"<img src='" + image +"'/></div><div class='clear'></div></div>"
var infowindow = new google.maps.InfoWindow()
var activeWindow;
google.maps.event.addListener(marker,'click', (function(marker,content,infowindow){
return function() {
//Close active window if exists
if(activeWindow != null)
activeWindow.close();
//Open new window
infowindow.setContent(content);
infowindow.open(map,marker);
//Store new window in global variable
activeWindow = infowindow;
};
})(marker,content,infowindow));
}
}
</script>
</head>
<body onload="initialize()">
<div id="default" style="width:100%; height:100%"></div>
</body>
</html>
I want to fetch the Heading text, co-ordinate, image path etc from google spreadsheet.
I have tried this code
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"> </script>
</head>
<body>
<script>
//https://docs.google.com/spreadsheets/d/1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g/pubhtml
var cell1= "a1";
var cell2= "b1";
var cell3= "c1";
var cell4= "d1";
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range="+cell1+"&b6&output=csv").done(function(result1){
document.getElementById("display1").innerHTML = result1;
});
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range="+cell2+"&b6&output=csv").done(function(result2){
document.getElementById("display2").innerHTML = result2;
});
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range="+cell3+"&b6&output=csv").done(function(result3){
document.getElementById("display3").innerHTML = result3;
});
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range="+cell4+"&b6&output=csv").done(function(result4){
document.getElementById("display4").innerHTML = result4;
});
</script>
<div id="display1"></div>
<div id="display2"></div>
<div id="display3"></div>
<div id="display4"></div>
</body>
</html>
I simply wish to know how to call varible result1, result2, result3, result4 value in location array.
Anyone's help appreciated..
Thanks in advance.
The other answers are suggesting you run your AJAX requests in series which in practice there is zero reason to do, so I'll offer a small variation. I've also tried to reduce code replication.
var locations = []; //global variable array
$(document).ready(function() {
var cells = ["a1", "b1", "c1", "d1"];
var url_start = "https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range=";
var url_end = "&b6&output=csv";
// for each of our cells
for (var i = 0; i < cells.length; i++){
// perform the ajax call
$.ajax(url_start + cells[i] + url_end).done(function(result){
// once we get our reply, store it
locations.push(result);
// was this the last reply?
if(locations.length == 4){
// then add our locations!
addToMap();
}
});
}
});
function addToMap() {
//here's the result of your ajax requests to the spreadsheet. You can use them in your map function.
$('#locations').html('[' + locations.join(", ") + ']');
}
This should be slightly but perceivably faster.
You must wait for the return of ajax before make the map.
here a working example for one marker:
<html>
<head>
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
.container{width: auto; height: auto; }
.clear{clear: both;}
</style>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyB1tbIAqN0XqcgTR1-FxYoVTVq6Is6lD98&sensor=false"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript">
var locations = [];
$( document ).ready(initialize())
function initialize() {
var cell1 = "a1";
var cell2 = "b1";
var cell3 = "c1";
var cell4 = "d1";
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range=" + cell1 + "&b6&output=csv").done(function(result1) {
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range=" + cell2 + "&b6&output=csv").done(function(result2) {
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range=" + cell3 + "&b6&output=csv").done(function(result3) {
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range=" + cell4 + "&b6&output=csv").done(function(result4) {
console.log("here");
locations.push(result1 + ', ' + result2 + ', ' + result3 + ', ' + result4);
makeMap();
});
});
});
});
}
function makeMap() {
var myOptions = {
center: new google.maps.LatLng(-31.65,116.688),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("default"),
myOptions);
setMarkers(map,locations)
google.maps.event.trigger(map, 'resize');
}
function setMarkers(map,locations){
var marker, i
for (i = 0; i < locations.length; i++)
{
console.log(locations);
var res = locations[0].split(" ");
console.log(res);
var loan = res[0]
var lat = -31.987717
var long = 115.814430
var add = res[3] + res[4] + res[5]
var image = res[6]
console.log(add)
console.log(image)
latlngset = new google.maps.LatLng(lat, long);
var marker = new google.maps.Marker({
map: map, title: loan , position: latlngset
});
map.setCenter(marker.getPosition())
var content = "<div class='container'>" + '<div style="float:left;">' +'<h2> Heading </h2>' + add +'</div>'+ '<div style="float:right;">' +"<img src='" + image +"'/></div><div class='clear'></div></div>"
var infowindow = new google.maps.InfoWindow()
var activeWindow;
google.maps.event.addListener(marker,'click', (function(marker,content,infowindow){
return function() {
//Close active window if exists
if(activeWindow != null)
activeWindow.close();
//Open new window
infowindow.setContent(content);
infowindow.open(map,marker);
//Store new window in global variable
activeWindow = infowindow;
};
})(marker,content,infowindow));
}
}
</script>
</head>
<body onload="">
<div id="default" style="width:100%; height:100%"></div>
</body>
</html>
Note: This is not clean code. When one request is inside the other(like the initialize function) we named as Pyramid of Doom. You can use q library for more clean code.
Here is a simplified demonstration of getting the results of your ajax requests into a variable that is available to your map function:
var locations = []; //global variable array
$(document).ready(function() {
var cell1 = "a1";
var cell2 = "b1";
var cell3 = "c1";
var cell4 = "d1";
//run each successive ajax function in the 'done' function of the previous
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range=" + cell1 + "&b6&output=csv").done(function(result1) {
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range=" + cell2 + "&b6&output=csv").done(function(result2) {
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range=" + cell3 + "&b6&output=csv").done(function(result3) {
$.ajax("https://docs.google.com/spreadsheet/pub?key=1-LBh3AdwWxhvlkxZrsCuJSz9y4xuBT5DRCgHC_m6F6g&single=true&gid=0&range=" + cell4 + "&b6&output=csv").done(function(result4) {
locations.push(result1 + ', ' + result2 + ', ' + result3 + ', ' + result4); //in the last function, push the results to the `locations` array;
//call the map function
goMap();
});
});
});
});
});
function goMap() {
//here's the result of your ajax requests to the spreadsheet. You can use them in your map function.
$('#locations').html('[' + locations + ']');
}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js">
</script>
<div id="locations"></div>
If you want to do this without writing code, check out GeoSheets. It's an add-on for Google Spreadsheets that allows you to create an map directly from your spreadsheet and embed it on your website. Check out the advanced docs for details on how to make the popup work using data from a column in the spreadsheet.
I have a project whereby a route is generated by the google maps directions service, and I have a loop to obtain all coordinates along it (using a functioned called showPathInfo - see base of query for full HTML):
var tp = result.routes[0].legs[i].steps[j].path[k]; // local variable
var z = new google.maps.LatLng(tp.lat(),tp.lng()); // local variable
I wish to make a call to the elevation service during each loop iteration using:
elevation = getElevation(z); // global variable but NOT an array
where getElevation is a function (see base of query for full HTML).
For some reason, even though the coords are correctly passed to the function, and are rendered appropriately into a getElevationForLocations object (I have checked this by having the getElevation return variables before the getElevationForLocations call); the service returns "undefined" for
return results[0].elevation;
I am interested in getting this solution to work to take advantage of the higher accuracy afforded to individual elevation service requests, and am trying to avoid batch requests with locations[] as a full array or using the getElevationForPath function.
Admittedly there is the problem of a limit to the number of single elevation requests that can be made per second and in total, but I have tried slowing down the code execution and limiting the distances in order to get this to work at least once:
function wait() { setTimeout(function () {
elevation = getElevation(z); // here defined as a global variable
}, 500);}
wait();
Does anyone have any ideas why such a nested call like this cannot work?
The full fiddle html code is as follows:
<!DOCTYPE html>
<html><head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>html, body, #map-canvas {height: 100%;margin: 0px;padding: 0px}</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script>
var rendererOptions = { draggable: true };
var directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);;
var directionsService = new google.maps.DirectionsService();
var infowindow = new google.maps.InfoWindow();
var map;
var elevation; // *******************
var elevator;
var start = new google.maps.LatLng(55.60289406109326, -2.88885779678822);
var wpnt1 = new google.maps.LatLng(55.59226543103951, -2.91247397661209);
var wpnt2 = new google.maps.LatLng(55.57330299699533, -2.88813963532448);
var wpnt3 = new google.maps.LatLng(55.58132161006218, -2.84357875585556);
var wpnt4 = new google.maps.LatLng(55.58602383263128, -2.87256672978401);
var wpnt5 = new google.maps.LatLng(55.60450928199337, -2.89154000580311);
var ended = new google.maps.LatLng(55.60289406109326, -2.88885779678822);
function initialize() {
elevator = new google.maps.ElevationService();
var mapOptions = { zoom: 10,center: start };
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('directionsPanel'));
google.maps.event.addListener(directionsDisplay, 'directions_changed', function() {
document.getElementById('points').innerHTML = "";
showPathInfo(directionsDisplay.getDirections());
});
calcRoute();
} // ***** End of initialise function
function calcRoute() {
var request = {origin: start,destination: ended,
waypoints:[{location: wpnt1}, {location: wpnt2}, {location: wpnt3}, {location: wpnt4}, {location: wpnt5}],
travelMode: google.maps.TravelMode.WALKING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
function showPathInfo(result) {
var total = 0;
var ns = 0;
var pt = 0;
var myroute = result.routes[0];
document.getElementById('points').insertAdjacentHTML('beforeend', '<th>Point</th><th>Lat</th><th>Lon</th><th>Elevation</th>');
for (var i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
ns += myroute.legs[i].steps.length;
for (var j = 0; j < myroute.legs[i].steps.length; j++) {
for (var k = 0; k < myroute.legs[i].steps[j].path.length; k++) {
var tp = myroute.legs[i].steps[j].path[k];
var z = new google.maps.LatLng(tp.lat(),tp.lng());
//function wait() { setTimeout(function () {
elevation = getElevation(z);
//}, 500);} // End of getAndWait
//wait();
document.getElementById('points').insertAdjacentHTML('beforeend',
'<tr><td>' + pt + '</td><td>' +
tp.lat().toFixed(7) + '</td><td>' +
tp.lng().toFixed(7) + '</td><td>' +
elevation + '</td></tr>');
pt += 1;
}
}
}
total = total / 1000.0;
document.getElementById('total').innerHTML = total + ' km';
document.getElementById('legs').innerHTML = myroute.legs.length;
document.getElementById('steps').innerHTML = ns;
}
function getElevation(z) {
var locations = [];
var clickedLocation = z;
locations.push(clickedLocation);
var positionalRequest = { 'locations': locations }
elevator.getElevationForLocations(positionalRequest, function(results, status) {
if (status == google.maps.ElevationStatus.OK) {
// Retrieve the first result
if (results[0]) {
return results[0].elevation;
} else {
return 'No results found';
}
} else {
return 'Elevation service failed due to: ' + status;
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas" style="float:left;width:70%; height:100%"></div>
<div id="directionsPanel" style="float:right;width:30%;height 25%">
<p>Total Distance: <span id="total"></span> Legs: <span id="legs"></span>Steps: <span id="steps"></span></p>
<table id="points"></table>
</div>
</body>
</html>
Postscript
In the end it was the use of a Bluebird promise loop that worked.
<script src="https://cdn.jsdelivr.net/bluebird/latest/bluebird.js"></script>
For the record I was not using node.js or any other functionality other than just plain js plus bluebird. Promises are dealt with in detail by many answers in StackOverflow so I recommend reading these and looking through the API: https://github.com/petkaantonov/bluebird/blob/master/API.md .
I am trying to adapt this Google Maps distance calculator to my needs, but am not overly familiar with plain Javascript, and only Jquery.
I am trying to modify one of the destination variables so that it pulls it from a text box instead.
Usually the line reads :
var destinationA = 'pe219px';
But I am trying to change it to the following, usually I would do this with a keyup function to update the value as the person types in jquery, but im not sure what im doing in plain javascript. This is what I have come up with so far, but it doesn't appear to do a lot :
function setValue() {
destinationA=parseInt(document.getElementById('deliverypostcode').value);
}
This is the example I am trying to modify
https://developers.google.com/maps/documentation/javascript/examples/distance-matrix
This is the whole code :
<!DOCTYPE html>
<html>
<head>
<title>Distance Matrix service</title>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map-canvas {
height: 100%;
width: 50%;
}
#content-pane {
float:right;
width:48%;
padding-left: 2%;
}
#outputDiv {
font-size: 11px;
}
</style>
<script>
var map;
var geocoder;
var bounds = new google.maps.LatLngBounds();
var markersArray = [];
var origin1 = new google.maps.LatLng(53.003604, -0.532764);
var origin2 = 'pe219px';
function setValue() {
destinationA=parseInt(document.getElementById('deliverypostcode').value);
}
var destinationB = new google.maps.LatLng(53.003604, -0.532764);
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';
function initialize() {
var opts = {
center: new google.maps.LatLng(53.003604, -0.532764),
zoom: 8
};
map = new google.maps.Map(document.getElementById('map-canvas'), opts);
geocoder = new google.maps.Geocoder();
}
function calculateDistances() {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [origin1, origin2],
destinations: [destinationA, destinationB],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
}, callback);
}
function callback(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var outputDiv = document.getElementById('outputDiv');
outputDiv.innerHTML = '';
deleteOverlays();
for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
addMarker(origins[i], false);
for (var j = 0; j < results.length; j++) {
addMarker(destinations[j], true);
outputDiv.innerHTML += origins[i] + ' to ' + destinations[j]
+ ': ' + results[j].distance.text + '<br>';
}
}
}
}
function addMarker(location, isDestination) {
var icon;
if (isDestination) {
icon = destinationIcon;
} else {
icon = originIcon;
}
geocoder.geocode({'address': location}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
bounds.extend(results[0].geometry.location);
map.fitBounds(bounds);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: icon
});
markersArray.push(marker);
} else {
alert('Geocode was not successful for the following reason: '
+ status);
}
});
}
function deleteOverlays() {
for (var i = 0; i < markersArray.length; i++) {
markersArray[i].setMap(null);
}
markersArray = [];
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="content-pane">
<div id="inputs">
<form name="form1" method="post" action="">
<label for="deliverypostcode">Your Postcode</label>
<input type="text" name="deliverypostcode" id="deliverypostcode">
</form>
<p><button type="button" onclick="calculateDistances();">Calculate
distances</button></p>
</div>
<div id="outputDiv"></div>
</div>
<div id="map-canvas"></div>
</body>
</html>
Your function setValue is never called.
What if you delete it and just place the following line at the begining of calculateDistances ?
var destinationA= document.getElementById('deliverypostcode').value;
This works for me. Also, you don't need to parseInt your text input. Geocoding converts strings to a lat/long coordinates.
I am new to JavaScript.
Writing a script that uses GooogleMaps API
Working OK. Get Lat Lngs from Database, Make markers, put on Map.
Decided to move a function call up a level, (it was in the OnSuccess method of a PageMethod call). Stopped working.
Put in alerts to diagnose. Starts working.
Narrowed down to having alert at top of called function MakeLatLngs().
MakeLatLngs code appears to execute regardless of alert being present or commented out.
It is just that the map displays with alert statement in and doesn't display with alert statement commented out.
The alert is just text and not using any variable. So I am at a loss to understand what is going on here.
The same thing is happening in the function that draws the map DrawMap(). I put an informative alert at the start of the function and the map draws. Leave it out and the map doesn't.
Any clues as to what is going on would be appreciated?
The script is below.
Flow starts at function Initialise at bottom of script.
thanks
var myPositions = [];
var myRoutes = [];
var myString = [];
var myLatLngs = [];
var myTitles = [];
var NumPoints;
var map;
var poly;
var RouteName;
var myMarkers = [];
var myMapCentre = new google.maps.LatLng(-41.2954168187213, 174.767133718655);
function DrawMap() {
alert("Generating Points for " + RouteName);// Need this to display
var thisLatLng = myLatLngs[0];
var myOptions = {
zoom: 8,
center: thisLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),
myOptions);
MakeMarkers();
RouteLine();
}
function OnSuccess1(response) {
myPositions = new Array();
myString = response;
NumPoints = response.length;
for (var i = 0; i < NumPoints; i++) {
myPositions[i] = response[i];
}
}
function OnError1(response) {
}
function Marker()
{
this.meterId=0;
this.latLng="";
}
function OnSuccess(response) {
myPositions = new Array();
myString = response;
NumPoints = response.length;
alert("Numpoints is " + NumPoints);
for (var i = 0; i < NumPoints; i++) {
myPositions[i] = response[i];
}
alert("Exiting OnSuccess");
//MakeLatLngs(); //ORIGINAL POSITION OF LATLNG CALL
return true;
}
function setRoute() {
RouteName = prompt(' What route?', '');
}
function OnError(error) {
alert("In Error");
}
function RouteLine() {
var polyOptions = {
strokeColor: '#000000',
strokeOpacity: 1.0,
strokeWeight: 3
}
poly = new google.maps.Polyline(polyOptions);
poly.setMap(map);
var path = poly.getPath();
for (var i = 0; i < NumPoints; i++) {
path.push(myLatLngs[i]);
}
}
function MakeLatLngs() {
alert("You need me now " );//Got to have this to display OK when called from LoadData
myLatLngs = new Array();
for (var i = 0; i < NumPoints; i++) {
var sMarker = myPositions[i];
var SeqPos = sMarker.indexOf(";");
var latLngPos = sMarker.indexOf(";", SeqPos + 1);
var marker = sMarker.substring(0, latLngPos);
//alert("Marker is " + marker);
//var Seq = sMarker.substring(latLngPos + 1, SeqPos - latLngPos);
myTitles[i] = marker;
//alert("MeterId is " + marker);
var sLatLng = sMarker.substring(latLngPos + 1)
//alert("SLatLng is " + sLatLng);
var pos = sLatLng.indexOf(",");
//alert("pos is " + pos);
var sLat = sLatLng.substring(0, pos);
//alert("sLat is " + sLat);
var sLng = sLatLng.substring(pos + 1, sLatLng.length - 1);
//alert("sLng is " + sLng);
var lat = parseFloat(sLat);
var lng = parseFloat(sLng);
//alert("Lat is " + lat + " Long is " + lng);
if (!isNaN(lng) && !isNaN(lat) && lat != 0 && lng != 0 ) {
var latlng = new google.maps.LatLng(lat, lng);
myLatLngs[i] = latlng;
}
}
alert("Exiting MakeLatLngs")
}
function MakeMarkers() {
for (var i = 0; i < NumPoints; i++) {
var sTitle = "MyValue " + i;
var marker = new google.maps.Marker({
position: myLatLngs[i],
map: map,
title: myTitles[i]
});
}
}
function LoadData() {
setRoute();//Get the desired route from the user
PageMethods.GetMarkers(RouteName, OnSuccess, OnError);
MakeLatLngs(); //Works here ONLY WHEN AN ALERT IS FIRST LINE in FUNCTION. Orginal call was at end of OnSuccess
//PageMethods.GetRouteBoundaries(OnSuccess1, OnError1);
return false;
}
function initialize() {
LoadData();
DrawMap();
}
google.maps.event.addDomListener(window, 'load', initialize);//yes you do need this with or without <body onload="initialise">
The reason is that your PageMethods.GetMarkers is asynchronous, so the data hasn't loaded when you invoke DrawMap. I guess when you use the alert, it pauses execution long enough for the data to load. Put the DrawMap method inside the OnSuccess of the page method, and that should solve the problem.