Skip to content

Commit

Permalink
Use inheritance rather than composition for QgsReferencedGeometries
Browse files Browse the repository at this point in the history
See #4720 (comment)
for discussion of the rationale
  • Loading branch information
nyalldawson committed Sep 6, 2017
1 parent e926f34 commit 1194b5a
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 60 deletions.
2 changes: 2 additions & 0 deletions python/core/geometry/qgsrectangle.sip
Expand Up @@ -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
Expand Down
54 changes: 26 additions & 28 deletions python/core/geometry/qgsreferencedgeometry.sip
Expand Up @@ -9,38 +9,27 @@



template<T>
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
#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();
QgsReferencedGeometryBase( const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
%Docstring
Returns the geometry primitive.
:rtype: T
Constructor for QgsReferencedGeometryBase, with the specified ``crs``.
%End

QgsCoordinateReferenceSystem crs() const;
Expand All @@ -60,11 +49,7 @@ class QgsReferencedGeometryPrimitive

};



typedef QgsReferencedGeometryPrimitive<QgsRectangle> QgsReferencedGeometryPrimitiveQgsRectangleBase;

class QgsReferencedRectangle : QgsReferencedGeometryPrimitiveQgsRectangleBase
class QgsReferencedRectangle : QgsRectangle, QgsReferencedGeometryBase
{
%Docstring
A QgsRectangle with associated coordinate reference system.
Expand All @@ -73,20 +58,33 @@ class QgsReferencedRectangle : QgsReferencedGeometryPrimitiveQgsRectangleBase

%TypeHeaderCode
#include "qgsreferencedgeometry.h"
typedef QgsReferencedGeometryPrimitive<QgsRectangle> QgsReferencedGeometryPrimitiveQgsRectangleBase;
%End
public:

QgsReferencedRectangle( const QgsRectangle &rect );
QgsReferencedRectangle( const QgsRectangle &rectangle, const QgsCoordinateReferenceSystem &crs );
%Docstring
Constructor for QgsReferencedRectangle, with the specified initial ``rectangle``
and ``crs``.
%End

};

class QgsReferencedPointXY : QgsPointXY, QgsReferencedGeometryBase
{
%Docstring
Construct a default optional expression.
It will be disabled and with an empty expression.
A QgsPointXY with associated coordinate reference system.
.. versionadded:: 3.0
%End

QgsRectangle &rect();
%TypeHeaderCode
#include "qgsreferencedgeometry.h"
%End
public:

QgsReferencedPointXY( const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs );
%Docstring
Returns the rectangles
:rtype: QgsRectangle
Constructor for QgsReferencedPointXY, with the specified initial ``point``
and ``crs``.
%End

};
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions src/core/geometry/qgsrectangle.h
Expand Up @@ -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.
Expand Down
32 changes: 32 additions & 0 deletions 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 )
{}
54 changes: 24 additions & 30 deletions src/core/geometry/qgsreferencedgeometry.h
Expand Up @@ -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<typename T>
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
Expand All @@ -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 );

};

Expand Down
6 changes: 4 additions & 2 deletions src/core/qgspointxy.h
Expand Up @@ -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
Expand Down

0 comments on commit 1194b5a

Please sign in to comment.