From eeba5a34c685a6df5745679ad93adc46677fd837 Mon Sep 17 00:00:00 2001 From: euzuro Date: Thu, 18 May 2006 12:48:52 +0000 Subject: [PATCH] Changed OpenLayers.Bounds to use left, bottom, right, top INSTEAD OF minlon, minlat, maxlon, maxlat. Removed OpenLayers.Box which was not getting used. JSDOC/coding standard-ified the OpenLayers.Bounds code and wrote thorough testing for it. Should be all good. git-svn-id: http://svn.openlayers.org/trunk/openlayers@140 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- lib/OpenLayers/Layer/Grid.js | 36 ++-- lib/OpenLayers/Layer/Marker.js | 4 +- lib/OpenLayers/Map.js | 6 +- lib/OpenLayers/Util.js | 318 +++++++++++++++++---------------- tests/test_Bounds.html | 126 +++++++++---- tests/test_Tile.html | 8 +- tests/test_Tile_Image.html | 8 +- 7 files changed, 293 insertions(+), 213 deletions(-) diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 5eae35affe..0b8e347551 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -43,16 +43,16 @@ OpenLayers.Layer.Grid.prototype = Object.extend( new OpenLayers.Layer(), { this._initTiles(); } else { var i = 0; - while (this.getGridBounds().minlat > bounds.minlat) { + while (this.getGridBounds().bottom > bounds.bottom) { this.insertRow(false); } - while (this.getGridBounds().minlon > bounds.minlon) { + while (this.getGridBounds().left > bounds.left) { this.insertColumn(true); } - while (this.getGridBounds().maxlat < bounds.maxlat) { + while (this.getGridBounds().top < bounds.top) { this.insertRow(true); } - while (this.getGridBounds().maxlon < bounds.maxlon) { + while (this.getGridBounds().right < bounds.right) { this.insertColumn(false); } } @@ -60,10 +60,10 @@ OpenLayers.Layer.Grid.prototype = Object.extend( new OpenLayers.Layer(), { getGridBounds:function() { var topLeftTile = this.grid[0][0]; var bottomRightTile = this.grid[this.grid.length-1][this.grid[0].length-1]; - return new OpenLayers.Bounds(topLeftTile.bounds.minlon, - bottomRightTile.bounds.minlat, - bottomRightTile.bounds.maxlon, - topLeftTile.bounds.maxlat); + return new OpenLayers.Bounds(topLeftTile.bounds.left, + bottomRightTile.bounds.bottom, + bottomRightTile.bounds.right, + topLeftTile.bounds.top); }, _initTiles:function() { var viewSize = this.map.getSize(); @@ -73,17 +73,17 @@ OpenLayers.Layer.Grid.prototype = Object.extend( new OpenLayers.Layer(), { var tilelon = resolution*this.tileSize.w; var tilelat = resolution*this.tileSize.h; - var offsetlon = bounds.minlon - extent.minlon; + var offsetlon = bounds.left - extent.left; var tilecol = Math.floor(offsetlon/tilelon); var tilecolremain = offsetlon/tilelon - tilecol; var tileoffsetx = -tilecolremain * this.tileSize.w; - var tileoffsetlon = extent.minlon + tilecol * tilelon; + var tileoffsetlon = extent.left + tilecol * tilelon; - var offsetlat = bounds.maxlat - (extent.minlat + tilelat); + var offsetlat = bounds.top - (extent.bottom + tilelat); var tilerow = Math.ceil(offsetlat/tilelat); var tilerowremain = tilerow - offsetlat/tilelat; var tileoffsety = -tilerowremain * this.tileSize.h; - var tileoffsetlat = extent.minlat + tilerow * tilelat; + var tileoffsetlat = extent.bottom + tilerow * tilelat; tileoffsetx = Math.round(tileoffsetx); // heaven help us tileoffsety = Math.round(tileoffsety); @@ -113,11 +113,11 @@ OpenLayers.Layer.Grid.prototype = Object.extend( new OpenLayers.Layer(), { tileoffsetlon += tilelon; tileoffsetx += this.tileSize.w; - } while (tileoffsetlon < bounds.maxlon) + } while (tileoffsetlon < bounds.right) tileoffsetlat -= tilelat; tileoffsety += this.tileSize.h; - } while(tileoffsetlat > bounds.minlat - tilelat) + } while(tileoffsetlat > bounds.bottom - tilelat) }, @@ -139,8 +139,8 @@ OpenLayers.Layer.Grid.prototype = Object.extend( new OpenLayers.Layer(), { var modelTile = modelRow[i]; var bounds = modelTile.bounds.copyOf(); var position = modelTile.position.copyOf(); - bounds.minlat = bounds.minlat + deltaLat; - bounds.maxlat = bounds.maxlat + deltaLat; + bounds.bottom = bounds.bottom + deltaLat; + bounds.top = bounds.top + deltaLat; position.y = position.y + deltaY; var newTile = this.addTile(bounds, position); newRow.append(newTile); @@ -172,8 +172,8 @@ OpenLayers.Layer.Grid.prototype = Object.extend( new OpenLayers.Layer(), { var bounds = modelTile.bounds.copyOf(); var position = modelTile.position.copyOf(); - bounds.minlon = bounds.minlon + deltaLon; - bounds.maxlon = bounds.maxlon + deltaLon; + bounds.left = bounds.left + deltaLon; + bounds.right = bounds.right + deltaLon; position.x = position.x + deltaX; var newTile = this.addTile(bounds, position); diff --git a/lib/OpenLayers/Layer/Marker.js b/lib/OpenLayers/Layer/Marker.js index 82e417b1f2..fb17b07866 100644 --- a/lib/OpenLayers/Layer/Marker.js +++ b/lib/OpenLayers/Layer/Marker.js @@ -50,8 +50,8 @@ OpenLayers.Layer.Marker.prototype = var resolution = this.map.getResolution(); var extent = this.map.getExtent(); var pixel = new OpenLayers.Pixel( - 1/resolution * (marker.lonlat.lon - extent.minlon), - 1/resolution * (extent.maxlat - marker.lonlat.lat) + 1/resolution * (marker.lonlat.lon - extent.left), + 1/resolution * (extent.top - marker.lonlat.lat) ); var m = marker.generateMarker(pixel); this.div.appendChild(m); diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js index b442287f82..6eb0b70e59 100644 --- a/lib/OpenLayers/Map.js +++ b/lib/OpenLayers/Map.js @@ -222,7 +222,7 @@ OpenLayers.Map.prototype = { */ getZoomForExtent: function (bounds) { var size = this.getSize(); - var deg_per_pixel = bounds.width / size.w; + var deg_per_pixel = bounds.getWidth() / size.w; var zoom = Math.log(deg_per_pixel / this.maxResolution) / Math.log(2); return Math.floor(Math.max(zoom, 0)); }, @@ -318,8 +318,8 @@ OpenLayers.Map.prototype = { var oldZoom = this.zoom; this.zoom = this.getZoomForExtent( fullExtent ); this.setCenter( - new OpenLayers.LonLat((fullExtent.minlon+fullExtent.maxlon)/2, - (fullExtent.minlat+fullExtent.maxlat)/2) + new OpenLayers.LonLat((fullExtent.left+fullExtent.right)/2, + (fullExtent.bottom+fullExtent.top)/2) ); }, diff --git a/lib/OpenLayers/Util.js b/lib/OpenLayers/Util.js index f4a0cf0f62..96ee855f9c 100644 --- a/lib/OpenLayers/Util.js +++ b/lib/OpenLayers/Util.js @@ -1,4 +1,4 @@ -/* +/** * @class */ OpenLayers.Util=new Object(); @@ -223,65 +223,56 @@ OpenLayers.LonLat.fromString = function(str) { /** * @class This class represents a bounding box. -* Data stored as Min and Max Longitudes and Latitudes +* Data stored as left, bottom, right, top floats */ OpenLayers.Bounds = Class.create(); OpenLayers.Bounds.prototype = { /** @type float */ - minlon: 0.0, + left: 0.0, /** @type float */ - minlat: 0.0, + bottom: 0.0, /** @type float */ - maxlon: 0.0, + right: 0.0, /** @type float */ - maxlat: 0.0, + top: 0.0, - /** @type float */ - width: 0.0, - - /** @type float */ - height: 0.0, - - - /** + /** * @constructor * - * @param {float} minlon - * @param {float} minlat - * @param {float} maxlon - * @param {float} maxlat + * @param {float} left + * @param {float} bottom + * @param {float} right + * @param {float} top + * */ - initialize: function(minlon, minlat, maxlon, maxlat) { - this.minlon = minlon; - this.minlat = minlat; - this.maxlon = maxlon; - this.maxlat = maxlat; - this.width = Math.abs(this.maxlon - this.minlon); - this.height = Math.abs(this.maxlat - this.minlat); + initialize: function(left, bottom, right, top) { + this.left = left; + this.bottom = bottom; + this.right = right; + this.top = top; }, - - /** - * @return String representation of OpenLayers.Bounds object. - * (ex."Min lon/lat=5/42 Max lon/lat=10/45 width=5 height=3") - * @type String - */ - toString:function(){ - return ("Min lon/lat=" + this.minlon +"/"+ this.minlat - + " Max lon/lat=" + this.maxlon +"/"+ this.maxlat - + " width=" + this.width + " height=" + this.height); - }, - - /** - * @return New OpenLayers.Bounds object with the same min/max lon/lat values + + /** + * @returns A fresh copy of the bounds * @type OpenLayers.Bounds */ copyOf:function() { - return new OpenLayers.Bounds(this.minlon, this.minlat, - this.maxlon, this.maxlat); + return new OpenLayers.Bounds(this.left, this.bottom, + this.right, this.top); + }, + + /** + * @return String representation of OpenLayers.Bounds object. + * (ex."left-bottom=(5,42) right-top=(10,45)") + * @type String + */ + toString:function(){ + return ( "left-bottom=(" + this.left + "," + this.bottom + ")" + + " right-top=(" + this.right + "," + this.top + ")" ); }, /** @@ -290,21 +281,136 @@ OpenLayers.Bounds.prototype = { * @type String */ toBBOX:function() { - return (this.minlon + "," + this.minlat + "," + - this.maxlon + "," + this.maxlat); + return (this.left + "," + this.bottom + "," + + this.right + "," + this.top); }, - - /** - * @return Whether or not the passed-in coordinate is within the area - * delineated by this OpenLayers.Bounds + /** + * @returns The width of the bounds + * @type float + */ + getWidth:function() { + return (this.right - this.left); + }, + + /** + * @returns The height of the bounds + * @type float + */ + getHeight:function() { + return (this.top - this.bottom); + }, + + /** + * @returns An OpenLayers.Size which represents the size of the box + * @type OpenLayers.Size + */ + getSize:function() { + return new OpenLayers.Size(this.getWidth(), this.getHeight()); + }, + + /** + * @returns An OpenLayers.Pixel which represents the center of the bounds + * @type OpenLayers.Pixel + */ + getCenterPixel:function() { + return new OpenLayers.Pixel(this.left + (this.getWidth() / 2), + this.bottom + (this.getHeight() / 2)); + }, + + /** + * @returns An OpenLayers.LonLat which represents the center of the bounds + * @type OpenLayers.LonLat + */ + getCenterLonLat:function() { + return new OpenLayers.LonLat(this.left + (this.getWidth() / 2), + this.bottom + (this.getHeight() / 2)); + }, + + /** + * @param {float} x + * @param {float} y + * + * @returns A new OpenLayers.Bounds whose coordinates are the same as this, + * but shifted by the passed-in x and y values + * @type OpenLayers.Bounds + */ + add:function(x, y){ + return new OpenLayers.Box(this.left + x, this.bottom + y, + this.right + x, this.top + y); + }, + + /** + * @param {float} x + * @param {float} y + * @param {Boolean} inclusive Whether or not to include the border. + * Default is true + * + * @return Whether or not the passed-in coordinates are within this bounds * @type Boolean */ - contains:function(ll) { - return ((ll.lon >= this.minlon) && (ll.lon <= this.maxlon) - && (ll.lat >= this.minlat) && (ll.lat <= this.maxlat)); - }, + contains:function(x, y, inclusive) { + //set default + if (inclusive == null) { + inclusive = true; + } + + var contains = false; + if (inclusive) { + contains = ((x >= this.left) && (x <= this.right) && + (y >= this.bottom) && (y <= this.top)); + } else { + contains = ((x > this.left) && (x < this.right) && + (y > this.bottom) && (y < this.top)); + } + return contains; + }, + + /** + * @param {OpenLayers.Bounds} bounds + * @param {Boolean} partial If true, only part of passed-in + * OpenLayers.Bounds needs be within this bounds. + * If false, the entire passed-in bounds must be + * within. Default is false + * @param {Boolean} inclusive Whether or not to include the border. + * Default is true + * + * @return Whether or not the passed-in OpenLayers.Bounds object is + * contained within this bounds. + * @type Boolean + */ + containsBounds:function(bounds, partial, inclusive) { + + //set defaults + if (partial == null) { + partial = false; + } + if (inclusive == null) { + inclusive = true; + } + + var inLeft; + var inTop; + var inRight; + var inBottom; + + if (inclusive) { + inLeft = (bounds.left >= this.left) && (bounds.left <= this.right); + inTop = (bounds.top >= this.bottom) && (bounds.top <= this.top); + inRight= (bounds.right >= this.left) && (bounds.right <= this.right); + inBottom = (bounds.bottom >= this.bottom) && (bounds.bottom <= this.top); + } else { + inLeft = (bounds.left > this.left) && (bounds.left < this.right); + inTop = (bounds.top > this.bottom) && (bounds.top < this.top); + inRight= (bounds.right > this.left) && (bounds.right < this.right); + inBottom = (bounds.bottom > this.bottom) && (bounds.bottom < this.top); + } + + return (partial) ? (inTop || inBottom) && (inLeft || inRight ) + : (inTop && inLeft && inBottom && inRight); + }, + /** @final @type String */ CLASS_NAME: "OpenLayers.Bounds" }; @@ -327,110 +433,18 @@ OpenLayers.Bounds.fromString = function(str) { parseFloat(bounds[3])); }; -OpenLayers.Box = Class.create(); -OpenLayers.Box.prototype = { - initialize: function(x,y,w,h){ - this.xy=new OpenLayers.Pixel(x,y); - this.sz=new OpenLayers.Size(w,h); - this.c = new OpenLayers.Pixel(x+(w/2), y+(h/2)); - this.br = new OpenLayers.Pixel(x+w-1,y+h-1); - }, - - /* offset box by df - * @df(OpenLayers.Size) - */ - offset:function(df){ - this.xy=new OpenLayers.Pixel(this.xy.x+df.w,this.xy.y+df.h); - this.c = new OpenLayers.Pixel(this.xy.x+(this.sz.w/2), this.xy.y+(this.sz.h/2)); - var x=this.xy.x; - var y=this.xy.y; - var w=this.sz.w; - var h=this.sz.h; - this.br = new OpenLayers.Pixel(x+w-1,y+h-1); - }, - - getOrigin:function(){return this.xy;}, - getSize:function(){return this.sz;}, - getCenter:function(){return this.c;}, - getBotRight:function(){return this.br;}, - getWidth:function(){return this.sz.w;}, - getHeight:function(){return this.sz.h;}, - getSize:function(){return this.sz;}, - - toString:function(){ - return (this.xy.toString() + " " + this.sz.toString()); - }, - copyOf:function(){ - return new OpenLayers.Box(this.xy.x, this.xy.y, this.sz.w, this.sz.h); - }, - toCoordsString:function(){ - var x1 = this.xy.x; - var x2 = this.xy.x+this.sz.w-1; - var y1 = this.xy.y; - var y2 = this.xy.y+this.sz.h-1; - return (x1+","+y1+","+x2+","+y2); - }, - contains:function(pt){ - var returnVal = false; - - var lx=this.xy.x; - var ly=this.xy.y; - var rx=lx+this.sz.w-1; - var ry=ly+this.sz.h-1; - - if (pt != null) { - //upper left in - returnVal = (pt.x >=lx && pt.x <=rx && pt.y >=ly && pt.y <= ry); - } - return returnVal; - }, - - /** - * @param {ol.Box} box - * @param {bool} partial - if true, returns whether any part of the passed - * in box is within the calling box. otherwise box - * must contain entire box to return true. - * - * @return {bool} - */ - containsBox:function(box, partial) { - var contains = false; - - var mainTop = this.xy.y; - var mainLeft = this.xy.x; - var mainBottom = this.xy.y + this.sz.h; - var mainRight = this.xy.x + this.sz.w; - - var top = box.xy.y; - var left = box.xy.x; - var bottom = box.xy.y + box.sz.h; - var right = box.xy.x + box.sz.w; - - var inTop = (top >= mainTop) && (top <= mainBottom); - var inLeft = (left >= mainLeft) && (left <= mainRight); - var inBottom = (bottom >= mainTop) && (bottom <= mainBottom); - var inRight= (right >= mainLeft) && (right <= mainRight); - - if (partial) { - contains = (inTop || inBottom) && (inLeft || inRight ); - } else { - contains = (inTop && inLeft && inBottom && inRight); - } - - return contains; - }, - - // is this point the center of the box, +-2 pixels (@todo fix that number!) - isCenter:function(pt){ - var size = this.c.absDiff(pt); - return (size.w <= 2 && size.h <= 2); - } -}; // Some other helpful things + +/** +* @param {String} sStart +* +* @returns Whether or not this string starts with the string passed in. +* @type Boolean +*/ String.prototype.startsWith = function(sStart){ - return (this.substr(0,sStart.length)==sStart); + return (this.substr(0,sStart.length) == sStart); }; String.prototype.trim = function() { var b=0,e=this.length -1; @@ -463,6 +477,8 @@ Array.prototype.append=function(the_item){ }; Array.prototype.clear=function() {this.length=0;}; + + /** Create a child element (a div currently) that * is a proper child of the supplied parent, is invisible, * positioned as requested within the parent, etc diff --git a/tests/test_Bounds.html b/tests/test_Bounds.html index 56bbd1ba5c..bcd520c57c 100644 --- a/tests/test_Bounds.html +++ b/tests/test_Bounds.html @@ -4,16 +4,29 @@ diff --git a/tests/test_Tile.html b/tests/test_Tile.html index 6dbf8ca07f..4ed7eaf1bd 100644 --- a/tests/test_Tile.html +++ b/tests/test_Tile.html @@ -11,10 +11,10 @@ new OpenLayers.Size(5,6)); t.ok( tile instanceof OpenLayers.Tile, "new OpenLayers.Tile returns Tile object" ); t.ok( tile.bounds instanceof OpenLayers.Bounds, "tile.bounds is a Bounds object" ); - t.eq( tile.bounds.minlon, 1, "tile.bounds.minlon is set correctly"); - t.eq( tile.bounds.minlat, 2, "tile.bounds.minlat is set correctly"); - t.eq( tile.bounds.maxlon, 3, "tile.bounds.maxlon is set correctly"); - t.eq( tile.bounds.maxlat, 4, "tile.bounds.maxlat is set correctly"); + t.eq( tile.bounds.left, 1, "tile.bounds.left is set correctly"); + t.eq( tile.bounds.bottom, 2, "tile.bounds.bottom is set correctly"); + t.eq( tile.bounds.right, 3, "tile.bounds.right is set correctly"); + t.eq( tile.bounds.top, 4, "tile.bounds.top is set correctly"); t.ok( tile.size instanceof OpenLayers.Size, "tile.size is a Size object" ); t.eq( tile.size.w, 5, "tile.size.w is set correctly"); t.eq( tile.size.h, 6, "tile.size.h is set correctly"); diff --git a/tests/test_Tile_Image.html b/tests/test_Tile_Image.html index c74cedb303..ec70297145 100644 --- a/tests/test_Tile_Image.html +++ b/tests/test_Tile_Image.html @@ -11,10 +11,10 @@ new OpenLayers.Size(5,6)); t.ok( tile instanceof OpenLayers.Tile.Image, "new OpenLayers.Tile returns Tile object" ); t.ok( tile.bounds instanceof OpenLayers.Bounds, "tile.bounds is a Bounds object" ); - t.eq( tile.bounds.minlon, 1, "tile.bounds.minlon is set correctly"); - t.eq( tile.bounds.minlat, 2, "tile.bounds.minlat is set correctly"); - t.eq( tile.bounds.maxlon, 3, "tile.bounds.maxlon is set correctly"); - t.eq( tile.bounds.maxlat, 4, "tile.bounds.maxlat is set correctly"); + t.eq( tile.bounds.left, 1, "tile.bounds.left is set correctly"); + t.eq( tile.bounds.bottom, 2, "tile.bounds.bottom is set correctly"); + t.eq( tile.bounds.right, 3, "tile.bounds.right is set correctly"); + t.eq( tile.bounds.top, 4, "tile.bounds.top is set correctly"); t.ok( tile.size instanceof OpenLayers.Size, "tile.size is a Size object" ); t.eq( tile.size.w, 5, "tile.size.w is set correctly"); t.eq( tile.size.h, 6, "tile.size.h is set correctly");