|
/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for |
|
* full list of contributors). Published under the Clear BSD license. |
|
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the |
|
* full text of the license. */ |
|
|
|
/** |
|
* @requires OpenLayers/Console.js |
|
*/ |
|
|
|
/** |
|
* Class: OpenLayers.Bounds |
|
* Instances of this class represent bounding boxes. Data stored as left, |
|
* bottom, right, top floats. All values are initialized to null, however, |
|
* you should make sure you set them before using the bounds for anything. |
|
* |
|
* Possible use case: |
|
* > bounds = new OpenLayers.Bounds(); |
|
* > bounds.extend(new OpenLayers.LonLat(4,5)); |
|
* > bounds.extend(new OpenLayers.LonLat(5,6)); |
|
* > bounds.toBBOX(); // returns 4,5,5,6 |
|
*/ |
|
OpenLayers.Bounds = OpenLayers.Class({ |
|
|
|
/** |
|
* Property: left |
|
* {Number} Minimum horizontal coordinate. |
|
*/ |
|
left: null, |
|
|
|
/** |
|
* Property: bottom |
|
* {Number} Minimum vertical coordinate. |
|
*/ |
|
bottom: null, |
|
|
|
/** |
|
* Property: right |
|
* {Number} Maximum horizontal coordinate. |
|
*/ |
|
right: null, |
|
|
|
/** |
|
* Property: top |
|
* {Number} Maximum vertical coordinate. |
|
*/ |
|
top: null, |
|
|
|
/** |
|
* Property: centerLonLat |
|
* {<OpenLayers.LonLat>} A cached center location. This should not be |
|
* accessed directly. Use <getCenterLonLat> instead. |
|
*/ |
|
centerLonLat: null, |
|
|
|
/** |
|
* Constructor: OpenLayers.Bounds |
|
* Construct a new bounds object. |
|
* |
|
* Parameters: |
|
* left - {Number} The left bounds of the box. Note that for width |
|
* calculations, this is assumed to be less than the right value. |
|
* bottom - {Number} The bottom bounds of the box. Note that for height |
|
* calculations, this is assumed to be more than the top value. |
|
* right - {Number} The right bounds. |
|
* top - {Number} The top bounds. |
|
*/ |
|
initialize: function(left, bottom, right, top) { |
|
if (left != null) { |
|
this.left = OpenLayers.Util.toFloat(left); |
|
} |
|
if (bottom != null) { |
|
this.bottom = OpenLayers.Util.toFloat(bottom); |
|
} |
|
if (right != null) { |
|
this.right = OpenLayers.Util.toFloat(right); |
|
} |
|
if (top != null) { |
|
this.top = OpenLayers.Util.toFloat(top); |
|
} |
|
}, |
|
|
|
/** |
|
* Method: clone |
|
* Create a cloned instance of this bounds. |
|
* |
|
* Returns: |
|
* {<OpenLayers.Bounds>} A fresh copy of the bounds |
|
*/ |
|
clone:function() { |
|
return new OpenLayers.Bounds(this.left, this.bottom, |
|
this.right, this.top); |
|
}, |
|
|
|
/** |
|
* Method: equals |
|
* Test a two bounds for equivalence. |
|
* |
|
* Parameters: |
|
* bounds - {<OpenLayers.Bounds>} |
|
* |
|
* Returns: |
|
* {Boolean} The passed-in bounds object has the same left, |
|
* right, top, bottom components as this. Note that if bounds |
|
* passed in is null, returns false. |
|
*/ |
|
equals:function(bounds) { |
|
var equals = false; |
|
if (bounds != null) { |
|
equals = ((this.left == bounds.left) && |
|
(this.right == bounds.right) && |
|
(this.top == bounds.top) && |
|
(this.bottom == bounds.bottom)); |
|
} |
|
return equals; |
|
}, |
|
|
|
/** |
|
* APIMethod: toString |
|
* |
|
* Returns: |
|
* {String} String representation of bounds object. |
|
* (ex.<i>"left-bottom=(5,42) right-top=(10,45)"</i>) |
|
*/ |
|
toString:function() { |
|
return ( "left-bottom=(" + this.left + "," + this.bottom + ")" |
|
+ " right-top=(" + this.right + "," + this.top + ")" ); |
|
}, |
|
|
|
/** |
|
* APIMethod: toArray |
|
* |
|
* Parameters: |
|
* reverseAxisOrder - {Boolean} Should we reverse the axis order? |
|
* |
|
* Returns: |
|
* {Array} array of left, bottom, right, top |
|
*/ |
|
toArray: function(reverseAxisOrder) { |
|
if (reverseAxisOrder === true) { |
|
return [this.bottom, this.left, this.top, this.right]; |
|
} else { |
|
return [this.left, this.bottom, this.right, this.top]; |
|
} |
|
}, |
|
|
|
/** |
|
* APIMethod: toBBOX |
|
* |
|
* Parameters: |
|
* decimal - {Integer} How many significant digits in the bbox coords? |
|
* Default is 6 |
|
* reverseAxisOrder - {Boolean} Should we reverse the axis order? |
|
* |
|
* Returns: |
|
* {String} Simple String representation of bounds object. |
|
* (ex. <i>"5,42,10,45"</i>) |
|
*/ |
|
toBBOX:function(decimal, reverseAxisOrder) { |
|
if (decimal== null) { |
|
decimal = 6; |
|
} |
|
var mult = Math.pow(10, decimal); |
|
var xmin = Math.round(this.left * mult) / mult; |
|
var ymin = Math.round(this.bottom * mult) / mult; |
|
var xmax = Math.round(this.right * mult) / mult; |
|
var ymax = Math.round(this.top * mult) / mult; |
|
if (reverseAxisOrder === true) { |
|
return ymin + "," + xmin + "," + ymax + "," + xmax; |
|
} else { |
|
return xmin + "," + ymin + "," + xmax + "," + ymax; |
|
} |
|
}, |
|
|
|
/** |
|
* APIMethod: toGeometry |
|
* Create a new polygon geometry based on this bounds. |
|
* |
|
* Returns: |
|
* {<OpenLayers.Geometry.Polygon>} A new polygon with the coordinates |
|
* of this bounds. |
|
*/ |
|
toGeometry: function() { |
|
return new OpenLayers.Geometry.Polygon([ |
|
new OpenLayers.Geometry.LinearRing([ |
|
new OpenLayers.Geometry.Point(this.left, this.bottom), |
|
new OpenLayers.Geometry.Point(this.right, this.bottom), |
|
new OpenLayers.Geometry.Point(this.right, this.top), |
|
new OpenLayers.Geometry.Point(this.left, this.top) |
|
]) |
|
]); |
|
}, |
|
|
|
/** |
|
* APIMethod: getWidth |
|
* |
|
* Returns: |
|
* {Float} The width of the bounds |
|
*/ |
|
getWidth:function() { |
|
return (this.right - this.left); |
|
}, |
|
|
|
/** |
|
* APIMethod: getHeight |
|
* |
|
* Returns: |
|
* {Float} The height of the bounds (top minus bottom). |
|
*/ |
|
getHeight:function() { |
|
return (this.top - this.bottom); |
|
}, |
|
|
|
/** |
|
* APIMethod: getSize |
|
* |
|
* Returns: |
|
* {<OpenLayers.Size>} The size of the box. |
|
*/ |
|
getSize:function() { |
|
return new OpenLayers.Size(this.getWidth(), this.getHeight()); |
|
}, |
|
|
|
/** |
|
* APIMethod: getCenterPixel |
|
* |
|
* Returns: |
|
* {<OpenLayers.Pixel>} The center of the bounds in pixel space. |
|
*/ |
|
getCenterPixel:function() { |
|
return new OpenLayers.Pixel( (this.left + this.right) / 2, |
|
(this.bottom + this.top) / 2); |
|
}, |
|
|
|
/** |
|
* APIMethod: getCenterLonLat |
|
* |
|
* Returns: |
|
* {<OpenLayers.LonLat>} The center of the bounds in map space. |
|
*/ |
|
getCenterLonLat:function() { |
|
if(!this.centerLonLat) { |
|
this.centerLonLat = new OpenLayers.LonLat( |
|
(this.left + this.right) / 2, (this.bottom + this.top) / 2 |
|
); |
|
} |
|
return this.centerLonLat; |
|
}, |
|
|
|
/** |
|
* Method: scale |
|
* Scales the bounds around a pixel or lonlat. Note that the new |
|
* bounds may return non-integer properties, even if a pixel |
|
* is passed. |
|
* |
|
* Parameters: |
|
* ratio - {Float} |
|
* origin - {<OpenLayers.Pixel> or <OpenLayers.LonLat>} |
|
* Default is center. |
|
* |
|
* Returns: |
|
* {<OpenLayers.Bound>} A new bounds that is scaled by ratio |
|
* from origin. |
|
*/ |
|
|
|
scale: function(ratio, origin){ |
|
if(origin == null){ |
|
origin = this.getCenterLonLat(); |
|
} |
|
|
|
var origx,origy; |
|
|
|
// get origin coordinates |
|
if(origin.CLASS_NAME == "OpenLayers.LonLat"){ |
|
origx = origin.lon; |
|
origy = origin.lat; |
|
} else { |
|
origx = origin.x; |
|
origy = origin.y; |
|
} |
|
|
|
var left = (this.left - origx) * ratio + origx; |
|
var bottom = (this.bottom - origy) * ratio + origy; |
|
var right = (this.right - origx) * ratio + origx; |
|
var top = (this.top - origy) * ratio + origy; |
|
|
|
return new OpenLayers.Bounds(left, bottom, right, top); |
|
}, |
|
|
|
/** |
|
* APIMethod: add |
|
* |
|
* Parameters: |
|
* x - {Float} |
|
* y - {Float} |
|
* |
|
* Returns: |
|
* {<OpenLayers.Bounds>} A new bounds whose coordinates are the same as |
|
* this, but shifted by the passed-in x and y values. |
|
*/ |
|
add:function(x, y) { |
|
if ( (x == null) || (y == null) ) { |
|
var msg = OpenLayers.i18n("boundsAddError"); |
|
OpenLayers.Console.error(msg); |
|
return null; |
|
} |
|
return new OpenLayers.Bounds(this.left + x, this.bottom + y, |
|
this.right + x, this.top + y); |
|
}, |
|
|
|
/** |
|
* APIMethod: extend |
|
* Extend the bounds to include the point, lonlat, or bounds specified. |
|
* Note, this function assumes that left < right and bottom < top. |
|
* |
|
* Parameters: |
|
* object - {Object} Can be LonLat, Point, or Bounds |
|
*/ |
|
extend:function(object) { |
|
var bounds = null; |
|
if (object) { |
|
// clear cached center location |
|
switch(object.CLASS_NAME) { |
|
case "OpenLayers.LonLat": |
|
bounds = new OpenLayers.Bounds(object.lon, object.lat, |
|
object.lon, object.lat); |
|
break; |
|
case "OpenLayers.Geometry.Point": |
|
bounds = new OpenLayers.Bounds(object.x, object.y, |
|
object.x, object.y); |
|
break; |
|
|
|
case "OpenLayers.Bounds": |
|
bounds = object; |
|
break; |
|
} |
|
|
|
if (bounds) { |
|
this.centerLonLat = null; |
|
if ( (this.left == null) || (bounds.left < this.left)) { |
|
this.left = bounds.left; |
|
} |
|
if ( (this.bottom == null) || (bounds.bottom < this.bottom) ) { |
|
this.bottom = bounds.bottom; |
|
} |
|
if ( (this.right == null) || (bounds.right > this.right) ) { |
|
this.right = bounds.right; |
|
} |
|
if ( (this.top == null) || (bounds.top > this.top) ) { |
|
this.top = bounds.top; |
|
} |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* APIMethod: containsLonLat |
|
* |
|
* Parameters: |
|
* ll - {<OpenLayers.LonLat>} |
|
* inclusive - {Boolean} Whether or not to include the border. |
|
* Default is true. |
|
* |
|
* Returns: |
|
* {Boolean} The passed-in lonlat is within this bounds. |
|
*/ |
|
containsLonLat:function(ll, inclusive) { |
|
return this.contains(ll.lon, ll.lat, inclusive); |
|
}, |
|
|
|
/** |
|
* APIMethod: containsPixel |
|
* |
|
* Parameters: |
|
* px - {<OpenLayers.Pixel>} |
|
* inclusive - {Boolean} Whether or not to include the border. Default is |
|
* true. |
|
* |
|
* Returns: |
|
* {Boolean} The passed-in pixel is within this bounds. |
|
*/ |
|
containsPixel:function(px, inclusive) { |
|
return this.contains(px.x, px.y, inclusive); |
|
}, |