【问题标题】:Geocoding and mapping addresses地理编码和映射地址
【发布时间】:2021-05-26 16:05:54
【问题描述】:

我在使用来自街道地址的 Google 地图上的图钉时遇到问题。我想放置引脚,将缩放级别设置为显示所有放置的引脚所需的最高级别(即在我的示例中放大 3 个位置)并在引脚上使用我的数组中的内容的 infoWindows。

我有一个地址数组(位置)[1],以及我想放在信息窗口中的信息[0]。我的地理编码工作正常,我的图钉放在地图上。地图不会放大我的图钉,也不会显示 infoWindows。

这是我的代码:

<div id="map" style="background:#db7093;height:600px;width:auto;"></div>

<script type="text/javascript">
var locations = [
    ["<a href=\"https://example.com/building1/\">Library</a>", " 350 W Georgia St, Vancouver, BC, Canada", 1],
    ["<a href=\"https://example.com/building2/\">City Hall</a>", "453 W 12th Ave, Vancouver, BC, Canada", 2],
    ["<a href=\"https://example.com/building3/\">Art Gallery</a>", "750 Hornby St, Vancouver, BC, Canada", 3]
];
</script>
<script type="text/javascript">
function mapAddress(currentLocation, bounds) {
    var geocoder = new google.maps.Geocoder();
    var marker = new google.maps.Marker();

    var address = currentLocation[1];

    geocoder.geocode({
        "address": address
    }, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            map.setCenter(results[0].geometry.location);
            if (marker)
                marker.setMap(null);
            marker = new google.maps.Marker({
                map: map,
                position: results[0].geometry.location,
                draggable: false
            });

            bounds.extend(marker.position);

            google.maps.event.addListener(marker, "click", (function(marker, i) {
                return function() {
                    infowindow.setContent(currentLocation[0]);
                    infowindow.open(map, marker);
                }
            })(marker, i));
        } else {
            alert("Geocode was not successful for the following reason: " + status);
        }
    });
}

function initMap() {
    window.map = new google.maps.Map(document.getElementById("map"), {
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var infowindow = new google.maps.InfoWindow();

    var bounds = new google.maps.LatLngBounds();

    for (i = 0; i < locations.length; i++) {
        var currentLocation = locations[i];

        mapAddress(currentLocation, bounds);
    }

    map.fitBounds(bounds);
    map.panToBounds(bounds);

    var listener = google.maps.event.addListener(map, "idle", function() {
        map.setZoom(14); // Manually setting zoom level, as fitBounds isn't working
        google.maps.event.removeListener(listener);
    });
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=[MyGoogleMapsAPIKeyHasBeenRemoved]&callback=initMap"></script>

【问题讨论】:

  • 您是否查看了 javascript 控制台的错误?我得到Uncaught ReferenceError: infowindow is not defined 显然是因为infowindow 变量在initMap 函数中声明并在mapAddress 中使用。
  • 解决我上面提到的范围问题将解决 infowindows 的问题。另请注意,地理编码器服务是异步的,因此您最终会在创建(所有)标记之前执行 fitbounds。你应该采取不同的方式。

标签: javascript google-maps google-maps-api-3 google-maps-markers google-geocoding-api


【解决方案1】:
  1. 创建具有正确范围的infowindow 和bounds 变量。了解 JS 中的 variables scope。
  2. 我已经删除了if (marker) marker.setMap(null); 部分,因为我想不出你为什么使用它。
  3. 我已将map.fitBounds(bounds) 移动到地理编码器回调中,否则它会在创建所有标记之前执行(地理编码器是异步的),换句话说,您在for 循环完成后调用fitBounds,但是那时,Geocoder 尚未完成从 API 获取信息和/或创建标记。
  4. 我已移除标记侦听器周围的闭包,因为它不是必需的。
  5. 我删除了不必要的map.panToBounds(bounds);。
  6. 我已经删除了你不必要的空 google.maps.Marker 声明。
  7. 我已删除您的地图idle 事件,这是不必要的,因为适当的缩放级别将由fitBounds 方法设置。
  8. 您应该知道,地理编码器每秒有 50 个请求的限制,因此如果您的位置列表大于 50 个,您的代码可能每秒发送超过 50 个请求。

var locations = [
  ["<a href=\"https://example.com/building1/\">Library</a>", " 350 W Georgia St, Vancouver, BC, Canada", 1],
  ["<a href=\"https://example.com/building2/\">City Hall</a>", "453 W 12th Ave, Vancouver, BC, Canada", 2],
  ["<a href=\"https://example.com/building3/\">Art Gallery</a>", "750 Hornby St, Vancouver, BC, Canada", 3]
];

var bounds, infowindow;

function mapAddress(currentLocation, bounds) {
  var geocoder = new google.maps.Geocoder();
  var address = currentLocation[1];

  geocoder.geocode({
    "address": address
  }, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      map.setCenter(results[0].geometry.location);
      var marker = new google.maps.Marker({
        map: map,
        position: results[0].geometry.location,
        draggable: false
      });

      bounds.extend(marker.position);
      map.fitBounds(bounds);

      google.maps.event.addListener(marker, "click", function() {
        infowindow.setContent(currentLocation[0]);
        infowindow.open(map, marker);
      });
    } else {
      alert("Geocode was not successful for the following reason: " + status);
    }
  });
}

function initMap() {
  window.map = new google.maps.Map(document.getElementById("map-canvas"), {
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });

  infowindow = new google.maps.InfoWindow();
  bounds = new google.maps.LatLngBounds();

  for (i = 0; i < locations.length; i++) {
    var currentLocation = locations[i];
    mapAddress(currentLocation, bounds);
  }
}
#map-canvas {
  height: 180px;
}
<div id="map-canvas"></div>

<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>

【讨论】:

  • 非常感谢您,特别是对于您所做更改的 cmets。非常感谢。我的计划是将经纬度值存储在数据库中,因为地图上显示了项目,所以我只在坐标未知的情况下查找它们。感谢您对每秒 50 个请求限制的提醒。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2021-07-19
相关资源
最近更新 更多