OSGeo/Proj库编译和使用
proj库编译需要提前编译Sqlite3
、TIFF
、Curl
库,在linux端可以通过apt或yum等包管理工具进行直接安装,在windows端需要用统一的编译器编译,本文档基于MSVC-2019进行所有库的编译和使用
一、前置依赖安装
1.Sqlite3
下载:https://www.sqlite.org/download.html,点击【sqlite-autoconf-xxxx.tar.gz】然后下载即可。
编译:解压缩后,使用x64 Native Tools Command Prompt for VS 2019
控制台工具,进入解压后的文件,输入以下命令进行编译安装:
#编译
cl -Os -O2 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_COLUMN_METADATA shell.c sqlite3.c -Fesqlite3.exe
#创建静态库
lib sqlite3.obj
#创建动态库
link -dll sqlite3.obj

使用:在某个资源路径下建立好sqlite3文件夹,文件夹中新建lib、include和bin文件夹,分别将,1:sqlite3.h和sqlite3ext.h复制到include路径;2:将sqlite3.lib复制到lib路径;3:将sqlite3.exe和sqlite3.dll复制到bin路径下。
2.TIFF
本次使用qt-creator编译tiff库,最终使用也是在qt项目中进行使用,也可以使用cmake和vs2019等完成编译。
下载:http://download.osgeo.org/libtiff/,下载和proj匹配的版本就行,不知道都下载使用最新版本,这里下载的是tiff-4.7.0.zip。
编译和安装:1:解压缩文件,使用qt-creator打开CMakeList.txt文件,选择对应qt版本下msvc-2019编译器,然后确认即可;2:导航到项目下cmake属性列表,修改CMAKE_INSTALL_PREFIX
为tiff环境文件夹,然后在构建步骤勾选install选项;3:导航到编辑页面,右键构建即可,会自动install生成对应的include、lib和bin目录到配置的文件夹下。




3.Curl
下载:https://github.com/curl/curl/releases/tag/curl-8_11_1,最新版为8.11。
编译:编译过程同tiff库编译,都能一次编译成功。
二、Proj库编译
PROJ 库是一个开源的软件库,专门用于进行坐标参考系统(CRS)之间的转换。它支持广泛的地理空间数据处理任务。PROJ 库允许开发者定义和执行从一个坐标系统到另一个坐标系统的变换,例如从地理坐标系(如 WGS84)转换为投影坐标系(如 UTM);通过 PROJ,用户还可以创建复杂的转换链,处理椭球体参数、投影方法、单位转换等细节问题。
1.下载
下载链接:https://github.com/OSGeo/PROJ/releases/tag/9.5.1,最新版本为9.5.1。
2.配置前置库环境
解压缩后,打开CMakeList.txt,导航到# Check for sqlite3,在下方添加如下环境,具体环境路径需要根据预编译的库进行选择。
################################################################################
# Check for sqlite3
################################################################################
set(SQLite3_INCLUDE_DIR "D:/env/cpp/sqlite3/include")
set(SQLite3_LIBRARY "D:/env/cpp/sqlite3/lib/sqlite3.lib") # 明确指定 .lib 文件
set(TIFF_INCLUDE_DIR "D:/env/cpp/tiff/include")
set(TIFF_LIBRARY "D:/env/cpp/tiff/lib/tiff.lib")
set(CURL_INCLUDE_DIR "D:/env/cpp/curl/include")
set(CURL_LIBRARY "D:/env/cpp/curl/lib/libcurl_imp.lib")
3.编译
编译过程同TIFF库编译,编译完成同样会在安装路径生成对应的include、lib和bin路径。
三、Proj使用
新建项目,使用如下代码进行测试:
#include "proj.h" // 包含 PROJ 库的头文件,提供地理坐标转换功能
#include <iostream> // 包含标准输入输出流库
#include <iomanip> // 包含用于格式化输出的库
using namespace std; // 使用标准命名空间,简化 std::cout 等的调用
int main() {
PJ_CONTEXT* C = nullptr; // 定义一个指针,指向 PROJ 上下文对象,用于管理多线程环境
PJ* P = nullptr; // 定义一个指针,指向投影变换对象
PJ* norm = nullptr; // 定义一个指针,指向标准化后的投影变换对象
PJ_COORD a, b; // 定义两个 PJ_COORD 结构体变量,用于存储坐标数据
// 创建 PROJ 上下文
C = proj_context_create(); // 创建一个新的 PROJ 上下文
if (!C) { // 检查是否成功创建上下文
cerr << "Failed to create PROJ context." << endl;
return 1; // 如果失败,输出错误信息并退出程序
}
// 创建从 EPSG:4326 到 UTM Zone 32N 的坐标转换对象
P = proj_create_crs_to_crs(C,
"EPSG:4326", // 源 CRS (WGS84 地理坐标系)
"+proj=utm +zone=32 +datum=WGS84", // 目标 CRS (UTM Zone 32N)
NULL);
if (!P) { // 检查是否成功创建转换对象
cerr << "Failed to create transformation object." << endl;
proj_context_destroy(C); // 销毁上下文以释放资源
return 1; // 输出错误信息并退出程序
}
// 将转换对象标准化,确保输入坐标按照经度、纬度顺序
norm = proj_normalize_for_visualization(C, P);
if (!norm) { // 检查是否成功标准化转换对象
cerr << "Failed to normalize transformation object." << endl;
proj_destroy(P); // 销毁原始转换对象
proj_context_destroy(C); // 销毁上下文
return 1; // 输出错误信息并退出程序
}
proj_destroy(P); // 释放原始转换对象
P = norm; // 使用标准化后的转换对象
// 定义一个地理坐标点:经度 12°E,纬度 55°N
a = proj_coord(12, 55, 0, 0); // 初始化坐标,第三个和第四个参数通常为高程和时间,这里设置为 0
// 执行正向转换(从地理坐标到 UTM 坐标)
b = proj_trans(P, PJ_FWD, a); // 使用 PJ_FWD 标志进行正向转换
cout << fixed << setprecision(6); // 设置浮点数输出为固定精度,保留六位小数
cout << "East: " << b.xy.x << "; North: " << b.xy.y << endl; // 输出东向和北向坐标
// 执行反向转换(从 UTM 坐标到地理坐标)
b = proj_trans(P, PJ_INV, b); // 使用 PJ_INV 标志进行反向转换
cout << "Longitude: " << b.lp.lam << "; Latitude: " << b.lp.phi << endl; // 输出经度和纬度
// 清理资源
proj_destroy(P); // 销毁转换对象
proj_context_destroy(C); // 销毁上下文
return 0; // 正常结束程序
}
#程序输出
East: 691875.632129; North: 6098907.825129
Longitude: 12.000000; Latitude: 55.000000
完整项目代码:testpro.zip