Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mesh Render Extent Settings #59636

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions python/PyQt6/core/auto_additions/qgis.py
Original file line number Diff line number Diff line change
Expand Up @@ -11041,6 +11041,34 @@
"""
# --
Qgis.MouseHandlesAction.baseClass = Qgis
# monkey patching scoped based enum
Qgis.MeshRangeLimit.NotSet.__doc__ = "User defined"
Qgis.MeshRangeLimit.MinimumMaximum.__doc__ = "Real min-max values"
Qgis.MeshRangeLimit.__doc__ = """Describes the limits used to compute mesh ranges (min/max values).

.. versionadded:: 3.42

* ``NotSet``: User defined
* ``MinimumMaximum``: Real min-max values

"""
# --
Qgis.MeshRangeLimit.baseClass = Qgis
# monkey patching scoped based enum
Qgis.MeshRangeExtent.WholeMesh.__doc__ = "Whole mesh is used to compute statistics"
Qgis.MeshRangeExtent.FixedCanvas.__doc__ = "Current extent of the canvas (at the time of computation) is used to compute statistics"
Qgis.MeshRangeExtent.UpdatedCanvas.__doc__ = "Constantly updated extent of the canvas is used to compute statistics"
Qgis.MeshRangeExtent.__doc__ = """Describes the extent used to compute mesh ranges (min/max values).

.. versionadded:: 3.42

* ``WholeMesh``: Whole mesh is used to compute statistics
* ``FixedCanvas``: Current extent of the canvas (at the time of computation) is used to compute statistics
* ``UpdatedCanvas``: Constantly updated extent of the canvas is used to compute statistics

