proj4-6.3.1编译及使用示例

新版本的 proj4 (官方说这个项目虽然版本已经升级了,但是还是叫 proj4),相对于旧版本已经有了很大的变化,这在《Proj.4 升级新版本5.x和6.x》 有详细说明。

Proj.4-4.9版本及使用链接:https://www.cnblogs.com/oloroso/p/5672837.html

编译准备工作

  1. sqlite3

    因为现在的版本,采用 sqlite3 文件来存储各种坐标系统的定义等信息,所以新版本的必须依赖 sqlite3 才行。

    SQLite3 的编译,这里就不介绍了,这里给出一个编译好的版本【sqlite3-msvc142-x64】 (下载源码包,cl /Ox shell.c sqlite3.c MSVCRT.LIB)。其它平台的可以直接下载 sqlite 官网的预编译二进制版本,也可以使用包管理器安装。

  2. proj 源码

    可以直接去官网下载,我这里下载的是 6.3.1 版本的,我写这个文章的时候,它已经发布了 6.3.2 版本,这里对编译来说没啥变化,都是一些 Bug 的修复。

    题外话:当前 Proj 项目正在开发 7.x 版本,这个版本看介绍变化比较大,这里不细述了。

windows下使用 VS2019 编译

我这里是在 git-bash 下操作的,所以命令不是 DOS 命令。

编译好的版本可以在这里下载:proj-msvc142-x64-output.7z

编译过程简述:

  1. 解压源码,进入源码目录,创建一个构建目录。

    # 我这里下载到了 D:/Downloads/temp/OSGeo-PROJ-6.3.1.tar.gz
    mkdir OSGeo-PROJ-6.3.1
    tar -xzf  OSGeo-PROJ-6.3.1.tar.gz -C OSGeo-PROJ-6.3.1  # 解压
    mkdir OSGeo-PROJ-6.3.1/PROJ-6.3.1/build-win            # 创建用于构建的目录
    cd OSGeo-PROJ-6.3.1/PROJ-6.3.1/build-win               # 进入目录
    
  2. 使用 cmake 命令生成 VS 2019 项目。

    # 使用 cmake 生成项目
    # 下面指定了 构建类型;sqlite3 相关文件路径;C++标准;输出目录;关闭gmock;不构建动态库;关闭 gtest 强制共享crt
    export SQLITE3_ROOT=D:/Downloads/temp/OSGeo-PROJ-6.3.1/sqlite3
    cmake .. -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DSQLITE3_LIBRARY="${SQLITE3_ROOT}/lib/sqlite3.lib" -DSQLITE3_INCLUDE_DIR="${SQLITE3_ROOT}/include" -DEXE_SQLITE3="${SQLITE3_ROOT}/bin/sqlite3.exe" -DCMAKE_CXX_STANDARD=11 -DCMAKE_INSTALL_PREFIX="./output" -DBUILD_GMOCK=OFF -DBUILD_LIBPROJ_SHARED=OFF -Dgtest_force_shared_crt=OFF
    

    注意:执行 cmake 的过程中会下载 gtest,所以需要联网。

  3. 使用 msbuild 编译生成。

    这里需要打开 x64 Native Tools Command Prompt for VS 2019 ,然后进入上面创建的构建目录,再执行 msbuild 命令进行构建。

    # 进入构建目录
    cd D:Downloads	empOSGeo-PROJ-6.3.1PROJ-6.3.1uild-vs2019
    # 执行构建,这里只构建 Release 版本
    msbuild ALL_BUILD.vcxproj /p:Configuration="Release"
    # 构建完成后输出到目标目录
    msbuild INSTALL.vcxproj /p:Configuration="Release"
    

cmake 命令执行记录

