Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsalgorithmorthogonalize.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 "qgsalgorithmorthogonalize.h" 19 : : #include "qgsprocessing.h" 20 : : 21 : : ///@cond PRIVATE 22 : : 23 : 0 : QString QgsOrthogonalizeAlgorithm::name() const 24 : : { 25 : 0 : return QStringLiteral( "orthogonalize" ); 26 : : } 27 : : 28 : 0 : QString QgsOrthogonalizeAlgorithm::displayName() const 29 : : { 30 : 0 : return QObject::tr( "Orthogonalize" ); 31 : : } 32 : : 33 : 0 : QStringList QgsOrthogonalizeAlgorithm::tags() const 34 : : { 35 : 0 : return QObject::tr( "rectangle,perpendicular,right,angles,square,quadrilateralise" ).split( ',' ); 36 : 0 : } 37 : : 38 : 0 : QString QgsOrthogonalizeAlgorithm::group() const 39 : : { 40 : 0 : return QObject::tr( "Vector geometry" ); 41 : : } 42 : : 43 : 0 : QString QgsOrthogonalizeAlgorithm::groupId() const 44 : : { 45 : 0 : return QStringLiteral( "vectorgeometry" ); 46 : : } 47 : : 48 : 0 : QString QgsOrthogonalizeAlgorithm::shortHelpString() const 49 : : { 50 : 0 : return QObject::tr( "Takes a line or polygon layer and attempts to orthogonalize " 51 : : "all the geometries in the layer. This process shifts the nodes " 52 : : "in the geometries to try to make every angle in the geometry " 53 : : "either a right angle or a straight line.\n\n" 54 : : "The angle tolerance parameter is used to specify the maximum " 55 : : "deviation from a right angle or straight line a node can have " 56 : : "for it to be adjusted. Smaller tolerances mean that only nodes " 57 : : "which are already closer to right angles will be adjusted, and " 58 : : "larger tolerances mean that nodes which deviate further from " 59 : : "right angles will also be adjusted.\n\n" 60 : : "The algorithm is iterative. Setting a larger number for the maximum " 61 : : "iterations will result in a more orthogonal geometry at the cost of " 62 : : "extra processing time." ); 63 : : } 64 : : 65 : 0 : QString QgsOrthogonalizeAlgorithm::outputName() const 66 : : { 67 : 0 : return QObject::tr( "Orthogonalized" ); 68 : : } 69 : : 70 : 0 : QList<int> QgsOrthogonalizeAlgorithm::inputLayerTypes() const 71 : : { 72 : 0 : return QList<int>() << QgsProcessing::TypeVectorPolygon << QgsProcessing::TypeVectorLine; 73 : 0 : } 74 : : 75 : 0 : QgsOrthogonalizeAlgorithm *QgsOrthogonalizeAlgorithm::createInstance() const 76 : : { 77 : 0 : return new QgsOrthogonalizeAlgorithm(); 78 : 0 : } 79 : : 80 : 0 : void QgsOrthogonalizeAlgorithm::initParameters( const QVariantMap & ) 81 : : { 82 : 0 : auto angleToleranceParam = std::make_unique < QgsProcessingParameterNumber >( QStringLiteral( "ANGLE_TOLERANCE" ), QObject::tr( "Maximum angle tolerance (degrees)" ), 83 : 0 : QgsProcessingParameterNumber::Double, 15.0, false, 0.0, 45.0 ); 84 : 0 : angleToleranceParam->setIsDynamic( true ); 85 : 0 : angleToleranceParam->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Angle tolerance" ), QObject::tr( "Maximum angle tolerance (degrees)" ), QgsPropertyDefinition::Double ) ); 86 : 0 : angleToleranceParam->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) ); 87 : 0 : addParameter( angleToleranceParam.release() ); 88 : : 89 : 0 : std::unique_ptr< QgsProcessingParameterNumber> maxIterations = std::make_unique< QgsProcessingParameterNumber >( 90 : 0 : QStringLiteral( "MAX_ITERATIONS" ), 91 : 0 : QObject::tr( "Maximum algorithm iterations" ), 92 : 0 : QgsProcessingParameterNumber::Integer, 93 : 0 : 1000, false, 1, 10000 ); 94 : 0 : maxIterations->setFlags( maxIterations->flags() | QgsProcessingParameterDefinition::FlagAdvanced ); 95 : 0 : addParameter( maxIterations.release() ); 96 : 0 : } 97 : : 98 : 0 : bool QgsOrthogonalizeAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) 99 : : { 100 : 0 : mAngleTolerance = parameterAsDouble( parameters, QStringLiteral( "ANGLE_TOLERANCE" ), context ); 101 : 0 : mDynamicAngleTolerance = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "ANGLE_TOLERANCE" ) ); 102 : 0 : if ( mDynamicAngleTolerance ) 103 : 0 : mAngleToleranceProperty = parameters.value( QStringLiteral( "ANGLE_TOLERANCE" ) ).value< QgsProperty >(); 104 : : 105 : 0 : mMaxIterations = parameterAsDouble( parameters, QStringLiteral( "MAX_ITERATIONS" ), context ); 106 : : 107 : 0 : return true; 108 : 0 : } 109 : : 110 : 0 : QgsFeatureList QgsOrthogonalizeAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * ) 111 : : { 112 : 0 : QgsFeature f = feature; 113 : : 114 : 0 : if ( f.hasGeometry() ) 115 : : { 116 : 0 : double angleTolerance = mAngleTolerance; 117 : 0 : if ( mDynamicAngleTolerance ) 118 : 0 : angleTolerance = mAngleToleranceProperty.valueAsDouble( context.expressionContext(), angleTolerance ); 119 : : 120 : 0 : QgsGeometry outputGeometry = f.geometry().orthogonalize( 1.0e-8, mMaxIterations, angleTolerance ); 121 : 0 : if ( outputGeometry.isNull() ) 122 : 0 : throw QgsProcessingException( QObject::tr( "Error orthogonalizing geometry" ) ); 123 : : 124 : 0 : f.setGeometry( outputGeometry ); 125 : 0 : } 126 : : 127 : 0 : return QgsFeatureList() << f; 128 : 0 : } 129 : : 130 : : ///@endcond