0

I've not been able to actually get EGM96 to WGS84 transformations to work in PROJ C++. I have however, gotten what I want to work in python, via pyproj, like this:

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()

This provides the result:

(43.70012234, -79.41629234, 62.71016021909354)

And the file us_nga_egm96_15.tif located in the ./proj/ directory However, my replication of the same in C++ doesn't appear to work.

#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; 
}

It actually prints out nothing (some strange character seems to be eating all the other characters), and in debug mode, I can see that b = {inf,inf,inf,inf}. Same thing happens if I don't manually specify the proj locaiton (but make sure the actual .tiff is located there).

What am I doing wrong here?

Krupip
  • 4,404
  • 2
  • 32
  • 54

1 Answers1

0

Something I didn't mention here, is that I was using VCPKG, due to https://github.com/microsoft/vcpkg/pull/16169, it is actually impossible to use GEO TIFF's on linux for PROJ through VCPKG I would recommend simply not using PROJ through VCPKG at all. The issues that are blocking this from being fixed have been blocked for years at this point, and don't seem to be something that is going to be fixed anytime soon.

seen how data is manually set here: https://raw.githubusercontent.com/Microsoft/vcpkg/master/ports/proj4/portfile.cmake

Stepping through the code, the issue was apparently that I set the correct file location, but that the code silently fails when TIFF_ENABLED is not defined.

 //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

Because I was using VCPKG, this was not possible to amend.

Krupip
  • 4,404
  • 2
  • 32
  • 54