QGIS API Documentation 4.3.0-Master (16649ce5cc6)
Loading...
Searching...
No Matches
qgsmeshvectorfieldvaluesource.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmeshvectorfieldvaluesource.cpp
3 ---------------------------------
4 begin : September 2026
5 copyright : (C) 2026 by Stefanos Natsis
6 email : uclaros at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
21#include "qgsmeshlayerutils.h"
22
24
25QgsMeshVectorFieldValueSource::QgsMeshVectorFieldValueSource(
26 const QgsTriangularMesh &triangularMesh,
27 const QgsMeshDataBlock &datasetVectorValues,
28 const QgsMeshDataBlock &scalarActiveFaceFlagValues,
29 const QVector<double> &datasetMagnitudeValues,
31 const QgsRectangle &layerExtent,
32 double maximumMagnitude
33)
34 : mTriangularMesh( triangularMesh )
35 , mDatasetValues( datasetVectorValues )
36 , mActiveFaceFlagValues( scalarActiveFaceFlagValues )
37 , mMagnitudeValues( datasetMagnitudeValues )
38 , mDataType( dataType )
39 , mExtent( layerExtent )
40 , mMaximumMagnitude( maximumMagnitude )
41 , mUseScalarActiveFaceFlagValues( scalarActiveFaceFlagValues.isValid() )
42{}
43
44std::unique_ptr<QgsMeshVectorFieldValueSource> QgsMeshVectorFieldValueSource::create(
45 const QgsTriangularMesh &triangularMesh,
46 const QgsMeshDataBlock &datasetVectorValues,
47 const QgsMeshDataBlock &scalarActiveFaceFlagValues,
48 const QVector<double> &datasetMagnitudeValues,
50 const QgsRectangle &layerExtent,
51 double maximumMagnitude
52)
53{
55 return std::make_unique<
56 QgsMeshVectorFieldValueSourceFromVertex>( triangularMesh, datasetVectorValues, scalarActiveFaceFlagValues, datasetMagnitudeValues, QgsMeshDatasetGroupMetadata::DataOnVertices, layerExtent, maximumMagnitude );
57
58 return std::make_unique<
59 QgsMeshVectorFieldValueSourceFromFace>( triangularMesh, datasetVectorValues, scalarActiveFaceFlagValues, datasetMagnitudeValues, QgsMeshDatasetGroupMetadata::DataOnFaces, layerExtent, maximumMagnitude );
60}
61
62QgsVector QgsMeshVectorFieldValueSource::vectorValue( const QgsPointXY &point ) const
63{
64 if ( mCacheFaceIndex != -1 && mCacheFaceIndex < mTriangularMesh.triangles().count() )
65 {
66 QgsVector res = interpolatedValuePrivate( mCacheFaceIndex, point );
67 if ( isVectorValid( res ) )
68 {
69 activeFaceFilter( res, mCacheFaceIndex );
70 return res;
71 }
72 }
73
74 //point is not on the face associated with mCacheIndex --> search for the face containing the point
75 QList<int> potentialFaceIndexes = mTriangularMesh.faceIndexesForRectangle( QgsRectangle( point, point ) );
76 mCacheFaceIndex = -1;
77 for ( const int faceIndex : potentialFaceIndexes )
78 {
79 QgsVector res = interpolatedValuePrivate( faceIndex, point );
80 if ( isVectorValid( res ) )
81 {
82 mCacheFaceIndex = faceIndex;
83 activeFaceFilter( res, mCacheFaceIndex );
84 return res;
85 }
86 }
87
88 //--> no face found return non valid vector
89 return ( QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() ) );
90}
91
92QgsRectangle QgsMeshVectorFieldValueSource::extent() const
93{
94 return mExtent;
95}
96
97double QgsMeshVectorFieldValueSource::maximumMagnitude() const
98{
99 return mMaximumMagnitude;
100}
101
102QVector<QgsPointXY> QgsMeshVectorFieldValueSource::seedPoints( const QgsRectangle &extent ) const
103{
104 const QList<int> facesInExtent = mTriangularMesh.faceIndexesForRectangle( extent );
105 QSet<int> vertices;
106 for ( const int f : facesInExtent )
107 {
108 const QgsMeshFace face = mTriangularMesh.triangles().at( f );
109 for ( const int i : face )
110 vertices.insert( i );
111 }
112
113 QVector<QgsPointXY> points;
114 points.reserve( vertices.count() );
115 for ( const int i : vertices )
116 points.append( mTriangularMesh.vertices().at( i ) );
117
118 return points;
119}
120
121std::unique_ptr<QgsRasterInterface> QgsMeshVectorFieldValueSource::magnitudeSource( const QgsRenderContext &context, QSize size ) const
122{
123 if ( mMagnitudeValues.isEmpty() )
124 return nullptr;
125
126 return std::make_unique<QgsMeshLayerInterpolator>( mTriangularMesh, mMagnitudeValues, mActiveFaceFlagValues, mDataType, context, size );
127}
128
129bool QgsMeshVectorFieldValueSource::isVectorValid( const QgsVector &v ) const
130{
131 return !( std::isnan( v.x() ) || std::isnan( v.y() ) );
132}
133
134void QgsMeshVectorFieldValueSource::activeFaceFilter( QgsVector &vector, int faceIndex ) const
135{
136 if ( mUseScalarActiveFaceFlagValues && !mActiveFaceFlagValues.active( mTriangularMesh.trianglesToNativeFaces()[faceIndex] ) )
137 vector = QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
138}
139
140QgsMeshVectorFieldValueSourceFromVertex *QgsMeshVectorFieldValueSourceFromVertex::clone() const
141{
142 return new QgsMeshVectorFieldValueSourceFromVertex( *this );
143}
144
145QgsVector QgsMeshVectorFieldValueSourceFromVertex::interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const
146{
147 const QgsMeshFace face = mTriangularMesh.triangles().at( faceIndex );
148
149 const QgsPoint p1 = mTriangularMesh.vertices().at( face.at( 0 ) );
150 const QgsPoint p2 = mTriangularMesh.vertices().at( face.at( 1 ) );
151 const QgsPoint p3 = mTriangularMesh.vertices().at( face.at( 2 ) );
152
153 const QgsVector v1 = QgsVector( mDatasetValues.value( face.at( 0 ) ).x(), mDatasetValues.value( face.at( 0 ) ).y() );
154 const QgsVector v2 = QgsVector( mDatasetValues.value( face.at( 1 ) ).x(), mDatasetValues.value( face.at( 1 ) ).y() );
155 const QgsVector v3 = QgsVector( mDatasetValues.value( face.at( 2 ) ).x(), mDatasetValues.value( face.at( 2 ) ).y() );
156
157 return QgsMeshLayerUtils::interpolateVectorFromVerticesData( p1, p2, p3, v1, v2, v3, point );
158}
159
160QgsMeshVectorFieldValueSourceFromFace *QgsMeshVectorFieldValueSourceFromFace::clone() const
161{
162 return new QgsMeshVectorFieldValueSourceFromFace( *this );
163}
164
165QgsVector QgsMeshVectorFieldValueSourceFromFace::interpolatedValuePrivate( int faceIndex, const QgsPointXY point ) const
166{
167 const QgsMeshFace face = mTriangularMesh.triangles().at( faceIndex );
168
169 const QgsPoint p1 = mTriangularMesh.vertices().at( face.at( 0 ) );
170 const QgsPoint p2 = mTriangularMesh.vertices().at( face.at( 1 ) );
171 const QgsPoint p3 = mTriangularMesh.vertices().at( face.at( 2 ) );
172
173 const int nativeFaceIndex = mTriangularMesh.trianglesToNativeFaces().at( faceIndex );
174 const QgsVector vect = QgsVector( mDatasetValues.value( nativeFaceIndex ).x(), mDatasetValues.value( nativeFaceIndex ).y() );
175
176 return QgsMeshLayerUtils::interpolateVectorFromFacesData( p1, p2, p3, vect, point );
177}
178
QgsVertexIterator vertices() const
Returns a read-only, Java-style iterator for traversal of vertices of all the geometry,...
A block of integers/doubles from a mesh dataset.
DataType
Location of where data is specified for datasets in the dataset group.
@ DataOnFaces
Data is defined on faces.
@ DataOnVertices
Data is defined on vertices.
Represents a 2D point.
Definition qgspointxy.h:62
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
A rectangle specified with double values.
Contains information about the context of a rendering operation.
A triangular/derived mesh with vertices in map coordinates.
Represent a 2-dimensional vector.
Definition qgsvector.h:34
double y() const
Returns the vector's y-component.
Definition qgsvector.h:155
double x() const
Returns the vector's x-component.
Definition qgsvector.h:146
QVector< int > QgsMeshFace
List of vertex indexes.