More trip planner testing with colors
[busui.git] / labs / openlayers / lib / OpenLayers / BaseTypes / Bounds.js
blob:a/labs/openlayers/lib/OpenLayers/BaseTypes/Bounds.js -> blob:b/labs/openlayers/lib/OpenLayers/BaseTypes/Bounds.js
  /* 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);
  },