38 QgsMeshLayerInterpolator::QgsMeshLayerInterpolator(
40 const QVector<double> &datasetValues,
45 : mTriangularMesh( m ),
46 mDatasetValues( datasetValues ),
47 mActiveFaceFlagValues( activeFaceFlagValues ),
49 mDataType( dataType ),
54 QgsMeshLayerInterpolator::~QgsMeshLayerInterpolator() =
default;
67 int QgsMeshLayerInterpolator::bandCount()
const
75 const double noDataValue = std::numeric_limits<double>::quiet_NaN();
76 outputBlock->setNoDataValue( noDataValue );
77 outputBlock->setIsNoData();
78 double *data =
reinterpret_cast<double *
>( outputBlock->bits() );
80 QList<int> spatialIndexTriangles;
82 if ( mSpatialIndexActive )
84 spatialIndexTriangles = mTriangularMesh.faceIndexesForRectangle( extent );
85 indexCount = spatialIndexTriangles.count();
89 indexCount = mTriangularMesh.triangles().count();
92 if ( mTriangularMesh.contains( QgsMesh::ElementType::Edge ) )
94 return outputBlock.release();
97 const QVector<QgsMeshVertex> &vertices = mTriangularMesh.vertices();
100 if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
101 Q_ASSERT( mDatasetValues.count() == mTriangularMesh.vertices().count() );
103 for (
int i = 0; i < indexCount; ++i )
108 if ( mContext.renderingStopped() )
112 if ( mSpatialIndexActive )
113 triangleIndex = spatialIndexTriangles[i];
117 const QgsMeshFace &face = mTriangularMesh.triangles()[triangleIndex];
119 if ( face.isEmpty() )
122 const int v1 = face[0], v2 = face[1], v3 = face[2];
123 const QgsPointXY &p1 = vertices[v1], &p2 = vertices[v2], &p3 = vertices[v3];
125 const int nativeFaceIndex = mTriangularMesh.trianglesToNativeFaces()[triangleIndex];
126 const bool isActive = mActiveFaceFlagValues.active( nativeFaceIndex );
130 const QgsRectangle bbox = QgsMeshLayerUtils::triangleBoundingBox( p1, p2, p3 );
135 int topLim, bottomLim, leftLim, rightLim;
136 QgsMeshLayerUtils::boundingBoxToScreenRectangle( mContext.mapToPixel(), mOutputSize, bbox, leftLim, rightLim, topLim, bottomLim );
138 double value( 0 ), value1( 0 ), value2( 0 ), value3( 0 );
139 const int faceIdx = mTriangularMesh.trianglesToNativeFaces()[triangleIndex];
141 if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
143 value1 = mDatasetValues[v1];
144 value2 = mDatasetValues[v2];
145 value3 = mDatasetValues[v3];
148 value = mDatasetValues[faceIdx];
151 for (
int j = topLim; j <= bottomLim; j++ )
153 double *line = data + ( j * width );
154 for (
int k = leftLim; k <= rightLim; k++ )
157 const QgsPointXY p = mContext.mapToPixel().toMapCoordinates( k, j );
158 if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
159 val = QgsMeshLayerUtils::interpolateFromVerticesData(
169 val = QgsMeshLayerUtils::interpolateFromFacesData(
177 if ( !std::isnan( val ) )
180 outputBlock->setIsData( j, k );
187 return outputBlock.release();
190 void QgsMeshLayerInterpolator::setSpatialIndexActive(
bool active ) {mSpatialIndexActive = active;}
199 double mapUnitsPerPixel,
209 const int widthPixel =
static_cast<int>( extent.
width() / mapUnitsPerPixel );
210 const int heightPixel =
static_cast<int>( extent.
height() / mapUnitsPerPixel );
226 std::unique_ptr<QgsMesh> nativeMesh = std::make_unique<QgsMesh>();
228 std::unique_ptr<QgsTriangularMesh> triangularMesh = std::make_unique<QgsTriangularMesh>();
229 triangularMesh->update( nativeMesh.get(), transform );
233 const int count = QgsMeshLayerUtils::datasetValuesCount( nativeMesh.get(), scalarDataType );
242 const QVector<double> datasetValues = QgsMeshLayerUtils::calculateMagnitudes( vals );
246 nativeMesh->faces.count() );
248 QgsMeshLayerInterpolator interpolator(
249 *( triangularMesh.get() ),
251 activeFaceFlagValues,
254 QSize( widthPixel, heightPixel )
257 return interpolator.block( 0, extent, widthPixel, heightPixel, feedback );
266 double mapUnitsPerPixel,
271 const int widthPixel =
static_cast<int>( extent.
width() / mapUnitsPerPixel );
272 const int heightPixel =
static_cast<int>( extent.
height() / mapUnitsPerPixel );
287 const QVector<double> magnitudes = QgsMeshLayerUtils::calculateMagnitudes( datasetValues );
289 QgsMeshLayerInterpolator interpolator(
295 QSize( widthPixel, heightPixel )
298 return interpolator.block( 0, extent, widthPixel, heightPixel, feedback );