cmake .. -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DSQLITE3_LIBRARY="${SQLITE3_ROOT}/lib/sqlite3.lib" -DSQLITE3_INCLUDE_DIR="${SQLITE3_ROOT}/include" -DEXE_SQLITE3="${SQLITE3_ROOT}/bin/sqlite3.exe" -DCMAKE_CXX_STANDARD=11 -DCMAKE_INSTALL_PREFIX="./output" -DBUILD_GMOCK=OFF -DBUILD_LIBPROJ_SHARED=OFF -Dgtest_force_shared_crt=OFF
-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
-- The C compiler identification is MSVC 19.25.28614.0
-- The CXX compiler identification is MSVC 19.25.28614.0
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Requiring C++11
-- Requiring C++11 - done
-- Requiring C99
-- Requiring C99 - done
--
-- Configuring PROJ:
--
-- PROJ_VERSION                             = 6.3.1
-- PROJ_ABI_VERSION                         = 6_3
-- Looking for include file dlfcn.h
-- Looking for include file dlfcn.h - not found
-- Looking for include file inttypes.h
-- Looking for include file inttypes.h - found
-- Looking for include file jni.h
-- Looking for include file jni.h - not found
-- Looking for include file memory.h
-- Looking for include file memory.h - found
-- Looking for include file stdint.h
-- Looking for include file stdint.h - found
-- Looking for include file stdlib.h
-- Looking for include file stdlib.h - found
-- Looking for include file string.h
-- Looking for include file string.h - found
-- Looking for include file sys/stat.h
-- Looking for include file sys/stat.h - found
-- Looking for include file sys/types.h
-- Looking for include file sys/types.h - found
-- Looking for include file unistd.h
-- Looking for include file unistd.h - not found
-- Looking for 4 include files stdlib.h, ..., float.h
-- Looking for 4 include files stdlib.h, ..., float.h - found
-- Looking for localeconv
-- Looking for localeconv - found
-- Looking for strerror
-- Looking for strerror - found
-- Looking for ceil in m
-- Looking for ceil in m - not found
-- Found Sqlite3: D:/Downloads/temp/OSGeo-PROJ-6.3.1/sqlite3/lib/sqlite3.lib
-- Sqlite3 version: 3.31.1
-- Looking for pthread.h
-- Looking for pthread.h - not found
-- Found Threads: TRUE
-- PROJ_TESTS                               = ON
--
-- Configuring proj library:
--
-- ENABLE_LTO                               = OFF
-- JNI_SUPPORT                              = OFF
-- PROJ_CORE_TARGET                         = proj
-- PROJ_CORE_TARGET_OUTPUT_NAME             = proj_6_3
-- PROJ_LIBRARY_TYPE                        = STATIC
-- PROJ_LIBRARIES                           = proj
-- Using internal GTest
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Downloads/temp/OSGeo-PROJ-6.3.1/PROJ-6.3.1/build-win/googletest-download
用于 .NET Framework 的 Microsoft (R) 生成引擎版本 16.5.0+d4cbfca49
版权所有(C) Microsoft Corporation。保留所有权利。

  Checking Build System
  Creating directories for 'googletest'
  Building Custom Rule D:/Downloads/temp/OSGeo-PROJ-6.3.1/PROJ-6.3.1/build-win/googletest-download/CMakeLists.txt
  Performing download step (download, verify and extract) for 'googletest'
  -- Downloading...
     dst='D:/Downloads/temp/OSGeo-PROJ-6.3.1/PROJ-6.3.1/build-win/googletest-download/googletest-prefix/src/release-1.8.1.zip'
     timeout='none'
  -- Using src='https://github.com/google/googletest/archive/release-1.8.1.zip'
  -- verifying file...
         file='D:/Downloads/temp/OSGeo-PROJ-6.3.1/PROJ-6.3.1/build-win/googletest-download/googletest-prefix/src/release-1.8.1.zip'
  -- Downloading... done
  -- extracting...
       src='D:/Downloads/temp/OSGeo-PROJ-6.3.1/PROJ-6.3.1/build-win/googletest-download/googletest-prefix/src/release-1.8.1.zip'
       dst='D:/Downloads/temp/OSGeo-PROJ-6.3.1/PROJ-6.3.1/build-win/googletest-src'
  -- extracting... [tar xfz]
  -- extracting... [analysis]
  -- extracting... [rename]
  -- extracting... [clean up]
  -- extracting... done
  No update step for 'googletest'
  No patch step for 'googletest'
  No configure step for 'googletest'
  No build step for 'googletest'
  No install step for 'googletest'
  No test step for 'googletest'
  Completed 'googletest'
  Building Custom Rule D:/Downloads/temp/OSGeo-PROJ-6.3.1/PROJ-6.3.1/build-win/googletest-download/CMakeLists.txt
-- Found PythonInterp: C:/scoop/apps/python/current/python.exe (found version "3.8.2")
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Downloads/temp/OSGeo-PROJ-6.3.1/PROJ-6.3.1/build-win

linux 下使用 gcc 9 编译

这里编译比较简单,就只记录下使用的命令了。

