<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Norman,<br>
      <br>
      (ISO-19111 pedantically speaking your object is not a CompoundCRS,
      which would be a geographic/projected 2D + vertical CRS, but more
      a DerivedCRS)</p>
    <p>the error is "expected" given that it is generally not possible to
      infer a CRS definition from a PROJ pipeline </p>
    <p>2 ways of addressing this:</p>
    <p>- the hard one: create a "real" CRS fighting with WKT/PROJSON
      (maybe just PROJJSON as I'm not sure WKT allows that 2-level
      nesting of derivation) of a DerivedGeodeticCRS (affine transform)
      of a DerivedGeodeticCRS (geographic to topocentric) of a
      geographic CRS... or something like that. I don't have  an example
      of that handy.  Some potential inspiration at
<a class="moz-txt-link-freetext" href="https://github.com/qgis/QGIS/pull/65873/changes#diff-443e243a4b840a314841dfd4d6aae7f0981d64233badade7af0a769e29536982R3332">https://github.com/qgis/QGIS/pull/65873/changes#diff-443e243a4b840a314841dfd4d6aae7f0981d64233badade7af0a769e29536982R3332</a>
      and
<a class="moz-txt-link-freetext" href="https://github.com/OSGeo/PROJ/blob/master/test/unit/test_operationfactory.cpp#L11174">https://github.com/OSGeo/PROJ/blob/master/test/unit/test_operationfactory.cpp#L11174</a></p>
    <p>- or likely easier, write the full PROJ pipeline of the
      transformation, which should probably be just a matter of
      inverting your pipeline (reversing the steps with a +inv keyword
      on each) and use ct.SetOperation(proj_pipeline) as in
<a class="moz-txt-link-freetext" href="https://github.com/OSGeo/gdal/blob/0bb1c88ff756f174577c6056af6d9452942a5a1a/autotest/osr/osr_ct.py#L359">https://github.com/OSGeo/gdal/blob/0bb1c88ff756f174577c6056af6d9452942a5a1a/autotest/osr/osr_ct.py#L359</a></p>
    <p>Even</p>
    <div class="moz-cite-prefix">Le 24/04/2026 à 02:08, Norman Barker
      via gdal-dev a écrit :<br>
    </div>
    <blockquote type="cite"
cite="mid:CAN_Dn-Eb=xU+-z=uSS2+qg1G4ucpeybFr5FnRbPGbyHYd0kA1g@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <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>
<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>
<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>
<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>
<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>
<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 <a class="moz-txt-link-rfc2396E" href="ERROR1:PROJ:proj_crs_get_coordinate_system:ObjectisnotaSingleCRS">"ERROR 1: PROJ:
          proj_crs_get_coordinate_system: Object is not a SingleCRS"</a></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>
      <br>
      <fieldset class="moz-mime-attachment-header"></fieldset>
      <pre wrap="" class="moz-quote-pre">_______________________________________________
gdal-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:gdal-dev@lists.osgeo.org">gdal-dev@lists.osgeo.org</a>
<a class="moz-txt-link-freetext" href="https://lists.osgeo.org/mailman/listinfo/gdal-dev">https://lists.osgeo.org/mailman/listinfo/gdal-dev</a>
</pre>
    </blockquote>
    <pre class="moz-signature" cols="72">-- 
<a class="moz-txt-link-freetext" href="http://www.spatialys.com">http://www.spatialys.com</a>
My software is free, but my time generally not.
Highly recommend OxiGDAL if you want to live in the 21th century and cure Bixonimania</pre>
  </body>
</html>