37 QgsMeshLayerInterpolator::QgsMeshLayerInterpolator(
39 const QVector<double> &datasetValues,
44 : mTriangularMesh( m ),
45 mDatasetValues( datasetValues ),
46 mActiveFaceFlagValues( activeFaceFlagValues ),
48 mDataType( dataType ),
53 QgsMeshLayerInterpolator::~QgsMeshLayerInterpolator() =
default;
66 int QgsMeshLayerInterpolator::bandCount()
const
74 const double noDataValue = std::numeric_limits<double>::quiet_NaN();
75 outputBlock->setNoDataValue( noDataValue );
76 outputBlock->setIsNoData();
77 double *data =
reinterpret_cast<double *
>( outputBlock->bits() );
79 QList<int> spatialIndexTriangles;
81 if ( mSpatialIndexActive )
83 spatialIndexTriangles = mTriangularMesh.faceIndexesForRectangle( extent );
84 indexCount = spatialIndexTriangles.count();
88 indexCount = mTriangularMesh.triangles().count();
91 if ( mTriangularMesh.contains( QgsMesh::ElementType::Edge ) )
93 return outputBlock.release();
96 const QVector<QgsMeshVertex> &vertices = mTriangularMesh.vertices();
99 if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
100 Q_ASSERT( mDatasetValues.count() == mTriangularMesh.vertices().count() );
102 for (
int i = 0; i < indexCount; ++i )
107 if ( mContext.renderingStopped() )
111 if ( mSpatialIndexActive )
112 triangleIndex = spatialIndexTriangles[i];
116 const QgsMeshFace &face = mTriangularMesh.triangles()[triangleIndex];
118 const int v1 = face[0], v2 = face[1], v3 = face[2];
119 const QgsPoint p1 = vertices[v1], p2 = vertices[v2], p3 = vertices[v3];
121 const int nativeFaceIndex = mTriangularMesh.trianglesToNativeFaces()[triangleIndex];
122 const bool isActive = mActiveFaceFlagValues.active( nativeFaceIndex );
126 QgsRectangle bbox = QgsMeshLayerUtils::triangleBoundingBox( p1, p2, p3 );
131 int topLim, bottomLim, leftLim, rightLim;
132 QgsMeshLayerUtils::boundingBoxToScreenRectangle( mContext.mapToPixel(), mOutputSize, bbox, leftLim, rightLim, topLim, bottomLim );
135 for (
int j = topLim; j <= bottomLim; j++ )
137 double *line = data + ( j * width );
138 for (
int k = leftLim; k <= rightLim; k++ )
141 const QgsPointXY p = mContext.mapToPixel().toMapCoordinates( k, j );
142 if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
143 val = QgsMeshLayerUtils::interpolateFromVerticesData(
153 const int faceIdx = mTriangularMesh.trianglesToNativeFaces()[triangleIndex];
154 val = QgsMeshLayerUtils::interpolateFromFacesData(
158 mDatasetValues[faceIdx],
162 if ( !std::isnan( val ) )
165 outputBlock->setIsData( j, k );
172 return outputBlock.release();
175 void QgsMeshLayerInterpolator::setSpatialIndexActive(
bool active ) {mSpatialIndexActive = active;}
184 double mapUnitsPerPixel,
194 int widthPixel =
static_cast<int>( extent.
width() / mapUnitsPerPixel );
195 int heightPixel =
static_cast<int>( extent.
height() / mapUnitsPerPixel );
211 std::unique_ptr<QgsMesh> nativeMesh = qgis::make_unique<QgsMesh>();
213 std::unique_ptr<QgsTriangularMesh> triangularMesh = qgis::make_unique<QgsTriangularMesh>();
214 triangularMesh->update( nativeMesh.get(), transform );
218 const int count = QgsMeshLayerUtils::datasetValuesCount( nativeMesh.get(), scalarDataType );
227 QVector<double> datasetValues = QgsMeshLayerUtils::calculateMagnitudes( vals );
231 nativeMesh->faces.count() );
233 QgsMeshLayerInterpolator interpolator(
234 *( triangularMesh.get() ),
236 activeFaceFlagValues,
239 QSize( widthPixel, heightPixel )
242 return interpolator.block( 0, extent, widthPixel, heightPixel, feedback );