2015-05-20 2 views
3

Я работаю над проектом отслеживания нескольких устройств с их последним адресом местоположения, именем, временем и т. Д. Для отображения адреса я использую обратное геокодирование (последнее местоположение lat long происходит от mysql db). Код работает для отслеживания одного устройства, но когда я пытаюсь отображать все устройства за раз, он отображает только адрес первого устройства. После этого, для цикла останавливается. Я не понимаю, где я ошибаюсь. Назовите мне мою ошибку и исправьте меня, если кто-нибудь знает. Вот мой полный код javascript.вызов геокодера не работает в цикле

<script type="text/javascript">  
function load() { 
      var abc; 
      var pqr; 
      function getLocation() { 
       navigator.geolocation.getCurrentPosition(showPosition); 
      } 
      function showPosition(position) { 
       abc = position.coords.latitude; 
       pqr = position.coords.longitude; 
       googlemap(abc, pqr); 
      } 
      getLocation(); 
     } 

     function googlemap(lat, lng) { 
      var x = document.getElementById("myForm"); 
      var text = ''; 
      for (var k = 0; k < x.length; k++) { 
       text += x[k].value; 
       if (k != (x.length - 1)) { 
        text += ","; 
       } 
      } 

      var names = new Array(); 
      var colors = new Array(); 
      var imeis = new Array(); 
      var times = new Array(); 
      var point; 

      var map = new google.maps.Map(document.getElementById("map"), { 
       center: new google.maps.LatLng(lat, lng), 
       zoom: 6, 
       mapTypeId: google.maps.MapTypeId.ROADMAP 
      }); 

      var iconsetngs = { 
       path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW 
      }; 

      setInterval(function() { 
       downloadUrl("points.php?data=" + text, function (data) { 
        var xml = data.responseXML; 
        var points = xml.documentElement.getElementsByTagName("point"); 
        flightPlanCoordinates = new Array(); 
        var imo = ''; 
        var w = -1; 
        for (var i = 0; i < points.length; i++) { 
         if (parseFloat(points[i].getAttribute("imei")) != imo) { 
          names.push(points[i].getAttribute("name")); 
          times.push(points[i].getAttribute("time")); 
          colors.push(points[i].getAttribute("color")); 
          imeis.push(parseFloat(points[i].getAttribute("imei"))); 
          imo = parseFloat(points[i].getAttribute("imei")); 
          w++; 
          flightPlanCoordinates[w] = new Array(); 
         } 
         point = new google.maps.LatLng(
           parseFloat(points[i].getAttribute("lat")), 
           parseFloat(points[i].getAttribute("lon")) 
           ); 
         flightPlanCoordinates[w].push(point); 
        } 

        for (var j = 0; j < imeis.length; j++) { 
         var flightPath = new google.maps.Polyline({ 
          path: flightPlanCoordinates[j], 
          geodesic: true, 
          strokeColor: colors[j], 
          strokeOpacity: 1.0, 
          strokeWeight: 2, 
          icons: [{ 
            icon: iconsetngs, 
            repeat: '35px', 
            offset: '100%'}] 
         }); 

         var geocoder = new google.maps.Geocoder(); 
         geocoder.geocode({'latLng': flightPlanCoordinates[j][(flightPlanCoordinates[j].length) - 1]}, function (results, status) { 
          if (status == google.maps.GeocoderStatus.OK) { 
           if (results[1]) { 
            map.setZoom(7); 
            var marker = new google.maps.Marker({ 
             position: flightPlanCoordinates[j][(flightPlanCoordinates[j].length) - 1], 
             map: map 
            }); 
            var contentString = names[j] + times[j] + results[1].formatted_address; 
            var infowindow = new google.maps.InfoWindow({ 
             content: contentString 
            }); 
            infowindow.open(map, marker); 
           } else { 
            alert('No results found'); 
           } 
          } else { 
           alert('Geocoder failed due to: ' + status); 
          } 
         }); 

         flightPath.setMap(map); 
         geocoder.setMap(map); 

        } 
       }); 
       names = []; 
       imeis = []; 
       times = []; 
       colors = []; 
       flightPlanCoordinates = []; 
      }, 10 * 1000); 
     } 


     function downloadUrl(url, callback) { 
      var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest; 
      request.onreadystatechange = function() { 
       if (request.readyState == 4) { 
        request.onreadystatechange = doNothing; 
        callback(request, request.status); 
       } 
      }; 
      request.open('GET', url, true); 
      request.send(null); 
     } 

     function doNothing() { 
     } </script> 
