<!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>