"""
# --
Qgis.MeshRangeExtent.baseClass = Qgis
try:
Qgis.__attribute_docs__ = {'QGIS_DEV_VERSION': 'The development version', 'DEFAULT_SEARCH_RADIUS_MM': 'Identify search radius in mm', 'DEFAULT_MAPTOPIXEL_THRESHOLD': 'Default threshold between map coordinates and device coordinates for map2pixel simplification', 'DEFAULT_HIGHLIGHT_COLOR': 'Default highlight color. The transparency is expected to only be applied to polygon\nfill. Lines and outlines are rendered opaque.', 'DEFAULT_HIGHLIGHT_BUFFER_MM': 'Default highlight buffer in mm.', 'DEFAULT_HIGHLIGHT_MIN_WIDTH_MM': 'Default highlight line/stroke minimum width in mm.', 'SCALE_PRECISION': 'Fudge factor used to compare two scales. The code is often going from scale to scale\ndenominator. So it looses precision and, when a limit is inclusive, can lead to errors.\nTo avoid that, use this factor instead of using <= or >=.\n\n.. deprecated:: 3.40\n\n No longer used by QGIS and will be removed in QGIS 4.0.', 'DEFAULT_Z_COORDINATE': 'Default Z coordinate value.\nThis value have to be assigned to the Z coordinate for the vertex.', 'DEFAULT_M_COORDINATE': 'Default M coordinate value.\nThis value have to be assigned to the M coordinate for the vertex.\n\n.. versionadded:: 3.20', 'UI_SCALE_FACTOR': 'UI scaling factor. This should be applied to all widget sizes obtained from font metrics,\nto account for differences in the default font sizes across different platforms.', 'DEFAULT_SNAP_TOLERANCE': 'Default snapping distance tolerance.', 'DEFAULT_SNAP_UNITS': 'Default snapping distance units.'}
Qgis.version = staticmethod(Qgis.version)
Expand Down
20 changes: 20 additions & 0 deletions python/PyQt6/core/auto_generated/mesh/qgsmeshlayer.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,26 @@ Sets labeling configuration. Takes ownership of the object.
.. versionadded:: 3.36
%End

bool minimumMaximumActiveScalarDataset( const QgsRectangle &extent, const QgsMeshDatasetIndex &datasetIndex, double &min /Out/, double &max /Out/ );
%Docstring
Extracts minimum and maximum value for active scalar dataset on mesh faces.

:param extent: extent in which intersecting faces are searched for
:param datasetIndex: index for which dataset the values should be extracted

:return: - ``True`` if values were extracted
- min: minimal value
- max: maximal value

.. versionadded:: 3.42
%End

QgsMeshDatasetIndex activeScalarDatasetIndex( QgsRenderContext &rendererContext );
%Docstring
Returns current active scalar dataset index for current renderer context.

.. versionadded:: 3.42
%End

public slots:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,34 @@ Returns the stroke width unit used to render edges scalar dataset
Sets the stroke width unit used to render edges scalar dataset

.. versionadded:: 3.14
%End

void setLimits( Qgis::MeshRangeLimit limits );
%Docstring
Sets the range limits type for minimum maximum calculation

.. versionadded:: 3.42
%End

Qgis::MeshRangeLimit limits() const;
%Docstring
Returns the range limits type for minimum maximum calculation

.. versionadded:: 3.42
%End

void setExtent( Qgis::MeshRangeExtent extent );
%Docstring
Sets the mesh extent for minimum maximum calculation

.. versionadded:: 3.42
%End

Qgis::MeshRangeExtent extent() const;
%Docstring
Returns the mesh extent for minimum maximum calculation

.. versionadded:: 3.42
%End

QDomElement writeXml( QDomDocument &doc, const QgsReadWriteContext &context = QgsReadWriteContext() ) const;
Expand Down
13 changes: 13 additions & 0 deletions python/PyQt6/core/auto_generated/qgis.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -3226,6 +3226,19 @@ The development version
NoAction
};

enum class MeshRangeLimit /BaseType=IntEnum/
{
NotSet,
MinimumMaximum,
};

enum class MeshRangeExtent /BaseType=IntEnum/
{
WholeMesh,
FixedCanvas,
UpdatedCanvas,
};

static const double DEFAULT_SEARCH_RADIUS_MM;

static const float DEFAULT_MAPTOPIXEL_THRESHOLD;
Expand Down
28 changes: 28 additions & 0 deletions python/core/auto_additions/qgis.py
Original file line number Diff line number Diff line change
Expand Up @@ -10951,6 +10951,34 @@
"""
# --
Qgis.MouseHandlesAction.baseClass = Qgis
# monkey patching scoped based enum
Qgis.MeshRangeLimit.NotSet.__doc__ = "User defined"
Qgis.MeshRangeLimit.MinimumMaximum.__doc__ = "Real min-max values"
Qgis.MeshRangeLimit.__doc__ = """Describes the limits used to compute mesh ranges (min/max values).

.. versionadded:: 3.42

* ``NotSet``: User defined
* ``MinimumMaximum``: Real min-max values

"""
# --
Qgis.MeshRangeLimit.baseClass = Qgis
# monkey patching scoped based enum
Qgis.MeshRangeExtent.WholeMesh.__doc__ = "Whole mesh is used to compute statistics"
Qgis.MeshRangeExtent.FixedCanvas.__doc__ = "Current extent of the canvas (at the time of computation) is used to compute statistics"
Qgis.MeshRangeExtent.UpdatedCanvas.__doc__ = "Constantly updated extent of the canvas is used to compute statistics"
Qgis.MeshRangeExtent.__doc__ = """Describes the extent used to compute mesh ranges (min/max values).

.. versionadded:: 3.42

* ``WholeMesh``: Whole mesh is used to compute statistics
* ``FixedCanvas``: Current extent of the canvas (at the time of computation) is used to compute statistics
* ``UpdatedCanvas``: Constantly updated extent of the canvas is used to compute statistics

"""
# --
Qgis.MeshRangeExtent.baseClass = Qgis
from enum import Enum


