使用Google Maps API查找2个点之间的距离

时间:2012-04-02 23:34:41

标签: ajax google-maps-api-3 callback

我试图找到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>

1 个答案:

答案 0 :(得分:2)

当您在showLocation()回调中拨打getData()时,会启动两个地理编码器呼叫,如果两个呼叫成功,则calculateDistance()

但是,这些地理编码器调用都需要时间。第一个getLocations()设置地理编码请求并让它继续,以便在其回调中处理。在该函数中,还有另一个请求,它在自己的回调中处理。

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

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

依赖于回调函数中找到的值的所有内容必须才能在该回调函数中处理。如果将数据显示移动到calculateDistance(),一切都会好的,因为该数据可用于该功能。