QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
qgsalgorithmpixelcentroidsfrompolygons.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmpixelcentroidsfrompolygons.cpp
3 ---------------------
4 begin : December 2019
5 copyright : (C) 2019 by Alexander Bruy
6 email : alexander dot bruy 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#include "qgsgeometryengine.h"
21
23
24QString QgsPixelCentroidsFromPolygonsAlgorithm::name() const
25{
26 return QStringLiteral( "generatepointspixelcentroidsinsidepolygons" );
27}
28
29QString QgsPixelCentroidsFromPolygonsAlgorithm::displayName() const
30{
31 return QObject::tr( "Generate points (pixel centroids) inside polygons" );
32}
33
34QStringList QgsPixelCentroidsFromPolygonsAlgorithm::tags() const
35{
36 return QObject::tr( "raster,polygon,centroid,pixel,create" ).split( ',' );
37}
38
39QString QgsPixelCentroidsFromPolygonsAlgorithm::group() const
40{
41 return QObject::tr( "Vector creation" );
42}
43
44QString QgsPixelCentroidsFromPolygonsAlgorithm::groupId() const
45{
46 return QStringLiteral( "vectorcreation" );
47}
48
49QString QgsPixelCentroidsFromPolygonsAlgorithm::shortHelpString() const
50{
51 return QObject::tr( "Generates pixel centroids for the raster area falling inside polygons. Used to generate points "
52 "for further raster sampling." );
53}
54
55QgsPixelCentroidsFromPolygonsAlgorithm *QgsPixelCentroidsFromPolygonsAlgorithm::createInstance() const
56{
57 return new QgsPixelCentroidsFromPolygonsAlgorithm();
58}
59
60void QgsPixelCentroidsFromPolygonsAlgorithm::initAlgorithm( const QVariantMap & )
61{
62 addParameter( new QgsProcessingParameterRasterLayer( QStringLiteral( "INPUT_RASTER" ), QObject::tr( "Raster layer" ) ) );
63 addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT_VECTOR" ), QObject::tr( "Vector layer" ), QList< int >() << QgsProcessing::TypeVectorPolygon ) );
64
65 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Pixel centroids" ), QgsProcessing::TypeVectorPoint ) );
66}
67
68QVariantMap QgsPixelCentroidsFromPolygonsAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
69{
70 QgsRasterLayer *rasterLayer = parameterAsRasterLayer( parameters, QStringLiteral( "INPUT_RASTER" ), context );
71
72 if ( !rasterLayer )
73 throw QgsProcessingException( invalidRasterError( parameters, QStringLiteral( "INPUT_RASTER" ) ) );
74
75 std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT_VECTOR" ), context ) );
76 if ( !source )
77 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT_VECTOR" ) ) );
78
79 QgsFields fields;
80 fields.append( QgsField( QStringLiteral( "id" ), QVariant::LongLong ) );
81 fields.append( QgsField( QStringLiteral( "poly_id" ), QVariant::Int ) );
82 fields.append( QgsField( QStringLiteral( "point_id" ), QVariant::Int ) );
83
84 QString dest;
85 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, Qgis::WkbType::Point, rasterLayer->crs(), QgsFeatureSink::RegeneratePrimaryKey ) );
86 if ( !sink )
87 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
88
89 const double step = source->featureCount() ? 100.0 / source->featureCount() : 1;
90 QgsFeatureIterator it = source->getFeatures( QgsFeatureRequest().setDestinationCrs( rasterLayer->crs(), context.transformContext() ).setSubsetOfAttributes( QList< int >() ) );
91
92 const double xPixel = rasterLayer->rasterUnitsPerPixelX();
93 const double yPixel = rasterLayer->rasterUnitsPerPixelY();
94 const QgsRectangle extent = rasterLayer->extent();
95
96 QgsFeature feature;
97 feature.setFields( fields );
98
99 int fid = 0;
100 int pointId = 0;
101
102 int i = 0;
103 QgsFeature f;
104 while ( it.nextFeature( f ) )
105 {
106 if ( feedback->isCanceled() )
107 {
108 break;
109 }
110
111 if ( !f.hasGeometry() )
112 {
113 continue;
114 }
115
116 const QgsRectangle bbox = f.geometry().boundingBox();
117 const double xMin = bbox.xMinimum();
118 const double xMax = bbox.xMaximum();
119 const double yMin = bbox.yMinimum();
120 const double yMax = bbox.yMaximum();
121
122 double x, y;
123 int startRow, startColumn;
124 int endRow, endColumn;
125 QgsRasterAnalysisUtils::mapToPixel( xMin, yMax, extent, xPixel, yPixel, startRow, startColumn );
126 QgsRasterAnalysisUtils::mapToPixel( xMax, yMin, extent, xPixel, yPixel, endRow, endColumn );
127
128 std::unique_ptr< QgsGeometryEngine > engine( QgsGeometry::createGeometryEngine( f.geometry().constGet() ) );
129 engine->prepareGeometry();
130
131 for ( int row = startRow; row <= endRow; row++ )
132 {
133 for ( int col = startColumn; col <= endColumn; col++ )
134 {
135 if ( feedback->isCanceled() )
136 {
137 break;
138 }
139
140 QgsRasterAnalysisUtils::pixelToMap( row, col, extent, xPixel, yPixel, x, y );
141 const QgsPoint point( x, y );
142 const QgsGeometry geom( point.clone() );
143 if ( engine->contains( geom.constGet() ) )
144 {
145 feature.setGeometry( geom );
146 feature.setAttributes( QgsAttributes() << fid << i << pointId );
147 if ( !sink->addFeature( feature, QgsFeatureSink::FastInsert ) )
148 throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
149
150 fid++;
151 pointId++;
152 }
153 }
154 }
155
156 pointId = 0;
157
158 feedback->setProgress( i * step );
159 i++;
160 }
161
162 QVariantMap outputs;
163 outputs.insert( QStringLiteral( "OUTPUT" ), dest );
164 return outputs;
165}
166
A vector of attributes.
Definition: qgsattributes.h:59
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:160
void setFields(const QgsFields &fields, bool initAttributes=false)
Assigns a field map with the feature to allow attribute access by attribute name.
Definition: qgsfeature.cpp:195
QgsGeometry geometry
Definition: qgsfeature.h:67
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:230
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:167
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:53
Container of fields for a vector layer.
Definition: qgsfields.h:45
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)
Definition: qgsfields.cpp:59
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:164
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:84
Base class for providing feedback from a processing algorithm.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A raster layer parameter for processing algorithms.
@ TypeVectorPolygon
Vector polygon layers.
Definition: qgsprocessing.h:52
@ TypeVectorPoint
Vector point layers.
Definition: qgsprocessing.h:50
Represents a raster layer.
double rasterUnitsPerPixelX() const
Returns the number of raster units per each raster pixel in X axis.
double rasterUnitsPerPixelY() const
Returns the number of raster units per each raster pixel in Y axis.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198