Opened 8 years ago

Closed 8 years ago

Last modified 7 years ago

#758 closed defect (fixed)

LineStringSnapper snaps in wrong order in last segment of closed linestring

Reported by: maxbo Owned by: geos-devel@…
Priority: minor Milestone: 3.6.1
Component: Default Version: 3.4.2
Severity: Unassigned Keywords: LineStringSnapper
Cc:

Description

st_snap(linestring, geometry) behaves not always as expected for closed linestrings in the last segment. This seems to be a bug in the geos LineStringSnapper class:

(using (POSTGIS="2.1.5 r13152" GEOS="3.4.2-CAPI-1.8.2 r3924" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.11.1, released 2014/09/24 GDAL_DATA not found" LIBXML="2.7.8" LIBJSON="UNKNOWN" TOPOLOGY RASTER)

The following example should demonstrate the problem:

SELECT (du).path[1] as vertex_nr, st_astext((du).geom) FROM ( SELECT st_dumppoints(st_snap(a, b, 2)) AS du FROM (SELECT 'LINESTRING (1 1, 5 9, 9 1, 1 1)'::geometry AS a, 'MULTIPOINT(0 0, 10 0, 1 0.5)'::geometry AS b ) c )d;

I expected that POINT(1 0.5) would be inserted into the last segment of the LINESTRING at position 4. This point is acutally inserted, but at a wrong position (Position 3), resulting in an "ugly" geometry.

1;POINT(0 0) 2;POINT(5 9) 3;POINT(1 0.5) 4;POINT(10 0) 5;POINT(0 0)

This behaviour only occures for a closed linestring. Opening the linestring SELECT (du).path[1] as vertex_nr, st_astext((du).geom) FROM ( SELECT st_dumppoints(st_snap(a, b, 2)) AS du FROM (SELECT 'LINESTRING (0.9 0.9, 5 9, 9 1, 1 1)'::geometry AS a, 'MULTIPOINT(0 0, 10 0, 1 0.5)'::geometry AS b ) c )d;

will take POINT(1, .5) as endpoint.

1;POINT(0 0) 2;POINT(5 9) 3;POINT(10 0) 4;POINT(1 0.5)

Shifting the start- and endpoint of the linestring

SELECT (du).path[1] as vertex_nr, st_astext((du).geom) FROM ( SELECT st_dumppoints(st_snap(a, b, 2)) AS du FROM (SELECT 'LINESTRING (5 9, 9 1, 1 1, 5 9)'::geometry AS a, 'MULTIPOINT(0 0, 10 0, 1 0.5)'::geometry AS b ) c )d;

results in a correct geometry, where POINT(1, .5) is inserted at position 3 between POINT(10 0) and POINT(0 0)

1;POINT(5 9) 2;POINT(10 0) 3;POINT(1 0.5) 4;POINT(0 0) 5;POINT(5 9)

Here a test for GEOSSnapTest.cpp

/ Test snapping of last segment of closed ring to snap points

{

geom1_ = GEOSGeomFromWKT("LINESTRING (1 1, 5 9, 9 1, 1 1)"); geom2_ = GEOSGeomFromWKT("MULTIPOINT(0 0, 10 0, 1 0.5)"); geom3_ = GEOSSnap(geom1_, geom2_, 2);

char* wkt_c = GEOSWKTWriter_write(w_, geom3_); std::string out(wkt_c); free(wkt_c);

ensure_equals(out, "LINESTRING (0 0, 5 9, 10 0, 1 0.5, 0 0)");

}

Thanks,

Max

Change History (9)

comment:1 by strk, 8 years ago

Great testcase, thanks for it! See how you like r4129 please.

comment:2 by strk, 8 years ago

Milestone: 3.5.13.4.3
Version: 3.5.03.4.2

comment:3 by strk, 8 years ago

Resolution: fixed
Status: newclosed

r4134 in 3.4 branch (3.4.3) -- r4131 in 3.5 branch (3.5.1) -- r3129 in trunk

comment:4 by strk, 8 years ago

Sorry it is r4129 in trunk (3.6.0), not r3129

comment:5 by maxbo, 8 years ago

Thanks for the quick fix! Max

comment:6 by strk, 7 years ago

Milestone: 3.4.33.6.1

Ticket retargeted after milestone deleted

comment:7 by Sandro Santilli <strk@…>, 7 years ago

In 449a78c/git:

Fix snapping of last segment in a closed linestring

See #758

git-svn-id: http://svn.osgeo.org/geos/trunk@4129 5242fede-7e19-0410-aef8-94bd7d2200fb

comment:8 by Sandro Santilli <strk@…>, 7 years ago

In 449a78c/git:

Fix snapping of last segment in a closed linestring

See #758

git-svn-id: http://svn.osgeo.org/geos/trunk@4129 5242fede-7e19-0410-aef8-94bd7d2200fb

comment:9 by Sandro Santilli <strk@…>, 7 years ago

In 449a78c/git:

Fix snapping of last segment in a closed linestring

See #758

git-svn-id: http://svn.osgeo.org/geos/trunk@4129 5242fede-7e19-0410-aef8-94bd7d2200fb

Note: See TracTickets for help on using tickets.