OSGeo/Proj库编译和使用

proj库编译需要提前编译Sqlite3TIFFCurl库,在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编译过程sqlite3编译过程

使用:在某个资源路径下建立好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目录到配置的文件夹下。

打开项目打开项目

选择install路径选择install路径

勾选install勾选install

安装后安装后

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

最后修改于:2025年01月20日 15:42

添加新评论