⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 source.txt

📁 大地坐标到平面坐标的转换——高斯-格吕特变换
💻 TXT
📖 第 1 页 / 共 2 页
字号:
这段代码是偶找来的,里面存在一些错误的代码偶没有改正,哈哈,希望大家自己去找出来,因为代码不是偶自己写的,如何调用也不要问偶,如果需要的话偶可以直接提供dll(偶不想写注释),保证绝对正确,计算出来的数值和国家正在使用的软件系统中的转换保持一致。偶不是搞地理信息系统的,其他问题不要找我。呵呵。  
  代码如下:  
  //CPP文件  
   
  #include   "CoorTrans.h"  
  ////////////////////////////////////////////  
  //   Common   functions  
  ////////////////////////////////////////////  
  double   Dms2Rad(double   Dms)  
  {  
  double   Degree,   Miniute;  
  double   Second;  
  int   Sign;  
  double   Rad;  
  if(Dms   >=   0)  
  Sign   =   1;  
  else  
  Sign   =   -1;  
  Dms   =   fabs(Dms);  
  Degree   =   floor(Dms);  
  Miniute   =   floor(fmod(Dms   *   100.0,   100.0));  
  Second   =   fmod(Dms   *   10000.0,   100.0);  
  Rad   =   Sign   *   (Degree   +   Miniute   /   60.0   +   Second   /   3600.0)   *   PI   /   180.0;  
  return   Rad;  
  }  
  double   Rad2Dms(double   Rad)  
  {  
  double   Degree,   Miniute;  
  double   Second;  
  int   Sign;  
  double   Dms;  
  if(Rad   >=   0)  
  Sign   =   1;  
  else  
  Sign   =   -1;  
  Rad   =   fabs(Rad   *   180.0   /   PI);  
  Degree   =   floor(Rad);  
  Miniute   =   floor(fmod(Rad   *   60.0,   60.0));  
  Second   =   fmod(Rad   *   3600.0,   60.0);  
  Dms   =   Sign   *   (Degree   +   Miniute   /   100.0   +   Second   /   10000.0);  
  return   Dms;  
  }  
  ///////////////////////////////////////////////////  
  //   Definition   of   PrjPoint  
  ///////////////////////////////////////////////////  
  BOOL   PrjPoint::BL2xy()  
  {  
  double   X,   N,   t,   t2,   m,   m2,   ng2;  
  double   sinB,   cosB;  
  X   =   A1   *   B   *   180.0   /   PI   +   A2   *   sin(2   *   B)   +   A3   *   sin(4   *   B)   +   A4   *   sin(6   *    
  B);  
  sinB   =   sin(B);  
  cosB   =   cos(B);  
  t   =   tan(B);  
  t2   =   t   *   t;  
  N   =   a   /   sqrt(1   -   e2   *   sinB   *   sinB);  
  m   =   cosB   *   (L   -   L0);  
  m2   =   m   *   m;  
  ng2   =   cosB   *   cosB   *   e2   /   (1   -   e2);  
  x   =   X   +   N   *   t   *   ((0.5   +   ((5   -   t2   +   9   *   ng2   +   4   *   ng2   *   ng2)   /   24.0   +   (61   -    
  58   *   t2   +   t2   *   t2)   *   m2   /   720.0)   *   m2)   *   m2);  
  y   =   N   *   m   *   (   1   +   m2   *   (   (1   -   t2   +   ng2)   /   6.0   +   m2   *   (   5   -   18   *   t2   +   t2   *   t  
  2   +   14   *   ng2   -   58   *   ng2   *   t2   )   /   120.0));  
  y   +=   500000;  
  return   TRUE;  
  }  
  BOOL   PrjPoint::xy2BL()  
  {  
  double   sinB,   cosB,   t,   t2,   N   ,ng2,   V,   yN;  
  double   preB0,   B0;  
  double   eta;  
  y   -=   500000;  
  B0   =   x   /   A1;  
  do  
  {  
  preB0   =   B0;  
  B0   =   B0   *   PI   /   180.0;  
  B0   =   (x   -   (A2   *   sin(2   *   B0)   +   A3   *   sin(4   *   B0)   +   A4   *   sin(6   *   B0)))   /   A1;  
  eta   =   fabs(B0   -   preB0);  
  }while(eta   >   0.000000001);  
  B0   =   B0   *   PI   /   180.0;  
  B   =   Rad2Dms(B0);  
  sinB   =   sin(B0);  
  cosB   =   cos(B0);  
  t   =   tan(B0);  
  t2   =   t   *   t;  
  N   =   a   /   sqrt(1   -   e2   *   sinB   *   sinB);  
  ng2   =   cosB   *   cosB   *   e2   /   (1   -   e2);  
  V   =   sqrt(1   +   ng2);  
  yN   =   y   /   N;  
  B   =   B0   -   (yN   *   yN   -   (5   +   3   *   t2   +   ng2   -   9   *   ng2   *   t2)   *   yN   *   yN   *   yN   *   yN   /  
  12.0   +   (61   +   90   *   t2   +   45   *   t2   *   t2)   *   yN   *   yN   *   yN   *   yN   *   yN   *   yN   /   360.0)  
  *   V   *   V   *   t   /   2;  
  L   =   L0   +   (yN   -   (1   +   2   *   t2   +   ng2)   *   yN   *   yN   *   yN   /   6.0   +   (5   +   28   *   t2   +   24    
  *   t2   *   t2   +   6   *   ng2   +   8   *   ng2   *   t2)   *   yN   *   yN   *   yN   *   yN   *   yN   /   120.0)   /   cosB  
  ;  
  return   TRUE;  
  }  
  BOOL   PrjPoint::SetL0(double   dL0)  
  {  
  L0   =   Dms2Rad(dL0);  
  return   TRUE;  
  }  
  BOOL   PrjPoint::SetBL(double   dB,   double   dL)  
  {  
  B   =   Dms2Rad(dB);  
  L   =   Dms2Rad(dL);  
  B   =   dB;  
  L   =   dL;  
  BL2xy();  
  return   TRUE;  
  }  
  BOOL   PrjPoint::GetBL(double   *dB,   double   *dL)  
  {  
  *dB   =   Rad2Dms(B);  
  *dL   =   Rad2Dms(L);  
  return   TRUE;  
  }  
  BOOL   PrjPoint::Setxy(double   dx,   double   dy)  
  {  
  x   =   dx;  
  y   =   dy;  
  xy2BL();  
  return   TRUE;  
  }  
  BOOL   PrjPoint::Getxy(double   *dx,   double   *dy)  
  {  
  *dx   =   x;  
  *dy   =   y;  
  return   TRUE;  
  }  
  ///////////////////////////////////////////////////  
  //   Definition   of   PrjPoint_IUGG1975  
  ///////////////////////////////////////////////////  
  PrjPoint_IUGG1975::PrjPoint_IUGG1975()  
  {  
  a   =   6378140;  
  f   =   298.257;  
  e2   =   1   -   ((f   -   1)   /   f)   *   ((f   -   1)   /   f);  
  e12   =   (f   /   (f   -   1))   *   (f   /   (f   -   1))   -   1;  
  A1   =   111133.0047;  
  A2   =   -16038.5282;  
  A3   =   16.8326;  
  A4   =   -0.0220;  
  }  
  PrjPoint_IUGG1975::~PrjPoint_IUGG1975()  
  {  
  }  
  ///////////////////////////////////////////////////  
  //   Definition   of   PrjPoint_Krasovsky  
  ///////////////////////////////////////////////////  
  PrjPoint_Krasovsky::PrjPoint_Krasovsky()  
  {  
  a   =   6378245;  
  f   =   298.3;  
  e2   =   1   -   ((f   -   1)   /   f)   *   ((f   -   1)   /   f);  
  e12   =   (f   /   (f   -   1))   *   (f   /   (f   -   1))   -   1;  
  A1   =   111134.8611;  
  A2   =   -16036.4803;  
  A3   =   16.8281;  
  A4   =   -0.0220;  
  }  
  PrjPoint_Krasovsky::~PrjPoint_Krasovsky()  
  {  
  }  
   
   
  //H文件  
   
   
  #ifndef   _COORTRANS_H_INCLUDED  
  #define   _COORTRANS_H_INCLUDED  
  #include    
  const   double   PI   =   3.14159265353846;  
  class   PrjPoint  
  {  
  public:  
  double   L0;   //   中央子午线经度  
  double   B,   L;   //   大地坐标  
  double   x,   y;   //   高斯投影平面坐标  
  public:  
  BOOL   BL2xy();  
  BOOL   xy2BL();  
  protected:  
  double   a,   f,   e2,   e12;   //   基本椭球参数  
  double   A1,   A2,   A3,   A4;   //   用于计算X的椭球参数  
  public:  
  BOOL   SetL0(double   dL0);  
  BOOL   SetBL(double   dB,   double   dL);  
  BOOL   GetBL(double   *dB,   double   *dL);  
  BOOL   Setxy(double   dx,   double   dy);  
  BOOL   Getxy(double   *dx,   double   *dy);  
  };  
  class   PrjPoint_Krasovsky   :   virtual   public   PrjPoint  
  {  
  public:  
  PrjPoint_Krasovsky();  
  ~PrjPoint_Krasovsky();  
  };  
  class   PrjPoint_IUGG1975   :   virtual   public   PrjPoint  
  {  
  public:  
  PrjPoint_IUGG1975();  
  ~PrjPoint_IUGG1975();  
  };  
  double   Dms2Rad(double   Dms);  
  double   Rad2Dms(double   Rad);  
  #endif   /*   ndef   _COORTRANS_H_INCLUDED   */ 
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  //高斯投影正、反算
//////6度带宽 54年北京坐标系
//高斯投影由经纬度(Unit:DD)反算大地坐标(含带号,Unit:Metres)
void GaussProjCal(double longitude, double latitude, double *X, double *Y)
{
int ProjNo=0; int ZoneWide; ////带宽
double longitude1,latitude1, longitude0,latitude0, X0,Y0, xval,yval;
double a,f, e2,ee, NN, T,C,A, M, iPI;
iPI = 0.0174532925199433; ////3.1415926535898/180.0;
ZoneWide = 6; ////6度带宽
a=6378245.0; f=1.0/298.3; //54年北京坐标系参数
////a=6378140.0; f=1/298.257; //80年西安坐标系参数
ProjNo = (int)(longitude / ZoneWide) ;
longitude0 = ProjNo * ZoneWide + ZoneWide / 2;
longitude0 = longitude0 * iPI ;
latitude0=0;
longitude1 = longitude * iPI ; //经度转换为弧度
latitude1 = latitude * iPI ; //纬度转换为弧度
e2=2*f-f*f;
ee=e2*(1.0-e2);
NN=a/sqrt(1.0-e2*sin(latitude1)*sin(latitude1));
T=tan(latitude1)*tan(latitude1);
C=ee*cos(latitude1)*cos(latitude1);
A=(longitude1-longitude0)*cos(latitude1);
M=a*((1-e2/4-3*e2*e2/64-5*e2*e2*e2/256)*latitude1-(3*e2/8+3*e2*e2/32+45*e2*e2
*e2/1024)*sin(2*latitude1)
+(15*e2*e2/256+45*e2*e2*e2/1024)*sin(4*latitude1)-(35*e2*e2*e2/3072)*sin(6*l
atitude1));
xval = NN*(A+(1-T+C)*A*A*A/6+(5-18*T+T*T+72*C-58*ee)*A*A*A*A*A/120);
yval = M+NN*tan(latitude1)*(A*A/2+(5-T+9*C+4*C*C)*A*A*A*A/24
+(61-58*T+T*T+600*C-330*ee)*A*A*A*A*A*A/720);
X0 = 1000000L*(ProjNo+1)+500000L;
Y0 = 0;
xval = xval+X0; yval = yval+Y0;
*X = xval;
*Y = yval;
}


