QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsalgorithmpolygonize.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmdpolygonize.cpp
3  ---------------------
4  begin : May 2020
5  copyright : (C) 2020 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 
18 #include "qgsalgorithmpolygonize.h"
19 #include "qgsgeometrycollection.h"
20 
22 
23 QString QgsPolygonizeAlgorithm::name() const
24 {
25  return QStringLiteral( "polygonize" );
26 }
27 
28 QString QgsPolygonizeAlgorithm::displayName() const
29 {
30  return QObject::tr( "Polygonize" );
31 }
32 
33 QString QgsPolygonizeAlgorithm::shortHelpString() const
34 {
35  return QObject::tr( "Creates a polygon layer from the input lines layer." );
36 }
37 
38 QStringList QgsPolygonizeAlgorithm::tags() const
39 {
40  return QObject::tr( "create,lines,polygons,convert" ).split( ',' );
41 }
42 
43 QString QgsPolygonizeAlgorithm::group() const
44 {
45  return QObject::tr( "Vector geometry" );
46 }
47 
48 QString QgsPolygonizeAlgorithm::groupId() const
49 {
50  return QStringLiteral( "vectorgeometry" );
51 }
52 
53 void QgsPolygonizeAlgorithm::initAlgorithm( const QVariantMap & )
54 {
55  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ),
56  QObject::tr( "Input layer" ), QList< int >() << QgsProcessing::TypeVectorLine ) );
57  addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "KEEP_FIELDS" ),
58  QObject::tr( "Keep table structure of line layer" ), false, true ) );
59  addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ),
60  QObject::tr( "Polygons" ), QgsProcessing::TypeVectorPolygon ) );
61  addOutput( new QgsProcessingOutputNumber( QStringLiteral( "NUM_POLYGONS" ), QObject::tr( "Number of polygons" ) ) );
62 }
63 
64 QgsPolygonizeAlgorithm *QgsPolygonizeAlgorithm::createInstance() const
65 {
66  return new QgsPolygonizeAlgorithm();
67 }
68 
69 QVariantMap QgsPolygonizeAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
70 {
71  std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
72  if ( !source )
73  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
74 
75  QgsFields fields = QgsFields();
76  if ( parameterAsBoolean( parameters, QStringLiteral( "KEEP_FIELDS" ), context ) )
77  fields = source->fields();
78 
79  QString dest;
80  std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, QgsWkbTypes::Polygon, source->sourceCrs() ) );
81  if ( !sink )
82  throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
83 
84  int polygonCount = 0;
85 
86  feedback->pushInfo( QObject::tr( "Collecting lines…" ) );
87  const int i = 0;
88  double step = source->featureCount() > 0 ? 40.0 / source->featureCount() : 1;
89  QgsFeature f;
90  QgsFeatureIterator features = source->getFeatures( QgsFeatureRequest().setNoAttributes() );
91  QVector<QgsGeometry> linesList;
92  linesList.reserve( source->featureCount() );
93  while ( features.nextFeature( f ) )
94  {
95  if ( feedback->isCanceled() )
96  break;
97 
98  if ( f.hasGeometry() )
99  linesList << f.geometry();
100 
101  feedback->setProgress( i * step );
102  }
103  feedback->setProgress( 40 );
104 
105  feedback->pushInfo( QObject::tr( "Noding lines…" ) );
106  const QgsGeometry lines = QgsGeometry::unaryUnion( linesList );
107  if ( feedback->isCanceled() )
108  return QVariantMap();
109  feedback->setProgress( 45 );
110 
111  feedback->pushInfo( QObject::tr( "Polygonizing…" ) );
112  const QgsGeometry polygons = QgsGeometry::polygonize( QVector< QgsGeometry >() << lines );
113  if ( polygons.isEmpty() )
114  feedback->reportError( QObject::tr( "No polygons were created." ) );
115 
116  feedback->setProgress( 50 );
117 
118  if ( !polygons.isEmpty() )
119  {
120  const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( polygons.constGet() );
121  step = collection->numGeometries() > 0 ? 50.0 / collection->numGeometries() : 1;
122  for ( int part = 0; part < collection->numGeometries(); ++part )
123  {
124  if ( feedback->isCanceled() )
125  break;
126 
127  QgsFeature outFeat;
128  outFeat.setGeometry( QgsGeometry( collection->geometryN( part )->clone() ) );
129  if ( !sink->addFeature( outFeat, QgsFeatureSink::FastInsert ) )
130  throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
131  feedback->setProgress( 50 + i * step );
132  polygonCount += 1;
133  }
134  }
135 
136  QVariantMap outputs;
137  outputs.insert( QStringLiteral( "OUTPUT" ), dest );
138  outputs.insert( QStringLiteral( "NUM_POLYGONS" ), polygonCount );
139  return outputs;
140 }
141 
QgsFeedback::setProgress
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:76
QgsProcessingFeedback
Base class for providing feedback from a processing algorithm.
Definition: qgsprocessingfeedback.h:37
QgsProcessingFeedback::pushInfo
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
Definition: qgsprocessingfeedback.cpp:77
QgsProcessingFeedback::reportError
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
Definition: qgsprocessingfeedback.cpp:59
QgsProcessing::TypeVectorPolygon
@ TypeVectorPolygon
Vector polygon layers.
Definition: qgsprocessing.h:51
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:44
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsFeedback::isCanceled
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:67
QgsProcessing::TypeVectorLine
@ TypeVectorLine
Vector line layers.
Definition: qgsprocessing.h:50
QgsProcessingParameterFeatureSource
An input feature source (such as vector layers) parameter for processing algorithms.
Definition: qgsprocessingparameters.h:3057
QgsProcessingOutputNumber
A numeric output for processing algorithms.
Definition: qgsprocessingoutputs.h:312
QgsGeometryCollection::numGeometries
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
Definition: qgsgeometrycollection.h:58
QgsProcessingParameterFeatureSink
A feature sink output for processing algorithms.
Definition: qgsprocessingparameters.h:3219
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
QgsGeometryCollection
Geometry collection.
Definition: qgsgeometrycollection.h:36
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:170
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:46
QgsAbstractGeometry::clone
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
QgsGeometry::isEmpty
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
Definition: qgsgeometry.cpp:379
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:136
QgsGeometry::polygonize
static QgsGeometry polygonize(const QVector< QgsGeometry > &geometries)
Creates a GeometryCollection geometry containing possible polygons formed from the constituent linewo...
Definition: qgsgeometry.cpp:3090
QgsProcessingParameterBoolean
A boolean parameter for processing algorithms.
Definition: qgsprocessingparameters.h:1709
QgsGeometryCollection::geometryN
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
Definition: qgsgeometrycollection.h:86
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:399
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:230
QgsWkbTypes::Polygon
@ Polygon
Definition: qgswkbtypes.h:74
qgsalgorithmpolygonize.h
qgsgeometrycollection.h
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:289
QgsProcessingException
Custom exception class for processing related exceptions.
Definition: qgsexception.h:82
QgsGeometry::unaryUnion
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries)
Compute the unary union on a list of geometries.
Definition: qgsgeometry.cpp:3079
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