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.

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .