PROJ icon indicating copy to clipboard operation
PROJ copied to clipboard

General Oblique Transformation yields unexpected results using o_lat_c, o_lon_c and o_alpha

Open Jeitan opened this issue 1 year ago • 3 comments

I have tried to use the General Oblique Transformation to obtain a rotated Oblique Mercator projection, but the results of +ob_tran are unexpected. If I construct it by using a new pole (as per the documentation here), it works as expected. But if I use the "rotate the projection around a given point" option, the results are unexpected and don't match the version that uses a pole. I don't know if it is an error in my understanding or an error in PROJ. I have a question here on GIS stack exchange where someone else confirmed my results.

If the following is not a bug but is an error in my understanding, then perhaps an explanation something like #3908 is requesting would help?

Example of problem

I am using pyproj to interface with PROJ, but pyproj is not the culprit as the answer at the stack exchange question above confirmed. I'm using the following code to create a projection then test its origin, and what the geodetic coordinates of 1 approximate degree in the +X and +Y directions yield.

import numpy as np
from pyproj import CRS, Transformer

geod = CRS.from_proj4("+proj=latlon")

custom3 = CRS.from_proj4(
    "+proj=ob_tran +o_proj=omerc +lonc=0 +lat_0=0 +alpha=0 +o_lat_p=90 +o_lon_p=0"
)

cust32geo = Transformer.from_crs(custom3, geod)
print("Custom General Oblique to mimic Oblique Mercator, using pole")
print("Origin: ", np.round(cust32geo.transform(0, 0)))
print("+X: ", np.round(cust32geo.transform(111e3, 0)))
print("+Y: ", np.round(cust32geo.transform(0, 111e3)))

custom4 = CRS.from_proj4(
    "+proj=ob_tran +o_proj=omerc +lonc=0 +lat_0=0 +alpha=0 +o_lat_c=0 +o_lon_c=0 +o_alpha=0"
)

cust42geo = Transformer.from_crs(custom4, geod)
print("Custom General Oblique to mimic Oblique Mercator, using center and rotation")
print("Origin: ", np.round(cust42geo.transform(0, 0)))
print("+X: ", np.round(cust42geo.transform(111e3, 0)))
print("+Y: ", np.round(cust42geo.transform(0, 111e3)))

Problem description

The above code prints the following:

Custom General Oblique to mimic Oblique Mercator, using pole
Origin:  [0. 0.]
+X:  [1. 0.]
+Y:  [0. 1.]
Custom General Oblique to mimic Oblique Mercator, using center and rotation
Origin:  [90.  0.]
+X:  [90. -1.]
+Y:  [91.  0.]

I expected the second version to be identical to the first ... but instead, the origin is at 0 degrees latitude and 90 degrees longitude, instead of (0, 0) like I expected. Also, the X and Y coordinate axes are rotated so +X is negative latitude and +Y is positive longitude.

ETA: I also get the same exact behavior if I use +o_proj=tmerc instead.

ETA 2: If I set +o_alpha=90, I get the X and Y axes oriented as I expect, which does make sense. The origin still shifts though.

Expected Output

I expected identical outputs from the two projections above.

Environment Information

Using pyproj 3.6.1 which according to the documentation contains PROJ 9.3.0. Environment: Windows with an installation of Miniconda

Installation method

Installed pyproj using Poetry (pip under the hood)

Jeitan avatar Feb 09 '24 21:02 Jeitan