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
[email protected]
https://lists.osgeo.org/mailman/listinfo/proj
--
http://www.spatialys.com
My software is free, but my time generally not.
_______________________________________________
PROJ mailing list
[email protected]
https://lists.osgeo.org/mailman/listinfo/proj