QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsalgorithmunion.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmunion.cpp
3  ---------------------
4  Date : April 2018
5  Copyright : (C) 2018 by Martin Dobias
6  Email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsalgorithmunion.h"
17 
18 #include "qgsoverlayutils.h"
19 
21 
22 
23 QString QgsUnionAlgorithm::name() const
24 {
25  return QStringLiteral( "union" );
26 }
27 
28 QString QgsUnionAlgorithm::displayName() const
29 {
30  return QObject::tr( "Union" );
31 }
32 
33 QString QgsUnionAlgorithm::group() const
34 {
35  return QObject::tr( "Vector overlay" );
36 }
37 
38 QString QgsUnionAlgorithm::groupId() const
39 {
40  return QStringLiteral( "vectoroverlay" );
41 }
42 
43 QString QgsUnionAlgorithm::shortHelpString() const
44 {
45  return QObject::tr( "This algorithm checks overlaps between features within the Input layer and creates separate features for overlapping "
46  "and non-overlapping parts. The area of overlap will create as many identical overlapping features as there are "
47  "features that participate in that overlap." )
48  + QStringLiteral( "\n\n" )
49  + QObject::tr( "An Overlay layer can also be used, in which case features from each layer are split at their overlap with features from "
50  "the other one, creating a layer containing all the portions from both Input and Overlay layers. "
51  "The attribute table of the Union layer is filled with attribute values from the respective original layer "
52  "for non-overlapping features, and attribute values from both layers for overlapping features." );
53 }
54 
55 QgsProcessingAlgorithm *QgsUnionAlgorithm::createInstance() const
56 {
57  return new QgsUnionAlgorithm();
58 }
59 
60 void QgsUnionAlgorithm::initAlgorithm( const QVariantMap & )
61 {
62  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
63  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "OVERLAY" ), QObject::tr( "Overlay layer" ), QList< int >(), QVariant(), true ) );
64 
65  std::unique_ptr< QgsProcessingParameterString > prefix = std::make_unique< QgsProcessingParameterString >( QStringLiteral( "OVERLAY_FIELDS_PREFIX" ), QObject::tr( "Overlay fields prefix" ), QString(), false, true );
66  prefix->setFlags( prefix->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
67  addParameter( prefix.release() );
68 
69  addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Union" ) ) );
70 }
71 
72 QVariantMap QgsUnionAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
73 {
74  std::unique_ptr< QgsFeatureSource > sourceA( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
75  if ( !sourceA )
76  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
77 
78  std::unique_ptr< QgsFeatureSource > sourceB( parameterAsSource( parameters, QStringLiteral( "OVERLAY" ), context ) );
79  if ( parameters.value( QStringLiteral( "OVERLAY" ) ).isValid() && !sourceB )
80  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "OVERLAY" ) ) );
81 
82  QgsWkbTypes::Type geomType = QgsWkbTypes::multiType( sourceA->wkbType() );
83 
84  QString overlayFieldsPrefix = parameterAsString( parameters, QStringLiteral( "OVERLAY_FIELDS_PREFIX" ), context );
85  QgsFields fields = sourceB ? QgsProcessingUtils::combineFields( sourceA->fields(), sourceB->fields(), overlayFieldsPrefix ) : sourceA->fields();
86 
87  QString dest;
88  std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, geomType, sourceA->sourceCrs(), QgsFeatureSink::RegeneratePrimaryKey ) );
89  if ( !sink )
90  throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
91 
92  QVariantMap outputs;
93  outputs.insert( QStringLiteral( "OUTPUT" ), dest );
94 
95  if ( !sourceB )
96  {
97  // we are doing single layer union
98  QgsOverlayUtils::resolveOverlaps( *sourceA, *sink, feedback );
99  return outputs;
100  }
101 
102  QList<int> fieldIndicesA = QgsProcessingUtils::fieldNamesToIndices( QStringList(), sourceA->fields() );
103  QList<int> fieldIndicesB = QgsProcessingUtils::fieldNamesToIndices( QStringList(), sourceB->fields() );
104 
105  long count = 0;
106  const long total = sourceA->featureCount() * 2 + sourceB->featureCount();
107 
108  QgsOverlayUtils::intersection( *sourceA, *sourceB, *sink, context, feedback, count, total, fieldIndicesA, fieldIndicesB );
109  if ( feedback->isCanceled() )
110  return outputs;
111 
112  QgsOverlayUtils::difference( *sourceA, *sourceB, *sink, context, feedback, count, total, QgsOverlayUtils::OutputAB );
113  if ( feedback->isCanceled() )
114  return outputs;
115 
116  QgsOverlayUtils::difference( *sourceB, *sourceA, *sink, context, feedback, count, total, QgsOverlayUtils::OutputBA );
117 
118  return outputs;
119 }
120 
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
Container of fields for a vector layer.
Definition: qgsfields.h:45
Abstract base class for processing algorithms.
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
Base class for providing feedback from a processing algorithm.
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
static QList< int > fieldNamesToIndices(const QStringList &fieldNames, const QgsFields &fields)
Returns a list of field indices parsed from the given list of field names.
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB, const QString &fieldsBPrefix=QString())
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
static Type multiType(Type type) SIP_HOLDGIL
Returns the multi type for a WKB type.
Definition: qgswkbtypes.h:302