26 #define M_DEG2RAD 0.0174532925 
   32   if ( mCacheFaceIndex != -1 && mCacheFaceIndex < mTriangularMesh.triangles().count() )
 
   34     QgsVector res = interpolatedValuePrivate( mCacheFaceIndex, point );
 
   35     if ( isVectorValid( res ) )
 
   37       activeFaceFilter( res, mCacheFaceIndex );
 
   43   QList<int> potentialFaceIndexes = mTriangularMesh.faceIndexesForRectangle( 
QgsRectangle( point, point ) );
 
   45   for ( 
const int faceIndex : potentialFaceIndexes )
 
   47     QgsVector res = interpolatedValuePrivate( faceIndex, point );
 
   48     if ( isVectorValid( res ) )
 
   50       mCacheFaceIndex = faceIndex;
 
   51       activeFaceFilter( res, mCacheFaceIndex );
 
   57   return ( 
QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() ) );
 
   61 QgsMeshVectorValueInterpolator &QgsMeshVectorValueInterpolator::operator=( 
const QgsMeshVectorValueInterpolator &other )
 
   63   mTriangularMesh = other.mTriangularMesh;
 
   64   mDatasetValues = other.mDatasetValues;
 
   65   mActiveFaceFlagValues = other.mActiveFaceFlagValues;
 
   66   mFaceCache = other.mFaceCache;
 
   67   mCacheFaceIndex = other.mCacheFaceIndex;
 
   68   mUseScalarActiveFaceFlagValues = other.mUseScalarActiveFaceFlagValues;
 
   73 QgsMeshVectorValueInterpolatorFromVertex::
 
   75   QgsMeshVectorValueInterpolator( triangularMesh, datasetVectorValues )
 
   80 QgsMeshVectorValueInterpolatorFromVertex::
 
   81 QgsMeshVectorValueInterpolatorFromVertex( 
const QgsTriangularMesh &triangularMesh,
 
   84   QgsMeshVectorValueInterpolator( triangularMesh, datasetVectorValues, scalarActiveFaceFlagValues )
 
   89 QgsMeshVectorValueInterpolatorFromVertex::QgsMeshVectorValueInterpolatorFromVertex( 
const QgsMeshVectorValueInterpolatorFromVertex &other ):
 
   90   QgsMeshVectorValueInterpolator( other )
 
   93 QgsMeshVectorValueInterpolatorFromVertex *QgsMeshVectorValueInterpolatorFromVertex::clone()
 
   95   return new QgsMeshVectorValueInterpolatorFromVertex( *
this );
 
   98 QgsMeshVectorValueInterpolatorFromVertex &QgsMeshVectorValueInterpolatorFromVertex::
 
   99 operator=( 
const QgsMeshVectorValueInterpolatorFromVertex &other )
 
  101   QgsMeshVectorValueInterpolator::operator=( other );
 
  105 QgsVector QgsMeshVectorValueInterpolatorFromVertex::interpolatedValuePrivate( 
int faceIndex, 
const QgsPointXY point )
 const 
  107   QgsMeshFace face = mTriangularMesh.triangles().at( faceIndex );
 
  114                             mDatasetValues.value( face.at( 0 ) ).y() );
 
  117                             mDatasetValues.value( face.at( 1 ) ).y() );
 
  120                             mDatasetValues.value( face.at( 2 ) ).y() );
 
  122   return QgsMeshLayerUtils::interpolateVectorFromVerticesData(
 
  132 QgsMeshVectorValueInterpolator::QgsMeshVectorValueInterpolator( 
const QgsTriangularMesh &triangularMesh,
 
  134   mTriangularMesh( triangularMesh ),
 
  135   mDatasetValues( datasetVectorValues ),
 
  136   mUseScalarActiveFaceFlagValues( false )
 
  139 QgsMeshVectorValueInterpolator::QgsMeshVectorValueInterpolator( 
const QgsTriangularMesh &triangularMesh,
 
  142   mTriangularMesh( triangularMesh ),
 
  143   mDatasetValues( datasetVectorValues ),
 
  144   mActiveFaceFlagValues( scalarActiveFaceFlagValues ),
 
  145   mUseScalarActiveFaceFlagValues( true )
 
  148 QgsMeshVectorValueInterpolator::QgsMeshVectorValueInterpolator( 
const QgsMeshVectorValueInterpolator &other ):
 
  149   mTriangularMesh( other.mTriangularMesh ),
 
  150   mDatasetValues( other.mDatasetValues ),
 
  151   mActiveFaceFlagValues( other.mActiveFaceFlagValues ),
 
  152   mFaceCache( other.mFaceCache ),
 
  153   mCacheFaceIndex( other.mCacheFaceIndex ),
 
  154   mUseScalarActiveFaceFlagValues( other.mUseScalarActiveFaceFlagValues )
 
  157 void QgsMeshVectorValueInterpolator::updateCacheFaceIndex( 
const QgsPointXY &point )
 const 
  161     mCacheFaceIndex = mTriangularMesh.faceIndexForPoint_v2( point );
 
  165 bool QgsMeshVectorValueInterpolator::isVectorValid( 
const QgsVector &v )
 const 
  167   return !( std::isnan( v.
x() ) || std::isnan( v.
y() ) );
 
  171 void QgsMeshVectorValueInterpolator::activeFaceFilter( 
QgsVector &vector, 
int faceIndex )
 const 
  173   if ( mUseScalarActiveFaceFlagValues && ! mActiveFaceFlagValues.active( mTriangularMesh.trianglesToNativeFaces()[faceIndex] ) )
 
  174     vector = 
QgsVector( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() ) ;
 
  177 QSize QgsMeshStreamField::size()
 const 
  182 QPoint QgsMeshStreamField::topLeft()
 const 
  184   return mFieldTopLeftInDeviceCoordinates;
 
  187 int QgsMeshStreamField::resolution()
 const 
  189   return mFieldResolution;
 
  192 QgsPointXY QgsMeshStreamField::positionToMapCoordinates( 
const QPoint &pixelPosition, 
const QgsPointXY &positionInPixel )
 
  194   QgsPointXY mapPoint = mMapToFieldPixel.toMapCoordinates( pixelPosition );
 
  195   mapPoint = mapPoint + 
QgsVector( positionInPixel.
x() * mMapToFieldPixel.mapUnitsPerPixel(),
 
  196                                    positionInPixel.
y() * mMapToFieldPixel.mapUnitsPerPixel() );
 
  200 QgsMeshStreamField::QgsMeshStreamField(
 
  205   double magnitudeMaximum, 
bool dataIsOnVertices,
 
  209   mFieldResolution( resolution ),
 
  210   mVectorColoring( vectorColoring ),
 
  211   mLayerExtent( layerExtent ),
 
  212   mMaximumMagnitude( magnitudeMaximum ),
 
  213   mRenderContext( rendererContext )
 
  215   if ( dataIsOnVertices )
 
  217     if ( scalarActiveFaceFlagValues.
isValid() )
 
  218       mVectorValueInterpolator.reset( 
new QgsMeshVectorValueInterpolatorFromVertex( triangularMesh,
 
  220                                       scalarActiveFaceFlagValues ) );
 
  222       mVectorValueInterpolator.reset( 
new QgsMeshVectorValueInterpolatorFromVertex( triangularMesh,
 
  223                                       dataSetVectorValues ) );
 
  227     if ( scalarActiveFaceFlagValues.
isValid() )
 
  228       mVectorValueInterpolator.reset( 
new QgsMeshVectorValueInterpolatorFromFace( triangularMesh,
 
  230                                       scalarActiveFaceFlagValues ) );
 
  232       mVectorValueInterpolator.reset( 
new QgsMeshVectorValueInterpolatorFromFace( triangularMesh,
 
  233                                       dataSetVectorValues ) );
 
  237 QgsMeshStreamField::QgsMeshStreamField( 
const QgsMeshStreamField &other ):
 
  238   mFieldSize( other.mFieldSize ),
 
  239   mFieldResolution( other.mFieldResolution ),
 
  241   mTraceImage( other.mTraceImage ),
 
  242   mMapToFieldPixel( other.mMapToFieldPixel ),
 
  243   mVectorColoring( other.mVectorColoring ),
 
  244   mPixelFillingCount( other.mPixelFillingCount ),
 
  245   mMaxPixelFillingCount( other.mMaxPixelFillingCount ),
 
  246   mLayerExtent( other.mLayerExtent ),
 
  247   mMapExtent( other.mMapExtent ),
 
  248   mFieldTopLeftInDeviceCoordinates( other.mFieldTopLeftInDeviceCoordinates ),
 
  249   mValid( other.mValid ),
 
  250   mMaximumMagnitude( other.mMaximumMagnitude ),
 
  251   mPixelFillingDensity( other.mPixelFillingDensity ),
 
  252   mMinMagFilter( other.mMinMagFilter ),
 
  253   mMaxMagFilter( other.mMaxMagFilter ),
 
  254   mRenderContext( other.mRenderContext ),
 
  255   mMinimizeFieldSize( other.mMinimizeFieldSize )
 
  257   mPainter.reset( 
new QPainter( &mTraceImage ) );
 
  258   mVectorValueInterpolator =
 
  259     std::unique_ptr<QgsMeshVectorValueInterpolator>( other.mVectorValueInterpolator->clone() );
 
  262 QgsMeshStreamField::~QgsMeshStreamField()
 
  268 void QgsMeshStreamField::updateSize( 
const QgsRenderContext &renderContext )
 
  281     layerExtent = mMapExtent;
 
  285   if ( mMinimizeFieldSize )
 
  286     interestZoneExtent = layerExtent.
intersect( mMapExtent );
 
  288     interestZoneExtent = mMapExtent;
 
  293     mFieldSize = QSize();
 
  294     mFieldTopLeftInDeviceCoordinates = QPoint();
 
  300   QgsRectangle fieldInterestZoneInDeviceCoordinates = QgsMeshLayerUtils::boundingBoxToScreenRectangle( deviceMapToPixel, interestZoneExtent );
 
  301   mFieldTopLeftInDeviceCoordinates = QPoint( 
int( fieldInterestZoneInDeviceCoordinates.
xMinimum() ), 
int( fieldInterestZoneInDeviceCoordinates.
yMinimum() ) );
 
  302   int fieldWidthInDeviceCoordinate = int( fieldInterestZoneInDeviceCoordinates.
width() );
 
  303   int fieldHeightInDeviceCoordinate = int ( fieldInterestZoneInDeviceCoordinates.
height() );
 
  305   int fieldWidth = int( fieldWidthInDeviceCoordinate / mFieldResolution );
 
  306   int fieldHeight = int( fieldHeightInDeviceCoordinate / mFieldResolution );
 
  309   if ( fieldWidthInDeviceCoordinate % mFieldResolution > 0 )
 
  311   if ( fieldHeightInDeviceCoordinate % mFieldResolution > 0 )
 
  314   if ( fieldWidth == 0 || fieldHeight == 0 )
 
  316     mFieldSize = QSize();
 
  320     mFieldSize.setWidth( fieldWidth );
 
  321     mFieldSize.setHeight( fieldHeight );
 
  324   double mapUnitPerFieldPixel;
 
  325   if ( interestZoneExtent.
width() > 0 )
 
  326     mapUnitPerFieldPixel = deviceMapToPixel.
mapUnitsPerPixel() * mFieldResolution * mFieldSize.width() / ( fieldWidthInDeviceCoordinate / mFieldResolution ) ;
 
  328     mapUnitPerFieldPixel = 1e-8;
 
  330   int fieldRightDevice = mFieldTopLeftInDeviceCoordinates.x() + mFieldSize.width() * mFieldResolution;
 
  331   int fieldBottomDevice = mFieldTopLeftInDeviceCoordinates.y() + mFieldSize.height() * mFieldResolution;
 
  334   int fieldTopDevice = mFieldTopLeftInDeviceCoordinates.
x();
 
  335   int fieldLeftDevice = mFieldTopLeftInDeviceCoordinates.y();
 
  338   double xc = ( fieldRightBottomMap.
x() + fieldTopLeftMap.
x() ) / 2;
 
  339   double yc = ( fieldTopLeftMap.
y() + fieldRightBottomMap.
y() ) / 2;
 
  353 void QgsMeshStreamField::updateSize( 
const QgsRenderContext &renderContext, 
int resolution )
 
  355   if ( renderContext.
mapExtent() == mMapExtent && resolution == mFieldResolution )
 
  357   mFieldResolution = resolution;
 
  359   updateSize( renderContext );
 
  362 bool QgsMeshStreamField::isValid()
 const 
  367 void QgsMeshStreamField::addTrace( 
QgsPointXY startPoint )
 
  369   addTrace( mMapToFieldPixel.transform( startPoint ).toQPointF().toPoint() );
 
  373 void QgsMeshStreamField::addRandomTraces()
 
  375   if ( mMaximumMagnitude > 0 )
 
  376     while ( mPixelFillingCount < mMaxPixelFillingCount && !mRenderContext.renderingStopped() )
 
  380 void QgsMeshStreamField::addRandomTrace()
 
  385   int xRandom =  1 + std::rand() / int( ( RAND_MAX + 1u ) / uint( mFieldSize.width() ) )  ;
 
  386   int yRandom = 1 + std::rand() / int ( ( RAND_MAX + 1u ) / uint( mFieldSize.height() ) ) ;
 
  387   addTrace( QPoint( xRandom, yRandom ) );
 
  390 void QgsMeshStreamField::addGriddedTraces( 
int dx, 
int dy )
 
  393   while ( i < mFieldSize.width() && !mRenderContext.renderingStopped() )
 
  396     while ( j < mFieldSize.height() && !mRenderContext.renderingStopped() )
 
  398       addTrace( QPoint( i, j ) );
 
  409   for ( 
auto f : std::as_const( facesInExtent ) )
 
  412     for ( 
auto i : std::as_const( face ) )
 
  413       vertices.insert( i );
 
  416   for ( 
auto i : std::as_const( vertices ) )
 
  418     addTrace( mesh.
vertices().at( i ) );
 
  422 void QgsMeshStreamField::addTrace( QPoint startPixel )
 
  428   if ( isTraceExists( startPixel ) || isTraceOutside( startPixel ) )
 
  431   if ( !mVectorValueInterpolator )
 
  434   if ( !( mMaximumMagnitude > 0 ) )
 
  437   mPainter->setPen( mPen );
 
  443   std::list<QPair<QPoint, FieldData>> chunkTrace;
 
  445   QPoint currentPixel = startPixel;
 
  450   while ( !mRenderContext.renderingStopped() )
 
  453     vector = mVectorValueInterpolator->vectorValue( mapPosition ) ;
 
  455     if ( std::isnan( vector.
x() ) || std::isnan( vector.
y() ) )
 
  457       mPixelFillingCount++;
 
  458       setChunkTrace( chunkTrace );
 
  459       drawChunkTrace( chunkTrace );
 
  467     QgsVector vu = vector / mMaximumMagnitude * 2;
 
  468     data.magnitude = vector.
length();
 
  472     double Vu = data.magnitude / mMaximumMagnitude * 2; 
 
  477       addPixelToChunkTrace( currentPixel, data, chunkTrace );
 
  478       simplifyChunkTrace( chunkTrace );
 
  479       setChunkTrace( chunkTrace );
 
  480       drawChunkTrace( chunkTrace );
 
  488     if ( nextPosition.
x() > 1 )
 
  490     if ( nextPosition.
x() < -1 )
 
  492     if ( nextPosition.
y() > 1 )
 
  494     if ( nextPosition.
y() < -1 )
 
  499     if ( incX != 0 || incY != 0 )
 
  501       data.directionX = incX;
 
  502       data.directionY = -incY;
 
  504       if ( chunkTrace.empty() )
 
  506         storeInField( QPair<QPoint, FieldData>( currentPixel, data ) );
 
  508       if ( addPixelToChunkTrace( currentPixel, data, chunkTrace ) )
 
  510         setChunkTrace( chunkTrace );
 
  511         drawChunkTrace( chunkTrace );
 
  512         clearChunkTrace( chunkTrace );
 
  516       currentPixel += QPoint( incX, -incY );
 
  517       x1 = nextPosition.
x() - 2 * incX;
 
  518       y1 = nextPosition.
y() - 2 * incY;
 
  548           x2 = x1 + ( 1 -  y1 ) * Vx / fabs( Vy ) ;
 
  550           x2 = x1 + ( 1 + y1 ) * Vx / fabs( Vy ) ;
 
  552           y2 = y1 + ( 1 - x1 ) * Vy / fabs( Vx ) ;
 
  554           y2 = y1 + ( 1 + x1 ) * Vy / fabs( Vx ) ;
 
  581       double dl = sqrt( dx * dx + dy * dy );
 
  583       data.time += dl / Vu ; 
 
  584       if ( data.time > 10000 ) 
 
  586         addPixelToChunkTrace( currentPixel, data, chunkTrace );
 
  587         setChunkTrace( chunkTrace );
 
  588         drawChunkTrace( chunkTrace );
 
  596     if ( isTraceExists( currentPixel ) )
 
  599       setChunkTrace( chunkTrace );
 
  600       addPixelToChunkTrace( currentPixel, data, chunkTrace );
 
  601       drawChunkTrace( chunkTrace );
 
  605     if ( isTraceOutside( currentPixel ) )
 
  607       setChunkTrace( chunkTrace );
 
  608       drawChunkTrace( chunkTrace );
 
  614 void QgsMeshStreamField::setResolution( 
int width )
 
  616   mFieldResolution = width;
 
  619 QSize QgsMeshStreamField::imageSize()
 const 
  621   return mFieldSize * mFieldResolution;
 
  624 QPointF QgsMeshStreamField::fieldToDevice( 
const QPoint &pixel )
 const 
  627   p = mFieldResolution * p + QPointF( mFieldResolution - 1, mFieldResolution - 1 ) / 2;
 
  631 bool QgsMeshStreamField::addPixelToChunkTrace( QPoint &pixel,
 
  632     QgsMeshStreamField::FieldData &data,
 
  633     std::list<QPair<QPoint, QgsMeshStreamField::FieldData> > &chunkTrace )
 
  635   chunkTrace.emplace_back( pixel, data );
 
  636   if ( chunkTrace.size() == 3 )
 
  638     simplifyChunkTrace( chunkTrace );
 
  644 void QgsMeshStreamlinesField::initField()
 
  646   mField = QVector<bool>( mFieldSize.width() * mFieldSize.height(), 
false );
 
  650 QgsMeshStreamlinesField::QgsMeshStreamlinesField( 
const QgsTriangularMesh &triangularMesh,
 
  655     bool dataIsOnVertices,
 
  658   QgsMeshStreamField( triangularMesh,
 
  660                       scalarActiveFaceFlagValues,
 
  668 QgsMeshStreamlinesField::QgsMeshStreamlinesField( 
const QgsMeshStreamlinesField &other ):
 
  669   QgsMeshStreamField( other ),
 
  670   mField( other.mField )
 
  673 QgsMeshStreamlinesField &QgsMeshStreamlinesField::operator=( 
const QgsMeshStreamlinesField &other )
 
  675   QgsMeshStreamField::operator=( other );
 
  676   mField = other.mField;
 
  680 void QgsMeshStreamlinesField::storeInField( 
const QPair<QPoint, FieldData> pixelData )
 
  682   int i = pixelData.first.x();
 
  683   int j = pixelData.first.y();
 
  684   if ( i >= 0 && i < mFieldSize.width() && j >= 0 && j < mFieldSize.height() )
 
  686     mField[j * mFieldSize.width() + i] = 
true;
 
  690 void QgsMeshStreamField::setChunkTrace( std::list<QPair<QPoint, FieldData> > &chunkTrace )
 
  692   auto p = chunkTrace.begin();
 
  693   while ( p != chunkTrace.end() )
 
  695     storeInField( ( *p ) );
 
  696     mPixelFillingCount++;
 
  701 void QgsMeshStreamlinesField::drawChunkTrace( 
const std::list<QPair<QPoint, QgsMeshStreamField::FieldData> > &chunkTrace )
 
  703   auto p1 = chunkTrace.begin();
 
  706   while ( p2 != chunkTrace.end() )
 
  708     double mag1 = ( *p1 ).second.magnitude;
 
  709     double mag2 = ( *p2 ).second.magnitude;
 
  710     if ( filterMag( mag1 ) && filterMag( mag2 ) )
 
  712       QPen pen = mPainter->pen();
 
  713       pen.setColor( mVectorColoring.color( ( mag1 + mag2 ) / 2 ) );
 
  714       mPainter->setPen( pen );
 
  715       mPainter->drawLine( fieldToDevice( ( *p1 ).first ), fieldToDevice( ( *p2 ).first ) );
 
  723 void QgsMeshStreamField::clearChunkTrace( std::list<QPair<QPoint, QgsMeshStreamField::FieldData> > &chunkTrace )
 
  725   auto one_before_end = std::prev( chunkTrace.end() );
 
  726   chunkTrace.erase( chunkTrace.begin(), one_before_end );
 
  729 void QgsMeshStreamField::simplifyChunkTrace( std::list<QPair<QPoint, FieldData> > &shunkTrace )
 
  731   if ( shunkTrace.size() != 3 )
 
  734   auto ip3 = shunkTrace.begin();
 
  738   while ( ip3 != shunkTrace.end() && ip2 != shunkTrace.end() )
 
  740     QPoint v1 = ( *ip1 ).first - ( *ip2 ).first;
 
  741     QPoint v2 = ( *ip2 ).first - ( *ip3 ).first;
 
  742     if ( v1.x()*v2.x() + v1.y()*v2.y() == 0 )
 
  744       ( *ip1 ).second.time += ( ( *ip2 ).second.time ) / 2;
 
  745       ( *ip3 ).second.time += ( ( *ip2 ).second.time ) / 2;
 
  746       ( *ip1 ).second.directionX += ( *ip2 ).second.directionX;
 
  747       ( *ip1 ).second.directionY += ( *ip2 ).second.directionY;
 
  748       shunkTrace.erase( ip2 );
 
  755 bool QgsMeshStreamlinesField::isTraceExists( 
const QPoint &pixel )
 const 
  759   if ( i >= 0 && i < mFieldSize.width() && j >= 0 && j < mFieldSize.height() )
 
  761     return mField[j * mFieldSize.width() + i];
 
  767 bool QgsMeshStreamField::isTraceOutside( 
const QPoint &pixel )
 const 
  771   if ( i >= 0 && i < mFieldSize.width() && j >= 0 && j < mFieldSize.height() )
 
  778 void QgsMeshStreamField::setMinimizeFieldSize( 
bool minimizeFieldSize )
 
  780   mMinimizeFieldSize = minimizeFieldSize;
 
  783 QgsMeshStreamField &QgsMeshStreamField::operator=( 
const QgsMeshStreamField &other )
 
  785   mFieldSize = other.mFieldSize ;
 
  786   mFieldResolution = other.mFieldResolution;
 
  788   mTraceImage = other.mTraceImage ;
 
  789   mMapToFieldPixel = other.mMapToFieldPixel ;
 
  790   mVectorColoring = other.mVectorColoring;
 
  791   mPixelFillingCount = other.mPixelFillingCount ;
 
  792   mMaxPixelFillingCount = other.mMaxPixelFillingCount ;
 
  793   mLayerExtent = other.mLayerExtent ;
 
  794   mMapExtent = other.mMapExtent;
 
  795   mFieldTopLeftInDeviceCoordinates = other.mFieldTopLeftInDeviceCoordinates ;
 
  796   mValid = other.mValid ;
 
  797   mMaximumMagnitude = other.mMaximumMagnitude ;
 
  798   mPixelFillingDensity = other.mPixelFillingDensity ;
 
  799   mMinMagFilter = other.mMinMagFilter ;
 
  800   mMaxMagFilter = other.mMaxMagFilter ;
 
  801   mMinimizeFieldSize = other.mMinimizeFieldSize ;
 
  802   mVectorValueInterpolator =
 
  803     std::unique_ptr<QgsMeshVectorValueInterpolator>( other.mVectorValueInterpolator->clone() );
 
  805   mPainter.reset( 
new QPainter( &mTraceImage ) );
 
  810 void QgsMeshStreamField::initImage()
 
  813   mTraceImage = QImage( mFieldSize * mFieldResolution, QImage::Format_ARGB32 );
 
  814   mTraceImage.fill( 0X00000000 );
 
  816   mPainter.reset( 
new QPainter( &mTraceImage ) );
 
  817   mPainter->setRenderHint( QPainter::Antialiasing, 
true );
 
  818   mPainter->setPen( mPen );
 
  821 bool QgsMeshStreamField::filterMag( 
double value )
 const 
  823   return ( mMinMagFilter < 0 || value > mMinMagFilter ) && ( mMaxMagFilter < 0 || value < mMaxMagFilter );
 
  826 QImage QgsMeshStreamField::image()
 
  828   return mTraceImage.scaled( mFieldSize * mFieldResolution, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
 
  831 void QgsMeshStreamField::setPixelFillingDensity( 
double maxFilling )
 
  833   mPixelFillingDensity = maxFilling;
 
  834   mMaxPixelFillingCount = int( mPixelFillingDensity * mFieldSize.width() * mFieldSize.height() );
 
  837 void QgsMeshStreamField::setColor( QColor color )
 
  839   mPen.setColor( color );
 
  842 void QgsMeshStreamField::setLineWidth( 
double width )
 
  844   mPen.setWidthF( width );
 
  847 void QgsMeshStreamField::setFilter( 
double min, 
double max )
 
  853 QgsMeshVectorValueInterpolatorFromFace::QgsMeshVectorValueInterpolatorFromFace( 
const QgsTriangularMesh &triangularMesh, 
const QgsMeshDataBlock &datasetVectorValues ):
 
  854   QgsMeshVectorValueInterpolator( triangularMesh, datasetVectorValues )
 
  858   QgsMeshVectorValueInterpolator( triangularMesh, datasetVectorValues, scalarActiveFaceFlagValues )
 
  861 QgsMeshVectorValueInterpolatorFromFace::QgsMeshVectorValueInterpolatorFromFace( 
const QgsMeshVectorValueInterpolatorFromFace &other ):
 
  862   QgsMeshVectorValueInterpolator( other )
 
  865 QgsMeshVectorValueInterpolatorFromFace *QgsMeshVectorValueInterpolatorFromFace::clone()
 
  867   return new QgsMeshVectorValueInterpolatorFromFace( *
this );
 
  870 QgsMeshVectorValueInterpolatorFromFace &QgsMeshVectorValueInterpolatorFromFace::operator=( 
const QgsMeshVectorValueInterpolatorFromFace &other )
 
  872   QgsMeshVectorValueInterpolator::operator=( other );
 
  876 QgsVector QgsMeshVectorValueInterpolatorFromFace::interpolatedValuePrivate( 
int faceIndex, 
const QgsPointXY point )
 const 
  878   QgsMeshFace face = mTriangularMesh.triangles().at( faceIndex );
 
  884   QgsVector vect = 
QgsVector( mDatasetValues.value( mTriangularMesh.trianglesToNativeFaces().at( faceIndex ) ).x(),
 
  885                               mDatasetValues.value( mTriangularMesh.trianglesToNativeFaces().at( faceIndex ) ).y() );
 
  887   return QgsMeshLayerUtils::interpolateVectorFromFacesData(
 
  895 QgsMeshVectorStreamlineRenderer::QgsMeshVectorStreamlineRenderer(
 
  899   bool dataIsOnVertices,
 
  903   mRendererContext( rendererContext )
 
  905   mStreamlineField.reset( 
new QgsMeshStreamlinesField( triangularMesh,
 
  907                           scalarActiveFaceFlagValues,
 
  914   mStreamlineField->updateSize( rendererContext );
 
  917                                   QgsUnitTypes::RenderUnit::RenderMillimeters ) ) ;
 
  918   mStreamlineField->setColor( settings.
color() );
 
  927         mStreamlineField->addTracesOnMesh( triangularMesh, rendererContext.
mapExtent() );
 
  930       mStreamlineField->addRandomTraces();
 
  935 void QgsMeshVectorStreamlineRenderer::draw()
 
  937   if ( mRendererContext.renderingStopped() )
 
  939   mRendererContext.painter()->drawImage( mStreamlineField->topLeft(), mStreamlineField->image() );
 
  942 QgsMeshParticleTracesField::QgsMeshParticleTracesField( 
const QgsTriangularMesh &triangularMesh,
 
  947     bool dataIsOnVertices,
 
  950   QgsMeshStreamField( triangularMesh,
 
  952                       scalarActiveFaceFlagValues,
 
  959   std::srand( uint( ::time( 
nullptr ) ) );
 
  960   mPen.setCapStyle( Qt::RoundCap );
 
  963 QgsMeshParticleTracesField::QgsMeshParticleTracesField( 
const QgsMeshParticleTracesField &other ):
 
  964   QgsMeshStreamField( other ),
 
  965   mTimeField( other.mTimeField ),
 
  966   mMagnitudeField( other.mMagnitudeField ),
 
  967   mDirectionField( other.mDirectionField ),
 
  968   mParticles( other.mParticles ),
 
  969   mStumpImage( other.mStumpImage ),
 
  970   mTimeStep( other.mTimeStep ),
 
  971   mParticlesLifeTime( other.mParticlesLifeTime ),
 
  972   mParticlesCount( other.mParticlesCount ),
 
  973   mTailFactor( other.mTailFactor ),
 
  974   mParticleColor( other.mParticleColor ),
 
  975   mParticleSize( other.mParticleSize ),
 
  976   mStumpFactor( other.mStumpFactor )
 
  979 void QgsMeshParticleTracesField::addParticle( 
const QPoint &startPoint, 
double lifeTime )
 
  981   addTrace( startPoint );
 
  982   if ( time( startPoint ) > 0 )
 
  984     QgsMeshTraceParticle p;
 
  985     p.lifeTime = lifeTime;
 
  986     p.position = startPoint;
 
  987     mParticles.append( p );
 
  992 void QgsMeshParticleTracesField::addParticleXY( 
const QgsPointXY &startPoint, 
double lifeTime )
 
  994   addParticle( mMapToFieldPixel.transform( startPoint ).toQPointF().toPoint(), lifeTime );
 
  997 void QgsMeshParticleTracesField::moveParticles()
 
 1000   for ( 
auto &p : mParticles )
 
 1002     double spentTime = p.remainingTime; 
 
 1003     size_t countAdded = 0;
 
 1004     while ( spentTime < mTimeStep && p.lifeTime > 0 )
 
 1006       double timeToSpend = double( time( p.position ) );
 
 1007       if ( timeToSpend > 0 )
 
 1009         p.lifeTime -= timeToSpend;
 
 1010         spentTime += timeToSpend;
 
 1011         QPoint dir = direction( p.position );
 
 1012         if ( p.lifeTime > 0 )
 
 1015           p.tail.emplace_back( p.position );
 
 1030     if ( p.lifeTime <= 0 )
 
 1038       p.remainingTime = spentTime - mTimeStep;
 
 1039       while ( 
int( p.tail.size() ) > mMinTailLength && p.tail.size() > countAdded * mTailFactor )
 
 1040         p.tail.erase( p.tail.begin() );
 
 1041       drawParticleTrace( p );
 
 1047   while ( i < mParticles.count() )
 
 1049     if ( mParticles.at( i ).tail.size() == 0 )
 
 1050       mParticles.removeAt( i );
 
 1056   if ( mParticles.count() < mParticlesCount )
 
 1057     addRandomParticles();
 
 1060 void QgsMeshParticleTracesField::addRandomParticles()
 
 1065   if ( mParticlesCount < 0 ) 
 
 1067     addParticleXY( 
QgsPointXY( mMapToFieldPixel.xCenter(), mMapToFieldPixel.yCenter() ), mParticlesLifeTime );
 
 1071   int count = mParticlesCount - mParticles.count();
 
 1073   for ( 
int i = 0; i < count; ++i )
 
 1075     int xRandom =  1 + std::rand() / int( ( RAND_MAX + 1u ) / uint( mFieldSize.width() ) )  ;
 
 1076     int yRandom = 1 + std::rand() / int ( ( RAND_MAX + 1u ) / uint( mFieldSize.height() ) ) ;
 
 1077     double lifeTime = ( std::rand() / ( ( RAND_MAX + 1u ) / mParticlesLifeTime ) );
 
 1078     addParticle( QPoint( xRandom, yRandom ), lifeTime );
 
 1082 void QgsMeshParticleTracesField::storeInField( 
const QPair<QPoint, QgsMeshStreamField::FieldData> pixelData )
 
 1084   int i = pixelData.first.x();
 
 1085   int j = pixelData.first.y();
 
 1086   if ( i >= 0 && i < mFieldSize.width() && j >= 0 && j < mFieldSize.height() )
 
 1088     mTimeField[j * mFieldSize.width() + i] = pixelData.second.time;
 
 1089     int d = pixelData.second.directionX + 2 + ( pixelData.second.directionY + 1 ) * 3;
 
 1090     mDirectionField[j * mFieldSize.width() + i] = 
static_cast<char>( d );
 
 1091     mMagnitudeField[j * mFieldSize.width() + i] = pixelData.second.magnitude;
 
 1095 void QgsMeshParticleTracesField::initField()
 
 1097   mTimeField = QVector<float>( mFieldSize.width() * mFieldSize.height(), -1 );
 
 1098   mDirectionField = QVector<char>( mFieldSize.width() * mFieldSize.height(), 
static_cast<char>( 
int( 0 ) ) );
 
 1099   mMagnitudeField = QVector<float>( mFieldSize.width() * mFieldSize.height(), 0 );
 
 1101   mStumpImage = QImage( mFieldSize * mFieldResolution, QImage::Format_ARGB32 );
 
 1102   mStumpImage.fill( QColor( 0, 0, 0, mStumpFactor ) ); 
 
 1105 bool QgsMeshParticleTracesField::isTraceExists( 
const QPoint &pixel )
 const 
 1109   if ( i >= 0 && i < mFieldSize.width() && j >= 0 && j < mFieldSize.height() )
 
 1111     return mTimeField[j * mFieldSize.width() + i] >= 0;
 
 1117 void QgsMeshParticleTracesField::setStumpParticleWithLifeTime( 
bool stumpParticleWithLifeTime )
 
 1119   mStumpParticleWithLifeTime = stumpParticleWithLifeTime;
 
 1122 void QgsMeshParticleTracesField::setParticlesColor( 
const QColor &
c )
 
 1124   mVectorColoring.setColor( 
c );
 
 1127 void QgsMeshParticleTracesField::setMinTailLength( 
int minTailLength )
 
 1129   mMinTailLength = minTailLength;
 
 1132 QgsMeshParticleTracesField &QgsMeshParticleTracesField::operator=( 
const QgsMeshParticleTracesField &other )
 
 1134   QgsMeshStreamField::operator=( other );
 
 1135   mTimeField = other.mTimeField;
 
 1136   mDirectionField = other.mDirectionField;
 
 1137   mParticles = other.mParticles;
 
 1138   mStumpImage = other.mStumpImage;
 
 1139   mTimeStep = other.mTimeStep;
 
 1140   mParticlesLifeTime = other.mParticlesLifeTime;
 
 1141   mParticlesCount = other.mParticlesCount;
 
 1142   mTailFactor = other.mTailFactor;
 
 1143   mParticleColor = other.mParticleColor;
 
 1144   mParticleSize = other.mParticleSize;
 
 1145   mStumpFactor = other.mStumpFactor;
 
 1150 void QgsMeshParticleTracesField::setTailFactor( 
double tailFactor )
 
 1152   mTailFactor = tailFactor;
 
 1155 void QgsMeshParticleTracesField::setParticleSize( 
double particleSize )
 
 1157   mParticleSize = particleSize;
 
 1160 void QgsMeshParticleTracesField::setTimeStep( 
double timeStep )
 
 1162   mTimeStep = timeStep;
 
 1165 void QgsMeshParticleTracesField::setParticlesLifeTime( 
double particlesLifeTime )
 
 1167   mParticlesLifeTime = particlesLifeTime;
 
 1170 QImage QgsMeshParticleTracesField::imageRendered()
 const 
 1175 void QgsMeshParticleTracesField::stump()
 
 1178   mPainter->setCompositionMode( QPainter::CompositionMode_DestinationIn );
 
 1179   mPainter->drawImage( QPoint( 0, 0 ), mStumpImage );
 
 1182 void QgsMeshParticleTracesField::setStumpFactor( 
int sf )
 
 1185   mStumpImage = QImage( mFieldSize * mFieldResolution, QImage::Format_ARGB32 );
 
 1186   mStumpImage.fill( QColor( 0, 0, 0, mStumpFactor ) );
 
 1189 QPoint QgsMeshParticleTracesField::direction( QPoint position )
 const 
 1191   int i = position.x();
 
 1192   int j = position.y();
 
 1193   if ( i >= 0 && i < mFieldSize.width() && j >= 0 && j < mFieldSize.height() )
 
 1195     int dir = 
static_cast<int>( mDirectionField[j * mFieldSize.width() + i] );
 
 1196     if ( dir != 0 && dir < 10 )
 
 1197       return QPoint( ( dir - 1 ) % 3 - 1, ( dir - 1 ) / 3 - 1 );
 
 1199   return QPoint( 0, 0 );
 
 1202 float QgsMeshParticleTracesField::time( QPoint position )
 const 
 1204   int i = position.x();
 
 1205   int j = position.y();
 
 1206   if ( i >= 0 && i < mFieldSize.width() && j >= 0 && j < mFieldSize.height() )
 
 1208     return mTimeField[j * mFieldSize.width() + i];
 
 1213 float QgsMeshParticleTracesField::magnitude( QPoint position )
 const 
 1215   int i = position.x();
 
 1216   int j = position.y();
 
 1217   if ( i >= 0 && i < mFieldSize.width() && j >= 0 && j < mFieldSize.height() )
 
 1219     return mMagnitudeField[j * mFieldSize.width() + i];
 
 1224 void QgsMeshParticleTracesField::drawParticleTrace( 
const QgsMeshTraceParticle &particle )
 
 1226   const std::list<QPoint> &tail = particle.tail;
 
 1227   if ( tail.size() == 0 )
 
 1229   double iniWidth = mParticleSize;
 
 1230   double finWidth = 0;
 
 1232   size_t pixelCount = tail.size();
 
 1234   double transparency = 1;
 
 1235   if ( mStumpParticleWithLifeTime )
 
 1236     transparency = sin( M_PI * particle.lifeTime / mParticlesLifeTime );
 
 1239   if ( pixelCount > 1 )
 
 1240     dw = ( iniWidth - finWidth ) / ( pixelCount );
 
 1244   auto ip1 = std::prev( tail.end() );
 
 1245   auto ip2 = std::prev( ip1 );
 
 1247   while ( ip1 != tail.begin() )
 
 1249     QPointF p1 = fieldToDevice( ( *ip1 ) );
 
 1250     QPointF p2 = fieldToDevice( ( *ip2 ) );
 
 1251     QColor traceColor = mVectorColoring.color( magnitude( *ip1 ) );
 
 1252     traceColor.setAlphaF( traceColor.alphaF()*transparency );
 
 1253     mPen.setColor( traceColor );
 
 1254     mPen.setWidthF( iniWidth - i * dw );
 
 1255     mPainter->setPen( mPen );
 
 1256     mPainter->drawLine( p1, p2 );
 
 1263 void QgsMeshParticleTracesField::setParticlesCount( 
int particlesCount )
 
 1265   mParticlesCount = particlesCount;
 
 1271     bool dataIsOnVertices,
 
 1276   mRendererContext( rendererContext )
 
 1278   mParticleField = std::unique_ptr<QgsMeshParticleTracesField>( 
new QgsMeshParticleTracesField( triangularMesh,
 
 1279                    dataSetVectorValues,
 
 1280                    scalarActiveFaceFlagValues,
 
 1286   mParticleField->updateSize( rendererContext ) ;
 
 1290   mRendererContext( rendererContext )
 
 1297   bool vectorDataOnVertices;
 
 1307   if ( ( cache->mDatasetGroupsCount == datasetGroupCount ) &&
 
 1308        ( cache->mActiveVectorDatasetIndex == datasetIndex ) )
 
 1310     vectorDatasetValues = cache->mVectorDatasetValues;
 
 1311     scalarActiveFaceFlagValues = cache->mScalarActiveFaceFlagValues;
 
 1312     magMax = cache->mVectorDatasetMagMaximum;
 
 1323     if ( vectorDataOnVertices )
 
 1328     vectorDatasetValues = QgsMeshLayerUtils::datasetValues( layer, datasetIndex, 0, count );
 
 1336   mParticleField = std::unique_ptr<QgsMeshParticleTracesField>( 
new QgsMeshParticleTracesField( ( *layer->
triangularMesh() ),
 
 1337                    vectorDatasetValues,
 
 1338                    scalarActiveFaceFlagValues,
 
 1341                    vectorDataOnVertices,
 
 1345   mParticleField->setMinimizeFieldSize( 
false );
 
 1346   mParticleField->updateSize( mRendererContext );
 
 1350   mRendererContext( other.mRendererContext ),
 
 1352   mVpixMax( other.mVpixMax ),
 
 1353   mParticleLifeTime( other.mParticleLifeTime )
 
 1355   mParticleField = std::unique_ptr<QgsMeshParticleTracesField>(
 
 1356                      new QgsMeshParticleTracesField( *other.mParticleField ) );
 
 1362   mParticleField->setParticlesCount( count );
 
 1363   mParticleField->addRandomParticles();
 
 1368   mParticleField->moveParticles();
 
 1369   return mParticleField->image();
 
 1379   updateFieldParameter();
 
 1385   updateFieldParameter();
 
 1390   mParticleLifeTime = particleLifeTime;
 
 1391   updateFieldParameter();
 
 1396   mParticleField->setParticlesColor( 
c );
 
 1401   mParticleField->setParticleSize( width );
 
 1406   mParticleField->setTailFactor( fct );
 
 1411   mParticleField->setMinTailLength( l );
 
 1420   mParticleField->setStumpFactor( 
int( 255 * p ) );
 
 1425   mParticleField.reset( 
new QgsMeshParticleTracesField( *mParticleField ) );
 
 1426   const_cast<QgsRenderContext &
>( mRendererContext ) = other.mRendererContext;
 
 1428   mVpixMax = other.mVpixMax;
 
 1429   mParticleLifeTime = other.mParticleLifeTime;
 
 1434 void QgsMeshVectorTraceAnimationGenerator::updateFieldParameter()
 
 1436   double fieldTimeStep = mVpixMax / mFPS;
 
 1437   double fieldLifeTime = mParticleLifeTime * mFPS * fieldTimeStep;
 
 1438   mParticleField->setTimeStep( fieldTimeStep );
 
 1439   mParticleField->setParticlesLifeTime( fieldLifeTime );
 
 1442 QgsMeshVectorTraceRenderer::QgsMeshVectorTraceRenderer(
 
 1446   bool dataIsOnVertices,
 
 1451   mRendererContext( rendererContext )
 
 1453   mParticleField = std::unique_ptr<QgsMeshParticleTracesField>( 
new QgsMeshParticleTracesField( triangularMesh,
 
 1454                    dataSetVectorValues,
 
 1455                    scalarActiveFaceFlagValues,
 
 1461   mParticleField->updateSize( rendererContext ) ;
 
 1464                                      settings.
lineWidth(), QgsUnitTypes::RenderUnit::RenderMillimeters ) );
 
 1466   mParticleField->setTailFactor( 1 );
 
 1467   mParticleField->setStumpParticleWithLifeTime( 
false );
 
 1470   mParticleField->addRandomParticles();
 
 1471   mParticleField->moveParticles();
 
 1474 void QgsMeshVectorTraceRenderer::draw()
 
 1476   if ( mRendererContext.renderingStopped() )
 
 1478   mRendererContext.painter()->drawImage( mParticleField->topLeft(), mParticleField->image() );
 
QgsVertexIterator vertices() const
Returns a read-only, Java-style iterator for traversal of vertices of all the geometry,...
Custom exception class for Coordinate Reference System related exceptions.
Class defining color to render mesh datasets.
Perform transforms between map coordinates and device coordinates.
double mapUnitsPerPixel() const
Returns current map units per pixel.
QgsPointXY toMapCoordinates(int x, int y) const
Transform device coordinates to map (world) coordinates.
double mapRotation() const
Returns current map rotation in degrees (clockwise)
QgsMeshDataBlock is a block of integers/doubles that can be used to retrieve: active flags (e....
bool isValid() const
Whether the block is valid.
QgsMeshDatasetIndex is index that identifies the dataset group (e.g.
int group() const
Returns a group index.
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.
virtual int datasetGroupCount() const =0
Returns number of datasets groups loaded.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
QgsRectangle extent() const override
Returns the extent of the layer.
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
void reload() override
Synchronises with changes in the datasource.
QgsMesh * nativeMesh()
Returns native mesh (nullptr before rendering or calling to updateMesh)
QgsMeshDatasetIndex activeVectorDatasetAtTime(const QgsDateTimeRange &timeRange) const
Returns dataset index from active vector group depending on the time range If the temporal properties...
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsTriangularMesh * triangularMesh(double minimumTriangleSize=0) const
Returns triangular mesh (nullptr before rendering or calling to updateMesh).
QgsMeshLayerRendererCache * rendererCache()
Returns native mesh (nullptr before rendering)
QgsMeshRendererVectorSettings vectorSettings(int groupIndex) const
Returns renderer settings.
Represents a renderer settings for vector datasets.
int userGridCellWidth() const
Returns width in pixels of user grid cell.
QgsMeshRendererVectorTracesSettings tracesSettings() const
Returns settings for vector rendered with traces.
QColor color() const
Returns color used for drawing arrows.
int userGridCellHeight() const
Returns height in pixels of user grid cell.
double lineWidth() const
Returns line width of the arrow (in millimeters)
double filterMax() const
Returns filter value for vector magnitudes.
QgsInterpolatedLineColor vectorStrokeColoring() const
Returns the stroke coloring used to render vector datasets.
bool isOnUserDefinedGrid() const
Returns whether vectors are drawn on user-defined grid.
double filterMin() const
Returns filter value for vector magnitudes.
QgsMeshRendererVectorStreamlineSettings streamLinesSettings() const
Returns settings for vector rendered with streamlines.
SeedingStartPointsMethod seedingMethod() const
Returns the method used for seeding start points of strealines.
@ Random
Seeds start points randomly on the mesh.
@ MeshGridded
Seeds start points on the vertices mesh or user regular grid.
double seedingDensity() const
Returns the density used for seeding start points.
double maximumTailLength() const
Returns the maximum tail length.
QgsUnitTypes::RenderUnit maximumTailLengthUnit() const
Returns the maximum tail length unit.
int particlesCount() const
Returns particles count.
A wrapper for QgsMeshParticuleTracesField used to render the particles.
void setParticlesLifeTime(double particleLifeTime)
Sets maximum life time of particles in seconds.
void setMinimumTailLength(int l)
Sets the minimum tail length.
void setTailPersitence(double p)
Sets the visual persistence of the tail.
void setParticlesColor(const QColor &c)
Sets colors of particle.
QImage imageRendered()
Moves all the particles using frame per second (fps) to calculate the displacement and return the ren...
void setTailFactor(double fct)
Sets the tail factor, used to adjust the length of the tail. 0 : minimum length, >1 increase the tail...
void setFPS(int FPS)
Sets the number of frames per seconds that will be rendered.
QgsMeshVectorTraceAnimationGenerator(const QgsTriangularMesh &triangularMesh, const QgsMeshDataBlock &dataSetVectorValues, const QgsMeshDataBlock &scalarActiveFaceFlagValues, bool dataIsOnVertices, const QgsRenderContext &rendererContext, const QgsRectangle &layerExtent, double magMax, const QgsMeshRendererVectorSettings &vectorSettings)
Constructor to use from QgsMeshVectorRenderer.
void setParticlesSize(double width)
Sets particle size in px.
void setMaxSpeedPixel(int max)
Sets the max number of pixels that can be go through by the particles in 1 second.
QgsMeshVectorTraceAnimationGenerator & operator=(const QgsMeshVectorTraceAnimationGenerator &other)
Assignment operator.
void seedRandomParticles(int count)
seeds particles in the vector fields
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
A rectangle specified with double values.
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Contains information about the context of a rendering operation.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QgsRectangle mapExtent() const
Returns the original extent of the map being rendered.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Scoped object for saving and restoring a QPainter object's state.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
Triangular/Derived Mesh is mesh with vertices in map coordinates.
const QVector< QgsMeshFace > & triangles() const
Returns triangles.
const QVector< QgsMeshVertex > & vertices() const
Returns vertices in map coordinate system.
QList< int > faceIndexesForRectangle(const QgsRectangle &rectangle) const
Finds indexes of triangles intersecting given bounding box It uses spatial indexing.
A class to represent a vector.
QgsVector rotateBy(double rot) const SIP_HOLDGIL
Rotates the vector by a specified angle.
double y() const SIP_HOLDGIL
Returns the vector's y-component.
double x() const SIP_HOLDGIL
Returns the vector's x-component.
double length() const SIP_HOLDGIL
Returns the length of the vector.
bool isInTriangleFace(const QgsPointXY point, const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Tests if point p is on the face defined with vertices.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
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.
QVector< QgsMeshVertex > vertices
QVector< QgsMeshFace > faces