时间:2010-07-26 12:23:48

标签: google-maps fitbounds

17 个答案:

答案 0 :(得分:120)

我喜欢mrt的解决方案(特别是当您不知道要映射或调整的点数时),除了它会关闭标记以使其不再位于地图的中心。我只是通过从lat和lng减去.01的额外点来扩展它,因此它将标记保持在中心。工作得很好,谢谢你!

// Pan & Zoom map to show all markers
function fitToMarkers(markers) {

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

    // Create bounds from markers
    for( var index in markers ) {
        var latlng = markers[index].getPosition();
        bounds.extend(latlng);
    }

    // Don't zoom in too far on only one marker
    if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
       var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01);
       var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - 0.01, bounds.getNorthEast().lng() - 0.01);
       bounds.extend(extendPoint1);
       bounds.extend(extendPoint2);
    }

    map.fitBounds(bounds);

    // Adjusting zoom here doesn't work :/

}

答案 1 :(得分:32)

您可以在maxZoom (api-reference) 中使用MapOptions设置地图,如下所示:

var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 });

这样可以防止地图在使用fitBounds()时进一步缩放,甚至可以从缩放控件中删除缩放级别。

答案 2 :(得分:28)

另一个解决方案是在执行fitBounds()之前检测到它们太小而扩展边界:

var bounds = new google.maps.LatLngBounds();
// here you extend your bound as you like
// ...
if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
   var extendPoint = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01);
   bounds.extend(extendPoint);
}
map.fitBounds(bounds);

答案 3 :(得分:18)

var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 });

使用MaxZoom选项最适合不缩放以接近您拥有的标记。

答案 4 :(得分:13)

一旦你添加了所有真实边界,就添加这些行

var offset = 0.002;     
var center = bounds.getCenter();                            
bounds.extend(new google.maps.LatLng(center.lat() + offset, center.lng() + offset));
bounds.extend(new google.maps.LatLng(center.lat() - offset, center.lng() - offset));

它获得真实边界的中心然后在东北部和中心西南部增加两个额外的点

这有效地设置了最小变焦,更改偏移值以增大或减小变焦

答案 5 :(得分:12)

答案 6 :(得分:9)

你可以用

map.setOptions({
    maxZoom: [what u want],
    minZoom: [what u want]
});

这样你就可以在地图初始化之后设置地图的属性....你可以根据需要设置它们多次...但是在你的情况下...你可以在fitBounds()之前设置它们

祝你好运, rarutu

答案 7 :(得分:7)

我阻止地图放大到远的方法是添加以下代码:

var zoomOverride = map.getZoom();
        if(zoomOverride > 15) {
        zoomOverride = 15;
        }
      map.setZoom(zoomOverride);

直接在这一行之后:

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

随意将缩放级别更改为您不希望地图缩放的任何级别。

如果您有任何问题或疑问,请在http://icode4you.net/creating-your-own-store-locator-map-how-to-prevent-the-map-from-zooming-in-too-close-on-a-single-marker

上写一篇关于此事的博客文章。

答案 8 :(得分:5)

我真的很喜欢mrt的解决方案,如果你总是只有一点可以使用它,那就完美了。但我确实发现,如果边界框不是基于一个点,但是点非常接近,这仍然可能导致地图放大太远。

这是首先检查点是否在彼此的定义距离内的方法,然后如果它们小于该最小距离,则将边界扩展到该最小距离:

var bounds = new google.maps.LatLngBounds();
// here you extend your bound as you like

// ...

var minDistance = 0.002;
var sumA = bounds.getNorthEast().lng() - bounds.getSouthWest().lng();
var sumB = bounds.getNorthEast().lat() - bounds.getSouthWest().lat();

if((sumA < minDistance && sumA > -minDistance) 
&& (sumB < minDistance && sumB > -minDistance)){
var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + minDistance, bounds.getNorthEast().lng() + minDistance);
    var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - minDistance, bounds.getNorthEast().lng() - minDistance);
    bounds.extend(extendPoint1);
    bounds.extend(extendPoint2);
}

希望这有助于某人!

答案 9 :(得分:3)

这使您可以直接控制最大允许缩放边界拟合。

var fitToMarkers = function(map, markers, maxZoom) {
    if (typeof maxZoom == 'undefined') maxZoom = 15;

    google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
        if (this.getZoom() > maxZoom) {
            this.setZoom(maxZoom);
        }
    });

    var bounds = new google.maps.LatLngBounds();
    for (var m = 0; m < markers.length; m++) {
        var marker = markers[m];
        var latlng = marker.getPosition();
        bounds.extend(latlng);
    }

    map.fitBounds(bounds);
};

答案 10 :(得分:2)

至于我们,我通过在fitBounds之后创建一个空闲事件来解决它。工作完美。猜猜这是最干净的解决方案之一

