39QgsMeshLayerInterpolator::QgsMeshLayerInterpolator(
41 const QVector<double> &datasetValues,
46 : mTriangularMesh( m ),
47 mDatasetValues( datasetValues ),
48 mActiveFaceFlagValues( activeFaceFlagValues ),
50 mDataType( dataType ),
55QgsMeshLayerInterpolator::~QgsMeshLayerInterpolator() =
default;
68int QgsMeshLayerInterpolator::bandCount()
const
76 const double noDataValue = std::numeric_limits<double>::quiet_NaN();
77 outputBlock->setNoDataValue( noDataValue );
78 outputBlock->setIsNoData();
79 double *data =
reinterpret_cast<double *
>( outputBlock->bits() );
81 QList<int> spatialIndexTriangles;
83 if ( mSpatialIndexActive )
85 spatialIndexTriangles = mTriangularMesh.faceIndexesForRectangle( extent );
86 indexCount = spatialIndexTriangles.count();
90 indexCount = mTriangularMesh.triangles().count();
93 if ( mTriangularMesh.contains( QgsMesh::ElementType::Edge ) )
95 return outputBlock.release();
98 const QVector<QgsMeshVertex> &vertices = mTriangularMesh.vertices();
101 if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
102 Q_ASSERT( mDatasetValues.count() == mTriangularMesh.vertices().count() );
104 for (
int i = 0; i < indexCount; ++i )
109 if ( mContext.renderingStopped() )
113 if ( mSpatialIndexActive )
114 triangleIndex = spatialIndexTriangles[i];
118 const QgsMeshFace &face = mTriangularMesh.triangles()[triangleIndex];
120 if ( face.isEmpty() )
123 const int v1 = face[0], v2 = face[1], v3 = face[2];
124 const QgsPointXY &p1 = vertices[v1], &p2 = vertices[v2], &p3 = vertices[v3];
126 const int nativeFaceIndex = mTriangularMesh.trianglesToNativeFaces()[triangleIndex];
127 const bool isActive = mActiveFaceFlagValues.active( nativeFaceIndex );
131 const QgsRectangle bbox = QgsMeshLayerUtils::triangleBoundingBox( p1, p2, p3 );
136 int topLim, bottomLim, leftLim, rightLim;
137 QgsMeshLayerUtils::boundingBoxToScreenRectangle( mContext.mapToPixel(), mOutputSize, bbox, leftLim, rightLim, topLim, bottomLim );
139 double value( 0 ), value1( 0 ), value2( 0 ), value3( 0 );
140 const int faceIdx = mTriangularMesh.trianglesToNativeFaces()[triangleIndex];
142 if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
144 value1 = mDatasetValues[v1];
145 value2 = mDatasetValues[v2];
146 value3 = mDatasetValues[v3];
149 value = mDatasetValues[faceIdx];
152 for (
int j = topLim; j <= bottomLim; j++ )
154 double *line = data + ( j * width );
155 for (
int k = leftLim; k <= rightLim; k++ )
158 const QgsPointXY p = mContext.mapToPixel().toMapCoordinates( k, j );
159 if ( mDataType == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
160 val = QgsMeshLayerUtils::interpolateFromVerticesData(
170 val = QgsMeshLayerUtils::interpolateFromFacesData(
178 if ( !std::isnan( val ) )
181 outputBlock->setIsData( j, k );
187 if ( mRenderElevation )
190 if ( elevationMap && elevationMap->
isValid() )
191 elevationMap->
fillWithRasterBlock( outputBlock.get(), 0, 0, mElevationScale, mElevationOffset );
194 return outputBlock.release();
197void QgsMeshLayerInterpolator::setSpatialIndexActive(
bool active )
199 mSpatialIndexActive = active;
202void QgsMeshLayerInterpolator::setElevationMapSettings(
bool renderElevationMap,
double elevationScale,
double elevationOffset )
204 mRenderElevation = renderElevationMap;
205 mElevationScale = elevationScale;
206 mElevationOffset = elevationOffset;
216 double mapUnitsPerPixel,
226 const int widthPixel =
static_cast<int>( extent.
width() / mapUnitsPerPixel );
227 const int heightPixel =
static_cast<int>( extent.
height() / mapUnitsPerPixel );
243 std::unique_ptr<QgsMesh> nativeMesh = std::make_unique<QgsMesh>();
245 std::unique_ptr<QgsTriangularMesh> triangularMesh = std::make_unique<QgsTriangularMesh>();
246 triangularMesh->update( nativeMesh.get(), transform );
250 const int count = QgsMeshLayerUtils::datasetValuesCount( nativeMesh.get(), scalarDataType );
259 const QVector<double> datasetValues = QgsMeshLayerUtils::calculateMagnitudes( vals );
263 nativeMesh->faces.count() );
265 QgsMeshLayerInterpolator interpolator(
266 *( triangularMesh.get() ),
268 activeFaceFlagValues,
271 QSize( widthPixel, heightPixel )
274 return interpolator.block( 0, extent, widthPixel, heightPixel, feedback );
283 double mapUnitsPerPixel,
288 const int widthPixel =
static_cast<int>( extent.
width() / mapUnitsPerPixel );
289 const int heightPixel =
static_cast<int>( extent.
height() / mapUnitsPerPixel );
304 const QVector<double> magnitudes = QgsMeshLayerUtils::calculateMagnitudes( datasetValues );
306 QgsMeshLayerInterpolator interpolator(
312 QSize( widthPixel, heightPixel )
315 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.
Stores digital elevation model in a raster image which may get updated as a part of map layer renderi...
bool isValid() const
Returns whether the elevation map is valid.
void fillWithRasterBlock(QgsRasterBlock *block, int top, int left, double zScale=1.0, double offset=0.0)
Fills the elevation map with values contains in a raster block starting from position defined by top ...
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.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
QgsMeshDataBlock areFacesActive(const QgsMeshDatasetIndex &index, int faceIndex, int count) const
Returns whether the faces are active for particular dataset.
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
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.