22#include <QRegularExpression>
23#include <QRegularExpressionMatch>
26 : mGroupIndex( group ), mDatasetIndex( dataset )
67 if ( std::isnan( mY ) )
71 else if ( std::isnan( mX ) )
73 return std::numeric_limits<double>::quiet_NaN();
77 return std::sqrt( ( mX ) * ( mX ) + ( mY ) * ( mY ) );
108 bool equal = std::isnan( mX ) == std::isnan( other.
x() );
109 equal &= std::isnan( mY ) == std::isnan( other.
y() );
113 if ( std::isnan( mY ) )
132 int maximumVerticalLevels,
133 const QDateTime &referenceTime,
135 const QMap<QString, QString> &extraOptions )
138 , mIsScalar( isScalar )
139 , mDataType( dataType )
140 , mMinimumValue( minimum )
141 , mMaximumValue( maximum )
142 , mExtraOptions( extraOptions )
143 , mMaximumVerticalLevelsCount( maximumVerticalLevels )
144 , mReferenceTime( referenceTime )
145 , mIsTemporal( isTemporal )
149 const thread_local QRegularExpression parentQuantityRegex( QStringLiteral(
"^(.*):.*?$" ) );
150 const QRegularExpressionMatch parentQuantityMatch = parentQuantityRegex.match( mName );
151 if ( parentQuantityMatch.hasMatch() )
153 mParentQuantityName = parentQuantityMatch.captured( 1 );
159 return mExtraOptions;
184 return mParentQuantityName;
195 return mMinimumValue;
200 return mMaximumValue;
205 return mMaximumVerticalLevelsCount;
210 return mReferenceTime;
223 int maximumVerticalLevels )
225 , mIsValid( isValid )
226 , mMinimumValue( minimum )
227 , mMaximumValue( maximum )
228 , mMaximumVerticalLevelsCount( maximumVerticalLevels )
244 return mMinimumValue;
249 return mMaximumValue;
254 return mMaximumVerticalLevelsCount;
258 : mType( ActiveFlagInteger )
280 return (
count() > 0 ) && ( mIsValid );
294 mDoubleBuffer[2 * index],
295 mDoubleBuffer[2 * index + 1]
306 if ( mIntegerBuffer.empty() )
309 return bool( mIntegerBuffer[index] );
315 Q_ASSERT( vals.size() ==
count() );
317 mIntegerBuffer = vals;
324 return mIntegerBuffer;
331 return mDoubleBuffer;
339 mDoubleBuffer = vals;
354 , mIsVector( isVector )
375 if ( mFaceToVolumeIndex.empty() )
377 return mFaceToVolumeIndex[0];
382 if ( mFaceToVolumeIndex.empty() || mVerticalLevelsCount.empty() )
384 const int lastVolumeStartIndex = mFaceToVolumeIndex[mFaceToVolumeIndex.size() - 1];
385 const int volumesCountInLastRow = mVerticalLevelsCount[mVerticalLevelsCount.size() - 1];
386 return lastVolumeStartIndex + volumesCountInLastRow;
397 return mVerticalLevelsCount;
415 return mVerticalLevels;
427 return mFaceToVolumeIndex;
433 return mDoubleBuffer;
445 mDoubleBuffer[2 * volumeIndex],
446 mDoubleBuffer[2 * volumeIndex + 1]
453 mDoubleBuffer = doubleBuffer;
466 : mOriginalName( defaultName )
467 , mSourceName( sourceName )
468 , mIsVector( isVector )
469 , mDatasetGroupIndex( index )
476 if ( itemElement.hasAttribute( QStringLiteral(
"display-name" ) ) )
477 mUserName = itemElement.attribute( QStringLiteral(
"display-name" ), mUserName );
479 if ( itemElement.hasAttribute( QStringLiteral(
"original-name" ) ) )
480 mOriginalName = itemElement.attribute( QStringLiteral(
"original-name" ), mOriginalName );
482 if ( itemElement.hasAttribute( QStringLiteral(
"source-name" ) ) )
483 mSourceName = itemElement.attribute( QStringLiteral(
"source-name" ), mSourceName );
485 if ( itemElement.hasAttribute( QStringLiteral(
"is-vector" ) ) )
486 mIsVector = itemElement.attribute( QStringLiteral(
"is-vector" ) ).toInt();
488 if ( itemElement.hasAttribute( QStringLiteral(
"dataset-index" ) ) )
489 mDatasetGroupIndex = itemElement.attribute( QStringLiteral(
"dataset-index" ) ).toInt();
491 if ( itemElement.hasAttribute( QStringLiteral(
"is-enabled" ) ) )
492 mIsEnabled = itemElement.attribute( QStringLiteral(
"is-enabled" ) ).toInt();
494 if ( itemElement.hasAttribute( QStringLiteral(
"dataset-group-type" ) ) )
495 mDatasetGroupType =
static_cast<QgsMeshDatasetGroup::Type>( itemElement.attribute( QStringLiteral(
"dataset-group-type" ) ) .toInt() ) ;
497 if ( itemElement.hasAttribute( QStringLiteral(
"description" ) ) )
498 mDescription = itemElement.attribute( QStringLiteral(
"description" ) );
500 QDomElement dependOnElement = itemElement.firstChildElement( QStringLiteral(
"dependent-on-item" ) );
501 while ( !dependOnElement.isNull() )
503 if ( dependOnElement.hasAttribute( QStringLiteral(
"dataset-index" ) ) )
504 mDatasetGroupDependentOn.append( dependOnElement.attribute( QStringLiteral(
"dataset-index" ) ).toInt() );
505 dependOnElement = dependOnElement.nextSiblingElement( QStringLiteral(
"dependent-on-item" ) );
508 QDomElement dependencyElement = itemElement.firstChildElement( QStringLiteral(
"dependency-item" ) );
509 while ( !dependencyElement.isNull() )
511 if ( dependencyElement.hasAttribute( QStringLiteral(
"dataset-index" ) ) )
512 mDatasetGroupDependencies.append( dependencyElement.attribute( QStringLiteral(
"dataset-index" ) ).toInt() );
513 dependencyElement = dependencyElement.nextSiblingElement( QStringLiteral(
"dependency-item" ) );
516 QDomElement childElement = itemElement.firstChildElement( QStringLiteral(
"mesh-dataset-group-tree-item" ) );
517 while ( !childElement.isNull() )
520 childElement = childElement.nextSiblingElement( QStringLiteral(
"mesh-dataset-group-tree-item" ) );
529 freeFromDependencies();
530 qDeleteAll( mChildren );
533 mParent->mDatasetGroupIndexToChild.remove( mDatasetGroupIndex );
534 mParent->mChildren.removeOne(
this );
543 other->mChildren.clear();
544 other->mDatasetGroupIndexToChild.clear();
545 if ( !mChildren.empty() )
546 for (
int i = 0; i < mChildren.count(); ++i )
554 mChildren.append( item );
555 item->mParent =
this;
566 if (
row < mChildren.count() )
567 return mChildren.at(
row );
574 if ( mDatasetGroupIndexToChild.empty() )
577 const QMap<int, QgsMeshDatasetGroupTreeItem *>::iterator it = mDatasetGroupIndexToChild.find( index );
579 if ( it != mDatasetGroupIndexToChild.end() )
584 for (
int i = 0; i < mChildren.count(); ++i )
586 item = mChildren.at( i )->childFromDatasetGroupIndex( index );
596 return mChildren.count();
602 for (
int i = 0; i < mChildren.count(); ++i )
605 count += mChildren.at( i )->totalChildCount();
612 QList<int> indexesList;
614 for (
int i = 0; i < mChildren.count(); ++i )
616 if ( mChildren.at( i )->isEnabled() )
617 indexesList.append( mChildren.at( i )->datasetGroupIndex() );
618 indexesList.append( mChildren.at( i )->enabledDatasetGroupIndexes() );
639 if ( mUserName.isEmpty() )
640 return mOriginalName;
652 return mDatasetGroupIndex;
662 mIsEnabled = enabled;
667 return mOriginalName;
672 return mDatasetGroupType;
685 mDatasetGroupType = datasetGroup->
type();
687 for (
const QString &varName : datasetGroupNames )
702 mDatasetGroupDependentOn.clear();
710 QDomElement itemElement = doc.createElement( QStringLiteral(
"mesh-dataset-group-tree-item" ) );
711 itemElement.setAttribute( QStringLiteral(
"display-name" ), mUserName );
712 itemElement.setAttribute( QStringLiteral(
"source-name" ), mSourceName );
713 itemElement.setAttribute( QStringLiteral(
"original-name" ), mOriginalName );
714 itemElement.setAttribute( QStringLiteral(
"is-vector" ), mIsVector ?
true : false );
715 itemElement.setAttribute( QStringLiteral(
"dataset-index" ), mDatasetGroupIndex );
716 itemElement.setAttribute( QStringLiteral(
"is-enabled" ), mIsEnabled ? true : false );
717 itemElement.setAttribute( QStringLiteral(
"dataset-group-type" ), mDatasetGroupType );
718 itemElement.setAttribute( QStringLiteral(
"description" ), mDescription );
720 for (
const int index : mDatasetGroupDependentOn )
722 QDomElement dependOnElement = doc.createElement( QStringLiteral(
"dependent-on-item" ) );
723 dependOnElement.setAttribute( QStringLiteral(
"dataset-index" ), index );
724 itemElement.appendChild( dependOnElement );
727 for (
const int index : mDatasetGroupDependencies )
729 QDomElement dependencyElement = doc.createElement( QStringLiteral(
"dependency-item" ) );
730 dependencyElement.setAttribute( QStringLiteral(
"dataset-index" ), index );
731 itemElement.appendChild( dependencyElement );
734 for (
int i = 0; i < mChildren.count(); ++i )
735 itemElement.appendChild( mChildren.at( i )->writeXml( doc, context ) );
742 QList<int> dependencies;
744 for (
const int index : mDatasetGroupDependencies )
746 if ( !dependencies.contains( index ) )
747 dependencies.append( index );
765 QList<QgsMeshDatasetGroupTreeItem *> itemToCheck;
766 itemToCheck.append( baseItem );
767 while ( baseItem && baseItem->
providerName() != sourceName && !itemToCheck.isEmpty() )
769 for (
int i = 0; i < baseItem->
childCount(); ++i )
770 itemToCheck.append( baseItem->
child( i ) );
771 itemToCheck.removeOne( baseItem );
772 if ( !itemToCheck.empty() )
773 baseItem = itemToCheck.first();
790void QgsMeshDatasetGroupTreeItem::freeAsDependency()
793 for (
const int index : mDatasetGroupDependentOn )
801void QgsMeshDatasetGroupTreeItem::freeFromDependencies()
804 for (
const int index : mDatasetGroupDependencies )
825 if ( valueIndex >= 0 && valueIndex <
values.count() )
826 return values[valueIndex];
834 QVector<double> buf( isScalar ? count : 2 * count );
835 for (
int i = 0; i < count; ++i )
837 const int idx = valueIndex + i;
838 if ( ( idx < 0 ) || ( idx >=
values.size() ) )
846 buf[2 * i] = val.
x();
847 buf[2 * i + 1] = val.
y();
859 ( faceIndex + count >
active.size() )
874 double min = std::numeric_limits<double>::max();
875 double max = std::numeric_limits<double>::lowest();
881 bool firstIteration =
true;
882 for (
int i = 0; i <
values.size(); ++i )
884 const double v =
values[i].scalar();
886 if ( std::isnan( v ) )
888 if ( firstIteration )
890 firstIteration =
false;
912 return active.at( faceIndex );
989 return QDomElement();
999 mIsStatisticObsolete =
true;
1004 return QStringList();
1014 mReferenceTime = referenceTime;
1017void QgsMeshDatasetGroup::updateStatistic()
const
1019 if ( !mIsStatisticObsolete )
1022 double min = std::numeric_limits<double>::max();
1023 double max = std::numeric_limits<double>::lowest();
1026 for (
int i = 0; i < count; ++i )
1029 min = std::min( min, meta.
minimum() );
1030 max = std::max( max, meta.
maximum() );
1035 mIsStatisticObsolete =
false;
1047 : mName( name ), mDataType( dataType ) {}
1118 if ( mMesh && valueIndex >= 0 && valueIndex < mMesh->vertexCount() )
1119 return mMesh->
vertex( valueIndex ).
z();
1121 return std::numeric_limits<double>::quiet_NaN();
1126 if ( !isScalar || !mMesh )
1130 int effectiveValueCount = std::min( count, ( mMesh->
vertexCount() - valueIndex ) );
1131 QVector<double> values( effectiveValueCount );
1132 for (
int i = valueIndex; i < effectiveValueCount; ++i )
1133 values[i] = mMesh->
vertex( i - valueIndex ).
z();
1148 double min = std::numeric_limits<double>::max();
1149 double max = -std::numeric_limits<double>::max();
1153 const double z = mMesh->
vertex( i ).
z();
1185 if ( datasetIndex != 0 )
1188 return mDataset->metadata();
1198 return mDataset.get();
void setFaceToVolumeIndex(const QVector< int > &faceToVolumeIndex)
Sets the indexing between faces and volumes.
QgsMeshDatasetValue value(int volumeIndex) const
Returns the value at volume centers.
QVector< double > values() const
Returns the values at volume centers.
void setVerticalLevels(const QVector< double > &verticalLevels)
Sets the vertical levels height.
void setValues(const QVector< double > &doubleBuffer)
Sets the values at volume centers.
~QgsMesh3DDataBlock()
Dtor.
QgsMesh3DDataBlock()
Constructs an invalid block.
bool isVector() const
Whether we store vector values.
int count() const
Number of 2d faces for which the volume data is stored in the block.
int volumesCount() const
Returns number of volumes stored in the buffer.
int firstVolumeIndex() const
Index of the first volume stored in the buffer (absolute)
int lastVolumeIndex() const
Index of the last volume stored in the buffer (absolute)
QVector< int > verticalLevelsCount() const
Returns number of vertical level above 2d faces.
bool isValid() const
Whether the block is valid.
void setVerticalLevelsCount(const QVector< int > &verticalLevelsCount)
Sets the vertical level counts.
void setValid(bool valid)
Sets block validity.
QVector< int > faceToVolumeIndex() const
Returns the indexing between faces and volumes.
QVector< double > verticalLevels() const
Returns the vertical levels height.
QgsMeshDataBlock is a block of integers/doubles that can be used to retrieve: active flags (e....
QgsMeshDatasetValue value(int index) const
Returns a value represented by the index For active flag the behavior is undefined.
QVector< double > values() const
Returns buffer to the array with values For vector it is pairs (x1, y1, x2, y2, .....
void setActive(const QVector< int > &vals)
Sets active flag values.
QVector< int > active() const
Returns active flag array.
bool isValid() const
Whether the block is valid.
QgsMeshDataBlock()
Constructs an invalid block.
DataType type() const
Type of data stored in the block.
DataType
Type of data stored in the block.
@ ScalarDouble
Scalar double values.
@ Vector2DDouble
Vector double pairs (x1, y1, x2, y2, ... )
@ ActiveFlagInteger
Integer boolean flag whether face is active.
int count() const
Number of items stored in the block.
void setValues(const QVector< double > &vals)
Sets values.
void setValid(bool valid)
Sets block validity.
Tree item for display of the mesh dataset groups.
void setName(const QString &name)
Overrides the default name with the name to display.
QgsMeshDatasetGroupTreeItem * clone() const
Clones the item.
QList< int > groupIndexDependencies() const
Returns a list of group index corresponding to dataset group that depends on the dataset group repres...
QString defaultName() const
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context)
Writes the item and its children in a DOM document.
void setPersistentDatasetGroup(const QString &uri)
Set parameters of the item in accordance with the persistent dataset group with uri.
int childCount() const
Returns the count of children.
~QgsMeshDatasetGroupTreeItem()
Destructor, destructs also the children.
int datasetGroupIndex() const
QgsMeshDatasetGroupTreeItem * parentItem() const
Returns the parent item, nullptr if it is root item.
QgsMeshDatasetGroupTreeItem * childFromDatasetGroupIndex(int index)
Returns the child with dataset group index Searches as depper as needed on the child hierarchy.
void removeChild(QgsMeshDatasetGroupTreeItem *item)
Removes and destroy a item child if exists.
void setIsEnabled(bool isEnabled)
Sets whether the item is enabled, that is if it is displayed in view.
int totalChildCount() const
Returns the total count of children, that is included deeper children and disabled items.
void setDatasetGroup(QgsMeshDatasetGroup *datasetGroup)
Set parameters of the item in accordance with the dataset group.
QList< int > enabledDatasetGroupIndexes() const
Returns a list of enabled dataset group indexes, included deeper children.
QgsMeshDatasetGroupTreeItem()
Constructor for an empty dataset group tree item.
QString providerName() const
Returns the name used by the provider to identify the dataset.
void appendChild(QgsMeshDatasetGroupTreeItem *item)
Appends a child item.
QgsMeshDatasetGroupTreeItem * child(int row) const
Returns a child.
QString description() const
Returns description about the dataset group (URI, formula,...)
int row() const
Returns the position of the item in the parent.
QString name() const
Returns the name of the item This name is the default name if the name has not been overridden (.
QgsMeshDatasetGroup::Type datasetGroupType() const
Abstract class that represents a dataset group.
bool isScalar() const
Returns whether the group contain scalar values.
void addExtraMetadata(QString key, QString value)
Adds extra metadata to the group.
bool checkValueCountPerDataset(int count) const
Returns whether all the datasets contain count values.
virtual QgsMeshDatasetMetadata datasetMetadata(int datasetIndex) const =0
Returns the metadata of the dataset with index datasetIndex.
void setMinimumMaximum(double min, double max) const
Overrides the minimum and the maximum value of the whole dataset group.
void setStatisticObsolete() const
Sets statistic obsolete, that means statistic will be recalculated when requested.
void setIsScalar(bool isScalar)
Sets whether the group contain scalar values.
QgsMeshDatasetGroup()=default
Default constructor.
void setDataType(const QgsMeshDatasetGroupMetadata::DataType &dataType)
Sets the data type of the dataset group.
QString name() const
Returns the name of the dataset group.
QgsMeshDatasetGroupMetadata::DataType dataType() const
Returns the data type of the dataset group.
virtual ~QgsMeshDatasetGroup()
virtual QStringList datasetGroupNamesDependentOn() const
Returns the dataset group variable name which this dataset group depends on.
virtual QString description() const
Returns some information about the dataset group.
QMap< QString, QString > mMetadata
Type
Type of the dataset group.
@ Memory
Dataset group store in a file.
@ Persistent
Generic type used for non typed dataset group.
void setReferenceTime(const QDateTime &referenceTime)
Sets the reference time of the dataset group.
double maximum() const
Returns the maximum value of the whole dataset group.
virtual QgsMeshDatasetGroup::Type type() const =0
Returns the type of dataset group.
QgsMeshDatasetGroupMetadata groupMetadata() const
Returns the metadata of the dataset group.
double minimum() const
Returns the minimum value of the whole dataset group.
QMap< QString, QString > extraMetadata() const
Returns all the extra metadata of the group.
void setName(const QString &name)
Sets the name of the dataset group.
virtual int datasetCount() const =0
Returns the count of datasets in the group.
void calculateStatistic() const
Calculates the statistics (minimum and maximum)
virtual QgsMeshDataset * dataset(int index) const =0
Returns the dataset with index.
QgsMeshDatasetGroupMetadata::DataType mDataType
QgsMeshDatasetIndex is index that identifies the dataset group (e.g.
QgsMeshDatasetIndex(int group=-1, int dataset=-1)
Creates an index. -1 represents invalid group/dataset.
bool operator==(QgsMeshDatasetIndex other) const
Equality operator.
bool operator!=(QgsMeshDatasetIndex other) const
Inequality operator.
bool isValid() const
Returns whether index is valid, ie at least groups is set.
int group() const
Returns a group index.
int dataset() const
Returns a dataset index within group()
QgsMeshDatasetValue represents single dataset value.
void setY(double y)
Sets Y value.
void set(double scalar)
Sets scalar value.
double y() const
Returns y value.
bool operator==(QgsMeshDatasetValue other) const
QgsMeshDatasetValue()=default
Default Ctor, initialize to NaN.
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
double x() const
Returns x value.
void setX(double x)
Sets X value.
Abstract class that represents a dataset.
virtual int valuesCount() const =0
Returns the values count.
void addDataset(std::shared_ptr< QgsMeshMemoryDataset > dataset)
Adds a memory dataset to the group.
QgsMeshMemoryDatasetGroup()=default
Constructor.
QgsMeshDatasetMetadata datasetMetadata(int datasetIndex) const override
Returns the metadata of the dataset with index datasetIndex.
void clearDatasets()
Removes all the datasets from the group.
void initialize() override
Initialize the dataset group.
std::shared_ptr< const QgsMeshMemoryDataset > constDataset(int index) const
Returns the dataset with index.
QVector< std::shared_ptr< QgsMeshMemoryDataset > > memoryDatasets
Contains all the memory datasets.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const override
Returns a invalid DOM element.
QgsMeshDataset * dataset(int index) const override
Returns the dataset with index.
int datasetCount() const override
Returns the count of datasets in the group.
QgsMeshDataBlock areFacesActive(int faceIndex, int count) const override
Returns whether faces are active.
bool isActive(int faceIndex) const override
Returns whether the face is active.
QVector< QgsMeshDatasetValue > values
QgsMeshDatasetValue datasetValue(int valueIndex) const override
Returns the value with index valueIndex.
QgsMeshDatasetMetadata metadata() const override
Returns the metadata of the dataset.
QgsMeshDataBlock datasetValues(bool isScalar, int valueIndex, int count) const override
Returns count values from valueIndex.
int valuesCount() const override
Returns the values count.
void calculateMinMax()
Calculates the minimum and the maximum of this group.
int datasetCount() const override
Returns the count of datasets in the group.
QgsMeshVerticesElevationDatasetGroup(QString name, QgsMesh *mesh)
Constructor with a name and linked to mesh.
void initialize() override
Initialize the dataset group.
QgsMeshDatasetGroup::Type type() const override
Returns the type of dataset group.
QgsMeshDataset * dataset(int index) const override
Returns the dataset with index.
QgsMeshDatasetMetadata datasetMetadata(int datasetIndex) const override
Returns the metadata of the dataset with index datasetIndex.
Class that represents a dataset with elevation value of the vertices of a existing mesh that can be e...
QgsMeshDatasetValue datasetValue(int valueIndex) const override
Returns the value with index valueIndex.
int valuesCount() const override
Returns the values count.
QgsMeshDataBlock areFacesActive(int faceIndex, int count) const override
Returns whether faces are active.
QgsMeshDatasetMetadata metadata() const override
Returns the metadata of the dataset.
QgsMeshDataBlock datasetValues(bool isScalar, int valueIndex, int count) const override
Returns count values from valueIndex.
QgsMeshVerticesElevationDataset(QgsMesh *mesh)
Constructor.
The class is used as a container of context for various read/write operations on other objects.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Mesh - vertices, edges and faces.
int vertexCount() const
Returns number of vertices.
int faceCount() const
Returns number of faces.
QgsMeshVertex vertex(int index) const
Returns a vertex at the index.