OpenLayers - 适合当前范围正在缩小

OpenLayers - Fit to current extent is zooming out

使用 OpenLayers,我想设置一张地图的视图,使其与另一张地图相同。 到目前为止,我使用了 Zoom 和 Center,效果很好,但由于技术上无法实现某种投影,我尝试在一定程度上进行。

我正在使用最新的 OpenLayers (4.6.3)。

理论上,以下代码应该获取我当前地图的范围,并将我的地图调整到该范围,这样就没有任何移动。

let view = map.getView();
let extent = view.calculateExtent(map.getSize());
view.fit(extent, map.getSize());

但实际上,如果我足够放大(例如,在加号按钮上单击 6 次),然后 运行 上面的代码,每次我 运行 它都会缩小,这不是我想要的。

我试过constraintResolution,但它最大限度地减少了损害,并没有完全消除它。

这里有一个 fiddle 可以玩:http://jsfiddle.net/t6uvybd3/1/ (我不确定那里的 ol 版本是什么,但它确实发生在那里)

视频:https://www.youtube.com/watch?v=ZAV_FuZ-p7M&feature=youtu.be

发生这种情况是因为它更改了分辨率以适应范围。如果您更改地图的大小 div,您可能不会遇到这个问题。无论如何,这似乎是 openlayers 的不当行为,但这里有一个解决方法。

var map = new ol.Map({
   target: 'map',
   loadTilesWhileAnimating: true,
   layers: [new ol.layer.Tile({source: new ol.source.OSM()})],
   view: new ol.View({
      center: ol.proj.transform([0, 0], 'EPSG:4326', 'EPSG:3857'),
      zoom: 1
   })
});

var fitExtentAnimated = document.getElementById('fit-extent-animated');
fitExtentAnimated.addEventListener('click', function() {

  let view = map.getView();
  let extent = view.calculateExtent(map.getSize());
  //hold the current resolution
  let res = view.getResolution();
  //if you use older versions of ol3 use `fitExtent` istead of `fit`
  view.fit(extent, map.getSize());
  //apply the resolution back 
  view.setResolution(res);
}, false);

我已经使用了@pavios 的解决方案,但由于我的情况有点不同,所以必须对其进行一些调整。我在地图中使用几何对象 fit/center。我注意到了 当几何只是一个点时,OL 会缩小太多。但我发现 发生这种情况时分辨率变为零。因此,我在调用 setResolution 之前添加了一个条件,因为每次调用它都会在几何不是 POINT 时弄乱其他条件。

let mainFeature: ol.Feature = feature == null ? this.mainFeature : feature;

if (mainFeature != null && this.map != null) {
  // get the current resolution before calling fit 
  // as this will zoom out too much if the geometry is just a POINT
  let res = this.map.getView().getResolution();
  this.map.getView().fit(mainFeature.getGeometry().getExtent(), { constrainResolution: false});

  // set the resolution back to the original resolution if the new resolution
  // after calling fit is equal or less than zero
  let newRes = this.map.getView().getResolution();
  if (newRes <= 0)
    this.map.getView().setResolution(res);
}