Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsalgorithmcentroid.cpp 3 : : ------------------------ 4 : : begin : April 2017 5 : : copyright : (C) 2017 by Nyall Dawson 6 : : email : nyall dot dawson 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 "qgsalgorithmcentroid.h" 19 : : #include "qgsgeometrycollection.h" 20 : : 21 : : ///@cond PRIVATE 22 : : 23 : 0 : QString QgsCentroidAlgorithm::name() const 24 : : { 25 : 0 : return QStringLiteral( "centroids" ); 26 : : } 27 : : 28 : 0 : QString QgsCentroidAlgorithm::displayName() const 29 : : { 30 : 0 : return QObject::tr( "Centroids" ); 31 : : } 32 : : 33 : 0 : QStringList QgsCentroidAlgorithm::tags() const 34 : : { 35 : 0 : return QObject::tr( "centroid,center,average,point,middle" ).split( ',' ); 36 : 0 : } 37 : : 38 : 0 : QString QgsCentroidAlgorithm::group() const 39 : : { 40 : 0 : return QObject::tr( "Vector geometry" ); 41 : : } 42 : : 43 : 0 : QString QgsCentroidAlgorithm::groupId() const 44 : : { 45 : 0 : return QStringLiteral( "vectorgeometry" ); 46 : : } 47 : : 48 : 0 : QString QgsCentroidAlgorithm::outputName() const 49 : : { 50 : 0 : return QObject::tr( "Centroids" ); 51 : : } 52 : : 53 : 0 : QgsFeatureSink::SinkFlags QgsCentroidAlgorithm::sinkFlags() const 54 : : { 55 : 0 : if ( mAllParts ) 56 : 0 : return QgsProcessingFeatureBasedAlgorithm::sinkFlags() | QgsFeatureSink::RegeneratePrimaryKey; 57 : : else 58 : 0 : return QgsProcessingFeatureBasedAlgorithm::sinkFlags(); 59 : 0 : } 60 : : 61 : 0 : QString QgsCentroidAlgorithm::shortHelpString() const 62 : : { 63 : 0 : return QObject::tr( "This algorithm creates a new point layer, with points representing the centroid of the geometries in an input layer.\n\n" 64 : : "The attributes associated to each point in the output layer are the same ones associated to the original features." ); 65 : : } 66 : : 67 : 0 : QgsCentroidAlgorithm *QgsCentroidAlgorithm::createInstance() const 68 : : { 69 : 0 : return new QgsCentroidAlgorithm(); 70 : 0 : } 71 : : 72 : 0 : void QgsCentroidAlgorithm::initParameters( const QVariantMap & ) 73 : : { 74 : 0 : std::unique_ptr< QgsProcessingParameterBoolean> allParts = std::make_unique< QgsProcessingParameterBoolean >( 75 : 0 : QStringLiteral( "ALL_PARTS" ), 76 : 0 : QObject::tr( "Create centroid for each part" ), 77 : 0 : false ); 78 : 0 : allParts->setIsDynamic( true ); 79 : 0 : allParts->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "All parts" ), QObject::tr( "Create centroid for each part" ), QgsPropertyDefinition::Boolean ) ); 80 : 0 : allParts->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) ); 81 : 0 : addParameter( allParts.release() ); 82 : 0 : } 83 : : 84 : 0 : bool QgsCentroidAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) 85 : : { 86 : 0 : mAllParts = parameterAsBoolean( parameters, QStringLiteral( "ALL_PARTS" ), context ); 87 : 0 : mDynamicAllParts = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "ALL_PARTS" ) ); 88 : 0 : if ( mDynamicAllParts ) 89 : 0 : mAllPartsProperty = parameters.value( QStringLiteral( "ALL_PARTS" ) ).value< QgsProperty >(); 90 : : 91 : 0 : return true; 92 : 0 : } 93 : : 94 : 0 : QgsFeatureList QgsCentroidAlgorithm::processFeature( const QgsFeature &f, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) 95 : : { 96 : 0 : QgsFeatureList list; 97 : 0 : QgsFeature feature = f; 98 : 0 : if ( feature.hasGeometry() && !feature.geometry().isEmpty() ) 99 : : { 100 : 0 : QgsGeometry geom = feature.geometry(); 101 : : 102 : 0 : bool allParts = mAllParts; 103 : 0 : if ( mDynamicAllParts ) 104 : 0 : allParts = mAllPartsProperty.valueAsBool( context.expressionContext(), allParts ); 105 : : 106 : 0 : if ( allParts && geom.isMultipart() ) 107 : : { 108 : 0 : const QgsGeometryCollection *geomCollection = static_cast<const QgsGeometryCollection *>( geom.constGet() ); 109 : : 110 : 0 : const int partCount = geomCollection->partCount(); 111 : 0 : list.reserve( partCount ); 112 : 0 : for ( int i = 0; i < partCount; ++i ) 113 : : { 114 : 0 : QgsGeometry partGeometry( geomCollection->geometryN( i )->clone() ); 115 : 0 : QgsGeometry outputGeometry = partGeometry.centroid(); 116 : 0 : if ( outputGeometry.isNull() ) 117 : : { 118 : 0 : feedback->reportError( QObject::tr( "Error calculating centroid for feature %1 part %2: %3" ).arg( feature.id() ).arg( i ).arg( outputGeometry.lastError() ) ); 119 : 0 : } 120 : 0 : feature.setGeometry( outputGeometry ); 121 : 0 : list << feature; 122 : 0 : } 123 : 0 : } 124 : : else 125 : : { 126 : 0 : QgsGeometry outputGeometry = feature.geometry().centroid(); 127 : 0 : if ( outputGeometry.isNull() ) 128 : : { 129 : 0 : feedback->reportError( QObject::tr( "Error calculating centroid for feature %1: %2" ).arg( feature.id() ).arg( outputGeometry.lastError() ) ); 130 : 0 : } 131 : 0 : feature.setGeometry( outputGeometry ); 132 : 0 : list << feature; 133 : 0 : } 134 : 0 : } 135 : : else 136 : : { 137 : 0 : list << feature; 138 : : } 139 : 0 : return list; 140 : 0 : } 141 : : 142 : : ///@endcond