QGIS API Documentation 4.3.0-Master (ffcfc20b9b4)
Loading...
Searching...
No Matches
qgsalgorithmcoverageunion.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmcoverageunion.cpp
3 ---------------------
4 begin : October 2023
5 copyright : (C) 2023 by Nyall Dawson
6 email : nyall dot dawson 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
20
22#include "qgsgeos.h"
23
24#include <QString>
25
26using namespace Qt::StringLiterals;
27
29
30QString QgsCoverageUnionAlgorithm::name() const
31{
32 return u"coverageunion"_s;
33}
34
35QString QgsCoverageUnionAlgorithm::displayName() const
36{
37 return QObject::tr( "Dissolve coverage" );
38}
39
40QStringList QgsCoverageUnionAlgorithm::tags() const
41{
42 return QObject::tr( "union,merge,topological,boundary" ).split( ',' );
43}
44
45QString QgsCoverageUnionAlgorithm::group() const
46{
47 return QObject::tr( "Vector coverage" );
48}
49
50QString QgsCoverageUnionAlgorithm::groupId() const
51{
52 return u"vectorcoverage"_s;
53}
54
55void QgsCoverageUnionAlgorithm::initAlgorithm( const QVariantMap & )
56{
57 addParameter( new QgsProcessingParameterFeatureSource( u"INPUT"_s, QObject::tr( "Input layer" ), QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorPolygon ) ) );
58 addParameter( new QgsProcessingParameterFeatureSink( u"OUTPUT"_s, QObject::tr( "Dissolved" ), Qgis::ProcessingSourceType::VectorPolygon ) );
59}
60
61QString QgsCoverageUnionAlgorithm::shortDescription() const
62{
63 return QObject::tr( "Dissolves a coverage of polygon features." );
64}
65
66QString QgsCoverageUnionAlgorithm::shortHelpString() const
67{
68 return QObject::tr(
69 "This algorithm operates on a coverage (represented as a set of polygon features "
70 "with exactly matching edge geometry) to dissolve (union) the geometries.\n\n"
71 "It provides a heavily optimized approach for unioning these features compared with "
72 "the standard Dissolve tools."
73 );
74}
75
76QgsCoverageUnionAlgorithm *QgsCoverageUnionAlgorithm::createInstance() const
77{
78 return new QgsCoverageUnionAlgorithm();
79}
80
81QVariantMap QgsCoverageUnionAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
82{
83 QGS_MARK_ALGORITHM_SOURCE
84
85 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, u"INPUT"_s, context ) );
86 if ( !source )
87 throw QgsProcessingException( invalidSourceError( parameters, u"INPUT"_s ) );
88
89 QString sinkId;
90 std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, u"OUTPUT"_s, context, sinkId, source->fields(), Qgis::WkbType::MultiPolygon, source->sourceCrs() ) );
91 if ( !sink )
92 throw QgsProcessingException( invalidSinkError( parameters, u"OUTPUT"_s ) );
93
94 // we have to build up a list of geometries in advance
95 QgsGeometryCollection collection;
96
97 const long count = source->featureCount();
98 if ( count > 0 )
99 {
100 collection.reserve( count );
101 }
102
103 const double step = count > 0 ? 100.0 / count : 1;
104 int current = 0;
105
106 feedback->pushInfo( QObject::tr( "Collecting features" ) );
107
108 QgsFeature inFeature;
110 req.setNoAttributes();
111 QgsFeatureIterator features = source->getFeatures( req );
112 while ( features.nextFeature( inFeature ) )
113 {
114 if ( feedback->isCanceled() )
115 {
116 break;
117 }
118
119 if ( inFeature.hasGeometry() )
120 {
121 collection.addGeometry( inFeature.geometry().constGet()->clone() );
122 }
123
124 feedback->setProgress( current * step * 0.2 );
125 current++;
126 }
127
128 feedback->pushInfo( QObject::tr( "Dissolving coverage" ) );
129
130 QgsGeos geos( &collection );
131 QString error;
132
133 switch ( source->invalidGeometryCheck() )
134 {
136 break;
137
140 {
141 if ( geos.validateCoverage( 0, nullptr, &error ) != Qgis::CoverageValidityResult::Valid )
142 {
143 throw QgsProcessingException( QObject::tr( "Coverage is not valid" ) );
144 }
145 break;
146 }
147 }
148
149 std::unique_ptr<QgsAbstractGeometry> dissolved = geos.unionCoverage( &error );
150
151 if ( !dissolved )
152 {
153 if ( !error.isEmpty() )
154 throw QgsProcessingException( error );
155 else
156 throw QgsProcessingException( QObject::tr( "No geometry was returned for dissolved coverage" ) );
157 }
158
159 feedback->setProgress( 95 );
160
161 feedback->pushInfo( QObject::tr( "Storing output" ) );
162 QgsFeature outFeature( source->fields() );
163 outFeature.setGeometry( std::move( dissolved ) );
164 if ( !sink->addFeature( outFeature, QgsFeatureSink::FastInsert ) )
165 throw QgsProcessingException( writeFeatureError( sink.get(), parameters, u"OUTPUT"_s ) );
166 else
167 feedback->featureAddedToSink( u"OUTPUT"_s );
168
169 sink->finalize();
170 feedback->featureSinkFinalized( u"OUTPUT"_s );
171
172 QVariantMap outputs;
173 outputs.insert( u"OUTPUT"_s, sinkId );
174 return outputs;
175}
176
@ VectorPolygon
Vector polygon layers.
Definition qgis.h:3752
@ Valid
Coverage is valid.
Definition qgis.h:2333
@ NoCheck
No invalid geometry checking.
Definition qgis.h:2404
@ AbortOnInvalid
Close iterator on encountering any features with invalid geometry. This requires a slow geometry vali...
Definition qgis.h:2406
@ SkipInvalid
Skip any features with invalid geometry. This requires a slow geometry validity check for every featu...
Definition qgis.h:2405
@ MultiPolygon
MultiPolygon.
Definition qgis.h:302
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
QgsGeometry geometry
Definition qgsfeature.h:66
bool hasGeometry() const
Returns true if the feature has an associated geometry.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:56
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:65
void reserve(int size)
Attempts to allocate memory for at least size geometries.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Does vector analysis using the GEOS library and handles import, export, and exception handling.
Definition qgsgeos.h:175
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
void featureAddedToSink(const QString &output)
Reports that a feature was added to the the sink associated with the specified algorithm output.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
void featureSinkFinalized(const QString &output)
Reports that a feature sink has been finalized.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
Contains geos related utilities and functions.
Definition qgsgeos.h:112