<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Thomas,<br>
</p>
| The main problem with PROJ's current push/pop functionality
<blockquote type="cite"
cite="mid:CAH0YoEM66oNNHAZJbmHfksepMMpOB8YpWPM7tS++Tmm-jPZn0Q@mail.gmail.com">
<div dir="ltr">
<div>is that the four-stack implementation makes it impossible<br>
to push one dimension of a coordinate-tuple and pop it into<br>
another, without an elaborate axisswap dance at both ends<br>
of the push/pop-pair.<br>
<br>
This is a consequence of the v_1 ... v_4 syntax used: Since<br>
the order of operator arguments is not necessarily preserved<br>
during the parsing process, a pair specified as "v_1 v_2"<br>
may appear as "v_2 v_1" at parsing time.<br>
</div>
</div>
</blockquote>
<p>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.</p>
<blockquote type="cite"
cite="mid:CAH0YoEM66oNNHAZJbmHfksepMMpOB8YpWPM7tS++Tmm-jPZn0Q@mail.gmail.com">
<div dir="ltr"><br>
<div><br>
</div>
<div> proj=stack push=1,3<br>
proj=stack swap<br>
proj=stack pop=1,3<br>
<br>
</div>
<div>to essentially do the same as above and:<br>
<br>
</div>
<div> proj=stack push=1,3<br>
proj=stack flip=3,1<br>
</div>
</div>
</blockquote>
<p>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 :-)</p>
<br>
<blockquote type="cite"
cite="mid:CAH0YoEM66oNNHAZJbmHfksepMMpOB8YpWPM7tS++Tmm-jPZn0Q@mail.gmail.com">
<div dir="ltr">
<div><br>
The wish for named registers mentioned earlier in the<br>
thread may be introduced using a similar syntax, where:<br>
<br>
</div>
<div> proj=reg save=1,3 into=first,third<br>
proj=reg restore=1,3 from=third,first<br>
</div>
</div>
</blockquote>
<p>I would be interested in implementing just save/restore.</p>
Why not having 2 separate operations, since (save,into) and
(restore,from) are mutually exclusive parameters.
<p>So</p>
<p>- proj=save from=1,3 into=first,third</p>
<p>- proj=restore into=1,3 from=first,third</p>
So my pipeline would become:<br>
<pre class="notranslate"><code class="notranslate">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</code></pre>
<p></p>
<p>I find it reasonably readable.<br>
</p>
<p>But I can also live with your proposed syntax.</p>
<p></p>
<p>~~~~~<br>
</p>
<p>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)<br>
</p>
<p>- proj=set first=v_1 : assign v_1 component to "first" variable<br>
</p>
<p>- proj=set v_1=first : restore v_1 component from "first"
variable<br>
</p>
<p>This causes a few departures from actual PROJ operator logic in,
but none of them are actually implementation issues:<br>
</p>
<p>- 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)<br>
</p>
<p>- 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...</p>
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.<br>
<p>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". </p>
<p>~~~~~~~</p>
<p>[ 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".</p>
<p>... 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]<br>
</p>
<p><br>
</p>
<p></p>
<p></p>
<blockquote type="cite"
cite="mid:CAH0YoEM66oNNHAZJbmHfksepMMpOB8YpWPM7tS++Tmm-jPZn0Q@mail.gmail.com">
<div dir="ltr">
<div><br>
The problem, however, is when trying to interpret the<br>
workings of a pipeline running in inverse mode:<br>
<br>
In the inverse stack-case, we only need to flip the<br>
abstract concepts of stack slots, and swap push for pop.<br>
<br>
Whereas in the register case, we also need to "abstractly<br>
swap the concrete concepts behind the concrete register<br>
names" which, at least to my imperfect brain, is much<br>
harder.<br>
</div>
</div>
</blockquote>
<p>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.<br>
</p>
Even
<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>