代码之家  ›  专栏  ›  技术社区  ›  chris

Google地图API v3:我可以在fitBounds之后设置zoom吗?

  •  193
  • chris  · 技术社区  · 16 年前

    我有一组点,我想在一个嵌入式谷歌地图(API v3)绘图。我想边界,以适应所有的点,除非缩放水平太低(即,缩小太多)。我的方法是这样的:

    var bounds = new google.maps.LatLngBounds();
    
    // extend bounds with each point
    
    gmap.fitBounds(bounds); 
    gmap.setZoom( Math.max(6, gmap.getZoom()) );
    

    这不管用。最后一行“gmap.setZoom()”如果直接在fitBounds之后调用,则不会更改地图的缩放级别。

    有没有一种方法可以在不应用于地图的情况下获得边界的缩放级别?还有其他解决办法吗?

    23 回复  |  直到 12 年前
        1
  •  363
  •   LGT    12 年前

    编辑

    知道了!试试这个:

    map.fitBounds(bounds);
    var listener = google.maps.event.addListener(map, "idle", function() { 
      if (map.getZoom() > 16) map.setZoom(16); 
      google.maps.event.removeListener(listener); 
    });
    

        2
  •  76
  •   bkaid    12 年前

    在我的应用程序中,我想绘制一个或多个标记,并确保地图显示了所有这些标记。问题是,如果我仅仅依赖fitBounds方法,那么当只有一个点时,缩放级别将达到最大值-这是不好的。

    解决方案是当有多个点时使用fitBounds,当只有一个点时使用setCenter+setZoom。

    if (pointCount > 1) {
      map.fitBounds(mapBounds);
    }
    else if (pointCount == 1) {
      map.setCenter(mapBounds.getCenter());
      map.setZoom(14);
    }
    
        3
  •  46
  •   Tomas    13 年前

    我多次来到这个页面来得到答案,虽然所有现有的答案都非常有用,但它们并没有完全解决我的问题。

    google.maps.event.addListenerOnce(googleMap, 'zoom_changed', function() {
        var oldZoom = googleMap.getZoom();
        googleMap.setZoom(oldZoom - 1); //Or whatever
    });
    

    基本上,我发现“zoom\u changed”事件阻止了地图的UI“跳过”,这是在我等待“idle”事件时发生的。

    希望这能帮上忙!

        4
  •  10
  •   Robin Whittleton    12 年前

    我只是通过预先设置maxZoom来解决这个问题,然后再删除它。例如:

    map.setOptions({ maxZoom: 15 });
    map.fitBounds(bounds);
    map.setOptions({ maxZoom: null });
    
        5
  •  5
  •   nass600 Atif Tariq    9 年前

    map.fitBounds(bounds);
    
    // CHANGE ZOOM LEVEL AFTER FITBOUNDS
    zoomChangeBoundsListener = google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
      if (this.getZoom()){
        this.setZoom(15);
      }
    });
    setTimeout(function(){
      google.maps.event.removeListener(zoomChangeBoundsListener)
    }, 2000);
    
        6
  •  4
  •   Preview 2pha    10 年前

    如果我没弄错的话,我假设你希望你的所有点都能在地图上以尽可能高的缩放级别显示出来。我通过将地图的缩放级别初始化为 (不确定是否是V3上可能的最高缩放级别)。

    var map = new google.maps.Map(document.getElementById('map_canvas'), {
      zoom: 16,
      center: marker_point,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
    

    var bounds = new google.maps.LatLngBounds();
    
    // You can have a loop here of all you marker points
    // Begin loop
    bounds.extend(marker_point);
    // End loop
    
    map.fitBounds(bounds);
    

    结果: 成功!

        7
  •  3
  •   ytg    16 年前

    我使用:

    gmap.setZoom(24); //this looks a high enough zoom value
    gmap.fitBounds(bounds); //now the fitBounds should make the zoom value only less
    

        8
  •  3
  •   Svilen Marchev    9 年前

    .

    原因是什么 setZoom() 不像你想的那样管用是吗 fitBounds() 是异步的,因此不能保证它会立即更新缩放,但是 设置缩放()

    minZoom 调用前映射选项 然后在完成后将其清除(这样用户仍然可以手动缩小):

    var bounds = new google.maps.LatLngBounds();
    // ... (extend bounds with all points you want to fit)
    
    // Ensure the map does not get too zoomed out when fitting the bounds.
    gmap.setOptions({minZoom: 6});
    // Clear the minZoom only after the map fits the bounds (note that
    // fitBounds() is asynchronous). The 'idle' event fires when the map
    // becomes idle after panning or zooming.
    google.maps.event.addListenerOnce(gmap, 'idle', function() {
      gmap.setOptions({minZoom: null});
    });
    
    gmap.fitBounds(bounds);
    

    maxZoom 财产。

    看到了吗 MapOptions docs .

        9
  •  2
  •   9monkeys    14 年前

    我有同样的问题,我能够解决它使用以下代码。此侦听器( google.maps.addListenerOnce() )事件只会被炒一次,就在之后 map.fitBounds() 已执行。所以,没有必要

    1. 等地图出来再说 idle .

    它最初设置适当的缩放级别,并允许用户在超过初始缩放级别时进行放大和缩小,因为事件侦听器已过期。例如,如果 google.maps.addListener() 则用户将 从未 ,用户将能够缩放到他/她选择的任何级别。

    map.fitBounds(bounds);
    
    var zoom_level_for_one_marker = 4;
    
    google.maps.event.addListenerOnce(map, 'bounds_changed', function(event){
       if (this.getZoom() >= zoom_level_for_one_marker){  
           this.setZoom(zoom_level_for_one_marker) 
       }
    });
    
        10
  •  2
  •   Adi Lester    13 年前

    有同样的问题,需要在地图上匹配许多标记。 这解决了我的问题:

    1. koderoid提供的使用方案(针对每个标记集) bounds.extend(objLatLng) )
    2. google.maps.event.addListenerOnce(map, 'idle', function() { 
          map.fitBounds( bounds );
      });
      
        11
  •  2
  •   CheapSteaks    13 年前

    我找到了一个解决方案,在打电话之前先检查一下 fitBounds 所以你不会放大然后突然缩小

    var bounds = new google.maps.LatLngBounds();
    
    // extend bounds with each point
    
    var minLatSpan = 0.001;
    if (bounds.toSpan().lat() > minLatSpan) {
        gmap.fitBounds(bounds); 
    } else {
        gmap.setCenter(bounds.getCenter());
        gmap.setZoom(16);
    }
    

    您必须对minLatSpan变量进行一些处理,才能将其放在所需的位置。它将根据缩放级别和地图画布的尺寸而变化。

        12
  •  1
  •   Mantis    16 年前

    我使用它来确保缩放级别不超过设置的级别,这样我就知道卫星图像将可用。

    zoom_changed 事件。 这还有一个额外的好处,就是可以控制UI上的缩放控件。

    只执行 setZoom if 声明比 Math.max 或者 Math.min

       google.maps.event.addListener(map, 'zoom_changed', function() { 
          if ( map.getZoom() > 19 ) { 
            map.setZoom(19); 
          } 
        });
        bounds = new google.maps.LatLngBounds( ... your bounds ... )
        map.fitBounds(bounds);
    

    为防止放大过远:

       google.maps.event.addListener(map, 'zoom_changed', function() { 
          if ( map.getZoom() < 6 ) { 
            map.setZoom(6); 
          } 
        });
        bounds = new google.maps.LatLngBounds( ... your bounds ... )
        map.fitBounds(bounds);
    
        13
  •  1
  •   CrazyEnigma    16 年前

    “fitGeometries”是一个扩展map对象的JSON函数。

    “geometries”是一个通用javascript数组,而不是MVCArray()。

    geometry.metadata = { type: "point" };
    var geometries = [geometry];
    
    fitGeometries: function (geometries) {
        // go and determine the latLngBounds...
        var bounds = new google.maps.LatLngBounds();
        for (var i = 0; i < geometries.length; i++) {
            var geometry = geometries[i];
            switch (geometry.metadata.type)
            {
                case "point":
                    var point = geometry.getPosition();
                    bounds.extend(point);
                    break;
                case "polyline":
                case "polygon": // Will only get first path
                    var path = geometry.getPath();
                    for (var j = 0; j < path.getLength(); j++) {
                        var point = path.getAt(j);
                        bounds.extend(point);
                    }
                    break;
            }
        }
        this.getMap().fitBounds(bounds);
    },
    
        14
  •  1
  •   Pedro Blaszczak    13 年前

    var bounds = new google.maps.LatLngBounds();
    // extend bounds with each point
    
    gmap.setCenter(bounds.getCenter()); 
    gmap.setZoom( 6 );
    
        15
  •  1
  •   Kanak Singhal    10 年前

    和我一样,如果你不愿意和听众一起玩,我提出了一个简单的解决方案: 在地图上添加一个严格按照您的要求工作的方法,例如:

        map.fitLmtdBounds = function(bounds, min, max){
            if(bounds.isEmpty()) return;
            if(typeof min == "undefined") min = 5;
            if(typeof max == "undefined") max = 15;
    
            var tMin = this.minZoom, tMax = this.maxZoom;
            this.setOptions({minZoom:min, maxZoom:max});
            this.fitBounds(bounds);
            this.setOptions({minZoom:tMin, maxZoom:tMax});
        }
    

    map.fitLmtdBounds(bounds) map.fitBounds(bounds) 要在定义的缩放范围下设置边界。。。或 map.fitLmtdBounds(bounds,3,5) 覆盖缩放范围。。

        16
  •  0
  •   Kanak Vaghela    16 年前

    // Find out what the map's zoom level is
    zoom = map.getZoom();
    if (zoom == 1) {
      // If the zoom level is that low, means it's looking around the
    world.
      // Swap the sw and ne coords
      viewportBounds = new
    google.maps.LatLngBounds(results[0].geometry.location, initialLatLng);
      map.fitBounds(viewportBounds);
    }
    

    祝你一切顺利

        17
  •  0
  •   Orhun Alp Oral    16 年前

    计算边界后,可以检查左上角和右下角之间的距离;然后您可以通过测试距离来了解缩放级别(如果距离太远,缩放级别将很低),然后您可以使用setbound方法或setZoom选择wheter。。

        18
  •  0
  •   Joseph Earl    16 年前

    必须 尝试-第一个呼叫

    gmap.fitBounds(bounds);

    然后创建一个新的Thread/AsyncTask,让它休眠20-50ms左右,然后调用

    gmap.setZoom( Math.max(6, gmap.getZoom()) );

    onPostExecute 异步任务的方法)。

    我不知道是否有效,只是一个建议。除此之外,你还得自己根据你的点来计算缩放级别,检查它是否太低,纠正它,然后打电话 gmap.setZoom(correctedZoom)

        19
  •  0
  •   tempranova    10 年前

    每次调用fitBounds()时,都会触发“center\u changed”事件,尽管它会立即运行,而不一定在映射移动之后运行。

    在正常情况下,“idle”仍然是最好的事件侦听器,但这可能会帮助一些人在fitBounds()调用中遇到奇怪的问题。

    看到了吗 google maps fitBounds callback

        20
  •  0
  •   philh user2407038    8 年前

    为了配合另一个解决方案,我发现“侦听更改的事件,然后设置新的缩放”方法对我来说不可靠。我想我有时会打电话 fitBounds 在映射被完全初始化之前,以及初始化导致一个将耗尽侦听器的buunds\u changed事件之前 更改了边界和缩放级别。我最终得到了这样一个代码,到目前为止似乎是可行的:

    // If there's only one marker, or if the markers are all super close together,
    // `fitBounds` can zoom in too far. We want to limit the maximum zoom it can
    // use.
    //
    // `fitBounds` is asynchronous, so we need to wait until the bounds have
    // changed before we know what the new zoom is, using an event handler.
    //
    // Sometimes this handler gets triggered by a different event, before
    // `fitBounds` takes effect; that particularly seems to happen if the map
    // hasn't been fully initialized yet. So we don't immediately remove the
    // listener; instead, we wait until the 'idle' event, and remove it then.
    //
    // But 'idle' might happen before 'bounds_changed', so we can't set up the
    // removal handler immediately. Set it up in the first event handler.
    
    var removeListener = null;
    var listener = google.maps.event.addListener(map, 'bounds_changed', () => {
      console.log(map.getZoom());
      if (map.getZoom() > 15) {
        map.setZoom(15);
      }
    
      if (!removeListener) {
        removeListener = google.maps.event.addListenerOnce(map, 'idle', () => {
          console.log('remove');
          google.maps.event.removeListener(listener);
        });
      }
    });
    
        21
  •  0
  •   horace    8 年前

    对我来说,最简单的解决办法是:

    map.fitBounds(bounds);
    
    function set_zoom() {
        if(map.getZoom()) {map.setZoom(map.getZoom() - 1);}
        else {setTimeout(set_zoom, 5);}
    }
    setTimeout(set_zoom, 5);
    
        22
  •  -1
  •   Mörre    12 年前
    google.maps.event.addListener(marker, 'dblclick', function () {
        var oldZoom = map.getZoom(); 
        map.setCenter(this.getPosition());
        map.setZoom(parseInt(oldZoom) + 1);
    });
    
        23
  •  -3
  •   Petr Svoboda    16 年前

    map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
    

    推荐文章