2012-04-02 181 views
0

我正在尝试查找2个点之间的距离,一个来自用户输入,另一个来自我的数据库中的地址。我已经把下面的代码放在一起,这似乎工作(我有测试变量,所以没有数据库正在进行测试),但是我碰到了一堵墙;我无法弄清楚为什么我需要点击两次按钮才能显示输出结果?使用Google Maps API查找2个点之间的距离

任何帮助深表感谢

下面的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml"> 
    <head> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
    <title>Google Maps JavaScript API Example: Extraction of Geocoding Data</title> 
    <script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAA7j_Q-rshuWkc8HyFI4V2HxQYPm-xtd00hTQOC0OXpAMO40FHAxT29dNBGfxqMPq5zwdeiDSHEPL89A" type="text/javascript"></script> 
<!-- According to the Google Maps API Terms of Service you are required display a Google map when using the Google Maps API. see: http://code.google.com/apis/maps/terms.html --> 
    <script type="text/javascript"> 

//var globalAddr = new Array(); 
var globalName; 
var xmlhttp; 
var geocoder, location1, location2; 
var distanceVal; 

    function initialize() { 
     geocoder = new GClientGeocoder(); 
    } 

     function showLocation() { 
     geocoder.getLocations(document.getElementById("address1").value, function (response) { 
      if (!response || response.Status.code != 200) 
      { 
       alert("Sorry, we were unable to geocode the first address"); 
      } 
      else 
      { 
       location1 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address}; 
       geocoder.getLocations(document.getElementById("address2").value, function (response) { 
        if (!response || response.Status.code != 200) 
        { 
         alert("Sorry, we were unable to geocode the second address"); 
        } 
        else 
        { 
         location2 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address}; 
         calculateDistance(); 
        } 
       }); 
      } 
     }); 
    } 

    function calculateDistance() 
    { 

      var glatlng1 = new GLatLng(location1.lat, location1.lon); 
      var glatlng2 = new GLatLng(location2.lat, location2.lon); 
      var miledistance = glatlng1.distanceFrom(glatlng2, 3959).toFixed(1); 
      var kmdistance = (miledistance * 1.609344).toFixed(1); 

      distanceVal = miledistance; 
    } 

function loadXMLDoc(url,cfunc) 
{ 
     if (window.XMLHttpRequest) 
      {// code for IE7+, Firefox, Chrome, Opera, Safari 
      xmlhttp=new XMLHttpRequest(); 
      } 
     else 
     {// code for IE6, IE5 
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
     } 
     xmlhttp.onreadystatechange=cfunc; 
     xmlhttp.open("GET",url,true); 
     xmlhttp.send(); 
} 
function getData(str) 
     { 
     loadXMLDoc("getData.php?address="+str,function() 
      { 
       if (xmlhttp.readyState==4 && xmlhttp.status==200) 
       { 
        var x = xmlhttp.responseText; 
        var dnames = x.split("~~~"); 
        var daddr = x.split("^^^"); 
        daddr.shift(); 
        dnames.pop(); 

        var testArray = new Array('85281','18657','90210'); 

        var shortest = 999999; 

        for(var i = 0; i <= testArray.length-1; i++) 
        { 

         document.getElementById("address2").value = testArray[i];//daddr[i]; 
         showLocation(); 

         //i get a blank alert 3 times here the first time, then I get the a value the 2nd time.. makes no sense! 
         alert(distanceVal); 

         if (shortest > distanceVal) 
         { 
          shortest = distanceVal; 
          globalName = dnames[i]; 
         } 

        } 

        document.getElementById("results").innerHTML = globalName + " " + shortest; 

       } 
      }) 
     } 

    </script> 
    </head> 

    <body onload="initialize()"> 

    <form> 
     <p> 
     <input type="text" id="address1" name="address1" class="address_input" size="40" /> 
     <input type="hidden" id="address2" name="address2" /> 
     <input type="hidden" id="distance" name="distance" /> 
     <input type="button" name="find" value="Search" onclick="getData(document.getElementsByName('address1')[0].value)"/> 
     </p> 
    </form> 
    <p id="results"></p> 

    </body> 
</html> 

回答

2

当您在getData()回拨电话showLocation(),这台假两个地理编码器调用,如果两者都成功呼叫calculateDistance()

但是,这两个地理编码调用都需要时间。第一个getLocations()引发了地理编码请求,并让它继续,并在其回调中处理。在这个函数中,还有另一个请求在它自己的回调中处理。

虽然那些正在等待结果,但代码执行仍在继续,并且即使尚未调用calculateDistance(),也已达到alert(distanceVal)。因此distanceVal尚未设置。

当您再次单击该按钮,全球distanceVal将已通过所有的回调函数填充,所以(即使第二组地理编码/回调有完成),它必须显示的值。但是,如果您更改要测试的值,则会发现它显示的旧值现在不正确。

一切这取决于在回调函数发现值必须该回调函数中进行处理。如果将数据显示移动到calculateDistance(),则一切都会正常,因为数据可用于该功能。

+0

谢谢安德鲁,我拉着我的头发试图让它工作,这完全有道理。 – bruchowski 2012-04-03 15:14:47

相关问题