[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