Skip to content
Permalink
Browse files

[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
  • Loading branch information
nyalldawson committed Aug 17, 2020
1 parent 0b651de commit 5d2495e65a56a79ac8409e0a5ec3ad68d5fae74e
@@ -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/;
@@ -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/;
@@ -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/;
@@ -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();
@@ -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();
@@ -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 );
}
}
@@ -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 );
}
}
@@ -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
@@ -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 ) ) );
@@ -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() )
{
@@ -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 ) ) );
@@ -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 );
@@ -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;
@@ -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 ) );
}
@@ -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" );
@@ -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;
@@ -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" );

0 comments on commit 5d2495e

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