大地坐标转大地空间直角坐标,经纬度计算距离,源代码如下:
源代码下载地址:
https://download.csdn.net/download/c_bright/11203522
// 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); }
