经纬度BL换算到高斯平面直角坐标XY(高斯投影正算)的源码及算法

一、
经纬度BL换算到高斯平面直角坐标XY(高斯投影正算)的源码及算法

在   gis   的帖子 "用excel完成gps坐标转换的简易方法   "   基础上,
我给出对应的vb程序段,我在   evb   开发的gps定位功能中,用它实现坐标换算(具体的参数请参考gis   的帖子)。
感觉速度比较快,效果比较好。所以帖上来,希望与名位交流:
=====================================
'经纬度bl换算到高斯平面直角坐标xy(高斯投影正算)

 

private     function    bl2xy( byref    a2    as     double ,    byref    f2    as     double ,    byref    e2    as     double ,   _ 
byref    s2    as     double ,    byref    t2    as     double )    as     boolean  
' a2   输入中央子午线,以度.分形式输入,如115度30分则输入115.30;   起算数据l0 
'
f2   以度小数形式输入经度值,   l 
'
e2   以度小数形式输入纬度值,b 
'
s2   计算结果,横坐标y 
'
t2   计算结果,纵坐标x 
'
投影带号计算 n=[l/6]+1   如:测得经度103.xxxx,故n=[103.x/6]+1=17+1=18 
'
中央经线经度 l0   =   n*6-3   =   [l/6]*6+3 

dim    b2    as     double  
' dim   g2   as   double 
dim    h2    as     double  
dim    i2    as     double  
dim    j2    as     double  
dim    k2    as     double  
dim    l2    as     double  
dim    m2    as     double  
dim    n2    as     double  
dim    o2    as     double  
dim    p2    as     double  
dim    q2    as     double  
dim    r2    as     double  

b2   
=     int (a2)    +    ( int (a2    *     100 )    -     int (a2)    *     100 )    /     60     +    (a2    *     10000     -     int (a2    *     100 )    *     100 )    /     3600  
' 把l0化成度(a2) 
'
g2   =   f2   -   b2   '   l   -l0 
'
h2   =   g2   /   57.2957795130823   '化作弧度 
h2    =    (f2    -    b2)    /     57.2957795130823     ' 将经差的单位化为弧度 
i2    =     tan (e2    /     57.2957795130823 )    ' tan   (b) 
j2    =     cos (e2    /     57.2957795130823 )    '    cos   (b) 
k2    =     0.006738525415     *    j2    *    j2 
l2   
=    i2    *    i2 
m2   
=     1     +    k2 
n2   
=     6399698.9018     /     sqr (m2) 
o2   
=    h2    *    h2    *    j2    *    j2 
p2   
=    i2    *    j2 
q2   
=    p2    *    p2 
r2   
=    ( 32005.78006     +    q2    *    ( 133.92133     +    q2    *     0.7031 )) 
s2   
=    ((((l2    -     18 )    *    l2    -    ( 58     *    l2    -     14 )    *    k2    +     5 )    *    o2    /     20     +    m2    -    l2)    *    o2    /     6     +     1 )    *    n2    *    (h2    *    j2) 
s2   
=    s2    +     18500000     ' 在计算的基础上加上了“带号”(18)和“东移”(500km) 
'
计算结果,横坐标y 
t2    =     6367558.49686     *    e2    /     57.29577951308     -    p2    *    j2    *    r2    +    ((((l2    -     58 )    *    l2    +     61 )    *    _ 
o2   
/     30     +    ( 4     *    k2    +     5 )    *    m2    -    l2)    *    o2    /     12     +     1 )    *    n2    *    i2    *    o2    /     2  
' 计算结果,纵坐标x 
'
msgbox   "pts2= "   &   s2   &   "   pt   t2= "   &   t2 

bl2xy   
=     true  
end     function

 二、

 

//    GaussBL2xy.cpp   :   Defines   the   entry   point   for   the   console   application. 
//  

#include   
" stdafx.h  "  
#include   
" math.h  "  
#include   
" CoorTrans.h  "  
#include   
< iostream >  

using     namespace    std; 

void    main( int    argc,    char *    argv[]) 

  
double    MyL0    =     108 ;    // 中央子午线 
   double    MyB    =     33.44556666 ;    // 33   du   44   fen   55.6666   miao 
   double    MyL    =     109.22334444 ;    // 3度带,109   d   22   m   33.4444   s 
  
  PrjPoint_Krasovsky   MyPrj; 
  MyPrj.SetL0(MyL0); 
  MyPrj.SetBL(MyB,   MyL); 
  
double    OutMyX;                        // 结果应该大致是:3736714.783,   627497.303 
   double    OutMyY; 
  OutMyX   
=    MyPrj.x;            // 正算结果:   北坐标x 
  OutMyY    =    MyPrj.y;            // 结果:东坐标y 
  
  
// 反算 ///
   double    InputMyX    =     3736714.783 ;      // 如果是独立计算,应该给出中央子午线L0 
   double    InputMyY    =     627497.303
  MyPrj.Setxy(InputMyX,   InputMyY); 
  MyPrj.GetBL(
& MyPrj.B,    & MyPrj.L);    // 把计算出的BL的弧度值换算为dms形式 
   double    OutputMyB; 
  
double    OutputMyL; 
  OutputMyB   
=    MyPrj.B;      // 反算结果:B 
  OutputMyL    =    MyPrj.L;      // 反算结果:L 

  
// 分析表明,此程序的结果和Coord4.2的转换结果是一样的,只差到毫米级 
        
// 原程序有几个问题,1.Pi的值不对。2.SetBL中多了两行错误代码 



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,y的计算公式见孔祥元等主编武汉大学出版社2002年出版的《控制测量学》的第72页 
  
// 书的的括号有问题,   (   和   [   应该交换 
  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    *    t2 
    
+     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;          // 我靠,I   wana   say   fuck 
  
// L   =   dL;    // del   it   ! 
  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 ;      // 这几个A是什么意思? 
  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() 



  

// CoorTrans.h   文件 
#ifndef   _COORTRANS_H_INCLUDED 
#define    _COORTRANS_H_INCLUDED 

#include   
" stdafx.h  "  
#include   
" math.h  "  

const     double    PI    =     3.141592653589793

double    Dms2Rad( double    Dms); 
double    Rad2Dms( double    Rad); 

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    // 类的继承,声明基类是   PrjPoint,虚基类 

public
  PrjPoint_Krasovsky();   
// 定义构造函数,用来初始化。(函数名和类名相同) 
   ~ PrjPoint_Krasovsky(); 
}; 

class    PrjPoint_IUGG1975   :    virtual     public    PrjPoint 

public
  PrjPoint_IUGG1975(); 
  
~ PrjPoint_IUGG1975(); 
}; 

#endif    /*   ndef   _COORTRANS_H_INCLUDED   */ 
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值