Expand Down
20 changes: 20 additions & 0 deletions python/core/auto_generated/mesh/qgsmeshlayer.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,26 @@ Sets labeling configuration. Takes ownership of the object.
.. versionadded:: 3.36
%End

bool minimumMaximumActiveScalarDataset( const QgsRectangle &extent, const QgsMeshDatasetIndex &datasetIndex, double &min /Out/, double &max /Out/ );
%Docstring
Extracts minimum and maximum value for active scalar dataset on mesh faces.

:param extent: extent in which intersecting faces are searched for
:param datasetIndex: index for which dataset the values should be extracted

:return: - ``True`` if values were extracted
- min: minimal value
- max: maximal value

.. versionadded:: 3.42
%End

QgsMeshDatasetIndex activeScalarDatasetIndex( QgsRenderContext &rendererContext );
%Docstring
Returns current active scalar dataset index for current renderer context.

.. versionadded:: 3.42
%End

public slots:

Expand Down
28 changes: 28 additions & 0 deletions python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,34 @@ Returns the stroke width unit used to render edges scalar dataset
Sets the stroke width unit used to render edges scalar dataset

.. versionadded:: 3.14
%End

void setLimits( Qgis::MeshRangeLimit limits );
%Docstring
Sets the range limits type for minimum maximum calculation

.. versionadded:: 3.42
%End

Qgis::MeshRangeLimit limits() const;
%Docstring
Returns the range limits type for minimum maximum calculation

.. versionadded:: 3.42
%End

void setExtent( Qgis::MeshRangeExtent extent );
%Docstring
Sets the mesh extent for minimum maximum calculation

.. versionadded:: 3.42
%End

Qgis::MeshRangeExtent extent() const;
%Docstring
Returns the mesh extent for minimum maximum calculation

.. versionadded:: 3.42
%End

QDomElement writeXml( QDomDocument &doc, const QgsReadWriteContext &context = QgsReadWriteContext() ) const;
Expand Down
13 changes: 13 additions & 0 deletions python/core/auto_generated/qgis.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -3226,6 +3226,19 @@ The development version
NoAction
};

enum class MeshRangeLimit
{
NotSet,
MinimumMaximum,
};

enum class MeshRangeExtent
{
WholeMesh,
FixedCanvas,
UpdatedCanvas,
};

static const double DEFAULT_SEARCH_RADIUS_MM;

static const float DEFAULT_MAPTOPIXEL_THRESHOLD;
Expand Down
14 changes: 14 additions & 0 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17171,6 +17171,20 @@ void QgisApp::handleRenderedLayerStatistics() const
rasterLayer->emitStyleChanged();
emit rasterLayer->rendererChanged();
}

QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( QgsProject::instance()->mapLayer( layerStatistics->layerId() ) );
if ( meshLayer )
{
QgsMeshRendererSettings rendererSettings = meshLayer->rendererSettings();
QgsMeshRendererScalarSettings scalarRendererSettings = rendererSettings.scalarSettings( rendererSettings.activeScalarDatasetGroup() );
scalarRendererSettings.setClassificationMinimumMaximum( layerStatistics->minimum( 0 ), layerStatistics->maximum( 0 ) );
rendererSettings.setScalarSettings( rendererSettings.activeScalarDatasetGroup(), scalarRendererSettings );
meshLayer->setRendererSettings( rendererSettings );

meshLayer->emitStyleChanged();
emit meshLayer->rendererChanged();
emit meshLayer->legendChanged();
}
}
}
}
89 changes: 89 additions & 0 deletions src/core/mesh/qgsmeshlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1664,6 +1664,95 @@ QgsMapLayerRenderer *QgsMeshLayer::createMapRenderer( QgsRenderContext &renderer
return new QgsMeshLayerRenderer( this, rendererContext );
}

