【问题标题】:Google Maps: remember id of marker with open info window谷歌地图:记住带有打开信息窗口的标记的 ID
【发布时间】:2010-02-04 17:32:34
【问题描述】:

我有一个显示许多标记的 Google 地图。当用户移动地图时,使用以下代码为新边界重新绘制标记:

GEvent.addListener(map, "moveend", function() { 
    var newBounds = map.getBounds();
    for(var i = 0; i < places_json.places.length ; i++) {
       // if marker is within the new bounds then do...
       var latlng = new GLatLng(places_json.places[i].lat, places_json.places[i].lon);
       var html = "blah";
       var marker = createMarker(latlng, html);
       map.addOverlay(marker);
    }
}); 

我的问题很简单。如果用户单击了标记以显示打开的信息窗口,则当前重新绘制边界时,信息窗口将关闭,因为标记是从头开始添加的。我怎样才能防止这种情况发生?

这并不理想,因为当用户单击标记并且地图移动以显示信息窗口时,通常会重新绘制边界 - 因此信息窗口会出现然后再次消失:)

我想有几种可能的方法:

  • 记住哪个标记有一个打开的信息窗口,并在重新绘制标记时再次打开它
  • 实际上不要在打开信息窗口的情况下重新添加标记,只需将其留在那里

但是,两者都要求带有打开窗口的标记具有某种 ID 号,我不知道 Google Maps API 中的实际情况是否如此。有人吗?

---------更新------

按照建议,我已尝试通过将标记加载到初始数组中来做到这一点。这加载正常,但拖动地图后页面崩溃。

<script type="text/javascript" src="{{ MEDIA_URL }}js/markerclusterer.js"></script>
<script type='text/javascript'>

function createMarker(point,html, hideMarker) {
  //alert('createMarker');
  var icon = new GIcon(G_DEFAULT_ICON);
  icon.image = "http://chart.apis.google.com/chart?cht=mm&chs=24x32&chco=FFFFFF,008CFF,000000&ext=.png";
  var tmpMarker = new GMarker(point, {icon: icon, hide: hideMarker});
  GEvent.addListener(tmpMarker, "click", function() {
    tmpMarker.openInfoWindowHtml(html);
  });
  return tmpMarker;
}

var map = new GMap2(document.getElementById("map_canvas"));
map.addControl(new GSmallMapControl());
var mapLatLng = new GLatLng({{ place.lat }}, {{ place.lon }});
map.setCenter(mapLatLng, 12);
map.addOverlay(new GMarker(mapLatLng));

// load initial markers from json array

var markers = [];
var initialBounds = map.getBounds();

for(var i = 0; i < places_json.places.length ; i++) {
      var latlng = new GLatLng(places_json.places[i].lat, places_json.places[i].lon);
      var html = "<strong><a href='/place/" + places_json.places[i].placesidx + "/" + places_json.places[i].area + "'>" + places_json.places[i].area + "</a></strong><br/>" + places_json.places[i].county;
      var hideMarker = true;
      if((initialBounds.getSouthWest().lat() < places_json.places[i].lat) && (places_json.places[i].lat < initialBounds.getNorthEast().lat()) && (initialBounds.getSouthWest().lng() < places_json.places[i].lon) && (places_json.places[i].lon < initialBounds.getNorthEast().lng()) && (places_json.places[i].placesidx != {{ place.placesidx  }})) {
          hideMarker = false;
      }
      var marker = createMarker(latlng, html, hideMarker);
      markers.push(marker);
}

var markerCluster = new MarkerClusterer(map, markers, {maxZoom: 11});

</script>

【问题讨论】:

    标签: javascript google-maps


    【解决方案1】:

    您可能应该在初始阶段使用您的createMarker() 方法创建所有标记,并将返回的GMarker 对象存储在一个数组中。确保在创建标记时在GMarkerOptions 中设置hide: true 属性,以便默认情况下将它们创建为隐藏。

    然后,您可以遍历新的 GMarker 数组,而不是遍历 places_json.places。您可以使用GMarker.getLatLng() 方法获取每个标记的坐标,用于检查每个标记是否在边界内。

    最后,只需调用 GMarker.show() 获取位于边界内的标记,或调用 GMarker.hide() 隐藏它们。

    您将消除每次地图移动时昂贵的标记破坏/创建。作为一个积极的副作用,这也将解决您的GInfoWindow 问题。

    【讨论】:

    • 也许——尽管我总共有 2000 个标记,这就是为什么我一开始就避免这样做。您认为我可以按照您建议的方式进行操作而不会导致浏览器崩溃吗?
    • (我想问这个问题的另一种方式是:如果我在地图上显示 2000 个标记,它肯定会使浏览器崩溃,但如果我在 javascript 中创建 2000 个标记并且只显示其中的 20 或 30 个一次,这会崩溃还是造成性能问题?)
    • 不,应该可以接受 2000 个隐藏标记。最初加载它们需要一些时间,但它应该比在每次鼠标移动时破坏所有标记并重新创建可见标记要平滑得多。 (如果你不破坏你的标记,你最终会导致内存泄漏。)...你可能想查看这篇文章,了解一些带有大量标记的基准:svennerberg.com/2009/01/…
    • 嗯,我更关心初始加载时间,而不是移动地图时的平滑度 - 无论如何,它看起来像我拥有的​​那样平滑,唯一的问题是信息窗口错误。我会尝试您建议的方式,但如果有人有任何其他建议,那就太好了。
    • @Daniel,请看我上面的尝试。这加载正常,但在拖动地图后浏览器崩溃。
    【解决方案2】:

    如果您要使用这么多标记,请确保使用 GMarkerManager。它专为许多标记而设计,一次只能看到几个。

    http://mapki.com/wiki/Marker_Optimization_Tips

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      • 1970-01-01
      相关资源
      最近更新 更多