WGS-84テスト

by tepe
♥0 | Line 225 | Modified 2012-06-07 07:18:23 | MIT License
play

ActionScript3 source code

/**
 * Copyright tepe ( http://wonderfl.net/user/tepe )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/qxBx
 */

package {
    import flash.text.TextField;
    import flash.display.Sprite;
    import flash.geom.*;
    public class FlashTest extends Sprite {
        
        private var tf:TextField = new TextField();
        public function FlashTest() {
            // write as3 code here..
            var pos:Point = new Point(0,10);
            var pos2:Point = new Point(0,-10);
            var aa:WGS84 = new WGS84();
            addChild(tf);
            var obj:Object =  aa.dms_to_XYZ(pos.x,pos.y);
            tf.text = "x:"+Math.floor(obj.x) +"\ny:"+Math.floor(obj.y)+"\nz:"+Math.floor(obj.z);
            obj =  aa.dms_to_XYZ(pos2.x,pos2.y);
            tf.text += "\nx:"+Math.floor(obj.x) +"\ny:"+Math.floor(obj.y)+"\nz:"+Math.floor(obj.z);
        }
    }
}

//package{
//public
    class WGS84{
        private const a:Number =   6377397.155;       /* 東京測地系の楕円体の長半径*/
        private const a84:Number = 6378137.0;       /* wgs-84 の楕円体の長半径*/
        private const f84:Number = 0.0033528106647478;   /* 1/298.257223563 WGS-84 の偏平度*/
        private const f_tokyo:Number = 0.00334277318;    /* 1/299.152813 東京測地系の偏平度*/
        private const e2:Number = 0.006674372231; /*ベッセル楕円体の第1離心率*/
        private const e12:Number = 0.006719218798; /*ベッセル楕円体の第2離心率*/ 
        private const m0:Number = 0.9999; /*縮尺係数 */
        private const pi:Number = 3.141592653589793; /*円周率*/
        private const q:Number = 10000855.7658;
        /* coefficient for equation #1 */
        private var A_coef:Array = new Array(6366742.52024116306, -15988.6385238568588,
                                        16.7299538817284, -0.0217848007897, 0.0000307730631,
                                        -0.0000000453374, 0.0000000000685, -0.0000000000001);                                
        /* coefficient for equation #2 */
        private var B_coef:Array = new Array( -64.7467764, 217.0549893, -283.3714576, 210.1702756,
                                        -156.901395, -637.6283903, 8326.0282307, -39421.8126979,
                                         81936.0763069, 9950730.8889188);
        /* coefficient for equation #3 */
        private var C_coef:Array = new Array( -0.00000203933504, 0.00000254941046, 0.00001390414031,
                                        -0.00008117092029, 0.000372749204, -0.001796898478,
                                        0.006708984087, -0.01313066154, 1.578708908847);
        /* zone origin for latitude */
        private var B_origin:Array = new Array( 33, 33, 36, 33, 36, 36, 36, 36, 36, 40,
                                                  44, 44, 44, 26, 26, 26, 26);
        /* zone origin for longitude */
        private var L_origin:Array = new Array( 129.5, 131, 132.166666666667, 133.5, 134.333333333333,
                            136,137.166666666667, 138.5, 139.833333333333, 140.833333333333, 140.25,142.25, 144.25,
                            142, 127.5, 124, 131);
                            
        /*度分秒からラジアンへの変換 */
        public function make_radian(deg:int, min:int, sec:Number):Number{                      
            return(((sec/60+min)/60+deg)*pi/180);
        }
        
        /* ラジアンを度分秒へ変換 */
        public function rad_to_dms(rad:Number):Object{
            var d:int,m:int,sign:int;
            var sd:Number;
            sd = Math.abs(rad)*3600*180/pi;
            m = Math.floor(sd/60.0);
            sd = sd - (m*60.0);
            d = Math.floor(m/60.0);
            m = m - d * 60.0;
            if (rad < 0) sign = -1;
            else if (rad == 0) sign = 0;
            sign = +1.0;
            d = sign * d;

            var result:Object = new Object();
            result.deg = d;
            result.min = m;
            result.sec = sd;
            return result;
        }
        
        /* 東京測地系の緯度、経度を平面座標系に変換 */
        /*緯度を与えて赤道からの子午線弧長を求める、出典:精密測地網一次基準点作業規定 P55-56*/
        public function mx(f:Number):Number{
            var f2:Number,m:Number;
            m = A_coef[0]*f;
            for(var i:int = 1; i < 8; i++)m = m + A_coef[i]*Math.sin(f*2*i);
            return m;
        }
        
        /* 計算式の出典:精密測地網一次基準点作業規定 P55-56*/
        public function bl2xy(lat:Number,lon:Number,zone:int):Object{
            var x:Number,y:Number,c:Number;
            var cdeg:int, cmin:int;
            var f:Number, dl:Number, dx:Number, mx0:Number, csec:Number ;
            var et2:Number,w:Number,n:Number,m:Number,tn2:Number,x2:Number,x4:Number,
                x6:Number,x8:Number,y1:Number,y3:Number,y5:Number,y7:Number;
            var B0:Number,L0:Number;
            var sinb:Number, cosb:Number, tanb:Number;
            
            B0 = B_origin[zone] * Math.PI/180;/*原点の緯度*/
            L0 = L_origin[zone] * Math.PI/180;/*原点の経度*/
            dl = lon - L0;
            cosb = Math.cos(lat);
            sinb = Math.sin(lat);
            tanb = Math.tan(lat);
            f = B0;
            mx0 = mx(f);
            f = lat;
            dx = mx(f) - mx0; /*原点の緯度と球点の緯度を与えて、それぞれの赤道からの子午線からの距離の差を取る。 S-S0*/
            et2 = e12 * Math.pow(cosb,2);
            w = 1 - e2*Math.pow(sinb,2);
            n = a/Math.pow(w,0.5);
            m = n * (1-e2)/w;
            tn2 = Math.pow(tanb,2);
            x2 = n*Math.pow(cosb,2)*tanb*Math.pow(dl,2)/2;
            x4 = n*tanb*Math.pow(cosb,4)*(5-tn2+9*et2+4*Math.pow(et2,2))*Math.pow(dl,4)/24;
            x6 = n*tanb*Math.pow(cosb,6)*(61-58*tn2+Math.pow(tn2,2)+270*et2 - 330*tn2*et2)*Math.pow(dl,6)/720;
            x8 = n*tanb*Math.pow(cosb,8)*(1385-3111*tn2+543*Math.pow(tn2,2) - Math.pow(tn2,3))*Math.pow(dl,8)/40320;
            
            x = m0*(x8 + x6 + x4 + x2 + dx);
            y1 = n*cosb*dl;
            y3 = n*Math.pow(cosb,3)*(1-tn2+et2)*Math.pow(dl,3)/6;
            y5 = n*Math.pow(cosb,5)*(5-18*tn2+Math.pow(tn2,2)+14*et2-58*tn2*et2)*Math.pow(dl,5)/120;
            /* corrected sign symbols for y5, 1998.10.22 */
            y7 = n*Math.pow(cosb,7)*(61-479*tn2+179*Math.pow(tn2,2)-Math.pow(tn2,3))*Math.pow(dl,7)/5040;1
            y = m0*(y7 + y5 + y3 + y1);
            c = (sinb*dl+sinb*Math.pow(cosb,2)*(1+3*et2)*Math.pow(dl,3)/3);
            var result:Object = new Object();
            result.x = x;
            result.y = y;
            result.c = c;
            return result;
        }//function
        
        /* 平面座標系を東京測地系の緯度、経度に変換 */
        /*計算式、係数パラメータは山海堂出版、パーソナルコンピュータによる測量計算プログラムの第3章による*/
        public function mxy(f:Number):Number{
            var f2:Number,m:Number;
            f2 = Math.pow(f,2);
            m = B_coef[0];
            for(var i:int = 1; i < 10; i++)m = m*f2 + B_coef[i];
            return(m*f);
        }
        public function bm(m:Number):Number{
            var m2:Number,b:Number;
            m2 = Math.pow(m,2);
            b = C_coef[0];
            for (var i:int = 1;i < 9;i++)
                b = b*m2+C_coef[i];
            return(b*m);
        }
        
        public function xy2bl(XI:Number,YI:Number,zone:int):Object{
            //var B:Number,L:Number,c:Number;
            
            var x1:Number,y1:Number,B0:Number,L0:Number,f:Number,m:Number,b1:Number;
            var sinb:Number, cosb:Number, tanb:Number;
            var w:Number, n1:Number, m1:Number, et2:Number, tn2:Number, b2:Number, b4:Number, secb:Number;
            var l1:Number, l3:Number, l5:Number,secl:Number,dl:Number;
            x1 = XI/m0;
            y1 = YI/m0;
            B0 = B_origin[zone] * pi/180;
            L0 = L_origin[zone] * pi/180;
            f = 2*B0/pi;
            m = (mxy(f)+x1)/q;
            b1 = bm(m);
            sinb = Math.sin(b1);
            cosb = Math.cos(b1);
            tanb = Math.tan(b1);
            w = 1-e2*Math.pow(sinb,2);
            n1 = a/Math.pow(w,0.5);
            m1 = n1*(1-e2)/w;
            et2 = e12*cosb;
            tn2 = Math.pow(tanb,2);
            b2 = tanb*Math.pow(y1,2)/(2*m1*n1);
            b4 = tanb*(5+3*tn2+et2-9*et2*tn2-4*Math.pow(et2,2))*Math.pow(y1,4)/(24*m1*Math.pow(n1,3));
            
            var result:Object = new Object();
            
            result.B = b4-b2+b1;
            l1 = y1/(n1*cosb);
            l3 = (1+2*tn2+et2)*Math.pow(y1,3)/(6*Math.pow(n1,3)*cosb);
            l5 = (5+28*tn2+24*Math.pow(tn2,2))*Math.pow(y1,5)/(120*Math.pow(n1,5)*cosb);
            dl = l5-l3+l1;
            
            result.L = L0+ dl;
            
            result.c = tanb*y1/n1-tanb*(1+tn2-et2)*Math.pow(y1,3)/(3*Math.pow(n1,3))+tanb*(1+tn2) * (2+3*tn2)*Math.pow(y1,5)/(15*Math.pow(n1,5));
            
            return result;            
        }
        
        /*緯度、経度、楕円体高を三次元直交座標系に変換*/
        public function dms_to_XYZ(lat:Number,lon:Number,height:Number=0,datum:int=1):Object{
            //var X:Number,Y:Number,Z:Number;
            var e_square:Number,N:Number,f:Number,adms:Number;
            switch(datum){
            case 1: /* wgs-84 */
                adms = a84;
                f = f84;
                break;
            case 2: /* tokyo datum */
                adms = a;
                f = f_tokyo;
                break;
            }
            e_square = f*(2-f);
            N = adms / Math.sqrt(1-e_square * Math.sin(lat) * Math.sin(lat));
            var result:Object = new Object();
            result.x = (N+height)*Math.cos(lat)*Math.cos(lon);
            result.y = (N+height)*Math.cos(lat)*Math.sin(lon);
            result.z = (N*(1-e_square)+height)*Math.sin(lat);
            return result;
        }

        /*三次元直交座標系から緯度、経度、楕円体高に変換*/
        public function XYZ_to_dms(X:Number,Y:Number,Z:Number=0,datum:int=1):Object{
            //var lat:Number,lon:Number,height:Number;
            var b_dash:Number,P:Number,theta:Number,E_square:Number,E_square_dash:Number,
                neu:Number,f:Number,adms:Number;
            
            switch(datum){
            case 1: /* wgs-84 */
                adms = a84;
                f = f84;
                break;
            case 2: /* tokyo datum */
                adms = a;
                f = f_tokyo;
                break;
            }
            b_dash = adms*(1-f);
            P = Math.sqrt(X*X + Y*Y);
            theta = Math.atan((Z*adms)/(P*b_dash));
            E_square = (adms*adms - b_dash*b_dash)/(adms*adms);
            E_square_dash = (adms*adms - b_dash*b_dash)/(b_dash*b_dash);
            
            var result:Object = new Object();
            result.lat = Math.atan((Z+E_square_dash*b_dash*Math.sin(theta)*Math.sin(theta)*Math.sin(theta))/
                                                (P-E_square*adms*Math.cos(theta)*Math.cos(theta)*Math.cos(theta)));
            
            result.lon =  Math.atan(Y/X) +pi;
            neu = adms/Math.sqrt(1-E_square*Math.sin(result.lat)*Math.sin(result.lat));
            
            result.height = P/Math.cos(result.lat)-neu;
            return result;
        }
        
        /*3 パラメータ変換、新、旧パラメータの選択に注意*/
        public function WGS84_to_Tokyo(X:Number,Y:Number,Z:Number):Object{
            var x:Number,y:Number,z:Number;
            x = X;
            y = Y;
            z = Z;
            var result:Object = new Object();
            result.X = x + 146.43;//(147.54)
            result.Y = y - 507.89;//(507.26)
            result.Z = z - 681.46;//(680.47) ()内は新パラメータ
            return result;
        }
        public function Tokyo_to_84(X:Number,Y:Number,Z:Number):Object{
            var x:Number,y:Number,z:Number;
            x = X;
            y = Y;
            z = Z;
            var result:Object = new Object();
            result.X = x - 146.43;//(147.54)
            result.Y = y + 507.89;//(507.26)
            result.Z = z + 681.46;//(680.47) ()内は新パラメータ
            return result;
        }
    
    }//class
//}//package