0

I'm trying to refactor some code, and am trying to use Google maps to calculate longitude and latitude. I orignally ran into a problem with Google maps getting the data ascynronously. Someone was nice enough to suggest a solution, but after a few days, I must conclude that I'm sadly too much of a JS newbie to get it to work. Here's the entire code, along with my original question: Asynchronous Google Maps request throwing off Javascript I'm sure it's something small, but I've tried for 2 days and haven't been able to get a working version. Any assistance would be much appreciated - I have a feeling it's something small, but just can't fathom what that is.

<script type="text/javascript"> //declare variables var map; var directionsService; var directionsDisplay1, directionsDisplay2, directionsDisplay3; var markersArray = []; var stations; var autocomplete_options = {componentRestrictions: {country: 'us'}}; var places = new Array(); places[0] = "Barlays Center, Brooklyn NY"; places[1] = "Union Square, nyc"; //formerly var autocomplete_start = new google.maps.places.Autocomplete(document.getElementById("id_start"), autocomplete_options); var autocomplete_start = places[0]; //var autocomplete_start = new google.maps.places.PlacesService(places[0]); var autocomplete_end = places[1]; //Figure out the distance between your location and the nearest Citibike station function getDistance(lat1,lng1,lat2,lng2) { var i = lat1 - lat2; var j = lng1 - lng2; return i*i + j*j; } function findNearestStation(lat,lng) { var min_distance = 99999; var closest_station_id; $.each(stations.stationBeanList, function(i, station) { var distance = getDistance(lat,lng, station.latitude, station.longitude); if (distance < min_distance) { min_distance = distance; closest_station_id = i; } }); console.log('Closest station idx: ' + closest_station_id); return stations.stationBeanList[closest_station_id]; } //Draw on the map function drawMarker(lat, lng, map, title, marker_text) { var point = new google.maps.LatLng(lat, lng); var marker = new google.maps.Marker({ position : point, map : map, title : title, icon: 'http://chart.apis.google.com/chartchst=d_map_pin_letter&chld='+marker_text+'|FE6256|000000' }); markersArray.push(marker); } function clearMarkers() { for (var i = 0; i < markersArray.length; i++ ) { markersArray[i].setMap(null); } markersArray = []; } function drawMap() { var center = new google.maps.LatLng(40.704066,-73.992727); var mapOptions = { mapTypeId: google.maps.MapTypeId.ROADMAP, mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU }, zoom: 14, center: center }; map = new google.maps.Map(document.getElementById("map"), mapOptions); directionsService = new google.maps.DirectionsService(); directionsDisplay1 = new google.maps.DirectionsRenderer(); directionsDisplay1.setMap(map); directionsDisplay1.setPanel(document.getElementById("directions-panel1")); directionsDisplay2 = new google.maps.DirectionsRenderer(); directionsDisplay2.setMap(map); directionsDisplay2.setPanel(document.getElementById("directions-panel2")); directionsDisplay3 = new google.maps.DirectionsRenderer(); directionsDisplay3.setMap(map); directionsDisplay3.setPanel(document.getElementById("directions-panel3")); $.getJSON('./static/js/stations.json', function(data) { stations = data; var bounds = new google.maps.LatLngBounds(); $.each(data.stationBeanList, function(i, station) { if (station.statusValue == 'In Service') { var point = new google.maps.LatLng(station.latitude, station.longitude); bounds.extend(point); } }); map.setCenter(bounds.getCenter(), map.fitBounds(bounds)); autocomplete_start.bindTo('bounds', map); autocomplete_end.bindTo('bounds', map); }); } $(document).ready(function(){ drawMap(); }); $('#btn-reset').click(function(){ $('#directions-panel1').empty(); $('#directions-panel2').empty(); $('#directions-panel3').empty(); $('#directions-info1').empty(); $('#directions-info2').empty(); $('#directions-info3').empty(); drawMap(); }); $('#btn-get-directions').click(function(){ //take directions on the map var start = autocomplete_start; var end = autocomplete_end; var start_lat=getLat(start); //this is legacy code - the original had Google autocomplete var start_lng; var end_lat; var end_lng; // getLat(start); function getLat(loc) { var geocoder = new google.maps.Geocoder(); geocoder.geocode({'address': loc}, function postcodesearch(results, status) { if (status == google.maps.GeocoderStatus.OK) { var lat = results[0].geometry.location.lat(); //alert(lat); return lat; //alert(start_lng); } else { alert("Error"); } }); } //These are original functions I wrote function getLng(loc) { var geocoder_lng = new google.maps.Geocoder(); geocoder_lng.geocode({'address': loc}, function postcodesearch(results, status) { if (status == google.maps.GeocoderStatus.OK) { var lng = results[0].geometry.location.lng(); // alert(lng); return lng; //alert(end_lat); //doRest(); } else { alert("Error"); } }); } //This is a far superior function someone else wrote, which I cannot implement function getLatLng(loc, callback) { var geocoder = new google.maps.Geocoder(); geocoder.geocode({'address': loc}, function postcodesearch(results, status) { if (status == google.maps.GeocoderStatus.OK) { var lat = results[0].geometry.location.lat(); var lng = results[0].geometry.location.lng(); alert("234234"); return(lat, lng); } } );} getLatLng(start); doRest() //This is the rest of the code function doRest(){ //var start_lat = start.geometry.location.lat(); //alert("DO REST"); var start_lng = getLng(start); alert(start_lng); var start_p = new google.maps.LatLng(getLatLng(start)); //alert(start_p); //alert(start_p); //var end_lat = end.geometry.location.lat(); //var end_lng = end.geometry.location.lng(); var end_p = new google.maps.LatLng(getLatLng(end)); var start_station = findNearestStation(start_p); var end_station = findNearestStation(end_p); alert("asdf"); var start_station_p = new google.maps.LatLng(start_station.latitude, start_station.longitude); alert("wtf"); var end_station_p = new google.maps.LatLng(end_station.latitude, end_station.longitude); // alert("stations"); var dir_bounds = new google.maps.LatLngBounds(); dir_bounds.extend(start_p); dir_bounds.extend(end_p); dir_bounds.extend(start_station_p); dir_bounds.extend(end_station_p); drawMarker(start_lat, start_lng, map, $('#id_start').val(), '1'); drawMarker(start_station.latitude, start_station.longitude, map, start_station.stationName, '2'); drawMarker(end_station.latitude, end_station.longitude, map, end_station.stationName, '3'); drawMarker(end_lat, end_lng, map, $('#id_end').val(), '4'); } // We'll make 3 calls, 1) walking, 2) biking, 3) walking // Walk from start to station 1 var request1 = { origin:start_p, destination:start_station_p, travelMode: google.maps.TravelMode.WALKING }; directionsService.route(request1, function(result, status) { if (status == google.maps.DirectionsStatus.OK) { $('#directions-info1').html('Walk from ' + $('#id_start').val() + ' to station at ' + start_station.stationName); directionsDisplay1.setDirections(result); } }); // Bike from station 1 to station 2 var request2 = { origin:start_station_p, destination:end_station_p, travelMode: google.maps.TravelMode.BICYCLING }; directionsService.route(request2, function(result, status) { if (status == google.maps.DirectionsStatus.OK) { $('#directions-info2').html('Bike from station at ' + start_station.stationName + ' to station at ' + end_station.stationName); directionsDisplay2.setDirections(result); } }); // Walk from station 2 to end var request3 = { origin:end_station_p, destination:end_p, travelMode: google.maps.TravelMode.WALKING }; directionsService.route(request3, function(result, status) { if (status == google.maps.DirectionsStatus.OK) { $('#directions-info3').html('Walk from station at ' + end_station.stationName + ' to ' + $('#id_end').val() ); directionsDisplay3.setDirections(result); } }); google.maps.event.addListener(directionsDisplay1, 'directions_changed', function() { map.setCenter(dir_bounds.getCenter(), map.fitBounds(dir_bounds)); }); google.maps.event.addListener(directionsDisplay2, 'directions_changed', function() { map.setCenter(dir_bounds.getCenter(), map.fitBounds(dir_bounds)); }); google.maps.event.addListener(directionsDisplay3, 'directions_changed', function() { map.setCenter(dir_bounds.getCenter(), map.fitBounds(dir_bounds)); }); }); 