//高斯投影由大地坐标(Unit:Metres)反算经纬度(Unit:DD)
void GaussProjInvCal(double X, double Y, double *longitude, double *latitude)

{
int ProjNo; int ZoneWide; ////带宽
double longitude1,latitude1, longitude0,latitude0, X0,Y0, xval,yval;
double e1,e2,f,a, ee, NN, T,C, M, D,R,u,fai, iPI;
iPI = 0.0174532925199433; ////3.1415926535898/180.0;
a = 6378245.0; f = 1.0/298.3; //54年北京坐标系参数
////a=6378140.0; f=1/298.257; //80年西安坐标系参数
ZoneWide = 6; ////6度带宽
ProjNo = (int)(X/1000000L) ; //查找带号
longitude0 = (ProjNo-1) * ZoneWide + ZoneWide / 2;
longitude0 = longitude0 * iPI ; //中央经线
X0 = ProjNo*1000000L+500000L;
Y0 = 0;
xval = X-X0; yval = Y-Y0; //带内大地坐标
e2 = 2*f-f*f;
e1 = (1.0-sqrt(1-e2))/(1.0+sqrt(1-e2));
ee = e2/(1-e2);
M = yval;
u = M/(a*(1-e2/4-3*e2*e2/64-5*e2*e2*e2/256));
fai = u+(3*e1/2-27*e1*e1*e1/32)*sin(2*u)+(21*e1*e1/16-55*e1*e1*e1*e1/32)*sin(
4*u)
+(151*e1*e1*e1/96)*sin(6*u)+(1097*e1*e1*e1*e1/512)*sin(8*u);
C = ee*cos(fai)*cos(fai);
T = tan(fai)*tan(fai);
NN = a/sqrt(1.0-e2*sin(fai)*sin(fai));
R = a*(1-e2)/sqrt((1-e2*sin(fai)*sin(fai))*(1-e2*sin(fai)*sin(fai))*(1-e2*sin
(fai)*sin(fai)));
D = xval/NN;
//计算经度(Longitude) 纬度(Latitude)
longitude1 = longitude0+(D-(1+2*T+C)*D*D*D/6+(5-2*C+28*T-3*C*C+8*ee+24*T*T)*D
*D*D*D*D/120)/cos(fai);
latitude1 = fai -(NN*tan(fai)/R)*(D*D/2-(5+3*T+10*C-4*C*C-9*ee)*D*D*D*D/24
+(61+90*T+298*C+45*T*T-256*ee-3*C*C)*D*D*D*D*D*D/720);
//转换为度 DD
*longitude = longitude1 / iPI;
*latitude = latitude1 / iPI;
}




































