diff --git a/python/PyQt6/core/auto_generated/mesh/qgsmeshdataset.sip.in b/python/PyQt6/core/auto_generated/mesh/qgsmeshdataset.sip.in index 5df433842ae..f25cc96e330 100644 --- a/python/PyQt6/core/auto_generated/mesh/qgsmeshdataset.sip.in +++ b/python/PyQt6/core/auto_generated/mesh/qgsmeshdataset.sip.in @@ -431,6 +431,13 @@ Constructs a valid metadata object QString name() const; %Docstring Returns name of the dataset group +%End + + QString parentGroup() const; +%Docstring +Returns the name of the dataset's parent group. + +.. versionadded:: 3.38 %End QString uri() const; diff --git a/python/core/auto_generated/mesh/qgsmeshdataset.sip.in b/python/core/auto_generated/mesh/qgsmeshdataset.sip.in index 16f891990df..7ad800e693e 100644 --- a/python/core/auto_generated/mesh/qgsmeshdataset.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshdataset.sip.in @@ -431,6 +431,13 @@ Constructs a valid metadata object QString name() const; %Docstring Returns name of the dataset group +%End + + QString parentGroup() const; +%Docstring +Returns the name of the dataset's parent group. + +.. versionadded:: 3.38 %End QString uri() const; diff --git a/src/core/mesh/qgsmeshdataset.cpp b/src/core/mesh/qgsmeshdataset.cpp index 56d5dc6830f..ed2667df8f7 100644 --- a/src/core/mesh/qgsmeshdataset.cpp +++ b/src/core/mesh/qgsmeshdataset.cpp @@ -19,6 +19,8 @@ #include "qgsmeshdataprovider.h" #include "qgsrectangle.h" #include "qgis.h" +#include +#include QgsMeshDatasetIndex::QgsMeshDatasetIndex( int group, int dataset ) : mGroupIndex( group ), mDatasetIndex( dataset ) @@ -142,6 +144,13 @@ QgsMeshDatasetGroupMetadata::QgsMeshDatasetGroupMetadata( const QString &name, , mReferenceTime( referenceTime ) , mIsTemporal( isTemporal ) { + const thread_local QRegularExpression parentGroupNameRegex( QStringLiteral( "^(.*):.*?$" ) ); + + const QRegularExpressionMatch parentGroupMatch = parentGroupNameRegex.match( mName ); + if ( parentGroupMatch.hasMatch() ) + { + mParentGroupName = parentGroupMatch.captured( 1 ); + } } QMap QgsMeshDatasetGroupMetadata::extraOptions() const @@ -169,7 +178,13 @@ QString QgsMeshDatasetGroupMetadata::name() const return mName; } -QgsMeshDatasetGroupMetadata::DataType QgsMeshDatasetGroupMetadata::dataType() const +QString QgsMeshDatasetGroupMetadata::parentGroup() const +{ + return mParentGroupName; +} + +QgsMeshDatasetGroupMetadata::DataType +QgsMeshDatasetGroupMetadata::dataType() const { return mDataType; } diff --git a/src/core/mesh/qgsmeshdataset.h b/src/core/mesh/qgsmeshdataset.h index ee0d34c9df9..6218fb4cb7c 100644 --- a/src/core/mesh/qgsmeshdataset.h +++ b/src/core/mesh/qgsmeshdataset.h @@ -397,6 +397,13 @@ class CORE_EXPORT QgsMeshDatasetGroupMetadata */ QString name() const; + /** + * Returns the name of the dataset's parent group. + * + * \since QGIS 3.38 + */ + QString parentGroup() const; + /** * Returns the uri of the source * @@ -457,6 +464,7 @@ class CORE_EXPORT QgsMeshDatasetGroupMetadata private: QString mName; + QString mParentGroupName; QString mUri; bool mIsScalar = false; DataType mDataType = DataType::DataOnFaces; diff --git a/src/core/mesh/qgsmeshlayerrenderer.cpp b/src/core/mesh/qgsmeshlayerrenderer.cpp index 655d10e12a9..d494a133c5d 100644 --- a/src/core/mesh/qgsmeshlayerrenderer.cpp +++ b/src/core/mesh/qgsmeshlayerrenderer.cpp @@ -99,28 +99,47 @@ QgsMeshLayerRenderer::QgsMeshLayerRenderer( case Qgis::MeshElevationMode::FixedRangePerGroup: { - // find the top-most group which matches the map range - int currentMatchingGroup = -1; - QgsDoubleRange currentMatchingRange; + // find the top-most group which matches the map range and parent group + int currentMatchingVectorGroup = -1; + int currentMatchingScalarGroup = -1; + QgsDoubleRange currentMatchingVectorRange; + QgsDoubleRange currentMatchingScalarRange; + const QMap rangePerGroup = elevProp->fixedRangePerGroup(); + + const int activeVectorDatasetGroup = mRendererSettings.activeVectorDatasetGroup(); + const int activeScalarDatasetGroup = mRendererSettings.activeScalarDatasetGroup(); + for ( auto it = rangePerGroup.constBegin(); it != rangePerGroup.constEnd(); ++it ) { if ( it.value().overlaps( context.zRange() ) ) { - if ( currentMatchingRange.isInfinite() - || ( it.value().includeUpper() && it.value().upper() >= currentMatchingRange.upper() ) - || ( !currentMatchingRange.includeUpper() && it.value().upper() >= currentMatchingRange.upper() ) ) + const bool matchesVectorParentGroup = QgsMeshLayerUtils::haveSameParentGroup( layer, QgsMeshDatasetIndex( activeVectorDatasetGroup ), QgsMeshDatasetIndex( it.key() ) ); + const bool matchesScalarParentGroup = QgsMeshLayerUtils::haveSameParentGroup( layer, QgsMeshDatasetIndex( activeScalarDatasetGroup ), QgsMeshDatasetIndex( it.key() ) ); + + if ( matchesVectorParentGroup && ( + currentMatchingVectorRange.isInfinite() + || ( it.value().includeUpper() && it.value().upper() >= currentMatchingVectorRange.upper() ) + || ( !currentMatchingVectorRange.includeUpper() && it.value().upper() >= currentMatchingVectorRange.upper() ) ) ) { - currentMatchingGroup = it.key(); - currentMatchingRange = it.value(); + currentMatchingVectorGroup = it.key(); + currentMatchingVectorRange = it.value(); + } + + if ( matchesScalarParentGroup && ( + currentMatchingScalarRange.isInfinite() + || ( it.value().includeUpper() && it.value().upper() >= currentMatchingScalarRange.upper() ) + || ( !currentMatchingScalarRange.includeUpper() && it.value().upper() >= currentMatchingScalarRange.upper() ) ) ) + { + currentMatchingScalarGroup = it.key(); + currentMatchingScalarRange = it.value(); } } } - if ( currentMatchingGroup >= 0 ) - { - mRendererSettings.setActiveScalarDatasetGroup( currentMatchingGroup ); - mRendererSettings.setActiveVectorDatasetGroup( currentMatchingGroup ); - } + if ( currentMatchingVectorGroup >= 0 ) + mRendererSettings.setActiveVectorDatasetGroup( currentMatchingVectorGroup ); + if ( currentMatchingScalarGroup >= 0 ) + mRendererSettings.setActiveScalarDatasetGroup( currentMatchingScalarGroup ); } } } diff --git a/src/core/mesh/qgsmeshlayerutils.cpp b/src/core/mesh/qgsmeshlayerutils.cpp index e6c00b840f3..a5398f0abbc 100644 --- a/src/core/mesh/qgsmeshlayerutils.cpp +++ b/src/core/mesh/qgsmeshlayerutils.cpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include "qgsmeshlayerutils.h" #include "qgsmeshtimesettings.h" @@ -702,4 +704,17 @@ QVector QgsMeshLayerUtils::calculateNormals( const QgsTriangularMesh return normals; } +bool QgsMeshLayerUtils::haveSameParentGroup( const QgsMeshLayer *layer, const QgsMeshDatasetIndex &index1, const QgsMeshDatasetIndex &index2 ) +{ + const QgsMeshDatasetGroupMetadata metadata1 = layer->datasetGroupMetadata( index1 ); + if ( metadata1.parentGroup().isEmpty() ) + return false; + + const QgsMeshDatasetGroupMetadata metadata2 = layer->datasetGroupMetadata( index2 ); + if ( metadata2.parentGroup().isEmpty() ) + return false; + + return metadata1.parentGroup().compare( metadata2.parentGroup(), Qt::CaseInsensitive ) == 0; +} + ///@endcond diff --git a/src/core/mesh/qgsmeshlayerutils.h b/src/core/mesh/qgsmeshlayerutils.h index 2d25837692b..e15f182dd10 100644 --- a/src/core/mesh/qgsmeshlayerutils.h +++ b/src/core/mesh/qgsmeshlayerutils.h @@ -369,6 +369,14 @@ class CORE_EXPORT QgsMeshLayerUtils const QgsTriangularMesh &triangularMesh, const QVector &verticalMagnitude, bool isRelative ); + + /** + * Returns TRUE if the datasets from \a layer at \a index1 and \a index2 share the same parent group. + * + * \since QGIS 3.38 + */ + static bool haveSameParentGroup( const QgsMeshLayer *layer, const QgsMeshDatasetIndex &index1, const QgsMeshDatasetIndex &index2 ); + }; ///@endcond