diff --git a/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in b/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in index 0e1e2e4966c..a044ca59e11 100644 --- a/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in @@ -92,7 +92,7 @@ class QgsMeshDatasetMetadata %Docstring QgsMeshDatasetMetadata is a collection of mesh dataset metadata such -as if the data is vector or scalar, etc. +as whether the data is vector or scalar, etc. .. note:: @@ -109,12 +109,18 @@ as if the data is vector or scalar, etc. %Docstring Constructs an empty metadata object %End + QgsMeshDatasetMetadata( bool isScalar, bool isValid, bool isOnVertices, const QMap &extraOptions ); %Docstring -Consutructs a valid metadata object +Constructs a valid metadata object + +:param isScalar: dataset contains scalar data, particulary the y-value of QgsMeshDatasetValue is NaN +:param isValid: dataset is loadad and valid for fetching the data +:param isOnVertices: dataset values are defined on mesh's vertices. If false, values are defined on faces. +:param extraOptions: dataset's extra options stored by the provider. Usually contains the name, time value, time units, data file vendor, ... %End QMap extraOptions() const; @@ -145,9 +151,12 @@ Usually including name, description or time variable }; -class QgsMeshSource /Abstract/ +class QgsMeshDataSourceInterface /Abstract/ { %Docstring + +Interface for mesh data sources + Mesh is a collection of vertices and faces in 2D or 3D space - vertex - XY(Z) point (in the mesh's coordinate reference system) - faces - sets of vertices forming a closed shape - typically triangles or quadrilaterals @@ -166,7 +175,7 @@ read on demand #include "qgsmeshdataprovider.h" %End public: - virtual ~QgsMeshSource(); + virtual ~QgsMeshDataSourceInterface(); virtual int vertexCount() const = 0; %Docstring @@ -197,13 +206,14 @@ read on demand %End }; -class QgsMeshDatasetSource /Abstract/ +class QgsMeshDatasetSourceInterface /Abstract/ { %Docstring -Dataset is a collection of vector or scalar values on vertices or faces of the mesh +Interface for mesh datasets -Based on the underlying data provider/format, whole dataset is either stored in memory or -read on demand +Dataset is a collection of vector or scalar values on vertices or faces of the mesh. +Based on the underlying data provider/format, whole dataset is either stored in memory +or read on demand .. note:: @@ -216,7 +226,7 @@ read on demand #include "qgsmeshdataprovider.h" %End public: - virtual ~QgsMeshDatasetSource(); + virtual ~QgsMeshDatasetSourceInterface(); virtual bool addDataset( const QString &uri ) = 0; %Docstring @@ -242,7 +252,7 @@ See QgsMeshDatasetMetadata.isVector() to check if the returned value is vector o }; -class QgsMeshDataProvider: QgsDataProvider, QgsMeshSource, QgsMeshDatasetSource +class QgsMeshDataProvider: QgsDataProvider, QgsMeshDataSourceInterface, QgsMeshDatasetSourceInterface { %Docstring Base class for providing data for :py:class:`QgsMeshLayer` diff --git a/python/core/auto_generated/mesh/qgsmeshlayer.sip.in b/python/core/auto_generated/mesh/qgsmeshlayer.sip.in index 0d1b3fff381..6112629d1a4 100644 --- a/python/core/auto_generated/mesh/qgsmeshlayer.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshlayer.sip.in @@ -103,6 +103,7 @@ QgsMeshLayer cannot be copied. virtual QgsRectangle extent() const; virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) /Factory/; + virtual bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context ); virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const; @@ -125,42 +126,42 @@ Returns the provider type for this layer QgsMeshRendererMeshSettings rendererNativeMeshSettings() const; %Docstring -Returns rendrer settings +Returns renderer settings %End void setRendererNativeMeshSettings( const QgsMeshRendererMeshSettings &settings ); %Docstring -Sets new rendering settings, triggers repaint +Sets new renderer settings, triggers repaint %End QgsMeshRendererMeshSettings rendererTriangularMeshSettings() const; %Docstring -Returns rendrer settings +Returns renderer settings %End void setRendererTriangularMeshSettings( const QgsMeshRendererMeshSettings &settings ); %Docstring -Sets new rendering settings, triggers repaint +Sets new renderer settings, triggers repaint %End QgsMeshRendererScalarSettings rendererScalarSettings() const; %Docstring -Returns rendrer settings +Returns renderer settings %End void setRendererScalarSettings( const QgsMeshRendererScalarSettings &settings ); %Docstring -Sets new rendering settings, triggers repaint +Sets new renderer settings, triggers repaint %End QgsMeshRendererVectorSettings rendererVectorSettings() const; %Docstring -Returns rendrer settings +Returns renderer settings %End void setRendererVectorSettings( const QgsMeshRendererVectorSettings &settings ); %Docstring -Sets new rendering settings, triggers repaint +Sets new renderer settings, triggers repaint %End void setActiveScalarDataset( int index = NO_ACTIVE_MESH_DATASET ); diff --git a/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in b/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in index 6b3eec34b5f..67ee3d5b733 100644 --- a/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in @@ -202,7 +202,7 @@ Sets filter value for vector magnitudes. %Docstring Returns method used for drawing arrows %End - void setShaftLengthMethod( const QgsMeshRendererVectorSettings::ArrowScalingMethod &shaftLengthMethod ); + void setShaftLengthMethod( ArrowScalingMethod shaftLengthMethod ); %Docstring Sets method used for drawing arrows %End diff --git a/src/core/mesh/qgsmeshdataprovider.cpp b/src/core/mesh/qgsmeshdataprovider.cpp index 163d14bd8bc..d45bbd5997a 100644 --- a/src/core/mesh/qgsmeshdataprovider.cpp +++ b/src/core/mesh/qgsmeshdataprovider.cpp @@ -40,10 +40,12 @@ QgsRectangle QgsMeshDataProvider::extent() const } -QgsMeshDatasetValue::QgsMeshDatasetValue( double x, double y ): mX( x ), mY( y ) +QgsMeshDatasetValue::QgsMeshDatasetValue( double x, double y ) + : mX( x ), mY( y ) {} -QgsMeshDatasetValue::QgsMeshDatasetValue( double scalar ): mX( scalar ) +QgsMeshDatasetValue::QgsMeshDatasetValue( double scalar ) + : mX( scalar ) {} double QgsMeshDatasetValue::scalar() const diff --git a/src/core/mesh/qgsmeshdataprovider.h b/src/core/mesh/qgsmeshdataprovider.h index c3d860e7b67..6b2523b7a18 100644 --- a/src/core/mesh/qgsmeshdataprovider.h +++ b/src/core/mesh/qgsmeshdataprovider.h @@ -79,7 +79,6 @@ class CORE_EXPORT QgsMeshDatasetValue //! Returns y value double y() const; - //! Equals bool operator==( const QgsMeshDatasetValue &other ) const; private: @@ -93,7 +92,7 @@ class CORE_EXPORT QgsMeshDatasetValue * \ingroup core * * QgsMeshDatasetMetadata is a collection of mesh dataset metadata such - * as if the data is vector or scalar, etc. + * as whether the data is vector or scalar, etc. * * \note The API is considered EXPERIMENTAL and can be changed without a notice * @@ -104,7 +103,15 @@ class CORE_EXPORT QgsMeshDatasetMetadata public: //! Constructs an empty metadata object QgsMeshDatasetMetadata() = default; - //! Consutructs a valid metadata object + + /** + * Constructs a valid metadata object + * + * \param isScalar dataset contains scalar data, particulary the y-value of QgsMeshDatasetValue is NaN + * \param isValid dataset is loadad and valid for fetching the data + * \param isOnVertices dataset values are defined on mesh's vertices. If false, values are defined on faces. + * \param extraOptions dataset's extra options stored by the provider. Usually contains the name, time value, time units, data file vendor, ... + */ QgsMeshDatasetMetadata( bool isScalar, bool isValid, bool isOnVertices, @@ -145,6 +152,9 @@ class CORE_EXPORT QgsMeshDatasetMetadata /** * \ingroup core + * + * Interface for mesh data sources + * * Mesh is a collection of vertices and faces in 2D or 3D space * - vertex - XY(Z) point (in the mesh's coordinate reference system) * - faces - sets of vertices forming a closed shape - typically triangles or quadrilaterals @@ -156,11 +166,11 @@ class CORE_EXPORT QgsMeshDatasetMetadata * * \since QGIS 3.2 */ -class CORE_EXPORT QgsMeshSource SIP_ABSTRACT +class CORE_EXPORT QgsMeshDataSourceInterface SIP_ABSTRACT { public: //! Dtor - virtual ~QgsMeshSource() = default; + virtual ~QgsMeshDataSourceInterface() = default; /** * \brief Returns number of vertices in the native mesh @@ -189,20 +199,21 @@ class CORE_EXPORT QgsMeshSource SIP_ABSTRACT /** * \ingroup core - * Dataset is a collection of vector or scalar values on vertices or faces of the mesh + * Interface for mesh datasets * - * Based on the underlying data provider/format, whole dataset is either stored in memory or - * read on demand + * Dataset is a collection of vector or scalar values on vertices or faces of the mesh. + * Based on the underlying data provider/format, whole dataset is either stored in memory + * or read on demand * * \note The API is considered EXPERIMENTAL and can be changed without a notice * * \since QGIS 3.2 */ -class CORE_EXPORT QgsMeshDatasetSource SIP_ABSTRACT +class CORE_EXPORT QgsMeshDatasetSourceInterface SIP_ABSTRACT { public: //! Dtor - virtual ~QgsMeshDatasetSource() = default; + virtual ~QgsMeshDatasetSourceInterface() = default; /** * \brief Associate dataset with the mesh @@ -239,7 +250,7 @@ class CORE_EXPORT QgsMeshDatasetSource SIP_ABSTRACT * \see QgsMeshSource * \since QGIS 3.2 */ -class CORE_EXPORT QgsMeshDataProvider: public QgsDataProvider, public QgsMeshSource, public QgsMeshDatasetSource +class CORE_EXPORT QgsMeshDataProvider: public QgsDataProvider, public QgsMeshDataSourceInterface, public QgsMeshDatasetSourceInterface { Q_OBJECT diff --git a/src/core/mesh/qgsmeshlayer.h b/src/core/mesh/qgsmeshlayer.h index 482fc29bd9f..9925be6c6e5 100644 --- a/src/core/mesh/qgsmeshlayer.h +++ b/src/core/mesh/qgsmeshlayer.h @@ -116,7 +116,7 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer const QgsMeshDataProvider *dataProvider() const override SIP_SKIP; QgsMeshLayer *clone() const override SIP_FACTORY; QgsRectangle extent() const override; - virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY; + QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY; bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context ) override; bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const override; QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const override; @@ -127,34 +127,34 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer //! Returns the provider type for this layer QString providerType() const; - //! Returns native mesh (nullprt before rendering) + //! Returns native mesh (nullptr before rendering) QgsMesh *nativeMesh() SIP_SKIP; - //! Returns triangular mesh (nullprt before rendering) + //! Returns triangular mesh (nullptr before rendering) QgsTriangularMesh *triangularMesh() SIP_SKIP; - //! Returns rendrer settings + //! Returns renderer settings QgsMeshRendererMeshSettings rendererNativeMeshSettings() const; - //! Sets new rendering settings, triggers repaint + //! Sets new renderer settings, triggers repaint void setRendererNativeMeshSettings( const QgsMeshRendererMeshSettings &settings ); - //! Returns rendrer settings + //! Returns renderer settings QgsMeshRendererMeshSettings rendererTriangularMeshSettings() const; - //! Sets new rendering settings, triggers repaint + //! Sets new renderer settings, triggers repaint void setRendererTriangularMeshSettings( const QgsMeshRendererMeshSettings &settings ); - //! Returns rendrer settings + //! Returns renderer settings QgsMeshRendererScalarSettings rendererScalarSettings() const; - //! Sets new rendering settings, triggers repaint + //! Sets new renderer settings, triggers repaint void setRendererScalarSettings( const QgsMeshRendererScalarSettings &settings ); - //! Returns rendrer settings + //! Returns renderer settings QgsMeshRendererVectorSettings rendererVectorSettings() const; - //! Sets new rendering settings, triggers repaint + //! Sets new renderer settings, triggers repaint void setRendererVectorSettings( const QgsMeshRendererVectorSettings &settings ); /** diff --git a/src/core/mesh/qgsmeshlayerinterpolator.cpp b/src/core/mesh/qgsmeshlayerinterpolator.cpp index bc014499569..edb5a9a598e 100644 --- a/src/core/mesh/qgsmeshlayerinterpolator.cpp +++ b/src/core/mesh/qgsmeshlayerinterpolator.cpp @@ -17,11 +17,15 @@ ///@cond PRIVATE +#include + #include "qgsmeshlayerinterpolator.h" #include "qgsrasterinterface.h" -#include #include "qgsmaptopixel.h" +#include "qgsvector.h" +#include "qgspoint.h" +#include "qgspointxy.h" static void bbox2rect( const QgsMapToPixel &mtp, @@ -37,7 +41,7 @@ static void bbox2rect( rightLim = std::min( int( ur.x() ), outputSize.width() - 1 ); } -static void lam_tol( double &lam ) +static void lamTol( double &lam ) { const static double eps = 1e-6; if ( ( lam < 0.0 ) && ( lam > -eps ) ) @@ -46,22 +50,23 @@ static void lam_tol( double &lam ) } } -static bool E3T_physicalToBarycentric( QPointF pA, QPointF pB, QPointF pC, QPointF pP, double &lam1, double &lam2, double &lam3 ) +static bool E3T_physicalToBarycentric( const QgsPointXY &pA, const QgsPointXY &pB, const QgsPointXY &pC, const QgsPointXY &pP, + double &lam1, double &lam2, double &lam3 ) { if ( pA == pB || pA == pC || pB == pC ) return false; // this is not a valid triangle! // Compute vectors - QVector2D v0( pC - pA ); - QVector2D v1( pB - pA ); - QVector2D v2( pP - pA ); + QgsVector v0( pC - pA ); + QgsVector v1( pB - pA ); + QgsVector v2( pP - pA ); // Compute dot products - double dot00 = QVector2D::dotProduct( v0, v0 ); - double dot01 = QVector2D::dotProduct( v0, v1 ); - double dot02 = QVector2D::dotProduct( v0, v2 ); - double dot11 = QVector2D::dotProduct( v1, v1 ); - double dot12 = QVector2D::dotProduct( v1, v2 ); + double dot00 = v0 * v0; + double dot01 = v0 * v1; + double dot02 = v0 * v2; + double dot11 = v1 * v1; + double dot12 = v1 * v2; // Compute barycentric coordinates double invDenom = 1.0 / ( dot00 * dot11 - dot01 * dot01 ); @@ -70,9 +75,9 @@ static bool E3T_physicalToBarycentric( QPointF pA, QPointF pB, QPointF pC, QPoin lam3 = 1.0 - lam1 - lam2; // Apply some tolerance to lam so we can detect correctly border points - lam_tol( lam1 ); - lam_tol( lam2 ); - lam_tol( lam3 ); + lamTol( lam1 ); + lamTol( lam2 ); + lamTol( lam3 ); // Return if POI is outside triangle if ( ( lam1 < 0 ) || ( lam2 < 0 ) || ( lam3 < 0 ) ) @@ -84,7 +89,8 @@ static bool E3T_physicalToBarycentric( QPointF pA, QPointF pB, QPointF pC, QPoin } -double interpolateFromVerticesData( const QPointF &p1, const QPointF &p2, const QPointF &p3, double val1, double val2, double val3, const QPointF &pt ) +double interpolateFromVerticesData( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3, + double val1, double val2, double val3, const QgsPointXY &pt ) { double lam1, lam2, lam3; if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) ) @@ -93,7 +99,7 @@ double interpolateFromVerticesData( const QPointF &p1, const QPointF &p2, const return lam1 * val3 + lam2 * val2 + lam3 * val1; } -double interpolateFromFacesData( const QPointF &p1, const QPointF &p2, const QPointF &p3, double val, const QPointF &pt ) +double interpolateFromFacesData( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3, double val, const QgsPointXY &pt ) { double lam1, lam2, lam3; if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) ) @@ -102,10 +108,12 @@ double interpolateFromFacesData( const QPointF &p1, const QPointF &p2, const QPo return val; } -QgsMeshLayerInterpolator::QgsMeshLayerInterpolator( const QgsTriangularMesh &m, - const QVector &datasetValues, bool dataIsOnVertices, - const QgsRenderContext &context, - const QSize &size ) +QgsMeshLayerInterpolator::QgsMeshLayerInterpolator( + const QgsTriangularMesh &m, + const QVector &datasetValues, + bool dataIsOnVertices, + const QgsRenderContext &context, + const QSize &size ) : mTriangularMesh( m ), mDatasetValues( datasetValues ), mContext( context ), @@ -118,7 +126,7 @@ QgsMeshLayerInterpolator::~QgsMeshLayerInterpolator() = default; QgsRasterInterface *QgsMeshLayerInterpolator::clone() const { - return nullptr; // we should not need this (hopefully) + assert( false ); // we should not need this (hopefully) } Qgis::DataType QgsMeshLayerInterpolator::dataType( int ) const @@ -133,23 +141,23 @@ int QgsMeshLayerInterpolator::bandCount() const QgsRasterBlock *QgsMeshLayerInterpolator::block( int, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback ) { - QgsRasterBlock *b = new QgsRasterBlock( Qgis::Float64, width, height ); - b->setIsNoData(); // assume initially that all values are unset - double *data = reinterpret_cast( b->bits() ); + std::unique_ptr outputBlock( new QgsRasterBlock( Qgis::Float64, width, height ) ); + outputBlock->setIsNoData(); // assume initially that all values are unset + double *data = reinterpret_cast( outputBlock->bits() ); - const QVector &triangels = mTriangularMesh.triangles(); + const QVector &triangles = mTriangularMesh.triangles(); const QVector &vertices = mTriangularMesh.vertices(); // currently expecting that triangulation does not add any new extra vertices on the way if ( mDataOnVertices ) Q_ASSERT( mDatasetValues.count() == mTriangularMesh.vertices().count() ); - for ( int i = 0; i < triangels.size(); ++i ) + for ( int i = 0; i < triangles.size(); ++i ) { if ( feedback && feedback->isCanceled() ) break; - const QgsMeshFace &face = triangels[i]; + const QgsMeshFace &face = triangles[i]; const int v1 = face[0], v2 = face[1], v3 = face[2]; const QgsPoint p1 = vertices[v1], p2 = vertices[v2], p3 = vertices[v3]; @@ -172,12 +180,12 @@ QgsRasterBlock *QgsMeshLayerInterpolator::block( int, const QgsRectangle &extent for ( int k = leftLim; k <= rightLim; k++ ) { double val; - QPointF p = mContext.mapToPixel().toMapCoordinates( k, j ).toQPointF(); + const QgsPointXY p = mContext.mapToPixel().toMapCoordinates( k, j ); if ( mDataOnVertices ) val = interpolateFromVerticesData( - QPointF( p1.x(), p1.y() ), - QPointF( p2.x(), p2.y() ), - QPointF( p3.x(), p3.y() ), + p1, + p2, + p3, mDatasetValues[v1], mDatasetValues[v2], mDatasetValues[v3], @@ -186,9 +194,9 @@ QgsRasterBlock *QgsMeshLayerInterpolator::block( int, const QgsRectangle &extent { int face = mTriangularMesh.trianglesToNativeFaces()[i]; val = interpolateFromFacesData( - QPointF( p1.x(), p1.y() ), - QPointF( p2.x(), p2.y() ), - QPointF( p3.x(), p3.y() ), + p1, + p2, + p3, mDatasetValues[face], p ); @@ -197,14 +205,14 @@ QgsRasterBlock *QgsMeshLayerInterpolator::block( int, const QgsRectangle &extent if ( !qIsNaN( val ) ) { line[k] = val; - b->setIsData( j, k ); + outputBlock->setIsData( j, k ); } } } } - return b; + return outputBlock.release();; } ///@endcond diff --git a/src/core/mesh/qgsmeshlayerinterpolator.h b/src/core/mesh/qgsmeshlayerinterpolator.h index f1567349c5e..54461f120ba 100644 --- a/src/core/mesh/qgsmeshlayerinterpolator.h +++ b/src/core/mesh/qgsmeshlayerinterpolator.h @@ -23,7 +23,6 @@ class QgsSymbol; #define SIP_NO_FILE -#include #include #include "qgis.h" @@ -34,7 +33,6 @@ class QgsSymbol; #include "qgsrasterinterface.h" #include "qgssinglebandpseudocolorrenderer.h" #include "qgsrastershader.h" -#include ///@cond PRIVATE @@ -56,16 +54,16 @@ class QgsMeshLayerInterpolator : public QgsRasterInterface const QSize &size ); ~QgsMeshLayerInterpolator() override; - virtual QgsRasterInterface *clone() const override; - virtual Qgis::DataType dataType( int ) const override; - virtual int bandCount() const override; - virtual QgsRasterBlock *block( int, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback = nullptr ) override; + QgsRasterInterface *clone() const override; + Qgis::DataType dataType( int ) const override; + int bandCount() const override; + QgsRasterBlock *block( int, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback = nullptr ) override; private: const QgsTriangularMesh &mTriangularMesh; const QVector &mDatasetValues; const QgsRenderContext &mContext; - bool mDataOnVertices; + bool mDataOnVertices = true; QSize mOutputSize; }; diff --git a/src/core/mesh/qgsmeshlayerrenderer.cpp b/src/core/mesh/qgsmeshlayerrenderer.cpp index 83f93e2a006..c9b7104181b 100644 --- a/src/core/mesh/qgsmeshlayerrenderer.cpp +++ b/src/core/mesh/qgsmeshlayerrenderer.cpp @@ -15,6 +15,8 @@ * * ***************************************************************************/ +#include + #include "qgsmeshlayerrenderer.h" #include "qgsfield.h" @@ -223,13 +225,10 @@ void QgsMeshLayerRenderer::renderScalarDataset() sh->setRasterShaderFunction( fcn ); // takes ownership of fcn QgsMeshLayerInterpolator interpolator( mTriangularMesh, mScalarDatasetValues, mScalarDataOnVertices, mContext, mOutputSize ); QgsSingleBandPseudoColorRenderer r( &interpolator, 0, sh ); // takes ownership of sh - QgsRasterBlock *bl = r.block( 0, mContext.extent(), mOutputSize.width(), mOutputSize.height(), mFeedback.get() ); - Q_ASSERT( bl ); - + std::unique_ptr bl( r.block( 0, mContext.extent(), mOutputSize.width(), mOutputSize.height(), mFeedback.get() ) ); QImage img = bl->image(); mContext.painter()->drawImage( 0, 0, img ); - delete bl; } void QgsMeshLayerRenderer::renderVectorDataset() diff --git a/src/core/mesh/qgsmeshlayerrenderer.h b/src/core/mesh/qgsmeshlayerrenderer.h index ebdc7d737bd..888b35669ea 100644 --- a/src/core/mesh/qgsmeshlayerrenderer.h +++ b/src/core/mesh/qgsmeshlayerrenderer.h @@ -84,13 +84,13 @@ class QgsMeshLayerRenderer : public QgsMapLayerRenderer // copy of the scalar dataset QVector mScalarDatasetValues; - bool mScalarDataOnVertices; + bool mScalarDataOnVertices = true; // copy of the vector dataset QVector mVectorDatasetValuesX; QVector mVectorDatasetValuesY; QVector mVectorDatasetValuesMag; - bool mVectorDataOnVertices; + bool mVectorDataOnVertices = true; // copy from mesh layer std::unique_ptr mNativeMeshSymbol = nullptr; diff --git a/src/core/mesh/qgsmeshmemorydataprovider.cpp b/src/core/mesh/qgsmeshmemorydataprovider.cpp index 628f57df70f..c0500a7fec7 100644 --- a/src/core/mesh/qgsmeshmemorydataprovider.cpp +++ b/src/core/mesh/qgsmeshmemorydataprovider.cpp @@ -71,7 +71,7 @@ bool QgsMeshMemoryDataProvider::splitMeshSections( const QString &uri ) const QStringList sections = uri.split( QStringLiteral( "---" ), QString::SkipEmptyParts ); if ( sections.size() != 2 ) { - setError( QgsError( QStringLiteral( "Invalid mesh definition, does not contain 2 sections" ), + setError( QgsError( tr( "Invalid mesh definition, does not contain 2 sections" ), QStringLiteral( "Mesh Memory Provider" ) ) ); return false; } @@ -92,7 +92,7 @@ bool QgsMeshMemoryDataProvider::addMeshVertices( const QString &def ) const QStringList coords = verticesCoords[i].split( ',', QString::SkipEmptyParts ); if ( coords.size() != 2 ) { - setError( QgsError( QStringLiteral( "Invalid mesh definition, vertex definition does not contain x, y" ), + setError( QgsError( tr( "Invalid mesh definition, vertex definition does not contain x, y" ), QStringLiteral( "Mesh Memory Provider" ) ) ); return false; } @@ -116,7 +116,7 @@ bool QgsMeshMemoryDataProvider::addMeshFaces( const QString &def ) const QStringList vertices = facesVertices[i].split( ',', QString::SkipEmptyParts ); if ( vertices.size() < 3 ) { - setError( QgsError( QStringLiteral( "Invalid mesh definition, face must contain at least 3 vertices" ), + setError( QgsError( tr( "Invalid mesh definition, face must contain at least 3 vertices" ), QStringLiteral( "Mesh Memory Provider" ) ) ); return false; } @@ -126,12 +126,14 @@ bool QgsMeshMemoryDataProvider::addMeshFaces( const QString &def ) int vertex_id = vertices[j].toInt(); if ( vertex_id < 0 ) { - setError( QgsError( QStringLiteral( "Invalid mesh definition, vertex index must be positive value" ), QStringLiteral( "Mesh Memory Provider" ) ) ); + setError( QgsError( tr( "Invalid mesh definition, vertex index must be positive value" ), + QStringLiteral( "Mesh Memory Provider" ) ) ); return false; } if ( mVertices.size() < vertex_id ) { - setError( QgsError( QStringLiteral( "Invalid mesh definition, missing vertex id defined in face" ), QStringLiteral( "Mesh Memory Provider" ) ) ); + setError( QgsError( tr( "Invalid mesh definition, missing vertex id defined in face" ), + QStringLiteral( "Mesh Memory Provider" ) ) ); return false; } @@ -152,7 +154,7 @@ bool QgsMeshMemoryDataProvider::splitDatasetSections( const QString &uri, QgsMes bool success = sections.size() == 3; if ( !success ) { - setError( QgsError( QStringLiteral( "Invalid dataset definition, does not contain 3 sections" ), + setError( QgsError( tr( "Invalid dataset definition, does not contain 3 sections" ), QStringLiteral( "Mesh Memory Provider" ) ) ); } @@ -174,13 +176,13 @@ bool QgsMeshMemoryDataProvider::setDatasetType( const QString &def, QgsMeshMemor if ( types.size() != 2 ) { - setError( QgsError( QStringLiteral( "Invalid type definition, must be Vertex/Face Vector/Scalar" ), + setError( QgsError( tr( "Invalid type definition, must be Vertex/Face Vector/Scalar" ), QStringLiteral( "Mesh Memory Provider" ) ) ); return false; } - dataset.isOnVertices = types[0].trimmed().toLower() == QStringLiteral( "vertex" ); - dataset.isScalar = types[1].trimmed().toLower() == QStringLiteral( "scalar" ); + dataset.isOnVertices = 0 == QString::compare( types[0].trimmed(), QStringLiteral( "vertex" ), Qt::CaseInsensitive ); + dataset.isScalar = 0 == QString::compare( types[1].trimmed(), QStringLiteral( "scalar" ), Qt::CaseInsensitive ); return true; } @@ -193,7 +195,7 @@ bool QgsMeshMemoryDataProvider::addDatasetMetadata( const QString &def, QgsMeshM const QStringList keyVal = metadataLines[i].split( ':', QString::SkipEmptyParts ); if ( keyVal.size() != 2 ) { - setError( QgsError( QStringLiteral( "Invalid dataset definition, dataset metadata does not contain key: value" ), + setError( QgsError( tr( "Invalid dataset definition, dataset metadata does not contain key: value" ), QStringLiteral( "Mesh Memory Provider" ) ) ); return false; } @@ -215,7 +217,7 @@ bool QgsMeshMemoryDataProvider::addDatasetValues( const QString &def, QgsMeshMem { if ( values.size() != 1 ) { - setError( QgsError( QStringLiteral( "Invalid dataset definition, dataset scalar values must be x" ), + setError( QgsError( tr( "Invalid dataset definition, dataset scalar values must be x" ), QStringLiteral( "Mesh Memory Provider" ) ) ); return false; } @@ -228,7 +230,7 @@ bool QgsMeshMemoryDataProvider::addDatasetValues( const QString &def, QgsMeshMem { if ( values.size() < 2 ) { - setError( QgsError( QStringLiteral( "Invalid dataset definition, dataset vector values must be x, y" ), + setError( QgsError( tr( "Invalid dataset definition, dataset vector values must be x, y" ), QStringLiteral( "Mesh Memory Provider" ) ) ); return false; } @@ -253,7 +255,7 @@ bool QgsMeshMemoryDataProvider::checkDatasetValidity( QgsMeshMemoryDataset &data if ( dataset.values.count() != vertexCount() ) { valid = false; - setError( QgsError( QStringLiteral( "Dataset defined on vertices has {} values, but mesh {}" ).arg( dataset.values.count(), vertexCount() ), + setError( QgsError( tr( "Dataset defined on vertices has {} values, but mesh {}" ).arg( dataset.values.count(), vertexCount() ), QStringLiteral( "Mesh Memory Provider" ) ) ); } } @@ -263,7 +265,7 @@ bool QgsMeshMemoryDataProvider::checkDatasetValidity( QgsMeshMemoryDataset &data if ( dataset.values.count() != faceCount() ) { valid = false; - setError( QgsError( QStringLiteral( "Dataset defined on faces has {} values, but mesh {}" ).arg( dataset.values.count(), faceCount() ), + setError( QgsError( tr( "Dataset defined on faces has {} values, but mesh {}" ).arg( dataset.values.count(), faceCount() ), QStringLiteral( "Mesh Memory Provider" ) ) ); } } @@ -303,7 +305,7 @@ bool QgsMeshMemoryDataProvider::addDataset( const QString &uri ) } else { - setError( QgsError( QStringLiteral( "Unable to add dataset to invalid mesh" ), + setError( QgsError( tr( "Unable to add dataset to invalid mesh" ), QStringLiteral( "Mesh Memory Provider" ) ) ); } diff --git a/src/core/mesh/qgsmeshrenderersettings.cpp b/src/core/mesh/qgsmeshrenderersettings.cpp index 8e18b18ab58..b76e2da76dc 100644 --- a/src/core/mesh/qgsmeshrenderersettings.cpp +++ b/src/core/mesh/qgsmeshrenderersettings.cpp @@ -132,7 +132,7 @@ QgsMeshRendererVectorSettings::ArrowScalingMethod QgsMeshRendererVectorSettings: return mShaftLengthMethod; } -void QgsMeshRendererVectorSettings::setShaftLengthMethod( const QgsMeshRendererVectorSettings::ArrowScalingMethod &shaftLengthMethod ) +void QgsMeshRendererVectorSettings::setShaftLengthMethod( QgsMeshRendererVectorSettings::ArrowScalingMethod shaftLengthMethod ) { mShaftLengthMethod = shaftLengthMethod; } diff --git a/src/core/mesh/qgsmeshrenderersettings.h b/src/core/mesh/qgsmeshrenderersettings.h index 5ac07ae8d28..2c83887f22c 100644 --- a/src/core/mesh/qgsmeshrenderersettings.h +++ b/src/core/mesh/qgsmeshrenderersettings.h @@ -187,7 +187,7 @@ class CORE_EXPORT QgsMeshRendererVectorSettings //! Returns method used for drawing arrows QgsMeshRendererVectorSettings::ArrowScalingMethod shaftLengthMethod() const; //! Sets method used for drawing arrows - void setShaftLengthMethod( const QgsMeshRendererVectorSettings::ArrowScalingMethod &shaftLengthMethod ); + void setShaftLengthMethod( ArrowScalingMethod shaftLengthMethod ); /** * Returns mininimum shaft length (in millimeters) diff --git a/src/core/mesh/qgsmeshvectorrenderer.cpp b/src/core/mesh/qgsmeshvectorrenderer.cpp index c45c73b385d..ace96c25554 100644 --- a/src/core/mesh/qgsmeshvectorrenderer.cpp +++ b/src/core/mesh/qgsmeshvectorrenderer.cpp @@ -55,12 +55,17 @@ QgsMeshVectorRenderer::QgsMeshVectorRenderer( const QgsTriangularMesh &m, , mDataOnVertices( dataIsOnVertices ) , mOutputSize( size ) { - mMinX = *std::min_element( datasetValuesX.constBegin(), datasetValuesX.constEnd() ); - mMaxX = *std::max_element( datasetValuesX.constBegin(), datasetValuesX.constEnd() ); - mMinY = *std::min_element( datasetValuesY.constBegin(), datasetValuesY.constEnd() ); - mMaxY = *std::max_element( datasetValuesY.constBegin(), datasetValuesY.constEnd() ); - mMinMag = *std::min_element( mDatasetValuesMag.constBegin(), mDatasetValuesMag.constEnd() ); - mMaxMag = *std::max_element( mDatasetValuesMag.constBegin(), mDatasetValuesMag.constEnd() ); + auto bounds = std::minmax_element( mDatasetValuesX.constBegin(), mDatasetValuesX.constEnd() ); + mMinX = *bounds.first; + mMaxX = *bounds.second; + + bounds = std::minmax_element( mDatasetValuesY.constBegin(), mDatasetValuesY.constEnd() ); + mMinY = *bounds.first; + mMaxY = *bounds.second; + + bounds = std::minmax_element( mDatasetValuesMag.constBegin(), mDatasetValuesMag.constEnd() ); + mMinMag = *bounds.first; + mMaxMag = *bounds.second; } QgsMeshVectorRenderer::~QgsMeshVectorRenderer() = default; @@ -68,9 +73,13 @@ QgsMeshVectorRenderer::~QgsMeshVectorRenderer() = default; void QgsMeshVectorRenderer::draw() { // Set up the render configuration options - QPainter *p = mContext.painter(); - p->setRenderHint( QPainter::Antialiasing ); - QPen pen = p->pen(); + QPainter *painter = mContext.painter(); + painter->save(); + if ( mContext.flags() & QgsRenderContext::Antialiasing ) + painter->setRenderHint( QPainter::Antialiasing, true ); + + painter->setRenderHint( QPainter::Antialiasing ); + QPen pen = painter->pen(); pen.setCapStyle( Qt::FlatCap ); pen.setJoinStyle( Qt::MiterJoin ); @@ -78,12 +87,14 @@ void QgsMeshVectorRenderer::draw() QgsUnitTypes::RenderUnit::RenderMillimeters ); pen.setWidthF( penWidth ); pen.setColor( mCfg.color() ); - p->setPen( pen ); + painter->setPen( pen ); if ( mDataOnVertices ) drawVectorDataOnVertices(); else drawVectorDataOnFaces(); + + painter->restore(); } bool QgsMeshVectorRenderer::calcVectorLineEnd( diff --git a/src/core/mesh/qgsmeshvectorrenderer.h b/src/core/mesh/qgsmeshvectorrenderer.h index e777df58252..c5256f79f66 100644 --- a/src/core/mesh/qgsmeshvectorrenderer.h +++ b/src/core/mesh/qgsmeshvectorrenderer.h @@ -57,7 +57,7 @@ class QgsMeshVectorRenderer ~QgsMeshVectorRenderer(); /** - * Draws vector arrows in the context's painter base on settings + * Draws vector arrows in the context's painter based on settings */ void draw(); @@ -84,15 +84,15 @@ class QgsMeshVectorRenderer const QVector &mDatasetValuesX; const QVector &mDatasetValuesY; const QVector &mDatasetValuesMag; //magnitudes - double mMinX; - double mMaxX; - double mMinY; - double mMaxY; - double mMinMag; - double mMaxMag; + double mMinX = 0.0; + double mMaxX = 0.0; + double mMinY = 0.0; + double mMaxY = 0.0; + double mMinMag = 0.0; + double mMaxMag = 0.0; QgsRenderContext &mContext; const QgsMeshRendererVectorSettings &mCfg; - bool mDataOnVertices; + bool mDataOnVertices = true; QSize mOutputSize; }; diff --git a/src/core/mesh/qgstriangularmesh.cpp b/src/core/mesh/qgstriangularmesh.cpp index d0af871d642..3d586b4be1d 100644 --- a/src/core/mesh/qgstriangularmesh.cpp +++ b/src/core/mesh/qgstriangularmesh.cpp @@ -131,6 +131,7 @@ void QgsTriangularMesh::update( QgsMesh *nativeMesh, QgsRenderContext *context ) { const QgsMeshFace &face = nativeMesh->faces.at( i ) ; QVector points; + points.reserve( face.size() ); for ( int j = 0; j < face.size(); ++j ) { int index = face.at( j ); diff --git a/src/providers/mdal/qgsmdalprovider.cpp b/src/providers/mdal/qgsmdalprovider.cpp index 7db467fd573..a5fab717958 100644 --- a/src/providers/mdal/qgsmdalprovider.cpp +++ b/src/providers/mdal/qgsmdalprovider.cpp @@ -168,8 +168,9 @@ QgsMeshDatasetValue QgsMdalProvider::datasetValue( int datasetIndex, int valueIn void QgsMdalProvider::refreshDatasets() { - mDatasets.clear(); int n = MDAL_M_datasetCount( mMeshH ); + mDatasets.resize( 0 ); // keeps allocated space - potentially avoids reallocation + mDatasets.reserve( n ); for ( int i = 0; i < n; ++i ) { DatasetH dataset = MDAL_M_dataset( mMeshH, i );