[postgis-tickets] [PostGIS] #3270: st_snap() snaps not to closest vertex of the last segment of a closed linestring or polygon
PostGIS
trac at osgeo.org
Wed Sep 2 13:37:55 PDT 2015
#3270: st_snap() snaps not to closest vertex of the last segment of a closed
linestring or polygon
---------------------+---------------------------
Reporter: maxbo | Owner: pramsey
Type: defect | Status: new
Priority: medium | Milestone: PostGIS 2.1.9
Component: postgis | Version: 2.1.x
Keywords: st_snap |
---------------------+---------------------------
st_snap(polygon, polygon) behaves not as expected in some cases:
SELECT (du).path, st_astext((du).geom) FROM
( SELECT st_dumppoints(st_snap(a, b, 1)) AS du
FROM
(SELECT 'POLYGON (( 3549792.3498 5834172.3803, 3550161.76 5833489.0901,
3548998.3501 5833696.5801, 3549384.15 5833671.1502, 3549601.0899
5833944.12, 3549792.3498 5834172.3803 ))'::geometry AS a,
'POLYGON (( 3549792.3498 5834172.3803, 3549792.3285
5834172.3548, 3549601.0899 5833944.12, 3549384.15 5833671.1502,
3548998.3501 5833696.5801, 3551115 5835384, 3550161.76 5833489.0901,
3549792.3498 5834172.3803 ))'::geometry AS b
) c
)d;
I expected to snap the last segment of polygon a
(between POINT(3549601.0899 5833944.12) and POINT(3549792.3498
5834172.3803)) towards POINT(3549792.3285 5834172.3548). So i expected
this point to become vertex {1, 6}.
Actually, Postgis snaps to this point, but snaps the segment before to the
point, which is at much more distance to the point. So the point becomes
vertex {1 5}, resulting in an "ugly" geometry.
This is the result of the query.
"path" "st_astext"
"{1,1}" "POINT(3549792.3498 5834172.3803)"
"{1,2}" "POINT(3550161.76 5833489.0901)"
"{1,3}" "POINT(3548998.3501 5833696.5801)"
"{1,4}" "POINT(3549384.15 5833671.1502)"
"{1,5}" "POINT(3549792.3285 5834172.3548)"
"{1,6}" "POINT(3549601.0899 5833944.12)"
"{1,7}" "POINT(3549792.3498 5834172.3803)"
The problem only occures when the point should be snapped to the last
segment of the polygon.
If i shift the start/endpoint of the polygon to the second point, the
result of the snapping is correct:
SELECT (du).path, st_astext((du).geom) FROM
( SELECT st_dumppoints(st_snap(a, b, 1)) AS du
FROM
(SELECT 'POLYGON (( 3550161.76 5833489.0901, 3548998.3501 5833696.5801,
3549384.15 5833671.1502, 3549601.0899 5833944.12, 3549792.3498
5834172.3803, 3550161.76 5833489.0901 ))'::geometry AS a,
'POLYGON (( 3549792.3498 5834172.3803, 3549792.3285
5834172.3548, 3549601.0899 5833944.12, 3549384.15 5833671.1502,
3548998.3501 5833696.5801, 3551115 5835384, 3550161.76 5833489.0901,
3549792.3498 5834172.3803 ))'::geometry AS b
) c
)d;
"path" "st_astext"
"{1,1}" "POINT(3550161.76 5833489.0901)"
"{1,2}" "POINT(3548998.3501 5833696.5801)"
"{1,3}" "POINT(3549384.15 5833671.1502)"
"{1,4}" "POINT(3549601.0899 5833944.12)"
"{1,5}" "POINT(3549792.3285 5834172.3548)"
"{1,6}" "POINT(3549792.3498 5834172.3803)"
"{1,7}" "POINT(3550161.76 5833489.0901)"
Now the POINT(3549792.3285 5834172.3548) is inserted between
POINT(3549601.0899 5833944.12) and POINT(3549792.3498 5834172.3803) as {1,
5}.
When i shift the start/endpoint into the other direction, it works fine,
too:
SELECT (du).path, st_astext((du).geom) FROM
( SELECT st_dumppoints(st_snap(a, b, 1)) AS du
(SELECT 'POLYGON (( 3549601.0899 5833944.12, 3549792.3498 5834172.3803,
3550161.76 5833489.0901, 3548998.3501 5833696.5801, 3549384.15
5833671.1502, 3549601.0899 5833944.12 ))'::geometry AS a,
'POLYGON (( 3549792.3498 5834172.3803, 3549792.3285
5834172.3548, 3549601.0899 5833944.12, 3549384.15 5833671.1502,
3548998.3501 5833696.5801, 3551115 5835384, 3550161.76 5833489.0901,
3549792.3498 5834172.3803 ))'::geometry AS b
) c
)d;
"path" "st_astext"
"{1,1}" "POINT(3549601.0899 5833944.12)"
"{1,2}" "POINT(3549792.3285 5834172.3548)"
"{1,3}" "POINT(3549792.3498 5834172.3803)"
"{1,4}" "POINT(3550161.76 5833489.0901)"
"{1,5}" "POINT(3548998.3501 5833696.5801)"
"{1,6}" "POINT(3549384.15 5833671.1502)"
"{1,7}" "POINT(3549601.0899 5833944.12)"
So the point is inserted again in the right position, this time it is
inserted into the first segment after point {1,1} as {1, 2}
The same problem occures for a closed linestring:
SELECT (du).path, st_astext((du).geom) FROM
( SELECT st_dumppoints(st_snap(a, b, 1)) AS du
FROM
(SELECT 'LINESTRING ( 3549792.3498 5834172.3803, 3550161.76
5833489.0901, 3548998.3501 5833696.5801, 3549384.15 5833671.1502,
3549601.0899 5833944.12, 3549792.3498 5834172.3803 )'::geometry AS a,
'LINESTRING ( 3549792.3498 5834172.3803, 3549792.3285
5834172.3548, 3549601.0899 5833944.12, 3549384.15 5833671.1502,
3548998.3501 5833696.5801, 3551115 5835384, 3550161.76 5833489.0901,
3549792.3498 5834172.3803 )'::geometry AS b
) c
)d;
"path" "st_astext"
"{1}" "POINT(3549792.3498 5834172.3803)"
"{2}" "POINT(3550161.76 5833489.0901)"
"{3}" "POINT(3548998.3501 5833696.5801)"
"{4}" "POINT(3549384.15 5833671.1502)"
"{5}" "POINT(3549792.3285 5834172.3548)"
"{6}" "POINT(3549601.0899 5833944.12)"
"{7}" "POINT(3549792.3498 5834172.3803)"
But it snaps correctly, when the linestring is not closed (by dropping the
first point...)
SELECT (du).path, st_astext((du).geom) FROM
( SELECT st_dumppoints(st_snap(a, b, 1)) AS du
FROM
(SELECT 'LINESTRING ( 3550161.76 5833489.0901, 3548998.3501
5833696.5801, 3549384.15 5833671.1502, 3549601.0899 5833944.12,
3549792.3498 5834172.3803 )'::geometry AS a,
'LINESTRING ( 3549792.3285 5834172.3548, 3549601.0899
5833944.12, 3549384.15 5833671.1502, 3548998.3501 5833696.5801, 3551115
5835384, 3550161.76 5833489.0901, 3549792.3498 5834172.3803 )'::geometry
AS b
) c
)d;
"path" "st_astext"
"{1}" "POINT(3550161.76 5833489.0901)"
"{2}" "POINT(3548998.3501 5833696.5801)"
"{3}" "POINT(3549384.15 5833671.1502)"
"{4}" "POINT(3549601.0899 5833944.12)"
"{5}" "POINT(3549792.3285 5834172.3548)"
"{6}" "POINT(3549792.3498 5834172.3803)"
So maybe this could be fixed by checking, if st_snap handles a segment
near the endpoint different?
I am using
select PostGIS_Full_Version();
POSTGIS="2.1.2 r12389" GEOS="3.4.2-CAPI-1.8.2 r3921" PROJ="Rel. 4.8.0, 6
March 2012" GDAL="GDAL 1.10.1, released 2013/08/26" LIBXML="2.9.1"
LIBJSON="UNKNOWN" TOPOLOGY RASTER
--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/3270>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.
More information about the postgis-tickets
mailing list