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