Skip to content
Permalink
Browse files

Fix reshape line tool fails when reshape line partially exactly overl…

…aps geometry
  • Loading branch information
github-actions authored and nyalldawson committed Oct 28, 2020
1 parent ad45f47 commit 497e313e326b1665697d38902bac502d5ceadd8e
Showing with 32 additions and 2 deletions.
  1. +4 −2 src/core/geometry/qgsgeos.cpp
  2. +28 −0 tests/src/python/test_qgsgeometry.py
@@ -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 )
{
@@ -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))'
@@ -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)')

0 comments on commit 497e313

Please sign in to comment.
You can’t perform that action at this time.