Fix #1951 by rounding all floats passed to Bounds.initialize() and

LonLat.initialize() to 14 significant figures.

Added an OpenLayers.Util.toFloat() function, and changed the LonLat constructor
and the Bounds constructor to truncate all float parameters to 14 significant
figures to avoid numeric comparison errors caused by floating point precision
loss. See the comments around the definition of
OpenLayers.Util.DEFAULT_PRECISION for how it works.

Also refactored Bounds.intersectBounds() for readability, and added a
Bounds.touchesBounds() in the process. After tweaking the tests for
Layer.SphericalMercator and Format.WKT (because they were expecting too many
significant figures), all tests pass.



git-svn-id: http://svn.openlayers.org/trunk/openlayers@9022 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
Schuyler Erle
2009-03-11 22:45:32 +00:00
parent 9afcb939be
commit e89774d568
8 changed files with 135 additions and 59 deletions

View File

@@ -796,6 +796,51 @@ OpenLayers.Util.mouseLeft = function (evt, div) {
return (target != div);
};
/**
* Property: precision
* {Number} The number of significant digits to retain to avoid
* floating point precision errors.
*
* We use 14 as a "safe" default because, although IEEE 754 double floats
* (standard on most modern operating systems) support up to about 16
* significant digits, 14 significant digits are sufficient to represent
* sub-millimeter accuracy in any coordinate system that anyone is likely to
* use with OpenLayers.
*
* If DEFAULT_PRECISION is set to 0, the original non-truncating behavior
* of OpenLayers <2.8 is preserved. Be aware that this will cause problems
* with certain projections, e.g. spherical Mercator.
*
*/
OpenLayers.Util.DEFAULT_PRECISION = 14;
/**
* Function: toFloat
* Convenience method to cast an object to a Number, rounded to the
* desired floating point precision.
*
* Parameters:
* number - {Number} The number to cast and round.
* precision - {Number} An integer suitable for use with
* Number.toPrecision(). Defaults to OpenLayers.Util.DEFAULT_PRECISION.
* If set to 0, no rounding is performed.
*
* Returns:
* {Number} The cast, rounded number.
*/
OpenLayers.Util.toFloat = function (number, precision) {
if (precision == null) {
precision = OpenLayers.Util.DEFAULT_PRECISION;
}
var number;
if (precision == 0) {
number = parseFloat(number);
} else {
number = parseFloat(parseFloat(number).toPrecision(precision))
}
return number;
};
/**
* Function: rad
*
@@ -1071,7 +1116,7 @@ OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT, {
OpenLayers.DOTS_PER_INCH = 72;
/**
* Function: normalzeScale
* Function: normalizeScale
*
* Parameters:
* scale - {float}