From 948e792ddd286ffccd7a89deaab5feba95d7a29b Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 21 Jun 2012 19:58:35 +0200 Subject: [PATCH] Bounds transforms. --- src/api/bounds.js | 14 ++++++++ src/ol/Bounds.js | 64 +++++++++++++++++++++++++++++++++++++ test/spec/ol/Bounds.test.js | 36 +++++++++++++++++++++ 3 files changed, 114 insertions(+) diff --git a/src/api/bounds.js b/src/api/bounds.js index eb87871275..89bf64de01 100644 --- a/src/api/bounds.js +++ b/src/api/bounds.js @@ -132,3 +132,17 @@ ol.Bounds.prototype.maxY = function(opt_arg){ return this.getMaxY(); } }; + +/** + * Transform this node into another coordinate reference system. Returns a new + * bounds instead of modifying this bounds. + * + * @param {ol.Projection|string} proj Target projection (or string identifier). + * @return {ol.Bounds} A new bounds in the target projection. + */ +ol.Bounds.prototype.transform = function(proj) { + if (goog.isString(proj)) { + proj = new ol.Projection(proj); + } + return this.doTransform(proj); +}; diff --git a/src/ol/Bounds.js b/src/ol/Bounds.js index 396361acb9..36b40e3086 100644 --- a/src/ol/Bounds.js +++ b/src/ol/Bounds.js @@ -1,7 +1,11 @@ goog.provide('ol.Bounds'); + goog.require('ol.UnreferencedBounds'); +goog.require('ol.Loc'); goog.require('ol.Projection'); +goog.require('goog.string.format') + /** * @export * @constructor @@ -39,3 +43,63 @@ ol.Bounds.prototype.setProjection = function(projection) { this.projection_ = projection; }; +/** + * Determine if this bounds intersects the target bounds (bounds that only + * touch are considered intersecting). + * + * @param {ol.Bounds} bounds Target bounds. + * @return {boolean} The provided bounds intersects this bounds. + */ +ol.Bounds.prototype.intersects = function(bounds) { + var otherProj = bounds.getProjection(); + if (!goog.isNull(otherProj) && !goog.isNull(this.projection_)) { + bounds = bounds.transform(this.projection_); + } + return goog.base(this, "intersects", bounds.toUnreferencedBounds()); +}; + +/** + * Transform this node into another coordinate reference system. Returns a new + * bounds instead of modifying this bounds. + * + * @param {ol.Projection} proj Target projection. + * @return {ol.Bounds} A new bounds in the target projection. + */ +ol.Bounds.prototype.doTransform = function(proj) { + if (goog.isNull(this.projection_)) { + throw new Error("Bounds must have a projection before transforming."); + } + var tl = new ol.Loc( + this.minX_, this.maxY_, undefined, this.projection_).transform(proj); + var tr = new ol.Loc( + this.maxX_, this.maxY_, undefined, this.projection_).transform(proj); + var bl = new ol.Loc( + this.minX_, this.minY_, undefined, this.projection_).transform(proj); + var br = new ol.Loc( + this.maxX_, this.minY_, undefined, this.projection_).transform(proj); + + var x = [tl.getX(), tr.getX(), bl.getX(), br.getX()].sort(); + var y = [tl.getY(), tr.getY(), bl.getY(), br.getY()].sort(); + + return new ol.Bounds(x[0], y[0], x[3], y[3], proj); +}; + +/** + * Return a bbox string for this bounds. + * + * @return {string} The "minx,miny,maxx,maxy" representation of this bounds. + */ +ol.Bounds.prototype.toBBOX = function() { + return goog.string.format( + '%f,%f,%f,%f', this.minX_, this.minY_, this.maxX_, this.maxY_); +}; + +/** + * Cast this bounds into an unreferenced bounds. + * + * @returns {ol.UnreferencedBounds} + */ +ol.Bounds.prototype.toUnreferencedBounds = function() { + return new ol.UnreferencedBounds( + this.getMinX(), this.getMinY(), this.getMaxX(), this.getMaxY()); +}; diff --git a/test/spec/ol/Bounds.test.js b/test/spec/ol/Bounds.test.js index 909ff292b8..51b9032a95 100644 --- a/test/spec/ol/Bounds.test.js +++ b/test/spec/ol/Bounds.test.js @@ -29,5 +29,41 @@ describe("ol.Bounds", function() { }); }); + + describe("transforming bounds", function() { + + var gg = new ol.Projection("EPSG:4326"); + var sm = new ol.Projection("EPSG:900913"); + + var bounds = new ol.Bounds(10, -10, 20, 10, gg); + + // approximate bbox array + function bbox(bounds) { + var mult = Math.pow(10, 6); // six figs + return [ + Math.round(bounds.getMinX() * mult) / mult, + Math.round(bounds.getMinY() * mult) / mult, + Math.round(bounds.getMaxX() * mult) / mult, + Math.round(bounds.getMaxY() * mult) / mult + ]; + } + + it("doesn't mind a null transform", function() { + var trans = bounds.transform(new ol.Projection("foo")); + expect(bbox(bounds)).toEqual([10, -10, 20, 10]); + }); + + it("transforms from geographic to spherical mercator", function() { + var trans = bounds.transform(sm); + expect(bbox(trans)).toEqual([1113194.907778, -1118889.974702, 2226389.815556, 1118889.974702]); + }); + + it("transforms from spherical mercator to geographic", function() { + var trans = bounds.transform(sm); + var back = trans.transform(gg); + expect(bbox(back)).toEqual([10, -10, 20, 10]); + }); + + }); });