introduce way for plugins to retreive 3d stacked data values [API]

This commit is contained in:
Peter Petrik 2019-12-13 16:30:14 +01:00
parent d20dd06334
commit 2564b021d8
6 changed files with 112 additions and 22 deletions

View File

@ -244,6 +244,7 @@ For scalar and vector 2d the behavior is undefined
QVector<double> values() const;
%Docstring
Returns buffer to the array with values
For vector it is pairs (x1, y1, x2, y2, ... )
.. versionadded:: 3.12
%End
@ -321,12 +322,12 @@ Number of 2d faces for which the volume data is stored in the block
int firstVolumeIndex() const;
%Docstring
Index of the first volume stored in the buffer
Index of the first volume stored in the buffer (absolute)
%End
int lastVolumeIndex() const;
%Docstring
Index of the last volume stored in the buffer
Index of the last volume stored in the buffer (absolute)
%End
int volumesCount() const;
@ -369,6 +370,15 @@ Sets the indexing between faces and volumes
Returns the values at volume centers
For vector datasets the number of values is doubled (x1, y1, x2, y2, ... )
%End
QgsMeshDatasetValue value( int volumeIndex ) const;
%Docstring
Returns the value at volume centers
:param volumeIndex: volume index relative to firstVolumeIndex()
:return: value (scalar or vector)
%End
void setValues( const QVector<double> &doubleBuffer );

View File

@ -201,6 +201,27 @@ Interpolates the value on the given point from given dataset.
.. versionadded:: 3.4
%End
QgsMesh3dDataBlock dataset3dValue( const QgsMeshDatasetIndex &index, const QgsPointXY &point ) const;
%Docstring
Returns the 3d values of stacked 3d mesh defined by the given point
.. note::
It uses previously cached and indexed triangular mesh
and so if the layer has not been rendered previously
(e.g. when used in a script) it returns NaN value
:param index: dataset index specifying group and dataset to extract value from
:param point: point to query in map coordinates
:return: all 3d stacked values that belongs to face defined by given point. Returns invalid block
for point outside the mesh layer or in case triangular mesh was not
previously used for rendering or for datasets that do not have type DataOnVolumes
.. versionadded:: 3.12
%End
public slots:

View File