对利用EXCEL电子表格进行高斯投影换算的方法进行了较详细的介绍,对如何进行GPS坐标系转换进行了分析,提出了一种简单实用的坐标改正转换方法,介绍了用EXCEL完成转换的思路。

[关键字] 电子表格;GPS;坐标转换

作为尖端技术GPS,能方便快捷性地测定出点位坐标,无论是操作上还是精度上,比全站仪等其他常规测量设备有明显的优越性。随着我国各地GPS差分台站的不断建立以及美国SA政策的取消,使得单机定位的精度大大提高,有的已经达到了亚米级精度,能够满足国土资源调查、土地利用更新、遥感监测、海域使用权清查等工作的应用。在一般情况下,我们使用的是1954年北京坐标系或1980年西安坐标系(以下分别简称54系和80系),而GPS测定的坐标是WGS- 84坐标系坐标,需要进行坐标系转换。对于非测量专业的工作人员来说,虽然GPS定位操作非常容易,但坐标转换则难以掌握,EXCEL是比较普及的电子表格软件,能够处理较复杂的数学运算,用它来进行GPS坐标转换、面积计算会非常轻松自如。要进行坐标系转换,离不开高斯投影换算,下面分别介绍用 EXCEL进行换算的方法和GPS坐标转换方法。

一、用EXCEL进行高斯投影换算

