3

I'm trying to select a feature first and then start the zoom animation but openlayers (v6) first start the zoom animation and when it's done the feature gets selected, what's going on here?

Here is my code:

function zoom(){
    selectSingleClick.getFeatures().push(featToZoom);

    var vectorSource = new ol.source.Vector();
    vectorSource.addFeature(featToZoom);

    map.getView().fit(vectorSource.getExtent(), {
            duration: 5000
    });
}

2 Answers 2

3

I found working solution by using setTimeout for zoom, but I didn't try to find reasons why it works. OpenLayers is a bit too complicated for my taste.

function zoom() {
  var vectorSource = new ol.source.Vector();
  vectorSource.addFeature(featToZoom);

  map.getView().fit(vectorSource.getExtent(), {
    duration: 5000
  });
}

function selectAndZoom(){
  selectSingleClick.getFeatures().push(featToZoom);
  setTimeout(zoom, 50);
}
2
  • Thank you very much again TomazicM. I had some initial difficulties but I feel more and more comfortable with OL.
    – BR75
    Dec 4, 2019 at 18:02
  • I will try it eventually, but at the moment, while learning GIS essentials, I'll stick to Leaflet.
    – TomazicM
    Dec 4, 2019 at 18:07
2

When you push a feature as following:

selectSingleClick.getFeatures().push(featToZoom);

OpenLayers generates internal event CollectionEventType.ADD (link to source code) and then highlights the feature. But, handler of event CollectionEventType.ADD doesn't run immediately. JavaScript engine has a single thread, forcing asynchronous events to queue waiting for execution (see How JavaScript Timers Work by John Resig). But map.getView().fit run here immediately.

If we add setTimeout() then we move our map.getView().fit in the end of the queue. Then highlighting will be first, but zooming will be second:

function fitByFeature(feature){
    map.getView().fit(feature.getGeometry().getExtent(), {
        duration: 5000
    });
}

function selectFeatureAndFit(feature) {
    selectSingleClick.getFeatures().push(feature);

    setTimeout(function () {
        fitByFeature(feature);
    });
}

// Get my feature from layer
var feature = vectorLayer.getSource().getFeatures()[0];
selectFeatureAndFit(feature);

In addition, instead using a temporary ol.source.Vector:

var vectorSource = new ol.source.Vector();
vectorSource.addFeature(featToZoom);
vectorSource.getExtent()

you could try to get an extent more easily:

feature.getGeometry().getExtent()

Working example here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.