2

In my web app I have a search side bar which can return results as either a bounding box, or an X and Y coordinate with a zoom level. The sidebar pops out the side of the screen and partially overlays the map, so I want the results centred on this slightly offset map. I can do this no problem when a bounding box is supplied to the search results, as I can simply use the padding FitOption like so

//leftPadding is a pixel value equal to the width of the sidebar
//result.bbox is an Openlayers Extent
olMap.getView().fit(result.bbox, { padding: [100, 100, 100, leftPadding] });

However, I cannot (to my knowledge) use .fit() with a coordinate and a zoom level.

This is how I zoom to a point at the moment (uses animation but doesn't have to)

olMap.getView().animate({
        duration: 1000,
        center: convertedCoord,
        zoom:result.zoom
    })

result.zoom is an integer indicating zoom level to zoom to

convertedCoord is an Openlayers Coordinate

I could use setView() like this

let view = new View({
    center: convertedCoord,
    padding: [100, 100, 100, leftPadding],
    zoom: result.zoom
});
olMap.setView(view);

However, this shifts the actual view of the map, so rotating now rotates around that point, and when I close the sidebar I would need to reset the padding every time.

What I ideally want is some way is to setCenter() with padding, but I can't seem to find a way to do that. Ideally I would want the animation to still work, but if it can't so be it.

I feel there is a possibility of using coordinate.add() to move the center point, but I can't quite figure out how to determine the delta required to move it to get the same padding.

3
  • 1
    Resolution is your answer, since it's map units per pixel. If you need offset of 100 pixels, just add map.getView().getResolution() * 100 to your coordinates.
    – TomazicM
    May 10, 2021 at 15:12
  • 1
    The bbox of a single coordinate is coordinate.concat(coordinate) or you could fit using a geometry new Point(coordinate). Note that a point is infinitely small so you will zoom the the maximum view zoom unless you specify maxZoom or minResolution as a fit option.
    – Mike
    May 10, 2021 at 16:27
  • @Mike that's an elegant solution and works nicely. I ended up creating a new Point and then calling fit() with the maxZoom option, like so: olMap.getView().fit(point, { padding: [100, 100, 100, leftPadding], maxZoom:result.zoom, duration:animationSpeed }); and it works perfectly. Feel free to put that as an answer and I'll accept it, otherwise I'll self answer it myself May 11, 2021 at 8:41

1 Answer 1

2

Mike in the comments came up with an elegant solution that I ended up using. Simply use .getView().fit() with an OpenLayers Point and set a maxZoom in the options, like so.

let point = new Point(coords);
olMap.getView().fit(point, { 
    padding: [100, 100, 100, leftPadding], 
    maxZoom:result.zoom, 
    duration:animationSpeed 
});

Which works perfectly and allows me to continue using the animation speed.

Your Answer

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

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