[PROJ] Units in a derived system

Even Rouault even.rouault at spatialys.com
Thu Aug 4 10:10:28 PDT 2022


Hum, it seems I was too fast about "Affine parametric transformation". 
The implementation in PROJ voluntarily ignores the unit specified to the 
A0/A1/A2/B0/B1/B2 and takes the value as it, and the axis order. I'm not 
completely if it is the right thing to do, but EPSG guidance 7-2 note 
isn't super clear about what to do. In their example, they use metre 
unit for A0 and B0, to go from a CRS in Clarke's foot to a CRS in 
metres. The value of the A1 and B2 scaling coefficient is close to the 
conversion factor of Clarke's foot to metre (but slightly different). 
PROJ reproduces the expected transformation on that example. We don't 
have an example of what we should do if the transformation parameter 
units aren't metre/coefficient (I see that there's a deprecated 
EPSG:10088 transformation that uses Clarke's foot but we can't ask it 
for comparison as the deprecation comment mentions that there was an 
error in coefficient values). I let you ask IOGP if you wish to clear 
that up. But in the meantime, you'd be better assuming that there's no 
unit transformation done for that particular method. Doh, coordinate 
transformations are hard and confusing :-)

Le 04/08/2022 à 18:37, Javier Jimenez Shaw a écrit :
> Hi Even. I have been testing your branch (I hope correctly) with the 
> method "Affine parametric transformation". Whit this derived CRS (very 
> similar to the previous example)
>
> DERIVEDPROJCRS["derived from EPSG:6507",
>     BASEPROJCRS["NAD83(2011) / Mississippi East (ftUS)",
>         BASEGEOGCRS["NAD83(2011)",
>             DATUM["NAD83 (National Spatial Reference System 2011)",
>                 ELLIPSOID["GRS 1980",6378137,298.257222101,
>                     LENGTHUNIT["metre",1]]],
>             PRIMEM["Greenwich",0,
>                 ANGLEUNIT["degree",0.0174532925199433]]],
>         CONVERSION["SPCS83 Mississippi East zone (US Survey feet)",
>             METHOD["Transverse Mercator",
>                 ID["EPSG",9807]],
>             PARAMETER["Latitude of natural origin",29.5,
>                 ANGLEUNIT["degree",0.0174532925199433],
>                 ID["EPSG",8801]],
>             PARAMETER["Longitude of natural origin",-88.8333333333333,
>                 ANGLEUNIT["degree",0.0174532925199433],
>                 ID["EPSG",8802]],
>             PARAMETER["Scale factor at natural origin",0.99995,
>                 SCALEUNIT["unity",1],
>                 ID["EPSG",8805]],
>             PARAMETER["False easting",984250,
>                 LENGTHUNIT["US survey foot",0.304800609601219],
>                 ID["EPSG",8806]],
>             PARAMETER["False northing",0,
>                 LENGTHUNIT["US survey foot",0.304800609601219],
>                 ID["EPSG",8807]]]],
>     DERIVINGCONVERSION["Affine",
>         METHOD["Affine parametric transformation",
>             ID["EPSG",9624]],
>         PARAMETER["A0",42,
>             LENGTHUNIT["US survey foot",0.304800609601219],
>             ID["EPSG",8623]],
>         PARAMETER["A1",1,
>             SCALEUNIT["coefficient",1],
>             ID["EPSG",8624]],
>         PARAMETER["A2",0,
>             SCALEUNIT["coefficient",1],
>             ID["EPSG",8625]],
>         PARAMETER["B0",999,
>             LENGTHUNIT["US survey foot",0.304800609601219],
>             ID["EPSG",8639]],
>         PARAMETER["B1",0,
>             SCALEUNIT["coefficient",1],
>             ID["EPSG",8640]],
>         PARAMETER["B2",1,
>             SCALEUNIT["coefficient",1],
>             ID["EPSG",8641]]],
>     CS[Cartesian,2],
>         AXIS["(Y)",north,
>             ORDER[1],
>             LENGTHUNIT["US survey foot",0.304800609601219,
>                 ID["EPSG",9003]]],
>         AXIS["(X)",east,
>             ORDER[2],
>             LENGTHUNIT["US survey foot",0.304800609601219,
>                 ID["EPSG",9003]]]]
>
> and I get these transformations:
>
> $ projinfo -s "EPSG:6507" -t "$(cat derived.wkt)" -o proj -q
> +proj=pipeline
>   +step +proj=unitconvert +xy_in=us-ft +xy_out=m
>   +step +proj=affine +xoff=42 +s11=1 +s12=0 +yoff=999 +s21=0 +s22=1
>
> $ projinfo -s "EPSG:6318" -t "$(cat derived.wkt)" -o proj -q
> +proj=pipeline
>   +step +proj=axisswap +order=2,1
>   +step +proj=unitconvert +xy_in=deg +xy_out=rad
>   +step +proj=tmerc +lat_0=29.5 +lon_0=-88.8333333333333 +k=0.99995 
> +x_0=300000
>         +y_0=0 +ellps=GRS80
>   +step +proj=affine +xoff=42 +s11=1 +s12=0 +yoff=999 +s21=0 +s22=1
>
> The first case is just applying the derived conversion because the 
> input is "the same" as the base (well, I swapped the axes). If I 
> understood correctly "+xy_out=m" is converting to meters, so the 
> affine operation is done in meters easting-northing, regardless the 
> unit I wrote in the parameters. But nothing is done later (like 
> correcting the out units an order as in your PR)
>
> On the second command, where the input is geographic coordinates, the 
> input for the affine is also meters, but no conversion at the end.
>
> Am I right?
>
> Thanks.
>
> PS what if I make a compound of a derived projected and vertical? Is 
> that a problem?
> .___ ._ ..._ .. . ._.  .___ .. __ . _. . __..  ... .... ._ .__
> Entre dos pensamientos racionales
> hay infinitos pensamientos irracionales.
>
>
>
> On Thu, 4 Aug 2022 at 18:09, Javier Jimenez Shaw <j1 at jimenezshaw.com> 
> wrote:
>
>     Thank you Even!
>
>     To confirm that I understood your changes and how to use it.
>     a) the PROJ-based operation method must work in meters and
>     easting-northing (converting from-meters at the beginning and
>     to-meters at the end if I want to keep my values unchanged)
>     b) In this case transverse mercator returns meters (the input unit
>     for the operation method). Is that the case for every projection?
>     c) your changes add a unit conversion and a swap axis if needed at
>     the end. That will produce a sensible output even with a no-op
>     toperation (like xoff=0) But as said in a), it is not affecting
>     the units and order of the operation method.
>
>     Does this apply to other derived operations, like "Affine
>     parametric transformation"
>     https://epsg.org/coord-operation-method_9624/Affine-parametric-transformation.html
>     ? I guess it may have a similar problem.
>     I do not have clear if the parameters of "Affine parametric
>     transformation" must be in the meters, in the same unit as the
>     system, or it is transforming it depending on the value in the WKT2.
>     I will use your branch and try an example.
>
>     Cheers,
>     Javier
>     .___ ._ ..._ .. . ._.  .___ .. __ . _. . __..  ... .... ._ .__
>     Entre dos pensamientos racionales
>     hay infinitos pensamientos irracionales.
>
>
>
>     On Thu, 4 Aug 2022 at 17:14, Even Rouault
>     <even.rouault at spatialys.com> wrote:
>
>         Javier,
>
>         I have had a bit of hesitation if the current behaviour was a
>         feature or a bug, and opted for the later while investigating
>         what happened: the axis unit and order of the source CRS
>         (projected CRS) were well taken into account to "normalize" to
>         metre, easting/northing order before applying the user
>         provided PROJ string, but the axis unit and order of the
>         target CRS (derived projected CRS) were ignored.
>
>         I've addressed this per
>         https://github.com/OSGeo/PROJ/pull/3281 . It might potentially
>         break people that have compensated for that, but I feel it is
>         such a marginal use case that fixing it is the best thing.
>
>         Note however that you must adjust your PROJ string: xoff must
>         be expressed in meters. So you should change xoff to
>         65.6166666666667. Or do like I did in the test I added, that
>         is convert xy from m (as I said above, PROJ normalizes to
>         (resp. from) metre, easting/northing  each step before (resp.
>         after) applying the user PROJ string) to us-ft, then apply the
>         affine with xoff=20, and finally convert back from us-ft to xy.
>
>         Even
>
>
>         Le 03/08/2022 à 19:52, Javier Jimenez Shaw a écrit :
>>         Hi
>>
>>         I am trying to make a derived projected CRS... in feet.
>>         The conversion method is a "PROJ-based operation method" with
>>         an affine transformation (simplified here with just xoff of
>>         20 feet).
>>         https://proj.org/operations/transformations/affine.html
>>
>>         The derived system is something like this (my data is 3D, but
>>         in 2D is also reproduced):
>>
>>         $ cat derived.wkt
>>
>>         DERIVEDPROJCRS["Custom Site Calibrated CRS",
>>             BASEPROJCRS["NAD83(2011) / Mississippi East (ftUS)",
>>                 BASEGEOGCRS["NAD83(2011)",
>>                     DATUM["NAD83 (National Spatial Reference System
>>         2011)",
>>                         ELLIPSOID["GRS 1980",6378137,298.257222101,
>>                             LENGTHUNIT["metre",1]]],
>>                     PRIMEM["Greenwich",0,
>>         ANGLEUNIT["degree",0.0174532925199433]]],
>>                 CONVERSION["SPCS83 Mississippi East zone (US Survey
>>         feet)",
>>                     METHOD["Transverse Mercator",
>>                         ID["EPSG",9807]],
>>                     PARAMETER["Latitude of natural origin",29.5,
>>         ANGLEUNIT["degree",0.0174532925199433],
>>                         ID["EPSG",8801]],
>>                     PARAMETER["Longitude of natural
>>         origin",-88.8333333333333,
>>         ANGLEUNIT["degree",0.0174532925199433],
>>                         ID["EPSG",8802]],
>>                     PARAMETER["Scale factor at natural origin",0.99995,
>>                         SCALEUNIT["unity",1],
>>                         ID["EPSG",8805]],
>>                     PARAMETER["False easting",984250,
>>                         LENGTHUNIT["US survey foot",0.304800609601219],
>>                         ID["EPSG",8806]],
>>                     PARAMETER["False northing",0,
>>                         LENGTHUNIT["US survey foot",0.304800609601219],
>>                         ID["EPSG",8807]]]],
>>             DERIVINGCONVERSION["Affine transformation as PROJ-based",
>>                 METHOD["PROJ-based operation method: +proj=pipeline
>>         +step +proj=affine +xoff=20"]],
>>             CS[Cartesian,2],
>>                 AXIS["easting (X)",east,
>>                     ORDER[1],
>>                     LENGTHUNIT["US survey foot",0.304800609601219]],
>>                 AXIS["northing (Y)",north,
>>                     ORDER[2],
>>                     LENGTHUNIT["US survey foot",0.304800609601219]],
>>             REMARK["EPSG:6507 with 20 feet offset"]]
>>
>>         But the output I get seems to be in meters (I deduced that
>>         running with PROJ_DEBUG=3) It is kind of ignoring the CS.
>>         $ echo 29 -88 0 | cs2cs EPSG:6318 EPSG:6507
>>         1250642.38 -180875.29 0.00
>>         $ echo 29 -88 0 | cs2cs EPSG:6318 "$(cat derived.wkt)"
>>         381216.56 -55130.90 0.00
>>
>>         If I concatenate the pipeline with cct, I get the result I
>>         was expecting (20 feet more in the x):
>>         $ echo 29 -88 0 | cs2cs EPSG:6318 EPSG:6507 | cct
>>         +proj=pipeline +step +proj=affine +xoff=20
>>         1250662.3800   -180875.2900        0.0000
>>
>>         Is that expected? Am I doing anything wrong?
>>
>>         Thanks.
>>         .___ ._ ..._ .. . ._.  .___ .. __ . _. . __..  ... .... ._ .__
>>         Entre dos pensamientos racionales
>>         hay infinitos pensamientos irracionales.
>>
>>
>>         _______________________________________________
>>         PROJ mailing list
>>         PROJ at lists.osgeo.org
>>         https://lists.osgeo.org/mailman/listinfo/proj
>
>         -- 
>         http://www.spatialys.com
>         My software is free, but my time generally not.
>
-- 
http://www.spatialys.com
My software is free, but my time generally not.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/proj/attachments/20220804/c8a5d258/attachment-0001.htm>


More information about the PROJ mailing list