Skip to content

Commit

Permalink
Calling QgsGeometry.asPoint on a multipoint with a single point part
Browse files Browse the repository at this point in the history
should be allowed
  • Loading branch information
nyalldawson committed Oct 22, 2021
1 parent 61eeb31 commit 7c03c9e
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 22 deletions.
19 changes: 11 additions & 8 deletions python/core/auto_generated/geometry/qgsgeometry.sip.in
Expand Up @@ -1967,25 +1967,28 @@ Any z or m values present in the geometry will be discarded.

This method works only with single-point geometry types.

:raises TypeError: if the geometry is not a single-point type
:raises TypeError: if the geometry is not a single-point type (or a multipoint containing a single point)

:raises ValueError: if the geometry is null
%End
%MethodCode
const QgsWkbTypes::Type type = sipCpp->wkbType();
if ( sipCpp->isNull() )
{
PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a point." ).toUtf8().constData() );
sipIsErr = 1;
}
else if ( QgsWkbTypes::flatType( type ) != QgsWkbTypes::Point )
{
PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
sipIsErr = 1;
}
else
{
sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
const QgsAbstractGeometry *geom = sipCpp->constGet();
if ( QgsWkbTypes::flatType( geom->simplifiedTypeRef()->wkbType() ) != QgsWkbTypes::Point )
{
PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg( QgsWkbTypes::displayString( geom->wkbType() ) ).toUtf8().constData() );
sipIsErr = 1;
}
else
{
sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
}
}
%End

Expand Down
11 changes: 6 additions & 5 deletions src/core/geometry/qgsgeometry.cpp
Expand Up @@ -1661,17 +1661,18 @@ bool QgsGeometry::convertGeometryCollectionToSubclass( QgsWkbTypes::GeometryType

QgsPointXY QgsGeometry::asPoint() const
{
if ( !d->geometry || QgsWkbTypes::flatType( d->geometry->wkbType() ) != QgsWkbTypes::Point )
if ( !d->geometry )
{
return QgsPointXY();
}
QgsPoint *pt = qgsgeometry_cast<QgsPoint *>( d->geometry.get() );
if ( !pt )
if ( QgsPoint *pt = qgsgeometry_cast<QgsPoint *>( d->geometry->simplifiedTypeRef() ) )
{
return QgsPointXY( pt->x(), pt->y() );
}
else
{
return QgsPointXY();
}

return QgsPointXY( pt->x(), pt->y() );
}

QgsPolylineXY QgsGeometry::asPolyline() const
Expand Down
22 changes: 13 additions & 9 deletions src/core/geometry/qgsgeometry.h
Expand Up @@ -1967,7 +1967,8 @@ class CORE_EXPORT QgsGeometry
*
* Any z or m values present in the geometry will be discarded.
*
* \warning If the geometry is not a single-point type, an empty QgsPointXY() will be returned.
* \warning If the geometry is not a single-point type (or a multipoint containing a single point)
* an empty QgsPointXY() will be returned.
*/
QgsPointXY asPoint() const;
#else
Expand All @@ -1979,25 +1980,28 @@ class CORE_EXPORT QgsGeometry
*
* This method works only with single-point geometry types.
*
* \throws TypeError if the geometry is not a single-point type
* \throws TypeError if the geometry is not a single-point type (or a multipoint containing a single point)
* \throws ValueError if the geometry is null
*/
SIP_PYOBJECT asPoint() const SIP_TYPEHINT( QgsPointXY );
% MethodCode
const QgsWkbTypes::Type type = sipCpp->wkbType();
if ( sipCpp->isNull() )
{
PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a point." ).toUtf8().constData() );
sipIsErr = 1;
}
else if ( QgsWkbTypes::flatType( type ) != QgsWkbTypes::Point )
{
PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
sipIsErr = 1;
}
else
{
sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
const QgsAbstractGeometry *geom = sipCpp->constGet();
if ( QgsWkbTypes::flatType( geom->simplifiedTypeRef()->wkbType() ) != QgsWkbTypes::Point )
{
PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg( QgsWkbTypes::displayString( geom->wkbType() ) ).toUtf8().constData() );
sipIsErr = 1;
}
else
{
sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
}
}
% End
#endif
Expand Down
5 changes: 5 additions & 0 deletions tests/src/python/test_qgsgeometry.py
Expand Up @@ -711,6 +711,11 @@ def testPointXY(self):
self.assertEqual(QgsGeometry.fromWkt('PointZ(11 13 14)').asPoint(), QgsPointXY(11, 13))
self.assertEqual(QgsGeometry.fromWkt('PointM(11 13 14)').asPoint(), QgsPointXY(11, 13))
self.assertEqual(QgsGeometry.fromWkt('PointZM(11 13 14 15)').asPoint(), QgsPointXY(11, 13))
# multipoint with single point should work too!
self.assertEqual(QgsGeometry.fromWkt('MultiPoint(11 13)').asPoint(), QgsPointXY(11, 13))
self.assertEqual(QgsGeometry.fromWkt('MultiPointZ(11 13 14)').asPoint(), QgsPointXY(11, 13))
self.assertEqual(QgsGeometry.fromWkt('MultiPointM(11 13 14)').asPoint(), QgsPointXY(11, 13))
self.assertEqual(QgsGeometry.fromWkt('MultiPointZM(11 13 14 15)').asPoint(), QgsPointXY(11, 13))
with self.assertRaises(TypeError):
QgsGeometry.fromWkt('MultiPoint(11 13,14 15)').asPoint()
with self.assertRaises(TypeError):
Expand Down

0 comments on commit 7c03c9e

Please sign in to comment.