Skip to content
Permalink
Browse files

[FEATURE] Scalar/vector data in mesh data providers

Reading and processing scalar (e.g. water depth) and vector (e.g.
velocity) data from mesh data providers (e.g. MDAL)
  • Loading branch information
PeterPetrik committed May 9, 2018
1 parent bfbc64c commit 3154102aa6952c156f4c219ac1adba8f277b3748
@@ -10,8 +10,44 @@



typedef QgsPoint QgsMeshVertex; //xyz coords of vertex
typedef QVector<int> QgsMeshFace; //list of vertex indexes
typedef QgsPoint QgsMeshVertex;

typedef QVector<int> QgsMeshFace;

typedef QMap<QString, QString> QgsMeshDatasetMetadata;

class QgsMeshDatasetValue
{
%Docstring

QgsMeshDatasetValue is a vector or a scalar value on vertex or face of the mesh with
support of nodata values

.. versionadded:: 3.2
%End

%TypeHeaderCode
#include "qgsmeshdataprovider.h"
%End
public:
QgsMeshDatasetValue( double x,
double y );
QgsMeshDatasetValue( double scalar );
QgsMeshDatasetValue( );

~QgsMeshDatasetValue();
void setNodata( bool nodata = true );
bool isNodata() const;
bool isScalar() const;
double scalar() const; //length for vectors, value for scalars
void set( double scalar );
void setX( double x );
void setY( double y );
double x() const;
double y() const;
bool operator==( const QgsMeshDatasetValue &other ) const;

};

class QgsMeshSource /Abstract/
{
@@ -61,7 +97,61 @@ read on demand
%End
};

class QgsMeshDataProvider: QgsDataProvider, QgsMeshSource
class QgsMeshDatasetSource /Abstract/
{
%Docstring
Dataset is a collection of vector or scalar values on vertices or faces of the mesh

Base on the underlying data provider/format, whole dataset is either stored in memory or
read on demand

.. versionadded:: 3.2
%End

%TypeHeaderCode
#include "qgsmeshdataprovider.h"
%End
public:
virtual ~QgsMeshDatasetSource();

virtual bool addDataset( const QString &uri ) = 0;
%Docstring
Associate dataset with the mesh
%End

virtual int datasetCount() const = 0;
%Docstring
Return number of datasets loaded
%End

virtual bool datasetHasScalarData( int index ) const = 0;
%Docstring
Whether dataset has scalar data associated
%End

virtual bool datasetIsOnVertices( int index ) const = 0;
%Docstring
Whether dataset is on vertices
%End

virtual QgsMeshDatasetMetadata datasetMetadata( int index ) const = 0;
%Docstring
Return dataset metadata
%End

virtual QgsMeshDatasetValue datasetValue( int datasetIndex, int valueIndex ) const = 0;
%Docstring
Return value associated with the index from the dataset
%End

virtual bool datasetIsValid( int index ) const = 0;
%Docstring
Return whether dataset is valid
%End
};


class QgsMeshDataProvider: QgsDataProvider, QgsMeshSource, QgsMeshDatasetSource
{
%Docstring
Base class for providing data for :py:class:`QgsMeshLayer`
@@ -52,6 +52,8 @@ E.g. to create mesh with one quad and one triangle
);
QgsMeshLayer *scratchLayer = new QgsMeshLayer(uri, "My Scratch layer", "memory_mesh");

Add datasets by adding them through data provider, :py:func:`QgsMeshDatasetSource.addDataset`

\subsection mdal MDAL data provider (mdal)

Accesses data using the MDAL drivers (https://github.com/lutraconsulting/MDAL). The url
@@ -133,6 +135,9 @@ Returns a line symbol used for rendering of triangular (derived) mesh.
Toggle rendering of triangular (derived) mesh. Off by default
%End

void setActiveScalarDataset( int index = -1 );
void setActiveVectorDataset( int index = -1 );

private: // Private methods
QgsMeshLayer( const QgsMeshLayer &rhs );
};
@@ -16,6 +16,7 @@
***************************************************************************/

#include "qgsmeshdataprovider.h"
#include "qgis.h"

QgsMeshDataProvider::QgsMeshDataProvider( const QString &uri )
: QgsDataProvider( uri )
@@ -38,3 +39,100 @@ QgsRectangle QgsMeshDataProvider::extent() const
return rec;

}

QgsMeshDatasetValue::QgsMeshDatasetValue( double x, double y )
{
setX( x );
setY( y );
}

QgsMeshDatasetValue::QgsMeshDatasetValue( double scalar )
{
set( scalar );
}

void QgsMeshDatasetValue::setNodata( bool nodata )
{
mIsNodata = nodata;
}

bool QgsMeshDatasetValue::isNodata() const
{return mIsNodata;}

bool QgsMeshDatasetValue::isScalar() const
{
return mIsScalar;
}

double QgsMeshDatasetValue::scalar() const
{
if ( isNodata() )
{
return std::numeric_limits<double>::quiet_NaN();
}

if ( isScalar() )
{
return mX;
}
else
{
return std::sqrt( ( mX ) * ( mX ) + ( mY ) * ( mY ) );
}
}

void QgsMeshDatasetValue::set( double scalar )
{
setX( scalar );
mIsScalar = true;
}

