From 1a961e804586aa4b3c45038a2e03b557f07d0298 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 13 Jun 2017 10:26:01 +1000 Subject: [PATCH 1/8] Template based referenced geometry class --- .../core/geometry/qgsreferencedgeometry.sip | 108 ++++++++++++++++++ src/core/CMakeLists.txt | 1 + src/core/geometry/qgsreferencedgeometry.h | 107 +++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 python/core/geometry/qgsreferencedgeometry.sip create mode 100644 src/core/geometry/qgsreferencedgeometry.h diff --git a/python/core/geometry/qgsreferencedgeometry.sip b/python/core/geometry/qgsreferencedgeometry.sip new file mode 100644 index 00000000000..2839cee8af0 --- /dev/null +++ b/python/core/geometry/qgsreferencedgeometry.sip @@ -0,0 +1,108 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/geometry/qgsreferencedgeometry.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + +template +class QgsReferencedGeometryPrimitive +{ +%Docstring + A template based class for storing geometry primitives with an associated reference system. + + QgsReferencedGeometryPrimitive classes represent some form of geometry primitive + (such as rectangles) which have an optional coordinate reference system + associated with them. + +.. versionadded:: 3.0 +.. seealso:: QgsReferencedRectangle +.. note:: + + Not available in Python bindings (although SIP file is present for specific implementations). +%End + +%TypeHeaderCode +#include "qgsreferencedgeometry.h" +%End + public: + + QgsReferencedGeometryPrimitive( T primitive, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); +%Docstring + Constructor for QgsReferencedGeometryPrimitive, for the specified ``primitive`` and ``crs``. +%End + + T primitive() const; +%Docstring + Returns the geometry primitive. + :rtype: T +%End + + T &primitive(); +%Docstring + Returns the geometry primitive. + :rtype: T +%End + + QgsCoordinateReferenceSystem crs() const; +%Docstring + Returns the associated coordinate reference system, or an invalid CRS if + no reference system is set. +.. seealso:: setCrs() + :rtype: QgsCoordinateReferenceSystem +%End + + void setCrs( const QgsCoordinateReferenceSystem &crs ); +%Docstring + Sets the associated ``crs``. Set to an invalid CRS if + no reference system is required. +.. seealso:: crs() +%End + +}; + + +typedef QgsReferencedGeometryPrimitive QgsReferencedGeometryPrimitiveQgsRectangleBase; + +class QgsReferencedRectangle : QgsReferencedGeometryPrimitiveQgsRectangleBase +{ +%Docstring + A QgsRectangle with associated coordinate reference system. +.. versionadded:: 3.0 +%End + +%TypeHeaderCode +#include "qgsreferencedgeometry.h" +typedef QgsReferencedGeometryPrimitive QgsReferencedGeometryPrimitiveQgsRectangleBase; +%End + public: + + QgsReferencedRectangle(); +%Docstring + Construct a default optional expression. + It will be disabled and with an empty expression. +%End + + QgsRectangle &rect(); +%Docstring + :rtype: QgsRectangle +%End + + +}; + + + + + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/geometry/qgsreferencedgeometry.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 8f424071d36..3826966c618 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1059,6 +1059,7 @@ SET(QGIS_CORE_HDRS geometry/qgsmultisurface.h geometry/qgspolygon.h geometry/qgsrectangle.h + geometry/qgsreferencedgeometry.h geometry/qgsregularpolygon.h geometry/qgstriangle.h geometry/qgssurface.h diff --git a/src/core/geometry/qgsreferencedgeometry.h b/src/core/geometry/qgsreferencedgeometry.h new file mode 100644 index 00000000000..b849ff7fb0e --- /dev/null +++ b/src/core/geometry/qgsreferencedgeometry.h @@ -0,0 +1,107 @@ +/*************************************************************************** + qgsreferencedgeometry.h + ---------------------- + begin : June 2017 + copyright : (C) 2017 by Nyall Dawson + email : nyall dot dawson at gmail dot com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSREFERENCEDGEOMETRY_H +#define QGSREFERENCEDGEOMETRY_H + +#include "qgis.h" +#include "qgis_sip.h" +#include "qgis_core.h" +#include "qgscoordinatereferencesystem.h" +#include "qgsrectangle.h" + +/** + * \class QgsReferencedGeometryPrimitive + * \ingroup core + * A template based class for storing geometry primitives with an associated reference system. + * + * QgsReferencedGeometryPrimitive classes represent some form of geometry primitive + * (such as rectangles) which have an optional coordinate reference system + * associated with them. + * + * \since QGIS 3.0 + * \see QgsReferencedRectangle + * \note Not available in Python bindings (although SIP file is present for specific implementations). + */ +template +class CORE_EXPORT QgsReferencedGeometryPrimitive +{ + public: + + /** + * Constructor for QgsReferencedGeometryPrimitive, for the specified \a primitive and \a crs. + */ + QgsReferencedGeometryPrimitive( T primitive, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ) + : mPrimitive( primitive ) + , mCrs( crs ) + {} + + /** + * Returns the geometry primitive. + */ + T primitive() const { return mPrimitive; } + + /** + * Returns the geometry primitive. + */ + T &primitive() { return mPrimitive; } + + /** + * Returns the associated coordinate reference system, or an invalid CRS if + * no reference system is set. + * \see setCrs() + */ + QgsCoordinateReferenceSystem crs() const { return mCrs; } + + /** + * Sets the associated \a crs. Set to an invalid CRS if + * no reference system is required. + * \see crs() + */ + void setCrs( const QgsCoordinateReferenceSystem &crs ) { mCrs = crs; } + + private: + + T mPrimitive; + QgsCoordinateReferenceSystem mCrs; + +}; + +/** + * A QgsRectangle with associated coordinate reference system. + * \since QGIS 3.0 + */ +class CORE_EXPORT QgsReferencedRectangle : public QgsReferencedGeometryPrimitive< QgsRectangle > +{ + public: + + /** + * Construct a default optional expression. + * It will be disabled and with an empty expression. + */ + QgsReferencedRectangle(); + + QgsRectangle &rect() { return primitive(); } + + +}; + +#endif // QGSREFERENCEDGEOMETRY_H + + + + From 8053b96ec07260f82bf49d833813648b4e8f1a84 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 13 Jun 2017 08:26:52 +0200 Subject: [PATCH 2/8] fix constructor and skip method with same python signature --- python/core/geometry/qgsreferencedgeometry.sip | 14 +++----------- src/core/geometry/qgsreferencedgeometry.h | 15 ++++++++------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/python/core/geometry/qgsreferencedgeometry.sip b/python/core/geometry/qgsreferencedgeometry.sip index 2839cee8af0..dd4c2ce91a6 100644 --- a/python/core/geometry/qgsreferencedgeometry.sip +++ b/python/core/geometry/qgsreferencedgeometry.sip @@ -36,11 +36,6 @@ class QgsReferencedGeometryPrimitive Constructor for QgsReferencedGeometryPrimitive, for the specified ``primitive`` and ``crs``. %End - T primitive() const; -%Docstring - Returns the geometry primitive. - :rtype: T -%End T &primitive(); %Docstring @@ -66,6 +61,7 @@ class QgsReferencedGeometryPrimitive }; + typedef QgsReferencedGeometryPrimitive QgsReferencedGeometryPrimitiveQgsRectangleBase; class QgsReferencedRectangle : QgsReferencedGeometryPrimitiveQgsRectangleBase @@ -81,7 +77,7 @@ typedef QgsReferencedGeometryPrimitive QgsReferencedGeometryPrimit %End public: - QgsReferencedRectangle(); + QgsReferencedRectangle( const QgsRectangle &rect ); %Docstring Construct a default optional expression. It will be disabled and with an empty expression. @@ -89,16 +85,12 @@ typedef QgsReferencedGeometryPrimitive QgsReferencedGeometryPrimit QgsRectangle &rect(); %Docstring + Returns the rectangles :rtype: QgsRectangle %End - }; - - - - /************************************************************************ * This file has been generated automatically from * * * diff --git a/src/core/geometry/qgsreferencedgeometry.h b/src/core/geometry/qgsreferencedgeometry.h index b849ff7fb0e..f7eeed57057 100644 --- a/src/core/geometry/qgsreferencedgeometry.h +++ b/src/core/geometry/qgsreferencedgeometry.h @@ -53,7 +53,7 @@ class CORE_EXPORT QgsReferencedGeometryPrimitive /** * Returns the geometry primitive. */ - T primitive() const { return mPrimitive; } + T primitive() const { return mPrimitive; } SIP_SKIP /** * Returns the geometry primitive. @@ -81,7 +81,10 @@ class CORE_EXPORT QgsReferencedGeometryPrimitive }; +//template class QgsReferencedGeometryPrimitive< QgsRectangle > QgsReferencedRectangle; + /** + * \ingroup core * A QgsRectangle with associated coordinate reference system. * \since QGIS 3.0 */ @@ -93,15 +96,13 @@ class CORE_EXPORT QgsReferencedRectangle : public QgsReferencedGeometryPrimitive * Construct a default optional expression. * It will be disabled and with an empty expression. */ - QgsReferencedRectangle(); + QgsReferencedRectangle( const QgsRectangle &rect ) : QgsReferencedGeometryPrimitive( rect ) {} + /** + * Returns the rectangles + */ QgsRectangle &rect() { return primitive(); } - }; #endif // QGSREFERENCEDGEOMETRY_H - - - - From e926f345e82260993126541c230ccc8e68e44dd3 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 31 Aug 2017 11:41:48 +1000 Subject: [PATCH 3/8] Update sip --- python/core/core_auto.sip | 1 + 1 file changed, 1 insertion(+) diff --git a/python/core/core_auto.sip b/python/core/core_auto.sip index 37cfc8ee399..fb4d918a1d6 100644 --- a/python/core/core_auto.sip +++ b/python/core/core_auto.sip @@ -268,6 +268,7 @@ %Include geometry/qgsmultisurface.sip %Include geometry/qgspolygon.sip %Include geometry/qgsrectangle.sip +%Include geometry/qgsreferencedgeometry.sip %Include geometry/qgsregularpolygon.sip %Include geometry/qgstriangle.sip %Include geometry/qgssurface.sip From 1194b5abea74e419d068420666bb47a2568da8e6 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 31 Aug 2017 13:53:00 +1000 Subject: [PATCH 4/8] Use inheritance rather than composition for QgsReferencedGeometries See https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392 for discussion of the rationale --- python/core/geometry/qgsrectangle.sip | 2 + .../core/geometry/qgsreferencedgeometry.sip | 54 +++++++++---------- src/core/CMakeLists.txt | 1 + src/core/geometry/qgsrectangle.h | 5 ++ src/core/geometry/qgsreferencedgeometry.cpp | 32 +++++++++++ src/core/geometry/qgsreferencedgeometry.h | 54 +++++++++---------- src/core/qgspointxy.h | 6 ++- 7 files changed, 94 insertions(+), 60 deletions(-) create mode 100644 src/core/geometry/qgsreferencedgeometry.cpp diff --git a/python/core/geometry/qgsrectangle.sip b/python/core/geometry/qgsrectangle.sip index 94c133c54b9..936a0fb67f1 100644 --- a/python/core/geometry/qgsrectangle.sip +++ b/python/core/geometry/qgsrectangle.sip @@ -42,6 +42,8 @@ Construct a rectangle from a QRectF. The rectangle is normalized after construct Copy constructor %End + ~QgsRectangle(); + void set( const QgsPointXY &p1, const QgsPointXY &p2 ); %Docstring Sets the rectangle from two QgsPoints. The rectangle is diff --git a/python/core/geometry/qgsreferencedgeometry.sip b/python/core/geometry/qgsreferencedgeometry.sip index dd4c2ce91a6..68349918a40 100644 --- a/python/core/geometry/qgsreferencedgeometry.sip +++ b/python/core/geometry/qgsreferencedgeometry.sip @@ -9,21 +9,17 @@ -template -class QgsReferencedGeometryPrimitive +class QgsReferencedGeometryBase { %Docstring - A template based class for storing geometry primitives with an associated reference system. + A base class for geometry primitives which are stored with an associated reference system. - QgsReferencedGeometryPrimitive classes represent some form of geometry primitive + QgsReferencedGeometryBase classes represent some form of geometry primitive (such as rectangles) which have an optional coordinate reference system associated with them. .. versionadded:: 3.0 .. seealso:: QgsReferencedRectangle -.. note:: - - Not available in Python bindings (although SIP file is present for specific implementations). %End %TypeHeaderCode @@ -31,16 +27,9 @@ class QgsReferencedGeometryPrimitive %End public: - QgsReferencedGeometryPrimitive( T primitive, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); + QgsReferencedGeometryBase( const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); %Docstring - Constructor for QgsReferencedGeometryPrimitive, for the specified ``primitive`` and ``crs``. -%End - - - T &primitive(); -%Docstring - Returns the geometry primitive. - :rtype: T + Constructor for QgsReferencedGeometryBase, with the specified ``crs``. %End QgsCoordinateReferenceSystem crs() const; @@ -60,11 +49,7 @@ class QgsReferencedGeometryPrimitive }; - - -typedef QgsReferencedGeometryPrimitive QgsReferencedGeometryPrimitiveQgsRectangleBase; - -class QgsReferencedRectangle : QgsReferencedGeometryPrimitiveQgsRectangleBase +class QgsReferencedRectangle : QgsRectangle, QgsReferencedGeometryBase { %Docstring A QgsRectangle with associated coordinate reference system. @@ -73,20 +58,33 @@ class QgsReferencedRectangle : QgsReferencedGeometryPrimitiveQgsRectangleBase %TypeHeaderCode #include "qgsreferencedgeometry.h" -typedef QgsReferencedGeometryPrimitive QgsReferencedGeometryPrimitiveQgsRectangleBase; %End public: - QgsReferencedRectangle( const QgsRectangle &rect ); + QgsReferencedRectangle( const QgsRectangle &rectangle, const QgsCoordinateReferenceSystem &crs ); %Docstring - Construct a default optional expression. - It will be disabled and with an empty expression. + Constructor for QgsReferencedRectangle, with the specified initial ``rectangle`` + and ``crs``. %End - QgsRectangle &rect(); +}; + +class QgsReferencedPointXY : QgsPointXY, QgsReferencedGeometryBase +{ %Docstring - Returns the rectangles - :rtype: QgsRectangle + A QgsPointXY with associated coordinate reference system. +.. versionadded:: 3.0 +%End + +%TypeHeaderCode +#include "qgsreferencedgeometry.h" +%End + public: + + QgsReferencedPointXY( const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs ); +%Docstring + Constructor for QgsReferencedPointXY, with the specified initial ``point`` + and ``crs``. %End }; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 3826966c618..0f1b48f7b06 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -447,6 +447,7 @@ SET(QGIS_CORE_SRCS geometry/qgspoint.cpp geometry/qgspolygon.cpp geometry/qgsrectangle.cpp + geometry/qgsreferencedgeometry.cpp geometry/qgsregularpolygon.cpp geometry/qgstriangle.cpp geometry/qgswkbptr.cpp diff --git a/src/core/geometry/qgsrectangle.h b/src/core/geometry/qgsrectangle.h index 5a1c15a0fd6..c8da1353019 100644 --- a/src/core/geometry/qgsrectangle.h +++ b/src/core/geometry/qgsrectangle.h @@ -47,6 +47,11 @@ class CORE_EXPORT QgsRectangle //! Copy constructor QgsRectangle( const QgsRectangle &other ); + // IMPORTANT - while QgsRectangle is inherited by QgsReferencedRectangle, we do NOT want a virtual destructor here + // because this class MUST be lightweight and we don't want the cost of the vtable here. + // see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392 + ~QgsRectangle() = default; + /** * Sets the rectangle from two QgsPoints. The rectangle is * normalised after construction. diff --git a/src/core/geometry/qgsreferencedgeometry.cpp b/src/core/geometry/qgsreferencedgeometry.cpp new file mode 100644 index 00000000000..5e0ed48476e --- /dev/null +++ b/src/core/geometry/qgsreferencedgeometry.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** + qgsreferencedgeometry.cpp + ------------------------ + begin : June 2017 + copyright : (C) 2017 by Nyall Dawson + email : nyall dot dawson at gmail dot com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsreferencedgeometry.h" + +QgsReferencedGeometryBase::QgsReferencedGeometryBase( const QgsCoordinateReferenceSystem &crs ) + : mCrs( crs ) +{} + +QgsReferencedRectangle::QgsReferencedRectangle( const QgsRectangle &rect, const QgsCoordinateReferenceSystem &crs ) + : QgsRectangle( rect ) + , QgsReferencedGeometryBase( crs ) +{} + +QgsReferencedPointXY::QgsReferencedPointXY( const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs ) + : QgsPointXY( point ) + , QgsReferencedGeometryBase( crs ) +{} diff --git a/src/core/geometry/qgsreferencedgeometry.h b/src/core/geometry/qgsreferencedgeometry.h index f7eeed57057..6d5c801b6b2 100644 --- a/src/core/geometry/qgsreferencedgeometry.h +++ b/src/core/geometry/qgsreferencedgeometry.h @@ -25,40 +25,25 @@ #include "qgsrectangle.h" /** - * \class QgsReferencedGeometryPrimitive + * \class QgsReferencedGeometryBase * \ingroup core - * A template based class for storing geometry primitives with an associated reference system. + * A base class for geometry primitives which are stored with an associated reference system. * - * QgsReferencedGeometryPrimitive classes represent some form of geometry primitive + * QgsReferencedGeometryBase classes represent some form of geometry primitive * (such as rectangles) which have an optional coordinate reference system * associated with them. * * \since QGIS 3.0 * \see QgsReferencedRectangle - * \note Not available in Python bindings (although SIP file is present for specific implementations). */ -template -class CORE_EXPORT QgsReferencedGeometryPrimitive +class CORE_EXPORT QgsReferencedGeometryBase { public: /** - * Constructor for QgsReferencedGeometryPrimitive, for the specified \a primitive and \a crs. + * Constructor for QgsReferencedGeometryBase, with the specified \a crs. */ - QgsReferencedGeometryPrimitive( T primitive, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ) - : mPrimitive( primitive ) - , mCrs( crs ) - {} - - /** - * Returns the geometry primitive. - */ - T primitive() const { return mPrimitive; } SIP_SKIP - - /** - * Returns the geometry primitive. - */ - T &primitive() { return mPrimitive; } + QgsReferencedGeometryBase( const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); /** * Returns the associated coordinate reference system, or an invalid CRS if @@ -76,32 +61,41 @@ class CORE_EXPORT QgsReferencedGeometryPrimitive private: - T mPrimitive; QgsCoordinateReferenceSystem mCrs; }; -//template class QgsReferencedGeometryPrimitive< QgsRectangle > QgsReferencedRectangle; - /** * \ingroup core * A QgsRectangle with associated coordinate reference system. * \since QGIS 3.0 */ -class CORE_EXPORT QgsReferencedRectangle : public QgsReferencedGeometryPrimitive< QgsRectangle > +class CORE_EXPORT QgsReferencedRectangle : public QgsRectangle, public QgsReferencedGeometryBase { public: /** - * Construct a default optional expression. - * It will be disabled and with an empty expression. + * Constructor for QgsReferencedRectangle, with the specified initial \a rectangle + * and \a crs. */ - QgsReferencedRectangle( const QgsRectangle &rect ) : QgsReferencedGeometryPrimitive( rect ) {} + QgsReferencedRectangle( const QgsRectangle &rectangle, const QgsCoordinateReferenceSystem &crs ); + +}; + +/** + * \ingroup core + * A QgsPointXY with associated coordinate reference system. + * \since QGIS 3.0 + */ +class CORE_EXPORT QgsReferencedPointXY : public QgsPointXY, public QgsReferencedGeometryBase +{ + public: /** - * Returns the rectangles + * Constructor for QgsReferencedPointXY, with the specified initial \a point + * and \a crs. */ - QgsRectangle &rect() { return primitive(); } + QgsReferencedPointXY( const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs ); }; diff --git a/src/core/qgspointxy.h b/src/core/qgspointxy.h index c3651d5d10c..deb94a796e9 100644 --- a/src/core/qgspointxy.h +++ b/src/core/qgspointxy.h @@ -91,8 +91,10 @@ class CORE_EXPORT QgsPointXY */ QgsPointXY( const QgsPoint &point ); - ~QgsPointXY() - {} + // IMPORTANT - while QgsPointXY is inherited by QgsReferencedPointXY, we do NOT want a virtual destructor here + // because this class MUST be lightweight and we don't want the cost of the vtable here. + // see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392 + ~QgsPointXY() = default; /** Sets the x value of the point * \param x x coordinate From 6ab7ebadec558f10edb23acfe90c90080a306ad1 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 31 Aug 2017 15:19:28 +1000 Subject: [PATCH 5/8] Metatype Qgs(Referenced)Rectangle/PointXY --- python/core/geometry/qgsrectangle.sip | 1 + python/core/geometry/qgsreferencedgeometry.sip | 6 ++++++ src/core/geometry/qgsrectangle.h | 2 ++ src/core/geometry/qgsreferencedgeometry.h | 8 ++++++++ src/core/qgspointxy.h | 1 + 5 files changed, 18 insertions(+) diff --git a/python/core/geometry/qgsrectangle.sip b/python/core/geometry/qgsrectangle.sip index 936a0fb67f1..5753fd1cd24 100644 --- a/python/core/geometry/qgsrectangle.sip +++ b/python/core/geometry/qgsrectangle.sip @@ -320,6 +320,7 @@ Copy constructor }; + /************************************************************************ * This file has been generated automatically from * * * diff --git a/python/core/geometry/qgsreferencedgeometry.sip b/python/core/geometry/qgsreferencedgeometry.sip index 68349918a40..17180a8ba6c 100644 --- a/python/core/geometry/qgsreferencedgeometry.sip +++ b/python/core/geometry/qgsreferencedgeometry.sip @@ -67,8 +67,11 @@ class QgsReferencedRectangle : QgsRectangle, QgsReferencedGeometryBase and ``crs``. %End + QgsReferencedRectangle(); + }; + class QgsReferencedPointXY : QgsPointXY, QgsReferencedGeometryBase { %Docstring @@ -87,8 +90,11 @@ class QgsReferencedPointXY : QgsPointXY, QgsReferencedGeometryBase and ``crs``. %End + QgsReferencedPointXY(); + }; + /************************************************************************ * This file has been generated automatically from * * * diff --git a/src/core/geometry/qgsrectangle.h b/src/core/geometry/qgsrectangle.h index c8da1353019..334ffcc0ee4 100644 --- a/src/core/geometry/qgsrectangle.h +++ b/src/core/geometry/qgsrectangle.h @@ -315,6 +315,8 @@ class CORE_EXPORT QgsRectangle }; +Q_DECLARE_METATYPE( QgsRectangle ) + #ifndef SIP_RUN /** diff --git a/src/core/geometry/qgsreferencedgeometry.h b/src/core/geometry/qgsreferencedgeometry.h index 6d5c801b6b2..d6d9274f87c 100644 --- a/src/core/geometry/qgsreferencedgeometry.h +++ b/src/core/geometry/qgsreferencedgeometry.h @@ -80,8 +80,12 @@ class CORE_EXPORT QgsReferencedRectangle : public QgsRectangle, public QgsRefere */ QgsReferencedRectangle( const QgsRectangle &rectangle, const QgsCoordinateReferenceSystem &crs ); + QgsReferencedRectangle(); + }; +Q_DECLARE_METATYPE( QgsReferencedRectangle ) + /** * \ingroup core * A QgsPointXY with associated coordinate reference system. @@ -97,6 +101,10 @@ class CORE_EXPORT QgsReferencedPointXY : public QgsPointXY, public QgsReferenced */ QgsReferencedPointXY( const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs ); + QgsReferencedPointXY(); + }; +Q_DECLARE_METATYPE( QgsReferencedPointXY ) + #endif // QGSREFERENCEDGEOMETRY_H diff --git a/src/core/qgspointxy.h b/src/core/qgspointxy.h index deb94a796e9..d9b919f84cd 100644 --- a/src/core/qgspointxy.h +++ b/src/core/qgspointxy.h @@ -311,6 +311,7 @@ class CORE_EXPORT QgsPointXY }; // class QgsPoint +Q_DECLARE_METATYPE( QgsPointXY ) inline bool operator==( const QgsPointXY &p1, const QgsPointXY &p2 ) SIP_SKIP { From 1e1ed8a4621115229218a6810fe36607bdcd4c85 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 31 Aug 2017 16:33:57 +1000 Subject: [PATCH 6/8] Add unit tests for referenced geometries --- src/core/geometry/qgsreferencedgeometry.h | 4 +- tests/src/python/CMakeLists.txt | 1 + .../src/python/test_qgsreferencedgeometry.py | 87 +++++++++++++++++++ 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 tests/src/python/test_qgsreferencedgeometry.py diff --git a/src/core/geometry/qgsreferencedgeometry.h b/src/core/geometry/qgsreferencedgeometry.h index d6d9274f87c..8ae882a4ecc 100644 --- a/src/core/geometry/qgsreferencedgeometry.h +++ b/src/core/geometry/qgsreferencedgeometry.h @@ -80,7 +80,7 @@ class CORE_EXPORT QgsReferencedRectangle : public QgsRectangle, public QgsRefere */ QgsReferencedRectangle( const QgsRectangle &rectangle, const QgsCoordinateReferenceSystem &crs ); - QgsReferencedRectangle(); + QgsReferencedRectangle() = default; }; @@ -101,7 +101,7 @@ class CORE_EXPORT QgsReferencedPointXY : public QgsPointXY, public QgsReferenced */ QgsReferencedPointXY( const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs ); - QgsReferencedPointXY(); + QgsReferencedPointXY() = default; }; diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt index bbcee6788db..b91da6b66f6 100755 --- a/tests/src/python/CMakeLists.txt +++ b/tests/src/python/CMakeLists.txt @@ -124,6 +124,7 @@ ADD_PYTHON_TEST(PyQgsRasterLayer test_qgsrasterlayer.py) ADD_PYTHON_TEST(PyQgsRasterColorRampShader test_qgsrastercolorrampshader.py) ADD_PYTHON_TEST(PyQgsRatioLockButton test_qgsratiolockbutton.py) ADD_PYTHON_TEST(PyQgsRectangle test_qgsrectangle.py) +ADD_PYTHON_TEST(PyQgsReferencedGeometry test_qgsreferencedgeometry.py) ADD_PYTHON_TEST(PyQgsRelation test_qgsrelation.py) ADD_PYTHON_TEST(PyQgsRelationManager test_qgsrelationmanager.py) ADD_PYTHON_TEST(PyQgsRenderContext test_qgsrendercontext.py) diff --git a/tests/src/python/test_qgsreferencedgeometry.py b/tests/src/python/test_qgsreferencedgeometry.py new file mode 100644 index 00000000000..164b6003587 --- /dev/null +++ b/tests/src/python/test_qgsreferencedgeometry.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +"""QGIS Unit tests for QgsReferencedGeometry. + +.. note:: This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. +""" +__author__ = 'Nyall Dawson' +__date__ = '31/08/2017' +__copyright__ = 'Copyright 2017, The QGIS Project' +# This will get replaced with a git SHA1 when you do a git archive +__revision__ = '$Format:%H$' + +import qgis # NOQA + +from qgis.core import (QgsRectangle, + QgsPointXY, + QgsReferencedRectangle, + QgsReferencedPointXY, + QgsCoordinateReferenceSystem) +from qgis.PyQt.QtCore import QVariant +from qgis.testing import start_app, unittest +from utilities import compareWkt + +start_app() + + +class TestQgsReferencedGeometry(unittest.TestCase): + + def testRectangle(self): + rect = QgsReferencedRectangle(QgsRectangle(0.0, 1.0, 20.0, 10.0), QgsCoordinateReferenceSystem('epsg:3111')) + self.assertEqual(rect.xMinimum(), 0.0) + self.assertEqual(rect.yMinimum(), 1.0) + self.assertEqual(rect.xMaximum(), 20.0) + self.assertEqual(rect.yMaximum(), 10.0) + self.assertEqual(rect.crs().authid(), 'EPSG:3111') + + rect.setCrs(QgsCoordinateReferenceSystem('epsg:28356')) + self.assertEqual(rect.crs().authid(), 'EPSG:28356') + + # in variant + v = QVariant(QgsReferencedRectangle(QgsRectangle(1.0, 2.0, 3.0, 4.0), QgsCoordinateReferenceSystem('epsg:3111'))) + self.assertEqual(v.value().xMinimum(), 1.0) + self.assertEqual(v.value().yMinimum(), 2.0) + self.assertEqual(v.value().xMaximum(), 3.0) + self.assertEqual(v.value().yMaximum(), 4.0) + self.assertEqual(v.value().crs().authid(), 'EPSG:3111') + + # to rectangle + r = QgsRectangle(rect) + self.assertEqual(r.xMinimum(), 0.0) + self.assertEqual(r.yMinimum(), 1.0) + self.assertEqual(r.xMaximum(), 20.0) + self.assertEqual(r.yMaximum(), 10.0) + + # test that QgsReferencedRectangle IS a QgsRectangle + r2 = QgsRectangle(5, 6, 30, 40) + r2.combineExtentWith(rect) + self.assertEqual(r2.xMinimum(), 0.0) + self.assertEqual(r2.yMinimum(), 1.0) + self.assertEqual(r2.xMaximum(), 30.0) + self.assertEqual(r2.yMaximum(), 40.0) + + def testPoint(self): + point = QgsReferencedPointXY(QgsPointXY(1.0, 2.0), QgsCoordinateReferenceSystem('epsg:3111')) + self.assertEqual(point.x(), 1.0) + self.assertEqual(point.y(), 2.0) + self.assertEqual(point.crs().authid(), 'EPSG:3111') + + point.setCrs(QgsCoordinateReferenceSystem('epsg:28356')) + self.assertEqual(point.crs().authid(), 'EPSG:28356') + + # in variant + v = QVariant(QgsReferencedPointXY(QgsPointXY(3.0, 4.0), QgsCoordinateReferenceSystem('epsg:3111'))) + self.assertEqual(v.value().x(), 3.0) + self.assertEqual(v.value().y(), 4.0) + self.assertEqual(v.value().crs().authid(), 'EPSG:3111') + + # to QgsPointXY + p = QgsPointXY(point) + self.assertEqual(p.x(), 1.0) + self.assertEqual(p.y(), 2.0) + + +if __name__ == '__main__': + unittest.main() From f12bb74b584b7a36a0029a752e4889e6985945f5 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 31 Aug 2017 19:55:41 +1000 Subject: [PATCH 7/8] Add missing docs --- python/core/geometry/qgsreferencedgeometry.sip | 6 ++++++ src/core/geometry/qgsreferencedgeometry.h | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/python/core/geometry/qgsreferencedgeometry.sip b/python/core/geometry/qgsreferencedgeometry.sip index 17180a8ba6c..e1505105689 100644 --- a/python/core/geometry/qgsreferencedgeometry.sip +++ b/python/core/geometry/qgsreferencedgeometry.sip @@ -68,6 +68,9 @@ class QgsReferencedRectangle : QgsRectangle, QgsReferencedGeometryBase %End QgsReferencedRectangle(); +%Docstring + Constructor for QgsReferencedRectangle. +%End }; @@ -91,6 +94,9 @@ class QgsReferencedPointXY : QgsPointXY, QgsReferencedGeometryBase %End QgsReferencedPointXY(); +%Docstring + Constructor for QgsReferencedPointXY. +%End }; diff --git a/src/core/geometry/qgsreferencedgeometry.h b/src/core/geometry/qgsreferencedgeometry.h index 8ae882a4ecc..2fce33771ba 100644 --- a/src/core/geometry/qgsreferencedgeometry.h +++ b/src/core/geometry/qgsreferencedgeometry.h @@ -80,6 +80,9 @@ class CORE_EXPORT QgsReferencedRectangle : public QgsRectangle, public QgsRefere */ QgsReferencedRectangle( const QgsRectangle &rectangle, const QgsCoordinateReferenceSystem &crs ); + /** + * Constructor for QgsReferencedRectangle. + */ QgsReferencedRectangle() = default; }; @@ -101,6 +104,9 @@ class CORE_EXPORT QgsReferencedPointXY : public QgsPointXY, public QgsReferenced */ QgsReferencedPointXY( const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs ); + /** + * Constructor for QgsReferencedPointXY. + */ QgsReferencedPointXY() = default; }; From f1313af9142069d63fd3f74a6daca6179e560dc2 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 31 Aug 2017 20:54:43 +1000 Subject: [PATCH 8/8] Add some more unit tests --- python/core/geometry/qgsrectangle.sip | 5 +++ .../core/geometry/qgsreferencedgeometry.sip | 10 +++++ python/core/qgspointxy.sip | 5 +++ src/core/geometry/qgsrectangle.h | 6 +++ src/core/geometry/qgsreferencedgeometry.h | 12 +++++ src/core/qgspointxy.h | 6 +++ tests/src/core/testqgspoint.cpp | 40 +++++++++++++++++ tests/src/core/testqgsrectangle.cpp | 44 +++++++++++++++++++ 8 files changed, 128 insertions(+) diff --git a/python/core/geometry/qgsrectangle.sip b/python/core/geometry/qgsrectangle.sip index 5753fd1cd24..90ad8022e61 100644 --- a/python/core/geometry/qgsrectangle.sip +++ b/python/core/geometry/qgsrectangle.sip @@ -317,6 +317,11 @@ Copy constructor :rtype: QgsBox3d %End + operator QVariant() const; +%Docstring +Allows direct construction of QVariants from rectangles. +%End + }; diff --git a/python/core/geometry/qgsreferencedgeometry.sip b/python/core/geometry/qgsreferencedgeometry.sip index e1505105689..9bc96028ba9 100644 --- a/python/core/geometry/qgsreferencedgeometry.sip +++ b/python/core/geometry/qgsreferencedgeometry.sip @@ -72,6 +72,11 @@ class QgsReferencedRectangle : QgsRectangle, QgsReferencedGeometryBase Constructor for QgsReferencedRectangle. %End + operator QVariant() const; +%Docstring +Allows direct construction of QVariants from rectangle. +%End + }; @@ -98,6 +103,11 @@ class QgsReferencedPointXY : QgsPointXY, QgsReferencedGeometryBase Constructor for QgsReferencedPointXY. %End + operator QVariant() const; +%Docstring +Allows direct construction of QVariants from point. +%End + }; diff --git a/python/core/qgspointxy.sip b/python/core/qgspointxy.sip index 4d14b3b3fd4..f2fe6c629c3 100644 --- a/python/core/qgspointxy.sip +++ b/python/core/qgspointxy.sip @@ -285,6 +285,11 @@ Divides the coordinates in this point by a scalar quantity in place :rtype: QgsPointXY %End + operator QVariant() const; +%Docstring +Allows direct construction of QVariants from points. +%End + SIP_PYOBJECT __repr__(); %MethodCode QString str = "(" + QString::number( sipCpp->x() ) + "," + QString::number( sipCpp->y() ) + ")"; diff --git a/src/core/geometry/qgsrectangle.h b/src/core/geometry/qgsrectangle.h index 334ffcc0ee4..57a41937469 100644 --- a/src/core/geometry/qgsrectangle.h +++ b/src/core/geometry/qgsrectangle.h @@ -306,6 +306,12 @@ class CORE_EXPORT QgsRectangle */ QgsBox3d toBox3d( double zMin, double zMax ) const; + //! Allows direct construction of QVariants from rectangles. + operator QVariant() const + { + return QVariant::fromValue( *this ); + } + private: double mXmin; diff --git a/src/core/geometry/qgsreferencedgeometry.h b/src/core/geometry/qgsreferencedgeometry.h index 2fce33771ba..71fbe73c5b0 100644 --- a/src/core/geometry/qgsreferencedgeometry.h +++ b/src/core/geometry/qgsreferencedgeometry.h @@ -85,6 +85,12 @@ class CORE_EXPORT QgsReferencedRectangle : public QgsRectangle, public QgsRefere */ QgsReferencedRectangle() = default; + //! Allows direct construction of QVariants from rectangle. + operator QVariant() const + { + return QVariant::fromValue( *this ); + } + }; Q_DECLARE_METATYPE( QgsReferencedRectangle ) @@ -109,6 +115,12 @@ class CORE_EXPORT QgsReferencedPointXY : public QgsPointXY, public QgsReferenced */ QgsReferencedPointXY() = default; + //! Allows direct construction of QVariants from point. + operator QVariant() const + { + return QVariant::fromValue( *this ); + } + }; Q_DECLARE_METATYPE( QgsReferencedPointXY ) diff --git a/src/core/qgspointxy.h b/src/core/qgspointxy.h index d9b919f84cd..2c4903dcbe2 100644 --- a/src/core/qgspointxy.h +++ b/src/core/qgspointxy.h @@ -262,6 +262,12 @@ class CORE_EXPORT QgsPointXY //! Divides the coordinates in this point by a scalar quantity in place QgsPointXY &operator/=( double scalar ) { mX /= scalar; mY /= scalar; return *this; } + //! Allows direct construction of QVariants from points. + operator QVariant() const + { + return QVariant::fromValue( *this ); + } + #ifdef SIP_RUN SIP_PYOBJECT __repr__(); % MethodCode diff --git a/tests/src/core/testqgspoint.cpp b/tests/src/core/testqgspoint.cpp index d3561451af7..726cfea7922 100644 --- a/tests/src/core/testqgspoint.cpp +++ b/tests/src/core/testqgspoint.cpp @@ -25,6 +25,7 @@ #include //header for class being tested #include +#include "qgsreferencedgeometry.h" class TestQgsPointXY: public QObject { @@ -51,6 +52,8 @@ class TestQgsPointXY: public QObject void compare(); void project(); void vector(); //tests for QgsVector + void asVariant(); + void referenced(); private: QgsPointXY mPoint1; @@ -760,5 +763,42 @@ void TestQgsPointXY::vector() QCOMPARE( v1.y(), 3.0 ); } +void TestQgsPointXY::asVariant() +{ + QgsPointXY p1 = QgsPointXY( 10.0, 20.0 ); + + //convert to and from a QVariant + QVariant var = QVariant::fromValue( p1 ); + QVERIFY( var.isValid() ); + QVERIFY( var.canConvert< QgsPointXY >() ); + QVERIFY( !var.canConvert< QgsReferencedPointXY >() ); + + QgsPointXY p2 = qvariant_cast( var ); + QCOMPARE( p2.x(), p1.x() ); + QCOMPARE( p2.y(), p1.y() ); +} + +void TestQgsPointXY::referenced() +{ + QgsReferencedPointXY p1 = QgsReferencedPointXY( QgsPointXY( 10.0, 20.0 ), QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3111" ) ) ); + QCOMPARE( p1.crs().authid(), QStringLiteral( "EPSG:3111" ) ); + p1.setCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:28356" ) ) ); + QCOMPARE( p1.crs().authid(), QStringLiteral( "EPSG:28356" ) ); + + //convert to and from a QVariant + QVariant var = QVariant::fromValue( p1 ); + QVERIFY( var.isValid() ); + + // not great - we'd ideally like this to pass, but it doesn't: + // QVERIFY( !var.canConvert< QgsPointXY >() ); + + QVERIFY( var.canConvert< QgsReferencedPointXY >() ); + + QgsReferencedPointXY p2 = qvariant_cast( var ); + QCOMPARE( p2.x(), p1.x() ); + QCOMPARE( p2.y(), p1.y() ); + QCOMPARE( p2.crs().authid(), QStringLiteral( "EPSG:28356" ) ); +} + QGSTEST_MAIN( TestQgsPointXY ) #include "testqgspoint.moc" diff --git a/tests/src/core/testqgsrectangle.cpp b/tests/src/core/testqgsrectangle.cpp index 6ac7a56c912..bc1bd62a4f5 100644 --- a/tests/src/core/testqgsrectangle.cpp +++ b/tests/src/core/testqgsrectangle.cpp @@ -19,6 +19,7 @@ #include #include #include "qgslogger.h" +#include "qgsreferencedgeometry.h" class TestQgsRectangle: public QObject { @@ -27,6 +28,8 @@ class TestQgsRectangle: public QObject void manipulate(); void regression6194(); void operators(); + void asVariant(); + void referenced(); }; void TestQgsRectangle::manipulate() @@ -111,5 +114,46 @@ void TestQgsRectangle::operators() QCOMPARE( rect2.width(), rect1.width() ); } +void TestQgsRectangle::asVariant() +{ + QgsRectangle rect1 = QgsRectangle( 10.0, 20.0, 110.0, 220.0 ); + + //convert to and from a QVariant + QVariant var = QVariant::fromValue( rect1 ); + QVERIFY( var.isValid() ); + QVERIFY( var.canConvert< QgsRectangle >() ); + QVERIFY( !var.canConvert< QgsReferencedRectangle >() ); + + QgsRectangle rect2 = qvariant_cast( var ); + QCOMPARE( rect2.xMinimum(), rect1.xMinimum() ); + QCOMPARE( rect2.yMinimum(), rect1.yMinimum() ); + QCOMPARE( rect2.height(), rect1.height() ); + QCOMPARE( rect2.width(), rect1.width() ); +} + +void TestQgsRectangle::referenced() +{ + QgsReferencedRectangle rect1 = QgsReferencedRectangle( QgsRectangle( 10.0, 20.0, 110.0, 220.0 ), QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3111" ) ) ); + QCOMPARE( rect1.crs().authid(), QStringLiteral( "EPSG:3111" ) ); + rect1.setCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:28356" ) ) ); + QCOMPARE( rect1.crs().authid(), QStringLiteral( "EPSG:28356" ) ); + + //convert to and from a QVariant + QVariant var = QVariant::fromValue( rect1 ); + QVERIFY( var.isValid() ); + + // not great - we'd ideally like this to pass, but it doesn't: + // QVERIFY( !var.canConvert< QgsRectangle >() ); + + QVERIFY( var.canConvert< QgsReferencedRectangle >() ); + + QgsReferencedRectangle rect2 = qvariant_cast( var ); + QCOMPARE( rect2.xMinimum(), rect1.xMinimum() ); + QCOMPARE( rect2.yMinimum(), rect1.yMinimum() ); + QCOMPARE( rect2.height(), rect1.height() ); + QCOMPARE( rect2.width(), rect1.width() ); + QCOMPARE( rect2.crs().authid(), QStringLiteral( "EPSG:28356" ) ); +} + QGSTEST_MAIN( TestQgsRectangle ) #include "testqgsrectangle.moc"