QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsalgorithmsymmetricaldifference.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmsymmetricaldifference.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 
17 
18 #include "qgsoverlayutils.h"
19 
21 
22 QString QgsSymmetricalDifferenceAlgorithm::name() const
23 {
24  return QStringLiteral( "symmetricaldifference" );
25 }
26 
27 QString QgsSymmetricalDifferenceAlgorithm::displayName() const
28 {
29  return QObject::tr( "Symmetrical difference" );
30 }
31 
32 QStringList QgsSymmetricalDifferenceAlgorithm::tags() const
33 {
34  return QObject::tr( "difference,symdiff,not overlap" ).split( ',' );
35 }
36 
37 QString QgsSymmetricalDifferenceAlgorithm::group() const
38 {
39  return QObject::tr( "Vector overlay" );
40 }
41 
42 QString QgsSymmetricalDifferenceAlgorithm::groupId() const
43 {
44  return QStringLiteral( "vectoroverlay" );
45 }
46 
47 QString QgsSymmetricalDifferenceAlgorithm::shortHelpString() const
48 {
49  return QObject::tr( "This algorithm extracts the portions of features from both the Input and Overlay layers that do not overlap. "
50  "Overlapping areas between the two layers are removed. The attribute table of the Symmetrical Difference layer "
51  "contains original attributes from both the Input and Difference layers." );
52 }
53 
54 QgsProcessingAlgorithm *QgsSymmetricalDifferenceAlgorithm::createInstance() const
55 {
56  return new QgsSymmetricalDifferenceAlgorithm();
57 }
58 
59 void QgsSymmetricalDifferenceAlgorithm::initAlgorithm( const QVariantMap & )
60 {
61  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
62  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "OVERLAY" ), QObject::tr( "Overlay layer" ) ) );
63 
64  std::unique_ptr< QgsProcessingParameterString > prefix = std::make_unique< QgsProcessingParameterString >( QStringLiteral( "OVERLAY_FIELDS_PREFIX" ), QObject::tr( "Overlay fields prefix" ), QString(), false, true );
65  prefix->setFlags( prefix->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
66  addParameter( prefix.release() );
67 
68  addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Symmetrical difference" ) ) );
69 }
70 
71 
72 QVariantMap QgsSymmetricalDifferenceAlgorithm::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 ( !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 = QgsProcessingUtils::combineFields( sourceA->fields(), sourceB->fields(), overlayFieldsPrefix );
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  long count = 0;
96  const long total = sourceA->featureCount() + sourceB->featureCount();
97 
98  QgsOverlayUtils::difference( *sourceA, *sourceB, *sink, context, feedback, count, total, QgsOverlayUtils::OutputAB );
99  if ( feedback->isCanceled() )
100  return outputs;
101 
102  QgsOverlayUtils::difference( *sourceB, *sourceA, *sink, context, feedback, count, total, QgsOverlayUtils::OutputBA );
103 
104  return outputs;
105 }
106 
@ 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 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