Nan when loading data from Geocoder

3

I am trying to use a geocoder to convert postcode data into coordinates. I have instantiated the function twice to separate the markers (in a loop for) and the main pinpoint. Once the values of all the coordinates are loaded, I try to calculate the distance between each marker and the main pinpoint.

The problem is that because geocoder loads coordinate values asynchronously, it often tries to do the final operation without having loaded some of the coordinates, returning NaN.

Is there any way to force the last operation to be performed once all the coordinates have been loaded?

I leave you with the script.

<script>
    var map = new google.maps.Map(document.getElementById('map'), {
        scrollwheel: true,
        zoom: 14,
        disableDefaultUI: true,
        controls:false,
        styles: [{"featureType":"water","elementType":"geometry","stylers":[{"color":"#e9e9e9"},{"lightness":17}]},{"featureType":"landscape","elementType":"geometry","stylers":[{"color":"#f5f5f5"},{"lightness":20}]},{"featureType":"road.highway","elementType":"geometry.fill","stylers":[{"color":"#ffffff"},{"lightness":17}]},{"featureType":"road.highway","elementType":"geometry.stroke","stylers":[{"color":"#ffffff"},{"lightness":29},{"weight":0.2}]},{"featureType":"road.arterial","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":18}]},{"featureType":"road.local","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":16}]},{"featureType":"poi","elementType":"geometry","stylers":[{"color":"#f5f5f5"},{"lightness":21}]},{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#dedede"},{"lightness":21}]},{"elementType":"labels.text.stroke","stylers":[{"visibility":"on"},{"color":"#ffffff"},{"lightness":16}]},{"elementType":"labels.text.fill","stylers":[{"saturation":36},{"color":"#333333"},{"lightness":40}]},{"elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"geometry","stylers":[{"color":"#f2f2f2"},{"lightness":19}]},{"featureType":"administrative","elementType":"geometry.fill","stylers":[{"color":"#fefefe"},{"lightness":20}]},{"featureType":"administrative","elementType":"geometry.stroke","stylers":[{"color":"#fefefe"},{"lightness":17},{"weight":1.2}]}]
    });
    var geocoder = new google.maps.Geocoder;
    geocodeAddress(geocoder, map);


    function geocodeAddress(geocoder, resultsMap) {
        var event = $('.event-location').text();
        var siteLoc = new Array();
        var siteLocs = $('.campsite-loc');
        siteLocs.each(function() {
            var siteLocation = $(this).text();
            siteLoc.push(siteLocation); 
        });
        var eventLat;
        var eventLng;
        var siteLat;
        var siteLng;

        geocoder.geocode({'address': event}, function(results, status) {
            if (status === google.maps.GeocoderStatus.OK) {
            resultsMap.setCenter(results[0].geometry.location);
            resultsMap.setZoom(15);
            var event = new google.maps.Marker({
                map: resultsMap,
                icon: '/assets/images/event.png',
                position: results[0].geometry.location
            });
            eventLat = results[0].geometry.location.lat();
            eventLng =  results[0].geometry.location.lng();
            } else {
            alert('Geocode was not successful for the following reason: ' + status);
            }

        });
        ffor (i=0; i < siteLoc.length; i++) {
        geocoder.geocode({'address': siteLoc[i]}, function(results, status) {
            if (status === google.maps.GeocoderStatus.OK) {
                var site = new google.maps.Marker({
                    map: resultsMap,
                    icon: '/assets/images/site1.png',
                    position: results[0].geometry.location
                });
                siteLat = results[0].geometry.location.lat();
                siteLng = results[0].geometry.location.lng();
                var x = eventLat;
                var y = eventLng;
                console.log(x,y,siteLat,siteLng);
                var distance = google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(x,y), new google.maps.LatLng(siteLat,siteLng));
                var distanceKm = (distance/1000).toFixed(1);
                if (isNaN(distanceKm)) {
                    $('.distance-loc').text(0.3);
                } else {
                    $('.distance-loc').text(distanceKm);
                }
                $('.event-main-container').on('click',function() {
                    resultsMap.setCenter(results[0].geometry.location);
                });
            } else {
                alert('Geocode was not successful for the following reason: ' + status);
            }

        });
    }
    </script>

Thanks for your help!

    
asked by David Cortes Nieto 15.03.2016 в 11:21
source

1 answer

1

The problem would be in this part of the for loop:

var x = eventLat;
var y = eventLng;
console.log(x,y,siteLat,siteLng);
var distance = google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(x,y), new google.maps.LatLng(siteLat,siteLng));

as eventLat and eventLng are calculated for the main pinpoint asynchronously, it could be the case that when the distance is calculated for the markers, those variables still have no value and that's why they appear as NaN.

One possible solution: moves the for loop within the pinpoint result. This way you will make sure that eventLat and eventLng are already defined and you should not have problems:

geocoder.geocode({'address': event}, function(results, status) {
  if (status === google.maps.GeocoderStatus.OK) {
    resultsMap.setCenter(results[0].geometry.location);
    resultsMap.setZoom(15);
    var event = new google.maps.Marker({
      map: resultsMap,
      icon: '/assets/images/event.png',
      position: results[0].geometry.location
    });
    eventLat = results[0].geometry.location.lat();
    eventLng =  results[0].geometry.location.lng();
  } else {
    alert('Geocode was not successful for the following reason: ' + status);
  }

  // en este punto ya tienes los valores de eventLat y eventLng
  for (i=0; i < siteLoc.length; i++) {
    geocoder.geocode({'address': siteLoc[i]}, function(results, status) {
      if (status === google.maps.GeocoderStatus.OK) {
        var site = new google.maps.Marker({
          map: resultsMap,
          icon: '/assets/images/site1.png',
          position: results[0].geometry.location
        });
        siteLat = results[0].geometry.location.lat();
        siteLng = results[0].geometry.location.lng();
        var x = eventLat;
        var y = eventLng;
        console.log(x,y,siteLat,siteLng);
        var distance = google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(x,y), new google.maps.LatLng(siteLat,siteLng));
        var distanceKm = (distance/1000).toFixed(1);
        if (isNaN(distanceKm)) {
          $('.distance-loc').text(0.3);
        } else {
          $('.distance-loc').text(distanceKm);
        }
        $('.event-main-container').on('click',function() {
          resultsMap.setCenter(results[0].geometry.location);
        });
      } else {
        alert('Geocode was not successful for the following reason: ' + status);
      }

    });
  }

});

One drawback of this solution is that the first main point ( pinpoint ) will wait for all others to be displayed. But one way or another, they will have to wait for the first one to be generated to calculate the distance anyway.

    
answered by 15.03.2016 / 14:22
source