Skip to content
Permalink
Browse files

[api] Raises ValueError and TypeError exceptions when QgsGeometry.asP…

…oint()

is called on non-single-point geometries

Previously we would just return QgsPointXY(0,0) when geometries of invalid
type were used, but this is dangerous and we are safer to explicitly
raise errors preventing use of asPoint() with incompatible geometry types.

(cherry picked from commit 0ca9777)
  • Loading branch information
nyalldawson committed Dec 14, 2018
1 parent c8a7e4d commit abbd4d08f1bd506006307141ba75d14e474aae5a
@@ -1413,10 +1413,33 @@ Try to convert the geometry to the requested type
%End


QgsPointXY asPoint() const;

SIP_PYOBJECT asPoint() const /TypeHint="QgsPointXY"/;
%Docstring
Returns contents of the geometry as a point
if wkbType is WKBPoint, otherwise returns [0,0]
Returns the contents of the geometry as a 2-dimensional point.

Any z or m values present in the geometry will be discarded.

This method works only with single-point geometry types. If the geometry
is not a single-point type, a TypeError will be raised. If the geometry
is null, a ValueError will be raised.
%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 );
}
%End

QgsPolylineXY asPolyline() const;
@@ -1413,11 +1413,46 @@ class CORE_EXPORT QgsGeometry

/* Accessor functions for getting geometry data */

#ifndef SIP_RUN

/**
* Returns contents of the geometry as a point
* if wkbType is WKBPoint, otherwise returns [0,0]
* Returns the contents of the geometry as a 2-dimensional point.
*
* Any z or m values present in the geometry will be discarded.
*
* \warning If the geometry is not a single-point type, a QgsPoint( 0, 0 ) will be returned.
*/
QgsPointXY asPoint() const;
#else

/**
* Returns the contents of the geometry as a 2-dimensional point.
*
* Any z or m values present in the geometry will be discarded.
*
* This method works only with single-point geometry types. If the geometry
* is not a single-point type, a TypeError will be raised. If the geometry
* is null, a ValueError will be raised.
*/
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 );
}
% End
#endif

/**
* Returns contents of the geometry as a polyline
@@ -255,6 +255,23 @@ def testFromMultiPolygon(self):
])
self.assertEqual(myMultiPolygon.wkbType(), QgsWkbTypes.MultiPolygon)

def testPointXY(self):
"""
Test the QgsPointXY conversion methods
"""
self.assertEqual(QgsGeometry.fromWkt('Point(11 13)').asPoint(), QgsPointXY(11, 13))
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))
with self.assertRaises(TypeError):
QgsGeometry.fromWkt('MultiPoint(11 13,14 15)').asPoint()
with self.assertRaises(TypeError):
QgsGeometry.fromWkt('LineString(11 13,14 15)').asPoint()
with self.assertRaises(TypeError):
QgsGeometry.fromWkt('Polygon((11 13,14 15, 14 13, 11 13))').asPoint()
with self.assertRaises(ValueError):
QgsGeometry().asPoint()

def testReferenceGeometry(self):
""" Test parsing a whole range of valid reference wkt formats and variants, and checking
expected values such as length, area, centroids, bounding boxes, etc of the resultant geometry.

0 comments on commit abbd4d0

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