QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 = qgis::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  int count = 0;
106  int total = sourceA->featureCount() * 2 + sourceB->featureCount();
107 
108  QgsOverlayUtils::intersection( *sourceA, *sourceB, *sink, context, feedback, count, total, fieldIndicesA, fieldIndicesB );
109 
110  QgsOverlayUtils::difference( *sourceA, *sourceB, *sink, context, feedback, count, total, QgsOverlayUtils::OutputAB );
111 
112  QgsOverlayUtils::difference( *sourceB, *sourceA, *sink, context, feedback, count, total, QgsOverlayUtils::OutputBA );
113 
114  return outputs;
115 }
116 
QgsWkbTypes::multiType
static Type multiType(Type type)
Returns the multi type for a WKB type.
Definition: qgswkbtypes.h:301
QgsProcessingFeedback
Definition: qgsprocessingfeedback.h:37
QgsFields
Definition: qgsfields.h:44
QgsProcessingParameterDefinition::FlagAdvanced
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
Definition: qgsprocessingparameters.h:419
QgsProcessingParameterFeatureSource
Definition: qgsprocessingparameters.h:2612
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsProcessingUtils::combineFields
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).
Definition: qgsprocessingutils.cpp:1113
QgsProcessingParameterFeatureSink
Definition: qgsprocessingparameters.h:2773
QgsProcessingContext
Definition: qgsprocessingcontext.h:43
QgsProcessingUtils::fieldNamesToIndices
static QList< int > fieldNamesToIndices(const QStringList &fieldNames, const QgsFields &fields)
Returns a list of field indices parsed from the given list of field names.
Definition: qgsprocessingutils.cpp:1149
qgsalgorithmunion.h
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
QgsProcessingAlgorithm
Definition: qgsprocessingalgorithm.h:51
qgsoverlayutils.h
QgsProcessingException
Definition: qgsexception.h:82