TransformerGroup does not handle cases where both the allow_superseded and always_xy user arguments is used
Example code
Ex. 1 TransformerGroup fails to list up available transformations when specifying both always_xy and allow_superseded
from pyproj.transformer import TransformerGroup
TransformerGroup("EPSG:4230", "EPSG:4326", allow_superseded=True, always_xy=True).transformers
Outputs:
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/pyproj/transformer.py", line 207, in __init__
super().__init__(
File "pyproj/_transformer.pyx", line 241, in pyproj._transformer._TransformerGroup.__init__
File "pyproj/_transformer.pyx", line 602, in pyproj._transformer._Transformer._from_pj
File "pyproj/_transformer.pyx", line 653, in pyproj._transformer._Transformer._init_from_crs
File "pyproj/_transformer.pyx", line 359, in pyproj._transformer._Transformer._initialize_from_projobj
pyproj.exceptions.ProjError: Input is not a transformation.
Ex.2 TransformerGroup should return 36 available transformations when allow_superseded not defined
ct_lst = TransformerGroup("EPSG:4230", "EPSG:4326").transformers
print(len(ct_lst))
Outputs:
36
Ex.3 TransformerGroup should return 37 available transformations when allow_superseded is set to True
ct_lst = TransformerGroup("EPSG:4230", "EPSG:4326", allow_superseded=True).transformers
print(len(ct_lst))
Outputs:
37
ct_lst = TransformerGroup("EPSG:4230", "EPSG:4326", allow_superseded=True).transformers print(len(ct_lst))
Problem description
TransformerGroup fails to a create a list of all available transformation objects when the user set both always_xy and allow_superseded equals True.
Environment Information
pyproj version 3.6.1 python 3.11
Installation method
pip wheel
An issue is created in PyProj GitHub repo.
This feels more like a pyproj bug, than a PROJ one. At least the exception comes from https://github.com/pyproj4/pyproj/blob/42aa92f489bd266749a44cb78101eae28e20f5c3/pyproj/_transformer.pyx#L341
Hi Even, I see. Feel free to delete this issue if you think its only related to pyproj
I did some debugging and this is what I found:
allow_supersededcallsproj_operation_factory_context_set_discard_supersededand creates aPJobject forED50 to WGS 84 (15)with thePJ_TYPE_TRANSFORMATIONwhen callingproj_create_operations.- Combining
allow_supersededwithalways_xycauses an issue because thePJobject isPJ_TYPE_TRANSFORMATION. Due to thisproj_coordoperation_is_instantiablereturns True. However,proj_normalize_for_visualizationreturns aPJobject of typePJ_TYPE_CONCATENATED_OPERATIONforED50 to WGS 84 (15). This is the source of the error when attempting to create theTransformer.
from pyproj import Transformer
print(Transformer.from_pipeline("ED50 to WGS 84 (15)").description)
"ED50 to WGS 84 (15)"
I modified the pyproj code to run proj_normalize_for_visualization on ED50 to WGS 84 (15) (cannot do this normally with the current release):
from pyproj._transformer import _Transformer
_Transformer.from_pipeline("ED50 to WGS 84 (15)", always_xy=True)
...
pyproj.exceptions.ProjError: Input is not a transformation.
This produces the error above.
@rouault is it expected for proj_normalize_for_visualization convert a PJ_TYPE_TRANSFORMATION into PJ_TYPE_CONCATENATED_OPERATION?
Hi @rouault, @snowman2
Has this been investigated further? Any conclusion on where the issue resides?
is it expected for
proj_normalize_for_visualizationconvert aPJ_TYPE_TRANSFORMATIONintoPJ_TYPE_CONCATENATED_OPERATION?
@snowman2 yes, that's exactly how the implementation works: it takes the original transformation and prepends / appends axis swap operations to it where needed, and returns a concatenated operation
yes, that's exactly how the implementation works: it takes the original transformation and prepends / appends axis swap operations to it where needed, and returns a concatenated operation
Thank you for clarifying that. That sounds like it is not the issue.
To further debug the issue, I ran proj_coordoperation_is_instantiable on the PJ * object after calling proj_normalize_for_visualization and it raised the error: missing required input. Is it expected that a PJ * that was instantiable before calling proj_normalize_for_visualization to no longer be instantiable after?
and it raised the error:
missing required input
proj_coordoperation_is_instantiable() returns that error if the passed PJ* object is NULL.
and it raised the error:
missing required inputproj_coordoperation_is_instantiable() returns that error if the passed PJ* object is NULL.
Huh, you're correct. proj_normalize_for_visualization is returning NULL now. I wonder what version of PROJ I was using that returned a PJ_TYPE_CONCATENATED_OPERATION 🤔.