@ -436,6 +436,20 @@ QVector<double> QgsMesh3dDataBlock::values() const
return mDoubleBuffer;
}
QgsMeshDatasetValue QgsMesh3dDataBlock::value( int volumeIndex ) const
{
if ( !isValid() )
return QgsMeshDatasetValue();
if ( !mIsVector )
return QgsMeshDatasetValue( mDoubleBuffer[volumeIndex] );
return QgsMeshDatasetValue(
mDoubleBuffer[2 * volumeIndex],
mDoubleBuffer[2 * volumeIndex + 1]
);
}
void QgsMesh3dDataBlock::setValues( const QVector<double> &doubleBuffer )
{
Q_ASSERT( doubleBuffer.size() == isVector() ? 2 * volumesCount() : volumesCount() );

View File

@ -227,6 +227,7 @@ class CORE_EXPORT QgsMeshDataBlock
/**
* Returns buffer to the array with values
* For vector it is pairs (x1, y1, x2, y2, ... )
*
* \since QGIS 3.12
*/
@ -291,10 +292,10 @@ class CORE_EXPORT QgsMesh3dDataBlock
//! Number of 2d faces for which the volume data is stored in the block
int count() const;
//! Index of the first volume stored in the buffer
//! Index of the first volume stored in the buffer (absolute)
int firstVolumeIndex() const;
//! Index of the last volume stored in the buffer
//! Index of the last volume stored in the buffer (absolute)
int lastVolumeIndex() const;
//! Returns number of volumes stored in the buffer
@ -337,6 +338,14 @@ class CORE_EXPORT QgsMesh3dDataBlock
*/
QVector<double> values() const;
/**
* Returns the value at volume centers
*
* \param volumeIndex volume index relative to firstVolumeIndex()
* \returns value (scalar or vector)
*/
QgsMeshDatasetValue value( int volumeIndex ) const;
/**
* Sets the values at volume centers
*

View File

@ -181,16 +181,14 @@ QgsMeshDatasetValue QgsMeshLayer::datasetValue( const QgsMeshDatasetIndex &index
{
int nativeFaceIndex = mTriangularMesh->trianglesToNativeFaces().at( faceIndex );
const QgsMeshDatasetGroupMetadata::DataType dataType = dataProvider()->datasetGroupMetadata( index ).dataType();
switch ( dataType )
if ( dataProvider()->isFaceActive( index, nativeFaceIndex ) )
{
case QgsMeshDatasetGroupMetadata::DataOnFaces:
if ( dataProvider()->isFaceActive( index, nativeFaceIndex ) )
{
switch ( dataType )
{
case QgsMeshDatasetGroupMetadata::DataOnFaces:
value = dataProvider()->datasetValue( index, nativeFaceIndex );
}
break;
case QgsMeshDatasetGroupMetadata::DataOnVertices:
if ( dataProvider()->isFaceActive( index, nativeFaceIndex ) )
break;
case QgsMeshDatasetGroupMetadata::DataOnVertices:
{
const QgsMeshFace &face = mTriangularMesh->triangles()[faceIndex];
const int v1 = face[0], v2 = face[1], v3 = face[2];
@ -207,18 +205,19 @@ QgsMeshDatasetValue QgsMeshLayer::datasetValue( const QgsMeshDatasetIndex &index
value = QgsMeshDatasetValue( x, y );
}
break;
case QgsMeshDatasetGroupMetadata::DataOnVolumes:
const QgsMesh3dAveragingMethod *avgMethod = mRendererSettings.averagingMethod();
if ( avgMethod )
{
const QgsMesh3dDataBlock block3d = dataProvider()->dataset3dValues( index, nativeFaceIndex, 1 );
const QgsMeshDataBlock block2d = avgMethod->calculate( block3d );
if ( block2d.active( 0 ) )
case QgsMeshDatasetGroupMetadata::DataOnVolumes:
const QgsMesh3dAveragingMethod *avgMethod = mRendererSettings.averagingMethod();
if ( avgMethod )
{
value = block2d.value( 0 );
const QgsMesh3dDataBlock block3d = dataProvider()->dataset3dValues( index, nativeFaceIndex, 1 );
const QgsMeshDataBlock block2d = avgMethod->calculate( block3d );
if ( block2d.isValid() )
{
value = block2d.value( 0 );
}
}
}
break;
break;
}
}
}
}
@ -226,6 +225,26 @@ QgsMeshDatasetValue QgsMeshLayer::datasetValue( const QgsMeshDatasetIndex &index
return value;
}
QgsMesh3dDataBlock QgsMeshLayer::dataset3dValue( const QgsMeshDatasetIndex &index, const QgsPointXY &point ) const
{
QgsMesh3dDataBlock block3d;
if ( mTriangularMesh && dataProvider() && dataProvider()->isValid() && index.isValid() )
{
const QgsMeshDatasetGroupMetadata::DataType dataType = dataProvider()->datasetGroupMetadata( index ).dataType();
if ( dataType == QgsMeshDatasetGroupMetadata::DataOnVolumes )
{
int faceIndex = mTriangularMesh->faceIndexForPoint( point ) ;
if ( faceIndex >= 0 )
{
int nativeFaceIndex = mTriangularMesh->trianglesToNativeFaces().at( faceIndex );
block3d = dataProvider()->dataset3dValues( index, nativeFaceIndex, 1 );
}
}
}
return block3d;
}
void QgsMeshLayer::setTransformContext( const QgsCoordinateTransformContext &transformContext )
{
if ( mDataProvider )

View File

@ -246,6 +246,23 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
*/
QgsMeshDatasetValue datasetValue( const QgsMeshDatasetIndex &index, const QgsPointXY &point ) const;
/**
* Returns the 3d values of stacked 3d mesh defined by the given point
*
* \note It uses previously cached and indexed triangular mesh
* and so if the layer has not been rendered previously
* (e.g. when used in a script) it returns NaN value
*
* \param index dataset index specifying group and dataset to extract value from
* \param point point to query in map coordinates
* \returns all 3d stacked values that belongs to face defined by given point. Returns invalid block
* for point outside the mesh layer or in case triangular mesh was not
* previously used for rendering or for datasets that do not have type DataOnVolumes
*
* \since QGIS 3.12
*/
QgsMesh3dDataBlock dataset3dValue( const QgsMeshDatasetIndex &index, const QgsPointXY &point ) const;
public slots:
/**