49  mTriangularMesh.
update( &mNativeMesh );
 
 
   53  : mTriangularMesh( triangularMesh )
 
   54  , mNativeMesh( nativeMesh )
 
   55  , mDatasetValues( datasetValues )
 
   56  , mScalarActiveFaceFlagValues( scalarActiveFaceFlagValues )
 
 
   72  populateCache( index, method );
 
 
   79  if ( min_value > max_value )
 
   81    const double tmp = max_value;
 
   82    max_value = min_value;
 
   86  QVector<QgsGeometry> multiPolygon;
 
   89  const QVector<QgsMeshVertex> vertices = mTriangularMesh.
vertices();
 
   93  for ( 
int i = 0; i < mTriangularMesh.
triangles().size(); ++i )
 
   98    const int nativeIndex = trianglesToNativeFaces.at( i );
 
   99    if ( !mScalarActiveFaceFlagValues.
active( nativeIndex ) )
 
  103    const int indices[3] = {
 
  109    const QVector<QgsMeshVertex> coords = {
 
  110      vertices.at( indices[0] ),
 
  111      vertices.at( indices[1] ),
 
  112      vertices.at( indices[2] )
 
  115    const double values[3] = {
 
  116      mDatasetValues.at( indices[0] ),
 
  117      mDatasetValues.at( indices[1] ),
 
  118      mDatasetValues.at( indices[2] )
 
  122    if ( std::isnan( values[0] ) || std::isnan( values[1] ) || std::isnan( values[2] ) )
 
  126    if ( ( ( min_value > values[0] ) && ( min_value > values[1] ) && ( min_value > values[2] ) ) || ( ( max_value < values[0] ) && ( max_value < values[1] ) && ( max_value < values[2] ) ) )
 
  129    const bool valueInRange[3] = {
 
  130      ( min_value <= values[0] ) && ( max_value >= values[0] ),
 
  131      ( min_value <= values[1] ) && ( max_value >= values[1] ),
 
  132      ( min_value <= values[2] ) && ( max_value >= values[2] )
 
  136    if ( valueInRange[0] && valueInRange[1] && valueInRange[2] )
 
  138      QVector<QgsMeshVertex> ring = coords;
 
  139      ring.push_back( coords[0] );
 
  140      auto ext = std::make_unique<QgsLineString>( coords );
 
  141      auto poly = std::make_unique<QgsPolygon>();
 
  142      poly->setExteriorRing( ext.release() );
 
  143      multiPolygon.push_back( 
QgsGeometry( std::move( poly ) ) );
 
  148    QVector<QgsMeshVertex> ring;
 
  149    for ( 
int i = 0; i < 3; ++i )
 
  151      const int j = ( i + 1 ) % 3;
 
  153      if ( valueInRange[i] )
 
  155        if ( valueInRange[j] )
 
  158          if ( !ring.contains( coords[i] ) )
 
  159            ring.push_back( coords[i] );
 
  160          if ( !ring.contains( coords[j] ) )
 
  161            ring.push_back( coords[j] );
 
  166          if ( !ring.contains( coords[i] ) )
 
  167            ring.push_back( coords[i] );
 
  169          double value = max_value;
 
  170          if ( values[i] > values[j] )
 
  174          const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
 
  176          if ( !ring.contains( xy ) )
 
  177            ring.push_back( xy );
 
  182        if ( valueInRange[j] )
 
  185          double value = max_value;
 
  186          if ( values[i] < values[j] )
 
  191          const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
 
  193          if ( !ring.contains( xy ) )
 
  194            ring.push_back( xy );
 
  197          if ( !ring.contains( coords[j] ) )
 
  198            ring.push_back( coords[j] );
 
  204          double value1 = max_value;
 
  205          double value2 = max_value;
 
  206          if ( values[i] < values[j] )
 
  208            if ( ( min_value < values[i] ) || ( max_value > values[j] ) )
 
  216            if ( ( min_value < values[j] ) || ( max_value > values[i] ) )
 
  223          const double fraction1 = ( value1 - values[i] ) / ( values[j] - values[i] );
 
  225          if ( !ring.contains( xy1 ) )
 
  226            ring.push_back( xy1 );
 
  228          const double fraction2 = ( value2 - values[i] ) / ( values[j] - values[i] );
 
  230          if ( !ring.contains( xy2 ) )
 
  231            ring.push_back( xy2 );
 
  237    if ( ring.size() > 2 )
 
  239      auto ext = std::make_unique<QgsLineString>( ring );
 
  240      auto poly = std::make_unique<QgsPolygon>();
 
  241      poly->setExteriorRing( ext.release() );
 
  242      multiPolygon.push_back( 
QgsGeometry( std::move( poly ) ) );
 
  247  if ( multiPolygon.isEmpty() )
 
 
  264  populateCache( index, method );
 
 
  271  auto multiLineString = std::make_unique<QgsMultiLineString>();
 
  272  QSet<QPair<int, int>> exactEdges;
 
  275  const QVector<QgsMeshVertex> vertices = mTriangularMesh.
vertices();
 
  279  for ( 
int i = 0; i < mTriangularMesh.
triangles().size(); ++i )
 
  284    const int nativeIndex = trianglesToNativeFaces.at( i );
 
  285    if ( !mScalarActiveFaceFlagValues.
active( nativeIndex ) )
 
  290    const int indices[3] = {
 
  296    const QVector<QgsMeshVertex> coords = {
 
  297      vertices.at( indices[0] ),
 
  298      vertices.at( indices[1] ),
 
  299      vertices.at( indices[2] )
 
  302    const double values[3] = {
 
  303      mDatasetValues.at( indices[0] ),
 
  304      mDatasetValues.at( indices[1] ),
 
  305      mDatasetValues.at( indices[2] )
 
  309    if ( std::isnan( values[0] ) || std::isnan( values[1] ) || std::isnan( values[2] ) )
 
  313    if ( ( ( value > values[0] ) && ( value > values[1] ) && ( value > values[2] ) ) || ( ( value < values[0] ) && ( value < values[1] ) && ( value < values[2] ) ) )
 
  323    for ( 
int i = 0; i < 3; ++i )
 
  325      const int j = ( i + 1 ) % 3;
 
  327      if ( ( ( value > values[i] ) && ( value > values[j] ) ) || ( ( value < values[i] ) && ( value < values[j] ) ) )
 
  333        if ( exactEdges.contains( { indices[i], indices[j] } ) || exactEdges.contains( { indices[j], indices[i] } ) )
 
  339          exactEdges.insert( { indices[i], indices[j] } );
 
  340          auto line = std::make_unique<QgsLineString>( coords[i], coords[j] );
 
  341          multiLineString->addGeometry( line.release() );
 
  353      const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
 
  356      if ( std::isnan( tmp.
x() ) )
 
  364        auto line = std::make_unique<QgsLineString>( tmp, xy );
 
  365        multiLineString->addGeometry( line.release() );
 
  372  if ( multiLineString->isEmpty() )
 
 
  389  if ( mCachedIndex != index )
 
  392    const int count = scalarDataOnVertices ? mNativeMesh.
vertices.count() : mNativeMesh.
faces.count();
 
  404      mDatasetValues = QgsMeshLayerUtils::calculateMagnitudes( vals );
 
  408      mDatasetValues = QVector<double>( count, std::numeric_limits<double>::quiet_NaN() );
 
  415      mNativeMesh.
faces.count()
 
  419    if ( ( !scalarDataOnVertices ) )
 
  421      mDatasetValues = QgsMeshLayerUtils::interpolateFromFacesData(
 
  425        &mScalarActiveFaceFlagValues,
 
virtual bool isValid() const =0
Returns true if this is a valid layer.
 
Base class for feedback objects to be used for cancellation of something running in a worker thread.
 
bool isCanceled() const
Tells whether the operation has been canceled already.
 
static QgsPointXY interpolatePointOnLine(double x1, double y1, double x2, double y2, double fraction)
Interpolates the position of a point a fraction of the way along the line from (x1,...
 
A geometry is the spatial representation of a feature.
 
QgsGeometry mergeLines(const QgsGeometryParameters ¶meters=QgsGeometryParameters()) const
Merges any connected lines in a LineString/MultiLineString geometry and converts them to single line ...
 
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters ¶meters=QgsGeometryParameters())
Compute the unary union on a list of geometries.
 
QgsGeometry exportPolygons(const QgsMeshDatasetIndex &index, double min_value, double max_value, QgsMeshRendererScalarSettings::DataResamplingMethod method, QgsFeedback *feedback=nullptr)
Exports multi polygons representing the areas with values in range for particular dataset.
 
QgsGeometry exportLines(const QgsMeshDatasetIndex &index, double value, QgsMeshRendererScalarSettings::DataResamplingMethod method, QgsFeedback *feedback=nullptr)
Exports multi line string containing the contour line for particular dataset and value.
 
QgsMeshContours(QgsMeshLayer *layer)
Constructs the mesh contours exporter.
 
A block of integers/doubles from a mesh dataset.
 
bool isValid() const
Whether the block is valid.
 
bool active(int index) const
Returns a value for active flag by the index For scalar and vector 2d the behavior is undefined.
 
bool contains(const QgsMesh::ElementType &type) const
Returns whether the mesh contains at mesh elements of given type.
 
virtual void populateMesh(QgsMesh *mesh) const =0
Populates the mesh vertices, edges and faces.
 
An index that identifies the dataset group (e.g.
 
virtual QgsMeshDatasetGroupMetadata datasetGroupMetadata(int groupIndex) const =0
Returns dataset group metadata.
 
virtual QgsMeshDataBlock areFacesActive(QgsMeshDatasetIndex index, int faceIndex, int count) const =0
Returns whether the faces are active for particular dataset.
 
Represents a mesh layer supporting display of data on structured or unstructured meshes.
 
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
 
DataResamplingMethod
Resampling of value from dataset.
 
Point geometry type, with support for z-dimension and m-values.
 
A triangular/derived mesh with vertices in map coordinates.
 
const QVector< QgsMeshFace > & triangles() const
Returns triangles.
 
const QVector< QgsMeshVertex > & vertices() const
Returns vertices in map coordinate system.
 
bool update(QgsMesh *nativeMesh, const QgsCoordinateTransform &transform)
Constructs triangular mesh from layer's native mesh and transform to destination CRS.
 
const QVector< int > & trianglesToNativeFaces() const
Returns mapping between triangles and original faces.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
QVector< int > QgsMeshFace
List of vertex indexes.
 
Mesh - vertices, edges and faces.
 
QVector< QgsMeshVertex > vertices
 
QVector< QgsMeshFace > faces