QGIS API Documentation  3.2.0-Bonn (bc43194)
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 creates a layer containing all the features from both input layers. In the case of polygon layers, separate features are created for overlapping and non-overlapping features. The attribute table of the union layer contains attribute values from the respective input layer for non-overlapping features, and attribute values from both input layers for overlapping features." );
46 }
47 
48 QgsProcessingAlgorithm *QgsUnionAlgorithm::createInstance() const
49 {
50  return new QgsUnionAlgorithm();
51 }
52 
53 void QgsUnionAlgorithm::initAlgorithm( const QVariantMap & )
54 {
55  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
56  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "OVERLAY" ), QObject::tr( "Union layer" ), QList< int >(), QVariant(), true ) );
57 
58  addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Union" ) ) );
59 }
60 
61 QVariantMap QgsUnionAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
62 {
63  std::unique_ptr< QgsFeatureSource > sourceA( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
64  if ( !sourceA )
65  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
66 
67  std::unique_ptr< QgsFeatureSource > sourceB( parameterAsSource( parameters, QStringLiteral( "OVERLAY" ), context ) );
68  if ( parameters.value( QStringLiteral( "OVERLAY" ) ).isValid() && !sourceB )
69  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "OVERLAY" ) ) );
70 
71  QgsWkbTypes::Type geomType = QgsWkbTypes::multiType( sourceA->wkbType() );
72 
73  QgsFields fields = sourceB ? QgsProcessingUtils::combineFields( sourceA->fields(), sourceB->fields() ) : sourceA->fields();
74 
75  QString dest;
76  std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, geomType, sourceA->sourceCrs() ) );
77  if ( !sink )
78  throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
79 
80  QVariantMap outputs;
81  outputs.insert( QStringLiteral( "OUTPUT" ), dest );
82 
83  if ( !sourceB )
84  {
85  // we are doing single layer union
86  QgsOverlayUtils::resolveOverlaps( *sourceA.get(), *sink.get(), feedback );
87  return outputs;
88  }
89 
90  QList<int> fieldIndicesA = QgsProcessingUtils::fieldNamesToIndices( QStringList(), sourceA->fields() );
91  QList<int> fieldIndicesB = QgsProcessingUtils::fieldNamesToIndices( QStringList(), sourceB->fields() );
92 
93  int count = 0;
94  int total = sourceA->featureCount() * 2 + sourceB->featureCount();
95 
96  QgsOverlayUtils::intersection( *sourceA.get(), *sourceB.get(), *sink.get(), context, feedback, count, total, fieldIndicesA, fieldIndicesB );
97 
98  QgsOverlayUtils::difference( *sourceA.get(), *sourceB.get(), *sink.get(), context, feedback, count, total, QgsOverlayUtils::OutputAB );
99 
100  QgsOverlayUtils::difference( *sourceB.get(), *sourceA.get(), *sink.get(), context, feedback, count, total, QgsOverlayUtils::OutputBA );
101 
102  return outputs;
103 }
104 
static Type multiType(Type type)
Returns the multi type for a WKB type.
Definition: qgswkbtypes.h:296
Base class for providing feedback from a processing algorithm.
Container of fields for a vector layer.
Definition: qgsfields.h:42
Abstract base class for processing algorithms.
A feature sink output 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.
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:67
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB)
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).
Custom exception class for processing related exceptions.
Definition: qgsexception.h:82
An input feature source (such as vector layers) parameter for processing algorithms.
Contains information about the context in which a processing algorithm is executed.