Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsalgorithmsplitlinesbylength.cpp 3 : : --------------------- 4 : : begin : December 2018 5 : : copyright : (C) 2018 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 "qgsalgorithmsplitlinesbylength.h" 19 : : #include "qgscurve.h" 20 : : #include "qgslinestring.h" 21 : : #include "qgscircularstring.h" 22 : : #include "qgscompoundcurve.h" 23 : : #include "qgsgeometrycollection.h" 24 : : 25 : : ///@cond PRIVATE 26 : : 27 : 0 : QString QgsSplitLinesByLengthAlgorithm::name() const 28 : : { 29 : 0 : return QStringLiteral( "splitlinesbylength" ); 30 : : } 31 : : 32 : 0 : QString QgsSplitLinesByLengthAlgorithm::displayName() const 33 : : { 34 : 0 : return QObject::tr( "Split lines by maximum length" ); 35 : : } 36 : : 37 : 0 : QStringList QgsSplitLinesByLengthAlgorithm::tags() const 38 : : { 39 : 0 : return QObject::tr( "segments,parts,distance,cut,chop" ).split( ',' ); 40 : 0 : } 41 : : 42 : 0 : QString QgsSplitLinesByLengthAlgorithm::group() const 43 : : { 44 : 0 : return QObject::tr( "Vector geometry" ); 45 : : } 46 : : 47 : 0 : QString QgsSplitLinesByLengthAlgorithm::groupId() const 48 : : { 49 : 0 : return QStringLiteral( "vectorgeometry" ); 50 : : } 51 : : 52 : 0 : QString QgsSplitLinesByLengthAlgorithm::shortHelpString() const 53 : : { 54 : 0 : return QObject::tr( "This algorithm takes a line (or curve) layer and splits each feature into multiple parts, " 55 : : "where each part is of a specified maximum length.\n\n" 56 : : "Z and M values at the start and end of the new line substrings are linearly interpolated from existing values." ); 57 : : } 58 : : 59 : 0 : QString QgsSplitLinesByLengthAlgorithm::shortDescription() const 60 : : { 61 : 0 : return QObject::tr( "Splits lines into parts which are no longer than a specified length." ); 62 : : } 63 : : 64 : 0 : QList<int> QgsSplitLinesByLengthAlgorithm::inputLayerTypes() const 65 : : { 66 : 0 : return QList<int>() << QgsProcessing::TypeVectorLine; 67 : 0 : } 68 : : 69 : 0 : QgsProcessing::SourceType QgsSplitLinesByLengthAlgorithm::outputLayerType() const 70 : : { 71 : 0 : return QgsProcessing::TypeVectorLine; 72 : : } 73 : : 74 : 0 : QgsSplitLinesByLengthAlgorithm *QgsSplitLinesByLengthAlgorithm::createInstance() const 75 : : { 76 : 0 : return new QgsSplitLinesByLengthAlgorithm(); 77 : 0 : } 78 : : 79 : 0 : void QgsSplitLinesByLengthAlgorithm::initParameters( const QVariantMap & ) 80 : : { 81 : 0 : std::unique_ptr< QgsProcessingParameterDistance > length = std::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "LENGTH" ), 82 : 0 : QObject::tr( "Maximum line length" ), 10, QStringLiteral( "INPUT" ), false, 0 ); 83 : 0 : length->setIsDynamic( true ); 84 : 0 : length->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "LENGTH" ), QObject::tr( "Maximum length" ), QgsPropertyDefinition::DoublePositive ) ); 85 : 0 : length->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) ); 86 : 0 : addParameter( length.release() ); 87 : 0 : } 88 : : 89 : 0 : bool QgsSplitLinesByLengthAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) 90 : : { 91 : 0 : mLength = parameterAsDouble( parameters, QStringLiteral( "LENGTH" ), context ); 92 : 0 : mDynamicLength = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "LENGTH" ) ); 93 : 0 : if ( mDynamicLength ) 94 : 0 : mLengthProperty = parameters.value( QStringLiteral( "LENGTH" ) ).value< QgsProperty >(); 95 : : 96 : 0 : return true; 97 : 0 : } 98 : : 99 : 0 : QString QgsSplitLinesByLengthAlgorithm::outputName() const 100 : : { 101 : 0 : return QObject::tr( "Split" ); 102 : : } 103 : : 104 : 0 : QgsWkbTypes::Type QgsSplitLinesByLengthAlgorithm::outputWkbType( QgsWkbTypes::Type inputWkbType ) const 105 : : { 106 : 0 : return QgsWkbTypes::singleType( inputWkbType ); 107 : : } 108 : : 109 : 0 : QgsFeatureList QgsSplitLinesByLengthAlgorithm::processFeature( const QgsFeature &f, QgsProcessingContext &context, QgsProcessingFeedback * ) 110 : : { 111 : 0 : if ( !f.hasGeometry() ) 112 : : { 113 : 0 : return QgsFeatureList() << f; 114 : : } 115 : : else 116 : : { 117 : 0 : double distance = mLength; 118 : 0 : if ( mDynamicLength ) 119 : 0 : distance = mLengthProperty.valueAsDouble( context.expressionContext(), distance ); 120 : : 121 : 0 : QgsFeature outputFeature; 122 : 0 : outputFeature.setAttributes( f.attributes() ); 123 : 0 : QgsFeatureList features; 124 : 0 : const QgsGeometry inputGeom = f.geometry(); 125 : 0 : for ( auto it = inputGeom.const_parts_begin(); it != inputGeom.const_parts_end(); ++it ) 126 : : { 127 : 0 : const QgsCurve *part = qgsgeometry_cast< const QgsCurve * >( *it ); 128 : 0 : if ( !part ) 129 : 0 : continue; 130 : : 131 : 0 : double start = 0.0; 132 : 0 : double end = distance; 133 : 0 : const double length = part->length(); 134 : 0 : while ( start < length ) 135 : : { 136 : 0 : outputFeature.setGeometry( QgsGeometry( part->curveSubstring( start, end ) ) ); 137 : 0 : start += distance; 138 : 0 : end += distance; 139 : 0 : features << outputFeature; 140 : : } 141 : : 142 : 0 : } 143 : 0 : return features; 144 : 0 : } 145 : 0 : } 146 : : 147 : 0 : QgsProcessingFeatureSource::Flag QgsSplitLinesByLengthAlgorithm::sourceFlags() const 148 : : { 149 : 0 : return QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks; 150 : : } 151 : : 152 : : 153 : : ///@endcond 154 : : 155 : : 156 : :