QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsalgorithmgeometrybyexpression.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmgeometrybyexpression.cpp
3  ------------------------
4  begin : November 2019
5  copyright : (C) 2019 by Alexander Bruy
6  email : alexander dot bruy at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgsgeometrycollection.h"
20 
22 
23 QString QgsGeometryByExpressionAlgorithm::name() const
24 {
25  return QStringLiteral( "geometrybyexpression" );
26 }
27 
28 QString QgsGeometryByExpressionAlgorithm::displayName() const
29 {
30  return QObject::tr( "Geometry by expression" );
31 }
32 
33 QStringList QgsGeometryByExpressionAlgorithm::tags() const
34 {
35  return QObject::tr( "geometry,expression,create,modify" ).split( ',' );
36 }
37 
38 QString QgsGeometryByExpressionAlgorithm::group() const
39 {
40  return QObject::tr( "Vector geometry" );
41 }
42 
43 QString QgsGeometryByExpressionAlgorithm::groupId() const
44 {
45  return QStringLiteral( "vectorgeometry" );
46 }
47 
48 QString QgsGeometryByExpressionAlgorithm::outputName() const
49 {
50  return QObject::tr( "Modified geometry" );
51 }
52 
53 QString QgsGeometryByExpressionAlgorithm::shortHelpString() const
54 {
55  return QObject::tr( "This algorithm updates existing geometries (or creates new geometries) for input "
56  "features by use of a QGIS expression. This allows complex geometry modifications "
57  "which can utilize all the flexibility of the QGIS expression engine to manipulate "
58  "and create geometries for output features.\n\n"
59  "For help with QGIS expression functions, see the inbuilt help for specific functions "
60  "which is available in the expression builder." );
61 }
62 
63 QgsGeometryByExpressionAlgorithm *QgsGeometryByExpressionAlgorithm::createInstance() const
64 {
65  return new QgsGeometryByExpressionAlgorithm();
66 }
67 
68 QList<int> QgsGeometryByExpressionAlgorithm::inputLayerTypes() const
69 {
70  return QList< int >() << QgsProcessing::TypeVector;
71 }
72 
73 QgsWkbTypes::Type QgsGeometryByExpressionAlgorithm::outputWkbType( QgsWkbTypes::Type ) const
74 {
75  return mWkbType;
76 }
77 
78 QgsProcessingFeatureSource::Flag QgsGeometryByExpressionAlgorithm::sourceFlags() const
79 {
81 }
82 
83 void QgsGeometryByExpressionAlgorithm::initParameters( const QVariantMap & )
84 {
85  addParameter( new QgsProcessingParameterEnum( QStringLiteral( "OUTPUT_GEOMETRY" ), QObject::tr( "Output geometry type" ),
86  QStringList() << QObject::tr( "Polygon" ) << QObject::tr( "Line" ) << QObject::tr( "Point" ), false, 0 ) );
87  addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "WITH_Z" ), QObject::tr( "Output geometry has z dimension" ), false ) );
88  addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "WITH_M" ), QObject::tr( "Output geometry has m values" ), false ) );
89  addParameter( new QgsProcessingParameterExpression( QStringLiteral( "EXPRESSION" ), QObject::tr( "Geometry expression" ),
90  QStringLiteral( "$geometry" ), QStringLiteral( "INPUT" ) ) );
91 }
92 
93 bool QgsGeometryByExpressionAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
94 {
95  int geometryType = parameterAsInt( parameters, QStringLiteral( "OUTPUT_GEOMETRY" ), context );
96  switch ( geometryType )
97  {
98  case 0:
99  mWkbType = QgsWkbTypes::Type::Polygon;
100  break;
101  case 1:
102  mWkbType = QgsWkbTypes::Type::LineString;
103  break;
104  case 2:
105  mWkbType = QgsWkbTypes::Type::Point;
106  break;
107  }
108 
109  if ( parameterAsBoolean( parameters, QStringLiteral( "WITH_Z" ), context ) )
110  {
111  mWkbType = QgsWkbTypes::addZ( mWkbType );
112  }
113  if ( parameterAsBoolean( parameters, QStringLiteral( "WITH_M" ), context ) )
114  {
115  mWkbType = QgsWkbTypes::addM( mWkbType );
116  }
117 
118  mExpression = QgsExpression( parameterAsString( parameters, QStringLiteral( "EXPRESSION" ), context ) );
119  if ( mExpression.hasParserError() )
120  {
121  feedback->reportError( mExpression.parserErrorString() );
122  return false;
123  }
124 
125  mExpressionContext = createExpressionContext( parameters, context );
126  mExpression.prepare( &mExpressionContext );
127 
128  return true;
129 }
130 
131 QgsFeatureList QgsGeometryByExpressionAlgorithm::processFeature( const QgsFeature &f, QgsProcessingContext &, QgsProcessingFeedback * )
132 {
133  QgsFeature feature = f;
134  mExpressionContext.setFeature( feature );
135  QVariant value = mExpression.evaluate( &mExpressionContext );
136 
137  if ( mExpression.hasEvalError() )
138  {
139  throw QgsProcessingException( QObject::tr( "Evaluation error: %1" ).arg( mExpression.evalErrorString() ) );
140  }
141 
142  if ( value.isNull() )
143  {
144  feature.setGeometry( QgsGeometry() );
145  }
146  else
147  {
148  if ( value.canConvert< QgsGeometry >() )
149  {
150  QgsGeometry geom = value.value<QgsGeometry>();
151  feature.setGeometry( geom );
152  }
153  else
154  {
155  throw QgsProcessingException( QObject::tr( "%1 is not a geometry" ).arg( value.toString() ) );
156  }
157  }
158 
159  return QgsFeatureList() << feature;
160 }
161 
QgsProcessingFeedback
Definition: qgsprocessingfeedback.h:37
QgsProcessingFeedback::reportError
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
Definition: qgsprocessingfeedback.cpp:39
QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks
@ FlagSkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition: qgsprocessingutils.h:475
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsWkbTypes::addM
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1163
qgsalgorithmgeometrybyexpression.h
QgsProcessing::TypeVector
@ TypeVector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:53
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:137
QgsProcessingContext
Definition: qgsprocessingcontext.h:43
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:572
QgsWkbTypes::addZ
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1138
QgsProcessingParameterBoolean
Definition: qgsprocessingparameters.h:1439
QgsProcessingFeatureSource::Flag
Flag
Flags controlling how QgsProcessingFeatureSource fetches features.
Definition: qgsprocessingutils.h:473
QgsGeometry
Definition: qgsgeometry.h:122
QgsProcessingParameterExpression
Definition: qgsprocessingparameters.h:2294
qgsgeometrycollection.h
QgsFeature
Definition: qgsfeature.h:55
QgsProcessingParameterEnum
Definition: qgsprocessingparameters.h:2134
QgsExpression
Definition: qgsexpression.h:113
QgsProcessingException
Definition: qgsexception.h:82