mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-22 00:14:55 -05:00
Fix QgsGeometry::asQPolygonF doesn't handle multipolygon inputs
gracefully
This commit is contained in:
parent
766e0b290e
commit
33f31d826a
@ -1823,9 +1823,14 @@ otherwise returns a null QPointF.
|
||||
|
||||
QPolygonF asQPolygonF() const;
|
||||
%Docstring
|
||||
Returns contents of the geometry as a QPolygonF. If geometry is a linestring,
|
||||
then the result will be an open QPolygonF. If the geometry is a polygon,
|
||||
then the result will be a closed QPolygonF of the geometry's exterior ring.
|
||||
Returns contents of the geometry as a QPolygonF.
|
||||
|
||||
If geometry is a linestring, then the result will be an open QPolygonF.
|
||||
If the geometry is a polygon, then the result will be a closed QPolygonF
|
||||
of the geometry's exterior ring.
|
||||
|
||||
If the geometry is a multi-part geometry, then only the first part will
|
||||
be considered when converting to a QPolygonF.
|
||||
|
||||
.. versionadded:: 2.7
|
||||
%End
|
||||
|
||||
@ -2558,36 +2558,22 @@ QPointF QgsGeometry::asQPointF() const
|
||||
|
||||
QPolygonF QgsGeometry::asQPolygonF() const
|
||||
{
|
||||
const QgsWkbTypes::Type type = wkbType();
|
||||
const QgsLineString *line = nullptr;
|
||||
if ( QgsWkbTypes::flatType( type ) == QgsWkbTypes::LineString )
|
||||
const QgsAbstractGeometry *part = constGet();
|
||||
|
||||
// if a geometry collection, get first part only
|
||||
if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection *>( part ) )
|
||||
{
|
||||
line = qgsgeometry_cast< const QgsLineString * >( constGet() );
|
||||
}
|
||||
else if ( QgsWkbTypes::flatType( type ) == QgsWkbTypes::Polygon )
|
||||
{
|
||||
const QgsPolygon *polygon = qgsgeometry_cast< const QgsPolygon * >( constGet() );
|
||||
if ( polygon )
|
||||
line = qgsgeometry_cast< const QgsLineString * >( polygon->exteriorRing() );
|
||||
if ( collection->numGeometries() > 0 )
|
||||
part = collection->geometryN( 0 );
|
||||
else
|
||||
return QPolygonF();
|
||||
}
|
||||
|
||||
if ( line )
|
||||
{
|
||||
const double *srcX = line->xData();
|
||||
const double *srcY = line->yData();
|
||||
const int count = line->numPoints();
|
||||
QPolygonF res( count );
|
||||
QPointF *dest = res.data();
|
||||
for ( int i = 0; i < count; ++i )
|
||||
{
|
||||
*dest++ = QPointF( *srcX++, *srcY++ );
|
||||
}
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QPolygonF();
|
||||
}
|
||||
if ( const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( part ) )
|
||||
return curve->asQPolygonF();
|
||||
else if ( const QgsCurvePolygon *polygon = qgsgeometry_cast< const QgsCurvePolygon * >( part ) )
|
||||
return polygon->exteriorRing() ? polygon->exteriorRing()->asQPolygonF() : QPolygonF();
|
||||
return QPolygonF();
|
||||
}
|
||||
|
||||
bool QgsGeometry::deleteRing( int ringNum, int partNum )
|
||||
|
||||
@ -1917,9 +1917,15 @@ class CORE_EXPORT QgsGeometry
|
||||
QPointF asQPointF() const;
|
||||
|
||||
/**
|
||||
* Returns contents of the geometry as a QPolygonF. If geometry is a linestring,
|
||||
* then the result will be an open QPolygonF. If the geometry is a polygon,
|
||||
* then the result will be a closed QPolygonF of the geometry's exterior ring.
|
||||
* Returns contents of the geometry as a QPolygonF.
|
||||
*
|
||||
* If geometry is a linestring, then the result will be an open QPolygonF.
|
||||
* If the geometry is a polygon, then the result will be a closed QPolygonF
|
||||
* of the geometry's exterior ring.
|
||||
*
|
||||
* If the geometry is a multi-part geometry, then only the first part will
|
||||
* be considered when converting to a QPolygonF.
|
||||
*
|
||||
* \since QGIS 2.7
|
||||
*/
|
||||
QPolygonF asQPolygonF() const;
|
||||
|
||||
@ -16590,6 +16590,34 @@ void TestQgsGeometry::asQPolygonF()
|
||||
QgsGeometry badGeom( QgsGeometry::fromPointXY( mPoint1 ) );
|
||||
QPolygonF fromBad = badGeom.asQPolygonF();
|
||||
QVERIFY( fromBad.isEmpty() );
|
||||
|
||||
// test a multipolygon
|
||||
QPolygonF res = QgsGeometry::fromWkt( QStringLiteral( "MultiPolygon (((0 0, 10 0, 10 10, 0 10, 0 0 )),((2 2, 4 2, 4 4, 2 4, 2 2)))" ) ).asQPolygonF();
|
||||
QVERIFY( res.isClosed() );
|
||||
QCOMPARE( res.size(), 5 );
|
||||
QCOMPARE( res.at( 0 ).x(), 0.0 );
|
||||
QCOMPARE( res.at( 0 ).y(), 0.0 );
|
||||
QCOMPARE( res.at( 1 ).x(), 10.0 );
|
||||
QCOMPARE( res.at( 1 ).y(), 0.0 );
|
||||
QCOMPARE( res.at( 2 ).x(), 10.0 );
|
||||
QCOMPARE( res.at( 2 ).y(), 10.0 );
|
||||
QCOMPARE( res.at( 3 ).x(), 0.0 );
|
||||
QCOMPARE( res.at( 3 ).y(), 10.0 );
|
||||
QCOMPARE( res.at( 4 ).x(), 0.0 );
|
||||
QCOMPARE( res.at( 4 ).y(), 0.0 );
|
||||
|
||||
// test a multilinestring
|
||||
res = QgsGeometry::fromWkt( QStringLiteral( "MultiLineString((0 0, 10 0, 10 10, 0 10 ),(2 2, 4 2, 4 4, 2 4))" ) ).asQPolygonF();
|
||||
QVERIFY( !res.isClosed() );
|
||||
QCOMPARE( res.size(), 4 );
|
||||
QCOMPARE( res.at( 0 ).x(), 0.0 );
|
||||
QCOMPARE( res.at( 0 ).y(), 0.0 );
|
||||
QCOMPARE( res.at( 1 ).x(), 10.0 );
|
||||
QCOMPARE( res.at( 1 ).y(), 0.0 );
|
||||
QCOMPARE( res.at( 2 ).x(), 10.0 );
|
||||
QCOMPARE( res.at( 2 ).y(), 10.0 );
|
||||
QCOMPARE( res.at( 3 ).x(), 0.0 );
|
||||
QCOMPARE( res.at( 3 ).y(), 10.0 );
|
||||
}
|
||||
|
||||
void TestQgsGeometry::comparePolylines()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user