43 mNativeMesh.reset(
new QgsMesh() );
52 mTriangularMesh->update( mNativeMesh.get(), &context );
66 if ( !mTriangularMesh )
69 if ( min_value > max_value )
71 double tmp = max_value;
72 max_value = min_value;
76 QVector<QgsGeometry> multiPolygon;
79 populateCache( index, method );
80 const QVector<QgsMeshVertex> vertices = mTriangularMesh->vertices();
81 const QVector<int> &trianglesToNativeFaces = mTriangularMesh->trianglesToNativeFaces();
84 for (
int i = 0; i < mTriangularMesh->triangles().size(); ++i )
89 int nativeIndex = trianglesToNativeFaces.at( i );
90 if ( !mScalarActiveFaceFlagValues.
active( nativeIndex ) )
93 const QgsMeshFace &triangle = mTriangularMesh->triangles().at( i );
94 const int indices[3] =
101 const QVector<QgsMeshVertex> coords =
103 vertices.at( indices[0] ),
104 vertices.at( indices[1] ),
105 vertices.at( indices[2] )
108 const double values[3] =
110 mDatasetValues.at( indices[0] ),
111 mDatasetValues.at( indices[1] ),
112 mDatasetValues.at( indices[2] )
116 if ( std::isnan( values[0] ) || std::isnan( values[1] ) || std::isnan( values[2] ) )
120 if ( ( ( min_value > values[0] ) && ( min_value > values[1] ) && ( min_value > values[2] ) ) ||
121 ( ( max_value < values[0] ) && ( max_value < values[1] ) && ( max_value < values[2] ) ) )
124 const bool valueInRange[3] =
126 ( min_value <= values[0] ) &&( max_value >= values[0] ),
127 ( min_value <= values[1] ) &&( max_value >= values[1] ),
128 ( min_value <= values[2] ) &&( max_value >= values[2] )
132 if ( valueInRange[0] && valueInRange[1] && valueInRange[2] )
134 QVector<QgsMeshVertex> ring = coords;
135 ring.push_back( coords[0] );
136 std::unique_ptr< QgsLineString > ext = qgis::make_unique< QgsLineString> ( coords );
137 std::unique_ptr< QgsPolygon > poly = qgis::make_unique< QgsPolygon >();
138 poly->setExteriorRing( ext.release() );
139 multiPolygon.push_back(
QgsGeometry( std::move( poly ) ) );
144 QVector<QgsMeshVertex> ring;
145 for (
int i = 0; i < 3; ++i )
147 const int j = ( i + 1 ) % 3;
149 if ( valueInRange[i] )
151 if ( valueInRange[j] )
154 if ( !ring.contains( coords[i] ) )
155 ring.push_back( coords[i] );
156 if ( !ring.contains( coords[j] ) )
157 ring.push_back( coords[j] );
162 if ( !ring.contains( coords[i] ) )
163 ring.push_back( coords[i] );
165 double value = max_value;
166 if ( values[i] > values[j] )
170 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
172 if ( !ring.contains( xy ) )
173 ring.push_back( xy );
178 if ( valueInRange[j] )
181 double value = max_value;
182 if ( values[i] < values[j] )
187 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
189 if ( !ring.contains( xy ) )
190 ring.push_back( xy );
193 if ( !ring.contains( coords[j] ) )
194 ring.push_back( coords[j] );
201 double value1 = max_value;
202 double value2 = max_value;
203 if ( values[i] < values[j] )
205 if ( ( min_value < values[i] ) || ( max_value > values[j] ) )
213 if ( ( min_value < values[j] ) || ( max_value > values[i] ) )
220 const double fraction1 = ( value1 - values[i] ) / ( values[j] - values[i] );
222 if ( !ring.contains( xy1 ) )
223 ring.push_back( xy1 );
225 const double fraction2 = ( value2 - values[i] ) / ( values[j] - values[i] );
227 if ( !ring.contains( xy2 ) )
228 ring.push_back( xy2 );
234 if ( ring.size() > 2 )
236 std::unique_ptr< QgsLineString > ext = qgis::make_unique< QgsLineString> ( ring );
237 std::unique_ptr< QgsPolygon > poly = qgis::make_unique< QgsPolygon >();
238 poly->setExteriorRing( ext.release() );
239 multiPolygon.push_back(
QgsGeometry( std::move( poly ) ) );
244 if ( multiPolygon.isEmpty() )
261 if ( !mTriangularMesh )
265 QSet<QPair<int, int>> exactEdges;
268 populateCache( index, method );
269 QVector<QgsMeshVertex> vertices = mTriangularMesh->vertices();
270 const QVector<int> &trianglesToNativeFaces = mTriangularMesh->trianglesToNativeFaces();
273 for (
int i = 0; i < mTriangularMesh->triangles().size(); ++i )
278 int nativeIndex = trianglesToNativeFaces.at( i );
279 if ( !mScalarActiveFaceFlagValues.
active( nativeIndex ) )
282 const QgsMeshFace &triangle = mTriangularMesh->triangles().at( i );
284 const int indices[3] =
291 const QVector<QgsMeshVertex> coords =
293 vertices.at( indices[0] ),
294 vertices.at( indices[1] ),
295 vertices.at( indices[2] )
298 const double values[3] =
300 mDatasetValues.at( indices[0] ),
301 mDatasetValues.at( indices[1] ),
302 mDatasetValues.at( indices[2] )
306 if ( std::isnan( values[0] ) || std::isnan( values[1] ) || std::isnan( values[2] ) )
310 if ( ( ( value > values[0] ) && ( value > values[1] ) && ( value > values[2] ) ) ||
311 ( ( value > values[0] ) && ( value > values[1] ) && ( value > values[2] ) ) )
321 for (
int i = 0; i < 3; ++i )
323 const int j = ( i + 1 ) % 3;
325 if ( ( ( value > values[i] ) && ( value > values[j] ) ) ||
326 ( ( value < values[i] ) && ( value < values[j] ) ) )
332 if ( exactEdges.contains( { indices[i], indices[j] } ) || exactEdges.contains( { indices[j], indices[i] } ) )
338 exactEdges.insert( { indices[i], indices[j] } );
339 std::unique_ptr<QgsLineString> line(
new QgsLineString( coords[i], coords[j] ) );
340 multiLineString->addGeometry( line.release() );
352 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
355 if ( std::isnan( tmp.
x() ) )
363 std::unique_ptr<QgsLineString> line(
new QgsLineString( tmp, xy ) );
364 multiLineString->addGeometry( line.release() );
371 if ( multiLineString->isEmpty() )
385 if ( mCachedIndex != index )
388 int count = scalarDataOnVertices ? mNativeMesh->vertices.count() : mNativeMesh->faces.count();
399 mDatasetValues = QgsMeshLayerUtils::calculateMagnitudes( vals );
403 mDatasetValues = QVector<double>( count, std::numeric_limits<double>::quiet_NaN() );
410 mNativeMesh->faces.count() );
413 if ( ( !scalarDataOnVertices ) )
415 mDatasetValues = QgsMeshLayerUtils::interpolateFromFacesData(
418 mTriangularMesh.get(),
419 &mScalarActiveFaceFlagValues,
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
void setExtent(const QgsRectangle &rect, bool magnified=true)
Set coordinates of the rectangle which should be rendered.
Triangular/Derived Mesh is mesh with vertices in map coordinates.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QgsMeshDataBlock is a block of integers/doubles that can be used to retrieve: active flags (e...
void setOutputDpi(double dpi)
Sets DPI used for conversion between real world units (e.g. mm) and pixels.
Multi line string geometry collection.
A geometry is the spatial representation of a feature.
The QgsMapSettings class contains configuration for rendering of the map.
bool active(int index) const
Returns a value for active flag by the index For scalar and vector 2d the behavior is undefined...
Base class for feedback objects to be used for cancellation of something running in a worker thread...
QgsGeometry mergeLines() const
Merges any connected lines in a LineString/MultiLineString geometry and converts them to single line ...
QgsRectangle extent() const override
Returns the extent of the layer.
DataInterpolationMethod
Interpolation of value defined on vertices from datasets with data defined on faces.
virtual bool isValid() const =0
Returns true if this is a valid layer.
QgsGeometry exportPolygons(const QgsMeshDatasetIndex &index, double min_value, double max_value, QgsMeshRendererScalarSettings::DataInterpolationMethod method, QgsFeedback *feedback=nullptr)
Exports multi polygons representing the areas with values in range for particular dataset...
QgsMeshContours(QgsMeshLayer *layer)
Constructs the mesh contours exporter.
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
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, y1) to (x2, y2).
Point geometry type, with support for z-dimension and m-values.
virtual void populateMesh(QgsMesh *mesh) const =0
Populates the mesh vertices and faces.
QgsGeometry exportLines(const QgsMeshDatasetIndex &index, double value, QgsMeshRendererScalarSettings::DataInterpolationMethod method, QgsFeedback *feedback=nullptr)
Exports multi line string containing the contour line for particular dataset and value.
Contains information about the context of a rendering operation.
Mesh - vertices and faces.
bool isCanceled() const
Tells whether the operation has been canceled already.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
Line string geometry type, with support for z-dimension and m-values.
bool isValid() const
Whether the block is valid.
QVector< int > QgsMeshFace
List of vertex indexes.
QgsMeshDatasetIndex is index that identifies the dataset group (e.g.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries)
Compute the unary union on a list of geometries.
QgsCoordinateReferenceSystem crs
virtual QgsMeshDataBlock areFacesActive(QgsMeshDatasetIndex index, int faceIndex, int count) const =0
Returns whether the faces are active for particular dataset.
virtual QgsMeshDatasetGroupMetadata datasetGroupMetadata(int groupIndex) const =0
Returns dataset group metadata.