<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>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 :-)<br>
</p>
<div class="moz-cite-prefix">Le 04/08/2022 à 18:37, Javier Jimenez
Shaw a écrit :<br>
</div>
<blockquote type="cite"
cite="mid:CADRrdKsSRUiSvu=ttkXT0D73i=K0p_TtZ-DbXCjN-+nSdmqVLg@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div dir="ltr">
<div>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)</div>
<div><br>
</div>
<div><span style="font-family:monospace">DERIVEDPROJCRS["derived
from EPSG:6507",<br>
BASEPROJCRS["NAD83(2011) / Mississippi East (ftUS)",<br>
BASEGEOGCRS["NAD83(2011)",<br>
DATUM["NAD83 (National Spatial Reference System
2011)",<br>
ELLIPSOID["GRS 1980",6378137,298.257222101,<br>
LENGTHUNIT["metre",1]]],<br>
PRIMEM["Greenwich",0,<br>
ANGLEUNIT["degree",0.0174532925199433]]],<br>
CONVERSION["SPCS83 Mississippi East zone (US Survey
feet)",<br>
METHOD["Transverse Mercator",<br>
ID["EPSG",9807]],<br>
PARAMETER["Latitude of natural origin",29.5,<br>
ANGLEUNIT["degree",0.0174532925199433],<br>
ID["EPSG",8801]],<br>
PARAMETER["Longitude of natural
origin",-88.8333333333333,<br>
ANGLEUNIT["degree",0.0174532925199433],<br>
ID["EPSG",8802]],<br>
PARAMETER["Scale factor at natural
origin",0.99995,<br>
SCALEUNIT["unity",1],<br>
ID["EPSG",8805]],<br>
PARAMETER["False easting",984250,<br>
LENGTHUNIT["US survey
foot",0.304800609601219],<br>
ID["EPSG",8806]],<br>
PARAMETER["False northing",0,<br>
LENGTHUNIT["US survey
foot",0.304800609601219],<br>
ID["EPSG",8807]]]],<br>
DERIVINGCONVERSION["Affine",<br>
METHOD["Affine parametric transformation",<br>
ID["EPSG",9624]],<br>
PARAMETER["A0",42,<br>
LENGTHUNIT["US survey foot",0.304800609601219],<br>
ID["EPSG",8623]],<br>
PARAMETER["A1",1,<br>
SCALEUNIT["coefficient",1],<br>
ID["EPSG",8624]],<br>
PARAMETER["A2",0,<br>
SCALEUNIT["coefficient",1],<br>
ID["EPSG",8625]],<br>
PARAMETER["B0",999,<br>
LENGTHUNIT["US survey foot",0.304800609601219],<br>
ID["EPSG",8639]],<br>
PARAMETER["B1",0,<br>
SCALEUNIT["coefficient",1],<br>
ID["EPSG",8640]],<br>
PARAMETER["B2",1,<br>
SCALEUNIT["coefficient",1],<br>
ID["EPSG",8641]]],<br>
CS[Cartesian,2],<br>
AXIS["(Y)",north,<br>
ORDER[1],<br>
LENGTHUNIT["US survey foot",0.304800609601219,<br>
ID["EPSG",9003]]],<br>
AXIS["(X)",east,<br>
ORDER[2],<br>
LENGTHUNIT["US survey foot",0.304800609601219,<br>
ID["EPSG",9003]]]]</span></div>
<div><br>
</div>
<div>and I get these transformations:</div>
<div><br>
</div>
<div><span style="font-family:monospace">$ projinfo -s
"EPSG:6507" -t "$(cat derived.wkt)" -o proj -q<br>
+proj=pipeline<br>
+step +proj=unitconvert +xy_in=us-ft +xy_out=m<br>
+step +proj=affine +xoff=42 +s11=1 +s12=0 +yoff=999 +s21=0
+s22=1</span><br>
</div>
<div><br>
</div>
<div><span style="font-family:monospace">$ projinfo -s
"EPSG:6318" -t "$(cat derived.wkt)" -o proj -q<br>
+proj=pipeline<br>
+step +proj=axisswap +order=2,1<br>
+step +proj=unitconvert +xy_in=deg +xy_out=rad<br>
+step +proj=tmerc +lat_0=29.5 +lon_0=-88.8333333333333
+k=0.99995 +x_0=300000<br>
+y_0=0 +ellps=GRS80<br>
+step +proj=affine +xoff=42 +s11=1 +s12=0 +yoff=999 +s21=0
+s22=1</span><br>
</div>
<div><br>
</div>
<div>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)<br>
</div>
<div><br>
</div>
<div>On the second command, where the input is geographic
coordinates, the input for the affine is also meters, but no
conversion at the end.</div>
<div><br>
</div>
<div>Am I right?<br>
</div>
<div><br>
</div>
<div>Thanks.</div>
<div><br>
</div>
<div>PS what if I make a compound of a derived projected and
vertical? Is that a problem?<br>
</div>
<div>
<div>
<div dir="ltr" data-smartmail="gmail_signature">.___ ._ ..._
.. . ._. .___ .. __ . _. . __.. ... .... ._ .__<br>
Entre dos pensamientos racionales <br>
hay infinitos pensamientos irracionales.<br>
<br>
</div>
</div>
<br>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Thu, 4 Aug 2022 at 18:09,
Javier Jimenez Shaw <<a href="mailto:j1@jimenezshaw.com"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">j1@jimenezshaw.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div>Thank you Even!</div>
<div><br>
</div>
<div>To confirm that I understood your changes and how to
use it.</div>
<div>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)</div>
<div>b) In this case transverse mercator returns meters (the
input unit for the operation method). Is that the case for
every projection?</div>
<div>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.<br>
</div>
<div><br>
</div>
<div>Does this apply to other derived operations, like <span
style="color:rgb(48,48,48);font-family:Arial,Helvetica,sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none">"Affine
parametric transformation" <a
href="https://epsg.org/coord-operation-method_9624/Affine-parametric-transformation.html"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">https://epsg.org/coord-operation-method_9624/Affine-parametric-transformation.html</a>
? I guess it may have a similar problem.</span></div>
<div>I do not have clear if the parameters of <span
style="color:rgb(48,48,48);font-family:Arial,Helvetica,sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none">"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.</span></div>
<div><span
style="color:rgb(48,48,48);font-family:Arial,Helvetica,sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none">I
will use your branch and try an example.</span></div>
<div><span
style="color:rgb(48,48,48);font-family:Arial,Helvetica,sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"><br>
</span></div>
<div><span
style="color:rgb(48,48,48);font-family:Arial,Helvetica,sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none">Cheers,</span></div>
<div><span
style="color:rgb(48,48,48);font-family:Arial,Helvetica,sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none">Javier<br>
</span></div>
<div><span
style="color:rgb(48,48,48);font-family:Arial,Helvetica,sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"></span></div>
<div>
<div>
<div>
<div dir="ltr">.___ ._ ..._ .. . ._. .___ .. __ . _.
. __.. ... .... ._ .__<br>
Entre dos pensamientos racionales <br>
hay infinitos pensamientos irracionales.<br>
<br>
</div>
</div>
<br>
</div>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Thu, 4 Aug 2022 at
17:14, Even Rouault <<a
href="mailto:even.rouault@spatialys.com" target="_blank"
moz-do-not-send="true" class="moz-txt-link-freetext">even.rouault@spatialys.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div>
<p>Javier,</p>
<p>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.</p>
<p>I've addressed this per <a
href="https://github.com/OSGeo/PROJ/pull/3281"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">https://github.com/OSGeo/PROJ/pull/3281</a>
. 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.</p>
<p>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. <br>
</p>
<p> Even</p>
<p><br>
</p>
<div>Le 03/08/2022 à 19:52, Javier Jimenez Shaw a
écrit :<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div>Hi</div>
<div><br>
</div>
<div>I am trying to make a derived projected CRS...
in feet.</div>
<div>The conversion method is a "PROJ-based
operation method" with an affine transformation
(simplified here with just xoff of 20 feet).</div>
<div><a
href="https://proj.org/operations/transformations/affine.html"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">https://proj.org/operations/transformations/affine.html</a></div>
<div><br>
</div>
<div>The derived system is something like this (my
data is 3D, but in 2D is also reproduced):</div>
<div><br>
</div>
<div><span style="font-family:monospace">$ cat
derived.wkt</span></div>
<div><br>
</div>
<div><span style="font-family:monospace">DERIVEDPROJCRS["Custom
Site Calibrated CRS",<br>
BASEPROJCRS["NAD83(2011) / Mississippi East
(ftUS)",<br>
BASEGEOGCRS["NAD83(2011)",<br>
DATUM["NAD83 (National Spatial
Reference System 2011)",<br>
ELLIPSOID["GRS
1980",6378137,298.257222101,<br>
LENGTHUNIT["metre",1]]],<br>
PRIMEM["Greenwich",0,<br>
ANGLEUNIT["degree",0.0174532925199433]]],<br>
CONVERSION["SPCS83 Mississippi East zone
(US Survey feet)",<br>
METHOD["Transverse Mercator",<br>
ID["EPSG",9807]],<br>
PARAMETER["Latitude of natural
origin",29.5,<br>
ANGLEUNIT["degree",0.0174532925199433],<br>
ID["EPSG",8801]],<br>
PARAMETER["Longitude of natural
origin",-88.8333333333333,<br>
ANGLEUNIT["degree",0.0174532925199433],<br>
ID["EPSG",8802]],<br>
PARAMETER["Scale factor at natural
origin",0.99995,<br>
SCALEUNIT["unity",1],<br>
ID["EPSG",8805]],<br>
PARAMETER["False easting",984250,<br>
LENGTHUNIT["US survey
foot",0.304800609601219],<br>
ID["EPSG",8806]],<br>
PARAMETER["False northing",0,<br>
LENGTHUNIT["US survey
foot",0.304800609601219],<br>
ID["EPSG",8807]]]],<br>
DERIVINGCONVERSION["Affine transformation as
PROJ-based",<br>
METHOD["PROJ-based operation method:
+proj=pipeline +step +proj=affine +xoff=20"]],<br>
CS[Cartesian,2],<br>
AXIS["easting (X)",east,<br>
ORDER[1],<br>
LENGTHUNIT["US survey
foot",0.304800609601219]],<br>
AXIS["northing (Y)",north,<br>
ORDER[2],<br>
LENGTHUNIT["US survey
foot",0.304800609601219]],<br>
REMARK["EPSG:6507 with 20 feet offset"]]</span></div>
<div><br>
</div>
<div>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.</div>
<div><span style="font-family:monospace">$ echo 29
-88 0 | cs2cs EPSG:6318 EPSG:6507<br>
1250642.38 -180875.29 0.00<br>
$ echo 29 -88 0 | cs2cs EPSG:6318 "$(cat
derived.wkt)"<br>
381216.56 -55130.90 0.00</span></div>
<div><br>
</div>
<div>If I concatenate the pipeline with cct, I get
the result I was expecting (20 feet more in the
x):</div>
<div><span style="font-family:monospace">$ echo 29
-88 0 | cs2cs EPSG:6318 EPSG:6507 | cct
+proj=pipeline +step +proj=affine +xoff=20<br>
1250662.3800 -180875.2900 0.0000</span></div>
<div><br>
</div>
<div>Is that expected? Am I doing anything wrong?<br>
</div>
<div><br>
</div>
<div>Thanks.<br>
</div>
<div>
<div>
<div dir="ltr">.___ ._ ..._ .. . ._. .___ .. __
. _. . __.. ... .... ._ .__<br>
Entre dos pensamientos racionales <br>
hay infinitos pensamientos irracionales.<br>
<br>
</div>
</div>
</div>
</div>
<br>
<fieldset></fieldset>
<pre>_______________________________________________
PROJ mailing list
<a href="mailto:PROJ@lists.osgeo.org" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">PROJ@lists.osgeo.org</a>
<a href="https://lists.osgeo.org/mailman/listinfo/proj" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://lists.osgeo.org/mailman/listinfo/proj</a>
</pre>
</blockquote>
<pre cols="72">--
<a href="http://www.spatialys.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">http://www.spatialys.com</a>
My software is free, but my time generally not.</pre>
</div>
</blockquote>
</div>
</blockquote>
</div>
</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.</pre>
</body>
</html>