QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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  const QgsWkbTypes::Type geomTypeA = QgsWkbTypes::promoteNonPointTypesToMulti( sourceA->wkbType() );
83  const QgsWkbTypes::Type geomTypeB = QgsWkbTypes::promoteNonPointTypesToMulti( sourceB->wkbType() );
84 
85  if ( geomTypeA != geomTypeB )
86  feedback->pushWarning( QObject::tr( "Performing symmetrical difference between layers with different geometry types (INPUT has %1 and OVERLAY has %2) can lead to unexpected results" ).arg( QgsWkbTypes::displayString( sourceA->wkbType() ), QgsWkbTypes::displayString( sourceB->wkbType() ) ) );
87 
88  const QString overlayFieldsPrefix = parameterAsString( parameters, QStringLiteral( "OVERLAY_FIELDS_PREFIX" ), context );
89  const QgsFields fields = QgsProcessingUtils::combineFields( sourceA->fields(), sourceB->fields(), overlayFieldsPrefix );
90 
91  QString dest;
92  std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, geomTypeA, sourceA->sourceCrs(), QgsFeatureSink::RegeneratePrimaryKey ) );
93  if ( !sink )
94  throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
95 
96  QVariantMap outputs;
97  outputs.insert( QStringLiteral( "OUTPUT" ), dest );
98 
99  long count = 0;
100  const long total = sourceA->featureCount() + sourceB->featureCount();
101 
102  QgsOverlayUtils::difference( *sourceA, *sourceB, *sink, context, feedback, count, total, QgsOverlayUtils::OutputAB );
103  if ( feedback->isCanceled() )
104  return outputs;
105 
106  QgsOverlayUtils::difference( *sourceB, *sourceA, *sink, context, feedback, count, total, QgsOverlayUtils::OutputBA );
107 
108  return outputs;
109 }
110 
qgsalgorithmsymmetricaldifference.h
QgsWkbTypes::displayString
static QString displayString(Type type) SIP_HOLDGIL
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
Definition: qgswkbtypes.cpp:145
QgsProcessingFeedback
Base class for providing feedback from a processing algorithm.
Definition: qgsprocessingfeedback.h:37
QgsWkbTypes::promoteNonPointTypesToMulti
static Type promoteNonPointTypesToMulti(Type type) SIP_HOLDGIL
Promotes a WKB geometry type to its multi-type equivalent, with the exception of point geometry types...
Definition: qgswkbtypes.h:451
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:44
QgsFeedback::isCanceled
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:67
QgsProcessingParameterDefinition::FlagAdvanced
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
Definition: qgsprocessingparameters.h:451
QgsProcessingParameterFeatureSource
An input feature source (such as vector layers) parameter for processing algorithms.
Definition: qgsprocessingparameters.h:3057
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:69
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:1238
QgsProcessingParameterFeatureSink
A feature sink output for processing algorithms.
Definition: qgsprocessingparameters.h:3219
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:46
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
Abstract base class for processing algorithms.
Definition: qgsprocessingalgorithm.h:52
qgsoverlayutils.h
QgsProcessingException
Custom exception class for processing related exceptions.
Definition: qgsexception.h:82
QgsProcessingFeedback::pushWarning
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
Definition: qgsprocessingfeedback.cpp:68