[gdal-dev] Compound CRS
Even Rouault
even.rouault at spatialys.com
Thu Apr 23 17:39:36 PDT 2026
Norman,
(ISO-19111 pedantically speaking your object is not a CompoundCRS, which
would be a geographic/projected 2D + vertical CRS, but more a DerivedCRS)
the error is "expected" given that it is generally not possible to infer
a CRS definition from a PROJ pipeline
2 ways of addressing this:
- 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
https://github.com/qgis/QGIS/pull/65873/changes#diff-443e243a4b840a314841dfd4d6aae7f0981d64233badade7af0a769e29536982R3332
and
https://github.com/OSGeo/PROJ/blob/master/test/unit/test_operationfactory.cpp#L11174
- 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
https://github.com/OSGeo/gdal/blob/0bb1c88ff756f174577c6056af6d9452942a5a1a/autotest/osr/osr_ct.py#L359
Even
Le 24/04/2026 à 02:08, Norman Barker via gdal-dev a écrit :
> Hi,
>
> 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.
>
> I am doing this in Python and the code is as follows;
>
> # planar angle between unit vector and northing in topocentric
> theta = np.arccos(np.clip(np.dot(uiay[:2], [0, 1]), -1.0, 1.0))
> # planar angle between unit vector and easting in topocentric
> phi = np.arccos(np.clip(np.dot(uiax[:2], [1, 0]), -1.0, 1.0))
> # 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
> wgs84 = osr.SpatialReference(epsg=4326)
> wgs84.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
> topo = osr.SpatialReference(f"+proj=pipeline "
> f"+step +proj=topocentric
> +X_0={ref_ecf[0]}+Y_0={ref_ecf[1]}+Z_0={ref_ecf[2]}"
> f"+step +proj=affine "
> 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]}"
> )
> ct = osr.CoordinateTransformation(topo, wgs84)
>
> I get the error message "ERROR 1: PROJ:
> proj_crs_get_coordinate_system: Object is not a SingleCRS"
>
> 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.
>
> Thanks,
>
> Norman
>
> _______________________________________________
> gdal-dev mailing list
> gdal-dev at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/gdal-dev
--
http://www.spatialys.com
My software is free, but my time generally not.
Highly recommend OxiGDAL if you want to live in the 21th century and cure Bixonimania
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/gdal-dev/attachments/20260424/4a3b49a3/attachment-0001.htm>
More information about the gdal-dev
mailing list