leaflet 中fitBounds去掉动画

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leaflet 中fitBounds去掉动画相关的知识,希望对你有一定的参考价值。

参考技术A setview方法。
这个方法用leaflet的同学都用过,可当没有图层的时候添加一个图层用这个方法定位就会出现不能再缩小的问题,第一个图层建议用setview方法,这样不会增加特殊属性minzoom。
javascript,在地图上进行操作(坐标点,路径,曲线等)的一个库,只提供操作地图API,实际加载某个地图,由开发者决定创建地图对象。

谷歌地图 API 3 缩小 fitBounds

【中文标题】谷歌地图 API 3 缩小 fitBounds【英文标题】:google maps API 3 zooms out on fitBounds 【发布时间】:2011-12-31 11:38:45 【问题描述】:

我遇到了调用 map.fitBounds 似乎缩小的问题。我正在尝试使用backbone.js 路由器将地图边界保存在url 中。我希望能够为网址添加书签,然后让地图看起来完全一样。

我注意到在控制台中调用map.fitBounds(map.getBounds()) 总是会缩小。我希望它不改变地图。

这是正常行为吗?如何强制执行此操作,以便地图从一个步骤到另一个步骤看起来都一样?

谢谢

【问题讨论】:

***.com/a/51270624/434697 为我工作。 【参考方案1】:

Google Map API 的这个问题已经讨论过几次了。见:

gmaps-api-issues google-maps-js-api-v3 group

函数map.fitBounds() 设置视口以包含边界。但是map.getBounds() 函数返回带有一些额外边距的视口边界(请注意,这是正常行为,没有错误)。放大的边界不再适合之前的视口,因此地图会缩小。

解决您的问题的一个简单方法是改用地图中心和缩放级别。查看函数map.getCenter()map.setCenter()map.getZoom()map.setZoom()

【讨论】:

我花了超过 16 个小时才到达这里。即使这不是错误,也应该为那些尝试这样做的人提供一些解决方法。【参考方案2】:

对于在 2018 年看到此问题的人,Google Maps API v3 现在支持第二个 padding 参数,该参数指定要包含在您指定的边界周围的填充量。

为避免缩小,只需调用fitBounds 并填充0。对于此示例,它将是 map.fitBounds(map.getBounds(), 0)

【讨论】:

【参考方案3】:

在 2017 年解决这个问题

在发送到map.fitBounds()之前稍微缩小边界框。

这是一个缩小边界框的函数:

// Values between 0.08 and 0.28 seem to work
// Any lower and the map will zoom out too much
// Any higher and it will zoom in too much
var BOUNDS_SHRINK_PERCENTAGE = 0.08; // 8%

/**
 * @param  google.maps.LatLngLiteral southwest
 * @param  google.maps.LatLngLiteral northeast
 * @return Array[google.maps.LatLngLiteral]
 */
function slightlySmallerBounds(southwest, northeast) 
  function adjustmentAmount(value1, value2) 
    return Math.abs(value1 - value2) * BOUNDS_SHRINK_PERCENTAGE;
  

  var latAdjustment = adjustmentAmount(northeast.lat, southwest.lat);
  var lngAdjustment = adjustmentAmount(northeast.lng, southwest.lng);

  return [
    lat: southwest.lat + latAdjustment, lng: southwest.lng + lngAdjustment,
    lat: northeast.lat - latAdjustment, lng: northeast.lng - lngAdjustment
  ]

像这样使用它:

// Ensure `southwest` and `northwest` are objects in google.maps.LatLngLiteral form:
// southwest == lat: 32.79712, lng: -117.13931
// northwest == lat: 32.85020, lng: -117.09356

var shrunkBounds = slightlySmallerBounds(southwest, northeast);
var newSouthwest = shrunkBounds[0];
var newNortheast = shrunkBounds[1];

// `map` is a `google.maps.Map`
map.fitBounds(
  new google.maps.LatLngBounds(newSouthwest, newNortheast)
);

我有一个应用程序与codr 做同样的事情:将当前地图边界保存在 URL 中,并在刷新时从 URL 边界初始化地图。这个解决方案非常适合。

为什么会这样?

