Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Ensure that rings are closed when adding to polygons
  • Loading branch information
nyalldawson committed Dec 22, 2015
1 parent 5838819 commit 856be9b
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 10 deletions.
12 changes: 12 additions & 0 deletions src/core/geometry/qgspolygonv2.cpp
Expand Up @@ -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 );
Expand Down Expand Up @@ -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
Expand Down
39 changes: 29 additions & 10 deletions tests/src/core/testqgsgeometry.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 856be9b

Please sign in to comment.