Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API to determine which grid files were actually used during a transformation #3176

Closed
DalePAtSafe opened this issue Apr 26, 2022 · 6 comments

Comments

@DalePAtSafe
Copy link

As a PROJ user integrating the library into my company’s software I would like to be able to inform my users when a requested grid file in a transformation has resolved to a different file.

For example, currently if the file NTv2_0.gsb in the PROJ search path, but the transformation specified uses ca_nrc_ntv2_0.tif, PROJ will silently use NTv2_0.gsb with no simple way of discovering it has done so. I would like to be able to query the transformation object for the required grids and also what they were resolved to.

Something like the following (API just given as an example of what we’re looking for, it doesn’t need to be exactly this):

Added to proj.h

struct PROJ_GRID_RESOLVE_INFO {
    const char* requested_grid;
    const char* resolved_grid_path;
};
 
PROJ_GRID_RESOLVE_INFO** proj_resolved_grids(PJ* trans, int* out_result_count);

Example Usage:

const char* proj_string = "+proj=hgridshift +grids=ca_nrc_ntv2_0.tif";
 
PJ* transformation = proj_create(nullptr, proj_string);
PJ_COORD coordinate = proj_coord(-123.10876, 49.27782, 0, 0);
proj_trans(transformation, coordinate);
 
PROJ_GRID_RESOLVE_INFO** resolved_grids = nullptr;
int num_resolve_info = 0;
 
resolved_grids = proj_resolved_grids(transformation, &num_resolve_info);
 
for (int i = 0; i < num_resolve_info; ++i) {
    if (resolved_grids[i]->resolved_grid_path != nullptr) {
        std::cout << "Requested grid " << resolved_grids[i]->requested_grid; 
        std::cout << " resolved to " << resolved_grids[i]->resolved_grid_path << std::endl;
    } else {
        std::cout << "Requested grid " << resolved_grids[i]->requested_grid << " not found" << std::endl;
    }
}

Which for my example would print:

Requested grid ca_nrc_ntv2_0.tif resolved to /path/to/NTv2_0.gsb

If networking were enabled and there was no matching grid locally it would print the CDN URL that was used:

Requested grid ca_nrc_ntv2_0.tif resolved to https://cdn.proj.org/ca_nrc_ntv2_0.tif

And of course if it was not found then it would print:

Requested grid ca_nrc_ntv2_0.tif not found

This was motivated by one of our developers trying to put together an example of a transformation that needed networking, and was surprised to discover that the transformation worked even without networking by using a completely different (though equivalent) grid file.

@snowman2
Copy link
Contributor

This can be achieved with the PROJ_DEBUG environment variable.

@DalePAtSafe
Copy link
Author

This can be achieved with the PROJ_DEBUG environment variable.

Adding all of PROJ's debug logging to our application's output isn't really what we're looking for. It also doesn't directly connect the grid that was requested in the transformation to the one that was eventually used, it just shows the files PROJ tried to access without any other context. Additionally it causes PROJ to print it's attempted access to every file that it uses, including proj.db and proj.ini as well as the grids it accesses when determining what transformations to even consider (if we're using proj_create_crs_to_crs). Which is more information than we need.

@snowman2
Copy link
Contributor

These are likely helpful:

PROJ/src/proj.h

Lines 1475 to 1487 in c0e2a9a

int PROJ_DLL proj_coordoperation_get_grid_used_count(PJ_CONTEXT *ctx,
const PJ *coordoperation);
int PROJ_DLL proj_coordoperation_get_grid_used(PJ_CONTEXT *ctx,
const PJ *coordoperation,
int index,
const char **out_short_name,
const char **out_full_name,
const char **out_package_name,
const char **out_url,
int *out_direct_download,
int *out_open_license,
int *out_available);

@DalePAtSafe
Copy link
Author

That gets a little closer to what we're looking for, but unfortunately it stops short of actually telling us which grid was used by a transformation. It mostly just lists information about where the grid could be found. It also has some slightly odd behaviour. The out_full_name parameter will contain the local file that the grid in the transformation resolves to if networking is off, but as soon as you turn networking on it doesn't anymore and it just contains the grid name from the transformation again (like out_short_name), which actually contradicts the behaviour of PROJ itself if I understand how it works correctly, since I'm pretty sure that PROJ will always use local files first, even if it falls back on an old name to do so (using PROJ_DEBUG seems to confirm this). Additionally the CDN set by proj_context_set_url_endpoint seems to not affect the out_url parameter at all. In my testing that always produced the URL as if https://cdn.proj.org was the CDN, regardless of what endpoint was set. That might be a bug (PROJ version 8.1.0).

Regardless even if we could deduce what grid was used from this information (not possible due to the weird behaviour when networking is enabled), I wouldn't want to rely on current knowledge of PROJ's internal behaviour when choosing grids to decide which was the right grid to report to our users, since PROJ's behaviour could change without any obvious external effect.

rouault added a commit to rouault/PROJ that referenced this issue May 3, 2022
rouault added a commit to rouault/PROJ that referenced this issue May 3, 2022
@rouault
Copy link
Member

rouault commented May 3, 2022

@DalePAtSafe #3180 should give you what you need

@DalePAtSafe
Copy link
Author

Thanks Even! Looking forward to testing it out.

rouault added a commit to rouault/PROJ that referenced this issue May 4, 2022
rouault added a commit to rouault/PROJ that referenced this issue May 4, 2022
rouault added a commit to rouault/PROJ that referenced this issue May 4, 2022
@rouault rouault closed this as completed in 5298fc0 May 8, 2022
rouault added a commit that referenced this issue May 8, 2022
Make it possible to determine which grid files were actually used during a transformation (fixes #3176)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants