Branch data Line data Source code
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 : : 18 : : #include "qgsalgorithmgeometrybyexpression.h" 19 : : #include "qgsgeometrycollection.h" 20 : : 21 : : ///@cond PRIVATE 22 : : 23 : 0 : QString QgsGeometryByExpressionAlgorithm::name() const 24 : : { 25 : 0 : return QStringLiteral( "geometrybyexpression" ); 26 : : } 27 : : 28 : 0 : QString QgsGeometryByExpressionAlgorithm::displayName() const 29 : : { 30 : 0 : return QObject::tr( "Geometry by expression" ); 31 : : } 32 : : 33 : 0 : QStringList QgsGeometryByExpressionAlgorithm::tags() const 34 : : { 35 : 0 : return QObject::tr( "geometry,expression,create,modify" ).split( ',' ); 36 : 0 : } 37 : : 38 : 0 : QString QgsGeometryByExpressionAlgorithm::group() const 39 : : { 40 : 0 : return QObject::tr( "Vector geometry" ); 41 : : } 42 : : 43 : 0 : QString QgsGeometryByExpressionAlgorithm::groupId() const 44 : : { 45 : 0 : return QStringLiteral( "vectorgeometry" ); 46 : : } 47 : : 48 : 0 : QString QgsGeometryByExpressionAlgorithm::outputName() const 49 : : { 50 : 0 : return QObject::tr( "Modified geometry" ); 51 : : } 52 : : 53 : 0 : QString QgsGeometryByExpressionAlgorithm::shortHelpString() const 54 : : { 55 : 0 : 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 : 0 : QgsGeometryByExpressionAlgorithm *QgsGeometryByExpressionAlgorithm::createInstance() const 64 : : { 65 : 0 : return new QgsGeometryByExpressionAlgorithm(); 66 : 0 : } 67 : : 68 : 0 : QList<int> QgsGeometryByExpressionAlgorithm::inputLayerTypes() const 69 : : { 70 : 0 : return QList< int >() << QgsProcessing::TypeVector; 71 : 0 : } 72 : : 73 : 0 : QgsWkbTypes::Type QgsGeometryByExpressionAlgorithm::outputWkbType( QgsWkbTypes::Type ) const 74 : : { 75 : 0 : return mWkbType; 76 : : } 77 : : 78 : 0 : QgsProcessingFeatureSource::Flag QgsGeometryByExpressionAlgorithm::sourceFlags() const 79 : : { 80 : 0 : return QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks; 81 : : } 82 : : 83 : 0 : void QgsGeometryByExpressionAlgorithm::initParameters( const QVariantMap & ) 84 : : { 85 : 0 : addParameter( new QgsProcessingParameterEnum( QStringLiteral( "OUTPUT_GEOMETRY" ), QObject::tr( "Output geometry type" ), 86 : 0 : QStringList() << QObject::tr( "Polygon" ) << QObject::tr( "Line" ) << QObject::tr( "Point" ), false, 0 ) ); 87 : 0 : addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "WITH_Z" ), QObject::tr( "Output geometry has z dimension" ), false ) ); 88 : 0 : addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "WITH_M" ), QObject::tr( "Output geometry has m values" ), false ) ); 89 : 0 : addParameter( new QgsProcessingParameterExpression( QStringLiteral( "EXPRESSION" ), QObject::tr( "Geometry expression" ), 90 : 0 : QStringLiteral( "$geometry" ), QStringLiteral( "INPUT" ) ) ); 91 : 0 : } 92 : : 93 : 0 : bool QgsGeometryByExpressionAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) 94 : : { 95 : 0 : int geometryType = parameterAsInt( parameters, QStringLiteral( "OUTPUT_GEOMETRY" ), context ); 96 : 0 : switch ( geometryType ) 97 : : { 98 : : case 0: 99 : 0 : mWkbType = QgsWkbTypes::Type::Polygon; 100 : 0 : break; 101 : : case 1: 102 : 0 : mWkbType = QgsWkbTypes::Type::LineString; 103 : 0 : break; 104 : : case 2: 105 : 0 : mWkbType = QgsWkbTypes::Type::Point; 106 : 0 : break; 107 : : } 108 : : 109 : 0 : if ( parameterAsBoolean( parameters, QStringLiteral( "WITH_Z" ), context ) ) 110 : : { 111 : 0 : mWkbType = QgsWkbTypes::addZ( mWkbType ); 112 : 0 : } 113 : 0 : if ( parameterAsBoolean( parameters, QStringLiteral( "WITH_M" ), context ) ) 114 : : { 115 : 0 : mWkbType = QgsWkbTypes::addM( mWkbType ); 116 : 0 : } 117 : : 118 : 0 : mExpression = QgsExpression( parameterAsString( parameters, QStringLiteral( "EXPRESSION" ), context ) ); 119 : 0 : if ( mExpression.hasParserError() ) 120 : : { 121 : 0 : feedback->reportError( mExpression.parserErrorString() ); 122 : 0 : return false; 123 : : } 124 : : 125 : 0 : mExpressionContext = createExpressionContext( parameters, context ); 126 : 0 : mExpression.prepare( &mExpressionContext ); 127 : : 128 : 0 : return true; 129 : 0 : } 130 : : 131 : 0 : QgsFeatureList QgsGeometryByExpressionAlgorithm::processFeature( const QgsFeature &f, QgsProcessingContext &, QgsProcessingFeedback * ) 132 : : { 133 : 0 : QgsFeature feature = f; 134 : 0 : mExpressionContext.setFeature( feature ); 135 : 0 : QVariant value = mExpression.evaluate( &mExpressionContext ); 136 : : 137 : 0 : if ( mExpression.hasEvalError() ) 138 : : { 139 : 0 : throw QgsProcessingException( QObject::tr( "Evaluation error: %1" ).arg( mExpression.evalErrorString() ) ); 140 : : } 141 : : 142 : 0 : if ( value.isNull() ) 143 : : { 144 : 0 : feature.setGeometry( QgsGeometry() ); 145 : 0 : } 146 : : else 147 : : { 148 : 0 : if ( value.canConvert< QgsGeometry >() ) 149 : : { 150 : 0 : QgsGeometry geom = value.value<QgsGeometry>(); 151 : 0 : feature.setGeometry( geom ); 152 : 0 : } 153 : : else 154 : : { 155 : 0 : throw QgsProcessingException( QObject::tr( "%1 is not a geometry" ).arg( value.toString() ) ); 156 : : } 157 : : } 158 : : 159 : 0 : return QgsFeatureList() << feature; 160 : 0 : } 161 : : 162 : : ///@endcond