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 the ability to determine if a more accurate transformation was skipped because of missing grids #3177

Open
DalePAtSafe opened this issue Apr 27, 2022 · 3 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 if there was a more accurate transformation for a given coordinate that was not used because of missing grids.

Currently in PROJ as far as I’m aware, when using proj_create_crs_to_crs will generate a set of transformations that could be used to go between the two provides CRSes and will quietly discard the ones for which we have no grids (if networking is disabled). Ideally there would be some way to maintain the information about all possible transformations such that after proj_trans is called we could call some API to find out if there were more accurate options we missed out on due to missing grids.

We’ve experimented with using the proj_operation_factory functions with the same settings as proj_create_crs_to_crs to try to create some kind of warning in this case, however, we are little wary about using that as our solution as it requires us to maintain our code in sync with the PROJ implementation and also doesn’t really enable us to know if a transformation with higher accuracy would have even been relevant for the coordinates that were eventually transformed. At least not without effectively re-implementing proj_create_crs_to_crs and then the automatic transformation selection based on coordinates ourselves, which we again don’t want to do because we don’t want to risk our implementation slipping out of sync with PROJ.

@rouault
Copy link
Member

rouault commented May 3, 2022

if you use proj_get_suggested_operation() on the operations returned with a context with proj_operation_factory_context_set_grid_availability_use(PROJ_GRID_AVAILABILITY_KNOWN_AVAILABLE) and compare that with the run of proj_get_suggested_operation() on the operations returned with a context with proj_operation_factory_context_set_grid_availability_use(PROJ_GRID_AVAILABILITY_DISCARD_OPERATION_IF_MISSING_GRID), you should get what you want.

@DalePAtSafe
Copy link
Author

I think this would mostly work for what we're looking for in that it solves the problem of not knowing if a transformation would have been relevant for a coordinate, however it still has the problem where we have to maintain our proj_operation_factory calls in sync with what proj_create_crs_to_crs_from_pj does. Ideally there would be a way to get the list of operations that proj_create_crs_to_crs_from_pj produces without manually setting up a PJ_OPERATION_FACTORY_CONTEXT to match it.

Maybe something like this?

// Takes the exact same inputs as proj_create_crs_to_crs_from_pj 
// but produces a list of operations that will be considered instead of a transformation object.
// Also has an additional option to assume networking is enabled
PJ_OBJ_LIST proj_get_crs_to_crs_candidate_operations(PJ_CONTEXT *ctx, 
                                                     PJ *src, 
                                                     PJ *dest,
                                                     PJ_AREA *area, 
                                                     const char* const *options,
                                                     bool assumeNetworkEnabled);

Then we could do something like this and be guaranteed that we'll always get exactly what proj_create_crs_to_crs_from_pj would use given the same inputs.

PJ* src = ...
PJ* dest = ...
PJ_COORD coord = ...

PJ_OBJ_LIST operationsWithNetworking = proj_get_crs_to_crs_candidate_operations(nullptr, src, dest, nullptr, nullptr, true);
PJ_OBJ_LIST operationsWithoutNetworking = proj_get_crs_to_crs_candidate_operations(nullptr, src, dest, nullptr, nullptr, false);

int withNetworkingOpIndex = proj_get_suggested_operation(nullptr, operationsWithNetworking, PJ_FWD, coord);
int withoutNetworkingOpIndex = proj_get_suggested_operation(nullptr, operationsWithoutNetworking, PJ_FWD, coord);

// Check if operations are different

This would basically get us what we need, obviously the API wouldn't have to look like this. I could also see maybe instead of adding an extra bool parameter, an extra option could be added for the options strings that allows controlling the grid availability settings separately from the networking setting for calls to proj_get_crs_to_crs_candidate_operations. However it's done, this is roughly what we're looking for.

@rhuijben
Copy link
Contributor

Reading up on old issues, I find more cases where transformations are skipped. Like in more recently added transforms where an Epoch is required for certain transforms. Perhaps a more generic 'this is required for a better transform's could do better than this suggestion.

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