GIS(Geographic Information System 地理信息系统)领域中最常提及 的一个概念是坐标系统,当我们提及一个地理位置的时候,与之伴随而产生的是该位置必定在一个空间参考下。当我们使用GPS设备获取到某个位置的经纬度的时候,我们实际上得到的是一个WGS-84椭球坐标系统下的空间地理坐标。目前空间坐标系统已经十分繁多,这些坐标系统有着特定的使用场合,并且可以通过一定的方式实现它们之间的相互转换,本文提到的Proj.4库正是这样一个提供了不同坐标系统(空间参考)之间相互转换的强大的工具。关于空间参考的详细介绍以及它们之间的转换方法可以参考以下的内容:Geometric Aspects of Mapping
C:\> cd proj //进入Proj.4源码目录(以自己的位置为准) C:\PROJ> nmake /f makefile.vc C:\PROJ> nmake /f makefile.vc install-all3.由于使用的是默认的命令,因此最终编译的结果会出现在C盘根目录下的PROJ目录下,目录结构如下:
#include <proj_api.h> #include <iostream> int main(int argc, char **argv) { projPJ pj_merc, pj_latlong; double x, y; if (!(pj_merc = pj_init_plus("+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"))) exit(1); if (!(pj_latlong = pj_init_plus("+proj=longlat +datum=WGS84 +no_defs"))) exit(1); x = -9.866554; y = 7.454779; x *= DEG_TO_RAD; y *= DEG_TO_RAD; pj_transform(pj_latlong, pj_merc, 1, 1, &x, &y, NULL); std::cout.precision(12); std::cout << "(" << x << " , " << y << ")" << std::endl; exit(0); }基本上我们需要调用的是proj4提供的函数 pj_transform函数,它的函数原型如下:
int pj_transform( projPJ src, projPJ dst, long point_count, int point_offset, double *x, double *y, double *z );我们传入 需要转换数据的坐标系统(源)和转换到指定的坐标系统(目标),由于上面的示例程序中只有一个点需要转换,并且这些数据之间也不存在着间隔,都是紧密排列的,因此后面的两个参数设置为1, x, y, z指针作为传出参数,将最后转换的结果写到x,y,z之中。
#include <proj_api.h> #include <iostream> //(-1098339.76716 , 826673.618947) // x = -9.866554; //y = 7.454779; int main(int argc, char **argv) { projPJ pj_merc, pj_latlong; double x, y; if (!(pj_merc = pj_init_plus("+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"))) exit(1); if (!(pj_latlong = pj_init_plus("+proj=longlat +datum=WGS84 +no_defs"))) exit(1); x = -1098339.76716; y = 826673.618947; pj_transform(pj_merc, pj_latlong, 1, 1, &x, &y, NULL); std::cout.precision(12); std::cout << "(" << x /DEG_TO_RAD<< " , " << y/DEG_TO_RAD << ")" << std::endl; exit(0); }
int pj_datum_transform( projPJ src, projPJ dst, long point_count, int point_offset, double *x, double *y, double *z );x, y, z的输入和输出均是 BLH(经纬高程),src和dst的参数必须包含基准面转换的参数(+towgs84):可以是三参数或者七参数,类似于:
+towgs84=-199.87,74.79,246.62 +towgs=0,0,4.5,0,0,0.554,0.219
int pj_geocentric_to_geodetic( double a, double es, long point_count, int point_offset, double *x, double *y, double *z ); int pj_geodetic_to_geocentric( double a, double es, long point_count, int point_offset, double *x, double *y, double *z );在转换为地心坐标之后,我们可以根据两个不同地心坐标系下面得到几个已知控制点计算出它们之间的三参数(需要1个已知控制点对)或者七参数(需要三个已知控制点对)