void QgsMeshDatasetValue::setX( double x )
{
mX = x;
if ( std::isnan( x ) )
{
mIsNodata = true;
}
}

void QgsMeshDatasetValue::setY( double y )
{
mY = y;
if ( std::isnan( y ) )
{
mIsScalar = true;
}
}

double QgsMeshDatasetValue::x() const
{
return mX;
}

double QgsMeshDatasetValue::y() const
{
return mY;
}

bool QgsMeshDatasetValue::operator==( const QgsMeshDatasetValue &other ) const
{
bool equal = true;
if ( isNodata() )
equal = other.isNodata();
else
{
if ( isScalar() )
{
equal &= other.isScalar();
equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
}
else
{
equal &= !other.isScalar();
equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
equal &= qgsDoubleNear( other.y(), mY, 1E-8 );
}
}
return equal;
}
@@ -25,9 +25,54 @@

#include <QVector>
#include <QString>
#include <QMap>
#include <limits>

typedef QgsPoint QgsMeshVertex; //xyz coords of vertex
typedef QVector<int> QgsMeshFace; //list of vertex indexes
//! xyz coords of vertex
typedef QgsPoint QgsMeshVertex;

//! List of vertex indexes
typedef QVector<int> QgsMeshFace;

//! Dataset's metadata key:value map
typedef QMap<QString, QString> QgsMeshDatasetMetadata;

/**
* \ingroup core
*
* QgsMeshDatasetValue is a vector or a scalar value on vertex or face of the mesh with
* support of nodata values
*
* \since QGIS 3.2
*/
class CORE_EXPORT QgsMeshDatasetValue
{
Q_GADGET

public:
QgsMeshDatasetValue( double x,
double y );
QgsMeshDatasetValue( double scalar );
QgsMeshDatasetValue( ) = default;

~QgsMeshDatasetValue() = default;
void setNodata( bool nodata = true );
bool isNodata() const;
bool isScalar() const;
double scalar() const; //length for vectors, value for scalars
void set( double scalar );
void setX( double x );
void setY( double y ) ;
double x() const;
double y() const;
bool operator==( const QgsMeshDatasetValue &other ) const;

private:
double mX = std::numeric_limits<double>::quiet_NaN();
double mY = std::numeric_limits<double>::quiet_NaN();
bool mIsNodata = true;
bool mIsScalar = true;
};

/**
* \ingroup core
@@ -73,14 +118,66 @@ class CORE_EXPORT QgsMeshSource SIP_ABSTRACT

/**
* \ingroup core
* Base class for providing data for QgsMeshLayer
*
* Responsible for reading native mesh data
*
* \see QgsMeshSource
* \since QGIS 3.2
*/
class CORE_EXPORT QgsMeshDataProvider: public QgsDataProvider, public QgsMeshSource
* Dataset is a collection of vector or scalar values on vertices or faces of the mesh
*
* Base on the underlying data provider/format, whole dataset is either stored in memory or
* read on demand
*
* \since QGIS 3.2
*/
class CORE_EXPORT QgsMeshDatasetSource SIP_ABSTRACT
{
public:
//! Dtor
virtual ~QgsMeshDatasetSource() = default;

/**
* \brief Associate dataset with the mesh
*/
virtual bool addDataset( const QString &uri ) = 0;

/**
* \brief Return number of datasets loaded
*/
virtual int datasetCount() const = 0;

/**
* \brief Whether dataset has scalar data associated
*/
virtual bool datasetHasScalarData( int index ) const = 0;

/**
* \brief Whether dataset is on vertices
*/
virtual bool datasetIsOnVertices( int index ) const = 0;

/**
* \brief Return dataset metadata
*/
virtual QgsMeshDatasetMetadata datasetMetadata( int index ) const = 0;

/**
* \brief Return value associated with the index from the dataset
*/
virtual QgsMeshDatasetValue datasetValue( int datasetIndex, int valueIndex ) const = 0;

/**
* \brief Return whether dataset is valid
*/
virtual bool datasetIsValid( int index ) const = 0;
};


/**
* \ingroup core
* Base class for providing data for QgsMeshLayer
*
* Responsible for reading native mesh data
*
* \see QgsMeshSource
* \since QGIS 3.2
*/
class CORE_EXPORT QgsMeshDataProvider: public QgsDataProvider, public QgsMeshSource, public QgsMeshDatasetSource
{
Q_OBJECT

@@ -127,6 +127,20 @@ void QgsMeshLayer::toggleTriangularMeshRendering( bool toggle )
triggerRepaint();
}

void QgsMeshLayer::setActiveScalarDataset( int index )
{
Q_ASSERT( dataProvider()->datasetCount() > index );
if ( dataProvider()->datasetHasScalarData( index ) )
mActiveScalarDataset = index;
}

void QgsMeshLayer::setActiveVectorDataset( int index )
{
Q_ASSERT( dataProvider()->datasetCount() > index );
if ( !dataProvider()->datasetHasScalarData( index ) )
mActiveVectorDataset = index;
}

void QgsMeshLayer::fillNativeMesh()
{
Q_ASSERT( !mNativeMesh );

0 comments on commit 3154102

Please sign in to comment.
You can’t perform that action at this time.