# Custom PROJ CRS for shifted, rotated, and skewed axes?

It is possible to create a custom PROJ definition for a cartesian CRS with shifted, rotated, and skewed axes? For example:

Where The x-axis is formed by the line `AC`, the y-axis by the line `AB`, and the origin at `A`. I'm thinking something like a typical UTM system, but the origin is shifted from the typical origin, rotated so axes don't align with cardinal directions, and skewed so the axes are not at right angles.

• Just noticed proj pipelines perhaps there is a way to use those?
– Ryan
Commented Dec 21, 2019 at 0:42
• The problem will be in the skewed axes, I think. Commented Dec 26, 2019 at 18:56

I linked this question to the proj gitter chat and was told to look at the affine transform operation. Here is how I used it.

First, I got the angles of my axes relative to the usual Northing and Easting directions (dashed lines):

I used the angle `theta` to define the rotation, and the angle `phi` to define shear/skew (wikipedia has a good picture.) And `O` is the origin in UTM.

From there I used `pyproj` to build the transformation pipeline from the skewed/rotated/shifted CRS into UTM:

``````import numpy as np
from pyproj import Transformer

# Build rotation matrix
rot = np.array([
[np.cos(theta), -np.sin(theta), 0.0, 0.0],
[np.sin(theta),  np.cos(theta), 0.0, 0.0],
[          0.0,            0.0, 1.0, 0.0],
[          0.0,            0.0, 0.0, 1.0],
]
)
# Build shear/skew matrix
m = np.tan(phi)
skew = np.array([
[1.0, 0.0, 0.0, 0.0],
[  m, 1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0],
]
)
# get affine transform
a = rot @ skew
# Build pipeline
pt_transform = Transformer.from_pipeline(
f"+proj=pipeline "
f"+step +proj=affine +xoff={origin_x} +yoff={origin_y} "
f"+s11={a[0,0]} +s12={a[0,1]} +s13={a[0,2]} "
f"+s21={a[1,0]} +s22={a[1,1]} +s23={a[1,2]} "
f"+s31={a[2,0]} +s32={a[2,1]} +s33={a[2,2]} "
)

# transform points into UTM
new_x, new_y = pt_transform.transform(x, y)

``````