大地坐标转大地空间直角坐标,经纬度计算距离,源代码如下:

源代码下载地址:


// CoordinateTransformationDlg.cpp : 实现文件
 //#include "stdafx.h"
 #include "CoordinateTransformation.h"
 #include "CoordinateTransformationDlg.h"
 #include "afxdialogex.h"
 #include <math.h>
 #include <iostream>
 using namespace std;#ifdef _DEBUG
 #define new DEBUG_NEW
 #endif // 数学符号pi
 #ifndef PI
 #define PI 3.1415926535897932384626433832795
 #endif
 // 数学符号pi
 #ifndef EARTH_RADIUS
 #define EARTH_RADIUS 6378137.0
 #endif
 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx
 {
 public:
     CAboutDlg();// 对话框数据
     enum { IDD = IDD_ABOUTBOX };    protected:
     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现
 protected:
     DECLARE_MESSAGE_MAP()
 };CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
 {
 }void CAboutDlg::DoDataExchange(CDataExchange* pDX)
 {
     CDialogEx::DoDataExchange(pDX);
 }BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
 END_MESSAGE_MAP() // CCoordinateTransformationDlg 对话框
 #define PI 3.1415926535897323
double a,b,c,e2,ep2;
 CCoordinateTransformationDlg::CCoordinateTransformationDlg(CWnd* pParent /*=NULL*/)
     : CDialogEx(CCoordinateTransformationDlg::IDD, pParent)
     , m_dflon(0)
     , m_dfLat(0)
     , m_dfMaxAxis(6378137)
     , m_dfMinAxis(6356752.3142)
     , m_dfCanxinX(0)
     , m_dfCanxinY(0)
     , m_dfCanxinZ(0)
     , m_dfPingmianRoteAngle(105.6)
     , m_dfCanxinPMRoteX(0)
     , m_dfCanxinPMRoteZ(0)
     , m_dfCanxinPMRoteY(0)
     , m_dfAngle(0)
     , m_dfMinite(0)
     , m_dfSeconde(0)
     , m_dfBL(0)
     , m_dfTuoqiuGao(0)
     , m_dfP1Longitude(0)
     , m_dfP2Longitude(0)
     , m_dfP1Latitude(0)
     , m_dfP2Latitude(0)
     , m_dfP1P2Distance(0)
 {
     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 }void CCoordinateTransformationDlg::DoDataExchange(CDataExchange* pDX)
 {
     CDialogEx::DoDataExchange(pDX);
     DDX_Text(pDX, IDC_EDIT1_LONTITUDE, m_dflon);
     DDX_Text(pDX, IDC_EDIT2_LATITUDE, m_dfLat);
     DDX_Text(pDX, IDC_EDIT3_MAJORSEMIAXIS, m_dfMaxAxis);
     DDX_Text(pDX, IDC_EDIT4_SEMI_MINOR_AXIS, m_dfMinAxis);
     DDX_Text(pDX, IDC_EDIT5_CANXIN_X, m_dfCanxinX);
     DDX_Text(pDX, IDC_EDIT6_CANXIN_Y, m_dfCanxinY);
     DDX_Text(pDX, IDC_EDIT7_CANXIN_Z, m_dfCanxinZ);
     DDX_Text(pDX, IDC_EDIT8_PINGMIAN_MOVE_ANGLE, m_dfPingmianRoteAngle);
     DDX_Text(pDX, IDC_EDIT9_PINGMIANMOVE_CANXIN_X, m_dfCanxinPMRoteX);
     DDX_Text(pDX, IDC_EDIT10_PINGMIAN_MOVE_CANXINZ, m_dfCanxinPMRoteZ);
     DDX_Text(pDX, IDC_EDIT11_PINGMIAN_MOVE_CANXINY, m_dfCanxinPMRoteY);
     DDX_Text(pDX, IDC_EDIT12_DU, m_dfAngle);
     DDX_Text(pDX, IDC_EDIT13_FEN, m_dfMinite);
     DDX_Text(pDX, IDC_EDIT14_MIAO, m_dfSeconde);
     DDX_Text(pDX, IDC_EDIT15_NEW_DU, m_dfBL);
     DDX_Text(pDX, IDC_EDIT16_TUOQIU_GAO, m_dfTuoqiuGao);
     DDX_Control(pDX, IDC_COMBO1_TUOQIU_NAME, m_ComboTuoQiuName);
     DDX_Text(pDX, IDC_EDIT1_POINT1_LONG, m_dfP1Longitude);
     DDX_Text(pDX, IDC_EDIT3_POINT2_LONG, m_dfP2Longitude);
     DDX_Text(pDX, IDC_EDIT2_POINT1_LAT, m_dfP1Latitude);
     DDX_Text(pDX, IDC_EDIT4_POINT2_LAT, m_dfP2Latitude);
     DDX_Text(pDX, IDC_EDIT5_LATLONG_DISTANCE, m_dfP1P2Distance);
 }BEGIN_MESSAGE_MAP(CCoordinateTransformationDlg, CDialogEx)
     ON_WM_SYSCOMMAND()
     ON_WM_PAINT()
     ON_WM_QUERYDRAGICON()
     ON_BN_CLICKED(IDC_BUTTON1_BL_TO_CANXIN_XYZ, &CCoordinateTransformationDlg::OnBnClickedButton1BlToCanxinXyz)
     ON_BN_CLICKED(IDC_BUTTON2_CANXIN_XYZ_TO_CANXIN_PINGMIANMOVE_XYZ, &CCoordinateTransformationDlg::OnBnClickedButton2CanxinXyzToCanxinPingmianmoveXyz)
     ON_BN_CLICKED(IDC_BUTTON3_DUFENMIAO_TO_DU, &CCoordinateTransformationDlg::OnBnClickedButton3DufenmiaoToDu)
     ON_BN_CLICKED(IDC_BUTTON4_DU_TO_DUFENMIAO, &CCoordinateTransformationDlg::OnBnClickedButton4DuToDufenmiao)
     ON_CBN_SELCHANGE(IDC_COMBO1_TUOQIU_NAME, &CCoordinateTransformationDlg::OnCbnSelchangeCombo1TuoqiuName)
     ON_BN_CLICKED(IDC_BUTTON1_COMPUTE_LATLONG_DISTAND, &CCoordinateTransformationDlg::OnBnClickedButton1ComputeLatlongDistand)
     ON_BN_CLICKED(IDC_BTN_XYZ_TO_BL, &CCoordinateTransformationDlg::OnBnClickedBtnXyzToBl)
 END_MESSAGE_MAP() // CCoordinateTransformationDlg 消息处理程序