从经纬度BL换算到高斯平面直角坐标XY(高斯投影正算),或从XY换算成BL(高斯投影反算),一般需要专用计算机软件完成,在目前流行的换算软件中,存在一个共同的不足之处,就是灵活性较差,大都需要一个点一个点地进行,不能成批量地完成,给实际工作带来许多不便。笔者发现,用EXCEL可以很直观、方便地完成坐标换算工作,不需要编制任何软件,只需要在EXCEL的相应单元格中输入相应的公式即可。下面以54系为例,介绍具体的计算方法。

完成经纬度BL到平面直角坐标XY的换算,在EXCEL中大约需要占用21列,当然读者可以通过简化计算公式或考虑直观性,适当增加或减少所占列数。在 EXCEL中,输入公式的起始单元格不同,则反映出来的公式不同,以公式从第2行第1列(A2格)为起始单元格为例,各单元格的公式如下:

单元格
单元格内容
说明

A2
输入中央子午线,以度.分秒形式输入,如115度30分则输入115.30
起算数据L0

B2
=INT(A2)+(INT(A2*100)-INT(A2)*100)/60+(A2*10000-INT(A2*100)*100)/3600
把L0化成度

C2
以度小数形式输入纬度值,如38°14′20″则输入38.1420
起算数据B

D2
以度小数形式输入经度值
起算数据L

E2
=INT(C2)+(INT(C2*100)-INT(C2)*100)/60+(C2*10000-INT(C2*100)*100)/3600
把B化成度

F2
=INT(D2)+(INT(D2*100)-INT(D2)*100)/60+(D2*10000-INT(D2*100)*100)/3600
把L化成度

G2
=F2-B2
L-L0

H2
=G2/57.2957795130823
化作弧度

I2
=TAN(RADIANS(E2))
Tan(B)

J2
=COS(RADIANS(E2))
COS(B)

K2
=0.006738525415*J2*J2


L2
=I2*I2


M2
=1+K2


N2
=6399698.9018/SQRT(M2)


O2
=H2*H2*J2*J2


P2
=I2*J2


Q2
=P2*P2


R2
=(32005.78006+Q2*(133.92133+Q2*0.7031))


S2
=6367558.49686*E2/57.29577951308-P2*J2*R2+((((L2-58)*L2+61)*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -