From 1194b5abea74e419d068420666bb47a2568da8e6 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 31 Aug 2017 13:53:00 +1000 Subject: [PATCH] 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