<body onload="load();"> 
    <form method="post" id="myForm" class="myForm" name="myForm"> 
     <select name="dvc"> 
      <option value="all">All</option> 
      <?php 
      $qry = mysql_query("SELECT * FROM devices"); 
      while ($row = mysql_fetch_array($qry)) { 
       ?> 
       <option value="<?php echo $row['device_imei']; ?>"><?php echo $row['device_name']; ?></option> 
      <?php } ?> 
     </select> 
     <input type="date" name="exct" value="<?php echo $date; ?>"/> 
     From: 
     <input type="date" name="from" /> 
     To: 
     <input type="date" name="to" /> 
    </form> 
    <button onclick="load();">Submit</button> 

    <div id="map" style="width: 100%; height: 100%"></div> 
</body> 
+0

Не могли бы вы также опубликовать некоторые ваши HTML и некоторые примеры данных? Я не вижу никаких реальных ошибок в вашем коде (хотя некоторые из ваших вариантов немного меня пугали), но если бы был какой-то исполняемый код (фрагмент или ссылка на пример jsFiddle, возможно), это помогло бы. –

+0

@http: //stackoverflow.com/users/2020820/steve-k Я тоже редактировал свой HTML-код .. И данные mysql поступают из XML –

+0

@Steve K Есть ли какие-либо ошибки в моем коде? Если нет, то почему это не работает после geocoder.setMap (map); заявление. После этого утверждения он не подходит для j = 1 in for loop (imeis.length равно 2). –

ответ

2

Переменные в настоящее время зависит от величины j во время обратного вызова, который выполняет не может быть до фактического for отделки петель и j находится на максимальном значении. Вместо этого вам нужно заставить их иметь свой собственный объем. Javascript не имеет блок области видимости, так что вам нужно обернуть его в другом вызове функции, как это:

var createGeocodeCallback = function(n){ 
    return function (results, status) { 
     if (status == google.maps.GeocoderStatus.OK) { 
      if (results[1]) { 
       map.setZoom(7); 
       var marker = new google.maps.Marker({ 
        position: flightPlanCoordinates[n][(flightPlanCoordinates[n].length) - 1], 
        map: map 
       }); 
       var contentString = names[n] + times[n] + results[n].formatted_address; 
       var infowindow = new google.maps.InfoWindow({ 
        content: contentString 
       }); 
       infowindow.open(map, marker); 
      } else { 
       alert('No results found'); 
      } 
     } else { 
      alert('Geocoder failed due to: ' + status); 
     } 
    }; 
} 

, а затем в вашем втором цикле для вашей googlemap() функции, вы можете сделать это:

for (var j = 0; j < imeis.length; j++) { 
    var flightPath = new google.maps.Polyline({ 
     path: flightPlanCoordinates[j], 
     geodesic: true, 
     strokeColor: colors[j], 
     strokeOpacity: 1.0, 
     strokeWeight: 2, 
     icons: [{ 
       icon: iconsetngs, 
       repeat: '35px', 
       offset: '100%'}] 
    }); 

    var geocoder = new google.maps.Geocoder(); 
    geocoder.geocode({'latLng': flightPlanCoordinates[j][(flightPlanCoordinates[j].length) - 1]}, createGeocodeCallback(j)); 

    flightPath.setMap(map); 
    geocoder.setMap(map); 

} 

Возможно, вам будет проще хранить данные как один массив объектов для обработки (и получить доступ к item.name, item.time, item.flightPlanCoordinates и т. Д.), Чтобы вы могли просто создавать свои обратные вызовы с помощью Array.forEach(), который заботится о всей области для вы.

+0

Получил успех. Благодарим за ваше предложение. Вся проблема возникла из-за геокодирования.setMap (карта); заявление. В этом не было необходимости. Это утверждение было неправильным. Поэтому Javascript больше не выполняется из этого. –

+0

Как справиться с проблемой OVER QUERY LIMIT в этом коде? Единственное, что я знаю, это то, что я должен что-то сделать в части if (status == google.maps.GeocoderStatus.OK). Но что делать? –