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\temp\OSGeo-PROJ-6.3.1\PROJ-6.3.1\build-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\n");
        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\n");
        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\n", b.enu.e, b.enu.n);
    // 從 UTM 32帶轉換到 WGS84大地坐標,PJ_INV 是逆向轉換
    b = proj_trans (P, PJ_INV, b);
    printf ("經度: %g, 緯度: %g\n", 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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM