QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsmeshlayerutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmeshlayerutils.cpp
3  --------------------------
4  begin : August 2018
5  copyright : (C) 2018 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include <limits>
19 #include <QTime>
20 #include <QDateTime>
21 
22 #include "qgsmeshlayerutils.h"
23 #include "qgsmeshtimesettings.h"
24 #include "qgstriangularmesh.h"
25 #include "qgslogger.h"
26 #include "qgsmeshdataprovider.h"
27 #include "qgsmesh3daveraging.h"
28 #include "qgsmeshlayer.h"
29 
30 
32 
33 int QgsMeshLayerUtils::datasetValuesCount( const QgsMesh *mesh, QgsMeshDatasetGroupMetadata::DataType dataType )
34 {
35  if ( !mesh )
36  return 0;
37 
38  switch ( dataType )
39  {
40  case QgsMeshDatasetGroupMetadata::DataType::DataOnEdges:
41  return mesh->edgeCount();
42  case QgsMeshDatasetGroupMetadata::DataType::DataOnFaces:
43  return mesh->faceCount();
44  case QgsMeshDatasetGroupMetadata::DataType::DataOnVertices:
45  return mesh->vertexCount();
46  case QgsMeshDatasetGroupMetadata::DataType::DataOnVolumes:
47  return mesh->faceCount(); // because they are averaged to faces
48  }
49  return 0;
50 }
51 
52 QgsMeshDatasetGroupMetadata::DataType QgsMeshLayerUtils::datasetValuesType( const QgsMeshDatasetGroupMetadata::DataType &type )
53 {
54  // data on volumes are averaged to 2D data on faces
55  if ( type == QgsMeshDatasetGroupMetadata::DataType::DataOnVolumes )
56  return QgsMeshDatasetGroupMetadata::DataType::DataOnFaces;
57 
58  return type;
59 }
60 
61 QgsMeshDataBlock QgsMeshLayerUtils::datasetValues(
62  const QgsMeshLayer *meshLayer,
63  QgsMeshDatasetIndex index,
64  int valueIndex,
65  int count )
66 {
67  QgsMeshDataBlock block;
68  if ( !meshLayer )
69  return block;
70 
71  const QgsMeshDataProvider *provider = meshLayer->dataProvider();
72  if ( !provider )
73  return block;
74 
75  if ( !index.isValid() )
76  return block;
77 
78  const QgsMeshDatasetGroupMetadata meta = meshLayer->dataProvider()->datasetGroupMetadata( index.group() );
79  if ( meta.dataType() != QgsMeshDatasetGroupMetadata::DataType::DataOnVolumes )
80  {
81  block = provider->datasetValues( index, valueIndex, count );
82  if ( block.isValid() )
83  return block;
84  }
85  else
86  {
87  const QgsMesh3dAveragingMethod *averagingMethod = meshLayer->rendererSettings().averagingMethod();
88  if ( !averagingMethod )
89  return block;
90 
91  QgsMesh3dDataBlock block3d = provider->dataset3dValues( index, valueIndex, count );
92  if ( !block3d.isValid() )
93  return block;
94 
95  block = averagingMethod->calculate( block3d );
96  }
97  return block;
98 }
99 
100 QVector<QgsVector> QgsMeshLayerUtils::griddedVectorValues( const QgsMeshLayer *meshLayer,
101  const QgsMeshDatasetIndex index,
102  double xSpacing,
103  double ySpacing,
104  const QSize &size,
105  const QgsPointXY &minCorner )
106 {
107  QVector<QgsVector> vectors;
108 
109  if ( !meshLayer || !index.isValid() )
110  return vectors;
111 
112  const QgsTriangularMesh *triangularMesh = meshLayer->triangularMesh();
113  const QgsMesh *nativeMesh = meshLayer->nativeMesh();
114 
115  if ( !triangularMesh || !nativeMesh )
116  return vectors;
117 
118  QgsMeshDatasetGroupMetadata meta = meshLayer->dataProvider()->datasetGroupMetadata( index );
119  if ( !meta.isVector() )
120  return vectors;
121 
122  // extract vector dataset
123  bool vectorDataOnVertices = meta.dataType() == QgsMeshDatasetGroupMetadata::DataOnVertices;
124  int datacount = vectorDataOnVertices ? nativeMesh->vertices.count() : nativeMesh->faces.count();
125  const QgsMeshDataBlock vals = QgsMeshLayerUtils::datasetValues( meshLayer, index, 0, datacount );
126 
127  const QgsMeshDataBlock isFacesActive = meshLayer->dataProvider()->areFacesActive( index, 0, nativeMesh->faceCount() );
128  const QgsMeshDatasetGroupMetadata::DataType dataType = meta.dataType();
129 
131  return vectors;
132 
133  try
134  {
135  vectors.reserve( size.height()*size.width() );
136  }
137  catch ( ... )
138  {
139  QgsDebugMsgLevel( "Unable to store the arrow grid in memory", 1 );
140  return QVector<QgsVector>();
141  }
142 
143  for ( int iy = 0; iy < size.height(); ++iy )
144  {
145  double y = minCorner.y() + iy * ySpacing;
146  for ( int ix = 0; ix < size.width(); ++ix )
147  {
148  double x = minCorner.x() + ix * xSpacing;
149  QgsPoint point( x, y );
150  int faceIndex = triangularMesh->faceIndexForPoint_v2( point );
151  int nativeFaceIndex = -1;
152  if ( faceIndex != -1 )
153  nativeFaceIndex = triangularMesh->trianglesToNativeFaces().at( faceIndex );
154  QgsMeshDatasetValue value;
155  if ( nativeFaceIndex != -1 && isFacesActive.active( nativeFaceIndex ) )
156  {
157  switch ( dataType )
158  {
161  value = vals.value( nativeFaceIndex );
162  break;
164  {
165  const QgsMeshFace &face = triangularMesh->triangles()[faceIndex];
166  const int v1 = face[0], v2 = face[1], v3 = face[2];
167  const QgsPoint p1 = triangularMesh->vertices()[v1], p2 = triangularMesh->vertices()[v2], p3 = triangularMesh->vertices()[v3];
168  const QgsMeshDatasetValue val1 = vals.value( v1 );
169  const QgsMeshDatasetValue val2 = vals.value( v2 );
170  const QgsMeshDatasetValue val3 = vals.value( v3 );
171  const double x = QgsMeshLayerUtils::interpolateFromVerticesData( p1, p2, p3, val1.x(), val2.x(), val3.x(), point );
172  const double y = QgsMeshLayerUtils::interpolateFromVerticesData( p1, p2, p3, val1.y(), val2.y(), val3.y(), point );
173  value = QgsMeshDatasetValue( x, y );
174  }
175  break;
177  break;
178  }
179  }
180  vectors.append( QgsVector( value.x(), value.y() ) );
181  }
182  }
183  return vectors;
184 }
185 
186 QVector<double> QgsMeshLayerUtils::calculateMagnitudes( const QgsMeshDataBlock &block )
187 {
188  Q_ASSERT( QgsMeshDataBlock::ActiveFlagInteger != block.type() );
189  int count = block.count();
190  QVector<double> ret( count );
191 
192  for ( int i = 0; i < count; ++i )
193  {
194  double mag = block.value( i ).scalar();
195  ret[i] = mag;
196  }
197  return ret;
198 }
199 
200 void QgsMeshLayerUtils::boundingBoxToScreenRectangle( const QgsMapToPixel &mtp,
201  const QSize &outputSize,
202  const QgsRectangle &bbox,
203  int &leftLim,
204  int &rightLim,
205  int &topLim,
206  int &bottomLim )
207 {
208  QgsPointXY ll = mtp.transform( bbox.xMinimum(), bbox.yMinimum() );
209  QgsPointXY ur = mtp.transform( bbox.xMaximum(), bbox.yMaximum() );
210  topLim = std::max( int( ur.y() ), 0 );
211  bottomLim = std::min( int( ll.y() ), outputSize.height() - 1 );
212  leftLim = std::max( int( ll.x() ), 0 );
213  rightLim = std::min( int( ur.x() ), outputSize.width() - 1 );
214 }
215 
216 static void lamTol( double &lam )
217 {
218  const static double eps = 1e-6;
219  if ( ( lam < 0.0 ) && ( lam > -eps ) )
220  {
221  lam = 0.0;
222  }
223 }
224 
225 static bool E3T_physicalToBarycentric( const QgsPointXY &pA, const QgsPointXY &pB, const QgsPointXY &pC, const QgsPointXY &pP,
226  double &lam1, double &lam2, double &lam3 )
227 {
228  if ( pA == pB || pA == pC || pB == pC )
229  return false; // this is not a valid triangle!
230 
231  // Compute vectors
232  QgsVector v0( pC - pA );
233  QgsVector v1( pB - pA );
234  QgsVector v2( pP - pA );
235 
236  // Compute dot products
237  double dot00 = v0 * v0;
238  double dot01 = v0 * v1;
239  double dot02 = v0 * v2;
240  double dot11 = v1 * v1;
241  double dot12 = v1 * v2;
242 
243  // Compute barycentric coordinates
244  double invDenom = 1.0 / ( dot00 * dot11 - dot01 * dot01 );
245  lam1 = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
246  lam2 = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
247  lam3 = 1.0 - lam1 - lam2;
248 
249  // Apply some tolerance to lam so we can detect correctly border points
250  lamTol( lam1 );
251  lamTol( lam2 );
252  lamTol( lam3 );
253 
254  // Return if POI is outside triangle
255  if ( ( lam1 < 0 ) || ( lam2 < 0 ) || ( lam3 < 0 ) )
256  {
257  return false;
258  }
259 
260  return true;
261 }
262 
263 double QgsMeshLayerUtils::interpolateFromVerticesData( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3,
264  double val1, double val2, double val3, const QgsPointXY &pt )
265 {
266  double lam1, lam2, lam3;
267  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
268  return std::numeric_limits<double>::quiet_NaN();
269 
270  return lam1 * val3 + lam2 * val2 + lam3 * val1;
271 }
272 
273 double QgsMeshLayerUtils::interpolateFromVerticesData( double fraction, double val1, double val2 )
274 {
275  if ( std::isnan( val1 ) || std::isnan( val2 ) || ( fraction < 0 ) || ( fraction > 1 ) )
276  {
277  return std::numeric_limits<double>::quiet_NaN();
278  }
279  return val1 + ( val2 - val1 ) * fraction;
280 }
281 
282 QgsMeshDatasetValue QgsMeshLayerUtils::interpolateFromVerticesData( double fraction, const QgsMeshDatasetValue &val1, const QgsMeshDatasetValue &val2 )
283 {
284  return QgsMeshDatasetValue( interpolateFromVerticesData( fraction, val1.x(), val2.x() ),
285  interpolateFromVerticesData( fraction, val1.y(), val2.y() ) );
286 }
287 
288 
289 QgsVector QgsMeshLayerUtils::interpolateVectorFromVerticesData( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3, QgsVector vect1, QgsVector vect2, QgsVector vect3, const QgsPointXY &pt )
290 {
291  double lam1, lam2, lam3;
292  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
293  return QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
294 
295  return vect3 * lam1 + vect2 * lam2 + vect1 * lam3;
296 }
297 
298 double QgsMeshLayerUtils::interpolateFromFacesData( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3,
299  double val, const QgsPointXY &pt )
300 {
301  double lam1, lam2, lam3;
302  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
303  return std::numeric_limits<double>::quiet_NaN();
304 
305  return val;
306 }
307 
308 QgsVector QgsMeshLayerUtils::interpolateVectorFromFacesData( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3,
309  QgsVector vect, const QgsPointXY &pt )
310 {
311  double lam1, lam2, lam3;
312  if ( !E3T_physicalToBarycentric( p1, p2, p3, pt, lam1, lam2, lam3 ) )
313  return QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
314 
315  return vect;
316 }
317 
318 
319 QVector<double> QgsMeshLayerUtils::interpolateFromFacesData(
320  QVector<double> valuesOnFaces,
321  const QgsMesh *nativeMesh,
322  const QgsTriangularMesh *triangularMesh,
323  QgsMeshDataBlock *active,
325 {
326  assert( nativeMesh );
327  Q_UNUSED( method );
329 
330  // assuming that native vertex count = triangular vertex count
331  assert( nativeMesh->vertices.size() == triangularMesh->vertices().size() );
332  int vertexCount = triangularMesh->vertices().size();
333 
334  QVector<double> res( vertexCount, 0.0 );
335  // for face datasets do simple average of the valid values of all faces that contains this vertex
336  QVector<int> count( vertexCount, 0 );
337 
338  for ( int i = 0; i < nativeMesh->faces.size(); ++i )
339  {
340  if ( !active || active->active( i ) )
341  {
342  double val = valuesOnFaces[ i ];
343  if ( !std::isnan( val ) )
344  {
345  // assign for all vertices
346  const QgsMeshFace &face = nativeMesh->faces.at( i );
347  for ( int j = 0; j < face.size(); ++j )
348  {
349  int vertexIndex = face[j];
350  res[vertexIndex] += val;
351  count[vertexIndex] += 1;
352  }
353  }
354  }
355  }
356 
357  for ( int i = 0; i < vertexCount; ++i )
358  {
359  if ( count.at( i ) > 0 )
360  {
361  res[i] = res[i] / double( count.at( i ) );
362  }
363  else
364  {
365  res[i] = std::numeric_limits<double>::quiet_NaN();
366  }
367  }
368 
369  return res;
370 }
371 
372 QVector<double> QgsMeshLayerUtils::resampleFromVerticesToFaces(
373  const QVector<double> valuesOnVertices,
374  const QgsMesh *nativeMesh,
375  const QgsTriangularMesh *triangularMesh,
376  const QgsMeshDataBlock *active,
378 {
379  assert( nativeMesh );
380  Q_UNUSED( method );
382 
383  // assuming that native vertex count = triangular vertex count
384  Q_UNUSED( triangularMesh );
385  assert( nativeMesh->vertices.size() == triangularMesh->vertices().size() );
386 
387  QVector<double> ret( nativeMesh->faceCount(), std::numeric_limits<double>::quiet_NaN() );
388 
389  for ( int i = 0; i < nativeMesh->faces.size(); ++i )
390  {
391  const QgsMeshFace face = nativeMesh->face( i );
392  if ( active->active( i ) && face.count() > 2 )
393  {
394  double value = 0;
395  for ( int j = 0; j < face.count(); ++j )
396  {
397  value += valuesOnVertices.at( face.at( j ) );
398  }
399  ret[i] = value / face.count();
400  }
401  }
402 
403  return ret;
404 }
405 
406 QVector<double> QgsMeshLayerUtils::calculateMagnitudeOnVertices( const QgsMeshLayer *meshLayer,
407  const QgsMeshDatasetIndex index,
408  QgsMeshDataBlock *activeFaceFlagValues,
410 {
411  QVector<double> ret;
412 
413  if ( !meshLayer && !index.isValid() )
414  return ret;
415 
416  const QgsTriangularMesh *triangularMesh = meshLayer->triangularMesh();
417  const QgsMesh *nativeMesh = meshLayer->nativeMesh();
418  if ( !triangularMesh || !nativeMesh )
419  return ret;
420 
421  const QgsMeshDatasetGroupMetadata metadata = meshLayer->dataProvider()->datasetGroupMetadata( index );
422  bool scalarDataOnVertices = metadata.dataType() == QgsMeshDatasetGroupMetadata::DataOnVertices;
423 
424  // populate scalar values
425  int datacount = scalarDataOnVertices ? nativeMesh->vertices.count() : nativeMesh->faces.count();
426  QgsMeshDataBlock vals = QgsMeshLayerUtils::datasetValues(
427  meshLayer,
428  index,
429  0,
430  datacount );
431 
432  if ( vals.isValid() )
433  {
434  ret = QgsMeshLayerUtils::calculateMagnitudes( vals );
435 
436  if ( !scalarDataOnVertices )
437  {
438  //Need to interpolate data on vertices
439  ret = QgsMeshLayerUtils::interpolateFromFacesData(
440  ret,
441  nativeMesh,
442  triangularMesh,
443  activeFaceFlagValues,
444  method );
445  }
446  }
447  return ret;
448 }
449 
450 QgsRectangle QgsMeshLayerUtils::triangleBoundingBox( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3 )
451 {
452  // p1
453  double xMin = p1.x();
454  double xMax = p1.x();
455  double yMin = p1.y();
456  double yMax = p1.y();
457 
458  //p2
459  xMin = ( ( xMin < p2.x() ) ? xMin : p2.x() );
460  xMax = ( ( xMax > p2.x() ) ? xMax : p2.x() );
461  yMin = ( ( yMin < p2.y() ) ? yMin : p2.y() );
462  yMax = ( ( yMax > p2.y() ) ? yMax : p2.y() );
463 
464  // p3
465  xMin = ( ( xMin < p3.x() ) ? xMin : p3.x() );
466  xMax = ( ( xMax > p3.x() ) ? xMax : p3.x() );
467  yMin = ( ( yMin < p3.y() ) ? yMin : p3.y() );
468  yMax = ( ( yMax > p3.y() ) ? yMax : p3.y() );
469 
470  QgsRectangle bbox( xMin, yMin, xMax, yMax );
471  return bbox;
472 }
473 
474 QString QgsMeshLayerUtils::formatTime( double hours, const QDateTime &referenceTime, const QgsMeshTimeSettings &settings )
475 {
476  QString ret;
477 
478  if ( referenceTime.isValid() )
479  {
480  QString format( settings.absoluteTimeFormat() );
481  QDateTime dateTime( referenceTime );
482  qint64 seconds = static_cast<qint64>( hours * 3600.0 );
483  dateTime = dateTime.addSecs( seconds );
484  ret = dateTime.toString( format );
485  if ( ret.isEmpty() ) // error
486  ret = dateTime.toString();
487  }
488  else
489  {
490  QString format( settings.relativeTimeFormat() );
491  format = format.trimmed();
492  int totalHours = static_cast<int>( hours );
493 
494  if ( format == QStringLiteral( "hh:mm:ss.zzz" ) )
495  {
496  int ms = static_cast<int>( hours * 3600.0 * 1000 );
497  int seconds = ms / 1000;
498  int z = ms % 1000;
499  int m = seconds / 60;
500  int s = seconds % 60;
501  int h = m / 60;
502  m = m % 60;
503  ret = QStringLiteral( "%1:%2:%3.%4" ).
504  arg( h, 2, 10, QLatin1Char( '0' ) ).
505  arg( m, 2, 10, QLatin1Char( '0' ) ).
506  arg( s, 2, 10, QLatin1Char( '0' ) ).
507  arg( z, 3, 10, QLatin1Char( '0' ) );
508  }
509  else if ( format == QStringLiteral( "hh:mm:ss" ) )
510  {
511  int seconds = static_cast<int>( hours * 3600.0 );
512  int m = seconds / 60;
513  int s = seconds % 60;
514  int h = m / 60;
515  m = m % 60;
516  ret = QStringLiteral( "%1:%2:%3" ).
517  arg( h, 2, 10, QLatin1Char( '0' ) ).
518  arg( m, 2, 10, QLatin1Char( '0' ) ).
519  arg( s, 2, 10, QLatin1Char( '0' ) );
520 
521  }
522  else if ( format == QStringLiteral( "d hh:mm:ss" ) )
523  {
524  int seconds = static_cast<int>( hours * 3600.0 );
525  int m = seconds / 60;
526  int s = seconds % 60;
527  int h = m / 60;
528  m = m % 60;
529  int d = totalHours / 24;
530  h = totalHours % 24;
531  ret = QStringLiteral( "%1 d %2:%3:%4" ).
532  arg( d ).
533  arg( h, 2, 10, QLatin1Char( '0' ) ).
534  arg( m, 2, 10, QLatin1Char( '0' ) ).
535  arg( s, 2, 10, QLatin1Char( '0' ) );
536  }
537  else if ( format == QStringLiteral( "d hh" ) )
538  {
539  int d = totalHours / 24;
540  int h = totalHours % 24;
541  ret = QStringLiteral( "%1 d %2" ).
542  arg( d ).
543  arg( h );
544  }
545  else if ( format == QStringLiteral( "d" ) )
546  {
547  int d = totalHours / 24;
548  ret = QStringLiteral( "%1" ).arg( d );
549  }
550  else if ( format == QStringLiteral( "ss" ) )
551  {
552  int seconds = static_cast<int>( hours * 3600.0 );
553  ret = QStringLiteral( "%1" ).arg( seconds );
554  }
555  else // "hh"
556  {
557  ret = QStringLiteral( "%1" ).arg( hours );
558  }
559  }
560  return ret;
561 }
562 
563 QVector<QVector3D> QgsMeshLayerUtils::calculateNormals( const QgsTriangularMesh &triangularMesh, const QVector<double> &verticalMagnitude, bool isRelative )
564 {
565  QVector<QVector3D> normals( triangularMesh.vertices().count() );
566  for ( const auto &face : triangularMesh.triangles() )
567  {
568  for ( int i = 0; i < 3; i++ )
569  {
570  int index( face.at( i ) );
571  int index1( face.at( ( i + 1 ) % 3 ) );
572  int index2( face.at( ( i + 2 ) % 3 ) );
573 
574  const QgsMeshVertex &vert( triangularMesh.vertices().at( index ) );
575  const QgsMeshVertex &otherVert1( triangularMesh.vertices().at( index1 ) );
576  const QgsMeshVertex &otherVert2( triangularMesh.vertices().at( index2 ) );
577 
578  float adjustRelative = 0;
579  float adjustRelative1 = 0;
580  float adjustRelative2 = 0;
581 
582  if ( isRelative )
583  {
584  adjustRelative = vert.z();
585  adjustRelative1 = otherVert1.z();
586  adjustRelative2 = otherVert2.z();
587  }
588 
589  QVector3D v1( float( otherVert1.x() - vert.x() ),
590  float( otherVert1.y() - vert.y() ),
591  float( verticalMagnitude[index1] - verticalMagnitude[index] + adjustRelative1 - adjustRelative ) );
592  QVector3D v2( float( otherVert2.x() - vert.x() ),
593  float( otherVert2.y() - vert.y() ),
594  float( verticalMagnitude[index2] - verticalMagnitude[index] + adjustRelative2 - adjustRelative ) );
595 
596  normals[index] += QVector3D::crossProduct( v1, v2 );
597  }
598  }
599 
600  return normals;
601 }
602 
qgsmeshlayerutils.h
qgsmesh3daveraging.h
QgsPointXY::y
double y
Definition: qgspointxy.h:48
QgsMeshDatasetGroupMetadata::DataOnVolumes
@ DataOnVolumes
Data is defined on volumes.
Definition: qgsmeshdataset.h:357
QgsTriangularMesh::vertices
const QVector< QgsMeshVertex > & vertices() const
Returns vertices in map coordinate system.
Definition: qgstriangularmesh.cpp:287
QgsMeshTimeSettings
Definition: qgsmeshtimesettings.h:35
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsMesh3dDataBlock::isValid
bool isValid() const
Whether the block is valid.
Definition: qgsmeshdataset.cpp:334
QgsRectangle::xMaximum
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
QgsMeshDatasetValue
Definition: qgsmeshdataset.h:76
QgsTriangularMesh::triangles
const QVector< QgsMeshFace > & triangles() const
Returns triangles.
Definition: qgstriangularmesh.cpp:292
QgsMesh
Definition: qgsmeshdataprovider.h:57
QgsMeshLayer::triangularMesh
QgsTriangularMesh * triangularMesh(double minimumTriangleSize=0) const
Returns triangular mesh (nullptr before rendering or calling to updateMesh).
Definition: qgsmeshlayer.cpp:224
QgsRectangle
Definition: qgsrectangle.h:41
QgsMesh3dDataBlock
Definition: qgsmeshdataset.h:243
QgsMeshDataBlock::type
DataType type() const
Type of data stored in the block.
Definition: qgsmeshdataset.cpp:244
QgsMeshLayer::rendererSettings
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
Definition: qgsmeshlayer.cpp:263
QgsMeshRendererScalarSettings::NeighbourAverage
@ NeighbourAverage
Does a simple average of values defined for all surrounding faces/vertices.
Definition: qgsmeshrenderersettings.h:116
qgstriangularmesh.h
qgsmeshtimesettings.h
QgsMeshDatasetSourceInterface::datasetValues
virtual QgsMeshDataBlock datasetValues(QgsMeshDatasetIndex index, int valueIndex, int count) const =0
Returns N vector/scalar values from the index from the dataset.
QgsMeshDatasetGroupMetadata::DataOnFaces
@ DataOnFaces
Data is defined on faces.
Definition: qgsmeshdataset.h:355
QgsMeshDatasetGroupMetadata::DataOnVertices
@ DataOnVertices
Data is defined on vertices.
Definition: qgsmeshdataset.h:356
QgsMesh::faceCount
int faceCount() const
Returns number of faces.
Definition: qgsmeshdataprovider.cpp:124
QgsMeshDatasetIndex::group
int group() const
Returns a group index.
Definition: qgsmeshdataset.cpp:26
QgsMesh::vertexCount
int vertexCount() const
Returns number of vertices.
Definition: qgsmeshdataprovider.cpp:119
QgsMesh::faces
QVector< QgsMeshFace > faces
Definition: qgsmeshdataprovider.h:107
QgsMesh::edgeCount
int edgeCount() const
Returns number of edge.
Definition: qgsmeshdataprovider.cpp:129
QgsMeshDatasetIndex
Definition: qgsmeshdataset.h:45
QgsMeshLayer
Definition: qgsmeshlayer.h:94
QgsMeshDataBlock::active
bool active(int index) const
Returns a value for active flag by the index For scalar and vector 2d the behavior is undefined.
Definition: qgsmeshdataset.cpp:275
QgsMeshDatasetIndex::isValid
bool isValid() const
Returns whether index is valid, ie at least groups is set.
Definition: qgsmeshdataset.cpp:36
QgsMeshTimeSettings::relativeTimeFormat
QString relativeTimeFormat() const
Returns format used for relative time.
Definition: qgsmeshtimesettings.cpp:39
QgsMeshDatasetValue::x
double x() const
Returns x value.
Definition: qgsmeshdataset.cpp:93
QgsMeshDataProvider
Definition: qgsmeshdataprovider.h:351
QgsMesh::face
QgsMeshFace face(int index) const
Returns a face at the index.
Definition: qgsmeshdataprovider.cpp:84
QgsMeshLayer::nativeMesh
QgsMesh * nativeMesh()
Returns native mesh (nullptr before rendering or calling to updateMesh)
Definition: qgsmeshlayer.cpp:214
QgsMeshRendererScalarSettings::DataResamplingMethod
DataResamplingMethod
Resampling of value from dataset.
Definition: qgsmeshrenderersettings.h:105
QgsTriangularMesh::faceIndexForPoint_v2
int faceIndexForPoint_v2(const QgsPointXY &point) const
Finds index of triangle at given point It uses spatial indexing and don't use geos to be faster.
Definition: qgstriangularmesh.cpp:340
QgsMeshDatasetGroupMetadata::DataOnEdges
@ DataOnEdges
Data is defined on edges.
Definition: qgsmeshdataset.h:358
QgsMeshFace
QVector< int > QgsMeshFace
List of vertex indexes.
Definition: qgsmeshdataprovider.h:41
QgsMeshTimeSettings::absoluteTimeFormat
QString absoluteTimeFormat() const
Returns format used for absolute time.
Definition: qgsmeshtimesettings.cpp:49
QgsMapToPixel::transform
QgsPointXY transform(const QgsPointXY &p) const
Transform the point from map (world) coordinates to device coordinates.
Definition: qgsmaptopixel.cpp:217
QgsRectangle::yMaximum
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
QgsMesh3dAveragingMethod
Definition: qgsmesh3daveraging.h:39
qgsmeshlayer.h
QgsPointXY
Definition: qgspointxy.h:43
QgsMeshDatasetGroupMetadata::dataType
DataType dataType() const
Returns whether dataset group data is defined on vertices or faces or volumes.
Definition: qgsmeshdataset.cpp:169
QgsMeshDatasetGroupMetadata
Definition: qgsmeshdataset.h:348
QgsMapToPixel
Definition: qgsmaptopixel.h:37
QgsMeshDatasetGroupMetadata::DataType
DataType
Location of where data is specified for datasets in the dataset group.
Definition: qgsmeshdataset.h:353
QgsMeshDataBlock::ActiveFlagInteger
@ ActiveFlagInteger
Integer boolean flag whether face is active.
Definition: qgsmeshdataset.h:140
QgsTriangularMesh::trianglesToNativeFaces
const QVector< int > & trianglesToNativeFaces() const
Returns mapping between triangles and original faces.
Definition: qgstriangularmesh.cpp:317
QgsVector
Definition: qgsvector.h:29
QgsPointXY::x
double x
Definition: qgspointxy.h:47
QgsMeshDatasetSourceInterface::dataset3dValues
virtual QgsMesh3dDataBlock dataset3dValues(QgsMeshDatasetIndex index, int faceIndex, int count) const =0
Returns N vector/scalar values from the face index from the dataset for 3d stacked meshes.
QgsMeshDatasetValue::y
double y() const
Returns y value.
Definition: qgsmeshdataset.cpp:98
QgsMesh::vertices
QVector< QgsMeshVertex > vertices
Definition: qgsmeshdataprovider.h:105
QgsMeshRendererSettings::averagingMethod
QgsMesh3dAveragingMethod * averagingMethod() const
Returns averaging method for conversion of 3d stacked mesh data to 2d data.
Definition: qgsmeshrenderersettings.cpp:396
QgsRectangle::yMinimum
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
QgsMeshDataBlock
Definition: qgsmeshdataset.h:134
QgsTriangularMesh
Definition: qgstriangularmesh.h:49
qgslogger.h
QgsMeshDatasetGroupMetadata::isVector
bool isVector() const
Returns whether dataset group has vector data.
Definition: qgsmeshdataset.cpp:149
QgsMeshDataBlock::value
QgsMeshDatasetValue value(int index) const
Returns a value represented by the index For active flag the behavior is undefined.
Definition: qgsmeshdataset.cpp:259
QgsMeshDatasetValue::scalar
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
Definition: qgsmeshdataset.cpp:62
QgsMesh3dAveragingMethod::calculate
QgsMeshDataBlock calculate(const QgsMesh3dDataBlock &block3d, QgsFeedback *feedback=nullptr) const
Calculated 2d block values from 3d stacked mesh values.
Definition: qgsmesh3daveraging.cpp:57
qgsmeshdataprovider.h
QgsMeshDatasetSourceInterface::areFacesActive
virtual QgsMeshDataBlock areFacesActive(QgsMeshDatasetIndex index, int faceIndex, int count) const =0
Returns whether the faces are active for particular dataset.
QgsMeshDatasetSourceInterface::datasetGroupMetadata
virtual QgsMeshDatasetGroupMetadata datasetGroupMetadata(int groupIndex) const =0
Returns dataset group metadata.
QgsMeshLayer::dataProvider
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
Definition: qgsmeshlayer.cpp:147
QgsRectangle::xMinimum
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
QgsMeshDataBlock::isValid
bool isValid() const
Whether the block is valid.
Definition: qgsmeshdataset.cpp:254
QgsMeshDataBlock::count
int count() const
Number of items stored in the block.
Definition: qgsmeshdataset.cpp:249