Нахождение расстояния между 2 точками с помощью Google Maps API - PullRequest
0 голосов
/ 03 апреля 2012

Я пытаюсь найти расстояние между двумя точками, одна из которых вводится пользователем, а другая - адресом из моей базы данных.Я собрал приведенный ниже код, который, кажется, работает (у меня есть тестовые переменные на месте, поэтому не выполняется извлечение базы данных для тестирования), однако я попал в стену;Я не могу понять, почему мне нужно дважды нажать кнопку, чтобы отобразить вывод?

Любая помощь очень ценится

КОД НИЖЕ:

<!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 Ответ

2 голосов
/ 03 апреля 2012

Когда вы вызываете showLocation() в вашем getData() обратном вызове, это вызывает два вызова геокодера, и если оба вызова успешны calculateDistance().

Однако оба этих вызова геокодера требуют времени. Первый getLocations() запускает запрос геокода и позволяет ему продолжить работу, которая будет обработана в его обратном вызове. Внутри этой функции есть еще один запрос, который обрабатывается в его собственном обратном вызове.

Пока они ждут результатов, выполнение кода продолжилось и достигло alert(distanceVal), хотя calculateDistance() еще не был вызван. Следовательно, distanceVal еще не установлен.

Когда вы нажмете кнопку еще раз, глобальный distanceVal будет заполнен всеми функциями обратного вызова, поэтому (хотя второй набор геокодов / обратных вызовов завершен , а не завершен), он будет иметь значение для отображения. Однако, если вы измените тестируемые значения, вы обнаружите, что оно отображает старое значение, которое сейчас неверно.

Все , которое зависит от значений, найденных в функции обратного вызова , должно быть обработано в этой функции обратного вызова. Если вы переместите отображение данных в calculateDistance(), все будет хорошо, потому что данные доступны для этой функции.

...