OpenLayers学习5-工具类Util_2 Posted on 2015-02-01 | In OpenLayers学习 | 一: 鼠标操作123456789101112131415161718192021222324252627//判断div是不是触发evt对象的根对象(最父级对象)//这个和事件关系比较紧密, 还不知道为什么这么处理...OpenLayers.Util.mouseLeft = function (evt, div) { //兼容IE, 获得事件源 var target = (evt.relatedTarget) ? evt.relatedTarget : evt.toElement; //直到追溯至根节点 while (target != div && target != null) { target = target.parentNode; } //如果div是根对象, 返回true return (target != div);}; //浮点精度OpenLayers.Util.DEFAULT_PRECISION = 14;//把对象转成浮点型OpenLayers.Util.toFloat = function (number, precision) { if (precision == null) { precision = OpenLayers.Util.DEFAULT_PRECISION;//默认精度 } //本来就是"number"型, 直接parseFloat if (typeof number !== "number") { number = parseFloat(number); } return precision === 0 ? number : //精度0 parseFloat(number.toPrecision(precision));//指数形式}; 二: 距离计算123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102//计算两点距离//角度转弧度OpenLayers.Util.rad = function(x) {return x*Math.PI/180;};//弧度转角度OpenLayers.Util.deg = function(x) {return x*180/Math.PI;};//a:长半轴, b短半轴, c扁率OpenLayers.Util.VincentyConstants = { a: 6378137, b: 6356752.3142, f: 1/298.257223563};//计算两点距离//提供两个带lat和lon的对象, 计算出以km为单位的距离//计算公式完全看不懂...OpenLayers.Util.distVincenty = function(p1, p2) { var ct = OpenLayers.Util.VincentyConstants; var a = ct.a, b = ct.b, f = ct.f; 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;}; //计算出经纬度(给定经纬度, 角度, 距离)//公式看不懂OpenLayers.Util.destinationVincenty = function(lonlat, brng, dist) { var u = OpenLayers.Util; var ct = u.VincentyConstants; var a = ct.a, b = ct.b, f = ct.f; var lon1 = lonlat.lon; var lat1 = lonlat.lat; var s = dist; var alpha1 = u.rad(brng); var sinAlpha1 = Math.sin(alpha1); var cosAlpha1 = Math.cos(alpha1); var tanU1 = (1-f) * Math.tan(u.rad(lat1)); var cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1*cosU1; var sigma1 = Math.atan2(tanU1, cosAlpha1); var sinAlpha = cosU1 * sinAlpha1; var cosSqAlpha = 1 - sinAlpha*sinAlpha; 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 sigma = s / (b*A), sigmaP = 2*Math.PI; while (Math.abs(sigma-sigmaP) > 1e-12) { var cos2SigmaM = Math.cos(2*sigma1 + sigma); var sinSigma = Math.sin(sigma); var cosSigma = Math.cos(sigma); var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)- B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM))); sigmaP = sigma; sigma = s / (b*A) + deltaSigma; } var tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1; var lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1, (1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp)); var lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1); var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha)); var L = lambda - (1-C) * f * sinAlpha * (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM))); var revAz = Math.atan2(sinAlpha, -tmp); // final bearing return new OpenLayers.LonLat(lon1+u.deg(L), u.deg(lat2));}; 三: URL操作123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869//从URL里解析参数, 参数里有逗号的话会写入数组//第二个参数options, 若true表示把含逗号的参数写入数组, 默认trueOpenLayers.Util.getParameters = function(url, options) { options = options || {}; //优先用传入的url, 否则用location.href url = (url === null || url === undefined) ? window.location.href : url; 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('=');//每个部分按"="切分 //若有key if (keyValue[0]) { var key = keyValue[0]; //对key解码 try { key = decodeURIComponent(key); } catch (err) { key = unescape(key); } //val里"+"替换成空格 var value = (keyValue[1] || '').replace(/\+/g, " "); //对val解码 try { value = decodeURIComponent(value); } catch (err) { value = unescape(value); } //有些OGC的参数里带"," 按逗号切分 if (options.splitArgs !== false) { value = value.split(","); } //要是没逗号, 就不写入数组 if (value.length == 1) { value = value[0]; } parameters[key] = value;//写入对象 } } return parameters;}; //自增id的记录OpenLayers.Util.lastSeqID = 0;//根据前缀,生成"前缀_自增id"OpenLayers.Util.createUniqueID = function(prefix) { if (prefix == null) { prefix = "id_"; } else { prefix = prefix.replace(OpenLayers.Util.dotless, "_");//把"."换成"_" } OpenLayers.Util.lastSeqID += 1; //自增 return prefix + OpenLayers.Util.lastSeqID; }; 四: 比例尺相关的计算123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657//Scale = 图上距离/实地距离 , Resolution = 一像素代表多少地图单位 //单位对象配置//相对来说是动态的配置对象, 比我之前在init函数里计算的思路要好OpenLayers.INCHES_PER_UNIT = { 'inches': 1.0, 'ft': 12.0, 'mi': 63360.0, 'm': 39.37, 'km': 39370, '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;//动态的配置 OpenLayers.METERS_PER_INCH = 0.02540005080010160020;OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT, { "Meter": 1.0 / OpenLayers.METERS_PER_INCH, //EPSG:9001 "Foot": 0.30480060960121920243 / OpenLayers.METERS_PER_INCH, //EPSG:9003 ... //DPI的默认值OpenLayers.DOTS_PER_INCH = 72;//比例尺计算, //已经是分数形式的( 1.0) ? (1.0 / scale) : scale; return normScale;}; //由Scale计算出Resolution, 默认单位是"degrees"OpenLayers.Util.getResolutionFromScale = function (scale, units) { var resolution; if (scale) { if (units == null) { units = "degrees"; } var normScale = OpenLayers.Util.normalizeScale(scale); resolution = 1 / (normScale * OpenLayers.INCHES_PER_UNIT[units] * OpenLayers.DOTS_PER_INCH); } return resolution;};//由Resolution计算对应的Scale, 默认单位是"degrees"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;};