var locations = [['loc', lat, lng], ['loc', lat, lng]];
.....
for (i = 0; i < locations.length; i++) { 
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10
  });
  .... create markers, etc.
}
....
map.fitBounds(bounds);  
google.maps.event.addListenerOnce(map, 'idle', function() {
  if (locations.length == 1) {
    map.setZoom(11);
  }
});

答案 11 :(得分:2)

我解决了这个问题,因为谷歌地图V3是事件驱动的:

zoom_changed 事件触发时,您可以告诉API将缩放设置为适当的数量:

var initial = true
google.maps.event.addListener(map, "zoom_changed", function() {
    if (intial == true){
       if (map.getZoom() > 11) {
         map.setZoom(11);
         intial = false;
       }
    }
}); 

我使用 intial 使得地图在最终的fitBounds permorfed时不会过度加载,没有任何超过11的缩放事件对用户来说是不可能的。

答案 12 :(得分:0)

而且......这是另一个 和mrt和Ryan一样,但是

    如果边界大小不完全为零(*),
  • 也可以
  • 防止极点附近的扭曲
  • 使用getCenter()而不是getNorthEast()

(*)注意:如果框已经足够大,那么添加这两个额外的点应该没有效果。所以我们不需要进一步检查。

function calcBounds(markers) {
  // bounds that contain all markers
  var bounds = new google.maps.LatLngBounds();
  // Using an underscore _.each(). Feel free to replace with standard for()
  _.each(markers, function(marker) {
    bounds.extend(marker.getPosition());
  });
  // prevent lat/lng distortion at the poles
  var lng0 = bounds.getNorthEast().lng();
  var lng1 = bounds.getSouthWest().lng();
  if (lng0 * lng1 < 0) {
    // Take the cos at the equator.
    var cos = 1;
  }
  else {
    var cos0 = Math.cos(lng0);
    var cos1 = Math.cos(lng1);
    // Prevent division by zero if the marker is exactly at the pole.
    var cos_safe = Math.max(cos0, cos1, 0.0001);
  }
  var cos0 = Math.cos(bounds.getNorthEast.lng() * Math.PI / 180);
  var cos1 = Math.cos(bounds.getSouthWest.lng() * Math.PI / 180);
  // "radius" in either direction.
  // 0.0006 seems to be an ok value for a typical city.
  // Feel free to make this value a function argument.
  var rLat = 0.0006;
  var rLng = rLat / cos_safe;
  // expand the bounds to a minimum width and height
  var center = bounds.getCenter();
  var p0 = new google.maps.LatLng(center.lat() - rLat, center.lng() - rLng);
  var p1 = new google.maps.LatLng(lat.center() + rLat, center.lng() + rLng);
  bounds.extend(p0);
  bounds.extend(p1);
  return bounds;
}

编辑:考虑到我们有一个墨卡托投影,我不确定我的比率计算是否正确。我可能会重新编辑这个..

答案 13 :(得分:0)

调用 func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { let widthOfCollectionView = collectionView.bounds.width - 40; // For collectionView use "item" instead of "row" if indexPath.item == 6{ return CGSizeMake(widthOfCollectionView,100) }else{ return CGSizeMake(widthOfCollectionView/3, 100) } } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat { return 10; } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat { return 10; } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets{ return UIEdgeInsetsMake(5, 5, 5, 5); } 方法后,尝试再次设置缩放级别。它将强制地图处于该缩放级别,同时在正确的位置居中。

答案 14 :(得分:0)

它已在这里得到答案Google Maps v3: Enforcing min. zoom level when using fitBounds它按预期工作:)所以现在如果在适合范围之后缩放比较少那么就说13然后你可以设置你想要的新缩放

答案 15 :(得分:0)

我根据限制最大变焦来设置边界。适用于我(在Win 7上测试 - IE 9,FF 13,Chrome 19):

// When fitting bounds:
var bounds = new google.maps.LatLngBounds();
// ...
// extend bounds as you like
// ..

// now set global variable when fitting bounds
window.fittingBounds = true;
map.fitBounds(bounds);
window.fittingBounds = false;


// attach this event listener after map init
google.maps.event.addListener(map, 'zoom_changed', function() {
    // set max zoom only when fitting bounds
    if (window.fittingBounds && map.getZoom() > 16) {
        this.setZoom(16);
    }
});

答案 16 :(得分:-1)

这是我的解决方案,当两个标记非常接近时也可以使用。在两种情况下,有效的最大缩放级别都相同。因此,当标记不止一个时,我们不会不必要地缩小图像

该效果再次确保了最大的缩放效果,而没有使用maxZoom选项,这可能导致不必要的效果,使用户无法使用缩放控件将其缩放到maxZoom级别之外

我已经预先计算了maxLat,minLat,maxLng和minLng ...

var minLatSpan = 0.002;
if (maxLat - minLat < minLatSpan) {
  // ensures that we do not zoom in too much
  var delta = (minLatSpan - (maxLat - minLat)) / 2;
  maxLat += delta;
  minLat -= delta;
}

map.fitBounds({
  east: maxLng,
  west: minLng,
  north: maxLat,
  south: minLat,
});