当调用fitBounds() 时,Google 地图基本上会执行此操作:

    以给定边界框的中心点居中地图。 放大到视口将包含给定边界inside视口框的最高缩放级别。

如果给定的边界完全与视口匹配,Google 地图不会将其视为“包含”边界,因此会再缩小一层。

【讨论】:

【参考方案4】:

在初始化名为map.fitBounds(...) 的地图后,我遇到了同样的问题。我遇到的行为是,如果在地图初始化后几秒钟调用 fitBounds 方法,那么没有问题(缩放是合适的)。 所以首先我在地图加载后开始调用fitBounds 方法,在谷歌地图上转换为地图为idle 时。

google.maps.event.addListener(map, 'idle', function() 
   var bounds = //define bounds...
   map.fitBounds(bounds);
);

这确实有效,但是idle 事件几乎不断被触发。如果地图有任何变化(拖动、缩放等),当这种变化停止时,地图将再次适应边界...... 问题是,只调用一次方法 not 工作(使用布尔值检查是否已被调用,或者使用google.maps.event.addListenerOnce,因为地图第一次空闲时它仍然“不是准备好”以适应边界。(根据经验)。

所以我的解决方案是在不同的事件上触发fitBounds。而不是idlefitBounds 方法调用太早,事件tilesloaded 实际上完成了工作(只调用一次)!

解决方案:

google.maps.event.addListenerOnce(map, 'tilesloaded', function() 
   var bounds = //define bounds...
   map.fitBounds(bounds);
);

【讨论】:

【参考方案5】:

我在隐藏地图视图上使用fitBounds() 时注意到了这种行为(使用前端渲染框架,如 Angular)。因为这是一个移动视图,所以我首先显示一个位置列表,并在加载列表时填充隐藏地图上的标记(并发加载)。因此,当用户想要查看地图并切换分段视图/选项卡/任何内容时,地图将显示已加载并在视图中的标记。但是这个问题出现了并放大以在地图中显示完整的世界。

<div [hidden]="view !== 'map'>
    <google-map></google-map>
</div>

fitBounds() 需要将地图加载到视图中,因为它使用地图尺寸来调整地图大小。如果地图被隐藏,它会缩放地图,直到显示完整的地图。

解决方法很简单:切换视图后,再次调用fitBounds()

<button (click)="showMap()">Show Map</button>

public showMap() 
    this.view = 'map';
    setTimeout(() => 
        if (typeof this.map !== 'undefined') this.map.fitBounds(this.bounds);
    );

注意:我在 fitBounds() 调用周围包裹了一个 setTimeout,以便 Angular 可以在调用之前完成生命周期并渲染地图。

【讨论】:

+1 遇到了这个确切的场景,这是对我有用的修复程序。我注意到,在我的情况下,我只使用了 setTimeout 并等待了 500 毫秒,因为 this.map 已经在我的页面上定义了。该问题仅在执行show()hide(),然后再次执行show() 时发生。半秒的延迟足以让地图内的一切都重置。 我在 Django 站点上使用隐藏地图,这就是问题所在。我发现在fitBounds() 正常工作之前,地图必须是字面上可见的。谢谢。【参考方案6】:

我也注意到了这个问题。我的解决方案是将map.getBounds() 与我设置的界限进行比较;如果它们相同,我将跳过map.fitBounds() 调用。

【讨论】:

【参考方案7】:

我遇到了同样的问题,@Tomik 的回答帮助我解决了这个问题。这是我使用的代码的sn-ps。

保存之前的缩放和居中。

const lastMapZoom = this.map.getZoom();
const lastMapCenter = this.map.getCenter();

重新设置值。

this.map.setCenter(lastMapCenter);
this.map.setZoom(lastMapZoom);

【讨论】:

以上是关于leaflet 中fitBounds去掉动画的主要内容,如果未能解决你的问题,请参考以下文章

传单 - Fitbounds 并保持居中

从外部访问 Leaflet.js GeoJson 功能

如何影响 map.fitBounds() 的“宽限”

如何影响 map.fitBounds() 的“宽限”

谷歌地图 API 3 缩小 fitBounds

在 Openstreet 地图上移动标记 - Leaflet API