24#include <QRegularExpression>
25#include <QRegularExpressionMatch>
69 if ( std::isnan( mY ) )
73 else if ( std::isnan( mX ) )
75 return std::numeric_limits<double>::quiet_NaN();
79 return std::sqrt( ( mX ) * ( mX ) + ( mY ) * ( mY ) );
110 bool equal = std::isnan( mX ) == std::isnan( other.
x() );
111 equal &= std::isnan( mY ) == std::isnan( other.
y() );
115 if ( std::isnan( mY ) )
134 int maximumVerticalLevels,
145 , mMaximumVerticalLevelsCount( maximumVerticalLevels )
151 const thread_local QRegularExpression parentQuantityRegex( QStringLiteral(
"^(.*):.*?$" ) );
152 const QRegularExpressionMatch parentQuantityMatch = parentQuantityRegex.match( mName );
153 if ( parentQuantityMatch.hasMatch() )
155 mParentQuantityName = parentQuantityMatch.captured( 1 );
161 return mExtraOptions;
186 return mParentQuantityName;
197 return mMinimumValue;
202 return mMaximumValue;
207 return mMaximumVerticalLevelsCount;
212 return mReferenceTime;
225 int maximumVerticalLevels )
230 , mMaximumVerticalLevelsCount( maximumVerticalLevels )
246 return mMinimumValue;
251 return mMaximumValue;
256 return mMaximumVerticalLevelsCount;
282 return (
count() > 0 ) && ( mIsValid );
296 mDoubleBuffer[2 * index],
297 mDoubleBuffer[2 * index + 1]
308 if ( mIntegerBuffer.empty() )
311 return bool( mIntegerBuffer[index] );
317 Q_ASSERT( vals.size() ==
count() );
319 mIntegerBuffer = vals;
326 return mIntegerBuffer;
333 return mDoubleBuffer;
341 mDoubleBuffer = vals;
355 : mSize( other.mSize )
356 , mIsValid( other.mIsValid )
357 , mIsVector( other.mIsVector )
358 , mVerticalLevelsCount( other.mVerticalLevelsCount )
359 , mVerticalLevels( other.mVerticalLevels )
360 , mFaceToVolumeIndex( other.mFaceToVolumeIndex )
361 , mDoubleBuffer( other.mDoubleBuffer )
367 : mSize( other.mSize )
368 , mIsValid( other.mIsValid )
369 , mIsVector( other.mIsVector )
370 , mVerticalLevelsCount( std::move( other.mVerticalLevelsCount ) )
371 , mVerticalLevels( std::move( other.mVerticalLevels ) )
372 , mFaceToVolumeIndex( std::move( other.mFaceToVolumeIndex ) )
373 , mDoubleBuffer( std::move( other.mDoubleBuffer ) )
380 if ( &other ==
this )
384 mIsValid = other.mIsValid;
385 mIsVector = other.mIsVector;
386 mVerticalLevelsCount = other.mVerticalLevelsCount;
387 mVerticalLevels = other.mVerticalLevels;
388 mFaceToVolumeIndex = other.mFaceToVolumeIndex;
389 mDoubleBuffer = other.mDoubleBuffer;
395 if ( &other ==
this )
399 mIsValid = other.mIsValid;
400 mIsVector = other.mIsVector;
401 mVerticalLevelsCount = std::move( other.mVerticalLevelsCount );
402 mVerticalLevels = std::move( other.mVerticalLevels );
403 mFaceToVolumeIndex = std::move( other.mFaceToVolumeIndex );
404 mDoubleBuffer = std::move( other.mDoubleBuffer );
431 if ( mFaceToVolumeIndex.empty() )
433 return mFaceToVolumeIndex[0];
438 if ( mFaceToVolumeIndex.empty() || mVerticalLevelsCount.empty() )
440 const int lastVolumeStartIndex = mFaceToVolumeIndex[mFaceToVolumeIndex.size() - 1];
441 const int volumesCountInLastRow = mVerticalLevelsCount[mVerticalLevelsCount.size() - 1];
442 return lastVolumeStartIndex + volumesCountInLastRow;
453 return mVerticalLevelsCount;
471 return mVerticalLevels;
483 return mFaceToVolumeIndex;
489 return mDoubleBuffer;
501 mDoubleBuffer[2 * volumeIndex],
502 mDoubleBuffer[2 * volumeIndex + 1]
509 mDoubleBuffer = doubleBuffer;
523 , mSourceName( sourceName )
525 , mDatasetGroupIndex( index )
532 if ( itemElement.hasAttribute( QStringLiteral(
"display-name" ) ) )
533 mUserName = itemElement.attribute( QStringLiteral(
"display-name" ), mUserName );
535 if ( itemElement.hasAttribute( QStringLiteral(
"original-name" ) ) )
536 mOriginalName = itemElement.attribute( QStringLiteral(
"original-name" ), mOriginalName );
538 if ( itemElement.hasAttribute( QStringLiteral(
"source-name" ) ) )
539 mSourceName = itemElement.attribute( QStringLiteral(
"source-name" ), mSourceName );
541 if ( itemElement.hasAttribute( QStringLiteral(
"is-vector" ) ) )
542 mIsVector = itemElement.attribute( QStringLiteral(
"is-vector" ) ).toInt();
544 if ( itemElement.hasAttribute( QStringLiteral(
"dataset-index" ) ) )
545 mDatasetGroupIndex = itemElement.attribute( QStringLiteral(
"dataset-index" ) ).toInt();
547 if ( itemElement.hasAttribute( QStringLiteral(
"is-enabled" ) ) )
548 mIsEnabled = itemElement.attribute( QStringLiteral(
"is-enabled" ) ).toInt();
550 if ( itemElement.hasAttribute( QStringLiteral(
"dataset-group-type" ) ) )
551 mDatasetGroupType =
static_cast<QgsMeshDatasetGroup::Type>( itemElement.attribute( QStringLiteral(
"dataset-group-type" ) ) .toInt() ) ;
553 if ( itemElement.hasAttribute( QStringLiteral(
"description" ) ) )
554 mDescription = itemElement.attribute( QStringLiteral(
"description" ) );
556 QDomElement dependOnElement = itemElement.firstChildElement( QStringLiteral(
"dependent-on-item" ) );
557 while ( !dependOnElement.isNull() )
559 if ( dependOnElement.hasAttribute( QStringLiteral(
"dataset-index" ) ) )
560 mDatasetGroupDependentOn.append( dependOnElement.attribute( QStringLiteral(
"dataset-index" ) ).toInt() );
561 dependOnElement = dependOnElement.nextSiblingElement( QStringLiteral(
"dependent-on-item" ) );
564 QDomElement dependencyElement = itemElement.firstChildElement( QStringLiteral(
"dependency-item" ) );
565 while ( !dependencyElement.isNull() )
567 if ( dependencyElement.hasAttribute( QStringLiteral(
"dataset-index" ) ) )
568 mDatasetGroupDependencies.append( dependencyElement.attribute( QStringLiteral(
"dataset-index" ) ).toInt() );
569 dependencyElement = dependencyElement.nextSiblingElement( QStringLiteral(
"dependency-item" ) );
572 QDomElement childElement = itemElement.firstChildElement( QStringLiteral(
"mesh-dataset-group-tree-item" ) );
573 while ( !childElement.isNull() )
576 childElement = childElement.nextSiblingElement( QStringLiteral(
"mesh-dataset-group-tree-item" ) );
585 freeFromDependencies();
586 qDeleteAll( mChildren );
589 mParent->mDatasetGroupIndexToChild.remove( mDatasetGroupIndex );
590 mParent->mChildren.removeOne(
this );
599 other->mChildren.clear();
600 other->mDatasetGroupIndexToChild.clear();
601 if ( !mChildren.empty() )
602 for (
int i = 0; i < mChildren.count(); ++i )
610 mChildren.append( item );
611 item->mParent =
this;
622 if (
row < mChildren.count() )
623 return mChildren.at(
row );
630 if ( mDatasetGroupIndexToChild.empty() )
633 const QMap<int, QgsMeshDatasetGroupTreeItem *>::iterator it = mDatasetGroupIndexToChild.find( index );
635 if ( it != mDatasetGroupIndexToChild.end() )
640 for (
int i = 0; i < mChildren.count(); ++i )
652 return mChildren.count();
658 for (
int i = 0; i < mChildren.count(); ++i )
661 count += mChildren.at( i )->totalChildCount();
668 QList<int> indexesList;
670 for (
int i = 0; i < mChildren.count(); ++i )
672 if ( mChildren.at( i )->isEnabled() )
673 indexesList.append( mChildren.at( i )->datasetGroupIndex() );
674 indexesList.append( mChildren.at( i )->enabledDatasetGroupIndexes() );
695 if ( mUserName.isEmpty() )
696 return mOriginalName;
708 return mDatasetGroupIndex;
718 mIsEnabled = enabled;
723 return mOriginalName;
728 return mDatasetGroupType;
741 mDatasetGroupType = datasetGroup->
type();
743 for (
const QString &varName : datasetGroupNames )
758 mDatasetGroupDependentOn.clear();
766 QDomElement itemElement = doc.createElement( QStringLiteral(
"mesh-dataset-group-tree-item" ) );
767 itemElement.setAttribute( QStringLiteral(
"display-name" ), mUserName );
768 itemElement.setAttribute( QStringLiteral(
"source-name" ), mSourceName );
769 itemElement.setAttribute( QStringLiteral(
"original-name" ), mOriginalName );
770 itemElement.setAttribute( QStringLiteral(
"is-vector" ), mIsVector ?
true :
false );
771 itemElement.setAttribute( QStringLiteral(
"dataset-index" ), mDatasetGroupIndex );
772 itemElement.setAttribute( QStringLiteral(
"is-enabled" ), mIsEnabled ?
true :
false );
773 itemElement.setAttribute( QStringLiteral(
"dataset-group-type" ), mDatasetGroupType );
774 itemElement.setAttribute( QStringLiteral(
"description" ), mDescription );
776 for (
const int index : mDatasetGroupDependentOn )
778 QDomElement dependOnElement = doc.createElement( QStringLiteral(
"dependent-on-item" ) );
779 dependOnElement.setAttribute( QStringLiteral(
"dataset-index" ), index );
780 itemElement.appendChild( dependOnElement );
783 for (
const int index : mDatasetGroupDependencies )
785 QDomElement dependencyElement = doc.createElement( QStringLiteral(
"dependency-item" ) );
786 dependencyElement.setAttribute( QStringLiteral(
"dataset-index" ), index );
787 itemElement.appendChild( dependencyElement );
790 for (
int i = 0; i < mChildren.count(); ++i )
791 itemElement.appendChild( mChildren.at( i )->writeXml( doc, context ) );
798 QList<int> dependencies;
800 for (
const int index : mDatasetGroupDependencies )
802 if ( !dependencies.contains( index ) )
803 dependencies.append( index );
821 QList<QgsMeshDatasetGroupTreeItem *> itemToCheck;
822 itemToCheck.append( baseItem );
823 while ( baseItem && baseItem->
providerName() != sourceName && !itemToCheck.isEmpty() )
825 for (
int i = 0; i < baseItem->
childCount(); ++i )
826 itemToCheck.append( baseItem->
child( i ) );
827 itemToCheck.removeOne( baseItem );
828 if ( !itemToCheck.empty() )
829 baseItem = itemToCheck.first();
846void QgsMeshDatasetGroupTreeItem::freeAsDependency()
852 for (
const int index : mDatasetGroupDependentOn )
860void QgsMeshDatasetGroupTreeItem::freeFromDependencies()
863 for (
const int index : mDatasetGroupDependencies )
884 if ( valueIndex >= 0 && valueIndex <
values.count() )
885 return values[valueIndex];
893 QVector<double> buf( isScalar ? count : 2 * count );
894 for (
int i = 0; i < count; ++i )
896 const int idx = valueIndex + i;
897 if ( ( idx < 0 ) || ( idx >=
values.size() ) )
905 buf[2 * i] = val.
x();
906 buf[2 * i + 1] = val.
y();
918 ( faceIndex + count >
active.size() )
933 double min = std::numeric_limits<double>::max();
934 double max = std::numeric_limits<double>::lowest();
940 bool firstIteration =
true;
941 for (
int i = 0; i <
values.size(); ++i )
943 const double v =
values[i].scalar();
945 if ( std::isnan( v ) )
947 if ( firstIteration )
949 firstIteration =
false;
971 return active.at( faceIndex );
1012 if ( datasetIndex >= 0 && datasetIndex <
memoryDatasets.count() )
1048 return QDomElement();
1058 mIsStatisticObsolete =
true;
1063 return QStringList();
1073 mReferenceTime = referenceTime;
1076void QgsMeshDatasetGroup::updateStatistic()
const
1078 if ( !mIsStatisticObsolete )
1081 double min = std::numeric_limits<double>::max();
1082 double max = std::numeric_limits<double>::lowest();
1085 for (
int i = 0; i < count; ++i )
1088 min = std::min( min, meta.
minimum() );
1089 max = std::max( max, meta.
maximum() );
1094 mIsStatisticObsolete =
false;
1100 if (
dataset( i )->valuesCount() != count )
1177 if ( mMesh && valueIndex >= 0 && valueIndex < mMesh->vertexCount() )
1178 return mMesh->vertex( valueIndex ).z();
1180 return std::numeric_limits<double>::quiet_NaN();
1185 if ( !isScalar || !mMesh )
1189 int effectiveValueCount = std::min( count, ( mMesh->vertexCount() - valueIndex ) );
1190 QVector<double> values( effectiveValueCount );
1191 for (
int i = valueIndex; i < effectiveValueCount; ++i )
1192 values[i] = mMesh->vertex( i - valueIndex ).z();
1207 double min = std::numeric_limits<double>::max();
1208 double max = -std::numeric_limits<double>::max();
1210 for (
int i = 0; i < mMesh->vertexCount(); ++i )
1212 const double z = mMesh->vertex( i ).z();
1225 return mMesh->vertexCount();
1244 if ( datasetIndex != 0 )
1247 return mDataset->metadata();
1257 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()
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.
QgsMesh3DDataBlock & operator=(const QgsMesh3DDataBlock &other)
QVector< int > faceToVolumeIndex() const
Returns the indexing between faces and volumes.
QVector< double > verticalLevels() const
Returns the vertical levels height.
A block of integers/doubles from a mesh dataset.
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...
bool isVector() const
Return true if the dataset group is vector.
QString defaultName() const
Returns the default name.
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
Returns the dataset group index.
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.
bool isEnabled() const
Returns true if the item is enabled, i.e.
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
Returns the dataset group type.
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
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
Temporary dataset group in memory.
@ Persistent
Dataset group store in a file.
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(int group=-1, int dataset=-1)
Creates an index. -1 represents invalid group/dataset.
bool operator==(QgsMeshDatasetIndex other) const
bool operator!=(QgsMeshDatasetIndex other) const
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().
Represents a single mesh 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.
QgsMeshDatasetValue(double x, double y)
Constructor for vector value.
double x() const
Returns x value.
void setX(double x)
Sets X value.
Abstract class that represents a mesh dataset.
void addDataset(std::shared_ptr< QgsMeshMemoryDataset > dataset)
Adds a memory dataset to the group.
QgsMeshMemoryDatasetGroup()=default
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.
Represents a dataset with elevation value of the vertices of an existing mesh that can be edited.
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.
A container for the context for various read/write operations on 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.