全部源码如下:
var touY={
MollY:new Array(),
MollCZ:function(W){ //插值法求摩尔威特投影的y值,W在正负pi_2之前
var i,N=100,B=this.MollY, f=1;
if(W<0) W = -W, f=-1;
if(W>pi_2-1E-10) return f;
if(!B.length){ //创建插值表,当N为100时,精度为10^-7,在于80度的高度纬区精度降为10^-6,88度为10^-5
for(i=0;i<N;i++){
var y0=0, y=i/100, c=pi_2*sin(y*pi_2);
while(abs(y-y0)>1E-12){
y0 = y;
y += (c-asin(y))/sqrt(1-y*y);
y /= 2;
}
B[i]=y;
}
B[N]=1;
}
var n = W/pi_2*N, k = int2(n+0.5);
if(!k) k=1; if(k>=N) k=N-1;
n -= k;
var y2=B[k], a=y2-B[k-1], b=B[k+1]-y2;
return f*( y2 +n*( a+b + n*(b-a) )/2 );
},
toxy0:function(J,W,a){ //平面正投
J -= this.J0+pi_2; //图中的经度自西向东测量
var x=Math.cos(W)*Math.cos(J), y=Math.cos(W)*Math.sin(J), z=Math.sin(W);
a.x = x;
a.y = this.cosE0*y + this.sinE0*z;
a.z =-this.sinE0*y + this.cosE0*z;
},
toxy1:function(J,W,a){//斜轴等距方位投影
J -= this.J0;
var cosJ=Math.cos(J), sinJ=Math.sin(J);
var cosW=Math.cos(W), sinW=Math.sin(W);
var L = Math.atan2( this.sinE0*sinW - this.cosE0*cosW*cosJ, sinJ*cosW );
var B = Math.acos ( this.cosE0*sinW + this.sinE0*cosW*cosJ );
a.x = a.y = 0, a.z=-1;
if(B>Math.PI-0.1) return; //接近180度失真太大,不必计算
B = B/Math.PI;
a.x = B*cos(L), a.y = B*sin(L), a.z = 1;
},
toxy2:function(J,W,a){//斜轴等积方位投影
J -= this.J0;
var cosJ=Math.cos(J), sinJ=Math.sin(J);
var cosW=Math.cos(W), sinW=Math.sin(W);
var L = Math.atan2( this.sinE0*sinW - this.cosE0*cosW*cosJ, sinJ*cosW );
var B = Math.acos ( this.cosE0*sinW + this.sinE0*cosW*cosJ );
a.x = a.y = 0, a.z=-1;
if(B>Math.PI-0.1) return; //接近180度失真太大,不必计算
B = Math.sin(B/2);
a.x = B*cos(L), a.y = B*sin(L), a.z = 1;
},
toxy3:function(J,W,a){//斜轴等角方位投影
J -= this.J0;
var cosJ=Math.cos(J), sinJ=Math.sin(J);
var cosW=Math.cos(W), sinW=Math.sin(W);
var L = Math.atan2( this.sinE0*sinW - this.cosE0*cosW*cosJ, sinJ*cosW );
var B = Math.acos ( this.cosE0*sinW + this.sinE0*cosW*cosJ );
a.x = a.y = 0, a.z=-1;
if(B>Math.PI-1) return; //接近180度失真太大,不必计算
B = Math.tan(B/2);
a.x = B*Math.cos(L), a.y = B*Math.sin(L), a.z = 1;
},
toxy4:function(J,W,a){ //摩尔威特
W = rad2rrad(W);
J = rad2rrad(J-this.J0);
a.y = this.MollCZ(W);
a.x = Math.sqrt(1-a.y*a.y)*J*2/Math.PI;
a.z = 1;
},
toxy5:function(J,W,a){ //正轴等距圆柱
a.x=rad2rrad(J-this.J0)/Math.PI;
a.y=rad2rrad(W)/Math.PI;
a.z=1;
},
toxy6:function(J,W,a){ //正轴等角圆柱
if(abs(W)>1.5) { a.x=a.y=0, a.z=-1; return; }
var f = 1; if(W<0) f = -1;
a.x = rad2rrad(J-this.J0)/Math.PI;
a.y = Math.log( tan(pi2/8+abs(W)/2) ) / Math.PI*f;
a.z=1;
},
toxy7:function(J,W,a){ //多圆锥
J = rad2rrad(J-this.J0);
var C = Math.cos(W); //纬线长度
var v = Math.tan(W); //纬线曲率
if(abs(W)>0.002){
var s=C*J*v, l=1/v;
a.x = l*Math.sin(s);
a.y = W+l-l*Math.cos(s);
}
else a.x = J, a.y = W+J*J*v/2;
a.x/=Math.PI, a.y/=Math.PI, a.z=1;
},
toxy8:function(J,W,a){ //中国灯笼投影
J = rad2rrad(J-this.J0);
var C = Math.cos(W*2/3); //纬线长度
var v = Math.sin(W*2/3)/5.3; //纬线曲率
J *= (1-abs(J)/11/Math.PI)*1.1;
W = (W+0.014830286*W*W*W)*1.2;
if(Math.abs(W)>0.002){
var s=C*J*v, l=1/v;
a.x = l*Math.sin(s);
a.y = W+l-l*Math.cos(s);
}
else a.x = J, a.y = W+J*J*v/2;
a.x/=Math.PI, a.y/=Math.PI, a.z=1;
},
toxy:function(J,W,a){ a.x=J, a.y=W, a.z=1; },
setlx:function(lx,J0,W0,jb){//设置类型, jb为局部显示参数
this.tylx=lx, this.J0=J0, this.W0=W0;
this.cosE0=sin(W0), this.sinE0=cos(W0);
if(lx==0) this.toxy=this.toxy0;
if(lx==1) this.toxy=this.toxy1;
if(lx==2) this.toxy=this.toxy2;
if(lx==3) this.toxy=this.toxy3;
if(lx==4) this.toxy=this.toxy4;
if(lx==5) this.toxy=this.toxy5;
if(lx==6) this.toxy=this.toxy6;
if(lx==7) this.toxy=this.toxy7;
if(lx==8) this.toxy=this.toxy8;
this.x1=jb[0]-jb[2], this.x2=jb[0]+jb[2];
this.y1=jb[1]-jb[3], this.y2=jb[1]+jb[3];
},
lineArr:function(d){ //画曲线
var p=new Array(), k=0;
var i, h, G=new Object(); //h为线头标记
var lx, ly, dd=0; //某条线的最后一个画线点(lx,ly),dd为画线状态
if(d[0]!=1e7) h=1; //不以moveto开头的数组
for(i=0; i<d.length; i++){
if(d[i]==1e7) { h=1, dd=0; continue; } //新线开始,清除最后画点
this.toxy(d[i],d[i+1],G); i++; //在flash,这么写this.toxy(d[i++],d[i],G);不可正确运行
if(G.x<this.x1||G.x>this.x2||G.y<this.y1||G.y>this.y2) G.z=-1;
if(G.z<0) {//不显示的点
if(dd%2==1) dd=2;
continue;
}
if(dd%2==0) dd++, h=1;
if(this.tylx==4){ //摩氏地图投影
if(abs(lx-G.x)>1/3) h=1; //防止出现水平回扫线(地图被边界切割时会有此问题)
}
if(this.tylx==5||this.tylx==6){ //正轴等距或等角圆柱
if(abs(lx-G.x)>1/3||abs(ly-G.y)>1/3) h=1; //防止出现水平回扫线
}
if(this.tylx==7||this.tylx==8||this.tylx==9){ //多圆锥
var cy=abs(ly-G.y), cx=abs(lx-G.x);
if(cx>1/3 || abs(G.y)>1/2 && lx*G.x<0) h=1; //防止出现水平回扫线
}
if(h) p[k++]=1e7, h=0;
p[k++]=G.x, p[k++]=G.y;
lx=G.x, ly=G.y;
}
return p;
}
};