ST_SNAP behaviour with 3D Geometries
Alexandre Neto <[email protected]> Mon, 13 Apr 2026 18:15:21 +0100
| Newsgroups | gmane.comp.gis.postgis |
|---|---|
| Message-ID | <CA+H0G_EQ9E08E2fdEX9-dbid0DRxvLtnQNu2gT8uJ3N3YFxVcQ@mail.gmail.com> |
--0000000000005e3086064f5aa1e9 Content-Type: text/plain; charset="UTF-8" Hi all, I am having trouble understanding the behaviour of St_Snap when used with 3D Geometries. I was aware that st_snap did not properly support 3D geometries, but I would not expect that it actually changes the Z coordinates. I would expect that the Z coordinates would be kept untouched, but that's not what happens. WITH input AS (SELECT 'POINT Z (1.001 1.001 50)'::geometry AS geom), reference AS (SELECT 'POINT Z (1.0 1.0 999)'::geometry AS geom) SELECT ST_AsEWKT(ST_Snap(i.geom, r.geom, 0.01)) AS snapped, ST_Z(ST_Snap(i.geom, r.geom, 0.01)) AS z_after_snap, ST_Z(i.geom) AS z_original FROM input i, reference r; *snapped |z_after_snap|z_original|--------------+------------+----------+POINT(1 1 999)| 999.0| 50.0|* In fact, not only the Z coordinate gets changed as it completely ignores the tolerance. I then tried to use ST_Force2D around the reference geometry, but the result is kind of expected, a 2D geometry with no Z coordinate. I wonder if these are the expected behaviour of ST_snap and there is more a convenient way to snap 3D geometries in 2D while ignoring the Z component without needing to recover all vertices Zs from the original geometry. Thanks, Alexandre Neto --0000000000005e3086064f5aa1e9 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div>Hi all,</div><div><br></div><div>I am having trouble = understanding the behaviour of St_Snap when used with 3D Geometries.</div><= div><br></div><div>I was aware that st_snap did not properly support 3D geo= metries, but I would not expect that it actually changes the Z coordinates.= </div><div><br></div><div>I would expect that the Z coordinates would be ke= pt untouched, but that's not what happens.</div><div><br></div><div sty= le=3D"background-color:rgb(255,255,255);padding:0px 0px 0px 2px"><div style= =3D"color:rgb(35,38,41);background-color:rgb(255,255,255);font-family:"= ;Monospace";font-size:10pt;white-space:pre"><p style=3D"margin:0px"><s= pan style=3D"color:rgb(128,0,0);font-weight:bold">WITH</span> <span style= =3D"color:rgb(142,0,198);font-style:italic">input</span> <span style=3D"= color:rgb(128,0,0);font-weight:bold">AS</span> (<span style=3D"color:rgb(12= 8,0,0);font-weight:bold">SELECT</span> <span style=3D"color:rgb(0,128,0)">&= #39;POINT Z (1.001 1.001 50)'</span>::<span style=3D"color:rgb(0,0,0)">= geometry</span> <span style=3D"color:rgb(128,0,0);font-weight:bold">AS</spa= n> <span style=3D"color:rgb(0,100,100);font-style:italic">geom</span>),</p>= <p style=3D"margin:0px"> <span style=3D"color:rgb(142,0,198);font-style= :italic">reference</span> <span style=3D"color:rgb(128,0,0);font-weight:bol= d">AS</span> (<span style=3D"color:rgb(128,0,0);font-weight:bold">SELECT</s= pan> <span style=3D"color:rgb(0,128,0)">'POINT Z (1.0 1.0 999)'= </span>::<span style=3D"color:rgb(0,0,0)">geometry</span> <span style=3D"co= lor:rgb(128,0,0);font-weight:bold">AS</span> <span style=3D"color:rgb(0,100= ,100);font-style:italic">geom</span>)</p><p style=3D"margin:0px"><span styl= e=3D"color:rgb(128,0,0);font-weight:bold">SELECT</span></p><p style=3D"marg= in:0px"> <span style=3D"color:rgb(0,0,128);font-weight:bold">ST_AsEWKT</= span>(<span style=3D"color:rgb(0,0,128);font-weight:bold">ST_Snap</span>(<s= pan style=3D"color:rgb(142,0,198);font-style:italic">i</span>.<span style= =3D"color:rgb(0,100,100);font-style:italic">geom</span>, <span style=3D"col= or:rgb(142,0,198);font-style:italic">r</span>.<span style=3D"color:rgb(0,10= 0,100);font-style:italic">geom</span>, <span style=3D"color:rgb(0,0,255)">0= .01</span>)) <span style=3D"color:rgb(128,0,0);font-weight:bold">AS</span> = <span style=3D"color:rgb(0,100,100);font-style:italic">snapped</span>,</p><= p style=3D"margin:0px"> <span style=3D"color:rgb(0,0,128);font-weight:bo= ld">ST_Z</span>(<span style=3D"color:rgb(0,0,128);font-weight:bold">ST_Snap= </span>(<span style=3D"color:rgb(142,0,198);font-style:italic">i</span>.<sp= an style=3D"color:rgb(0,100,100);font-style:italic">geom</span>, <span styl= e=3D"color:rgb(142,0,198);font-style:italic">r</span>.<span style=3D"color:= rgb(0,100,100);font-style:italic">geom</span>, <span style=3D"color:rgb(0,0= ,255)">0.01</span>)) <span style=3D"color:rgb(128,0,0);font-weight:bol= d">AS</span> <span style=3D"color:rgb(0,100,100);font-style:italic">z_after= _snap</span>,</p><p style=3D"margin:0px"> <span style=3D"color:rgb(0,0,1= 28);font-weight:bold">ST_Z</span>(<span style=3D"color:rgb(142,0,198);font-= style:italic">i</span>.<span style=3D"color:rgb(0,100,100);font-style:itali= c">geom</span>) <span style=3D"color:rgb(128,0= ,0);font-weight:bold">AS</span> <span style=3D"color:rgb(0,100,100);font-st= yle:italic">z_original</span></p><p style=3D"margin:0px"><span style=3D"col= or:rgb(128,0,0);font-weight:bold">FROM</span> <span style=3D"color:rgb(142,= 0,198);font-style:italic">input</span> <span style=3D"color:rgb(142,0,198);= font-style:italic">i</span>, <span style=3D"color:rgb(142,0,198);font-style= :italic">reference</span> <span style=3D"color:rgb(142,0,198);font-style:it= alic">r</span><span style=3D"color:rgb(255,0,0)">;</span></p></div></div><d= iv><span style=3D"font-family:monospace"><span><span class=3D"gmail-token g= mail-token" style=3D"color:rgb(43,48,59)"><br></span></span></span></div><d= iv><span style=3D"font-family:monospace"><span><span class=3D"gmail-token g= mail-token" style=3D"color:rgb(43,48,59)"><br></span></span></span></div><d= iv><span style=3D"font-family:monospace"><b><font size=3D"4">snapped =C2=A0= =C2=A0 =C2=A0 |z_after_snap|z_original|<br>--------------+------------+---= -------+<br>POINT(1 1 999)| =C2=A0 =C2=A0 =C2=A0 999.0| =C2=A0 =C2=A0 =C2= =A050.0|</font></b></span></div><div><span><span class=3D"gmail-token gmail= -token" style=3D"color:rgb(43,48,59)"><br></span></span></div><div><span><s= pan class=3D"gmail-token gmail-token" style=3D"color:rgb(43,48,59)">In fact= , not only the Z coordinate gets changed as it completely ignores the toler= ance.</span></span></div><div><span><span class=3D"gmail-token gmail-token"= style=3D"color:rgb(43,48,59)"><br></span></span></div><div><span><span cla= ss=3D"gmail-token gmail-token" style=3D"color:rgb(43,48,59)">I then tried t= o use ST_Force2D around the reference geometry, but the result is kind of e= xpected, a 2D geometry with no Z coordinate.<br><br></span></span></div><di= v><span><span class=3D"gmail-token gmail-token" style=3D"color:rgb(43,48,59= )">I wonder if these are the expected behaviour of ST_snap and there=C2=A0i= s more a convenient way to snap 3D geometries in 2D while ignoring=C2=A0the= =C2=A0Z component without needing to recover all vertices Zs from the origi= nal geometry.</span></span></div><div><span><span class=3D"gmail-token gmai= l-token" style=3D"color:rgb(43,48,59)"><br></span></span></div><div><span><= span class=3D"gmail-token gmail-token" style=3D"color:rgb(43,48,59)">Thanks= ,</span></span></div><div><span><span class=3D"gmail-token gmail-token" sty= le=3D"color:rgb(43,48,59)"><br></span></span></div><div><span><span class= =3D"gmail-token gmail-token" style=3D"color:rgb(43,48,59)">Alexandre Neto</= span></span></div></div> --0000000000005e3086064f5aa1e9--