openlayers内lib/openlayers/util.js源码解析

//这个是指PNG图片的alpha透明处理是不是需要,一般浏览器都支持PNG的alpha透明,只有IE6不支持,所以要单独CSS Hack一下  
    OpenLayers.Util.alphaHackNeeded = null;  
    //测试是否需要alpha hack,IE6则需要  
    OpenLayers.Util.alphaHack = function() {  
        if (OpenLayers.Util.alphaHackNeeded == null) {  
            var arVersion = navigator.appVersion.split(“MSIE”);  
            var version = parseFloat(arVersion[1]);  
            var filter = false;  
          
            try {   
                filter = !!(document.body.filters);  
            } catch (e) {}      
          
            OpenLayers.Util.alphaHackNeeded = (filter &&   
                                               (version >= 5.5) && (version < 7));  
        }  
        return OpenLayers.Util.alphaHackNeeded;  
    };  
    //修改一个有image背景的div,针对IE6的alpha 透明,使用了AlphaImageLoader。具体说明可以参考这里http://support.microsoft.com/kb/294714/zh-cn  
    OpenLayers.Util.modifyAlphaImageDiv = function(div, id, px, sz, imgURL,   
                                                   position, border, sizing,   
                                                   opacity) {  
        OpenLayers.Util.modifyDOMElement(div, id, px, sz, position,  
                                         null, null, opacity);  
        var img = div.childNodes[0];  
        if (imgURL) {  
            img.src = imgURL;  
        }  
        OpenLayers.Util.modifyDOMElement(img, div.id + “_innerImage”, null, sz,   
                                         “relative”, border);  
          
        if (OpenLayers.Util.alphaHack()) {  
            if(div.style.display != “none”) {  
                div.style.display = “inline-block”;  
            }  
            if (sizing == null) {  
                sizing = “scale”;  
            }  
              
            div.style.filter = “progid:DXImageTransform.Microsoft” +  
                               “.AlphaImageLoader(src='” + img.src + “‘, ” +  
                               “sizingMethod='” + sizing + “‘)”;  
            if (parseFloat(div.style.opacity) >= 0.0 &&   
                parseFloat(div.style.opacity) < 1.0) {  
                div.style.filter += ” alpha(opacity=” + div.style.opacity * 100 + “)”;  
            }  
            img.style.filter = “alpha(opacity=0)”;  
        }  
    };  
    //创建一个带背景的div   
    OpenLayers.Util.createAlphaImageDiv = function(id, px, sz, imgURL,   
                                                   position, border, sizing,   
                                                   opacity, delayDisplay) {  
          
        var div = OpenLayers.Util.createDiv();  
        var img = OpenLayers.Util.createImage(null, null, null, null, null, null,   
                                              null, false);  
        div.appendChild(img);  
        if (delayDisplay) {  
            img.style.display = “none”;  
            OpenLayers.Event.observe(img, “load”,  
                OpenLayers.Function.bind(OpenLayers.Util.onImageLoad, div));  
            OpenLayers.Event.observe(img, “error”,  
                OpenLayers.Function.bind(OpenLayers.Util.onImageLoadError, div));  
        }  
        OpenLayers.Util.modifyAlphaImageDiv(div, id, px, sz, imgURL, position,   
                                            border, sizing, opacity);  
          
        return div;  
    };  
    //很简单的一个函数,把对象的属性名全改成大写  
    OpenLayers.Util.upperCaseObject = function (object) {  
        var uObject = {};  
        for (var key in object) {  
            uObject[key.toUpperCase()] = object[key];  
        }  
        return uObject;  
    };  
    //一个简单的浅拷贝,如果目标对象有这个属性,则不拷贝,否则拷贝  
    OpenLayers.Util.applyDefaults = function (to, from) {  
        to = to || {};  
        var fromIsEvt = typeof window.Event == “function”  
                        && from instanceof window.Event;  
        for (var key in from) {  
            if (to[key] === undefined ||  
                (!fromIsEvt && from.hasOwnProperty  
                 && from.hasOwnProperty(key) && !to.hasOwnProperty(key))) {  
                to[key] = from[key];  
            }  
        }  
        if(!fromIsEvt && from && from.hasOwnProperty  
           && from.hasOwnProperty(‘toString’) && !to.hasOwnProperty(‘toString’)) {  
            to.toString = from.toString;  
        }  
          
        return to;  
    };  
    //把对象属性和值,转换成url的参数格式,这个函数在ajax中,经常调用  
    OpenLayers.Util.getParameterString = function(params) {  
        var paramsArray = [];  
          
        for (var key in params) {  
          var value = params[key];  
          if ((value != null) && (typeof value != ‘function’)) {  
            var encodedValue;  
            if (typeof value == ‘object’ && value.constructor == Array) {  
              /* value is an array; encode items and separate with “,” */  
              var encodedItemArray = [];  
              for (var itemIndex=0, len=value.length; itemIndex<len; itemIndex++) {  
                encodedItemArray.push(encodeURIComponent(value[itemIndex]));  
              }  
              encodedValue = encodedItemArray.join(“,”);  
            }  
            else {  
              /* value is a string; simply encode */  
              encodedValue = encodeURIComponent(value);  
            }  
            paramsArray.push(encodeURIComponent(key) + “=” + encodedValue);  
          }  
        }  
          
        return paramsArray.join(“&”);  
    };  
    //img的路径  
    OpenLayers.ImgPath = ”;  
    //获取Openlayers的img路径  
    OpenLayers.Util.getImagesLocation = function() {  
        return OpenLayers.ImgPath || (OpenLayers._getScriptLocation() + “img/”);  
    };  
    //这个函数的参数就是函数指针,运行这些函数,只到第一个不抛出异常的函数,返回其返回值  
    OpenLayers.Util.Try = function() {  
        var returnValue = null;  
        for (var i=0, len=arguments.length; i<len; i++) {  
          var lambda = arguments[i];  
          try {  
            returnValue = lambda();  
            break;  
          } catch (e) {}  
        }  
        return returnValue;  
    };  
    //把对象p个子节点中的所有tagName的节点,做成数组返回  
    OpenLayers.Util.getNodes=function(p, tagName) {  
        var nodes = OpenLayers.Util.Try(  
            function () {  
                return OpenLayers.Util._getNodes(p.documentElement.childNodes,  
                                                tagName);  
            },  
            function () {  
                return OpenLayers.Util._getNodes(p.childNodes, tagName);  
            }  
        );  
        return nodes;  
    };  
    //过滤出指定tagName的node,做成数组返回  
    OpenLayers.Util._getNodes=function(nodes, tagName) {  
        var retArray = [];  
        for (var i=0, len=nodes.length; i<len; i++) {  
            if (nodes[i].nodeName==tagName) {  
                retArray.push(nodes[i]);  
            }  
        }  
        return retArray;  
    };  
    //取parent的节点标签名为item的第index项的nodeValue  
    OpenLayers.Util.getTagText = function (parent, item, index) {  
        var result = OpenLayers.Util.getNodes(parent, item);  
        if (result && (result.length > 0))  
        {  
            if (!index) {  
                index=0;  
            }  
            if (result[index].childNodes.length > 1) {  
                return result.childNodes[1].nodeValue;   
            }  
            else if (result[index].childNodes.length == 1) {  
                return result[index].firstChild.nodeValue;   
            }  
        } else {   
            return “”;   
        }  
    };  
    //取指定节点的nodeValue值,因为Firefox的标签中空白占一个位置,而IE不占。所以有两套函数。  
    OpenLayers.Util.getXmlNodeValue = function(node) {  
        var val = null;  
        OpenLayers.Util.Try(   
            function() {  
                val = node.text;  
                if (!val) {  
                    val = node.textContent;  
                }  
                if (!val) {  
                    val = node.firstChild.nodeValue;  
                }  
            },   
            function() {  
                val = node.textContent;  
            });   
        return val;  
    };  
    /**  
     * Function: mouseLeft 
     *  
     * Parameters: 
     * evt – {Event} 
     * div – {HTMLDivElement} 
     *  
     * Returns: 
     * {Boolean} 
     */  
    OpenLayers.Util.mouseLeft = function (evt, div) {  
        // start with the element to which the mouse has moved  
        var target = (evt.relatedTarget) ? evt.relatedTarget : evt.toElement;  
        // walk up the DOM tree.  
        while (target != div && target != null) {  
            target = target.parentNode;  
        }  
        // if the target we stop at isn’t the div, then we’ve left the 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 
     *  
     * Parameters: 
     * x – {Float} 
     *  
     * Returns: 
     * {Float} 
     */  
    OpenLayers.Util.rad = function(x) {return x*Math.PI/180;};  
    /** 
     * Function: distVincenty 
     * Given two objects representing points with geographic coordinates, this 
     *     calculates the distance between those points on the surface of an 
     *     ellipsoid. 
     *  
     * Parameters: 
     * p1 – {<OpenLayers.LonLat>} (or any object with both .lat, .lon properties) 
     * p2 – {<OpenLayers.LonLat>} (or any object with both .lat, .lon properties) 
     *  
     * Returns: 
     * {Float} The distance (in km) between the two input points as measured on an 
     *     ellipsoid.  Note that the input point objects must be in geographic 
     *     coordinates (decimal degrees) and the return distance is in kilometers. 
     */  
    OpenLayers.Util.distVincenty=function(p1, p2) {  
        var a = 6378137, b = 6356752.3142,  f = 1/298.257223563;  
        var L = OpenLayers.Util.rad(p2.lon – p1.lon);  
        var U1 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p1.lat)));  
        var U2 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p2.lat)));  
        var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);  
        var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);  
        var lambda = L, lambdaP = 2*Math.PI;  
        var iterLimit = 20;  
        while (Math.abs(lambda-lambdaP) > 1e-12 && –iterLimit>0) {  
            var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);  
            var sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +  
            (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda));  
            if (sinSigma==0) {  
                return 0;  // co-incident points  
            }  
            var cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda;  
            var sigma = Math.atan2(sinSigma, cosSigma);  
            var alpha = Math.asin(cosU1 * cosU2 * sinLambda / sinSigma);  
            var cosSqAlpha = Math.cos(alpha) * Math.cos(alpha);  
            var cos2SigmaM = cosSigma – 2*sinU1*sinU2/cosSqAlpha;  
            var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));  
            lambdaP = lambda;  
            lambda = L + (1-C) * f * Math.sin(alpha) *  
            (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));  
        }  
        if (iterLimit==0) {  
            return NaN;  // formula failed to converge  
        }  
        var uSq = cosSqAlpha * (a*a – b*b) / (b*b);  
        var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));  
        var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));  
        var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-  
            B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));  
        var s = b*A*(sigma-deltaSigma);  
        var d = s.toFixed(3)/1000; // round to 1mm precision  
        return d;  
    };  
    /** 
     * Function: getParameters 
     * Parse the parameters from a URL or from the current page itself into a  
     *     JavaScript Object. Note that parameter values with commas are separated 
     *     out into an Array. 
     *  
     * Parameters: 
     * url – {String} Optional url used to extract the query string. 
     *                If null, query string is taken from page location. 
     *  
     * Returns: 
     * {Object} An object of key/value pairs from the query string. 
     */  
    OpenLayers.Util.getParameters = function(url) {  
        // if no url specified, take it from the location bar  
        url = url || window.location.href;  
        //parse out parameters portion of url string  
        var paramsString = “”;  
        if (OpenLayers.String.contains(url, ‘?’)) {  
            var start = url.indexOf(‘?’) + 1;  
            var end = OpenLayers.String.contains(url, “#”) ?  
                        url.indexOf(‘#’) : url.length;  
            paramsString = url.substring(start, end);  
        }  
              
        var parameters = {};  
        var pairs = paramsString.split(/[&;]/);  
        for(var i=0, len=pairs.length; i<len; ++i) {  
            var keyValue = pairs[i].split(‘=’);  
            if (keyValue[0]) {  
                var key = decodeURIComponent(keyValue[0]);  
                var value = keyValue[1] || ”; //empty string if no value  
                //decode individual values  
                value = value.split(“,”);  
                for(var j=0, jlen=value.length; j<jlen; j++) {  
                    value[j] = decodeURIComponent(value[j]);  
                }  
                //if there’s only one value, do not return as array                      
                if (value.length == 1) {  
                    value = value[0];  
                }                  
                  
                parameters[key] = value;  
             }  
         }  
        return parameters;  
    };  
    /** 
     * Function: getArgs 
     * *Deprecated*.  Will be removed in 3.0.  Please use instead 
     *     <OpenLayers.Util.getParameters> 
     *  
     * Parameters: 
     * url – {String} Optional url used to extract the query string. 
     *                If null, query string is taken from page location. 
     *  
     * Returns: 
     * {Object} An object of key/value pairs from the query string. 
     */  
    OpenLayers.Util.getArgs = function(url) {  
        OpenLayers.Console.warn(  
            OpenLayers.i18n(  
                “methodDeprecated”, {‘newMethod’: ‘OpenLayers.Util.getParameters’}  
            )  
        );  
        return OpenLayers.Util.getParameters(url);  
    };  
    /** 
     * Property: lastSeqID 
     * {Integer} The ever-incrementing count variable. 
     *           Used for generating unique ids. 
     */  
    OpenLayers.Util.lastSeqID = 0;  
    /** 
     * Function: createUniqueID 
     * Create a unique identifier for this session.  Each time this function 
     *     is called, a counter is incremented.  The return will be the optional 
     *     prefix (defaults to “id_”) appended with the counter value. 
     *  
     * Parameters: 
     * prefix {String} Optionsal string to prefix unique id. Default is “id_”. 
     *  
     * Returns: 
     * {String} A unique id string, built on the passed in prefix. 
     */  
    OpenLayers.Util.createUniqueID = function(prefix) {  
        if (prefix == null) {  
            prefix = “id_”;  
        }  
        OpenLayers.Util.lastSeqID += 1;   
        return prefix + OpenLayers.Util.lastSeqID;          
    };  
    /** 
     * Constant: INCHES_PER_UNIT 
     * {Object} Constant inches per unit — borrowed from MapServer mapscale.c 
     * derivation of nautical miles from http://en.wikipedia.org/wiki/Nautical_mile 
     * Includes the full set of units supported by CS-MAP (http://trac.osgeo.org/csmap/) 
     * and PROJ.4 (http://trac.osgeo.org/proj/) 
     * The hardcoded table is maintain in a CS-MAP source code module named CSdataU.c 
     * The hardcoded table of PROJ.4 units are in pj_units.c. 
     */  
    OpenLayers.INCHES_PER_UNIT = {   
        ‘inches’: 1.0,  
        ‘ft’: 12.0,  
        ‘mi’: 63360.0,  
        ‘m’: 39.3701,  
        ‘km’: 39370.1,  
        ‘dd’: 4374754,  
        ‘yd’: 36  
    };  
    OpenLayers.INCHES_PER_UNIT[“in”]= OpenLayers.INCHES_PER_UNIT.inches;  
    OpenLayers.INCHES_PER_UNIT[“degrees”] = OpenLayers.INCHES_PER_UNIT.dd;  
    OpenLayers.INCHES_PER_UNIT[“nmi”] = 1852 * OpenLayers.INCHES_PER_UNIT.m;  
    // Units from CS-Map  
    OpenLayers.METERS_PER_INCH = 0.02540005080010160020;  
    OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT, {  
        “Inch”: OpenLayers.INCHES_PER_UNIT.inches,  
        “Meter”: 1.0 / OpenLayers.METERS_PER_INCH,   //EPSG:9001  
        “Foot”: 0.30480060960121920243 / OpenLayers.METERS_PER_INCH,   //EPSG:9003  
        “IFoot”: 0.30480000000000000000 / OpenLayers.METERS_PER_INCH,   //EPSG:9002  
        “ClarkeFoot”: 0.3047972651151 / OpenLayers.METERS_PER_INCH,   //EPSG:9005  
        “SearsFoot”: 0.30479947153867624624 / OpenLayers.METERS_PER_INCH,   //EPSG:9041  
        “GoldCoastFoot”: 0.30479971018150881758 / OpenLayers.METERS_PER_INCH,   //EPSG:9094  
        “IInch”: 0.02540000000000000000 / OpenLayers.METERS_PER_INCH,  
        “MicroInch”: 0.00002540000000000000 / OpenLayers.METERS_PER_INCH,  
        “Mil”: 0.00000002540000000000 / OpenLayers.METERS_PER_INCH,  
        “Centimeter”: 0.01000000000000000000 / OpenLayers.METERS_PER_INCH,  
        “Kilometer”: 1000.00000000000000000000 / OpenLayers.METERS_PER_INCH,   //EPSG:9036  
        “Yard”: 0.91440182880365760731 / OpenLayers.METERS_PER_INCH,  
        “SearsYard”: 0.914398414616029 / OpenLayers.METERS_PER_INCH,   //EPSG:9040  
        “IndianYard”: 0.91439853074444079983 / OpenLayers.METERS_PER_INCH,   //EPSG:9084  
        “IndianYd37”: 0.91439523 / OpenLayers.METERS_PER_INCH,   //EPSG:9085  
        “IndianYd62”: 0.9143988 / OpenLayers.METERS_PER_INCH,   //EPSG:9086  
        “IndianYd75”: 0.9143985 / OpenLayers.METERS_PER_INCH,   //EPSG:9087  
        “IndianFoot”: 0.30479951 / OpenLayers.METERS_PER_INCH,   //EPSG:9080  
        “IndianFt37”: 0.30479841 / OpenLayers.METERS_PER_INCH,   //EPSG:9081  
        “IndianFt62”: 0.3047996 / OpenLayers.METERS_PER_INCH,   //EPSG:9082  
        “IndianFt75”: 0.3047995 / OpenLayers.METERS_PER_INCH,   //EPSG:9083  
        “Mile”: 1609.34721869443738887477 / OpenLayers.METERS_PER_INCH,  
        “IYard”: 0.91440000000000000000 / OpenLayers.METERS_PER_INCH,   //EPSG:9096  
        “IMile”: 1609.34400000000000000000 / OpenLayers.METERS_PER_INCH,   //EPSG:9093  
        “NautM”: 1852.00000000000000000000 / OpenLayers.METERS_PER_INCH,   //EPSG:9030  
        “Lat-66”: 110943.316488932731 / OpenLayers.METERS_PER_INCH,  
        “Lat-83”: 110946.25736872234125 / OpenLayers.METERS_PER_INCH,  
        “Decimeter”: 0.10000000000000000000 / OpenLayers.METERS_PER_INCH,  
        “Millimeter”: 0.00100000000000000000 / OpenLayers.METERS_PER_INCH,  
        “Dekameter”: 10.00000000000000000000 / OpenLayers.METERS_PER_INCH,  
        “Decameter”: 10.00000000000000000000 / OpenLayers.METERS_PER_INCH,  
        “Hectometer”: 100.00000000000000000000 / OpenLayers.METERS_PER_INCH,  
        “GermanMeter”: 1.0000135965 / OpenLayers.METERS_PER_INCH,   //EPSG:9031  
        “CaGrid”: 0.999738 / OpenLayers.METERS_PER_INCH,  
        “ClarkeChain”: 20.1166194976 / OpenLayers.METERS_PER_INCH,   //EPSG:9038  
        “GunterChain”: 20.11684023368047 / OpenLayers.METERS_PER_INCH,   //EPSG:9033  
        “BenoitChain”: 20.116782494375872 / OpenLayers.METERS_PER_INCH,   //EPSG:9062  
        “SearsChain”: 20.11676512155 / OpenLayers.METERS_PER_INCH,   //EPSG:9042  
        “ClarkeLink”: 0.201166194976 / OpenLayers.METERS_PER_INCH,   //EPSG:9039  
        “GunterLink”: 0.2011684023368047 / OpenLayers.METERS_PER_INCH,   //EPSG:9034  
        “BenoitLink”: 0.20116782494375872 / OpenLayers.METERS_PER_INCH,   //EPSG:9063  
        “SearsLink”: 0.2011676512155 / OpenLayers.METERS_PER_INCH,   //EPSG:9043  
        “Rod”: 5.02921005842012 / OpenLayers.METERS_PER_INCH,  
        “IntnlChain”: 20.1168 / OpenLayers.METERS_PER_INCH,   //EPSG:9097  
        “IntnlLink”: 0.201168 / OpenLayers.METERS_PER_INCH,   //EPSG:9098  
        “Perch”: 5.02921005842012 / OpenLayers.METERS_PER_INCH,  
        “Pole”: 5.02921005842012 / OpenLayers.METERS_PER_INCH,  
        “Furlong”: 201.1684023368046 / OpenLayers.METERS_PER_INCH,  
        “Rood”: 3.778266898 / OpenLayers.METERS_PER_INCH,  
        “CapeFoot”: 0.3047972615 / OpenLayers.METERS_PER_INCH,  
        “Brealey”: 375.00000000000000000000 / OpenLayers.METERS_PER_INCH,  
        “ModAmFt”: 0.304812252984505969011938 / OpenLayers.METERS_PER_INCH,  
        “Fathom”: 1.8288 / OpenLayers.METERS_PER_INCH,  
        “NautM-UK”: 1853.184 / OpenLayers.METERS_PER_INCH,  
        “50kilometers”: 50000.0 / OpenLayers.METERS_PER_INCH,  
        “150kilometers”: 150000.0 / OpenLayers.METERS_PER_INCH  
    });  
    //unit abbreviations supported by PROJ.4  
    OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT, {  
        “mm”: OpenLayers.INCHES_PER_UNIT[“Meter”] / 1000.0,  
        “cm”: OpenLayers.INCHES_PER_UNIT[“Meter”] / 100.0,  
        “dm”: OpenLayers.INCHES_PER_UNIT[“Meter”] * 100.0,  
        “km”: OpenLayers.INCHES_PER_UNIT[“Meter”] * 1000.0,  
        “kmi”: OpenLayers.INCHES_PER_UNIT[“nmi”],    //International Nautical Mile  
        “fath”: OpenLayers.INCHES_PER_UNIT[“Fathom”], //International Fathom  
        “ch”: OpenLayers.INCHES_PER_UNIT[“IntnlChain”],  //International Chain  
        “link”: OpenLayers.INCHES_PER_UNIT[“IntnlLink”], //International Link  
        “us-in”: OpenLayers.INCHES_PER_UNIT[“inches”], //U.S. Surveyor’s Inch  
        “us-ft”: OpenLayers.INCHES_PER_UNIT[“Foot”],    //U.S. Surveyor’s Foot  
        “us-yd”: OpenLayers.INCHES_PER_UNIT[“Yard”],    //U.S. Surveyor’s Yard  
        “us-ch”: OpenLayers.INCHES_PER_UNIT[“GunterChain”], //U.S. Surveyor’s Chain  
        “us-mi”: OpenLayers.INCHES_PER_UNIT[“Mile”],   //U.S. Surveyor’s Statute Mile  
        “ind-yd”: OpenLayers.INCHES_PER_UNIT[“IndianYd37”],  //Indian Yard  
        “ind-ft”: OpenLayers.INCHES_PER_UNIT[“IndianFt37”],  //Indian Foot  
        “ind-ch”: 20.11669506 / OpenLayers.METERS_PER_INCH  //Indian Chain  
    });  
    /**  
     * Constant: DOTS_PER_INCH 
     * {Integer} 72 (A sensible default) 
     */  
    OpenLayers.DOTS_PER_INCH = 72;  
    /** 
     * Function: normalizeScale 
     *  
     * Parameters: 
     * scale – {float} 
     *  
     * Returns: 
     * {Float} A normalized scale value, in 1 / X format.  
     *         This means that if a value less than one ( already 1/x) is passed 
     *         in, it just returns scale directly. Otherwise, it returns  
     *         1 / scale 
     */  
    OpenLayers.Util.normalizeScale = function (scale) {  
        var normScale = (scale > 1.0) ? (1.0 / scale)   
                                      : scale;  
        return normScale;  
    };  
    /** 
     * Function: getResolutionFromScale 
     *  
     * Parameters: 
     * scale – {Float} 
     * units – {String} Index into OpenLayers.INCHES_PER_UNIT hashtable. 
     *                  Default is degrees 
     *  
     * Returns: 
     * {Float} The corresponding resolution given passed-in scale and unit  
     *         parameters. 
     */  
    OpenLayers.Util.getResolutionFromScale = function (scale, units) {  
        if (units == null) {  
            units = “degrees”;  
        }  
        var normScale = OpenLayers.Util.normalizeScale(scale);  
        var resolution = 1 / (normScale * OpenLayers.INCHES_PER_UNIT[units]  
                                        * OpenLayers.DOTS_PER_INCH);  
        return resolution;  
    };  
    /** 
     * Function: getScaleFromResolution 
     *  
     * Parameters: 
     * resolution – {Float} 
     * units – {String} Index into OpenLayers.INCHES_PER_UNIT hashtable. 
     *                  Default is degrees 
     *  
     * Returns: 
     * {Float} The corresponding scale given passed-in resolution and unit  
     *         parameters. 
     */  
    OpenLayers.Util.getScaleFromResolution = function (resolution, units) {  
        if (units == null) {  
            units = “degrees”;  
        }  
        var scale = resolution * OpenLayers.INCHES_PER_UNIT[units] *  
                        OpenLayers.DOTS_PER_INCH;  
        return scale;  
    };  
    /** 
     * Function: safeStopPropagation 
     * *Deprecated*. This function has been deprecated. Please use directly  
     *     <OpenLayers.Event.stop> passing ‘true’ as the 2nd  
     *     argument (preventDefault) 
     *  
     * Safely stop the propagation of an event *without* preventing 
     *   the default browser action from occurring. 
     *  
     * Parameter: 
     * evt – {Event} 
     */  
    OpenLayers.Util.safeStopPropagation = function(evt) {  
        OpenLayers.Event.stop(evt, true);  
    };  
    /** 
     * Function: pagePositon 
     * Calculates the position of an element on the page.  
     * 
     * Parameters: 
     * forElement – {DOMElement} 
     *  
     * Returns: 
     * {Array} two item array, L value then T value. 
     */  
    OpenLayers.Util.pagePosition = function(forElement) {  
        var valueT = 0, valueL = 0;  
        var element = forElement;  
        var child = forElement;  
        while(element) {  
            if(element == document.body) {  
                if(OpenLayers.Element.getStyle(child, ‘position’) == ‘absolute’) {  
                    break;  
                }  
            }  
              
            valueT += element.offsetTop  || 0;  
            valueL += element.offsetLeft || 0;  
            child = element;  
            try {  
                // wrapping this in a try/catch because IE chokes on the offsetParent  
                element = element.offsetParent;  
            } catch(e) {  
                OpenLayers.Console.error(OpenLayers.i18n(  
                                      “pagePositionFailed”,{‘elemId’:element.id}));  
                break;  
            }  
        }  
        element = forElement;  
        while(element) {  
            valueT -= element.scrollTop  || 0;  
            valueL -= element.scrollLeft || 0;  
            element = element.parentNode;  
        }  
          
        return [valueL, valueT];  
    };  
    /**  
     * Function: isEquivalentUrl 
     * Test two URLs for equivalence.  
     *  
     * Setting ‘ignoreCase’ allows for case-independent comparison. 
     *  
     * Comparison is based on:  
     *  – Protocol 
     *  – Host (evaluated without the port) 
     *  – Port (set ‘ignorePort80’ to ignore “80” values) 
     *  – Hash ( set ‘ignoreHash’ to disable) 
     *  – Pathname (for relative <-> absolute comparison)  
     *  – Arguments (so they can be out of order) 
     *   
     * Parameters: 
     * url1 – {String} 
     * url2 – {String} 
     * options – {Object} Allows for customization of comparison: 
     *                    ‘ignoreCase’ – Default is True 
     *                    ‘ignorePort80’ – Default is True 
     *                    ‘ignoreHash’ – Default is True 
     * 
     * Returns: 
     * {Boolean} Whether or not the two URLs are equivalent 
     */  
    OpenLayers.Util.isEquivalentUrl = function(url1, url2, options) {  
        options = options || {};  
        OpenLayers.Util.applyDefaults(options, {  
            ignoreCase: true,  
            ignorePort80: true,  
            ignoreHash: true  
        });  
        var urlObj1 = OpenLayers.Util.createUrlObject(url1, options);  
        var urlObj2 = OpenLayers.Util.createUrlObject(url2, options);  
        //compare all keys except for “args” (treated below)  
        for(var key in urlObj1) {  
            if(key !== “args”) {  
                if(urlObj1[key] != urlObj2[key]) {  
                    return false;  
                }  
            }  
        }  
        // compare search args – irrespective of order  
        for(var key in urlObj1.args) {  
            if(urlObj1.args[key] != urlObj2.args[key]) {  
                return false;  
            }  
            delete urlObj2.args[key];  
        }  
        // urlObj2 shouldn’t have any args left  
        for(var key in urlObj2.args) {  
            return false;  
        }  
          
        return true;  
    };  
    /** 
     * Function: createUrlObject 
     *  
     * Parameters: 
     * url – {String} 
     * options – {Object} A hash of options.  Can be one of: 
     *            ignoreCase: lowercase url, 
     *            ignorePort80: don’t include explicit port if port is 80, 
     *            ignoreHash: Don’t include part of url after the hash (#). 
     *  
     * Returns: 
     * {Object} An object with separate url, a, port, host, and args parsed out  
     *          and ready for comparison 
     */  
    OpenLayers.Util.createUrlObject = function(url, options) {  
        options = options || {};  
        // deal with relative urls first  
        if(!(/^\w+:\/\//).test(url)){ 
            var loc = window.location;  
            var port = loc.port ? “:” + loc.port : “”;  
            var fullUrl = loc.protocol + “//” + loc.host.split(“:”).shift() + port;  
            if(url.indexOf(“/”) === 0) {  
                // full pathname  
                url = fullUrl + url;  
            } else {  
                // relative to current path  
                var parts = loc.pathname.split(“/”);  
                parts.pop();  
                url = fullUrl + parts.join(“/”) + “/” + url;  
            }  
        }  
        
        if (options.ignoreCase) {  
            url = url.toLowerCase();   
        }  
        var a = document.createElement(‘a’);  
        a.href = url;  
          
        var urlObject = {};  
          
        //host (without port)  
        urlObject.host = a.host.split(“:”).shift();  
        //protocol  
        urlObject.protocol = a.protocol;    
        //port (get uniform browser behavior with port 80 here)  
        if(options.ignorePort80) {  
            urlObject.port = (a.port == “80” || a.port == “0”) ? “” : a.port;  
        } else {  
            urlObject.port = (a.port == “” || a.port == “0”) ? “80” : a.port;  
        }  
        //hash  
        urlObject.hash = (options.ignoreHash || a.hash === “#”) ? “” : a.hash;    
          
        //args  
        var queryString = a.search;  
        if (!queryString) {  
            var qMark = url.indexOf(“?”);  
            queryString = (qMark != -1) ? url.substr(qMark) : “”;  
        }  
        urlObject.args = OpenLayers.Util.getParameters(queryString);  
        //pathname (uniform browser behavior with leading “/”)  
        urlObject.pathname = (a.pathname.charAt(0) == “/”) ? a.pathname : “/” + a.pathname;  
          
        return urlObject;   
    };  
       
    /** 
     * Function: removeTail 
     * Takes a url and removes everything after the ? and # 
     *  
     * Parameters: 
     * url – {String} The url to process 
     *  
     * Returns: 
     * {String} The string with all queryString and Hash removed 
     */  
    OpenLayers.Util.removeTail = function(url) {  
        var head = null;  
          
        var qMark = url.indexOf(“?”);  
        var hashMark = url.indexOf(“#”);  
        if (qMark == -1) {  
            head = (hashMark != -1) ? url.substr(0,hashMark) : url;  
        } else {  
            head = (hashMark != -1) ? url.substr(0,Math.min(qMark, hashMark))   
                                      : url.substr(0, qMark);  
        }  
        return head;  
    };  
    /** 
     * Function: getBrowserName 
     *  
     * Returns: 
     * {String} A string which specifies which is the current  
     *          browser in which we are running.  
     *  
     *          Currently-supported browser detection and codes: 
     *           * ‘opera’ — Opera 
     *           * ‘msie’  — Internet Explorer 
     *           * ‘safari’ — Safari 
     *           * ‘firefox’ — FireFox 
     *           * ‘mozilla’ — Mozilla 
     *  
     *          If we are unable to property identify the browser, we  
     *           return an empty string. 
     */  
    OpenLayers.Util.getBrowserName = function() {  
        var browserName = “”;  
          
        var ua = navigator.userAgent.toLowerCase();  
        if ( ua.indexOf( “opera” ) != -1 ) {  
            browserName = “opera”;  
        } else if ( ua.indexOf( “msie” ) != -1 ) {  
            browserName = “msie”;  
        } else if ( ua.indexOf( “safari” ) != -1 ) {  
            browserName = “safari”;  
        } else if ( ua.indexOf( “mozilla” ) != -1 ) {  
            if ( ua.indexOf( “firefox” ) != -1 ) {  
                browserName = “firefox”;  
            } else {  
                browserName = “mozilla”;  
            }  
        }  
          
        return browserName;  
    };  
          
    /** 
     * Method: getRenderedDimensions 
     * Renders the contentHTML offscreen to determine actual dimensions for 
     *     popup sizing. As we need layout to determine dimensions the content 
     *     is rendered -9999px to the left and absolute to ensure the  
     *     scrollbars do not flicker 
     *      
     * Parameters: 
     * contentHTML 
     * size – {<OpenLayers.Size>} If either the ‘w’ or ‘h’ properties is  
     *     specified, we fix that dimension of the div to be measured. This is  
     *     useful in the case where we have a limit in one dimension and must  
     *     therefore meaure the flow in the other dimension. 
     * options – {Object} 
     *     displayClass – {String} Optional parameter.  A CSS class name(s) string 
     *         to provide the CSS context of the rendered content. 
     *     containerElement – {DOMElement} Optional parameter. Insert the HTML to  
     *         this node instead of the body root when calculating dimensions.  
     *  
     * Returns: 
     * {OpenLayers.Size} 
     */  
    OpenLayers.Util.getRenderedDimensions = function(contentHTML, size, options) {  
          
        var w, h;  
          
        // create temp container div with restricted size  
        var container = document.createElement(“div”);  
        container.style.visibility = “hidden”;  
              
        var containerElement = (options && options.containerElement)   
            ? options.containerElement : document.body;  
        //fix a dimension, if specified.  
        if (size) {  
            if (size.w) {  
                w = size.w;  
                container.style.width = w + “px”;  
            } else if (size.h) {  
                h = size.h;  
                container.style.height = h + “px”;  
            }  
        }  
        //add css classes, if specified  
        if (options && options.displayClass) {  
            container.className = options.displayClass;  
        }  
          
        // create temp content div and assign content  
        var content = document.createElement(“div”);  
        content.innerHTML = contentHTML;  
          
        // we need overflow visible when calculating the size  
        content.style.overflow = “visible”;  
        if (content.childNodes) {  
            for (var i=0, l=content.childNodes.length; i<l; i++) {  
                if (!content.childNodes[i].style) continue;  
                content.childNodes[i].style.overflow = “visible”;  
            }  
        }  
          
        // add content to restricted container   
        container.appendChild(content);  
          
        // append container to body for rendering  
        containerElement.appendChild(container);  
          
        // Opera and IE7 can’t handle a node with position:aboslute if it inherits  
        // position:absolute from a parent.  
        var parentHasPositionAbsolute = false;  
        var parent = container.parentNode;  
        while (parent && parent.tagName.toLowerCase()!=”body”) {  
            var parentPosition = OpenLayers.Element.getStyle(parent, “position”);  
            if(parentPosition == “absolute”) {  
                parentHasPositionAbsolute = true;  
                break;  
            } else if (parentPosition && parentPosition != “static”) {  
                break;  
            }  
            parent = parent.parentNode;  
        }  
        if(!parentHasPositionAbsolute) {  
            container.style.position = “absolute”;  
        }  
          
        // calculate scroll width of content and add corners and shadow width  
        if (!w) {  
            w = parseInt(content.scrollWidth);  
          
            // update container width to allow height to adjust  
            container.style.width = w + “px”;  
        }          
        // capture height and add shadow and corner image widths  
        if (!h) {  
            h = parseInt(content.scrollHeight);  
        }  
        // remove elements  
        container.removeChild(content);  
        containerElement.removeChild(container);  
          
        return new OpenLayers.Size(w, h);  
    };  
    /** 
     * APIFunction: getScrollbarWidth 
     * This function has been modified by the OpenLayers from the original version, 
     *     written by Matthew Eernisse and released under the Apache 2  
     *     license here: 
     *  
     *     http://www.fleegix.org/articles/2006/05/30/getting-the-scrollbar-width-in-pixels 
     *  
     *     It has been modified simply to cache its value, since it is physically  
     *     impossible that this code could ever run in more than one browser at  
     *     once.  
     *  
     * Returns: 
     * {Integer} 
     */  
    OpenLayers.Util.getScrollbarWidth = function() {  
          
        var scrollbarWidth = OpenLayers.Util._scrollbarWidth;  
          
        if (scrollbarWidth == null) {  
            var scr = null;  
            var inn = null;  
            var wNoScroll = 0;  
            var wScroll = 0;  
          
            // Outer scrolling div  
            scr = document.createElement(‘div’);  
            scr.style.position = ‘absolute’;  
            scr.style.top = ‘-1000px’;  
            scr.style.left = ‘-1000px’;  
            scr.style.width = ‘100px’;  
            scr.style.height = ’50px’;  
            // Start with no scrollbar  
            scr.style.overflow = ‘hidden’;  
          
            // Inner content div  
            inn = document.createElement(‘div’);  
            inn.style.width = ‘100%’;  
            inn.style.height = ‘200px’;  
          
            // Put the inner div in the scrolling div  
            scr.appendChild(inn);  
            // Append the scrolling div to the doc  
            document.body.appendChild(scr);  
          
            // Width of the inner div sans scrollbar  
            wNoScroll = inn.offsetWidth;  
          
            // Add the scrollbar  
            scr.style.overflow = ‘scroll’;  
            // Width of the inner div width scrollbar  
            wScroll = inn.offsetWidth;  
          
            // Remove the scrolling div from the doc  
            document.body.removeChild(document.body.lastChild);  
          
            // Pixel width of the scroller  
            OpenLayers.Util._scrollbarWidth = (wNoScroll – wScroll);  
            scrollbarWidth = OpenLayers.Util._scrollbarWidth;  
        }  
        return scrollbarWidth;  
    };  

转载自:https://blog.csdn.net/wangzhiyuande/article/details/7704061

You may also like...

退出移动版