地理编码器调用在for循环中不起作用

时间:2015-05-20 05:21:25

标签: javascript google-maps reverse-geocoding

我正在研究跟踪多个设备的项目,包括他们的最后位置地址,姓名,时间等。要显示地址,我使用反向地理编码(最后位置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>

1 个答案:

答案 0 :(得分:3)

当前变量在回调执行时依赖于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.nameitem.timeitem.flightPlanCoordinates等)可能会更容易,更清晰,因此您可以使用Array.forEach()创建回调,为您处理整个范围。