[PROJ] Make push and pop FIFO?

Even Rouault even.rouault at spatialys.com
Sat Dec 16 11:29:50 PST 2023


I find that push, pop, exch are not super intuitive. For the sake of 
brainstorming, here are my thoughts... I'm not totally convinced they 
are good as they are kind of exceptions to the way pipelines operate in 
the reverse direction (which isn't totally obvious either)

So basically we would have 2 new operations:

* +proj=save +only_fwd|+only_inv +into=some_name  : save the current 
coordinate as "some_name", but only do that in the specified direction. 
That is, it is a no-op in the other direction. +omit_fwd/+omit_inv are 
obviously not allowed on such an operation

* +proj=restore +only_fwd|+only_inv +from=some_name [+v_1] [+v_2] [+v_3] 
[+v_4]: restore "some_name" as the current coordinate, only in the 
specified direction. One must explicitly specify at least one +v_X. 
no-op in the other direction. +omit_fwd/+omit_inv are not allowed on 
such an operation

You can interleave save and restore in any order, provided that you 
restore an already saved name...


So Jochem's pipeline would become (if I've understood well):

cct +proj=pipeline

+step +proj=save +only_fwd +into=orthometric_height

+step +proj=restore +only_inv +v_3 +from=orthometric_height

+step +proj=tmerc +inv +lat_0=12.180658675 +lon_0=-68.251802281 +k_0=1 
+x_0=23209.5600 +y_0=21423.9900 +ellps=intl

+step +proj=cart +ellps=intl

+step +proj=helmert +x=-366.1939 +y=-115.0688 +z=-776.7039 +rx=20.963080 
+ry=16.462749 +rz=-14.276379 +s=-12.80900 +convention=coordinate_frame 
+exact

+step +proj=cart +inv +ellps=GRS80

+step +proj=restore +only_fwd +v_3 +from=orthometric_height

+step +proj=restore +only_inv +v_3 +from=ellipsoidal_height

+step +proj=save +only_inv +into=orthometric_height

+step +proj=vgridshift +grids=egm2008_0_45.tif +inv

+step +proj=save +only_inv +into=ellipsoidal_height


In the forward direction, it would be interpreted as (omitting all 
+only=inv steps):


cct +proj=pipeline

+step +proj=save +only_fwd +into=orthometric_height

+step +proj=tmerc +inv +lat_0=12.180658675 +lon_0=-68.251802281 +k_0=1 
+x_0=23209.5600 +y_0=21423.9900 +ellps=intl

+step +proj=cart +ellps=intl

+step +proj=helmert +x=-366.1939 +y=-115.0688 +z=-776.7039 +rx=20.963080 
+ry=16.462749 +rz=-14.276379 +s=-12.80900 +convention=coordinate_frame 
+exact

+step +proj=cart +inv +ellps=GRS80

+step +proj=restore +only_fwd +v_3+from=orthometric_height

+step +proj=vgridshift +grids=egm2008_0_45.tif +inv


And for the reverse direction, it would be interpreted as the following 
(that is when taking with a forward direction perspective), by reversing 
the order of steps, reversing the direction of each step (except the 
ones tagged with +only_fwd/+only_inv), omitting all +only_fwd steps, and 
renaming the +only_inv ones as +only_fwd :

cct +proj=pipeline

+step +proj=save +only_fwd +into=ellipsoidal_height

+step +proj=vgridshift +grids=egm2008_0_45.tif

+step +proj=save +only_fwd +into=orthometric_height

+step +proj=restore +only_fwd +v_3 +from=ellipsoidal_height

+step +proj=cart +ellps=GRS80

+step +inv +proj=helmert +x=-366.1939 +y=-115.0688 +z=-776.7039 
+rx=20.963080 +ry=16.462749 +rz=-14.276379 +s=-12.80900 
+convention=coordinate_frame +exact

+step +inv +proj=cart +ellps=intl

+step +proj=tmerc +lat_0=12.180658675 +lon_0=-68.251802281 +k_0=1 
+x_0=23209.5600 +y_0=21423.9900 +ellps=intl

