[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