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 QgsPointXY &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 );
134 double value( 0 ), value1( 0 ), value2( 0 ), value3( 0 );
135 const int faceIdx = mTriangularMesh.trianglesToNativeFaces()[triangleIndex];
137 if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
139 value1 = mDatasetValues[v1];
140 value2 = mDatasetValues[v2];
141 value3 = mDatasetValues[v3];
144 value = mDatasetValues[faceIdx];
147 for (
int j = topLim; j <= bottomLim; j++ )
149 double *line = data + ( j * width );
150 for (
int k = leftLim; k <= rightLim; k++ )
153 const QgsPointXY p = mContext.mapToPixel().toMapCoordinates( k, j );
154 if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
155 val = QgsMeshLayerUtils::interpolateFromVerticesData(
165 val = QgsMeshLayerUtils::interpolateFromFacesData(
173 if ( !std::isnan( val ) )
176 outputBlock->setIsData( j, k );
183 return outputBlock.release();
186 void QgsMeshLayerInterpolator::setSpatialIndexActive(
bool active ) {mSpatialIndexActive = active;}
195 double mapUnitsPerPixel,
205 int widthPixel =
static_cast<int>( extent.
width() / mapUnitsPerPixel );
206 int heightPixel =
static_cast<int>( extent.
height() / mapUnitsPerPixel );
222 std::unique_ptr<QgsMesh> nativeMesh = qgis::make_unique<QgsMesh>();
224 std::unique_ptr<QgsTriangularMesh> triangularMesh = qgis::make_unique<QgsTriangularMesh>();
225 triangularMesh->update( nativeMesh.get(), transform );
229 const int count = QgsMeshLayerUtils::datasetValuesCount( nativeMesh.get(), scalarDataType );
238 QVector<double> datasetValues = QgsMeshLayerUtils::calculateMagnitudes( vals );
242 nativeMesh->faces.count() );
244 QgsMeshLayerInterpolator interpolator(
245 *( triangularMesh.get() ),
247 activeFaceFlagValues,
250 QSize( widthPixel, heightPixel )
253 return interpolator.block( 0, extent, widthPixel, heightPixel, feedback );
262 double mapUnitsPerPixel,
267 int widthPixel =
static_cast<int>( extent.
width() / mapUnitsPerPixel );
268 int heightPixel =
static_cast<int>( extent.
height() / mapUnitsPerPixel );
283 QVector<double> magnitudes = QgsMeshLayerUtils::calculateMagnitudes( datasetValues );
285 QgsMeshLayerInterpolator interpolator(
291 QSize( widthPixel, heightPixel )
294 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
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
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.