BOOL CCoordinateTransformationDlg::OnInitDialog()
 {
     CDialogEx::OnInitDialog();    // 将“关于...”菜单项添加到系统菜单中。
    // IDM_ABOUTBOX 必须在系统命令范围内。
     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
     ASSERT(IDM_ABOUTBOX < 0xF000);    CMenu* pSysMenu = GetSystemMenu(FALSE);
     if (pSysMenu != NULL)
     {
         BOOL bNameValid;
         CString strAboutMenu;
         bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
         ASSERT(bNameValid);
         if (!strAboutMenu.IsEmpty())
         {
             pSysMenu->AppendMenu(MF_SEPARATOR);
             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
         }
     }    // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
     //  执行此操作
     SetIcon(m_hIcon, TRUE);            // 设置大图标
     SetIcon(m_hIcon, FALSE);        // 设置小图标    // TODO: 在此添加额外的初始化代码
 //     printf("请选择椭球参数(输入椭球序号):\n");
 //     printf("1.克拉索夫斯基椭球参数\n");
 //     printf("2.IUGG_1975椭球参数\n");
 //     printf("3.CGCS_2000椭球参数\n");
 //     printf("0.其他椭球参数(自行输入)\n");
 //     scanf("%d",&n);    m_ComboTuoQiuName.AddString(_T("WGS84 椭球"));
     m_ComboTuoQiuName.AddString(_T("克拉索夫斯基椭球"));
     m_ComboTuoQiuName.AddString(_T("IUGG_1975椭球"));
     m_ComboTuoQiuName.AddString(_T("CGCS_2000椭球"));
     m_ComboTuoQiuName.AddString(_T("其他椭球参数(自行输入)"));
     m_ComboTuoQiuName.SetCurSel(0);    CWnd* wnd = GetDlgItem(IDC_EDIT3_MAJORSEMIAXIS);
     wnd->EnableWindow(FALSE);
     wnd = GetDlgItem(IDC_EDIT4_SEMI_MINOR_AXIS);
     wnd->EnableWindow(FALSE);
     int n = m_ComboTuoQiuName.GetCurSel();
     switch(n)
     {
     case 0:
         {
             a=6378137;b=6356752.3142;
             c=a*a/b;
             ep2=(a*a-b*b)/(b*b);
             e2=(a*a-b*b)/(a*a);
             break;
         }
     case 1:
         {
             a=6378245.0;b=6356863.0188;c=6399698.9018;e2=0.00669342162297;ep2=0.00673852541468;break;
         }
     case 2:a=6378140.0;b=6356755.2882;c=6399596.6520;e2=0.00669438499959;ep2=0.00673950181947;break;
     case 3:a=6378137.0;b=6356752.3141;c=6399593.6259;e2=0.00669438002290;ep2=0.00673949677547;break;
     default:
         break;
     }
     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
 }void CCoordinateTransformationDlg::OnSysCommand(UINT nID, LPARAM lParam)
 {
     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
     {
         CAboutDlg dlgAbout;
         dlgAbout.DoModal();
     }
     else
     {
         CDialogEx::OnSysCommand(nID, lParam);
     }
 }// 如果向对话框添加最小化按钮,则需要下面的代码
 //  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
 //  这将由框架自动完成。void CCoordinateTransformationDlg::OnPaint()
 {
     if (IsIconic())
     {
         CPaintDC dc(this); // 用于绘制的设备上下文        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
        // 使图标在工作区矩形中居中
         int cxIcon = GetSystemMetrics(SM_CXICON);
         int cyIcon = GetSystemMetrics(SM_CYICON);
         CRect rect;
         GetClientRect(&rect);
         int x = (rect.Width() - cxIcon + 1) / 2;
         int y = (rect.Height() - cyIcon + 1) / 2;        // 绘制图标
         dc.DrawIcon(x, y, m_hIcon);
     }
     else
     {
         CDialogEx::OnPaint();
     }
 }//当用户拖动最小化窗口时系统调用此函数取得光标
 //显示。
 HCURSOR CCoordinateTransformationDlg::OnQueryDragIcon()
 {
     return static_cast<HCURSOR>(m_hIcon);
 }double RAD(double d,double f,double m)
 {
     double e;
     double sign=(d<0.0)?-1.0:1.0;
     if(d==0)
     {
         sign=(f<0.0)?-1.0:1.0;
         if(f==0)
         {
             sign=(m<0.0)?-1.0:1.0;
         }
     }
     if(d<0)
         d=d*(-1.0);
     if(f<0)
         f=f*(-1.0);
     if(m<0)
         m=m*(-1.0);    e=sign*(d*3600+f*60+m)*PI/(3600*180);
     return e;
 }
 double RAD(double du)
 {    double d = int(du);
     double dfTmp = du - d;
     double dfMiniteTmp = (dfTmp * 60);
     double f = (int) dfMiniteTmp;
     double m = (dfMiniteTmp - f)*60;    double e;
     double sign=(d<0.0)?-1.0:1.0;
     if(d==0)
     {
         sign=(f<0.0)?-1.0:1.0;
         if(f==0)
         {
             sign=(m<0.0)?-1.0:1.0;
         }
     }
     if(d<0)
         d=d*(-1.0);
     if(f<0)
         f=f*(-1.0);
     if(m<0)
         m=m*(-1.0);    e=sign*(d*3600+f*60+m)*PI/(3600*180);
     return e;
 }
 void RBD(double hd)
 {
     int t;
     int d,f;
     double m;
     double sign=(hd<0.0)?-1.0:1.0;
     if(hd<0)
         hd=fabs(hd);
     hd=hd*3600*180/PI;
     t=int(hd/3600);
     d=sign*t;
     hd=hd-t*3600;
     f=int(hd/60);
     m=hd-f*60;
     //printf("%d'%d'%lf'\n",d,f,m);
 }
 void BLH_XYZ()
 {
     double B,L,H,N,W;
     double d,f,m;
     double X,Y,Z;
     printf("   请输入大地坐标(输入格式为角度(例如:30'40'50')):\n");
     printf("    大地经度 L=");
     scanf("%lf'%lf'%lf'",&d,&f,&m);
     L=RAD(d,f,m);
     printf("    大地纬度 B=");
     scanf("%lf'%lf'%lf'",&d,&f,&m);
     B=RAD(d,f,m);
     printf("    大地高   H=");
     scanf("%lf",&H);    W=sqrt(1-e2*sin(B)*sin(B));
     N=a/W;
     X=(N+H)*cos(B)*cos(L);
     Y=(N+H)*cos(B)*sin(L);
     Z=(N*(1-e2)+H)*sin(B);    printf("\n\n     转换后得到大地空间直角坐标为:\n\n");
     printf("X=%lf\nY=%lf\nZ=%lf\n\n",X,Y,Z);
 }
 void XYZ_BLH()
 {
     double B,L,H,N,W;
     double X,Y,Z;
     double tgB0,tgB1;    printf("    请输入大地空间直角坐标:\n");
     printf("    X=");
     scanf("%lf",&X);
     printf("    Y=");
     scanf("%lf",&Y);
     printf("    Z=");
     scanf("%lf",&Z);    printf("\n\n   转换后得到大地坐标为:\n\n");
     L=atan(Y/X);
     printf("    大地经度为: L=");
     RBD(L);
     printf("\n");    tgB0=Z/sqrt(X*X+Y*Y);
     tgB1=(1/sqrt(X*X+Y*Y))*(Z+a*e2*tgB0/sqrt(1+tgB0*tgB0-e2*tgB0*tgB0));    while(fabs(tgB0-tgB1)>5*pow(10.0,-10))
     {
         tgB0=tgB1;
         tgB1=(1/sqrt(X*X+Y*Y))*(Z+a*e2*tgB0/sqrt(1+tgB0*tgB0-e2*tgB0*tgB0));
     }
     B=atan(tgB1);
     printf("    大地纬度为:B=");
     RBD(B);
     printf("\n");
     W=sqrt(1-e2*sin(B)*sin(B));
     N=a/W;
     H=sqrt(X*X+Y*Y)/cos(B)-N;
     printf("    大地高为:H=%lf\n\n",H);
 }
 void B_ZS()
 {
     double L1,B1,A1,s,d,f,mi;
     double u1,u2,m,M,k2,alfa,bt,r,kp2,alfap,btp,rp;
     double sgm0,sgm1,lmd,lmd1,lmd2,A2,B2,l,L2;    printf("请输入已知点的大地坐标(输入格式为角度(例如:30'40'50'),下同):\nL1=");
     scanf("%lf'%lf'%lf'",&d,&f,&mi);
     L1=RAD(d,f,mi);
     printf("\nB1=");
     scanf("%lf'%lf'%lf'",&d,&f,&mi);
     B1=RAD(d,f,mi);
     printf("请输入大地方位角:\nA1=");
     scanf("%lf'%lf'%lf'",&d,&f,&mi);
     A1=RAD(d,f,mi);
     printf("请输入该点至另一点的大地线长:\ns=");
     scanf("%lf",&s);        u1=atan(sqrt(1-e2)*tan(B1));
     m=asin(cos(u1)*sin(A1));
     M=atan(tan(u1)/cos(A1));
     m=(m>0)?m:m+2*PI;
     M=(M>0)?M:M+PI;
     k2=ep2*cos(m)*cos(m);
     alfa=(1-k2/4+7*k2*k2/64-15*k2*k2*k2/256)/b;
     bt=k2/4-k2*k2/8+37*k2*k2*k2/512;
     r=k2*k2/128-k2*k2*k2/128;    sgm0=alfa*s;
     sgm1=alfa*s+bt*sin(sgm0)*cos(2*M+sgm0)+r*sin(2*sgm0)*cos(4*M+2*sgm0);
     while(fabs(sgm0-sgm1)>2.8*PI/180*pow(10.0,-7))
     {
         sgm0=sgm1;
         sgm1=alfa*s+bt*sin(sgm0)*cos(2*M+sgm0)+r*sin(2*sgm0)*cos(4*M+2*sgm0);
     }
     sgm0=sgm1;     A2=atan(tan(m)/cos(M+sgm0));
     A2=(A2>0)?A2:A2+PI;
     A2=(A1>PI)?A2:A2+PI;
     u2=atan(-cos(A2)*tan(M+sgm0));
     lmd1=atan(sin(u1)*tan(A1));
     lmd1=(lmd1>0)?lmd1:lmd1+PI;
     lmd1=(m<PI)?lmd1:lmd1+PI;
     lmd2=atan(sin(u2)*tan(A2));
     lmd2=(lmd2>0)?lmd2:lmd2+PI;
     lmd2=(m<PI)?(((M+sgm0)<PI)?lmd2:lmd2+PI):(((M+sgm0)>PI)?lmd2:lmd2+PI);
     lmd=lmd2-lmd1;
     B2=atan(sqrt(1+ep2)*tan(u2));    kp2=e2*cos(m)*cos(m);
     alfap=(e2/2+e2*e2/8+e2*e2*e2/16)-e2/16*(1+e2)*kp2+3*e2*kp2*kp2/128;
     btp=e2*(1+e2)*kp2/16-e2*kp2*kp2/32;
     rp=e2*kp2*kp2/256;    l=lmd-sin(m)*(alfap*sgm0+btp*sin(sgm0)*cos(2*M+sgm0)+rp*sin(2*sgm0)*cos(4*M+2*sgm0));
     L2=L1+l;    printf("\n\n得到另一点的大地坐标和大地线在该点的大地方位角为:\n\n");
     printf("L2=");
     RBD(L2);printf("\n");
     printf("B2=");
     RBD(B2);printf("\n");
     printf("A2=");
     RBD(A2);
     printf("\n");
 }
 void B_FS()
 {
     double L1,B1,L2,B2,s,A1,A2,du,f,mi,m0,m,M;
     double l,u1,u2,alfa,bt,r,lmd0,dit_lmd,lmd,sgm,dit_sgm,sgm0,sgm1,alfap,btp,rp,k2,kp2;    printf("请输入第一个点大地坐标(输入格式为角度(例如:30'40'50'),下同):\n大地经度 L1=");
     scanf("%lf'%lf'%lf'",&du,&f,&mi);
     L1=RAD(du,f,mi);
     printf("大地纬度 B1=");
     scanf("%lf'%lf'%lf'",&du,&f,&mi);
     B1=RAD(du,f,mi);
     printf("\n请输入第二个点大地坐标:\n大地经度:L2=");
     scanf("%lf'%lf'%lf'",&du,&f,&mi);
     L2=RAD(du,f,mi);
     printf("大地纬度:B2=");
     scanf("%lf'%lf'%lf'",&du,&f,&mi);
     B2=RAD(du,f,mi);    l=L2-L1;
     u1=atan(sqrt(1-e2)*tan(B1));
     u2=atan(sqrt(1-e2)*tan(B2));
     sgm0=acos(sin(u1)*sin(u2)+cos(u1)*cos(u2)*cos(l));
     m0=asin(cos(u1)*cos(u2)*sin(l)/sin(sgm0));
     dit_lmd=0.003351831*sgm0*sin(m0);
     lmd0=l+dit_lmd;
     dit_sgm=sin(m0)*dit_lmd;
     sgm1=sgm0+dit_sgm;
     m=asin(cos(u1)*cos(u2)*sin(lmd0)/sin(sgm1));
     A1=atan(sin(lmd0)/(cos(u1)*tan(u2)-sin(u1)*cos(lmd0)));
     A1=(A1>0)?A1:A1+PI;
     A1=(m>0)?A1:A1+PI;    M=atan(sin(u1)*tan(A1)/sin(m));
     M=(M>0)?M:M+PI;
     k2=ep2*cos(m)*cos(m);
     alfa=(1-k2/4+7*k2*k2/64-15*k2*k2*k2/256)/b;
     bt=k2/4-k2*k2/8+37*k2*k2*k2/512;
     r=k2*k2/128-k2*k2*k2/128;    kp2=e2*cos(m)*cos(m);
     alfap=(e2/2+e2*e2/8+e2*e2*e2/16)-e2/16*(1+e2)*kp2+3*e2*kp2*kp2/128;
     btp=e2*(1+e2)*kp2/16-e2*kp2*kp2/32;
     rp=e2*kp2*kp2/256;    sgm0=acos(sin(u1)*sin(u2)+cos(u1)*cos(u2)*cos(l));
     sgm1=acos(sin(u1)*sin(u2)+cos(u1)*cos(u2)*cos(l+sin(m)*(alfap*sgm0+btp*sin(sgm0)*cos(2*M+sgm0))));
     while(fabs(sgm0-sgm1)>1*PI/180*pow(10.0,-8))
     {
         sgm0=sgm1;
         sgm1=acos(sin(u1)*sin(u2)+cos(u1)*cos(u2)*cos(l+sin(m)*(alfap*sgm0+btp*sin(sgm0)*cos(2*M+sgm0))));
     }
     sgm=sgm1;
     lmd=l+sin(m)*(alfap*sgm+btp*sin(sgm)*cos(2*M+sgm));    s=(sgm-bt*sin(sgm)*cos(2*M+sgm)-r*sin(2*sgm)*cos(4*M+2*sgm))/alfa;
     A1=atan(sin(lmd)/(cos(u1)*tan(u2)-sin(u1)*cos(lmd)));
     A1=(A1>0)?A1:A1+PI;
     A1=(m>0)?A1:A1+PI;
     A2=atan(sin(lmd)/(sin(u2)*cos(lmd)-tan(u1)*cos(u2)));
     A2=(A2>0)?A2:A2+PI;
     A2=(m<0)?A2:A2+PI;        printf("\n\n得到两点间大地线长S和大地正反方位角A1、A2如下:\n\n");
     printf("s=%lf\n",s);
     printf("A1=");
     RBD(A1);printf("\n");
     printf("A2=");
     RBD(A2);printf("\n");
 }
 void GUS_ZS()
 {
     double B,L,x3,x6,y3,y6,Y3,Y6,du,f,mi,X,N,n,t;
     double At,Bt,Ct,Dt,m3,m6,l3,l6,W,L03,L06;
     int DH3,DH6;    printf("请输入大地坐标(输入格式为角度(例如:30'40'50')):\n大地经度 L=");
     scanf("%lf'%lf'%lf'",&du,&f,&mi);
     L=RAD(du,f,mi);
     printf("\n大地纬度 B=");
     scanf("%lf'%lf'%lf'",&du,&f,&mi);
     B=RAD(du,f,mi);    At=1+3*e2/4+45*e2*e2/64+175*e2*e2*e2/256;
     Bt=3*e2/4+15*e2*e2/16+525*e2*e2*e2/512;
     Ct=15*e2*e2/64+105*e2*e2*e2/256;
     Dt=35*e2*e2*e2/512;
     X=a*(1-e2)*(At*B-Bt*sin(2*B)/2+Ct*sin(4*B)/4-Dt*sin(6*B)/6);    W=sqrt(1-e2*sin(B)*sin(B));
     N=a/W;
     n=sqrt(ep2)*cos(B);
     t=tan(B);    DH3=(L-(1.5*PI/180))/(3*PI/180)+1;
     DH6=L/(6*PI/180)+1;
     L03=DH3*(3*PI/180);
     L06=DH6*(6*PI/180)-(3*PI/180);
     l3=L-L03;
     l6=L-L06;
     m3=cos(B)*l3;
     m6=cos(B)*l6;    x3=X+N*t*(m3*m3/2+(5-t*t+9*n*n+4*n*n*n*n)*m3*m3*m3*m3/24+(61-58*t*t+t*t*t*t)*m3*m3*m3*m3*m3*m3/720);
     x6=X+N*t*(m6*m6/2+(5-t*t+9*n*n+4*n*n*n*n)*m6*m6*m6*m6/24+(61-58*t*t+t*t*t*t)*m6*m6*m6*m6*m6*m6/720);
     y3=N*(m3+(1-t*t+n*n)*m3*m3*m3/6+(5-18*t*t+t*t*t*t+14*n*n-58*n*n*t*t)*m3*m3*m3*m3*m3/120);
     y6=N*(m6+(1-t*t+n*n)*m6*m6*m6/6+(5-18*t*t+t*t*t*t+14*n*n-58*n*n*t*t)*m6*m6*m6*m6*m6/120);
     Y3=DH3*1000000+500000+y3;
     Y6=DH6*1000000+500000+y6;    printf("\n\n   得到的高斯平面坐标为:\n\n");
     printf("   对于3度带:\n    纵坐标x=%.3lf\n    横坐标y=%.3lf(通用坐标Y=%.3lf)\n\n",x3,y3,Y3);
     printf("   对于6度带:\n    纵坐标x=%.3lf\n    横坐标y=%.3lf(通用坐标Y=%.3lf)\n\n",x6,y6,Y6);
 }
 void GUS_FS()
 {
     double x,y,Y,B,B0,B1,Bf,Vf,tf,Nf,nf,L,At,Bt,Ct,Dt,L3,L6;
     long DH;    printf("   请输入高斯平面坐标:\n\n");
     printf("    纵坐标 X=");
     scanf("%lf",&x);printf("\n");
     printf("    自然坐标 y=");
     scanf("%lf",&y);printf("\n");
     printf("    通用坐标 Y=");
     scanf("%lf",&Y);printf("\n");    At=1+3*e2/4+45*e2*e2/64+175*e2*e2*e2/256;
     Bt=3*e2/4+15*e2*e2/16+525*e2*e2*e2/512;
     Ct=15*e2*e2/64+105*e2*e2*e2/256;
     Dt=35*e2*e2*e2/512;
     B0=x/(a*(1-e2)*At);
     B1=(x-a*(1-e2)*(-Bt*sin(2*B0)/2+Ct*sin(4*B0)/4-Dt*sin(6*B0)/6))/(a*(1-e2)*At);
     while(fabs(B1-B0)>1*pow(10.0,-8))
     {
         B0=B1;
         B1=(x-a*(1-e2)*(-Bt*sin(2*B0)/2+Ct*sin(4*B0)/4-Dt*sin(6*B0)/6))/(a*(1-e2)*At);
     }
     Bf=B1;    nf=sqrt(ep2)*cos(Bf);
     tf=tan(Bf);
     Vf=sqrt(1+ep2*cos(Bf)*cos(Bf));
     Nf=c/Vf;
     B=Bf-Vf*Vf*tf/2*((y/Nf)*(y/Nf)-(5+3*tf*tf+nf*nf-9*nf*nf*tf*tf)*pow((y/Nf),4)/12+(61+90*tf*tf+45*tf*tf)*pow((y/Nf),6)/360);
     L=((y/Nf)-(1+2*tf*tf+nf*nf)*(y/Nf)*(y/Nf)*(y/Nf)/6+(5+28*tf*tf+24*pow(tf,4)+6*nf*nf+8*nf*nf*tf*tf)*pow((y/Nf),5)/120)/cos(Bf);    DH=Y/1000000;
     L3=3*PI/180*double(DH)+L;
     L6=6*PI/180*double(DH)-3*PI/180+L;    printf("\n\n   得到的大地坐标为:\n\n");
     printf("    大地纬度 B=");
     RBD(B);printf("\n");
     printf("    若为6度带,大地经度 L=");
     RBD(L6);printf("\n");
     printf("    若为3度带,大地经度 L=");
     RBD(L3);printf("\n");
 }void CCoordinateTransformationDlg::OnBnClickedButton1BlToCanxinXyz()
 {
     //经纬度转参心空间直角坐标
     UpdateData(TRUE);
 //     double dfe = sqrt(m_dfMaxAxis*m_dfMaxAxis - m_dfMinAxis*m_dfMinAxis)/m_dfMaxAxis;
 //     double dfW = sqrt(1-dfe*dfe*sin(m_dfLat)*sin(m_dfLat));
 //     double dfN = m_dfMaxAxis / dfW;
 // 
 //     m_dfCanxinX = (dfN + m_dfTuoqiuGao) * cos(m_dfLat) * cos(m_dflon);
 //     m_dfCanxinY = (dfN + m_dfTuoqiuGao) * cos(m_dfLat) * sin(m_dflon);
 //     m_dfCanxinZ = (dfN*(1-dfe*dfe)+ m_dfTuoqiuGao) * sin(m_dfLat);    //
     if (m_dfMaxAxis < 100 || m_dfMinAxis < 100)
     {
         AfxMessageBox(_T("请输入规范的椭球参数!"));
         return;
     }    a=m_dfMaxAxis;b=m_dfMinAxis;
     c=a*a/b;
     ep2=(a*a-b*b)/(b*b);
     e2=(a*a-b*b)/(a*a);    double B,L,H,N,W;
     double d,f,m;
     double X,Y,Z;
     
     L=RAD(m_dflon);    B=RAD(m_dfLat);
     //printf("    大地高   H=");
     H = m_dfTuoqiuGao;    W=sqrt(1-e2*sin(B)*sin(B));
     N=a/W;
     X=(N+H)*cos(B)*cos(L);
     Y=(N+H)*cos(B)*sin(L);
     Z=(N*(1-e2)+H)*sin(B);    m_dfCanxinX = X;
     m_dfCanxinY = Y;
     m_dfCanxinZ = Z;
     UpdateData(FALSE);
 } void CCoordinateTransformationDlg::OnBnClickedButton2CanxinXyzToCanxinPingmianmoveXyz()
 {
     UpdateData(TRUE);
     if (m_dfMaxAxis < 100 || m_dfMinAxis < 100)
     {
         AfxMessageBox(_T("请输入规范的椭球参数!"));
         return;
     }
     if (m_dfPingmianRoteAngle == 0)
     {
         m_dfCanxinPMRoteZ = m_dfCanxinX;
         m_dfCanxinPMRoteX = m_dfCanxinY;
         m_dfCanxinPMRoteY = m_dfCanxinZ;
     }
     else
     {
         double dfX0 = 0, dfY0 = 0;
     //    double dfHudu = m_dfPingmianRoteAngle;
         double dfHudu = RAD(-m_dfPingmianRoteAngle);
     //     m_dfCanxinPMRoteX = (m_dfCanxinX - dfX0) * cos(dfHudu) - (m_dfCanxinY - dfY0) * sin(dfHudu) + dfX0;
     //     m_dfCanxinPMRoteZ = (m_dfCanxinX - dfX0) * sin(dfHudu) + (m_dfCanxinY - dfY0) * cos(dfHudu) + dfY0;
     //     m_dfCanxinPMRoteY = m_dfCanxinZ;        m_dfCanxinPMRoteZ = (m_dfCanxinY * cos(dfHudu) - m_dfCanxinX * sin(dfHudu))/(cos(dfHudu)*cos(dfHudu) - sin(dfHudu)*sin(dfHudu));
         m_dfCanxinPMRoteX = (m_dfCanxinY - m_dfCanxinPMRoteZ*cos(dfHudu))/sin(dfHudu);
         m_dfCanxinPMRoteY = m_dfCanxinZ;
     }
     UpdateData(FALSE);
 } void CCoordinateTransformationDlg::OnBnClickedButton3DufenmiaoToDu()
 {
     UpdateData(TRUE);
     m_dfBL = m_dfAngle + m_dfMinite/60 + m_dfSeconde/3600;
     UpdateData(FALSE);
 } void CCoordinateTransformationDlg::OnBnClickedButton4DuToDufenmiao()
 {
     UpdateData(TRUE);
     m_dfAngle = int(m_dfBL);
     double dfTmp = m_dfBL - m_dfAngle;
     double dfMiniteTmp = (dfTmp * 60);
     m_dfMinite = (int) dfMiniteTmp;
     m_dfSeconde = (dfMiniteTmp - m_dfMinite)*60;    UpdateData(FALSE);
 } void CCoordinateTransformationDlg::OnCbnSelchangeCombo1TuoqiuName()
 {
     UpdateData(TRUE);
     CWnd* wnd =NULL;
     int n = m_ComboTuoQiuName.GetCurSel();
     switch(n)
     {
     case 0:
         {
             a=6378137;b=6356752.3142;
             c=a*a/b;
             ep2=(a*a-b*b)/(b*b);
             e2=(a*a-b*b)/(a*a);
             m_dfMaxAxis = a;
             m_dfMinAxis = b;
             wnd = GetDlgItem(IDC_EDIT3_MAJORSEMIAXIS);
             wnd->EnableWindow(FALSE);
             wnd = GetDlgItem(IDC_EDIT4_SEMI_MINOR_AXIS);
             wnd->EnableWindow(FALSE);
             break;
         }
     case 1:
         {
             a=6378245.0;b=6356863.0188;c=6399698.9018;e2=0.00669342162297;ep2=0.00673852541468;
             m_dfMaxAxis = a;
             m_dfMinAxis = b;
             wnd = GetDlgItem(IDC_EDIT3_MAJORSEMIAXIS);
             wnd->EnableWindow(FALSE);
             wnd = GetDlgItem(IDC_EDIT4_SEMI_MINOR_AXIS);
             wnd->EnableWindow(FALSE);
             break;
         }
     case 2:
         {
             a=6378140.0;b=6356755.2882;c=6399596.6520;e2=0.00669438499959;ep2=0.00673950181947;
             m_dfMaxAxis = a;
             m_dfMinAxis = b;
             wnd = GetDlgItem(IDC_EDIT3_MAJORSEMIAXIS);
             wnd->EnableWindow(FALSE);
             wnd = GetDlgItem(IDC_EDIT4_SEMI_MINOR_AXIS);
             wnd->EnableWindow(FALSE);
             break;
         }
     case 3:
         {
             a=6378137.0;b=6356752.3141;c=6399593.6259;e2=0.00669438002290;ep2=0.00673949677547;
             m_dfMaxAxis = a;
             m_dfMinAxis = b;
             wnd = GetDlgItem(IDC_EDIT3_MAJORSEMIAXIS);
             wnd->EnableWindow(FALSE);
             wnd = GetDlgItem(IDC_EDIT4_SEMI_MINOR_AXIS);
             wnd->EnableWindow(FALSE);
             break;
         }
     default:
         {
             wnd = GetDlgItem(IDC_EDIT3_MAJORSEMIAXIS);
             wnd->EnableWindow(TRUE);
             wnd = GetDlgItem(IDC_EDIT4_SEMI_MINOR_AXIS);
             wnd->EnableWindow(TRUE);
             m_dfMaxAxis = 0;m_dfMinAxis = 0;
             break;
         }
     }
     UpdateData(FALSE);
 } static inline double  rad( double degree )
 {
     return  PI * degree / 180.0;
 }
 static inline double  rad2degree( double rad )
 {
     return  rad * 180.0 / PI;
 }
 static inline double haverSin(double x)
 {
     double v = sin(x / 2.0);
     return v * v;
 }double GetRadioDistance(double lon1, double lat1, double lon2, double lat2)
 {
     if (lon1 < -180 || lon1 > 180)
     {
         return 0;
     }
     if (lon2 < -180 || lon2 > 180)
     {
         return 0;
     }
     if (lat1 < -90 || lat1 > 90)
     {
         return 0;
     }
     if (lat2 < -90 || lat2 > 90)
     {
         return 0;
     }
     double radlon1 = rad(lon1);
     double radlat1 = rad(lat1);
     double radlon2 = rad(lon2);
     double radlat2 = rad(lat2);    double b = fabs(radlat1 - radlat2);
     double a = fabs(radlon1 - radlon2);    double h = haverSin(b) + cos(radlat1)*cos(radlat2)*haverSin(a);
     h = sqrt(h);
     h = asin(h);
     double distance = 2 * EARTH_RADIUS * h;
     return  distance;
 }double GetLength(double x1, double y1, double x2, double y2)
 {
     double dfLength = 0.0;
     double cx = x1 - x2;
     double cy = y1 - y2;
     dfLength = sqrt(cx*cx + cy*cy);    return dfLength;
 }
 void CCoordinateTransformationDlg::OnBnClickedButton1ComputeLatlongDistand()
 {
     UpdateData(TRUE);
     bool bLatlong = true;
     if (m_dfP1Longitude < -180 || m_dfP1Longitude > 180)
     {
         bLatlong = 0;
     }
     if (m_dfP2Longitude < -180 || m_dfP2Longitude > 180)
     {
         bLatlong = 0;
     }
     if (m_dfP1Latitude < -90 || m_dfP1Latitude > 90)
     {
         bLatlong = 0;
     }
     if (m_dfP2Latitude < -90 || m_dfP2Latitude > 90)
     {
         bLatlong = 0;
     }
     if (!bLatlong)
     {
         AfxMessageBox(_T("兄台,这哪里是经度啊?分明是想忽悠我嘛"));
         return;
     }    m_dfP1P2Distance = GetRadioDistance(m_dfP1Longitude, m_dfP1Latitude, m_dfP2Longitude, m_dfP2Latitude);
     UpdateData(FALSE);
 } void CCoordinateTransformationDlg::OnBnClickedBtnXyzToBl()
 {    //经纬度转参心空间直角坐标
     UpdateData(TRUE);    if (m_dfMaxAxis < 100 || m_dfMinAxis < 100)
     {
         AfxMessageBox(_T("请输入规范的椭球参数!"));
         return;
     }
     
     double B,L,H,N,W;
     double X = m_dfCanxinX,Y=m_dfCanxinY,Z=m_dfCanxinZ;
     double tgB0,tgB1;
     
     L=atan(Y/X);    m_dflon = rad2degree(L);
     printf("    大地经度为: L=");
     RBD(L);
     printf("\n");    tgB0=Z/sqrt(X*X+Y*Y);
     tgB1=(1/sqrt(X*X+Y*Y))*(Z+a*e2*tgB0/sqrt(1+tgB0*tgB0-e2*tgB0*tgB0));    while(fabs(tgB0-tgB1)>5*pow(10.0,-10))
     {
         tgB0=tgB1;
         tgB1=(1/sqrt(X*X+Y*Y))*(Z+a*e2*tgB0/sqrt(1+tgB0*tgB0-e2*tgB0*tgB0));
     }
     B=atan(tgB1);
     m_dfLat = rad2degree(B);
     //printf("    大地纬度为:B=");
     RBD(B);
     //printf("\n");
     W=sqrt(1-e2*sin(B)*sin(B));
     N=a/W;
     H=sqrt(X*X+Y*Y)/cos(B)-N;
     
     m_dfTuoqiuGao = H;
     //printf("    大地高为:H=%lf\n\n",H);
     UpdateData(FALSE);
 }