QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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"
20 #include "qgsrasteranalysisutils.h"
21 
23 
24 QString QgsPixelCentroidsFromPolygonsAlgorithm::name() const
25 {
26  return QStringLiteral( "generatepointspixelcentroidsinsidepolygons" );
27 }
28 
29 QString QgsPixelCentroidsFromPolygonsAlgorithm::displayName() const
30 {
31  return QObject::tr( "Generate points (pixel centroids) inside polygons" );
32 }
33 
34 QStringList QgsPixelCentroidsFromPolygonsAlgorithm::tags() const
35 {
36  return QObject::tr( "raster,polygon,centroid,pixel,create" ).split( ',' );
37 }
38 
39 QString QgsPixelCentroidsFromPolygonsAlgorithm::group() const
40 {
41  return QObject::tr( "Vector creation" );
42 }
43 
44 QString QgsPixelCentroidsFromPolygonsAlgorithm::groupId() const
45 {
46  return QStringLiteral( "vectorcreation" );
47 }
48 
49 QString 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 
55 QgsPixelCentroidsFromPolygonsAlgorithm *QgsPixelCentroidsFromPolygonsAlgorithm::createInstance() const
56 {
57  return new QgsPixelCentroidsFromPolygonsAlgorithm();
58 }
59 
60 void 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 
68 QVariantMap 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, QgsWkbTypes::Point, rasterLayer->crs(), QgsFeatureSink::RegeneratePrimaryKey ) );
86  if ( !sink )
87  throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
88 
89  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  double xPixel = rasterLayer->rasterUnitsPerPixelX();
93  double yPixel = rasterLayer->rasterUnitsPerPixelY();
94  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  QgsRectangle bbox = f.geometry().boundingBox();
117  double xMin = bbox.xMinimum();
118  double xMax = bbox.xMaximum();
119  double yMin = bbox.yMinimum();
120  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  QgsPoint point( x, y );
142  QgsGeometry geom( point.clone() );
143  if ( engine->contains( geom.constGet() ) )
144  {
145  feature.setGeometry( geom );
146  feature.setAttributes( QgsAttributes() << fid << i << pointId );
147  sink->addFeature( feature, QgsFeatureSink::FastInsert );
148 
149  fid++;
150  pointId++;
151  }
152  }
153  }
154 
155  pointId = 0;
156 
157  feedback->setProgress( i * step );
158  i++;
159  }
160 
161  QVariantMap outputs;
162  outputs.insert( QStringLiteral( "OUTPUT" ), dest );
163  return outputs;
164 }
165 
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:89
QgsFeedback::setProgress
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:62
QgsWkbTypes::Point
@ Point
Definition: qgswkbtypes.h:72
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
QgsProcessingFeedback
Base class for providing feedback from a processing algorithm.
Definition: qgsprocessingfeedback.h:38
QgsProcessing::TypeVectorPolygon
@ TypeVectorPolygon
Vector polygon layers.
Definition: qgsprocessing.h:50
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:45
QgsRectangle::yMinimum
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:67
QgsProcessingParameterFeatureSource
An input feature source (such as vector layers) parameter for processing algorithms.
Definition: qgsprocessingparameters.h:2734
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:185
qgsrasteranalysisutils.h
QgsFields::append
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
QgsProcessing::TypeVectorPoint
@ TypeVectorPoint
Vector point layers.
Definition: qgsprocessing.h:48
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsProcessingParameterFeatureSink
A feature sink output for processing algorithms.
Definition: qgsprocessingparameters.h:2895
QgsRectangle::xMaximum
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
qgsgeometryengine.h
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:139
QgsFeature::setFields
void setFields(const QgsFields &fields, bool initAttributes=false)
Assign a field map with the feature to allow attribute access by attribute name.
Definition: qgsfeature.cpp:164
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:44
QgsMapLayer::extent
virtual QgsRectangle extent() const
Returns the extent of the layer.
Definition: qgsmaplayer.cpp:197
QgsProcessingParameterRasterLayer
A raster layer parameter for processing algorithms.
Definition: qgsprocessingparameters.h:2223
qgsalgorithmpixelcentroidsfrompolygons.h
QgsProcessingContext::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Definition: qgsprocessingcontext.h:149
QgsRectangle::xMinimum
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
QgsRasterLayer
Represents a raster layer.
Definition: qgsrasterlayer.h:71
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsFeatureSink::RegeneratePrimaryKey
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
Definition: qgsfeaturesink.h:55
QgsRasterLayer::rasterUnitsPerPixelY
double rasterUnitsPerPixelY() const
Returns the number of raster units per each raster pixel in Y axis.
Definition: qgsrasterlayer.cpp:583
QgsFeedback::isCanceled
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:53
QgsGeometry::createGeometryEngine
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine.
Definition: qgsgeometry.cpp:3636
QgsRectangle::yMaximum
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:199
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:996
QgsAttributes
A vector of attributes.
Definition: qgsattributes.h:58
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsFeature::setAttributes
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:129
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:265
QgsProcessingException
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
QgsFeatureSink::FastInsert
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
Definition: qgsfeaturesink.h:70
QgsRasterLayer::rasterUnitsPerPixelX
double rasterUnitsPerPixelX() const
Returns the number of raster units per each raster pixel in X axis.
Definition: qgsrasterlayer.cpp:567
QgsField
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:50