Amit
Amit

Reputation: 6304

OpenLayers - Fit to current extent is zooming out

Using OpenLayers, I want to set a view of 1 map, to be the same as another. So far I used Zoom and Center, which worked well, but because of a technical impossibility with a certain projection, I tried doing it with an extent.

I am using the latest OpenLayers (4.6.3).

The following code should in theory get my current map's extent, and fit my map to that extent, such that nothing moves.

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

But in practice, if I zoom in enough (for example, 6 clicks on the plus button), and then run the above code, it zooms out every time I run it, which is just not what I want.

I tried constraintResolution, but it minimizes the damage, not removes it entirely.

Here is a fiddle to play with: http://jsfiddle.net/t6uvybd3/1/ (I am not sure what is the ol version there, but it does happen there as well)

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

Upvotes: 2

Views: 7442

Answers (2)

Christian Abella
Christian Abella

Reputation: 5797

I've used the solution of @pavios but have to tweaked it a bit as my scenario is a bit different. I am using a geometry object to fit/center in the map. I've noticed that when the geometry is just a POINT, OL would zoom out too much. But I discovered that the resolution becomes zero when this happens. So, I added a condition before calling setResolution as calling it everytime messes up other condtions when geometry is not a 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);
}

Upvotes: 0

pavlos
pavlos

Reputation: 3081

This is happening because it changes the resolution in order to fit the extent. If you change the size of your map div you will probably not face the problem. In any way , this seems to be a misbehaviour of openlayers but here is a workaround.

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);

Upvotes: 5

Related Questions