Skip to content
Permalink
Browse files

Merge pull request #2606 from nyalldawson/close_rings

Ensure that rings are closed when adding to polygons
  • Loading branch information
mhugent committed Jan 4, 2016
2 parents 73945c0 + 856be9b commit 164739f205354f2fe692dfdfe9a38a050a4a777a
Showing with 41 additions and 10 deletions.
  1. +12 −0 src/core/geometry/qgspolygonv2.cpp
  2. +29 −10 tests/src/core/testqgsgeometry.cpp
@@ -182,6 +182,12 @@ void QgsPolygonV2::addInteriorRing( QgsCurveV2* ring )
ring = segmented;
}

QgsLineStringV2* lineString = dynamic_cast< QgsLineStringV2*>( ring );
if ( lineString && !lineString->isClosed() )
{
lineString->close();
}

if ( mWkbType == QgsWKBTypes::Polygon25D )
{
ring->convertTo( QgsWKBTypes::LineString25D );
@@ -209,6 +215,12 @@ void QgsPolygonV2::setExteriorRing( QgsCurveV2* ring )
ring = line;
}

QgsLineStringV2* lineString = dynamic_cast< QgsLineStringV2*>( ring );
if ( lineString && !lineString->isClosed() )
{
lineString->close();
}

mExteriorRing = ring;

//set proper wkb type
@@ -2152,6 +2152,16 @@ void TestQgsGeometry::polygonV2()
//retrieve exterior ring and check
QCOMPARE( *( static_cast< QgsLineStringV2* >( p1.exteriorRing() ) ), *ext );

//test that a non closed exterior ring will be automatically closed
ext = new QgsLineStringV2();
ext->setPoints( QList< QgsPointV2 >() << QgsPointV2( 0, 0 ) << QgsPointV2( 0, 10 ) << QgsPointV2( 10, 10 )
<< QgsPointV2( 10, 0 ) );
QVERIFY( !ext->isClosed() );
p1.setExteriorRing( ext );
QVERIFY( !p1.isEmpty() );
QVERIFY( p1.exteriorRing()->isClosed() );
QCOMPARE( p1.nCoordinates(), 5 );

//initial setting of exterior ring should set z/m type
QgsPolygonV2 p2;
ext = new QgsLineStringV2();
@@ -2228,35 +2238,44 @@ void TestQgsGeometry::polygonV2()
QCOMPARE( p6.interiorRing( 0 ), ring );
QVERIFY( !p6.interiorRing( 1 ) );

//add non-closed interior ring, should be closed automatically
ring = new QgsLineStringV2();
ring->setPoints( QList< QgsPointV2 >() << QgsPointV2( 0.1, 0.1 ) << QgsPointV2( 0.1, 0.9 ) << QgsPointV2( 0.9, 0.9 )
<< QgsPointV2( 0.9, 0.1 ) );
QVERIFY( !ring->isClosed() );
p6.addInteriorRing( ring );
QCOMPARE( p6.numInteriorRings(), 2 );
QVERIFY( p6.interiorRing( 1 )->isClosed() );

//try adding an interior ring with z to a 2d polygon, z should be dropped
ring = new QgsLineStringV2();
ring->setPoints( QList< QgsPointV2 >() << QgsPointV2( QgsWKBTypes::PointZ, 0.1, 0.1, 1 )
<< QgsPointV2( QgsWKBTypes::PointZ, 0.1, 0.2, 2 ) << QgsPointV2( QgsWKBTypes::PointZ, 0.2, 0.2, 3 )
<< QgsPointV2( QgsWKBTypes::PointZ, 0.2, 0.1, 4 ) << QgsPointV2( QgsWKBTypes::PointZ, 0.1, 0.1, 1 ) );
p6.addInteriorRing( ring );
QCOMPARE( p6.numInteriorRings(), 2 );
QCOMPARE( p6.numInteriorRings(), 3 );
QVERIFY( !p6.is3D() );
QVERIFY( !p6.isMeasure() );
QCOMPARE( p6.wkbType(), QgsWKBTypes::Polygon );
QVERIFY( p6.interiorRing( 1 ) );
QVERIFY( !p6.interiorRing( 1 )->is3D() );
QVERIFY( !p6.interiorRing( 1 )->isMeasure() );
QCOMPARE( p6.interiorRing( 1 )->wkbType(), QgsWKBTypes::LineString );
QVERIFY( p6.interiorRing( 2 ) );
QVERIFY( !p6.interiorRing( 2 )->is3D() );
QVERIFY( !p6.interiorRing( 2 )->isMeasure() );
QCOMPARE( p6.interiorRing( 2 )->wkbType(), QgsWKBTypes::LineString );

//try adding an interior ring with m to a 2d polygon, m should be dropped
ring = new QgsLineStringV2();
ring->setPoints( QList< QgsPointV2 >() << QgsPointV2( QgsWKBTypes::PointM, 0.1, 0.1, 0, 1 )
<< QgsPointV2( QgsWKBTypes::PointM, 0.1, 0.2, 0, 2 ) << QgsPointV2( QgsWKBTypes::PointM, 0.2, 0.2, 0, 3 )
<< QgsPointV2( QgsWKBTypes::PointM, 0.2, 0.1, 0, 4 ) << QgsPointV2( QgsWKBTypes::PointM, 0.1, 0.1, 0, 1 ) );
p6.addInteriorRing( ring );
QCOMPARE( p6.numInteriorRings(), 3 );
QCOMPARE( p6.numInteriorRings(), 4 );
QVERIFY( !p6.is3D() );
QVERIFY( !p6.isMeasure() );
QCOMPARE( p6.wkbType(), QgsWKBTypes::Polygon );
QVERIFY( p6.interiorRing( 2 ) );
QVERIFY( !p6.interiorRing( 2 )->is3D() );
QVERIFY( !p6.interiorRing( 2 )->isMeasure() );
QCOMPARE( p6.interiorRing( 2 )->wkbType(), QgsWKBTypes::LineString );
QVERIFY( p6.interiorRing( 3 ) );
QVERIFY( !p6.interiorRing( 3 )->is3D() );
QVERIFY( !p6.interiorRing( 3 )->isMeasure() );
QCOMPARE( p6.interiorRing( 3 )->wkbType(), QgsWKBTypes::LineString );

//addInteriorRing without z/m to PolygonZM
QgsPolygonV2 p6b;

0 comments on commit 164739f

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