<div dir="ltr">Hi,<div><br></div><div>I am trying to use a compound CRS in GDAL. I have a CRS that is essentially topocentric but with an angle and skew applied to the tangential plane by two unit vectors uiax and uiay.</div><div><br></div><div>I am doing this in Python and the code is as follows;</div><div><br></div><div><div><div style="color:rgb(187,190,191);background-color:rgb(18,19,20);font-family:Consolas,"Courier New",monospace;font-size:14px;line-height:19px;white-space:pre"><div>            <span style="color:rgb(139,148,158)"># planar angle between unit vector and northing in topocentric</span></div><div>            <span style="color:rgb(201,209,217)">theta</span> <span style="color:rgb(212,212,212)">=</span>  <span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(201,209,217)">arccos</span>(<span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(210,168,255)">clip</span>(<span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(210,168,255)">dot</span>(<span style="color:rgb(201,209,217)">uiay</span>[:<span style="color:rgb(181,206,168)">2</span>], [<span style="color:rgb(181,206,168)">0</span>, <span style="color:rgb(181,206,168)">1</span>]), <span style="color:rgb(212,212,212)">-</span><span style="color:rgb(181,206,168)">1.0</span>, <span style="color:rgb(181,206,168)">1.0</span>))</div><div>            <span style="color:rgb(139,148,158)"># planar angle between unit vector and easting in topocentric</span></div><div>            <span style="color:rgb(201,209,217)">phi</span> <span style="color:rgb(212,212,212)">=</span>  <span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(201,209,217)">arccos</span>(<span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(210,168,255)">clip</span>(<span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(210,168,255)">dot</span>(<span style="color:rgb(201,209,217)">uiax</span>[:<span style="color:rgb(181,206,168)">2</span>], [<span style="color:rgb(181,206,168)">1</span>, <span style="color:rgb(181,206,168)">0</span>]), <span style="color:rgb(212,212,212)">-</span><span style="color:rgb(181,206,168)">1.0</span>, <span style="color:rgb(181,206,168)">1.0</span>))</div><br><div>            <span style="color:rgb(139,148,158)"># Build rotation matrix</span></div><div>            <span style="color:rgb(201,209,217)">rot</span> <span style="color:rgb(212,212,212)">=</span> <span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(210,168,255)">array</span>([</div><div>                [<span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(201,209,217)">cos</span>(<span style="color:rgb(201,209,217)">theta</span>), <span style="color:rgb(212,212,212)">-</span><span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(201,209,217)">sin</span>(<span style="color:rgb(201,209,217)">theta</span>), <span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">0.0</span>],</div><div>                [<span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(201,209,217)">sin</span>(<span style="color:rgb(201,209,217)">theta</span>),  <span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(201,209,217)">cos</span>(<span style="color:rgb(201,209,217)">theta</span>), <span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">0.0</span>],</div><div>                [          <span style="color:rgb(181,206,168)">0.0</span>,            <span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">1.0</span>, <span style="color:rgb(181,206,168)">0.0</span>],</div><div>                [          <span style="color:rgb(181,206,168)">0.0</span>,            <span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">1.0</span>],</div><div>            ]</div><div>            )</div><br><div>            <span style="color:rgb(139,148,158)"># Build shear/skew matrix</span></div><div>            <span style="color:rgb(201,209,217)">m</span> <span style="color:rgb(212,212,212)">=</span> <span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(201,209,217)">tan</span>(<span style="color:rgb(201,209,217)">phi</span>)</div><div>            <span style="color:rgb(201,209,217)">skew</span> <span style="color:rgb(212,212,212)">=</span> <span style="color:rgb(78,201,176)">np</span>.<span style="color:rgb(210,168,255)">array</span>([</div><div>                [<span style="color:rgb(181,206,168)">1.0</span>, <span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">0.0</span>],</div><div>                [  <span style="color:rgb(201,209,217)">m</span>, <span style="color:rgb(181,206,168)">1.0</span>, <span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">0.0</span>],</div><div>                [<span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">1.0</span>, <span style="color:rgb(181,206,168)">0.0</span>],</div><div>                [<span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">0.0</span>, <span style="color:rgb(181,206,168)">1.0</span>],</div><div>            ]</div><div>            )</div><br><div>            <span style="color:rgb(139,148,158)"># get affine transform</span></div><div>            <span style="color:rgb(201,209,217)">a</span> <span style="color:rgb(212,212,212)">=</span> <span style="color:rgb(201,209,217)">rot</span> <span style="color:rgb(220,220,170)">@</span> <span style="color:rgb(201,209,217)">skew</span></div><br><div>            <span style="color:rgb(201,209,217)">wgs84</span> <span style="color:rgb(212,212,212)">=</span> osr.SpatialReference(<span style="color:rgb(255,166,87)">epsg</span><span style="color:rgb(212,212,212)">=</span><span style="color:rgb(181,206,168)">4326</span>)</div><div>            <span style="color:rgb(201,209,217)">wgs84</span>.SetAxisMappingStrategy(osr.<span style="color:rgb(121,192,255)">OAMS_TRADITIONAL_GIS_ORDER</span>)</div><br><div>            <span style="color:rgb(201,209,217)">topo</span> <span style="color:rgb(212,212,212)">=</span> osr.SpatialReference(<span style="color:rgb(255,123,114)">f</span><span style="color:rgb(165,214,255)">"+proj=pipeline "</span></div><div>                                        <span style="color:rgb(255,123,114)">f</span><span style="color:rgb(165,214,255)">"+step +proj=topocentric +X_0=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">ref_ecf</span>[<span style="color:rgb(181,206,168)">0</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> +Y_0=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">ref_ecf</span>[<span style="color:rgb(181,206,168)">1</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> +Z_0=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">ref_ecf</span>[<span style="color:rgb(181,206,168)">2</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> "</span></div><div>                                        <span style="color:rgb(255,123,114)">f</span><span style="color:rgb(165,214,255)">"+step +proj=affine "</span></div><div>                                        <span style="color:rgb(255,123,114)">f</span><span style="color:rgb(165,214,255)">"+s11=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">a</span>[<span style="color:rgb(181,206,168)">0</span>,<span style="color:rgb(181,206,168)">0</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> +s12=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">a</span>[<span style="color:rgb(181,206,168)">0</span>,<span style="color:rgb(181,206,168)">1</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> +s13=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">a</span>[<span style="color:rgb(181,206,168)">0</span>,<span style="color:rgb(181,206,168)">2</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> "</span></div><div>                                        <span style="color:rgb(255,123,114)">f</span><span style="color:rgb(165,214,255)">"+s21=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">a</span>[<span style="color:rgb(181,206,168)">1</span>,<span style="color:rgb(181,206,168)">0</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> +s22=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">a</span>[<span style="color:rgb(181,206,168)">1</span>,<span style="color:rgb(181,206,168)">1</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> +s23=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">a</span>[<span style="color:rgb(181,206,168)">1</span>,<span style="color:rgb(181,206,168)">2</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> "</span></div><div>                                        <span style="color:rgb(255,123,114)">f</span><span style="color:rgb(165,214,255)">"+s31=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">a</span>[<span style="color:rgb(181,206,168)">2</span>,<span style="color:rgb(181,206,168)">0</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> +s32=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">a</span>[<span style="color:rgb(181,206,168)">2</span>,<span style="color:rgb(181,206,168)">1</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> +s33=</span><span style="color:rgb(255,123,114)">{</span><span style="color:rgb(201,209,217)">a</span>[<span style="color:rgb(181,206,168)">2</span>,<span style="color:rgb(181,206,168)">2</span>]<span style="color:rgb(255,123,114)">}</span><span style="color:rgb(165,214,255)"> "</span></div><div>                                        )</div><div>            <span style="color:rgb(201,209,217)">ct</span> <span style="color:rgb(212,212,212)">=</span> osr.CoordinateTransformation(<span style="color:rgb(201,209,217)">topo</span>, <span style="color:rgb(201,209,217)">wgs84</span>)</div></div></div></div><div><br></div><div>I get the error message "ERROR 1: PROJ: proj_crs_get_coordinate_system: Object is not a SingleCRS"</div><div><br></div><div>Which is true, it is not. I have grep'd the tests and have not seen any examples. Using `CoordinateTransformationOptions` applies once the conversion to lat/lon is complete.</div><div><br></div><div>Thanks,</div><div><br></div><div>Norman</div></div>