Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsalgorithmsinglesidedbuffer.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 "qgsalgorithmsinglesidedbuffer.h" 19 : : #include "qgsprocessing.h" 20 : : 21 : : ///@cond PRIVATE 22 : : 23 : 0 : QString QgsSingleSidedBufferAlgorithm::name() const 24 : : { 25 : 0 : return QStringLiteral( "singlesidedbuffer" ); 26 : : } 27 : : 28 : 0 : QString QgsSingleSidedBufferAlgorithm::displayName() const 29 : : { 30 : 0 : return QObject::tr( "Single sided buffer" ); 31 : : } 32 : : 33 : 0 : QStringList QgsSingleSidedBufferAlgorithm::tags() const 34 : : { 35 : 0 : return QObject::tr( "rectangle,perpendicular,right,angles,square,quadrilateralise" ).split( ',' ); 36 : 0 : } 37 : : 38 : 0 : QString QgsSingleSidedBufferAlgorithm::group() const 39 : : { 40 : 0 : return QObject::tr( "Vector geometry" ); 41 : : } 42 : : 43 : 0 : QString QgsSingleSidedBufferAlgorithm::groupId() const 44 : : { 45 : 0 : return QStringLiteral( "vectorgeometry" ); 46 : : } 47 : : 48 : 0 : QString QgsSingleSidedBufferAlgorithm::shortHelpString() const 49 : : { 50 : 0 : return QObject::tr( "This algorithm buffers lines by a specified distance on one " 51 : : "side of the line only.\n\nThe segments parameter controls " 52 : : "the number of line segments to use to approximate a quarter " 53 : : "circle when creating rounded buffers. The join style parameter " 54 : : "specifies whether round, miter or beveled joins should be used " 55 : : "when buffering corners in a line. The miter limit parameter is " 56 : : "only applicable for miter join styles, and controls the maximum " 57 : : "distance from the buffer to use when creating a mitered join." ); 58 : : } 59 : : 60 : 0 : QString QgsSingleSidedBufferAlgorithm::outputName() const 61 : : { 62 : 0 : return QObject::tr( "Buffered" ); 63 : : } 64 : : 65 : 0 : QList<int> QgsSingleSidedBufferAlgorithm::inputLayerTypes() const 66 : : { 67 : 0 : return QList<int>() << QgsProcessing::TypeVectorLine; 68 : 0 : } 69 : : 70 : 0 : QgsProcessing::SourceType QgsSingleSidedBufferAlgorithm::outputLayerType() const 71 : : { 72 : 0 : return QgsProcessing::TypeVectorPolygon; 73 : : } 74 : : 75 : 0 : QgsWkbTypes::Type QgsSingleSidedBufferAlgorithm::outputWkbType( QgsWkbTypes::Type type ) const 76 : : { 77 : : Q_UNUSED( type ); 78 : 0 : return QgsWkbTypes::Polygon; 79 : : } 80 : : 81 : 0 : QgsSingleSidedBufferAlgorithm *QgsSingleSidedBufferAlgorithm::createInstance() const 82 : : { 83 : 0 : return new QgsSingleSidedBufferAlgorithm(); 84 : 0 : } 85 : : 86 : 0 : void QgsSingleSidedBufferAlgorithm::initParameters( const QVariantMap & ) 87 : : { 88 : 0 : auto bufferParam = std::make_unique < QgsProcessingParameterDistance >( QStringLiteral( "DISTANCE" ), QObject::tr( "Distance" ), 10, QStringLiteral( "INPUT" ) ); 89 : 0 : bufferParam->setIsDynamic( true ); 90 : 0 : bufferParam->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Distance" ), QObject::tr( "Buffer distance" ), QgsPropertyDefinition::Double ) ); 91 : 0 : bufferParam->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) ); 92 : 0 : addParameter( bufferParam.release() ); 93 : : 94 : 0 : addParameter( new QgsProcessingParameterEnum( QStringLiteral( "SIDE" ), QObject::tr( "Side" ), QStringList() << QObject::tr( "Left" ) << QObject::tr( "Right" ), false, 0 ) ); 95 : 0 : addParameter( new QgsProcessingParameterNumber( QStringLiteral( "SEGMENTS" ), QObject::tr( "Segments" ), QgsProcessingParameterNumber::Integer, 8, false, 1 ) ); 96 : 0 : addParameter( new QgsProcessingParameterEnum( QStringLiteral( "JOIN_STYLE" ), QObject::tr( "Join style" ), QStringList() << QObject::tr( "Round" ) << QObject::tr( "Miter" ) << QObject::tr( "Bevel" ), false, 0 ) ); 97 : 0 : addParameter( new QgsProcessingParameterNumber( QStringLiteral( "MITER_LIMIT" ), QObject::tr( "Miter limit" ), QgsProcessingParameterNumber::Double, 2, false, 1 ) ); 98 : 0 : } 99 : : 100 : 0 : bool QgsSingleSidedBufferAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) 101 : : { 102 : 0 : mDistance = parameterAsDouble( parameters, QStringLiteral( "DISTANCE" ), context ); 103 : 0 : mDynamicDistance = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DISTANCE" ) ); 104 : 0 : if ( mDynamicDistance ) 105 : 0 : mDistanceProperty = parameters.value( QStringLiteral( "DISTANCE" ) ).value< QgsProperty >(); 106 : : 107 : 0 : mSide = static_cast< QgsGeometry::BufferSide>( parameterAsInt( parameters, QStringLiteral( "SIDE" ), context ) ); 108 : 0 : mSegments = parameterAsInt( parameters, QStringLiteral( "SEGMENTS" ), context ); 109 : 0 : mJoinStyle = static_cast< QgsGeometry::JoinStyle>( 1 + parameterAsInt( parameters, QStringLiteral( "JOIN_STYLE" ), context ) ); 110 : 0 : mMiterLimit = parameterAsDouble( parameters, QStringLiteral( "MITER_LIMIT" ), context ); 111 : : 112 : 0 : return true; 113 : 0 : } 114 : : 115 : 0 : QgsFeatureList QgsSingleSidedBufferAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * ) 116 : : { 117 : 0 : QgsFeature f = feature; 118 : : 119 : 0 : if ( f.hasGeometry() ) 120 : : { 121 : 0 : double distance = mDistance; 122 : 0 : if ( mDynamicDistance ) 123 : 0 : distance = mDistanceProperty.valueAsDouble( context.expressionContext(), distance ); 124 : : 125 : 0 : QgsGeometry outputGeometry = f.geometry().singleSidedBuffer( distance, mSegments, mSide, mJoinStyle, mMiterLimit ); 126 : 0 : if ( outputGeometry.isNull() ) 127 : 0 : throw QgsProcessingException( QObject::tr( "Error calculating single sided buffer" ) ); 128 : : 129 : 0 : f.setGeometry( outputGeometry ); 130 : 0 : } 131 : : 132 : 0 : return QgsFeatureList() << f; 133 : 0 : } 134 : : 135 : : ///@endcond