30 #include <QTextStream>
35 static QgsFields createFields(
const QList<QgsMeshDatasetGroupMetadata> &groupMetadataList,
int vectorOption )
40 if ( meta.isVector() )
42 if ( vectorOption == 0 || vectorOption == 2 )
44 fields.
append( QStringLiteral(
"%1_x" ).arg( meta.name() ) );
45 fields.
append( QStringLiteral(
"%1_y" ).arg( meta.name() ) );
48 if ( vectorOption == 1 || vectorOption == 2 )
50 fields.
append( QStringLiteral(
"%1_mag" ).arg( meta.name() ) );
51 fields.
append( QStringLiteral(
"%1_dir" ).arg( meta.name() ) );
55 fields.
append( meta.name() );
62 QVector<double> ret( exportOption == 2 ? 4 : 2 );
64 if ( exportOption == 0 || exportOption == 2 )
69 if ( exportOption == 1 || exportOption == 2 )
73 double magnitude = sqrt( x * x + y * y );
74 double direction = ( asin( x / magnitude ) ) / M_PI * 180;
76 direction = 180 - direction;
78 if ( exportOption == 1 )
83 if ( exportOption == 2 )
96 QVector<double> vectorValues = vectorValue( value, vectorOption );
97 for (
double v : vectorValues )
99 if ( v == std::numeric_limits<double>::quiet_NaN() )
100 attributes.append( QVariant() );
102 attributes.append( v );
107 if ( value.
scalar() == std::numeric_limits<double>::quiet_NaN() )
108 attributes.append( QVariant() );
110 attributes.append( value.
scalar() );
117 int triangularFaceIndex,
123 bool faceActive = activeFaces.
active( nativeFaceIndex );
135 value = datasetValues.
value( nativeFaceIndex );
142 const int v1 = face[0], v2 = face[1], v3 = face[2];
147 const double x = QgsMeshLayerUtils::interpolateFromVerticesData( p1, p2, p3, val1.
x(), val2.
x(), val3.
x(), point );
148 double y = std::numeric_limits<double>::quiet_NaN();
149 bool isVector = metadata.
isVector();
151 y = QgsMeshLayerUtils::interpolateFromVerticesData( p1, p2, p3, val1.
y(), val2.
y(), val3.
y(), point );
162 QString QgsExportMeshOnElement::group()
const
164 return QObject::tr(
"Mesh" );
167 QString QgsExportMeshOnElement::groupId()
const
169 return QStringLiteral(
"mesh" );
172 QString QgsExportMeshVerticesAlgorithm::shortHelpString()
const
174 return QObject::tr(
"Exports mesh layer's vertices to a point vector layer, with the dataset values on vertices as attribute values" );
177 QString QgsExportMeshVerticesAlgorithm::name()
const
179 return QStringLiteral(
"exportmeshvertices" );
182 QString QgsExportMeshVerticesAlgorithm::displayName()
const
184 return QObject::tr(
"Export mesh vertices" );
189 return new QgsExportMeshVerticesAlgorithm();
192 QgsGeometry QgsExportMeshVerticesAlgorithm::meshElement(
int index )
const
197 void QgsExportMeshOnElement::initAlgorithm(
const QVariantMap &configuration )
199 Q_UNUSED( configuration );
205 QStringLiteral(
"DATASET_GROUPS" ),
206 QObject::tr(
"Dataset groups" ),
207 QStringLiteral(
"INPUT" ),
208 supportedDataType(),
true ) );
211 QStringLiteral(
"DATASET_TIME" ),
212 QObject::tr(
"Dataset time" ),
213 QStringLiteral(
"INPUT" ),
214 QStringLiteral(
"DATASET_GROUPS" ) ) );
216 addParameter(
new QgsProcessingParameterCrs( QStringLiteral(
"CRS_OUTPUT" ), QObject::tr(
"Output coordinate system" ), QVariant(),
true ) );
218 QStringList exportVectorOptions;
219 exportVectorOptions << QObject::tr(
"Cartesian (x,y)" )
220 << QObject::tr(
"Polar (magnitude,degree)" )
221 << QObject::tr(
"Cartesian and Polar" );
222 addParameter(
new QgsProcessingParameterEnum( QStringLiteral(
"VECTOR_OPTION" ), QObject::tr(
"Export vector option" ), exportVectorOptions,
false, 0 ) );
232 if ( timeType == QLatin1String(
"dataset-time-step" ) )
237 else if ( timeType == QLatin1String(
"defined-date-time" ) )
240 if ( dateTime.isValid() )
241 relativeTime =
QgsInterval( layerReferenceTime.secsTo( dateTime ) );
243 else if ( timeType == QLatin1String(
"current-context-time" ) )
246 if ( dateTime.isValid() )
247 relativeTime =
QgsInterval( layerReferenceTime.secsTo( dateTime ) );
256 QgsMeshLayer *meshLayer = parameterAsMeshLayer( parameters, QStringLiteral(
"INPUT" ), context );
258 if ( !meshLayer || !meshLayer->
isValid() )
270 QList<int> datasetGroups =
281 QVariant parameterTimeVariant = parameters.value( QStringLiteral(
"DATASET_TIME" ) );
282 QgsInterval relativeTime = datasetRelativetime( parameterTimeVariant, meshLayer, context );
284 switch ( meshElementType() )
287 mElementCount = mNativeMesh.faceCount();
290 mElementCount = mNativeMesh.vertexCount();
293 mElementCount = mNativeMesh.edgeCount();
297 for (
int i = 0; i < datasetGroups.count(); ++i )
299 int groupIndex = datasetGroups.at( i );
304 if ( supportedDataType().contains( dataGroup.metadata.dataType() ) )
306 dataGroup.datasetValues = meshLayer->
datasetValues( datasetIndex, 0, mElementCount );
307 mDataPerGroup.append( dataGroup );
310 feedback->
setProgress( 100 * i / datasetGroups.count() );
313 mExportVectorOption = parameterAsInt( parameters, QStringLiteral(
"VECTOR_OPTION" ), context );
323 return QVariantMap();
325 feedback->
setProgressText( QObject::tr(
"Creating output vector layer" ) );
328 QList<QgsMeshDatasetGroupMetadata> metaList;
329 metaList.reserve( mDataPerGroup.size() );
330 for (
const DataGroup &dataGroup : mDataPerGroup )
331 metaList.append( dataGroup.metadata );
332 QgsFields fields = createFields( metaList, mExportVectorOption );
337 QStringLiteral(
"OUTPUT" ),
344 return QVariantMap();
349 return QVariantMap();
351 feedback->
setProgressText( QObject::tr(
"Creating points for each vertices" ) );
354 for (
int i = 0; i < mElementCount; ++i )
357 for (
const DataGroup &dataGroup : mDataPerGroup )
360 addAttributes( value, attributes, dataGroup.metadata.isVector(), mExportVectorOption );
371 geom = meshElement( i );
372 feedback->
reportError( QObject::tr(
"Could not transform point to destination CRS" ) );
382 return QVariantMap();
388 ret[QStringLiteral(
"OUTPUT" )] = identifier;
393 QString QgsExportMeshFacesAlgorithm::shortHelpString()
const
395 return QObject::tr(
"Exports mesh layer's faces to a polygon vector layer, with the dataset values on faces as attribute values" );
398 QString QgsExportMeshFacesAlgorithm::name()
const
400 return QStringLiteral(
"exportmeshfaces" );
403 QString QgsExportMeshFacesAlgorithm::displayName()
const
405 return QObject::tr(
"Export mesh faces" );
410 return new QgsExportMeshFacesAlgorithm();
413 QgsGeometry QgsExportMeshFacesAlgorithm::meshElement(
int index )
const
415 const QgsMeshFace &face = mNativeMesh.face( index );
416 QVector<QgsPoint> vertices( face.size() );
417 for (
int i = 0; i < face.size(); ++i )
418 vertices[i] = mNativeMesh.vertex( face.at( i ) );
419 std::unique_ptr<QgsPolygon> polygon = qgis::make_unique<QgsPolygon>();
424 QString QgsExportMeshEdgesAlgorithm::shortHelpString()
const
426 return QObject::tr(
"Exports mesh layer's edges to a line vector layer, with the dataset values on edges as attribute values" );
429 QString QgsExportMeshEdgesAlgorithm::name()
const
431 return QStringLiteral(
"exportmeshedges" );
434 QString QgsExportMeshEdgesAlgorithm::displayName()
const
436 return QObject::tr(
"Export mesh edges" );
441 return new QgsExportMeshEdgesAlgorithm();
444 QgsGeometry QgsExportMeshEdgesAlgorithm::meshElement(
int index )
const
446 const QgsMeshEdge &edge = mNativeMesh.edge( index );
447 QVector<QgsPoint> vertices( 2 );
448 vertices[0] = mNativeMesh.vertex( edge.first );
449 vertices[1] = mNativeMesh.vertex( edge.second );
454 QString QgsExportMeshOnGridAlgorithm::name()
const {
return QStringLiteral(
"exportmeshongrid" );}
456 QString QgsExportMeshOnGridAlgorithm::displayName()
const {
return QObject::tr(
"Export mesh on grid" );}
458 QString QgsExportMeshOnGridAlgorithm::group()
const {
return QObject::tr(
"Mesh" );}
460 QString QgsExportMeshOnGridAlgorithm::groupId()
const {
return QStringLiteral(
"mesh" );}
462 QString QgsExportMeshOnGridAlgorithm::shortHelpString()
const
464 return QObject::tr(
"Exports mesh layer's dataset values to a gridded point vector layer, with the dataset values on this point as attribute values.\n"
465 "For data on volume (3D stacked dataset values), the exported dataset values are averaged on faces using the method defined in the mesh layer properties (default is Multi level averaging method).\n"
466 "1D meshes are not supported." );
471 return new QgsExportMeshOnGridAlgorithm();
474 void QgsExportMeshOnGridAlgorithm::initAlgorithm(
const QVariantMap &configuration )
476 Q_UNUSED( configuration );
481 QStringLiteral(
"DATASET_GROUPS" ),
482 QObject::tr(
"Dataset groups" ),
483 QStringLiteral(
"INPUT" ),
484 supportedDataType() ) );
487 QStringLiteral(
"DATASET_TIME" ),
488 QObject::tr(
"Dataset time" ),
489 QStringLiteral(
"INPUT" ),
490 QStringLiteral(
"DATASET_GROUPS" ) ) );
494 addParameter(
new QgsProcessingParameterDistance( QStringLiteral(
"GRID_SPACING" ), QObject::tr(
"Grid spacing" ), 10, QStringLiteral(
"INPUT" ),
false ) );
496 addParameter(
new QgsProcessingParameterCrs( QStringLiteral(
"CRS_OUTPUT" ), QObject::tr(
"Output coordinate system" ), QVariant(),
true ) );
498 QStringList exportVectorOptions;
499 exportVectorOptions << QObject::tr(
"Cartesian (x,y)" )
500 << QObject::tr(
"Polar (magnitude,degree)" )
501 << QObject::tr(
"Cartesian and Polar" );
502 addParameter(
new QgsProcessingParameterEnum( QStringLiteral(
"VECTOR_OPTION" ), QObject::tr(
"Export vector option" ), exportVectorOptions,
false, 0 ) );
506 static void extractDatasetValues(
const QList<int> &datasetGroups,
511 const QSet<int> supportedDataType,
512 QList<DataGroup> &datasetPerGroup,
515 for (
int i = 0; i < datasetGroups.count(); ++i )
517 int groupIndex = datasetGroups.at( i );
522 if ( supportedDataType.contains( dataGroup.metadata.dataType() ) )
526 dataGroup.datasetValues = meshLayer->
datasetValues( datasetIndex, 0, valueCount );
530 dataGroup.dataset3dStakedValue = meshLayer->
dataset3dValues( datasetIndex, 0, valueCount );
532 datasetPerGroup.append( dataGroup );
535 feedback->
setProgress( 100 * i / datasetGroups.count() );
541 QgsMeshLayer *meshLayer = parameterAsMeshLayer( parameters, QStringLiteral(
"INPUT" ), context );
543 if ( !meshLayer || !meshLayer->
isValid() )
556 QList<int> datasetGroups =
565 QVariant parameterTimeVariant = parameters.value( QStringLiteral(
"DATASET_TIME" ) );
566 QgsInterval relativeTime = datasetRelativetime( parameterTimeVariant, meshLayer, context );
568 extractDatasetValues( datasetGroups, meshLayer, mTriangularMesh, nativeMesh, relativeTime, supportedDataType(), mDataPerGroup, feedback );
570 mExportVectorOption = parameterAsInt( parameters, QStringLiteral(
"VECTOR_OPTION" ), context );
580 return QVariantMap();
582 feedback->
setProgressText( QObject::tr(
"Creating output vector layer" ) );
587 for ( DataGroup &dataGroup : mDataPerGroup )
589 if ( dataGroup.dataset3dStakedValue.isValid() )
590 dataGroup.datasetValues = avgMethod->
calculate( dataGroup.dataset3dStakedValue );
593 QList<QgsMeshDatasetGroupMetadata> metaList;
594 metaList.reserve( mDataPerGroup.size() );
595 for (
const DataGroup &dataGroup : mDataPerGroup )
596 metaList.append( dataGroup.metadata );
597 QgsFields fields = createFields( metaList, mExportVectorOption );
603 QStringLiteral(
"OUTPUT" ),
610 return QVariantMap();
615 return QVariantMap();
621 double gridSpacing = parameterAsDouble( parameters, QStringLiteral(
"GRID_SPACING" ), context );
622 QgsRectangle extent = parameterAsExtent( parameters, QStringLiteral(
"EXTENT" ), context );
624 extent = mTriangularMesh.extent();
625 int pointXCount = int( extent.
width() / gridSpacing ) + 1;
626 int pointYCount = int( extent.
height() / gridSpacing ) + 1;
628 for (
int ix = 0; ix < pointXCount; ++ix )
630 for (
int iy = 0; iy < pointYCount; ++iy )
633 int triangularFaceIndex = mTriangularMesh.faceIndexForPoint_v2( point );
634 if ( triangularFaceIndex >= 0 )
638 int nativeFaceIndex = mTriangularMesh.trianglesToNativeFaces().at( triangularFaceIndex );
639 for (
int i = 0; i < mDataPerGroup.count(); ++i )
641 const DataGroup &dataGroup = mDataPerGroup.at( i );
642 bool faceActive = dataGroup.activeFaces.active( nativeFaceIndex );
650 dataGroup.activeFaces,
651 dataGroup.datasetValues,
652 dataGroup.metadata );
654 if ( dataGroup.metadata.isVector() )
656 QVector<double> vector = vectorValue( dataGroup.datasetValues.value( i ), mExportVectorOption );
657 for (
double v : vector )
659 attributes.append( v );
663 attributes.append( value.
scalar() );
674 feedback->
reportError( QObject::tr(
"Could not transform point to destination CRS" ) );
685 ret[QStringLiteral(
"OUTPUT" )] = identifier;
690 QSet<int> QgsExportMeshOnGridAlgorithm::supportedDataType()
699 QString QgsMeshRasterizeAlgorithm::name()
const
701 return QStringLiteral(
"meshrasterize" );
704 QString QgsMeshRasterizeAlgorithm::displayName()
const
706 return QObject::tr(
"Rasterize mesh dataset" );
709 QString QgsMeshRasterizeAlgorithm::group()
const
711 return QObject::tr(
"Mesh" );
714 QString QgsMeshRasterizeAlgorithm::groupId()
const
716 return QStringLiteral(
"mesh" );
719 QString QgsMeshRasterizeAlgorithm::shortHelpString()
const
721 return QObject::tr(
"Create a raster layer from a mesh dataset.\n"
722 "For data on volume (3D stacked dataset values), the exported dataset values are averaged on faces using the method defined in the mesh layer properties (default is Multi level averaging method).\n"
723 "1D meshes are not supported." );
728 return new QgsMeshRasterizeAlgorithm();
731 void QgsMeshRasterizeAlgorithm::initAlgorithm(
const QVariantMap &configuration )
733 Q_UNUSED( configuration );
738 QStringLiteral(
"DATASET_GROUPS" ),
739 QObject::tr(
"Dataset groups" ),
740 QStringLiteral(
"INPUT" ),
741 supportedDataType() ) );
744 QStringLiteral(
"DATASET_TIME" ),
745 QObject::tr(
"Dataset time" ),
746 QStringLiteral(
"INPUT" ),
747 QStringLiteral(
"DATASET_GROUPS" ) ) );
751 addParameter(
new QgsProcessingParameterDistance( QStringLiteral(
"PIXEL_SIZE" ), QObject::tr(
"Pixel size" ), 1, QStringLiteral(
"INPUT" ),
false ) );
753 addParameter(
new QgsProcessingParameterCrs( QStringLiteral(
"CRS_OUTPUT" ), QObject::tr(
"Output coordinate system" ), QVariant(),
true ) );
760 QgsMeshLayer *meshLayer = parameterAsMeshLayer( parameters, QStringLiteral(
"INPUT" ), context );
762 if ( !meshLayer || !meshLayer->
isValid() )
774 QList<int> datasetGroups =
783 QVariant parameterTimeVariant = parameters.value( QStringLiteral(
"DATASET_TIME" ) );
784 QgsInterval relativeTime = datasetRelativetime( parameterTimeVariant, meshLayer, context );
786 extractDatasetValues( datasetGroups, meshLayer, mTriangularMesh, *meshLayer->
nativeMesh(), relativeTime, supportedDataType(), mDataPerGroup, feedback );
798 return QVariantMap();
805 for ( DataGroup &dataGroup : mDataPerGroup )
807 if ( dataGroup.dataset3dStakedValue.isValid() )
808 dataGroup.datasetValues = avgMethod->
calculate( dataGroup.dataset3dStakedValue );
812 double pixelSize = parameterAsDouble( parameters, QStringLiteral(
"PIXEL_SIZE" ), context );
813 QgsRectangle extent = parameterAsExtent( parameters, QStringLiteral(
"EXTENT" ), context );
815 extent = mTriangularMesh.extent();
817 int width = extent.
width() / pixelSize;
818 int height = extent.
height() / pixelSize;
820 QString fileName = parameterAsOutputLayer( parameters, QStringLiteral(
"OUTPUT" ), context );
821 QFileInfo fileInfo( fileName );
824 rasterFileWriter.setOutputProviderKey( QStringLiteral(
"gdal" ) );
825 rasterFileWriter.setOutputFormat( outputFormat );
827 std::unique_ptr<QgsRasterDataProvider> rasterDataProvider(
828 rasterFileWriter.createMultiBandRaster(
Qgis::Float64, width, height, extent, mTransform.destinationCrs(), mDataPerGroup.count() ) );
829 rasterDataProvider->setEditable(
true );
831 for (
int i = 0; i < mDataPerGroup.count(); ++i )
833 const DataGroup &dataGroup = mDataPerGroup.at( i );
840 dataGroup.datasetValues,
841 dataGroup.activeFaces,
842 dataGroup.metadata.dataType(),
846 &rasterBlockFeedBack );
850 rasterDataProvider->writeBlock( block, i + 1 );
851 rasterDataProvider->setNoDataValue( i + 1, block->
noDataValue() );
855 return QVariantMap();
856 feedback->
setProgress( 100 * i / mDataPerGroup.count() );
860 rasterDataProvider->setEditable(
false );
866 ret[QStringLiteral(
"OUTPUT" )] = fileName;
871 QSet<int> QgsMeshRasterizeAlgorithm::supportedDataType()
880 QString QgsMeshContoursAlgorithm::name()
const
882 return QStringLiteral(
"meshcontours" );
885 QString QgsMeshContoursAlgorithm::displayName()
const
887 return QObject::tr(
"Export contours" );
890 QString QgsMeshContoursAlgorithm::group()
const
892 return QObject::tr(
"Mesh" );
895 QString QgsMeshContoursAlgorithm::groupId()
const
897 return QStringLiteral(
"mesh" );
900 QString QgsMeshContoursAlgorithm::shortHelpString()
const
902 return QObject::tr(
"Creates contours as vector layer from mesh scalar dataset" );
907 return new QgsMeshContoursAlgorithm();
910 void QgsMeshContoursAlgorithm::initAlgorithm(
const QVariantMap &configuration )
912 Q_UNUSED( configuration );
917 QStringLiteral(
"DATASET_GROUPS" ),
918 QObject::tr(
"Dataset groups" ),
919 QStringLiteral(
"INPUT" ),
920 supportedDataType() ) );
923 QStringLiteral(
"DATASET_TIME" ),
924 QObject::tr(
"Dataset time" ),
925 QStringLiteral(
"INPUT" ),
926 QStringLiteral(
"DATASET_GROUPS" ) ) );
937 QStringLiteral(
"CONTOUR_LEVEL_LIST" ), QObject::tr(
"List of contours level" ), QVariant(),
false,
true ) );
939 addParameter(
new QgsProcessingParameterCrs( QStringLiteral(
"CRS_OUTPUT" ), QObject::tr(
"Output coordinate system" ), QVariant(),
true ) );
948 QgsMeshLayer *meshLayer = parameterAsMeshLayer( parameters, QStringLiteral(
"INPUT" ), context );
950 if ( !meshLayer || !meshLayer->
isValid() )
966 QString levelsString = parameterAsString( parameters, QStringLiteral(
"CONTOUR_LEVEL_LIST" ), context );
967 if ( ! levelsString.isEmpty() )
969 QStringList levelStringList = levelsString.split(
',' );
970 if ( !levelStringList.isEmpty() )
972 for (
const QString &stringVal : levelStringList )
975 double val = stringVal.toDouble( &ok );
977 mLevels.append( val );
979 throw QgsProcessingException( QObject::tr(
"Invalid format for level values, must be numbers separated with comma" ) );
981 if ( mLevels.count() >= 2 )
982 if ( mLevels.last() <= mLevels.at( mLevels.count() - 2 ) )
983 throw QgsProcessingException( QObject::tr(
"Invalid format for level values, must be different numbers and in increasing order" ) );
988 if ( mLevels.isEmpty() )
990 double minimum = parameterAsDouble( parameters, QStringLiteral(
"MINIMUM" ), context );
991 double maximum = parameterAsDouble( parameters, QStringLiteral(
"MAXIMUM" ), context );
992 double interval = parameterAsDouble( parameters, QStringLiteral(
"INCREMENT" ), context );
997 if ( minimum >= maximum )
998 throw QgsProcessingException( QObject::tr(
"Invalid minimum and maximum values, minimum must be lesser than maximum" ) );
1000 if ( interval > ( maximum - minimum ) )
1001 throw QgsProcessingException( QObject::tr(
"Invalid minimum, maximum and interval values, difference between minimum and maximum must be greater or equal than interval" ) );
1003 int intervalCount = ( maximum - minimum ) / interval;
1005 mLevels.reserve( intervalCount );
1006 for (
int i = 0; i < intervalCount; ++i )
1008 mLevels.append( minimum + i * interval );
1013 QList<int> datasetGroups =
1022 QVariant parameterTimeVariant = parameters.value( QStringLiteral(
"DATASET_TIME" ) );
1023 QgsInterval relativeTime = datasetRelativetime( parameterTimeVariant, meshLayer, context );
1027 extractDatasetValues( datasetGroups, meshLayer, mTriangularMesh, mNativeMesh, relativeTime, supportedDataType(), mDataPerGroup, feedback );
1038 for ( DataGroup &dataGroup : mDataPerGroup )
1040 if ( dataGroup.dataset3dStakedValue.isValid() )
1041 dataGroup.datasetValues = avgMethod->
calculate( dataGroup.dataset3dStakedValue );
1047 polygonFields.
append( QObject::tr(
"group" ) );
1048 polygonFields.
append( QObject::tr(
"time" ) );
1049 polygonFields.
append( QObject::tr(
"min_value" ) );
1050 polygonFields.
append( QObject::tr(
"max_value" ) );
1051 lineFields.
append( QObject::tr(
"group" ) );
1052 lineFields.
append( QObject::tr(
"time" ) );
1053 lineFields.
append( QObject::tr(
"value" ) );
1057 QString lineIdentifier;
1058 QString polygonIdentifier;
1060 QStringLiteral(
"OUTPUT_POLYGONS" ),
1067 QStringLiteral(
"OUTPUT_LINES" ),
1074 if ( !sinkLines || !sinkPolygons )
1075 return QVariantMap();
1078 for (
int i = 0; i < mDataPerGroup.count(); ++i )
1080 DataGroup dataGroup = mDataPerGroup.at( i );
1082 int count = scalarDataOnVertices ? mNativeMesh.vertices.count() : mNativeMesh.faces.count();
1084 QVector<double> values;
1085 if ( dataGroup.datasetValues.isValid() )
1088 values = QgsMeshLayerUtils::calculateMagnitudes( dataGroup.datasetValues );
1092 values = QVector<double>( count, std::numeric_limits<double>::quiet_NaN() );
1095 if ( ( !scalarDataOnVertices ) )
1097 values = QgsMeshLayerUtils::interpolateFromFacesData(
1100 &dataGroup.activeFaces,
1105 QgsMeshContours contoursExported( mTriangularMesh, mNativeMesh, values, dataGroup.activeFaces );
1108 firstAttributes.append( dataGroup.metadata.name() );
1109 firstAttributes.append( mDateTimeString );
1111 for (
double level : mLevels )
1113 QgsGeometry line = contoursExported.exportLines( level, feedback );
1115 return QVariantMap();
1119 lineAttributes.append( level );
1129 for (
int l = 0; l < mLevels.count() - 1; ++l )
1131 QgsGeometry polygon = contoursExported.exportPolygons( mLevels.at( l ), mLevels.at( l + 1 ), feedback );
1133 return QVariantMap();
1138 polygonAttributes.append( mLevels.at( l ) );
1139 polygonAttributes.append( mLevels.at( l + 1 ) );
1149 feedback->
setProgress( 100 * i / mDataPerGroup.count() );
1154 ret[QStringLiteral(
"OUTPUT_LINES" )] = lineIdentifier;
1155 ret[QStringLiteral(
"OUTPUT_POLYGONS" )] = polygonIdentifier;
1160 QString QgsMeshExportCrossSection::name()
const
1162 return QStringLiteral(
"meshexportcrosssection" );
1165 QString QgsMeshExportCrossSection::displayName()
const
1167 return QObject::tr(
"Export cross section dataset values on lines from mesh" );
1170 QString QgsMeshExportCrossSection::group()
const
1172 return QObject::tr(
"Mesh" );
1175 QString QgsMeshExportCrossSection::groupId()
const
1177 return QStringLiteral(
"mesh" );
1180 QString QgsMeshExportCrossSection::shortHelpString()
const
1182 return QObject::tr(
"This algorithm extracts mesh's dataset values from line contained in a vector layer.\n"
1183 "Each line is discretized with a resolution distance parameter for extraction of values on its vertices." );
1188 return new QgsMeshExportCrossSection();
1191 void QgsMeshExportCrossSection::initAlgorithm(
const QVariantMap &configuration )
1193 Q_UNUSED( configuration );
1198 QStringLiteral(
"DATASET_GROUPS" ),
1199 QObject::tr(
"Dataset groups" ),
1200 QStringLiteral(
"INPUT" ),
1201 supportedDataType() ) );
1204 QStringLiteral(
"DATASET_TIME" ),
1205 QObject::tr(
"Dataset time" ),
1206 QStringLiteral(
"INPUT" ),
1207 QStringLiteral(
"DATASET_GROUPS" ) ) );
1209 QList<int> datatype;
1212 QStringLiteral(
"INPUT_LINES" ), QObject::tr(
"Lines for data export" ), datatype, QVariant(),
false ) );
1215 QStringLiteral(
"RESOLUTION" ), QObject::tr(
"Line segmentation resolution" ), 10.0, QStringLiteral(
"INPUT_LINES" ),
false, 0 ) );
1224 QStringLiteral(
"OUTPUT" ), QObject::tr(
"Exported data CSV file" ), QObject::tr(
"CSV file (*.csv)" ) ) );
1229 QgsMeshLayer *meshLayer = parameterAsMeshLayer( parameters, QStringLiteral(
"INPUT" ), context );
1231 if ( !meshLayer || !meshLayer->
isValid() )
1234 mMeshLayerCrs = meshLayer->
crs();
1237 QList<int> datasetGroups =
1246 QVariant parameterTimeVariant = parameters.value( QStringLiteral(
"DATASET_TIME" ) );
1247 QgsInterval relativeTime = datasetRelativetime( parameterTimeVariant, meshLayer, context );
1249 extractDatasetValues( datasetGroups, meshLayer, mTriangularMesh, *meshLayer->
nativeMesh(), relativeTime, supportedDataType(), mDataPerGroup, feedback );
1262 for ( DataGroup &dataGroup : mDataPerGroup )
1264 if ( dataGroup.dataset3dStakedValue.isValid() )
1265 dataGroup.datasetValues = avgMethod->
calculate( dataGroup.dataset3dStakedValue );
1267 double resolution = parameterAsDouble( parameters, QStringLiteral(
"RESOLUTION" ), context );
1268 int datasetDigits = parameterAsInt( parameters, QStringLiteral(
"DATASET_DIGITS" ), context );
1269 int coordDigits = parameterAsInt( parameters, QStringLiteral(
"COORDINATES_DIGITS" ), context );
1272 if ( !featureSource )
1277 QString outputFileName = parameterAsFileOutput( parameters, QStringLiteral(
"OUTPUT" ), context );
1278 QFile file( outputFileName );
1279 if ( ! file.open( QIODevice::WriteOnly ) )
1282 QTextStream textStream( &file );
1284 header << QStringLiteral(
"fid" ) << QStringLiteral(
"x" ) << QStringLiteral(
"y" ) << QObject::tr(
"offset" );
1285 for (
const DataGroup &datagroup : mDataPerGroup )
1286 header << datagroup.metadata.name();
1287 textStream << header.join(
',' ) << QStringLiteral(
"\n" );
1290 int featCounter = 0;
1295 int fid = feat.
id();
1304 feedback->
reportError( QObject::tr(
"Could not transform line to mesh CRS" ) );
1310 while ( offset <= line.
length() )
1313 return QVariantMap();
1315 QStringList textLine;
1317 int triangularFaceIndex = mTriangularMesh.faceIndexForPoint_v2( point );
1318 textLine << QString::number( fid ) << QString::number( point.
x(),
'f', coordDigits ) << QString::number( point.
y(),
'f', coordDigits ) << QString::number( offset,
'f', coordDigits );
1319 if ( triangularFaceIndex >= 0 )
1323 int nativeFaceIndex = mTriangularMesh.trianglesToNativeFaces().at( triangularFaceIndex );
1324 for (
int i = 0; i < mDataPerGroup.count(); ++i )
1326 const DataGroup &dataGroup = mDataPerGroup.at( i );
1327 bool faceActive = dataGroup.activeFaces.active( nativeFaceIndex );
1333 triangularFaceIndex,
1335 dataGroup.activeFaces,
1336 dataGroup.datasetValues,
1337 dataGroup.metadata );
1339 if ( abs( value.
x() ) == std::numeric_limits<double>::quiet_NaN() )
1340 textLine << QString(
' ' );
1342 textLine << QString::number( value.
scalar(),
'f', datasetDigits );
1346 for (
int i = 0; i < mDataPerGroup.count(); ++i )
1347 textLine << QString(
' ' );
1349 textStream << textLine.join(
',' ) << QStringLiteral(
"\n" );
1351 offset += resolution;
1356 feedback->
setProgress( 100 * featCounter / featCount );
1358 return QVariantMap();
1365 ret[QStringLiteral(
"OUTPUT" )] = outputFileName;
1369 QString QgsMeshExportTimeSeries::name()
const
1371 return QStringLiteral(
"meshexporttimeseries" );
1374 QString QgsMeshExportTimeSeries::displayName()
const
1376 return QObject::tr(
"Export time series values from points of a mesh dataset" );
1379 QString QgsMeshExportTimeSeries::group()
const
1381 return QObject::tr(
"Mesh" );
1384 QString QgsMeshExportTimeSeries::groupId()
const
1386 return QStringLiteral(
"mesh" );
1389 QString QgsMeshExportTimeSeries::shortHelpString()
const
1391 return QObject::tr(
"This algorithm extracts mesh's dataset time series values from points contained in a vector layer.\n"
1392 "If the time step is kept to its default value (0 hours), the time step used is the one of the two first datasets of the first selected dataset group" );
1397 return new QgsMeshExportTimeSeries();
1400 void QgsMeshExportTimeSeries::initAlgorithm(
const QVariantMap &configuration )
1402 Q_UNUSED( configuration );
1407 QStringLiteral(
"DATASET_GROUPS" ),
1408 QObject::tr(
"Dataset groups" ),
1409 QStringLiteral(
"INPUT" ),
1410 supportedDataType() ) );
1413 QStringLiteral(
"STARTING_TIME" ),
1414 QObject::tr(
"Starting time" ),
1415 QStringLiteral(
"INPUT" ),
1416 QStringLiteral(
"DATASET_GROUPS" ) ) );
1419 QStringLiteral(
"FINISHING_TIME" ),
1420 QObject::tr(
"Finishing time" ),
1421 QStringLiteral(
"INPUT" ),
1422 QStringLiteral(
"DATASET_GROUPS" ) ) );
1427 QList<int> datatype;
1430 QStringLiteral(
"INPUT_POINTS" ), QObject::tr(
"Points for data export" ), datatype, QVariant(),
false ) );
1439 QStringLiteral(
"OUTPUT" ), QObject::tr(
"Exported data CSV file" ), QObject::tr(
"CSV file (*.csv)" ) ) );
1444 QgsMeshLayer *meshLayer = parameterAsMeshLayer( parameters, QStringLiteral(
"INPUT" ), context );
1446 if ( !meshLayer || !meshLayer->
isValid() )
1449 mMeshLayerCrs = meshLayer->
crs();
1452 QList<int> datasetGroups =
1461 QVariant parameterStartTimeVariant = parameters.value( QStringLiteral(
"STARTING_TIME" ) );
1462 QgsInterval relativeStartTime = datasetRelativetime( parameterStartTimeVariant, meshLayer, context );
1464 QVariant parameterEndTimeVariant = parameters.value( QStringLiteral(
"FINISHING_TIME" ) );
1465 QgsInterval relativeEndTime = datasetRelativetime( parameterEndTimeVariant, meshLayer, context );
1468 qint64 timeStepInterval = parameterAsDouble( parameters, QStringLiteral(
"TIME_STEP" ), context ) * 1000 * 3600;
1469 if ( timeStepInterval == 0 )
1472 for (
int groupIndex : datasetGroups )
1486 mRelativeTimeSteps.clear();
1487 mTimeStepString.clear();
1488 if ( timeStepInterval != 0 )
1490 mRelativeTimeSteps.append( relativeStartTime.
seconds() * 1000 );
1491 while ( mRelativeTimeSteps.last() < relativeEndTime.
seconds() * 1000 )
1492 mRelativeTimeSteps.append( mRelativeTimeSteps.last() + timeStepInterval );
1494 for ( qint64 relativeTimeStep : mRelativeTimeSteps )
1496 mTimeStepString.append( meshLayer->
formatTime( relativeTimeStep / 3600.0 / 1000.0 ) );
1501 for (
int i = 0; i < datasetGroups.count(); ++i )
1503 int groupIndex = datasetGroups.at( i );
1505 if ( supportedDataType().contains( meta.
dataType() ) )
1507 mGroupIndexes.append( groupIndex );
1508 mGroupsMetadata[groupIndex] = meta;
1512 if ( !mRelativeTimeSteps.isEmpty() )
1516 for ( qint64 relativeTimeStep : mRelativeTimeSteps )
1518 QMap<int, int> &groupIndexToData = mRelativeTimeToData[relativeTimeStep];
1519 QgsInterval timeStepInterval( relativeTimeStep / 1000.0 );
1521 if ( !datasetIndex.
isValid() )
1523 if ( datasetIndex != lastDatasetIndex )
1525 DataGroup dataGroup;
1526 dataGroup.metadata = meta;
1527 dataGroup.datasetValues = meshLayer->
datasetValues( datasetIndex, 0, valueCount );
1531 dataGroup.dataset3dStakedValue = meshLayer->
dataset3dValues( datasetIndex, 0, valueCount );
1533 mDatasets.append( dataGroup );
1534 lastDatasetIndex = datasetIndex;
1536 groupIndexToData[groupIndex] = mDatasets.count() - 1;
1542 QMap<int, int> &groupIndexToData = mRelativeTimeToData[0];
1544 DataGroup dataGroup;
1545 dataGroup.metadata = meta;
1546 dataGroup.datasetValues = meshLayer->
datasetValues( datasetIndex, 0, valueCount );
1550 dataGroup.dataset3dStakedValue = meshLayer->
dataset3dValues( datasetIndex, 0, valueCount );
1552 mDatasets.append( dataGroup );
1553 groupIndexToData[groupIndex] = mDatasets.
count() - 1;
1558 feedback->
setProgress( 100 * i / datasetGroups.count() );
1574 for ( DataGroup &dataGroup : mDatasets )
1576 if ( dataGroup.dataset3dStakedValue.isValid() )
1577 dataGroup.datasetValues = avgMethod->
calculate( dataGroup.dataset3dStakedValue );
1580 int datasetDigits = parameterAsInt( parameters, QStringLiteral(
"DATASET_DIGITS" ), context );
1581 int coordDigits = parameterAsInt( parameters, QStringLiteral(
"COORDINATES_DIGITS" ), context );
1584 if ( !featureSource )
1589 QString outputFileName = parameterAsFileOutput( parameters, QStringLiteral(
"OUTPUT" ), context );
1590 QFile file( outputFileName );
1591 if ( ! file.open( QIODevice::WriteOnly ) )
1594 QTextStream textStream( &file );
1596 header << QStringLiteral(
"fid" ) << QStringLiteral(
"x" ) << QStringLiteral(
"y" ) << QObject::tr(
"time" );
1598 for (
int gi : mGroupIndexes )
1599 header << mGroupsMetadata.value( gi ).name();
1601 textStream << header.join(
',' ) << QStringLiteral(
"\n" );
1604 int featCounter = 0;
1609 int fid = feat.
id();
1618 feedback->
reportError( QObject::tr(
"Could not transform line to mesh CRS" ) );
1625 int triangularFaceIndex = mTriangularMesh.faceIndexForPoint_v2( point );
1627 if ( triangularFaceIndex >= 0 )
1629 int nativeFaceIndex = mTriangularMesh.trianglesToNativeFaces().at( triangularFaceIndex );
1630 if ( !mRelativeTimeSteps.isEmpty() )
1632 for (
int timeIndex = 0; timeIndex < mRelativeTimeSteps.count(); ++timeIndex )
1634 qint64 timeStep = mRelativeTimeSteps.at( timeIndex );
1635 QStringList textLine;
1636 textLine << QString::number( fid )
1637 << QString::number( point.
x(),
'f', coordDigits )
1638 << QString::number( point.
y(),
'f', coordDigits )
1639 << mTimeStepString.at( timeIndex );
1641 if ( mRelativeTimeToData.contains( timeStep ) )
1643 const QMap<int, int> &groupToData = mRelativeTimeToData.value( timeStep );
1644 for (
int groupIndex : mGroupIndexes )
1646 if ( !groupToData.contains( groupIndex ) )
1648 int dataIndex = groupToData.value( groupIndex );
1649 if ( dataIndex < 0 || dataIndex > mDatasets.count() - 1 )
1652 const DataGroup &dataGroup = mDatasets.at( dataIndex );
1655 triangularFaceIndex,
1657 dataGroup.activeFaces,
1658 dataGroup.datasetValues,
1659 dataGroup.metadata );
1660 if ( abs( value.
x() ) == std::numeric_limits<double>::quiet_NaN() )
1661 textLine << QString(
' ' );
1663 textLine << QString::number( value.
scalar(),
'f', datasetDigits ) ;
1666 textStream << textLine.join(
',' ) << QStringLiteral(
"\n" );
1671 QStringList textLine;
1672 textLine << QString::number( fid )
1673 << QString::number( point.
x(),
'f', coordDigits )
1674 << QString::number( point.
y(),
'f', coordDigits )
1675 << QObject::tr(
"static dataset" );
1676 const QMap<int, int> &groupToData = mRelativeTimeToData.value( 0 );
1677 for (
int groupIndex : mGroupIndexes )
1679 if ( !groupToData.contains( groupIndex ) )
1681 int dataIndex = groupToData.value( groupIndex );
1682 if ( dataIndex < 0 || dataIndex > mDatasets.count() - 1 )
1684 const DataGroup &dataGroup = mDatasets.at( dataIndex );
1687 triangularFaceIndex,
1689 dataGroup.activeFaces,
1690 dataGroup.datasetValues,
1691 dataGroup.metadata );
1692 if ( abs( value.
x() ) == std::numeric_limits<double>::quiet_NaN() )
1693 textLine << QString(
' ' );
1695 textLine << QString::number( value.
scalar(),
'f', datasetDigits );
1697 textStream << textLine.join(
',' ) << QStringLiteral(
"\n" );
1703 feedback->
setProgress( 100 * featCounter / featCount );
1705 return QVariantMap();
1712 ret[QStringLiteral(
"OUTPUT" )] = outputFileName;
@ Float64
Sixty four bit floating point (double)
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Custom exception class for Coordinate Reference System related exceptions.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
An interface for objects which accept features via addFeature(s) methods.
virtual bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags())
Adds a single feature to the sink.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool isCanceled() const
Tells whether the operation has been canceled already.
void canceled()
Internal routines can connect to this signal if they use event loop.
void cancel()
Tells the internal routines that the current operation should be canceled. This should be run by the ...
void setProgress(double progress)
Sets the current progress for the feedback object.
Container of fields for a vector layer.
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
A geometry is the spatial representation of a feature.
double length() const
Returns the planar, 2-dimensional length of geometry.
QgsGeometry interpolate(double distance) const
Returns an interpolated point on the geometry at the specified distance.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
A representation of the interval between two datetime values.
double seconds() const
Returns the interval duration in seconds.
double hours() const
Returns the interval duration in hours.
Line string geometry type, with support for z-dimension and m-values.
QgsCoordinateReferenceSystem crs
Abstract class to interpolate 3d stacked mesh data to 2d data.
QgsMeshDataBlock calculate(const QgsMesh3dDataBlock &block3d, QgsFeedback *feedback=nullptr) const
Calculated 2d block values from 3d stacked mesh values.
int count() const
Number of 2d faces for which the volume data is stored in the block.
Exporter of contours lines or polygons from a mesh layer.
QgsMeshDataBlock is a block of integers/doubles that can be used to retrieve: active flags (e....
QgsMeshDatasetValue value(int index) const
Returns a value represented by the index For active flag the behavior is undefined.
bool active(int index) const
Returns a value for active flag by the index For scalar and vector 2d the behavior is undefined.
QgsMeshDatasetIndex is index that identifies the dataset group (e.g.
bool isValid() const
Returns whether index is valid, ie at least groups is set.
QgsMeshDatasetValue represents single dataset value.
double y() const
Returns y value.
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
double x() const
Returns x value.
Implementation of map layer temporal properties for mesh layers.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
int datasetCount(const QgsMeshDatasetIndex &index) const
Returns the dataset count in the dataset groups.
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
QgsMesh3dDataBlock dataset3dValues(const QgsMeshDatasetIndex &index, int faceIndex, int count) const
Returns N vector/scalar values from the face index from the dataset for 3d stacked meshes.
void updateTriangularMesh(const QgsCoordinateTransform &transform=QgsCoordinateTransform())
Gets native mesh and updates (creates if it doesn't exist) the base triangular mesh.
QgsMesh * nativeMesh()
Returns native mesh (nullptr before rendering or calling to updateMesh)
QgsMeshDatasetIndex datasetIndexAtRelativeTime(const QgsInterval &relativeTime, int datasetGroupIndex) const
Returns dataset index from datasets group depending on the relative time from the layer reference tim...
QgsMeshDataBlock datasetValues(const QgsMeshDatasetIndex &index, int valueIndex, int count) const
Returns N vector/scalar values from the index from the dataset.
QgsMeshDataBlock areFacesActive(const QgsMeshDatasetIndex &index, int faceIndex, int count) const
Returns whether the faces are active for particular dataset.
QgsInterval datasetRelativeTime(const QgsMeshDatasetIndex &index)
Returns the relative time of the dataset from the reference time of its group.
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
qint64 datasetRelativeTimeInMilliseconds(const QgsMeshDatasetIndex &index)
Returns the relative time (in milliseconds) of the dataset from the reference time of its group.
QgsTriangularMesh * triangularMesh(double minimumTriangleSize=0) const
Returns triangular mesh (nullptr before rendering or calling to updateMesh).
QString formatTime(double hours)
Returns (date) time in hours formatted to human readable form.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
@ NeighbourAverage
Does a simple average of values defined for all surrounding faces/vertices.
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
Abstract base class for processing algorithms.
Contains information about the context in which a processing algorithm is executed.
QgsDateTimeRange currentTimeRange() const
Returns the current time range to use for temporal operations.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Custom exception class for processing related exceptions.
QgsFeatureSource subclass which proxies methods to an underlying QgsFeatureSource,...
long featureCount() const override
Returns the number of features contained in the source, or -1 if the feature count is unknown.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request, Flags flags) const
Returns an iterator for the features in the source, respecting the supplied feature flags.
QgsCoordinateReferenceSystem sourceCrs() const override
Returns the coordinate reference system for features in the source.
Base class for providing feedback from a processing algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
virtual void setProgressText(const QString &text)
Sets a progress report text string.
A coordinate reference system parameter for processing algorithms.
A double numeric parameter for distance values.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
A rectangular map extent parameter for processing algorithms.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A generic file based destination parameter, for specifying the destination path for a file (non-map l...
A parameter for processing algorithms that need a list of mesh dataset groups.
static QList< int > valueAsDatasetGroup(const QVariant &value)
Returns the value as a list if dataset group indexes.
A parameter for processing algorithms that need a list of mesh dataset index from time parameter.
static QString valueAsTimeType(const QVariant &value)
Returns the dataset value time type as a string : current-context-time : the time is store in the pro...
static QgsMeshDatasetIndex timeValueAsDatasetIndex(const QVariant &value)
Returns the value as a QgsMeshDatasetIndex if the value has "dataset-time-step" type.
static QDateTime timeValueAsDefinedDateTime(const QVariant &value)
Returns the value as a QDateTime if the value has "defined-date-time" type.
A mesh layer parameter for processing algorithms.
A numeric parameter for processing algorithms.
@ Double
Double/float values.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
A string parameter for processing algorithms.
@ TypeVectorLine
Vector line layers.
@ TypeVectorPolygon
Vector polygon layers.
@ TypeVectorPoint
Vector point layers.
Feedback object tailored for raster block reading.
double noDataValue() const SIP_HOLDGIL
Returns no data value.
The raster file writer which allows you to save a raster to a new file.
static QString driverForExtension(const QString &extension)
Returns the GDAL driver name for a specified file extension.
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.
bool isEmpty() const
Returns true if the rectangle is empty.
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.
CORE_EXPORT QgsRasterBlock * exportRasterBlock(const QgsMeshLayer &layer, const QgsMeshDatasetIndex &datasetIndex, const QgsCoordinateReferenceSystem &destinationCrs, const QgsCoordinateTransformContext &transformContext, double mapUnitsPerPixel, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Exports mesh layer's dataset values as raster block.
QVector< int > QgsMeshFace
List of vertex indexes.
QPair< int, int > QgsMeshEdge
Edge is a straight line seqment between 2 points.
const QgsCoordinateReferenceSystem & outputCrs
Mesh - vertices, edges and faces.
void clear()
Remove all vertices, edges and faces.
int faceCount() const
Returns number of faces.