2013-07-17 24 views
0

我試圖重構一些代碼,並試圖使用谷歌地圖來計算經度和緯度。我偶然遇到了一個問題,谷歌地圖以非同尋常的方式獲取數據。有人很好地提出了一個解決方案,但幾天後,我必須得出結論,我可悲的是太多的JS新手讓它工作。下面是整個代碼,以及我的原始問題:Asynchronous Google Maps request throwing off Javascript我確定它很小,但我已經嘗試了2天,並且無法獲得工作版本。任何援助將不勝感激 - 我有一種感覺,這是一個小的,但只是無法理解那是什麼。異步Google地圖拋出Javascript - 回調如何工作?

<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

你有一大堆代碼在那裏。你能把它降到相關的代碼嗎?例如,我們不需要看'$('#btn-reset')。click(...);'。 –

回答

1

主要的問題,我看到的是,你想從getlatLng返回值 - 這是行不通的,因爲地理編碼調用是異步的。關鍵是要使用回調。相反,這樣做的:

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

而是執行此操作:

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

這裏是getLatLng的實現,需要一個起點,終點和回調。反過來,這個回調函數有四個參數:start_lat,start_lng,end_lat,end_lng。語法沒有檢查,但希望它有幫助。

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 
}); 

注意作爲一般的提示,使用瀏覽器的調試工具(Shift鍵CTL-J在Chrome)。這應該允許您:

  1. 在控制檯
  2. 添加「的console.log」語句代碼檢查Javascript錯誤,以幫助跟蹤其進展情況
  3. 添加斷點的代碼,使您能夠跟蹤它的執行