+step +proj=restore +only_fwd +v_3+from=orthometric_height

I guess we could potentially use the +omit_fwd/+omit_inv logic, with its 
logic of inverting the semantics when reading in the reverse directions, 
but my brain is hurting hard when I'm tring to comprehend that (1).



Hence this proposal of +only_fwd/+only_inv. Which is probably what we 
should have come up with originally instead of +omit_fwd/+omit_inv

I guess we could generalize +only_fwd/+only_inv to all operations, with 
the semantic detailed above, that is they are interpreted as written in 
the direction where they should be applied, without a reversal of their 
direction.


Actually... At the expense of being super verbose, but hopefully super 
straightforward, why not having "+proj=if +dir=fwd"  , "+proj=elseif 
dir=inv" and "+proj=endif", eliminating all convoluted uses of 
+omit_fwd/inv (and/or +only_fwd/inv), and the mental process of 
inferring the inverse pipeline by reversing the order of the steps and 
their direction:

cct +proj=pipeline

+step +proj=if +dir=fwd

+step +proj=save +into=orthometric_height

+step +proj=tmerc +inv +lat_0=12.180658675 +lon_0=-68.251802281 +k_0=1 
+x_0=23209.5600 +y_0=21423.9900 +ellps=intl

+step +proj=cart +ellps=intl

+step +proj=helmert +x=-366.1939 +y=-115.0688 +z=-776.7039 +rx=20.963080 
+ry=16.462749 +rz=-14.276379 +s=-12.80900 +convention=coordinate_frame 
+exact

+step +proj=cart +inv +ellps=GRS80

+step +proj=restore +v_3+from=orthometric_height

+step +proj=vgridshift +grids=egm2008_0_45.tif +inv

+step +proj=elseif +dir=inv

+step +proj=save +into=ellipsoidal_height

+step +proj=vgridshift +grids=egm2008_0_45.tif

+step +proj=save  +into=orthometric_height

+step +proj=restore +v_3 +from=ellipsoidal_height

+step +proj=cart +ellps=GRS80

+step +proj=helmert +inv +x=-366.1939 +y=-115.0688 +z=-776.7039 
+rx=20.963080 +ry=16.462749 +rz=-14.276379 +s=-12.80900 
+convention=coordinate_frame +exact

+step +proj=cart +inv +ellps=intl

+step +proj=tmerc +lat_0=12.180658675 +lon_0=-68.251802281 +k_0=1 
+x_0=23209.5600 +y_0=21423.9900 +ellps=intl

+step +proj=restore +v_3+from=orthometric_height

+step +proj=endif


if / elseif would be strictly restricted to this exact construct, but 
could potentially be later extended to doing other things. I'm quite 
happy with that last proposal actually