QgsMeshDatasetIndex QgsMeshLayer::activeScalarDatasetIndex( QgsRenderContext &rendererContext )
{
if ( rendererContext.isTemporal() )
return activeScalarDatasetAtTime( rendererContext.temporalRange(), mRendererSettings.activeScalarDatasetGroup() );
else
return staticScalarDatasetIndex( mRendererSettings.activeScalarDatasetGroup() );

return QgsMeshDatasetIndex();
}

bool QgsMeshLayer::minimumMaximumActiveScalarDataset( const QgsRectangle &extent, const QgsMeshDatasetIndex &datasetIndex, double &min, double &max )
{

if ( extent.isNull() || !this->extent().intersects( extent ) )
return false;

QgsTriangularMesh *tMesh = triangularMesh();

QVector<double> scalarDatasetValues;
const QgsMeshDatasetGroupMetadata metadata = datasetGroupMetadata( datasetIndex.group() );

if ( !metadata.isScalar() )
{
return false;
}

QgsMeshDatasetGroupMetadata::DataType scalarDataType = QgsMeshLayerUtils::datasetValuesType( metadata.dataType() );

if ( !datasetIndex.isValid() )
{
return false;
}

// populate scalar values
const int count = QgsMeshLayerUtils::datasetValuesCount( mNativeMesh.get(), scalarDataType );
const QgsMeshDataBlock vals = QgsMeshLayerUtils::datasetValues(
this,
datasetIndex,
0,
count );

if ( vals.isValid() )
{
// vals could be scalar or vectors, for contour rendering we want always magnitude
scalarDatasetValues = QgsMeshLayerUtils::calculateMagnitudes( vals );
}
else
{
scalarDatasetValues = QVector<double>( count, std::numeric_limits<double>::quiet_NaN() );
}

QList<int> intersectedFacesIndices = tMesh->faceIndexesForRectangle( extent );

if ( intersectedFacesIndices.isEmpty() )
{
return false;
}

min = std::numeric_limits<double>::max();
max = -std::numeric_limits<double>::max();

double value;

for ( int intersectedFaceIndex : intersectedFacesIndices )
{
QgsMeshFace face = tMesh->triangles().at( intersectedFaceIndex );

if ( metadata.dataType() == QgsMeshDatasetGroupMetadata::DataType::DataOnFaces || metadata.dataType() == QgsMeshDatasetGroupMetadata::DataType::DataOnVolumes )
{
value = scalarDatasetValues.at( tMesh->trianglesToNativeFaces().at( intersectedFaceIndex ) );
min = std::min( min, value );
max = std::max( max, value );
}
else if ( metadata.dataType() == QgsMeshDatasetGroupMetadata::DataType::DataOnVertices )
{
QgsMeshVertex vertex;

for ( int vertexIndex : face )
{
value = scalarDatasetValues.at( vertexIndex );
min = std::min( min, value );
max = std::max( max, value );
}
}
}

return true;
}

QgsAbstractProfileGenerator *QgsMeshLayer::createProfileGenerator( const QgsProfileRequest &request )
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Expand Down
17 changes: 17 additions & 0 deletions src/core/mesh/qgsmeshlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,23 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer, public QgsAbstractProfileSo
*/
void setLabeling( QgsAbstractMeshLayerLabeling *labeling SIP_TRANSFER );

/**
* Extracts minimum and maximum value for active scalar dataset on mesh faces.
* \param extent extent in which intersecting faces are searched for
* \param datasetIndex index for which dataset the values should be extracted
* \param min minimal value
* \param max maximal value
* \return TRUE if values were extracted
* \since QGIS 3.42
*/
bool minimumMaximumActiveScalarDataset( const QgsRectangle &extent, const QgsMeshDatasetIndex &datasetIndex, double &min SIP_OUT, double &max SIP_OUT );

/**
* Returns current active scalar dataset index for current renderer context.
*
* \since QGIS 3.42
*/
QgsMeshDatasetIndex activeScalarDatasetIndex( QgsRenderContext &rendererContext );

public slots:

Expand Down
Loading