diff --git a/src/ol/view2d.exports b/src/ol/view2d.exports index 8953445dd7..01d44dd7b5 100644 --- a/src/ol/view2d.exports +++ b/src/ol/view2d.exports @@ -4,6 +4,7 @@ @exportProperty ol.View2D.prototype.constrainRotation @exportProperty ol.View2D.prototype.fitExtent @exportProperty ol.View2D.prototype.fitGeometry +@exportProperty ol.View2D.prototype.centerOn @exportProperty ol.View2D.prototype.getView2D @exportProperty ol.View2D.prototype.getZoom @exportProperty ol.View2D.prototype.setZoom diff --git a/src/ol/view2d.js b/src/ol/view2d.js index 3c800d3b61..0276506464 100644 --- a/src/ol/view2d.js +++ b/src/ol/view2d.js @@ -497,6 +497,34 @@ ol.View2D.prototype.fitGeometry = function(geometry, size, opt_options) { }; +/** + * Center on coordinate and view position. + * Take care on the map angle. + * @param {ol.Coordinate} coordinate Coordinate. + * @param {ol.Size} size Box pixel size. + * @param {ol.Pixel} position Position on the view to center on. + * @todo stability experimental + */ +ol.View2D.prototype.centerOn = function(coordinate, size, position) { + // calculate rotated position + var rotation = this.getRotation(); + var cosAngle = Math.cos(-rotation); + var sinAngle = Math.sin(-rotation); + var rotX = coordinate[0] * cosAngle - coordinate[1] * sinAngle; + var rotY = coordinate[1] * cosAngle + coordinate[0] * sinAngle; + var resolution = this.getResolution(); + rotX += (size[0] / 2 - position[0]) * resolution; + rotY += (position[1] - size[1] / 2) * resolution; + + // go back to original angle + sinAngle = -sinAngle; // go back to original rotation + var centerX = rotX * cosAngle - rotY * sinAngle; + var centerY = rotY * cosAngle + rotX * sinAngle; + + this.setCenter([centerX, centerY]); +}; + + /** * @return {boolean} Is defined. */ diff --git a/test/spec/ol/view2d.test.js b/test/spec/ol/view2d.test.js index 48693ccc62..0e51e0d3ac 100644 --- a/test/spec/ol/view2d.test.js +++ b/test/spec/ol/view2d.test.js @@ -172,6 +172,34 @@ describe('ol.View2D', function() { expect(view.getCenter()[1]).to.be(46300); }); }); + + describe('centerOn', function() { + var view; + beforeEach(function() { + view = new ol.View2D({ + resolutions: [200, 100, 50, 20, 10, 5, 2, 1] + }); + }); + it('fit correctly to the coordinates', function() { + view.setResolution(10); + view.centerOn( + [6000, 46000], + [400, 400], + [300, 300] + ); + expect(view.getCenter()[0]).to.be(5000); + expect(view.getCenter()[1]).to.be(47000); + + view.setRotation(Math.PI / 4); + view.centerOn( + [6000, 46000], + [400, 400], + [300, 300] + ); + expect(view.getCenter()[0]).to.be(4585.78643762691); + expect(view.getCenter()[1]).to.be(46000); + }); + }); }); goog.require('ol.View2D');