fix python constructor for QgsPoint (does not accept QgsPointXY & QPointF anymore)

fixes #32443
This commit is contained in:
Juergen E. Fischer 2019-10-27 13:29:02 +01:00 committed by Jürgen Fischer
parent b9d219e19b
commit 03baeea083
5 changed files with 115 additions and 86 deletions

View File

@ -26,7 +26,7 @@ Point geometry type, with support for z-dimension and m-values.
public:
QgsPoint( SIP_PYOBJECT x = Py_None, SIP_PYOBJECT y = Py_None, SIP_PYOBJECT z = Py_None, SIP_PYOBJECT m = Py_None, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown ) [( double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown )];
QgsPoint( SIP_PYOBJECT x = Py_None, SIP_PYOBJECT y = Py_None, SIP_PYOBJECT z = Py_None, SIP_PYOBJECT m = Py_None, SIP_PYOBJECT wkbType = Py_None ) [( double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown )];
%Docstring
Construct a point with the provided initial coordinate values.
@ -53,59 +53,53 @@ based on the following rules:
pt.wkbType() # QgsWkbTypes.PointZ
%End
%MethodCode
double x;
double y;
double z;
double m;
if ( sipCanConvertToType( a0, sipType_QgsPointXY, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None )
{
int state;
int sipIsErr = 0;
if ( a0 == Py_None )
{
x = std::numeric_limits<double>::quiet_NaN();
QgsPointXY *p = reinterpret_cast<QgsPointXY *>( sipConvertToType( a0, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
if ( sipIsErr )
{
sipReleaseType( p, sipType_QgsPointXY, state );
}
else
{
sipCpp = new sipQgsPoint( QgsPoint( *p ) );
}
}
else
else if ( sipCanConvertToType( a0, sipType_QPointF, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None )
{
x = PyFloat_AsDouble( a0 );
}
int state;
int sipIsErr = 0;
if ( a1 == Py_None )
{
y = std::numeric_limits<double>::quiet_NaN();
QPointF *p = reinterpret_cast<QPointF *>( sipConvertToType( a0, sipType_QPointF, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
if ( sipIsErr )
{
sipReleaseType( p, sipType_QPointF, state );
}
else
{
sipCpp = new sipQgsPoint( QgsPoint( *p ) );
}
}
else
else if (
( a0 == Py_None || PyFloat_AsDouble( a0 ) != -1.0 || !PyErr_Occurred() ) &&
( a1 == Py_None || PyFloat_AsDouble( a1 ) != -1.0 || !PyErr_Occurred() ) &&
( a2 == Py_None || PyFloat_AsDouble( a2 ) != -1.0 || !PyErr_Occurred() ) &&
( a3 == Py_None || PyFloat_AsDouble( a3 ) != -1.0 || !PyErr_Occurred() ) &&
( a4 == Py_None || sipCanConvertToEnum( a4, sipType_QgsWkbTypes_Type ) ) )
{
y = PyFloat_AsDouble( a1 );
double x = a0 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a0 );
double y = a1 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a1 );
double z = a2 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a2 );
double m = a3 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a3 );
QgsWkbTypes::Type wkbType = a4 == Py_None ? QgsWkbTypes::Unknown : static_cast<QgsWkbTypes::Type>( sipConvertToEnum( a4, sipType_QgsWkbTypes_Type ) );
sipCpp = new sipQgsPoint( QgsPoint( x, y, z, m, wkbType ) );
}
if ( a2 == Py_None )
{
z = std::numeric_limits<double>::quiet_NaN();
}
else
{
z = PyFloat_AsDouble( a2 );
}
if ( a3 == Py_None )
{
m = std::numeric_limits<double>::quiet_NaN();
}
else
{
m = PyFloat_AsDouble( a3 );
}
sipCpp = new sipQgsPoint( x, y, z, m, a4 );
%End
explicit QgsPoint( const QgsPointXY &p );
%Docstring
Construct a QgsPoint from a QgsPointXY object
%End
explicit QgsPoint( QPointF p );
%Docstring
Construct a QgsPoint from a QPointF
%End
virtual bool operator==( const QgsAbstractGeometry &other ) const;

View File

@ -32,7 +32,7 @@
/**
* \ingroup core
* \brief Point geometry type, with support for z-dimension and m-values.
* \since QGIS 3.0, (previously QgsPointv2 since QGIS 2.10)
* \since QGIS 3.0, (previously QgsPointV2 since QGIS 2.10)
*/
class CORE_EXPORT QgsPoint: public QgsAbstractGeometry
{
@ -73,62 +73,64 @@ class CORE_EXPORT QgsPoint: public QgsAbstractGeometry
#ifndef SIP_RUN
QgsPoint( double x = std::numeric_limits<double>::quiet_NaN(), double y = std::numeric_limits<double>::quiet_NaN(), double z = std::numeric_limits<double>::quiet_NaN(), double m = std::numeric_limits<double>::quiet_NaN(), QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown );
#else
QgsPoint( SIP_PYOBJECT x = Py_None, SIP_PYOBJECT y = Py_None, SIP_PYOBJECT z = Py_None, SIP_PYOBJECT m = Py_None, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown ) [( double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown )];
QgsPoint( SIP_PYOBJECT x = Py_None, SIP_PYOBJECT y = Py_None, SIP_PYOBJECT z = Py_None, SIP_PYOBJECT m = Py_None, SIP_PYOBJECT wkbType = Py_None ) [( double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown )];
% MethodCode
double x;
double y;
double z;
double m;
if ( sipCanConvertToType( a0, sipType_QgsPointXY, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None )
{
int state;
int sipIsErr = 0;
if ( a0 == Py_None )
{
x = std::numeric_limits<double>::quiet_NaN();
QgsPointXY *p = reinterpret_cast<QgsPointXY *>( sipConvertToType( a0, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
if ( sipIsErr )
{
sipReleaseType( p, sipType_QgsPointXY, state );
}
else
{
sipCpp = new sipQgsPoint( QgsPoint( *p ) );
}
}
else
else if ( sipCanConvertToType( a0, sipType_QPointF, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None )
{
x = PyFloat_AsDouble( a0 );
}
int state;
int sipIsErr = 0;
if ( a1 == Py_None )
{
y = std::numeric_limits<double>::quiet_NaN();
QPointF *p = reinterpret_cast<QPointF *>( sipConvertToType( a0, sipType_QPointF, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
if ( sipIsErr )
{
sipReleaseType( p, sipType_QPointF, state );
}
else
{
sipCpp = new sipQgsPoint( QgsPoint( *p ) );
}
}
else
else if (
( a0 == Py_None || PyFloat_AsDouble( a0 ) != -1.0 || !PyErr_Occurred() ) &&
( a1 == Py_None || PyFloat_AsDouble( a1 ) != -1.0 || !PyErr_Occurred() ) &&
( a2 == Py_None || PyFloat_AsDouble( a2 ) != -1.0 || !PyErr_Occurred() ) &&
( a3 == Py_None || PyFloat_AsDouble( a3 ) != -1.0 || !PyErr_Occurred() ) &&
( a4 == Py_None || sipCanConvertToEnum( a4, sipType_QgsWkbTypes_Type ) ) )
{
y = PyFloat_AsDouble( a1 );
double x = a0 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a0 );
double y = a1 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a1 );
double z = a2 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a2 );
double m = a3 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a3 );
QgsWkbTypes::Type wkbType = a4 == Py_None ? QgsWkbTypes::Unknown : static_cast<QgsWkbTypes::Type>( sipConvertToEnum( a4, sipType_QgsWkbTypes_Type ) );
sipCpp = new sipQgsPoint( QgsPoint( x, y, z, m, wkbType ) );
}
if ( a2 == Py_None )
{
z = std::numeric_limits<double>::quiet_NaN();
}
else
{
z = PyFloat_AsDouble( a2 );
}
if ( a3 == Py_None )
{
m = std::numeric_limits<double>::quiet_NaN();
}
else
{
m = PyFloat_AsDouble( a3 );
}
sipCpp = new sipQgsPoint( x, y, z, m, a4 );
% End
#endif
/**
* Construct a QgsPoint from a QgsPointXY object
*/
explicit QgsPoint( const QgsPointXY &p );
explicit QgsPoint( const QgsPointXY &p ) SIP_SKIP;
/**
* Construct a QgsPoint from a QPointF
*/
explicit QgsPoint( QPointF p );
explicit QgsPoint( QPointF p ) SIP_SKIP;
/**
* Create a new point with the given wkbtype and values.

View File

@ -39,7 +39,6 @@ SET (WFS_MOC_HDRS
qgswfsdescribefeaturetype.h
qgswfstransactionrequest.h
qgswfsshareddata.h
qgswfsutils.h
qgsbackgroundcachedfeatureiterator.h
qgscachedirectorymanager.h
qgsoapiflandingpagerequest.h

View File

@ -106,7 +106,7 @@ class TestQgsEditFormConfig(unittest.TestCase):
app.processEvents()
self.assertEqual(content.status(), QgsFetchedContent.Finished)
# Failing on Travis, seg faut in event loop, no idea why
# Failing on Travis, seg fault in event loop, no idea why
"""
@unittest.expectedFailure
def testFormPy(self):

View File

@ -12,7 +12,8 @@ __copyright__ = 'Copyright 2012, The QGIS Project'
import qgis # NOQA
from qgis.core import QgsPointXY
from qgis.core import QgsPointXY, QgsPoint, QgsWkbTypes
from qgis.PyQt.QtCore import QPointF
from qgis.testing import start_app, unittest
@ -52,6 +53,39 @@ class TestQgsPointXY(unittest.TestCase):
mySet = set([a, b, c, d, e])
assert len(mySet) == 4
def test_issue_32443(self):
p = QgsPoint()
assert p.wkbType() == QgsWkbTypes.Point and p.x() != p.x() and p.y() != p.y()
# ctor from QgsPointXY should be available
p = QgsPoint(QgsPointXY(1, 2))
assert p.wkbType() == QgsWkbTypes.Point and p.x() == 1 and p.y() == 2
# ctor from QPointF should be available
p = QgsPoint(QPointF(1, 2))
assert p.wkbType() == QgsWkbTypes.Point and p.x() == 1 and p.y() == 2
p = QgsPoint(1, 2)
assert p.wkbType() == QgsWkbTypes.Point and p.x() == 1 and p.y() == 2
p = QgsPoint(1, 2, 3)
assert p.wkbType() == QgsWkbTypes.PointZ and p.x() == 1 and p.y() == 2 and p.z() == 3
p = QgsPoint(1, 2, z=3)
assert p.wkbType() == QgsWkbTypes.PointZ and p.x() == 1 and p.y() == 2 and p.z() == 3
p = QgsPoint(1, 2, m=3)
assert p.wkbType() == QgsWkbTypes.PointM and p.x() == 1 and p.y() == 2 and p.m() == 3
p = QgsPoint(1, 2, wkbType=QgsWkbTypes.PointM)
assert p.wkbType() == QgsWkbTypes.PointM and p.x() == 1 and p.y() == 2 and p.m() != p.m()
p = QgsPoint(1, 2, 3, 4)
assert p.wkbType() == QgsWkbTypes.PointZM and p.x() == 1 and p.y() == 2 and p.z() == 3 and p.m() == 4
p = QgsPoint(1, 2, m=4, z=3)
assert p.wkbType() == QgsWkbTypes.PointZM and p.x() == 1 and p.y() == 2 and p.z() == 3 and p.m() == 4
if __name__ == '__main__':
unittest.main()