地理编码和 Animation.drop 与超时不兼容?

Geocoding and Animation.drop incompatible with timeout?

我写了一个小 html 页面,以便在地图上显示图钉。 我为我的网页提供了一些地址,然后我使用地理编码 () 并显示图钉。

然后,我想添加带有超时的 google.maps.Animation.DROP,如 Google 地图 API 页面中所述。 (https://developers.google.com/maps/documentation/javascript/examples/marker-animations-iteration?hl=fr)

在Google地图API页面中,示例代码直接使用了坐标。很简单。

在我的例子中,我需要在 geocoding() 之前使用以获得积分,然后显示图钉。

我真的不明白,但我无法使用地理编码超时使用此 Drop 动画。我在Chrome中使用了调试器视图,但我不明白。

这是我的代码,我尽量做到简单:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<style>
    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
    }
    #map {
        width:100%;
        height:100%;
    }
</style>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps</title>
<script async defer
  src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAs4c8xnkxcZNRK6yQt-Y21N1L3mT1AFfE&callback=initMap">
</script>
</head>
<body>

<div id="map"  ></div>

<noscript><b>JavaScript must be enabled in order for you to use Google Maps.</b> 
  However, it seems JavaScript is either disabled or not supported by your browser. 
  To view Google Maps, enable JavaScript by changing your browser options, and then 
  try again.
</noscript>

<script type="text/javascript">
//<![CDATA[

var infoWindow;
var map;
var geocoder;
var bounds; 
var TbCoordonnees       =   [];
var TbMarkers           =   [];
var AdresseTiersTb      =   [];

function initMap() 
{   

    geocoder = new google.maps.Geocoder();
    var optionsCarte =  {
                            zoom: 8,
                            center: new google.maps.LatLng(48.5, 2.9),
                            mapTypeId: google.maps.MapTypeId.ROADMAP
                        };

    map = new google.maps.Map(document.getElementById('map'), optionsCarte);

    bounds = new google.maps.LatLngBounds();

    infoWindow = new google.maps.InfoWindow({});

    // EXAMPLE :

    AdresseTiersTb.push("39 Boulevard de Courtais, 03100 Montluçon");
    AdresseTiersTb.push("Place de l'Hôtel de ville, 13100 Aix-en-Provence");
    AdresseTiersTb.push("55 Rue du Faubourg Saint-Honoré, 75008 Paris");
    AdresseTiersTb.push("Place des Buisses, 59000 Lille");

    for (var i = 0; i < AdresseTiersTb.length; i++)
    {   
        geocodeAddress(AdresseTiersTb[i],i*200);        
    }

}   

function geocodeAddress(address,timeout)
{
    geocoder.geocode(
    {'address': address},
        function(results, status)
        {
            if((results != null) && (status == google.maps.GeocoderStatus.OK))
            {
                var marker = createMarker(address,timeout,results);
            } 
            else 
            {
                alert("geocode failed on "+address+", status="+status);
            }
        }
    );
}

function createMarker(address,timeout,results)
{
    var marker;

    window.setTimeout(function() {
    marker = new google.maps.Marker({
                    map: map,
                    position: results[0].geometry.location,animation: google.maps.Animation.DROP
                });},timeout);


    bounds.extend(results[0].geometry.location);
    map.fitBounds(bounds)
    map.panToBounds(bounds); 
    map.setCenter(bounds.getCenter()); 

    var infocontent = address;

    google.maps.event.addListener(marker, 'click', function() {
            infoWindow.setContent(infocontent);
            infoWindow.open(map, marker);
    });
    return marker;
}

function listenMarker (marker, info)
{
    google.maps.event.addListener(marker, 'click', function() {
    infoWindow.setContent(info);
    infoWindow.open(map, this);
    });
}




</script>

问题是 var marker 似乎未定义,因此一旦显示图钉而不是三个图钉就没有图钉。我不知道为什么,但是当我在调试模式下查看时,我不明白地理编码是如何执行的。很奇怪。

您无法从异步 setTimeout 回调函数(创建并添加到地图的地方)return marker 变量的有用值。函数 return 立即变量(在它被 setTimeout 调用的回调定义之前(稍后运行)。添加时 marker 也没有定义click 事件侦听器。

proof of concept fiddle

代码片段:

var infoWindow;
var map;
var geocoder;
var bounds;
var TbCoordonnees = [];
var TbMarkers = [];
var AdresseTiersTb = [];

function initMap() {
  geocoder = new google.maps.Geocoder();
  var optionsCarte = {
    zoom: 8,
    center: new google.maps.LatLng(48.5, 2.9),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById('map'), optionsCarte);
  bounds = new google.maps.LatLngBounds();
  infoWindow = new google.maps.InfoWindow({});

  // EXAMPLE :
  AdresseTiersTb.push("Versailles, FR");
  AdresseTiersTb.push("Paris, FR");
  AdresseTiersTb.push("Sens, FR");

  for (var i = 0; i < AdresseTiersTb.length; i++) {
    geocodeAddress(AdresseTiersTb[i], i * 200);
  }
}

function geocodeAddress(address, timeout) {
  // function closure on address.
  geocoder.geocode({
      'address': address
    },
    function(results, status) {
      if ((results != null) && (status == google.maps.GeocoderStatus.OK)) {
        createMarker(address, results[0].geometry.location, timeout);
        bounds.extend(results[0].geometry.location);
        map.fitBounds(bounds)
      } else {
        alert("geocode failed on " + address + ", status=" + status);
      }
    }
  );
}

function createMarker(address, latLng, timeout) {
  // function closure on address, latLng
  window.setTimeout(function() {
    var marker = new google.maps.Marker({
      map: map,
      position: latLng,
      animation: google.maps.Animation.DROP
    });
    google.maps.event.addListener(marker, 'click', (function(marker, address) {
      // function closure on marker, address
      return function() {
        infoWindow.setContent(address);
        infoWindow.open(map, marker);
      }
    })(marker, address));
  }, timeout);
}

function listenMarker(marker, info) {
  google.maps.event.addListener(marker, 'click', function() {
    infoWindow.setContent(info);
    infoWindow.open(map, this);
  });
}

google.maps.event.addDomListener(window, "load", initMap);
html,
body,
#map {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map"></div>