[api] Add helper api to directly retrieve a point/linestring/polygon from

a QgsMultiPoint/QgsMultiLineString/QgsMultiPolygon

Avoids the need to have to manually do an annoying cast when we
already know the geometry type
This commit is contained in:
Nyall Dawson 2020-08-17 13:00:47 +10:00
parent 0b651de82e
commit 5d2495e65a
27 changed files with 485 additions and 33 deletions

View File

@ -21,6 +21,30 @@ Multi curve geometry collection.
%End
public:
QgsMultiCurve();
SIP_PYOBJECT curveN( int index ) /TypeHint="QgsCurve"/;
%Docstring
Returns the curve with the specified ``index``.
An IndexError will be raised if no curve with the specified index exists.
.. versionadded:: 3.16
%End
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
{
PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
return sipConvertFromType( sipCpp->curveN( a0 ), sipType_QgsCurve, NULL );
}
%End
virtual QString geometryType() const;
virtual QgsMultiCurve *clone() const /Factory/;

View File

@ -8,6 +8,7 @@
class QgsMultiLineString: QgsMultiCurve
{
%Docstring
@ -22,6 +23,29 @@ Multi line string geometry collection.
public:
QgsMultiLineString();
SIP_PYOBJECT lineStringN( int index ) /TypeHint="QgsLineString"/;
%Docstring
Returns the line string with the specified ``index``.
An IndexError will be raised if no line string with the specified index exists.
.. versionadded:: 3.16
%End
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
{
PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
return sipConvertFromType( sipCpp->lineStringN( a0 ), sipType_QgsLineString, NULL );
}
%End
virtual QString geometryType() const;
virtual QgsMultiLineString *clone() const /Factory/;

View File

@ -22,6 +22,29 @@ Multi point geometry collection.
public:
QgsMultiPoint();
SIP_PYOBJECT pointN( int index ) /TypeHint="QgsPoint"/;
%Docstring
Returns the point with the specified ``index``.
An IndexError will be raised if no point with the specified index exists.
.. versionadded:: 3.16
%End
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
{
PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
return sipConvertFromType( sipCpp->pointN( a0 ), sipType_QgsPoint, NULL );
}
%End
virtual QString geometryType() const;
virtual QgsMultiPoint *clone() const /Factory/;

View File

@ -8,6 +8,7 @@
class QgsMultiPolygon: QgsMultiSurface
{
%Docstring
@ -21,6 +22,30 @@ Multi polygon geometry collection.
%End
public:
QgsMultiPolygon();
SIP_PYOBJECT polygonN( int index ) /TypeHint="QgsPolygon"/;
%Docstring
Returns the polygon with the specified ``index``.
An IndexError will be raised if no polygon with the specified index exists.
.. versionadded:: 3.16
%End
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
{
PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
return sipConvertFromType( sipCpp->polygonN( a0 ), sipType_QgsPolygon, NULL );
}
%End
virtual QString geometryType() const;
virtual void clear();

View File

@ -8,6 +8,8 @@
class QgsMultiSurface: QgsGeometryCollection
{
%Docstring
@ -21,6 +23,30 @@ Multi surface geometry collection.
%End
public:
QgsMultiSurface();
SIP_PYOBJECT surfaceN( int index ) /TypeHint="QgsSurface"/;
%Docstring
Returns the surface with the specified ``index``.
An IndexError will be raised if no surface with the specified index exists.
.. versionadded:: 3.16
%End
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
{
PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
return sipConvertFromType( sipCpp->surfaceN( a0 ), sipType_QgsSurface, NULL );
}
%End
virtual QString geometryType() const;
virtual void clear();

View File

@ -130,9 +130,7 @@ void QgsBufferedLine3DSymbolHandler::processFeature( QgsFeature &f, const Qgs3DR
QgsMultiPolygon *mpolyBuffered = static_cast<QgsMultiPolygon *>( buffered );
for ( int i = 0; i < mpolyBuffered->numGeometries(); ++i )
{
QgsAbstractGeometry *partBuffered = mpolyBuffered->geometryN( i );
Q_ASSERT( QgsWkbTypes::flatType( partBuffered->wkbType() ) == QgsWkbTypes::Polygon );
QgsPolygon *polyBuffered = static_cast<QgsPolygon *>( partBuffered )->clone(); // need to clone individual geometry parts
QgsPolygon *polyBuffered = static_cast<QgsPolygon *>( mpolyBuffered->polygonN( i ) )->clone(); // need to clone individual geometry parts
processPolygon( polyBuffered, f.id(), mSymbol.height(), mSymbol.extrusionHeight(), context, out );
}
delete buffered;
@ -259,7 +257,7 @@ void QgsSimpleLine3DSymbolHandler::processFeature( QgsFeature &f, const Qgs3DRen
{
for ( int nGeom = 0; nGeom < mls->numGeometries(); ++nGeom )
{
const QgsLineString *ls = qgsgeometry_cast<const QgsLineString *>( mls->geometryN( nGeom ) );
const QgsLineString *ls = mls->lineStringN( nGeom );
out.addLineString( *ls );
}
}
@ -372,7 +370,7 @@ void QgsThickLine3DSymbolHandler::processFeature( QgsFeature &f, const Qgs3DRend
{
for ( int nGeom = 0; nGeom < mls->numGeometries(); ++nGeom )
{
const QgsLineString *ls = qgsgeometry_cast<const QgsLineString *>( mls->geometryN( nGeom ) );
const QgsLineString *ls = mls->lineStringN( nGeom );
out.addLineString( *ls );
}
}

View File

@ -175,9 +175,7 @@ void QgsPolygon3DSymbolHandler::processFeature( QgsFeature &f, const Qgs3DRender
{
for ( int i = 0; i < mpoly->numGeometries(); ++i )
{
const QgsAbstractGeometry *g2 = mpoly->geometryN( i );
Q_ASSERT( QgsWkbTypes::flatType( g2->wkbType() ) == QgsWkbTypes::Polygon );
QgsPolygon *polyClone = static_cast< const QgsPolygon *>( g2 )->clone();
QgsPolygon *polyClone = static_cast< const QgsPolygon *>( mpoly->polygonN( i ) )->clone();
processPolygon( polyClone, f.id(), height, extrusionHeight, context, out );
}
}

View File

@ -273,7 +273,7 @@ int QgsTinInterpolator::insertData( const QgsFeature &f, QgsInterpolator::ValueS
const QgsMultiCurve *mc = qgsgeometry_cast< const QgsMultiCurve * >( g.constGet() );
for ( int i = 0; i < mc->numGeometries(); ++i )
{
curves.emplace_back( qgsgeometry_cast< const QgsCurve * >( mc->geometryN( i ) ) );
curves.emplace_back( mc->curveN( i ) );
}
}
else

View File

@ -126,7 +126,7 @@ QgsFeatureList QgsProjectPointCartesianAlgorithm::processFeature( const QgsFeatu
result->reserve( mp->numGeometries() );
for ( int i = 0; i < mp->numGeometries(); ++i )
{
const QgsPoint *p = static_cast< const QgsPoint * >( mp->geometryN( i ) );
const QgsPoint *p = mp->pointN( i );
result->addGeometry( p->project( distance, bearing ).clone() );
}
f.setGeometry( QgsGeometry( std::move( result ) ) );

View File

@ -173,7 +173,7 @@ QVariantMap QgsTransectAlgorithm::processAlgorithm( const QVariantMap &parameter
const QgsMultiLineString *multiLine = static_cast< const QgsMultiLineString * >( inputGeometry.constGet() );
for ( int id = 0; id < multiLine->numGeometries(); ++id )
{
const QgsLineString *line = static_cast< const QgsLineString * >( multiLine->geometryN( id ) );
const QgsLineString *line = multiLine->lineStringN( id );
QgsAbstractGeometry::vertex_iterator it = line->vertices_begin();
while ( it != line->vertices_end() )
{

View File

@ -176,7 +176,7 @@ QgsFeatureList QgsWedgeBuffersAlgorithm::processFeature( const QgsFeature &featu
result->reserve( mp->numGeometries() );
for ( int i = 0; i < mp->numGeometries(); ++i )
{
const QgsPoint *p = static_cast< const QgsPoint * >( mp->geometryN( i ) );
const QgsPoint *p = mp->pointN( i );
result->addGeometry( QgsGeometry::createWedgeBuffer( *p, azimuth, width, outerRadius, innerRadius ).constGet()->clone() );
}
f.setGeometry( QgsGeometry( std::move( result ) ) );

View File

@ -100,7 +100,7 @@ void QgsMapToolReverseLine::canvasReleaseEvent( QgsMapMouseEvent *e )
if ( f.geometry().isMultipart() )
{
std::unique_ptr<QgsMultiCurve> line_reversed( static_cast<QgsMultiCurve * >( f.geometry().constGet()->clone() ) );
std::unique_ptr<QgsCurve> line_part( static_cast<QgsCurve *>( line_reversed->geometryN( mPressedPartNum )->clone() ) );
std::unique_ptr<QgsCurve> line_part( line_reversed->curveN( mPressedPartNum )->clone() );
std::unique_ptr<QgsCurve> line_part_reversed( line_part->reversed() );
line_reversed->removeGeometry( mPressedPartNum );
line_reversed->insertGeometry( line_part_reversed.release(), mPressedPartNum );

View File

@ -67,7 +67,7 @@ static bool isEndpointAtVertexIndex( const QgsGeometry &geom, int vertexIndex )
{
for ( int i = 0; i < multiCurve->numGeometries(); ++i )
{
QgsCurve *part = qgsgeometry_cast<QgsCurve *>( multiCurve->geometryN( i ) );
const QgsCurve *part = multiCurve->curveN( i );
Q_ASSERT( part );
if ( vertexIndex < part->numPoints() )
return vertexIndex == 0 || vertexIndex == part->numPoints() - 1;
@ -97,7 +97,7 @@ int adjacentVertexIndexToEndpoint( const QgsGeometry &geom, int vertexIndex )
int offset = 0;
for ( int i = 0; i < multiCurve->numGeometries(); ++i )
{
const QgsCurve *part = qgsgeometry_cast<const QgsCurve *>( multiCurve->geometryN( i ) );
const QgsCurve *part = multiCurve->curveN( i );
Q_ASSERT( part );
if ( vertexIndex < part->numPoints() )
return vertexIndex == 0 ? offset + 1 : offset + part->numPoints() - 2;

View File

@ -1642,7 +1642,7 @@ QgsMultiPointXY QgsGeometry::asMultiPoint() const
QgsMultiPointXY multiPoint( nPoints );
for ( int i = 0; i < nPoints; ++i )
{
const QgsPoint *pt = static_cast<const QgsPoint *>( mp->geometryN( i ) );
const QgsPoint *pt = mp->pointN( i );
multiPoint[i].setX( pt->x() );
multiPoint[i].setY( pt->y() );
}
@ -3158,7 +3158,7 @@ QgsGeometry QgsGeometry::smooth( const unsigned int iterations, const double off
resultMultiline->reserve( multiLine->numGeometries() );
for ( int i = 0; i < multiLine->numGeometries(); ++i )
{
resultMultiline->addGeometry( smoothLine( *( qgsgeometry_cast< const QgsLineString * >( multiLine->geometryN( i ) ) ), iterations, offset, minimumDistance, maxAngle ).release() );
resultMultiline->addGeometry( smoothLine( *( multiLine->lineStringN( i ) ), iterations, offset, minimumDistance, maxAngle ).release() );
}
return QgsGeometry( std::move( resultMultiline ) );
}
@ -3177,7 +3177,7 @@ QgsGeometry QgsGeometry::smooth( const unsigned int iterations, const double off
resultMultiPoly->reserve( multiPoly->numGeometries() );
for ( int i = 0; i < multiPoly->numGeometries(); ++i )
{
resultMultiPoly->addGeometry( smoothPolygon( *( qgsgeometry_cast< const QgsPolygon * >( multiPoly->geometryN( i ) ) ), iterations, offset, minimumDistance, maxAngle ).release() );
resultMultiPoly->addGeometry( smoothPolygon( *( multiPoly->polygonN( i ) ), iterations, offset, minimumDistance, maxAngle ).release() );
}
return QgsGeometry( std::move( resultMultiPoly ) );
}

View File

@ -31,6 +31,16 @@ QgsMultiCurve::QgsMultiCurve()
mWkbType = QgsWkbTypes::MultiCurve;
}
QgsCurve *QgsMultiCurve::curveN( int index )
{
return qgsgeometry_cast< QgsCurve * >( geometryN( index ) );
}
const QgsCurve *QgsMultiCurve::curveN( int index ) const
{
return qgsgeometry_cast< const QgsCurve * >( geometryN( index ) );
}
QString QgsMultiCurve::geometryType() const
{
return QStringLiteral( "MultiCurve" );

View File

@ -30,6 +30,51 @@ class CORE_EXPORT QgsMultiCurve: public QgsGeometryCollection
{
public:
QgsMultiCurve();
#ifndef SIP_RUN
/**
* Returns the curve with the specified \a index.
*
* \since QGIS 3.16
*/
QgsCurve *curveN( int index );
#else
/**
* Returns the curve with the specified \a index.
*
* An IndexError will be raised if no curve with the specified index exists.
*
* \since QGIS 3.16
*/
SIP_PYOBJECT curveN( int index ) SIP_TYPEHINT( QgsCurve );
% MethodCode
if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
{
PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
return sipConvertFromType( sipCpp->curveN( a0 ), sipType_QgsCurve, NULL );
}
% End
#endif
#ifndef SIP_RUN
/**
* Returns the curve with the specified \a index.
*
* \note Not available in Python bindings
*
* \since QGIS 3.16
*/
const QgsCurve *curveN( int index ) const;
#endif
QString geometryType() const override;
QgsMultiCurve *clone() const override SIP_FACTORY;
void clear() override;

View File

@ -30,6 +30,16 @@ QgsMultiLineString::QgsMultiLineString()
mWkbType = QgsWkbTypes::MultiLineString;
}
QgsLineString *QgsMultiLineString::lineStringN( int index )
{
return qgsgeometry_cast< QgsLineString * >( geometryN( index ) );
}
const QgsLineString *QgsMultiLineString::lineStringN( int index ) const
{
return qgsgeometry_cast< const QgsLineString * >( geometryN( index ) );
}
QString QgsMultiLineString::geometryType() const
{
return QStringLiteral( "MultiLineString" );

View File

@ -20,6 +20,8 @@ email : marco.hugentobler at sourcepole dot com
#include "qgis_sip.h"
#include "qgsmulticurve.h"
class QgsLineString;
/**
* \ingroup core
* \class QgsMultiLineString
@ -31,6 +33,50 @@ class CORE_EXPORT QgsMultiLineString: public QgsMultiCurve
public:
QgsMultiLineString();
#ifndef SIP_RUN
/**
* Returns the line string with the specified \a index.
*
* \since QGIS 3.16
*/
QgsLineString *lineStringN( int index );
#else
/**
* Returns the line string with the specified \a index.
*
* An IndexError will be raised if no line string with the specified index exists.
*
* \since QGIS 3.16
*/
SIP_PYOBJECT lineStringN( int index ) SIP_TYPEHINT( QgsLineString );
% MethodCode
if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
{
PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
return sipConvertFromType( sipCpp->lineStringN( a0 ), sipType_QgsLineString, NULL );
}
% End
#endif
#ifndef SIP_RUN
/**
* Returns the line string with the specified \a index.
*
* \note Not available in Python bindings
*
* \since QGIS 3.16
*/
const QgsLineString *lineStringN( int index ) const;
#endif
QString geometryType() const override;
QgsMultiLineString *clone() const override SIP_FACTORY;
void clear() override;

View File

@ -28,6 +28,16 @@ QgsMultiPoint::QgsMultiPoint()
mWkbType = QgsWkbTypes::MultiPoint;
}
QgsPoint *QgsMultiPoint::pointN( int index )
{
return qgsgeometry_cast< QgsPoint * >( geometryN( index ) );
}
const QgsPoint *QgsMultiPoint::pointN( int index ) const
{
return qgsgeometry_cast< const QgsPoint * >( geometryN( index ) );
}
QString QgsMultiPoint::geometryType() const
{
return QStringLiteral( "MultiPoint" );

View File

@ -31,6 +31,50 @@ class CORE_EXPORT QgsMultiPoint: public QgsGeometryCollection
public:
QgsMultiPoint();
#ifndef SIP_RUN
/**
* Returns the point with the specified \a index.
*
* \since QGIS 3.16
*/
QgsPoint *pointN( int index );
#else
/**
* Returns the point with the specified \a index.
*
* An IndexError will be raised if no point with the specified index exists.
*
* \since QGIS 3.16
*/
SIP_PYOBJECT pointN( int index ) SIP_TYPEHINT( QgsPoint );
% MethodCode
if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
{
PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
return sipConvertFromType( sipCpp->pointN( a0 ), sipType_QgsPoint, NULL );
}
% End
#endif
#ifndef SIP_RUN
/**
* Returns the point with the specified \a index.
*
* \note Not available in Python bindings
*
* \since QGIS 3.16
*/
const QgsPoint *pointN( int index ) const;
#endif
QString geometryType() const override;
QgsMultiPoint *clone() const override SIP_FACTORY;
QgsMultiPoint *toCurveType() const override SIP_FACTORY;

View File

@ -30,6 +30,16 @@ QgsMultiPolygon::QgsMultiPolygon()
mWkbType = QgsWkbTypes::MultiPolygon;
}
QgsPolygon *QgsMultiPolygon::polygonN( int index )
{
return qgsgeometry_cast< QgsPolygon * >( geometryN( index ) );
}
const QgsPolygon *QgsMultiPolygon::polygonN( int index ) const
{
return qgsgeometry_cast< const QgsPolygon * >( geometryN( index ) );
}
QString QgsMultiPolygon::geometryType() const
{
return QStringLiteral( "MultiPolygon" );

View File

@ -20,6 +20,8 @@ email : marco.hugentobler at sourcepole dot com
#include "qgis_sip.h"
#include "qgsmultisurface.h"
class QgsPolygon;
/**
* \ingroup core
* \class QgsMultiPolygon
@ -30,6 +32,51 @@ class CORE_EXPORT QgsMultiPolygon: public QgsMultiSurface
{
public:
QgsMultiPolygon();
#ifndef SIP_RUN
/**
* Returns the polygon with the specified \a index.
*
* \since QGIS 3.16
*/
QgsPolygon *polygonN( int index );
#else
/**
* Returns the polygon with the specified \a index.
*
* An IndexError will be raised if no polygon with the specified index exists.
*
* \since QGIS 3.16
*/
SIP_PYOBJECT polygonN( int index ) SIP_TYPEHINT( QgsPolygon );
% MethodCode
if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
{
PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
return sipConvertFromType( sipCpp->polygonN( a0 ), sipType_QgsPolygon, NULL );
}
% End
#endif
#ifndef SIP_RUN
/**
* Returns the polygon with the specified \a index.
*
* \note Not available in Python bindings
*
* \since QGIS 3.16
*/
const QgsPolygon *polygonN( int index ) const;
#endif
QString geometryType() const override;
void clear() override;
QgsMultiPolygon *clone() const override SIP_FACTORY;

View File

@ -31,6 +31,16 @@ QgsMultiSurface::QgsMultiSurface()
mWkbType = QgsWkbTypes::MultiSurface;
}
QgsSurface *QgsMultiSurface::surfaceN( int index )
{
return qgsgeometry_cast< QgsSurface * >( geometryN( index ) );
}
const QgsSurface *QgsMultiSurface::surfaceN( int index ) const
{
return qgsgeometry_cast< const QgsSurface * >( geometryN( index ) );
}
QString QgsMultiSurface::geometryType() const
{
return QStringLiteral( "MultiSurface" );

View File

@ -20,6 +20,9 @@ email : marco.hugentobler at sourcepole dot com
#include "qgis_sip.h"
#include "qgsgeometrycollection.h"
class QgsSurface;
/**
* \ingroup core
* \class QgsMultiSurface
@ -30,6 +33,51 @@ class CORE_EXPORT QgsMultiSurface: public QgsGeometryCollection
{
public:
QgsMultiSurface();
#ifndef SIP_RUN
/**
* Returns the surface with the specified \a index.
*
* \since QGIS 3.16
*/
QgsSurface *surfaceN( int index );
#else
/**
* Returns the surface with the specified \a index.
*
* An IndexError will be raised if no surface with the specified index exists.
*
* \since QGIS 3.16
*/
SIP_PYOBJECT surfaceN( int index ) SIP_TYPEHINT( QgsSurface );
% MethodCode
if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
{
PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
return sipConvertFromType( sipCpp->surfaceN( a0 ), sipType_QgsSurface, NULL );
}
% End
#endif
#ifndef SIP_RUN
/**
* Returns the surface with the specified \a index.
*
* \note Not available in Python bindings
*
* \since QGIS 3.16
*/
const QgsSurface *surfaceN( int index ) const;
#endif
QString geometryType() const override;
void clear() override;
QgsMultiSurface *clone() const override SIP_FACTORY;

View File

@ -336,7 +336,7 @@ void QgsVectorTileMVTEncoder::addFeature( vector_tile::Tile_Layer *tileLayer, co
const QgsMultiPoint *mpt = static_cast<const QgsMultiPoint *>( geom );
geomWriter.addMoveTo( mpt->numGeometries() );
for ( int i = 0; i < mpt->numGeometries(); ++i )
geomWriter.addPoint( *static_cast<const QgsPoint *>( mpt->geometryN( i ) ) );
geomWriter.addPoint( *mpt->pointN( i ) );
}
break;
@ -345,7 +345,7 @@ void QgsVectorTileMVTEncoder::addFeature( vector_tile::Tile_Layer *tileLayer, co
const QgsMultiLineString *mls = qgsgeometry_cast<const QgsMultiLineString *>( geom );
for ( int i = 0; i < mls->numGeometries(); ++i )
{
encodeLineString( qgsgeometry_cast<const QgsLineString *>( mls->geometryN( i ) ), true, false, geomWriter );
encodeLineString( mls->lineStringN( i ), true, false, geomWriter );
}
}
break;
@ -355,7 +355,7 @@ void QgsVectorTileMVTEncoder::addFeature( vector_tile::Tile_Layer *tileLayer, co
const QgsMultiPolygon *mp = qgsgeometry_cast<const QgsMultiPolygon *>( geom );
for ( int i = 0; i < mp->numGeometries(); ++i )
{
encodePolygon( static_cast<const QgsPolygon *>( mp->geometryN( i ) ), geomWriter );
encodePolygon( mp->polygonN( i ), geomWriter );
}
}
break;

View File

@ -2614,10 +2614,10 @@ void TestQgsGeometry::circularString()
QgsAbstractGeometry *boundary = boundary1.boundary();
QgsMultiPoint *mpBoundary = dynamic_cast< QgsMultiPoint * >( boundary );
QVERIFY( mpBoundary );
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
QCOMPARE( mpBoundary->pointN( 0 )->x(), 0.0 );
QCOMPARE( mpBoundary->pointN( 0 )->y(), 0.0 );
QCOMPARE( mpBoundary->pointN( 1 )->x(), 1.0 );
QCOMPARE( mpBoundary->pointN( 1 )->y(), 1.0 );
delete boundary;
// closed string = no boundary
@ -2629,11 +2629,11 @@ void TestQgsGeometry::circularString()
boundary = boundary1.boundary();
mpBoundary = dynamic_cast< QgsMultiPoint * >( boundary );
QVERIFY( mpBoundary );
QCOMPARE( mpBoundary->geometryN( 0 )->wkbType(), QgsWkbTypes::PointZ );
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->z(), 10.0 );
QCOMPARE( mpBoundary->geometryN( 1 )->wkbType(), QgsWkbTypes::PointZ );
QCOMPARE( mpBoundary->pointN( 0 )->wkbType(), QgsWkbTypes::PointZ );
QCOMPARE( mpBoundary->pointN( 0 )->x(), 0.0 );
QCOMPARE( mpBoundary->pointN( 0 )->y(), 0.0 );
QCOMPARE( mpBoundary->pointN( 0 )->z(), 10.0 );
QCOMPARE( mpBoundary->pointN( 1 )->wkbType(), QgsWkbTypes::PointZ );
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->z(), 20.0 );

View File

@ -444,12 +444,12 @@ class TestQgsGeometry(unittest.TestCase):
g = QgsGeometryCollection()
self.assertTrue(bool(g))
self.assertEqual(len(g), 0)
g = QgsGeometryCollection()
g.fromWkt('GeometryCollection( Point(1 2), Point(11 12))')
g = QgsMultiPoint()
g.fromWkt('MultiPoint( (1 2), (11 12))')
self.assertTrue(bool(g))
self.assertEqual(len(g), 2)
# pointN
# geometryN
with self.assertRaises(IndexError):
g.geometryN(-1)
with self.assertRaises(IndexError):
@ -457,7 +457,16 @@ class TestQgsGeometry(unittest.TestCase):
self.assertEqual(g.geometryN(0), QgsPoint(1, 2))
self.assertEqual(g.geometryN(1), QgsPoint(11, 12))
# pointN
with self.assertRaises(IndexError):
g.pointN(-1)
with self.assertRaises(IndexError):
g.pointN(2)
self.assertEqual(g.pointN(0), QgsPoint(1, 2))
self.assertEqual(g.pointN(1), QgsPoint(11, 12))
# removeGeometry
g = QgsGeometryCollection()
g.fromWkt('GeometryCollection( Point(1 2), Point(11 12), Point(33 34))')
with self.assertRaises(IndexError):
g.removeGeometry(-1)
@ -508,6 +517,51 @@ class TestQgsGeometry(unittest.TestCase):
g.fromWkt('GeometryCollection( Point(1 2), Point(11 12), LineString(33 34, 44 45))')
self.assertEqual([p.asWkt() for p in g], ['Point (1 2)', 'Point (11 12)', 'LineString (33 34, 44 45)'])
g = QgsGeometryCollection()
g.fromWkt('GeometryCollection( Point(1 2), Point(11 12))')
self.assertTrue(bool(g))
self.assertEqual(len(g), 2)
# lineStringN
g = QgsMultiLineString()
g.fromWkt('MultiLineString( (1 2, 3 4), (11 12, 13 14))')
with self.assertRaises(IndexError):
g.lineStringN(-1)
with self.assertRaises(IndexError):
g.lineStringN(2)
self.assertEqual(g.lineStringN(0).asWkt(), 'LineString (1 2, 3 4)')
self.assertEqual(g.lineStringN(1).asWkt(), 'LineString (11 12, 13 14)')
# curveN
g = QgsMultiCurve()
g.fromWkt('MultiCurve( LineString(1 2, 3 4), LineString(11 12, 13 14))')
with self.assertRaises(IndexError):
g.curveN(-1)
with self.assertRaises(IndexError):
g.curveN(2)
self.assertEqual(g.curveN(0).asWkt(), 'LineString (1 2, 3 4)')
self.assertEqual(g.curveN(1).asWkt(), 'LineString (11 12, 13 14)')
# polygonN
g = QgsMultiPolygon()
g.fromWkt('MultiPolygon( ((1 2, 3 4, 3 6, 1 2)), ((11 12, 13 14, 13 16, 11 12)))')
with self.assertRaises(IndexError):
g.polygonN(-1)
with self.assertRaises(IndexError):
g.polygonN(2)
self.assertEqual(g.polygonN(0).asWkt(), 'Polygon ((1 2, 3 4, 3 6, 1 2))')
self.assertEqual(g.polygonN(1).asWkt(), 'Polygon ((11 12, 13 14, 13 16, 11 12))')
# surfaceN
g = QgsMultiSurface()
g.fromWkt('MultiSurface( Polygon((1 2, 3 4, 3 6, 1 2)), Polygon((11 12, 13 14, 13 16, 11 12)))')
with self.assertRaises(IndexError):
g.surfaceN(-1)
with self.assertRaises(IndexError):
g.surfaceN(2)
self.assertEqual(g.surfaceN(0).asWkt(), 'Polygon ((1 2, 3 4, 3 6, 1 2))')
self.assertEqual(g.surfaceN(1).asWkt(), 'Polygon ((11 12, 13 14, 13 16, 11 12))')
def testCurvePolygonPythonAdditions(self):
"""
Tests Python specific additions to the QgsCurvePolygon API