如何让 PROJ C++ 识别网格目录?

Posted

技术标签:

【中文标题】如何让 PROJ C++ 识别网格目录?【英文标题】:How to get PROJ C++ to recognize grid directory? 【发布时间】:2021-11-30 12:58:03 【问题描述】:

我实际上无法将 EGM96 转换为 WGS84 以在 PROJ C++ 中工作。然而,我已经通过 pyproj 得到了我想要在 python 中工作的东西,如下所示:

from pyproj import Transformer, CRS
from pyproj.transformer import TransformerGroup, TransformDirection
from pyproj.datadir import append_data_dir, get_data_dir

def main():
    lat = 43.70012234
    lng = -79.41629234
    z = 100


    append_data_dir("/absolute_directory_to/proj/")

    transformer = Transformer.from_crs("epsg:4326", "epsg:5773",)

    results = transformer.transform(lat, lng, z,  None, False, True, TransformDirection.INVERSE)

    print(results)



    

if __name__ == "__main__":
    main()

这提供了结果:

(43.70012234, -79.41629234, 62.71016021909354)

而文件us_nga_egm96_15.tif 位于./proj/ 目录中 但是,我在 C++ 中的复制似乎不起作用。

#include <proj.h> 
#include <filesystem> 
#include <array>  
void main()
    auto proj_context = proj_context_create();
    const char * path =  "/absolute_directory_to/proj";
    const char * db_path = proj_context_get_database_path(proj_context);

    std::filesystem::path db_path_path = std::filesystem::path(db_path);
    std::string db_path_str = db_path_path.parent_path().string();
    std::array paths = path, db_path_str.c_str();
    proj_context_set_search_paths(proj_context, paths.size(), paths.data());

    std::cout << proj_errno_string(proj_context_errno(proj_context)) << std::endl;
    auto temp = proj_create_crs_to_crs (proj_context,
                                        "EPSG:4326",
                                        "EPSG:5773",
                                        NULL);
    std::cout << proj_errno_string(proj_errno(temp)) << std::endl;
    std::cout << proj_errno_string(proj_context_errno(proj_context)) << std::endl;
    auto b = proj_trans(temp, PJ_INV, 43.70012234,-79.41629234,100,0);
    std::cout << proj_errno_string(proj_errno(temp)) << std::endl;
    std::cout << proj_errno_string(proj_context_errno(proj_context)) << std::endl;

    std::cout << b.v[0] << "," << b.v[1] << "," << b.v[2] << "," << b.v[3] << std::endl;
    std::cout << proj_errno_string(proj_errno(temp)) << std::endl;
    std::cout << proj_errno_string(proj_context_errno(proj_context)) << std::endl;

    proj_destroy(temp);

    proj_context_destroy(proj_context);
    return 0; 

它实际上什么也没打印出来(一些奇怪的字符似乎正在吃掉所有其他字符),在调试模式下,我可以看到b = inf,inf,inf,inf。如果我不手动指定项目位置(但要确保实际的 .tiff 位于那里),也会发生同样的事情。

我在这里做错了什么?

【问题讨论】:

【参考方案1】:

我在这里没有提到的一点是,我使用的是 VCPKG,由于 https://github.com/microsoft/vcpkg/pull/16169,实际上 不可能通过 VCPKG 在 linux 上使用 GEO TIFF 用于 PROJ 我建议根本不完全通过 VCPKG 使用 PROJ。在这一点上,阻止此问题得到解决的问题已被阻止多年,而且似乎不会很快得到解决。

在这里查看如何手动设置数据:https://raw.githubusercontent.com/Microsoft/vcpkg/master/ports/proj4/portfile.cmake

单步执行代码,问题显然是我设置了正确的文件位置,但是当 TIFF_ENABLED 未定义时,代码会静默失败。

 //grids.cpp

    if (IsTIFF(header_size, header)) 
#ifdef TIFF_ENABLED
        auto set = std::unique_ptr<VerticalShiftGridSet>(
            GTiffVGridShiftSet::open(ctx, std::move(fp), actualName));
        if (!set)
            pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
        return set;
#else
        pj_log(ctx, PJ_LOG_ERROR,
               "TIFF grid, but TIFF support disabled in this build");
        return nullptr;
#endif

因为我使用的是 VCPKG,所以无法修改。

【讨论】:

以上是关于如何让 PROJ C++ 识别网格目录?的主要内容,如果未能解决你的问题,请参考以下文章

从 C# 解决方案调试 C++ 解决方案

如何使用 C++ 迭代数独子网格?

Python setup.py:如何让 find_packages() 识别子目录中的包

如何在 C++ 中解决网格继承问题

c++ 和 OpenGl:如何从类中创建网格对象实例

如何在 C++ 中按递增顺序绘制球体网格?