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

custom CRS 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
    Dec 21, 2019 at 0:42
  • The problem will be in the skewed axes, I think.
    – mkennedy
    Dec 26, 2019 at 18:56

1 Answer 1


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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.