#758 closed defect (fixed)
LineStringSnapper snaps in wrong order in last segment of closed linestring
Reported by: | maxbo | Owned by: | |
---|---|---|---|
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 , 9 years ago
comment:2 by , 9 years ago
Milestone: | 3.5.1 → 3.4.3 |
---|---|
Version: | 3.5.0 → 3.4.2 |
comment:3 by , 9 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Great testcase, thanks for it! See how you like r4129 please.