[PROJ] Make push and pop FIFO?
Even Rouault
even.rouault at spatialys.com
Sat Feb 3 10:29:47 PST 2024
Thomas,
| The main problem with PROJ's current push/pop functionality
> is that the four-stack implementation makes it impossible
> to push one dimension of a coordinate-tuple and pop it into
> another, without an elaborate axisswap dance at both ends
> of the push/pop-pair.
>
> This is a consequence of the v_1 ... v_4 syntax used: Since
> the order of operator arguments is not necessarily preserved
> during the parsing process, a pair specified as "v_1 v_2"
> may appear as "v_2 v_1" at parsing time.
While I agree with the theoretical problem, is it actually an issue in
practice? I can't remember having been annoyed by that a single time.
Axis swap issues mostly/only occur to get compliant with CRS official
axis order, and that happens only at the early and final stages of a
pipeline, whereas push/pop logic happens in between where we always
speak longitude,latitude / easting, northing in that order. So during
most of a pipeline execution, axis order remains quite stable. So while
imperfect, I don't see a strong/immediate need to implement a new
improved push/pop.
>
>
> proj=stack push=1,3
> proj=stack swap
> proj=stack pop=1,3
>
> to essentially do the same as above and:
>
> proj=stack push=1,3
> proj=stack flip=3,1
stack swap, flip: sorry but my own imperfect brain of a programmer not
having coded in Forth, I will have a very hard time to remember what
they do exactly without referring to the doc :-)
>
> The wish for named registers mentioned earlier in the
> thread may be introduced using a similar syntax, where:
>
> proj=reg save=1,3 into=first,third
> proj=reg restore=1,3 from=third,first
I would be interested in implementing just save/restore.
Why not having 2 separate operations, since (save,into) and
(restore,from) are mutually exclusive parameters.
So
- proj=save from=1,3 into=first,third
- proj=restore into=1,3 from=first,third
So my pipeline would become:
|proj=pipeline step proj=save from=3 into=etrs89_h omit_inv # skipped on
reverse path step inv proj=vgridshift grids=CR2005.tif multiplier=1 step
proj=save from=3 into=baltic57_h # reversed as restore step proj=restore
from=etrs89_h into=3 omit_inv # skipped on reverse path step proj=cart
ellps=GRS80 step inv proj=helmert x=572.213 rx=-4.9732 y=85.334
ry=-1.529 z=461.94 rz=-5.2484 s=3.5378 convention=coordinate_frame step
inv proj=cart ellps=bessel step proj=restore from=baltic57_h into=3 #
reversed as a save|
I find it reasonably readable.
But I can also live with your proposed syntax.
~~~~~
Or... at least for the sake of brainstorming.... I've also imagined that
we could extent the existing "set" operator with new capabilities, that
would bring it even closer to the syntax of most programming languages
(destination=source)
- proj=set first=v_1 : assign v_1 component to "first" variable
- proj=set v_1=first : restore v_1 component from "first" variable
This causes a few departures from actual PROJ operator logic in, but
none of them are actually implementation issues:
- the parameter name is actually a variable for the "save" semantics (so
we have to iterate over the list of parameters, instead of just querying
a fixed set of parameter names)
- for the restore case (ie v_1=), we need to look at the value to
determine the semantics. If it is a number, then use the current
semantics. If it is a string, then it is a variable name. But not
different from programming language with A=1 and A=B...
In the reverse path, proj=set first=v_1 would be interpreted as proj=set
v_1=first, and vice-verca. That part is admitedly a bit hard to
swallow... especially since it wouldn't apply to when you do the regular
v_1=numeric_value, and would be my main hesitation to implement that.
If we'd go with the idea, we would likely need to exclude v_1, v_2, v_3,
v_4 as valid variable names (that is assigning a component to another
one, since that's generally the role of axisswap) mostly because it is
not intuitive to me what should be done in the reverse path. We's also
need to exclude "proj" as a variable name to avoid awkward and
unparseable things like "proj=set proj=v_1".
~~~~~~~
[ side remark: Actually I believe the push/pop stack logic could be
entirely replaced by named registers. If you look at programming
languages, you use more often named variables than stacks. And in actual
PROJ pipelines, I believe you have rarely have patterns where you have
nested pushes of the same variable, that is something like "push 1", do
X, "push 1", do Y "pop 1", do Z, "pop 1". And even if you have, that can
be easily replaced with "save 1 as first_one", do X, "save 1 as
second_one", do Y, "restore 1 from second_one", do Z, "restore 1 from
first_one".
... but ... while my above remark is likely true for "optimized" /
hand-written pipelines, looking at the code in createOperations() that
compose pipelines, I wouldn't exclude that such situations could happen
where it would generate a pipeline with nested pushes, some of them
being likely redundant/no-op. I'm not sure really of what monstrosities
that code can generate :-) Anyway the current push/pop will remain]
>
> The problem, however, is when trying to interpret the
> workings of a pipeline running in inverse mode:
>
> In the inverse stack-case, we only need to flip the
> abstract concepts of stack slots, and swap push for pop.
>
> Whereas in the register case, we also need to "abstractly
> swap the concrete concepts behind the concrete register
> names" which, at least to my imperfect brain, is much
> harder.
Understanding the inversion of a pipelines requires a fully awaken
brain (Acually when you think of it, no programming language I'm aware
of offers the possibility to execute a program in reverse order) -
especially with omit_fwd/omit_inv, double negation of +inv, etc. , but
the inverse of a save is a restore, and the inverse of into is from. So
not terribly different from push / pop.
Even
--
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/20240203/7a6ebeb0/attachment-0001.htm>
More information about the PROJ
mailing list