Skip to content
Permalink
Browse files

Fix reshape line tool fails when reshape line partially exactly

overlaps geometry

(cherry picked from commit 37de804)
  • Loading branch information
nyalldawson committed Nov 20, 2020
1 parent 9a075a4 commit ad4909633f37a03e6cf41edbf0bf63e4f0699ecd
Showing with 32 additions and 2 deletions.
  1. +4 −2 src/core/geometry/qgsgeos.cpp
  2. +28 −0 tests/src/python/test_qgsgeometry.py
@@ -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 )
{
@@ -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))'
@@ -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)')

0 comments on commit ad49096

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