【问题标题】:Google Maps - zoom to fit markers doesn't work when map isn't visible谷歌地图 - 当地图不可见时,缩放以适应标记不起作用
【发布时间】:2011-01-21 20:19:31
【问题描述】:

我正在使用 Google Maps API v2。我在地图上添加标记,然后缩放以适应这些标记。如果地图可见我这样做很好。但如果不是 - 例如,如果我有一个标签条,并且在页面加载时未选择地图的标签 - 那么当我显示地图时,缩放级别和中心是错误的。

这是一个简单的测试用例(使用 jQuery):

<script type="text/javascript">

    var scale = Math.random() * 20;

    $(document).ready(function() {
        var $container = $('#container');
        // $container.hide();
        var map = new GMap2($('#map')[0]);
        $container.show();
        var markerBounds = new GLatLngBounds();
        for (var i = 0; i < 10; i++) {
            var randomPoint = new GLatLng(38.935394 + (Math.random() - 0.5) * scale, -77.061382 + (Math.random() - 0.5) * scale);
            map.addOverlay(new GMarker(randomPoint));
            markerBounds.extend(randomPoint);
        }
        map.setCenter(markerBounds.getCenter(), map.getBoundsZoomLevel(markerBounds));
    });

</script>

<div id="container">
    <div id="map" style="margin: 100px; width: 450px; height: 300px;"></div>
</div>

这可以正常工作,但如果您取消注释 $container.hide(),它就会全部失效。

有没有办法让 Google Maps API 在不可见的 div 上正常工作?

【问题讨论】:

  • getBounds (在 getBoundsZoomLevel 中调用)返回地图的可见区域,所以我假设您必须缩放以适应标签条的点击事件。 v3中的方法总结优于v2中的描述:v3"返回当前视口的lat/lng边界。如果地图还没有初始化(即mapType仍然为null),或者center和zoom还没有已设置,则结果为空。”我认为 getBounds 在版本之间没有太大变化。

标签: google-maps google-maps-markers google-maps-api-2


【解决方案1】:

这就是我最终所做的,物有所值。

            $(".TabPanel").watch("display,visibility", function() {
                $(".MapContainer", this).each(function() {
                    if ($(this).is(":visible") == true) {
                        $(this).zoomToFitMarkers();
                    };
                });
            });

这使用Rick Strahl's monitoring plugin for jQuery 来观察选项卡面板的可见性变化,然后重新应用缩放逻辑。

为了完整起见,这是我的zoomToFitMarkers 分机:

$.fn.zoomToFitMarkers = function() {
    var map = this[0];
    map.gmap.checkResize();
    map.bounds = new GLatLngBounds();
    if (!!map.gmap.getOverlays) {
        for (i = 0; i < map.gmap.getOverlays.length; i++) {
            map.bounds.extend(map.gmap.getOverlays[i].getLatLng());
        }
        if (map.bounds && !map.bounds.isEmpty()) {
            var zoomLevel = map.gmap.getBoundsZoomLevel(map.bounds);
            zoomLevel = zoomLevel > 9 ? 9 : zoomLevel;
            zoomLevel = zoomLevel < 2 ? 2 : zoomLevel;
            map.gmap.setCenter(map.bounds.getCenter(), zoomLevel);
        }
    }
    map.gmap.checkResize();
};

这依赖于几个约定:

  1. GMap2 对象存储在map.gmap 中,其中map 是目标DOM 元素:

    var map= $("div#MapTarget")[0];
    map.gmap = new google.maps.Map2(map);
    
  2. 每次将标记添加到地图时,它都会存储在一个数组中以供将来使用:

    var marker = new GMarker(point);
    map.gmap.addOverlay(marker);
    // Keep track of new marker in getOverlays array
    if (!map.gmap.getOverlays) map.gmap.getOverlays = new Array();
    map.gmap.getOverlays.push(marker);
    

【讨论】:

    【解决方案2】:

    您需要做的就是先创建GMaps2()。然后您可以hide() 容器,添加点,再次获取getBoundsZoomLevel()show(),它应该可以正常工作。

    尝试以下方法:

    $(document).ready(function() {
       var $container = $('#container');
    
       // First create the Map.
       var map = new GMap2($('#map')[0]);
    
       // The container can be hidden immediately afterwards.
       $container.hide();
    
       // Now you can do whatever you like!
       var markerBounds = new GLatLngBounds();
       for (var i = 0; i < 10; i++) {
          var randomPoint = new GLatLng( 38.935394 + (Math.random() - 0.5) * scale, 
                                        -77.061382 + (Math.random() - 0.5) * scale);
          map.addOverlay(new GMarker(randomPoint));
          markerBounds.extend(randomPoint);
       }
       map.setCenter(markerBounds.getCenter(), map.getBoundsZoomLevel(markerBounds));
    
       // Finally unhide the container.
       $container.show();
    });
    

    【讨论】:

    • 你是对的,这确实有效。不过,我的标签条的工作方式是加载时隐藏所有内容(使用 CSS),然后显示正确的标签。否则会有一个短暂的时间段,所有选项卡都可见。因此,如果可能的话,我想找到一种方法在 div 上创建 GMap2,同时它仍然隐藏。
    • @Herb:不幸的是,在映射 div 设置为 display: none 的情况下,GMap2 似乎没有正确创建。如果你在谷歌上搜索“getBoundsZoomLevel 返回 0”,你会发现一些相关的故事。我认为你最好的办法是解决这个问题,通过调整你的标签的工作方式......我不知道这是否有帮助,但如果你用$container.css('visibility', 'hidden');隐藏地图,你可以打电话给GMap2()当您使用$container.css('visibility', 'visible'); 恢复可见性时,它会正常工作。
    • 谢谢。这很有帮助。 display:nonevisibility:hidden 的区别很有趣——这不是我以前真正理解的。使用可见性属性隐藏选项卡是行不通的,因为带有visibility:hidden 的项目仍会占用页面空间。
    猜你喜欢
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 2012-12-13
    • 2023-03-21
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 2014-05-23
    相关资源
    最近更新 更多