您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
技术交流群:665060698
proj4是一个非常有用的坐标转换类库,有各种语言版本的,C++,java,js,python版等,可以很方便的将坐标从一个坐标系转换到另一个
坐标系。
在网页端使用的时候,转换大量的坐标时,发现存在性能有问题,就查看了一下proj4js的源代码,发现初始化很多不相关的类型,对象等,
基于现有的项目,就进行相关代码的提取,以下是提取的兰伯特和经纬度坐标的转换,简略代码说明如下:
//初始化常用的变量,直接换算成弧度,提升计算性能 var EPSLN = (typeof Number.EPSILON === 'undefined') ? 1.0e-10 : Number.EPSILON; var conv = 180 / Math.PI; var HALF_PI = Math.PI / 2; var SPI = 3.14159265359; var TWO_PI = 2 * Math.PI; var a = 6378137; var b = 6356752.314245179; var e = 0.08181919084262157; var lat1 = 0.52359877559829; var lat2 = 1.04719755119659; var long0 = 1.8029251173101; var lat0 = 0; var k0 = 1; var ns; var f0; var rh; //常用的转换参数,直接提取引用 var tsfnz = function(eccent, phi, sinphi) { var con = eccent * sinphi; var com = 0.5 * eccent; con = Math.pow(((1 - con) / (1 + con)), com); return(Math.tan(0.5 * (HALF_PI - phi)) / con); }; var sign = function(x) { return x < 0 ? -1 : 1; }; var msfnz = function(eccent, sinphi, cosphi) { var con = eccent * sinphi; return cosphi / (Math.sqrt(1 - con * con)); }; var adjust_lon = function(x) { return(Math.abs(x) <= SPI) ? x : (x - (sign(x) * TWO_PI)); }; var phi2z = function(eccent, ts) { var eccnth = 0.5 * eccent; var con, dphi; var phi = HALF_PI - 2 * Math.atan(ts); for(var i = 0; i <= 15; i++) { con = eccent * Math.sin(phi); dphi = HALF_PI - 2 * Math.atan(ts * (Math.pow(((1 - con) / (1 + con)), eccnth))) - phi; phi += dphi; if(Math.abs(dphi) <= 0.0000000001) { return phi; } } //console.log("phi2z has NoConvergence"); return -9999; }; //根据proj4的坐标系描述字符串,解析其中的参数 function init(prjstr) { if(prjstr.indexOf(" ") > -1) { var _prjArr = prjstr.split(" "); _prjArr.forEach(function(item, index, input) { if(item.indexOf("lat_0") > -1) { lat0 = parseFloat(item.split("=")[1]) / conv; } }) } var sin1 = Math.sin(lat1); var cos1 = Math.cos(lat1); var ms1 = msfnz(e, sin1, cos1); var ts1 = tsfnz(e, lat1, sin1); var sin2 = Math.sin(lat2); var cos2 = Math.cos(lat2); var ms2 = msfnz(e, sin2, cos2); var ts2 = tsfnz(e, lat2, sin2); var ts0 = tsfnz(e, lat0, Math.sin(lat0)); if(Math.abs(lat1 - lat2) > EPSLN) { ns = Math.log(ms1 / ms2) / Math.log(ts1 / ts2); } else { ns = sin1; } if(isNaN(ns)) { ns = sin1; } f0 = ms1 / (ns * Math.pow(ts1, ns)); rh = a * f0 * Math.pow(ts0, ns); } //经纬度坐标转兰伯特坐标 function projCood(lon, lat) { lon = lon / conv; lat = lat / conv; if(Math.abs(2 * Math.abs(lat) - Math.PI) <= EPSLN) { lat = sign(lat) * (HALF_PI - 2 * EPSLN); } var con = Math.abs(Math.abs(lat) - HALF_PI); var ts, rh2; if(con > EPSLN) { ts = tsfnz(e, lat, Math.sin(lat)); rh2 = a * f0 * Math.pow(ts, ns); } else { con = lat * ns; if(con <= 0) { return null; } rh2 = 0; } var theta = ns * adjust_lon(lon - long0); var nlon = (rh2 * Math.sin(theta)); var nlat = (rh - rh2 * Math.cos(theta)); return [nlon, nlat]; } //兰伯特坐标转经纬度坐标 function inverseProj(x1, y1) { var rh2, con, ts; var lat, lon; var x = x1 / k0; var y = (rh - y1 / k0); if(ns > 0) { rh2 = Math.sqrt(x * x + y * y); con = 1; } else { rh2 = -Math.sqrt(x * x + y * y); con = -1; } var theta = 0; if(rh2 !== 0) { theta = Math.atan2((con * x), (con * y)); } if((rh2 !== 0) || (ns > 0)) { con = 1 / ns; ts = Math.pow((rh2 / (a * f0)), con); lat = phi2z(e, ts); if(lat === -9999) { return null; } } else { lat = -HALF_PI; } lon = adjust_lon(theta / ns + long0); return [lon * conv, conv * lat]; }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。