1
  • 1
    You have a lot of code there. Can you minimize it down to the relevant code? For example, we don't need to see $('#btn-reset').click(...);. Commented Jul 17, 2013 at 0:11

1 Answer 1

1

The main problem I see is that you're trying to return values from getlatLng -- that won't work, because the geocode call is asynchronous. The key point is to use callbacks. Instead of doing this:

function getLatLng() { return somevalue; } latlng = getLatLng(); // do something 

Do this instead:

function getLatLng(callback) { callback(somevalue); } getLatLng(function(latlng) { // do something }); 

Here's an implementation of getLatLng that takes a start, end, and callback. The callback, in turn, is a function that takes four parameters: start_lat, start_lng, end_lat, end_lng. It is unchecked for syntax, but hopefully it helps.

function getLatLng(start, end, callback) { var geocoder = new google.maps.Geocoder(); // geocode the start geocoder.geocode({'address': start}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { var startlat = results[0].geometry.location.lat(); var startlng = results[0].geometry.location.lng(); console.log('Got start: ' + startlat + ', ' + startlng); // geocode the end geocoder.geocode({'address': end}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { var endlat = results[0].geometry.location.lat(); var endlng = results[0].geometry.location.lng(); console.log('Got end: ' + endlat + ', ' + endlng); // invoke the callback function callback(startlat, startlng, endlat, endlng); } }); } }); } // the third parameter provided here to getLatLng is the callback function: getLatLng(start, end, function(start_lat, start_lng, end_lat, end_lng) { //This is the rest of the code var start_p = new google.maps.LatLng(start_lat, start_lng); var end_p = new google.maps.LatLng(end_lat, end_lng); var start_station = findNearestStation(start_p); var end_station = findNearestStation(end_p); // etc }); 

Note As a general tip, use your browser's debugging tools (Shift-Ctl-J in Chrome). This should allow you to:

  1. Check for Javascript errors in the console
  2. Add "console.log" statements to your code to help trace its progress
  3. Add breakpoints to the code to enable you to trace its execution
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.