Proj.4是开源GIS最著名的地图投影库,许多GIS开源软件的投影都直接或简介的使用Proj.4的库, 该项目遵循MIT license,用C语言编写,由USGS的Gerald I. Evenden在1980年代创立并一直维护到退休,后转手到Frank Warmerdam手中。Warmerdam现任OSGeo主席,于2008年5月把Proj.4纳入成为MetaCRS的一部分。
一直想好好使用和研究Proj.4库,但总是被庞大的英文给吓到了,由于最近总是碰到坐标转换的业务,每次调试或研究转换坐标时都要下个坐标转换工具来进行单独的坐标计算和转换,一直采用的是中海达GPS解算软件自带的CoordMG程序进行坐标转换,主要是方便易用,但必须每次都要下载这个客户端,而且有时候很不容易找到该客户端,考虑到目前是个互谅网的时代,因此萌发了做一个在线的坐标转换系统,界面初步考虑采用CoordMG的界面,考虑到各种投影功能的需求,因此还是决定采用Proj.4这个强大的投影库,认真的看了下Proj.4的使用,发现原来它是这么的简单和方便!
总的来说,Proj.4提供了一下基本函数
pj_init:初始化投影参数
pj_init_plus:初始化投影参数
pj_transform:投影变换
pj_fwd:投影正变换
pj_inv:投影逆变换
pj_free:释放内存
projPJ pj_init(int argc, char** argv)
该函数主要用在命令行中靠接受命令行参数来进行初始化
projPJ pj_init_plus(const char* definition)
利用投影定义参数来初始化一个投影对象projPJ, 如下定义了一个北京54的墨卡托投影,也就是国内常见的高斯投影,中央经度为:+lon_0=116.35025181e
char* beijing1954="+proj=tmerc +ellps=krass +lon_0=116.35025181e +lat_0=39.86576583n +x_0=500000 +y_0=000000 +units=m +k=1.0 +towgs84=22,-118,30.5,0,0,0,0";
projPJ pj = NULL;
void projInit() {
if (!(pj = pj_init_plus(beijing1954))) exit(1); }
void projFree() { pj_free(pj); }
int pj_transform(projPJ srcdefn, projPJ destfn, long point_count,int point_offset, double* x, double* y, double* z );
进行投影变换,x,y,z是出入、输出参数,z可为Null
projPJ pj_merc, pj_latlong; double x, y;
if (!(pj_merc = pj_init_plus("+proj=merc +ellps=clrk66 +lat_ts=33")) ) exit(1);
if (!(pj_latlong = pj_init_plus("+proj=latlong +ellps=clrk66")) ) exit(1);
//x,y为经纬度
x *= DEG_TO_RAD;
y *= DEG_TO_RAD;
p = pj_transform(pj_latlong, pj_merc, 1, 1, &x, &y, NULL );
projXY pj_fwd(projLP lp, projPJ pj );
讲经纬度转换为平面直角坐标
projUV p
p.u *= DEG_TO_RAD
p.v *= DEG_TO_RAD p = pj_fwd(p,pj);
projLP pj_inv(projXY xy, projPJ pj);
讲平面之间坐标转换为经纬度
void pj_free(projPJ pj); 释放projPJ结构内存
其他重要函数
pj_datum_transform
pj_geocentric_to_geodetic
pj_geodetic_to_geocentric
pj_compare_datums
pj_is_latlong pj_is_geocent
int pj_datum_transform(projPJ src, projPJ dst, long point_count, int point_offset, double* x, double* y, double* z )
基准变换(BLH->BLH) x,y,z输入输出均为BLH 注意:src、dst中必须有参数转换参数towgs84参数
3参数:dx,dy,dz,例:+towgs84=-199.87,74.79,246.62
7参数:dx,dy,dz,rx,ry,rz,dscale,例:+towgs=0,0,4.5,0,0,0.554,0.219
dscale是单位,为ppm, Scale=1+dscale/1000000
int pj_geocentric_to_geodetic(double a, double es, long point_count, int point_offset, double* x, double* y, double* z );
根据跟定的椭球,讲地心坐标系统转换为大地坐标(XYZ->BLH)
int pj_geodetic_to_geocentric(double a, double es, long point_count, int point_offset, double* x, double* y, double* z );
根据跟定的椭球,讲大地坐标系统转换为地心坐标(BLH->XYZ)
int pj_compare_datums(projPJ src, projPJ dst );
比较两个投影方式是否采用相同的基准,返回1表示true
int pj_is_latlong(projPJ);
判断是否为经纬度坐标(proj=latlong) 返回1表示true
int pj_is_geocent(projPJ);
判断是否为地心坐标(proj=geocent) 返回1表示true
坐标转换的步骤:
北京54变换到西安80的步骤
1.投影逆变换 北京54 XYH-> 北京54 BLH
2.基准变换 北京54 BLH-> 西安80 BLH
3.投影正变换 西安80 BLH-> 西安80 XYH
敬请期待在线版坐标转换工具 http://cehui0303.yhd.delldns.com/coordinate/default.htm
参考文献:
地图投影变换开源包PROJ.4 http://wenku.baidu.com/view/8c3fa227a5e9856a56126004.html
PROJ.4官网 http://trac.osgeo.org/proj/wiki/ProjAPI
Proj.4的使用示例 http://my.oschina.net/chunquedong/blog/54352
关于GPS坐标转换的基本知识 http://blog.sina.com.cn/s/blog_4c8b1bdd0100gbfq.html