And syntaxic sugar, I guess we coud tweak the PROJ string parser, to 
just understand +proj=XXX  as +step +proj=XXXX (would require +inv to be 
placed after +proj). And actually rename +proj as +op (from a quick 
check, it doesn't seem it is a valid parameter of an operation)

So here's my final proposal for today:

cct +op=pipeline
+op=if +dir=fwd
      +op=save +into=orthometric_height
      +op=tmerc +inv +lat_0=12.180658675 +lon_0=-68.251802281 +k_0=1 
+x_0=23209.5600 +y_0=21423.9900 +ellps=intl
      +op=cart +ellps=intl
      +op=helmert +x=-366.1939 +y=-115.0688 +z=-776.7039 +rx=20.963080 
+ry=16.462749 +rz=-14.276379 +s=-12.80900 +convention=coordinate_frame 
+exact
      +op=cart +inv +ellps=GRS80
      +op=restore +v_3 +from=orthometric_height
      +op=vgridshift +grids=egm2008_0_45.tif +inv
+op=elseif +dir=inv
      +op=save +into=ellipsoidal_height
      +op=vgridshift +grids=egm2008_0_45.tif
      +op=save  +into=orthometric_height
      +op=restore +v_3 +from=ellipsoidal_height
      +op=cart +ellps=GRS80
      +op=helmert +inv +x=-366.1939 +y=-115.0688 +z=-776.7039 
+rx=20.963080 +ry=16.462749 +rz=-14.276379 +s=-12.80900 
+convention=coordinate_frame +exact
      +op=cart  +inv +ellps=intl
      +op=tmerc +lat_0=12.180658675 +lon_0=-68.251802281 +k_0=1 
+x_0=23209.5600 +y_0=21423.9900 +ellps=intl
      +op=restore +v_3 +from=orthometric_height
+op=endif

Even


(1) It would look as:

cct +proj=pipeline

+step +proj=save +name=orthometric_height +omit_inv

+step +proj=save +name=orthometric_height +v_3 +omit_fwd

+step +proj=tmerc +inv +lat_0=12.180658675 +lon_0=-68.251802281 +k_0=1 
+x_0=23209.5600 +y_0=21423.9900 +ellps=intl

+step +proj=cart +ellps=intl

+step +proj=helmert +x=-366.1939 +y=-115.0688 +z=-776.7039 +rx=20.963080 
+ry=16.462749 +rz=-14.276379 +s=-12.80900 +convention=coordinate_frame 
+exact

+step +proj=cart +inv +ellps=GRS80

+step +proj=restore +name=orthometric_height +v_3 +omit_inv

+step +proj=save  +name=ellipsoidal_height +v_3 +omit_fwd

+step +proj=restore +name=orthometric_height  +omit_fwd

+step +proj=vgridshift +grids=egm2008_0_45.tif +inv

+step +proj=restore  +name=ellipsoidal_height +omit_fwd



Le 16/12/2023 à 17:42, Thomas Knudsen via PROJ a écrit :
>
>     Greg Troxel said:
>     > We are really re-inventing the traditional HP RPN, and
>     > that's ok, but it's better to re-implement it as
>     > consistently as possible.
>
>     Actually Chuck Moore implemented Forth already in 1968,
>     four years before HP-35, the first HP RPN calculator,
>     was introduced. So in that sense "swap" is historically
>     more consistent than the 1984 PostScript "exch".
>
>     My trusty old HP-15, now doing attic service, had a "x<>y"
>     key for "swap", and I see on the Wikipedia photo [1],
>     that that "x<>y" was used all the way back to the 1972 HP-35.
>
>     The HP-48G, introduced in 1990, according to the photo [2]
>     had a key labelled "swap", so HP RPN appears to be more
>     true to Forth, than to PostScript.
>
>     So for HP, as well as Forth, consistency, "swap" would be
>     preferable.
>
>     The bad thing, however, is that PROJ stacks do not work as
>     one would immediately expect: Actually, there are 4 separate
>     stacks, one for each coordinate, so doing a "push v_1 v_2"
>     followed by a "pop v_2 v_1" does not do any swapping (sse the
>     example in footnote [4], and try to play with different orders
>     of v_1 and v_2).
>
>     Hence, you need to do a preparatory axisswap step to actually
>     put the first coordinate onto the second coordinate stack (from
>     where it can be pop'd back into the first coordinate of the
>     operand). I tend to forget this...
>
>     Rust Geodesy [4] makes do with one stack, but for semi-consistency
>     with PROJ, always pushes and pops in fixed order, i.e. pop v_2 v_1
>     gives the same result as pop v_1 v_2
>
>     In order to follow the principle of least astonishment (POLA) [5],
>     I would have preferred a single stack, and push/pop in consistent
>     order. But since the state of things are as they are, keeping POLA
>     will probably require us to keep things as is.
>
>
>     [1] https://en.wikipedia.org/wiki/HP-35#/media/File:HP-35_Red_Dot.jpg
>     [2] https://upload.wikimedia.org/wikipedia/commons/9/95/HP48G.jpg
>     [3] echo 1 2 3 4 | cct proj=pipeline step proj=push v_1 v_2 step
>     proj=pop v_2 step proj=pop v_1  --
>     [4] https://github.com/busstoptaktik/geodesy
>     [5] https://en.wikipedia.org/wiki/Principle_of_least_astonishment
>
>
> _______________________________________________
> 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/proj/attachments/20231216/f8ede227/attachment-0001.htm>


More information about the PROJ mailing list