Proj.4 升级新版本5.x和6.x
目錄
- Proj.4 升級新版本5.x和6.x
- 0、緣起
- 1、5.x和6.x更新情況簡述
- PROJ 5.x 更新
- PROJ 6.x 更新
- 2、從PROJ.4向新版本遷移
- 遷移到5.x版本
- 遷移到6.x版本
Proj.4 升級新版本5.x和6.x
0、緣起
今天(2019年5月30日)去編譯最新版本的GDAL,發現其對Proj.4的依賴已經要求為6.x版本了。于是去https://github.com/OSGeo/proj.4看了一下最新的代碼,又去https://proj4.org/看了一下文檔,感覺5.x和6.x的更新挺大的,有必要測試一下,看工作中的項目是不是要升級過來。
1、5.x和6.x更新情況簡述
我沒有仔細去看5.x版本的代碼,僅看了一下最新的Proj.4 版本6的代碼,與早前使用的4.9.3版本簡單對比了一下,感覺區別還是挺大的,這里列出幾點我關注的地方的對比。
1、新版本改用C++編寫,相比4.9版本代碼量增加了不少,功能也多了不少。代碼層次結構清晰了許多,比如各種轉換算法都在src/transformations目錄下可以找到,各種投影方法相關的算法都在src/projections目錄可以找到。
2、支持了從WKT/WKT2字符串和EPSG代碼直接創建坐標系對象,也支持導出WKT字符串。老版本中記錄EPSG坐標系定義的的nad/epsg被棄用,改用SQLite數據庫來記錄(在data/sql目錄下保存著用于生成proj.db文件的SQL腳本),不過新版本需要依賴SQLite3。
3、新版的實現使用了緩存機制,在創建操作坐標系對象及搜索查找等都有用到。代碼可見 src/iso19111/factory.cpp、src/iso19111/crs.cpp、src/iso19111/coordinateoperation.cpp、
src/iso19111/coordinateoperation.cpp 等文件。
4、新版添加了proj_math.h、math.cpp,添加了pj_hypot等函數,這解決了一些編譯問題(因為之前版本projects.h中聲明了hypot函數,但這個函數在非_WIN32環境中也可能是存在math.h中的)。
以下主要翻譯自:PROJ.4 News
PROJ 5.x 更新
此版本的 PROJ 對系統的大地測量功能 (主要是) 引入了一些重要的擴展和改進。
引入新功能的主要驅動因素是動態參考框架的出現、高精度全球導航衛星系統的使用日益增加以及對精確坐標變換的相關需求的增加。雖然舊版本的 PROJ 包含一些大地測量功能, 但新框架為將 PROJ 轉變為通用地理空間坐標轉換引擎奠定了基礎。
內部架構也有了許多變化和改進。到目前為止,這些改進都遵循現有的編程接口。但是這個過程已經顯示出需要簡化和減少代碼庫,以支持持續的主動開發。
新的主要版本號使該項目在名稱上留下了一些難題。在產品的大部分使用壽命中,它被稱為PROJ.4,但由于我們現在已達到版本5,因此名稱不再與版本號對齊。
因此,我們決定將名稱與版本號和該版本分離,然后將產品簡稱為PROJ。為了表彰軟件的歷史,我們將PROJ.4作為組織項目的名稱。同一個項目團隊也會生成datum-grid 包。
綜上所述:
- PROJ.4項目提供產品PROJ,現在版本為5.0.0。
- PROJ的基礎組件是庫libproj。
- 其他PROJ組件包括應用程序proj,它為libproj提供命令行界面。
- PROJ.4項目還分發了基準網格(datum-grid)包,在編寫本文時,它是1.6.0版本。
5.0.0 更新
推出新的API在proj.h
- 新版API增加了4D空間坐標轉換功能
- 新API中的函數使用proj_命名空間(名稱前綴)
- 新API中的數據類型使用PJ_命名空間(名稱前綴)
引入“轉換管道”(transformation pipelines)的概念,可以通過 菊花鏈 的方式簡化坐標操作,可以對坐標進行復雜的大地轉換。
采用 OGC/ISO-19100 地理空間標準系列術語。關鍵定義是:
- 在通用層面上,坐標操作是基于從一個坐標參考系統到另一個坐標參考系統的一對一關系的坐標變換。
- 變換(transformation )是一種坐標操作,其中兩個坐標參考系統基于不同的基準,例如,從全局參考框架改變到區域框架。
- 轉換(conversion )是一種坐標操作,其中兩個坐標參考系統都基于相同的數據,例如,坐標單位的變化。
- 投影是從橢球坐標系到平面坐標系的坐標轉換。雖然投影只是根據標準進行的轉換, 但它們在 PROJ 中被視為單獨的實體, 因為它們占庫中絕大多數操作。
新操作
- 管線操作 The pipeline operator (pipeline)
- 變換 Transformations
- 霍默特變換 Helmert transform (helmert)
- 霍納實數和復數的多項式評估 (horner)
- Horizontal gridshift (hgridshift)
- Vertical gridshift (vgridshift)
- 莫洛金斯基變換 Molodensky transform (molodensky)
- Kinematic gridshift with deformation model (deformation)
- 轉換 Conversions
- 單位轉換 Unit conversion (unitconvert)
- 軸向交換 Axis swap (axisswap)
- 投影 Projections
- 中央圓錐投影 Central Conic projection (ccon)
新的“自由格式”(free format)選項,運行在指定key/value鍵值對時候通過空白字符進行分割標記,例如proj = merc lat_0 = 45
添加到init-files的元數據,可以通過proj.h中新的API函數proj_init_info()讀取它們。
添加了具有ITRF轉換參數的ITRF2000,ITRF2008和ITRF2014初始化文件,包括板塊運動模型參數。
添加橢球參數到GSK2011,PZ90和"danish"。后者類似于已經支持的andrae橢球體,但長半軸略微不同。
添加哥本哈根本初子午線.
將EPSG數據庫更新至9.2.0版。
Geodesic庫已更新至1.49.2-c版。
對分析性偏導數的支持已被移除。
改善了Winkel Tripel和Aitoff的表現。
將pj_has_inverse()函數引入proj_api.h,使用它檢測一個操作是否可反轉,而不是檢測P->inv是否存在。
ABI版本號更新為13:0:0。
刪除了對Windows CE的支持。
刪除了VB6 COM接口。
5.1.0 更新
- 添加函數proj_errno_string() 到 proj.h
- 驗證管道步驟之間的單位,并確保轉換的完整性。
- 在沒有參數的情況下調用cct和gie程序時打印幫助。
- CITATION文件添加到源碼發行。
- 添加了Web墨卡托操作。
- 提高了赤道附近(4326)向spherical Mercator(3857)前向轉換的數值精度。
- 為cct添加了--skip-lines選項。
- 始終對輸入NaN 處返回Nan值。
- 移除沒有使用的src/org_proj4_Projections.h文件。
- Java Native Interface綁定已更新
- 水平和垂直網格移位操作擴展到時域(temporal domain)。
5.2.0 更新
- 在unitconvert中增加了對deg,rad和grad的支持。
- 當沒有另外指定時,假設+t_epoch為時間輸入。
- 添加了逆拉格朗日投影。
- 添加-multiplier選項到vgridshift。
- 添加等地球投影。(等地球地圖投影是用于世界地圖的新的等面積假圓柱投影)
- 為gie添加了“require_grid”選項。
- 將 Helmert 變換的+transpose選項替換為+convention。從現在開始應當顯示指定convertion使用,使用+transpose選項將返回錯誤。
- 改進的逆spherical Mercator投影數值精度
- 當前cct會將前向輸入的坐標,轉發到輸出流。 (#1111)
PROJ 6.x 更新
PROJ6 進行了廣泛的更改, 以增加其功能范圍, 從具有所謂 "早期綁定" 大地測量基準轉換功能的制圖投影引擎, 到更完整的庫, 支持坐標變換和坐標參考系統。
作為其他增強功能的基礎, PROJ 現在包括由 iso-19111:2019 標準/OGC 抽象規范主題 2: "按坐標引用" 的模型的 C++ 實現, 用于大地測量參照框 (基準), 坐標參考系統和協調操作。這些大地測量對象的構造和查詢可通過新的 C++ API 進行, 并且在很大程度上可以從 C API 中的綁定中訪問。
這些大地測量對象可以從 OGC 已知文本格式 (WKT) 以不同的變體導入和導出: ESRI WKT、GDAL WKT 1、WKT2:2015 (ISO 191.2: 2015) 和 WKT2:2018 (ISO 19162: 2018)。還支持從 PROJ 字符串導入和導出 crs 對象。此功能以前在 GDAL 軟件庫中可用 (WKT2 支持除外, 這是一項新功能), 現在是 PROJ 不可或缺的一部分。
現在, sqlite3 數據庫文件 proj.db 中提供了一個統一的大地測量對象數據庫、坐標參考系統及其元數據以及這些 CRS 之間的坐標操作。這包括從 IOMP EPSG 數據集 (v9.6.0 版本)、法國國家測繪機構大地測量登記冊和 ESRI 投影引擎數據庫中導入的定義。PROJ 現在是此 CRS 和坐標操作數據庫的 "OSGeo C stack" 中的參考軟件, 而以前此功能分布在 PROJ、GDAL 和歌詞地理, 并使用 CSV 或其他基于特定文本的格式。
添加了考慮到元數據 (如使用區域和準確性) 的后期綁定坐標操作功能。這可以在許多情況下避免過去使用 WGS84 作為中間系統的要求, 這可能會導致不必要的精度損失, 或者在無法轉換到 WGS84 的情況下有時是無法實現的。這些后期綁定功能現在由 proj_create_crs_to_crs() 函數和 cs2cs 實用程序使用。
添加了一個新的命令行實用程序 projinfo 來查詢有關數據庫的大地測量對象的信息, 從 WKT 字符串和 PROJ 字符串導入和導出大地測量對象, 并顯示兩個 CRS(坐標參考系統) 之間可用的坐標操作。
6.0.0 更新
- 公開接口中移除projects.h(當前僅作為內部接口)(#835)
- 不推薦使用proj_api.h接口。頭文件仍然可用,但將在下一個主要版本的PROJ中刪除?,F在需要定義ACCEPT_USE_OF_DEPRECATED_PROJ_API_H宏接口才可用。 (#836)
- 刪除了對nmake構建系統的支持。(#838)
- 刪除對proj_def.dat 默認文件的支持。 (#201)
- 構建PROJ需要支持C++11編譯器。
- 構建添加對SQLite 3.7的依賴。(#1175)
- 添加 projinfo 命令行程序。
- 添加一些用于處理ISO19111功能函數的到proj.h。(#1175)
- 更新了cs2cs以使用后期綁定特性。(#1182)
- 移除 nad2bin 程序?,F在可以在proj-datumgrid倉庫中查看。
- 在proj中刪除了對Chebyshev多項式的支持
- 從proj.h中移除proj_geocentric_latitude() API
- 更改proj行為:現在只允許投影的初始化 (#1162)
- 更改tmerc行為:現在默認擴展橫軸墨卡托算法 (etmerc)。舊的實現可以通過添加 +approx參數(#404)
- 更改行為:默認橢球現在設置為GRS80 (之前是WGS84) (#1210)
- 允許在 PROJ_LIB 環境變量中使用多個目錄 (#1218)
- 添加Lambert Conic Conformal (2SP Michigan) 投影 (#1142)
- 添加 Bertin1953 投影 (#1133)
- 添加Tobler-Mercator 投影 (#1153)
- 添加Molodensky-Badekas 變換 (#1160)
- 添加push 和pop 坐標操作 (#1250)
- 添加+t_obs 參數,從helmert 和deformation中 (#1264)
- 添加+dt 參數到deformation中,用于替換移除的 +t_obs (#1264)
6.1.0 更新
- 包含 QGIS 中定義的橢球 (#1137)
- 添加 -k ellipsoid 選項到 projinfo (#1338)
- cs2cs支持4D坐標 (#1355)
- WKT2 解析:更新到OGC 18-010r6 (#1360 #1366))
- 更新googletest內部版本到v1.8.1 (#1361)
- 數據庫更新:EPSG v9.6.2 (#1462), IGNF v3.0.3, ESRI 10.7.0 并添加operation_version列(#1368)
- 添加proj_normalize_for_visualization() 嘗試應用大多數 GIS 應用和 PROJ <6 使用的軸序 (#1387)
- 添加 noop(空)操作 (#1391)
- 用戶設置的路徑優先于 PROJ_LIB 搜索路徑 (#1398)
- 縮小數據庫大小 (#1438)
- 添加對compoundCRS 和concatenatedOperation組件命名的支持 (#1441)
2、從PROJ.4向新版本遷移
以下內容主要來自Version 4 to 5/6 API Migration。
遷移到5.x版本
這是希望將代碼遷移到使用PROJ 5的開發人員的過渡指南。
背景
原文太長,這里簡單抽取一部分。
1、之前老的API兩個坐標參考系統之間的任何轉換都必須通過未明確定義的WGS84框架進行中轉,新的API取消了對PROJ中轉換的限制。雖然任然可以進行這種類型的轉換,但是在多數情況下,有更好的替代方案。
2、如果你只關心到米級精度,那么舊的API是夠用的。但是WGS84并非真實世界的基礎,其它一切都可以通過WGS84進行轉換的觀點是有缺陷的。并且這里說的WGS84是6個實現中的哪一個呢?
3、對許多坐標系統而言,轉換到WGS84,在舊系統之間可能變換精度在厘米級。
4、hub(這里說的就是把所有坐標之間的轉換都通過WGS84做中轉)框架("基準")概念本身沒有大問題。但世界本質是4維的,為了獲得大地測量精確變換,可能需要在四個維度下計算,新的API允許這樣做。
舊的API下,坐標從坐標系A轉換到坐標系B的過程,需要從A變換到WGS84(反算),再從WGS84變換到B(正算)
$ echo 300000 6100000 | cs2cs +proj=utm +zone=33 +ellps=GRS80 +to +proj=utm +zone=32 +ellps=GRS80 683687.87 6099299.66 0.00新的命令行工具cct使用新的API,所以同樣的轉換可能結果不一樣
$ echo 300000 6100000 0 0 | cct +proj=pipeline +step +inv +proj=utm +zone=33 +ellps=GRS80 +step +proj=utm +zone=32 +ellps=GRS80 683687.8667 6099299.6624 0.0000 0.0000
代碼示例
這里顯示了舊API和新API之間的區別,并舉了幾個例子。 下面我們用兩個不同的API實現相同的程序。 程序從命令行讀取輸入經度和緯度,并使用墨卡托投影將它們轉換為投影坐標。
我們首先編寫PROJ v.4的程序:
#include <proj_api.h>main(int argc, char **argv) {projPJ pj_merc, pj_longlat;double x, y;// 創建坐標參考系對象if (!(pj_longlat = pj_init_plus("+proj=longlat +ellps=clrk66")) )return 1;if (!(pj_merc = pj_init_plus("+proj=merc +ellps=clrk66 +lat_ts=33")) )return 1;// PROJ.4 API 默認的經緯度都是使用弧度值while (scanf("%lf %lf", &x, &y) == 2) {x *= DEG_TO_RAD; /* 經度 */y *= DEG_TO_RAD; /* 緯度 */// 進行坐標轉換p = pj_transform(pj_longlat, pj_merc, 1, 1, &x, &y, NULL );printf("%.2f\t%.2f\n", x, y);}pj_free(pj_longlat);pj_free(pj_merc);return 0; }使用PROJ v.5實現的相同程序:
// 使用新的頭文件 #include <proj.h>main(int argc, char **argv) {PJ *P;PJ_COORD c;// 創建墨卡托投影坐標系P = proj_create(PJ_DEFAULT_CTX, "+proj=merc +ellps=clrk66 +lat_ts=33");if (P==0)return 1;while (scanf("%lf %lf", &c.lp.lam, &c.lp.phi) == 2) {// 度轉弧度c.lp.lam = proj_torad(c.lp.lam);c.lp.phi = proj_torad(c.lp.phi);// 進行坐標轉換(正算)c = proj_trans(P, PJ_FWD, c);printf("%.2f\t%.2f\n", c.xy.x, c.xy.y);}proj_destroy(P); }新舊API函數對照表
| pj_fwd | proj_trans() |
| pj_inv | proj_trans() |
| pj_fwd3 | proj_trans() |
| pj_inv3 | proj_trans() |
| pj_transform | proj_trans_array or proj_trans_generic |
| pj_init | proj_create() |
| pj_init_plus | proj_create() |
| pj_free | proj_destroy() |
| pj_is_latlong | proj_angular_output() |
| pj_is_geocent | proj_angular_output() |
| pj_get_def | proj_pj_info() |
| pj_latlong_from_proj | No equivalent |
| pj_set_finder | No equivalent |
| pj_set_searchpath | No equivalent |
| pj_deallocate_grids | No equivalent |
| pj_strerrno | No equivalent |
| pj_get_errno_ref | proj_errno() |
| pj_get_release | proj_info() |
遷移到6.x版本
這是希望遷移代碼以使用PROJ 6的開發人員的過渡指南。
代碼示例
這里顯示了舊API和新API之間的區別,并舉了幾個例子。 下面我們用兩個不同的API實現相同的程序。 程序從命令行讀取輸入經度和緯度,并使用墨卡托投影將它們轉換為投影坐標。
我們首先編寫PROJ v.4的程序:
#include <proj_api.h>main(int argc, char **argv) {projPJ pj_merc, pj_longlat;double x, y;// 創建坐標參考系對象if (!(pj_longlat = pj_init_plus("+proj=longlat +ellps=clrk66")) )return 1;if (!(pj_merc = pj_init_plus("+proj=merc +ellps=clrk66 +lat_ts=33")) )return 1;// PROJ.4 API 默認的經緯度都是使用弧度值while (scanf("%lf %lf", &x, &y) == 2) {x *= DEG_TO_RAD; /* 經度 */y *= DEG_TO_RAD; /* 緯度 */// 進行坐標轉換p = pj_transform(pj_longlat, pj_merc, 1, 1, &x, &y, NULL );printf("%.2f\t%.2f\n", x, y);}pj_free(pj_longlat);pj_free(pj_merc);return 0; }使用PROJ v.6實現的相同程序:
#include <proj.h>main(int argc, char **argv) {PJ *P;PJ_COORD c;/* 注意: 在PROJ 6中強烈建議不要使用 PROJ 格式字符串來定義 CRS ,因為 PROJ 格式字符串*//* 不是描述 CRS 的一種好方式,準確說來是其對大地基準的描述不夠詳細。 *//* 使用權威機構提供的坐標系代碼(例如"EPSG:4326", etc...)或者WKT字符串來創建,將能夠 *//* 充分利用PROJ的“transformation engine”來確定兩個CRS直接的最佳轉換方式 */P = proj_create_crs_to_crs(PJ_DEFAULT_CTX,"+proj=longlat +ellps=clrs66","+proj=merc +ellps=clrk66 +lat_ts=33",NULL);if (P==0)return 1;{/* 對于特定的使用情況下(轉換前后坐標系已知),這是沒有必要的。 *//* proj_normalize_for_visualization() 確保預期坐標順序和由 proj_trans() *//* 返回的順序是 大地坐標系下先經度后緯度,投影坐標系下先東向后北向 *//* 如果不是使用上面的PROJ字符串,而是使用 "EPSG:XXXX" 代碼,這可能是必要的。 */PJ* P_for_GIS = proj_normalize_for_visualization(C, P);if( 0 == P_for_GIS ) {proj_destroy(P);return 1;}proj_destroy(P);P = P_for_GIS;}while (scanf("%lf %lf", &c.lp.lam, &c.lp.phi) == 2) {/* 不需要轉換到弧度 */c = proj_trans(P, PJ_FWD, c);printf("%.2f\t%.2f\n", c.xy.x, c.xy.y);}proj_destroy(P); }新舊API函數對照表
| pj_fwd | proj_trans() |
| pj_inv | proj_trans() |
| pj_fwd3 | proj_trans() |
| pj_inv3 | proj_trans() |
| pj_transform | proj_create_crs_to_crs() + (proj_normalize_for_visualization() +) proj_trans(), proj_trans_array() or proj_trans_generic() |
| pj_init | proj_create() / proj_create_crs_to_crs() |
| pj_init | proj_create() / proj_create_crs_to_crs() |
| pj_free | proj_destroy() |
| pj_is_latlong | proj_get_type() |
| pj_is_geocent | proj_get_type() |
| pj_get_def | proj_pj_info() |
| pj_latlong_from_proj | No direct equivalent, but can be accomplished by chaining proj_create(), proj_crs_get_horizontal_datum() and proj_create_geographic_crs_from_datum() |
| pj_set_finder | proj_context_set_file_finder() |
| pj_set_searchpath | proj_context_set_search_paths() |
| pj_deallocate_grids | No equivalent |
| pj_strerrno | No equivalent |
| pj_get_errno_ref | proj_errno() |
| pj_get_release | proj_info() |
轉載于:https://www.cnblogs.com/oloroso/p/10955620.html
總結
以上是生活随笔為你收集整理的Proj.4 升级新版本5.x和6.x的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python爬虫案例-陶瓷公司数据爬取
- 下一篇: Java通过JDBC连接SQL Serv