Skip to content

Commit

Permalink
Fix reshape line tool fails when reshape line partially exactly
Browse files Browse the repository at this point in the history
overlaps geometry
  • Loading branch information
nyalldawson committed Oct 28, 2020
1 parent d8351c0 commit 37de804
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/core/geometry/qgsgeos.cpp
Expand Up @@ -2491,8 +2491,10 @@ geos::unique_ptr QgsGeos::reshapeLine( const GEOSGeometry *line, const GEOSGeome
geos::unique_ptr intersectGeom( GEOSIntersection_r( geosinit()->ctxt, line, reshapeLineGeos ) );
if ( intersectGeom )
{
atLeastTwoIntersections = ( GEOSGeomTypeId_r( geosinit()->ctxt, intersectGeom.get() ) == GEOS_MULTIPOINT
&& GEOSGetNumGeometries_r( geosinit()->ctxt, intersectGeom.get() ) > 1 );
const int geomType = GEOSGeomTypeId_r( geosinit()->ctxt, intersectGeom.get() );
atLeastTwoIntersections = ( geomType == GEOS_MULTIPOINT && GEOSGetNumGeometries_r( geosinit()->ctxt, intersectGeom.get() ) > 1 )
|| ( geomType == GEOS_GEOMETRYCOLLECTION && GEOSGetNumGeometries_r( geosinit()->ctxt, intersectGeom.get() ) > 0 ) // a collection implies at least two points!
|| ( geomType == GEOS_MULTILINESTRING && GEOSGetNumGeometries_r( geosinit()->ctxt, intersectGeom.get() ) > 0 );
// one point is enough when extending line at its endpoint
if ( GEOSGeomTypeId_r( geosinit()->ctxt, intersectGeom.get() ) == GEOS_POINT )
{
Expand Down
28 changes: 28 additions & 0 deletions tests/src/python/test_qgsgeometry.py
Expand Up @@ -2568,6 +2568,14 @@ def testRegression13274(self):

def testReshape(self):
""" Test geometry reshaping """

# no overlap
g = QgsGeometry.fromWkt('LineString (0 0, 5 0, 5 1, 6 1, 6 0, 7 0)')
self.assertEqual(g.reshapeGeometry(QgsLineString([QgsPoint(4, 2), QgsPoint(7, 2)])), 0)
expWkt = 'LineString (0 0, 5 0, 5 1, 6 1, 6 0, 7 0)'
wkt = g.asWkt()
self.assertTrue(compareWkt(expWkt, wkt), "testReshape failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))

g = QgsGeometry.fromWkt('Polygon ((0 0, 1 0, 1 1, 0 1, 0 0))')
g.reshapeGeometry(QgsLineString([QgsPoint(0, 1.5), QgsPoint(1.5, 0)]))
expWkt = 'Polygon ((0.5 1, 0 1, 0 0, 1 0, 1 0.5, 0.5 1))'
Expand Down Expand Up @@ -2621,6 +2629,26 @@ def testReshape(self):
wkt = g.asWkt()
assert compareWkt(expWkt, wkt), "testReshape failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)

# reshape where reshape line exactly overlaps some portions of geometry
g = QgsGeometry.fromWkt('LineString (0 0, 5 0, 5 1, 6 1, 6 0, 7 0)')
self.assertEqual(g.reshapeGeometry(QgsLineString([QgsPoint(2, 0), QgsPoint(6, 0)])), 0)
expWkt = 'LineString (0 0, 2 0, 5 0, 6 0, 7 0)'
wkt = g.asWkt()
self.assertTrue(compareWkt(expWkt, wkt), "testReshape failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))

g = QgsGeometry.fromWkt('LineString (0 0, 5 0, 5 1, 6 1, 6 0, 7 0)')
self.assertEqual(g.reshapeGeometry(QgsLineString([QgsPoint(5, 0), QgsPoint(7, 0)])), 0)
expWkt = 'LineString (0 0, 5 0, 6 0, 7 0)'
wkt = g.asWkt()
self.assertTrue(compareWkt(expWkt, wkt), "testReshape failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))

# reshape line overlaps at both start and end
g = QgsGeometry.fromWkt('LineString (0 0, 5 0, 5 1, 6 1, 6 0, 7 0)')
self.assertEqual(g.reshapeGeometry(QgsLineString([QgsPoint(4, 0), QgsPoint(7, 0)])), 0)
expWkt = 'LineString (0 0, 4 0, 5 0, 6 0, 7 0)'
wkt = g.asWkt()
self.assertTrue(compareWkt(expWkt, wkt), "testReshape failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))

def testConvertToMultiType(self):
""" Test converting geometries to multi type """
point = QgsGeometry.fromWkt('Point (1 2)')
Expand Down

0 comments on commit 37de804

Please sign in to comment.