Geocoder call not working in for loop

I am working on a project to track multiple devices with their latest location address, name, time, etc. To display the address I am using reverse geocoding (the last lat long location comes from mysql db). The code works for tracking one device, but when I try to display all devices at a time, it only displays the address of the first device. After that, the cycle stops. I don't understand where I am going wrong. Tell me my mistake and correct me if anyone knows. Here is my complete javascript code.

<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>

      

+3


source to share


1 answer


Variables are currently dependent on a value j

during callback execution, which may not finish until the actual loop for

ends rather j

than reaching its maximum value. Instead, you need to force them to have their own volume. Javascript has no scope, so you need to wrap it in another function call like this:

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);
        }
    };
}

      

And then in the second loop for your function, googlemap()

you can do this:



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);

}

      

You may find it easier to store the data as a array of objects for processing (and have access to the item.name

, item.time

, item.flightPlanCoordinates

, and so on), so you can easily create their callbacks using Array.forEach()

, which takes care of you for the entire region.

+3


source







All Articles