QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsmeshlayerinterpolator.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmeshlayerinterpolator.cpp
3  ----------------------------
4  begin : April 2018
5  copyright : (C) 2018 by Peter Petrik
6  email : zilolv 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 
19 
20 #include <memory>
21 
23 
24 #include "qgsrasterinterface.h"
25 #include "qgsmaptopixel.h"
26 #include "qgsvector.h"
27 #include "qgspoint.h"
28 #include "qgspointxy.h"
29 #include "qgsmeshlayerutils.h"
30 
31 QgsMeshLayerInterpolator::QgsMeshLayerInterpolator( const QgsTriangularMesh &m,
32  const QVector<double> &datasetValues, const QVector<bool> &activeFaceFlagValues,
33  bool dataIsOnVertices,
34  const QgsRenderContext &context,
35  const QSize &size )
36  : mTriangularMesh( m ),
37  mDatasetValues( datasetValues ),
38  mActiveFaceFlagValues( activeFaceFlagValues ),
39  mContext( context ),
40  mDataOnVertices( dataIsOnVertices ),
41  mOutputSize( size )
42 {
43 }
44 
45 QgsMeshLayerInterpolator::~QgsMeshLayerInterpolator() = default;
46 
47 QgsRasterInterface *QgsMeshLayerInterpolator::clone() const
48 {
49  assert( false ); // we should not need this (hopefully)
50  return nullptr;
51 }
52 
53 Qgis::DataType QgsMeshLayerInterpolator::dataType( int ) const
54 {
55  return Qgis::Float64;
56 }
57 
58 int QgsMeshLayerInterpolator::bandCount() const
59 {
60  return 1;
61 }
62 
63 QgsRasterBlock *QgsMeshLayerInterpolator::block( int, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback )
64 {
65  std::unique_ptr<QgsRasterBlock> outputBlock( new QgsRasterBlock( Qgis::Float64, width, height ) );
66  outputBlock->setIsNoData(); // assume initially that all values are unset
67  double *data = reinterpret_cast<double *>( outputBlock->bits() );
68 
69  const QVector<QgsMeshFace> &triangles = mTriangularMesh.triangles();
70  const QVector<QgsMeshVertex> &vertices = mTriangularMesh.vertices();
71 
72  // currently expecting that triangulation does not add any new extra vertices on the way
73  if ( mDataOnVertices )
74  Q_ASSERT( mDatasetValues.count() == mTriangularMesh.vertices().count() );
75 
76  for ( int i = 0; i < triangles.size(); ++i )
77  {
78  if ( feedback && feedback->isCanceled() )
79  break;
80 
81  if ( mContext.renderingStopped() )
82  break;
83 
84  const QgsMeshFace &face = triangles[i];
85 
86  const int v1 = face[0], v2 = face[1], v3 = face[2];
87  const QgsPoint p1 = vertices[v1], p2 = vertices[v2], p3 = vertices[v3];
88 
89  const int nativeFaceIndex = mTriangularMesh.trianglesToNativeFaces()[i];
90  const bool isActive = mActiveFaceFlagValues[nativeFaceIndex];
91  if ( !isActive )
92  continue;
93 
94  QgsRectangle bbox = QgsMeshLayerUtils::triangleBoundingBox( p1, p2, p3 );
95  if ( !extent.intersects( bbox ) )
96  continue;
97 
98  // Get the BBox of the element in pixels
99  int topLim, bottomLim, leftLim, rightLim;
100  QgsMeshLayerUtils::boundingBoxToScreenRectangle( mContext.mapToPixel(), mOutputSize, bbox, leftLim, rightLim, topLim, bottomLim );
101 
102  // interpolate in the bounding box of the face
103  for ( int j = topLim; j <= bottomLim; j++ )
104  {
105  double *line = data + ( j * width );
106  for ( int k = leftLim; k <= rightLim; k++ )
107  {
108  double val;
109  const QgsPointXY p = mContext.mapToPixel().toMapCoordinates( k, j );
110  if ( mDataOnVertices )
111  val = QgsMeshLayerUtils::interpolateFromVerticesData(
112  p1,
113  p2,
114  p3,
115  mDatasetValues[v1],
116  mDatasetValues[v2],
117  mDatasetValues[v3],
118  p );
119  else
120  {
121  int face = mTriangularMesh.trianglesToNativeFaces()[i];
122  val = QgsMeshLayerUtils::interpolateFromFacesData(
123  p1,
124  p2,
125  p3,
126  mDatasetValues[face],
127  p
128  );
129  }
130 
131  if ( !std::isnan( val ) )
132  {
133  line[k] = val;
134  outputBlock->setIsData( j, k );
135  }
136  }
137  }
138 
139  }
140 
141  return outputBlock.release();;
142 }
143 
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
bool intersects(const QgsRectangle &rect) const
Returns true when rectangle intersects with other rectangle.
Definition: qgsrectangle.h:327
A rectangle specified with double values.
Definition: qgsrectangle.h:40
Triangular/Derived Mesh is mesh with vertices in map coordinates.
A class to represent a 2D point.
Definition: qgspointxy.h:43
DataType
Raster data types.
Definition: qgis.h:92
Sixty four bit floating point (double)
Definition: qgis.h:101
QgsRectangle extent() const override
Returns the extent of the layer.
Raster data container.
Base class for processing filters like renderers, reprojector, resampler etc.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
Contains information about the context of a rendering operation.
QVector< int > QgsMeshFace
List of vertex indexes.
Feedback object tailored for raster block reading.