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

(cherry picked from commit 37de804)
  • Loading branch information
nyalldawson committed Nov 20, 2020
1 parent 9a075a4 commit ad49096
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 @@ -2439,8 +2439,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 @@ -2358,6 +2358,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 @@ -2408,6 +2416,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 ad49096

Please sign in to comment.