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 );
DataType
Raster data types.
@ Float64
Sixty four bit floating point (double)
This class represents a coordinate reference system (CRS).
Contains information about the context in which a coordinate transform is executed.
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
QgsCoordinateReferenceSystem crs
Perform transforms between map coordinates and device coordinates.
QgsMeshDataBlock is a block of integers/doubles that can be used to retrieve: active flags (e....
bool isValid() const
Whether the block is valid.
virtual void populateMesh(QgsMesh *mesh) const =0
Populates the mesh vertices, edges and faces.
QgsMeshDatasetIndex is index that identifies the dataset group (e.g.
bool isValid() const
Returns whether index is valid, ie at least groups is set.
virtual QgsMeshDatasetGroupMetadata datasetGroupMetadata(int groupIndex) const =0
Returns dataset group metadata.
virtual QgsMeshDataBlock areFacesActive(QgsMeshDatasetIndex index, int faceIndex, int count) const =0
Returns whether the faces are active for particular dataset.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
A class to represent a 2D point.
Feedback object tailored for raster block reading.
Base class for processing filters like renderers, reprojector, resampler etc.
A rectangle specified with double values.
bool intersects(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle intersects with other rectangle.
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Contains information about the context of a rendering operation.
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
Triangular/Derived Mesh is mesh with vertices in map coordinates.
CORE_EXPORT QgsRasterBlock * exportRasterBlock(const QgsMeshLayer &layer, const QgsMeshDatasetIndex &datasetIndex, const QgsCoordinateReferenceSystem &destinationCrs, const QgsCoordinateTransformContext &transformContext, double mapUnitsPerPixel, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Exports mesh layer's dataset values as raster block.
QVector< int > QgsMeshFace
List of vertex indexes.