由于工作需要,编写了大地测量方面坐标转换的程序,主要实现以下功能:
程序特点:
经过大量的实验数据验证,程序稳定可靠。精度可达到亚毫米级别。
程序的可执行文件可以免费分享和使用。在CSDN博客我的下载中有。
源代码有偿提供。
联系[email protected]
软件中的基本坐标转换都是通过以下几个核心函数组合实现的。
//度数和弧度的转换
double Deg2Rad(double deg);
double Rad2Deg(double rad);
//度转度分秒
double Deg2DMS(double deg);
//度分秒转度
double DMS2Deg(double DMS);
//高斯投影正反算
void GaussForward(double a,double f,double B,double L,double L0,double &x,double &y,double east_plus);
void GaussBackword(double a,double f,double x,double y,double L0,double &B,double &L,double east_plus);
//UTM投影正反算
void UTMForward(double a,double f,double B,double L,double L0,double &x,double &y,double east_plus);
void UTMBackword(double a,double f,double x,double y,double L0,double &B,double &L,double east_plus);
//大地坐标系和空间直角坐标系的相互转换
void BLH2XYZ(double a,double f,double B,double L,double H, double &X,double &Y,double &Z);
void XYZ2BLH(double a,double f,double X,double Y,double Z, double &B,double &L,double &H);```
以上代码每次只能转换一个点的坐标,为了实现点的批量转换,构建下面的类:
单点类
/******************坐标系坐标****************
成员变量有点号、北、东、高
可以用来表示空间直角坐标系坐标,对应为XYZ
可以用来表示投影坐标系坐标,对应为北东高
可以用来表示大地坐标,对应为纬度、经度、椭球高
********************************************/
class Coor
{
public:
string ID;
double east;
double north;
double h;
public:
Coor();
Coor(string ID, double east,double north, double h);
void PrintData();
}
点集类
通过该类进行批量坐标的转换
/******************点位坐标的集合****************
************************************************/
class CoorVector
{
public:
vector v_coor;
public:
CoorVector();
//将上面的单点转换写成批量转换
void GaussForward_cv(double a,double f,double L0,double east_plus = 500000);
void GaussBackword_cv(double a,double f,double L0,double east_plus = 500000);
void UTMBackword_cv(double a,double f,double L0,double east_plus = 500000);
void UTMForward_cv(double a,double f,double L0,double east_plus = 500000);
void Deg2Rad_cv();
void Rad2Deg_cv();
void BLH2XYZ_cv(double a,double f);
void XYZ2BLH_cv(double a,double f);
void DMS2Deg_cv();
void Deg2DMS_cv();
//读文件
bool ReadData(string fileName);
//打印数据到屏幕
void PrintData();
//数据写入文件
void WriteData(string fileName);
};
到此为止,软件可以进行单点和批量的坐标转换,包括大地坐标、高斯投影、UTM投影坐标,空间直角坐标系之间的任意转换,涉及北京54、西安80、WGS84、CGCS2000和自定义坐标系。
那么给定两组坐标,如何进行布尔沙七参数的反算呢?以及如何进行不同椭球之家附带七参数转换关系的坐标转换呢?下面一个新的类可以解决问题:
七参数模型类:
/*****************布尔沙七参数模型*******************
平移参数DX,DY,DZ 单位米
旋转参数WX,WY,WZ 单位秒
尺度参数K,单位ppm
初值为0,这样即使进行了七参数转换,依然不改变坐标值
****************************************************/
class Brusa
{
public:
double DX;
double DY;
double DZ;
double WX;
double WY;
double WZ;
double K;
public:
Brusa();
/**************根据七参数进行坐标计算****************
输入为两组坐标变量,一组转换前,一组转换后
坐标系为空间直角坐标系
****************************************************/
void TransCoor(double X_befor,double Y_befor,double Z_befor,double &X_after,double &Y_after,double &Z_after);
/*****************布尔沙七参数反算*******************
平移参数DX,DY,DZ 单位米
旋转参数WX,WY,WZ 单位秒
尺度参数K,单位ppm
运用最小二乘计算七参数,公式为Ax=B,无需迭代
输入为两组点坐标,坐标系为空间直角坐标系,计算完更新
单位为米、弧度、单位1
两组点数量不一致或者数量少于3对,返回false
不进行点名的匹配,同名点按照顺序匹配
****************************************************/
bool CalBrusa(CoorVector vc_befor, CoorVector vc_after);
void PrintData();
};
该类中一个函数进行七参数反算,一个函数进行使用七参数的坐标转换。下面只贴出最核心的七参数反算代码,该代码进行最小二乘计算,无需迭代。涉及矩阵运算,矩阵运算有自己写的类库,但是太水了,后面改成Engin类库。使用方法自行百度,很简单,类库源代码代码包中有。
//参数为转换前点集、转换后点集,该函数其实就是解一个Ax=B的矩阵。
//在代码中A=MA,x=Mx,B=MB.
bool CalBrusa(CoorVector vc_befor, CoorVector vc_after)
{
//两组坐标点数量不同,不进行计算
if (vc_befor.v_coor.size() != vc_after.v_coor.size())
return false;
//点集数量少于3组,无法计算
if (vc_befor.v_coor.size() < 3)
return false;
int num = vc_befor.v_coor.size();
MatrixXd MB(num*3,1);
MatrixXd MA(num*3,7);
for (int i=0;i
软件截图如下:
测试数据:
下面简单介绍软件使用:
下面三个点是WGS84坐标系下大地坐标
坐标排列方式在软件面板上写着:
p1 30.0 120.0 1000
p1 30.5 120.5 1000
p3 30.8 120.8 1000
选取源坐标,选取源数据的坐标系,选取目标坐标系,选取写入文件,点击坐标转换按钮,即可完成计算。如果批量计算,可以采用文件方式,如果单点计算,面板上的数据框也可以进行单点计算,而不用采用文件方式。点击转换按钮,可以同时计算单点和文件。如果没有文件或者没有单点,也没有关系,忽略即可。
转换后坐标,UTM投影,中央经线120度。
p1 3318785.352607667900 500000.000000000000 999.999999991618
p1 3374297.773515739000 547980.561370084410 999.999999989755
p3 3407710.849772922700 576532.969669877670 999.999999989755
下面有刚才的两种数据进行七参数计算。
1选取源数据,2选取转换后数据,34选取数据对应的坐标系,5进行计算。计算完成后,如果需要使用该七参数进行坐标转,需要按6启用七参,再通过坐标转换按钮进行计算。
七参计算后,在程序文件夹下回生成一个report报告:
包含七参数的值,以及三个方向的误差,以及按照七参数将源数据进行转换,和转换后的数据进行比较,很直观看出来点位的精度和偏差。
注意:
七参计算和坐标转换共享一套坐标系选项。七参数只是表示连个椭球之间的空间关系,和坐标系,投影方式以及分度带无关。七参计算完毕后,只要椭球没变,可以任意改变投影的方式。
另外:
如果你有七参数,可以填到七参数文本框中,点击启用,计算的时候会将七参数加入计算过程。依然可以得到正确的结果。
由于数据保密原因,随手写了几个坐标进行转换,读者可以使用真实数据进行验证。该软件进行过大量数据验证,请放心使用。