Google 地图 API - 地理编码 + 热图

Google Maps API - Geocoding + Heatmap

我正在尝试构建一个应用程序,我可以在其中插入带有邮政编码的数组,执行地理编码 API 过程(有效)以将邮政编码转换为 long/lat,然后创建使用那些 long/lat 组合的热图(不起作用)。我使用了以下代码:

<!DOCTYPE html>
<html>
  <head>
    <title>Heatmap</title>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #floating-panel {
        position: absolute;
        top: 10px;
        left: 25%;
        z-index: 5;
        background-color: #fff;
        padding: 5px;
        border: 1px solid #999;
        text-align: center;
        font-family: 'Roboto','sans-serif';
        line-height: 30px;
        padding-left: 10px;
      }
    </style>
  </head>
  <body>
    <div id="floating-panel">
      <input id="address" type="textbox" value="Sydney, NSW">
      <input id="submit" type="button" value="Geocode">
    </div>
    <div id="map"></div>
    <script>
        function initMap() {
            var map = new google.maps.Map(document.getElementById('map'), {
                zoom: 8,
                center: {lat: -34.397, lng: 150.644}
            });
            var geocoder = new google.maps.Geocoder();

            geocodeAddress(geocoder, map);
        }

        function geocodeAddress(geocoder, resultsMap) {
            // var address = document.getElementById('address').value;
            // 
            var listAddress = [ "AB31", "AB38", "AB41", "AB42", "AB45", "AB51", "AB56", "AL1 ", "AL2 ", "AL3 ", "AL4 ", "AL5 ", "AL7 ", "AL8 ", "APTE", "B13 ", "B14 ", "B15 ", "B17 ", "B25 ", "B27 ", "B28 ", "B29 ", "B30 ", "B44 ", "B46 ", "B47 ", "B49 ", "B60 ", "B62 ", "B63 ", "B72 ", "B73 ", "B74 ", "B75 ", "B77 ", "B78 ", "B79 ", "B90 ", "B91 ", "B92 ", "B93 ", "B94 ", "B95 ", "B96 ", "B97 ", "B98 ", "BA1 ", "BA11", "BA13", "BA14", "BA15", "BA16", "BA2 ", "BA21", "BA22", "BA3 ", "BA4 ", "BA8 ", "BB1 ", "BB10", "BB11", "BB12", "BB18", "BB2 ", "BB3 ", "BB4 ", "BB5 ", "BB6 ", "BB7 ", "BB8 ", "BB9 ", "BD10", "BD11", "BD12", "BD13", "BD14", "BD15", "BD16", "BD17", "BD18", "BD19", "BD2 ", "BD20", "BD21", "BD22", "BD23", "BD24", "BD3 " ];

            for (index = 0; index < listAddress.length; ++index) {
                // console.log(listAddress[index]);

                var address = listAddress[index],
                    loc=[],
                    lat='',
                    lng='',
                    locationEach='';
                    heatmapData = [];

                geocoder.geocode({'address': address}, function(results, status) {
                  // if (status === 'OK') {
                  //   resultsMap.setCenter(results[0].geometry.location);
                  //   var marker = new google.maps.Marker({
                  //     map: resultsMap,
                  //     position: results[0].geometry.location
                  //   });
                  // } else {
                  //   alert('Geocode was not successful for the following reason: ' + status);
                  // }
                  if (status === 'OK') {
                    loc[0]=results[0].geometry.location.lat();
                    loc[1]=results[0].geometry.location.lng();
                    console.log(results[0].geometry.location.lat());
                    lat = String(loc[0]);
                    lng = String(loc[1]);
                    locationEach = lat + ', ' + lng;


                    heatmapData.push( new google.maps.LatLng( locationEach ) );

                    console.log( heatmapData );
                    heatMap(heatmapData);

                  } else {
                    alert('Geocode was not successful for the following reason: ' + status);
                  }
                });
            }
        }

      // var sanFrancisco = new google.maps.LatLng(37.774546, -122.433523);

      // map = new google.maps.Map(document.getElementById('map'), {
      //   center: sanFrancisco,
      //   zoom: 13,
      //   mapTypeId: 'satellite'
      // });

      function heatMap(heatmapData) {
          var heatmap = new google.maps.visualization.HeatmapLayer({
            data: heatmapData,
            setMap: map
          });
          // heatmap.setMap(map);
      }

    </script>
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=&libraries=visualization&callback=initMap">
    </script>
  </body>
</html>

理想结果:邮政编码数组将用于创建热图。

编辑:

我已经设法修复了控制台中的错误,但现在它仍然没有在地图上显示热图。

这里有几个问题:

  1. 对点进行地理编码的请求是异步发生的。因此,需要在对所有点进行地理编码后添加热图。一种方法是检查 heatmapData 的长度是否等于地址数组的长度。所以在geocoder.geocode()的回调中,添加这个检查:

    } else {
      alert('Geocode was not successful for the following reason: ' + status);
    }
    if (heatmapData.length == listAddress.length ) {
      //call heatmap() here
      heatmap()
    }
    
  2. 变量mapinitMap()scope中可见,所以当函数 heatMap() 中的代码添加了热图,它无法解析 map。为了避免这个问题,在函数 initMap() 之前声明 map。请参阅以下示例:

    var map, heatmapData = [];
    function initMap() {
        map = map = new google.maps.Map(document.getElementById('map'), {
     // ...
    }
    function heatMap() {
        //map and heatmapData are now visible
    }
    

查看 this plunker 中演示的这些更改。