# 1、下载
wget https://github.com/OSGeo/PROJ/releases/download/6.3.1/proj-6.3.1.tar.gz
# 2、解压,创建构建目录;这里要注意,文件名是区分大小写的,Windows 上是不区分的
mkdir proj-6.3.1 && tar -xzf proj-6.3.1.tar.gz -C proj-6.3.1
mddir proj-6.3.1/proj-6.3.1/build-linux && cd proj-6.3.1/proj-6.3.1/build-linux
# 3、执行 cmake 命令,生成 Makefile;这里不指定 sqlite3 路径,因为已经安装到系统路径
cmake .. -DCMAKE_CXX_STANDARD=11 -DCMAKE_INSTALL_PREFIX="./output" -DBUILD_GMOCK=OFF -DBUILD_LIBPROJ_SHARED=OFF -Dgtest_force_shared_crt=OFF
# 4、进行编译
make -j2
# 5、编译好的文件安装到输出目录
make install

使用示例说明

这里只是对 https://proj.org/development/quickstart.html 里面内容的一个简单介绍。

#include <stdio.h>
#include <proj.h>

int main (void) {
    PJ_CONTEXT *C;
    PJ *P;
    PJ* P_for_GIS;
    PJ_COORD a, b;
    // 创建一个上下文对象,这个是非线程安全的,建议为每个线程都创建一个
    // 如果是单线程使用,可以直接使用 PJ_DEFAULT_CTX ,而不创建
    C = proj_context_create();
    
    // 这里需要先设置一下 proj.db 文件的搜索目录
    const char* proj_share_path = "./output/share/proj/";
    proj_context_set_search_paths(C, 1, &proj_share_path);
    
	// 创建一个坐标系转换处理对象
    // 第二个参数是源坐标系,第三个参数是目标坐标系
    // 可以输入3种形式:1 EPGS编号;2 proj4 字符串;3 OGC WKT 字符串
    // 最后一个参数是一个 PJ_AREA ,用于指定 执行转换的区域 ,以便提供更精确的转换
    // NULL 表示不指定转换执行区域。
    // 可以通过 proj_area_create 来创建,然后使用 proj_area_set_bbox 来设置范围。
    P = proj_create_crs_to_crs (C,
                                "EPSG:4326",
                                "+proj=utm +zone=32 +datum=WGS84", /* or EPSG:32632 */
                                NULL);
    // 这里也可以通过 proj_create 函数创建两个坐标系
    // 然后使用 proj_create_crs_to_crs_from_pj 来创建转换处理对象

    if (0==P) {
        fprintf(stderr, "Oops
");
        return 1;
    }

    // 统一坐标系的坐标轴顺序,以便在使用的时候可以不关系坐标系创建参数
    // 所定义的坐标轴顺序。例如 EPSG:4326 要求的坐标顺序是[纬度,经度]
    // 统一之后,输入坐标的时候,坐标输入顺序为
    // 1、地理坐标系,先经度后纬度
    // 2、投影坐标系:先东(X)后北(Y)
    P_for_GIS = proj_normalize_for_visualization(C, P);
    if( 0 == P_for_GIS )  {
        fprintf(stderr, "Oops
");
        return 1;
    }
    proj_destroy(P);
    P = P_for_GIS;
    // 对于 PROJ 字符串定义坐标系,除非指定 +axis 参数对轴序进行修改
    // 不然都是 先经度后纬度,先东后北 的坐标顺序
    // 对于 EPSG 机构定义的地理坐标系,则是 先纬度后经度

    // 下面是哥本哈根的坐标: 东经12度北纬55度
    // 这里也可以这样 a.xy.x = 12; a.xy.y = 55;
    a = proj_coord (12, 55, 0, 0);

    // 转换到 UTM 32带 坐标系,PJ_FWD 是前向转换,就是从源坐标系向目标坐标系转换
    b = proj_trans (P, PJ_FWD, a);
    printf ("东: %.3f, 北: %.3f
", b.enu.e, b.enu.n);
    // 从 UTM 32带转换到 WGS84大地坐标,PJ_INV 是逆向转换
    b = proj_trans (P, PJ_INV, b);
    printf ("经度: %g, 纬度: %g
", b.lp.lam, b.lp.phi);
    // 可以使用 proj_trans_array 来一次转换批量坐标点
    // 如果转换出错,可以使用 en = proj_context_errno(C) 获取 errno
    // 然后使用 proj_errno_string(en) 获取错误消息
    

    // 清理使用对象
    proj_destroy (P);
    // 上下文对象在线程结束前,或不再使用的时候进行销毁
    proj_context_destroy (C); /* 如果是单线程也可忽略这一步 */
    return 0;
}
原文地址:https://www.cnblogs.com/oloroso/p/12869278.html