Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsalgorithmarrayoffsetlines.cpp
3 : : ---------------------
4 : : begin : July 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 "qgsalgorithmarrayoffsetlines.h"
19 : :
20 : : ///@cond PRIVATE
21 : :
22 : 0 : QString QgsCreateArrayOffsetLinesAlgorithm::name() const
23 : : {
24 : 0 : return QStringLiteral( "arrayoffsetlines" );
25 : : }
26 : :
27 : 0 : QString QgsCreateArrayOffsetLinesAlgorithm::displayName() const
28 : : {
29 : 0 : return QObject::tr( "Array of offset (parallel) lines" );
30 : : }
31 : :
32 : 0 : QStringList QgsCreateArrayOffsetLinesAlgorithm::tags() const
33 : : {
34 : 0 : return QObject::tr( "offset,parallel,duplicate,create,spaced,copy,features,objects,step,repeat" ).split( ',' );
35 : 0 : }
36 : :
37 : 0 : QString QgsCreateArrayOffsetLinesAlgorithm::group() const
38 : : {
39 : 0 : return QObject::tr( "Vector creation" );
40 : : }
41 : :
42 : 0 : QString QgsCreateArrayOffsetLinesAlgorithm::groupId() const
43 : : {
44 : 0 : return QStringLiteral( "vectorcreation" );
45 : : }
46 : :
47 : 0 : QString QgsCreateArrayOffsetLinesAlgorithm::outputName() const
48 : : {
49 : 0 : return QObject::tr( "Offset lines" );
50 : : }
51 : :
52 : 0 : QString QgsCreateArrayOffsetLinesAlgorithm::shortHelpString() const
53 : : {
54 : 0 : return QObject::tr( "This algorithm creates copies of line features in a layer, by creating multiple offset versions of each feature. "
55 : : "Each copy is offset by a preset distance." );
56 : : }
57 : :
58 : 0 : QString QgsCreateArrayOffsetLinesAlgorithm::shortDescription() const
59 : : {
60 : 0 : return QObject::tr( "Creates multiple offset copies of lines from a layer." );
61 : : }
62 : :
63 : 0 : QgsCreateArrayOffsetLinesAlgorithm *QgsCreateArrayOffsetLinesAlgorithm::createInstance() const
64 : : {
65 : 0 : return new QgsCreateArrayOffsetLinesAlgorithm();
66 : 0 : }
67 : :
68 : 0 : void QgsCreateArrayOffsetLinesAlgorithm::initParameters( const QVariantMap & )
69 : : {
70 : 0 : std::unique_ptr< QgsProcessingParameterNumber > count = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "COUNT" ),
71 : 0 : QObject::tr( "Number of features to create" ), QgsProcessingParameterNumber::Integer,
72 : 0 : 10, false, 1 );
73 : 0 : count->setIsDynamic( true );
74 : 0 : count->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "COUNT" ), QObject::tr( "Number of features to create" ), QgsPropertyDefinition::IntegerPositiveGreaterZero ) );
75 : 0 : count->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
76 : 0 : addParameter( count.release() );
77 : :
78 : 0 : std::unique_ptr< QgsProcessingParameterDistance > offset = std::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "OFFSET" ),
79 : 0 : QObject::tr( "Offset step distance" ),
80 : 0 : 1.0, QStringLiteral( "INPUT" ) );
81 : 0 : offset->setIsDynamic( true );
82 : 0 : offset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "OFFSET" ), QObject::tr( "Step distance" ), QgsPropertyDefinition::Double ) );
83 : 0 : offset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
84 : 0 : addParameter( offset.release() );
85 : :
86 : 0 : auto segmentParam = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "SEGMENTS" ), QObject::tr( "Segments" ), QgsProcessingParameterNumber::Integer, 8, false, 1 );
87 : 0 : segmentParam->setFlags( segmentParam->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
88 : 0 : addParameter( segmentParam.release() );
89 : :
90 : 0 : auto joinStyleParam = std::make_unique< QgsProcessingParameterEnum>( QStringLiteral( "JOIN_STYLE" ), QObject::tr( "Join style" ), QStringList() << QObject::tr( "Round" ) << QObject::tr( "Miter" ) << QObject::tr( "Bevel" ), false, 0 );
91 : 0 : joinStyleParam->setFlags( joinStyleParam->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
92 : 0 : addParameter( joinStyleParam.release() );
93 : :
94 : 0 : auto miterLimitParam = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MITER_LIMIT" ), QObject::tr( "Miter limit" ), QgsProcessingParameterNumber::Double, 2, false, 1 );
95 : 0 : miterLimitParam->setFlags( miterLimitParam->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
96 : 0 : addParameter( miterLimitParam.release() );
97 : 0 : }
98 : :
99 : 0 : QList<int> QgsCreateArrayOffsetLinesAlgorithm::inputLayerTypes() const
100 : : {
101 : 0 : return QList< int >() << QgsProcessing::TypeVectorLine;
102 : 0 : }
103 : :
104 : 0 : bool QgsCreateArrayOffsetLinesAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * )
105 : : {
106 : 0 : mCount = parameterAsInt( parameters, QStringLiteral( "COUNT" ), context );
107 : 0 : mDynamicCount = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "COUNT" ) );
108 : 0 : if ( mDynamicCount )
109 : 0 : mCountProperty = parameters.value( QStringLiteral( "COUNT" ) ).value< QgsProperty >();
110 : :
111 : 0 : mOffsetStep = parameterAsDouble( parameters, QStringLiteral( "OFFSET" ), context );
112 : 0 : mDynamicOffset = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "OFFSET" ) );
113 : 0 : if ( mDynamicOffset )
114 : 0 : mOffsetStepProperty = parameters.value( QStringLiteral( "OFFSET" ) ).value< QgsProperty >();
115 : :
116 : 0 : mSegments = parameterAsInt( parameters, QStringLiteral( "SEGMENTS" ), context );
117 : 0 : mJoinStyle = static_cast< QgsGeometry::JoinStyle>( 1 + parameterAsInt( parameters, QStringLiteral( "JOIN_STYLE" ), context ) );
118 : 0 : mMiterLimit = parameterAsDouble( parameters, QStringLiteral( "MITER_LIMIT" ), context );
119 : :
120 : 0 : return true;
121 : 0 : }
122 : :
123 : 0 : QgsFeatureList QgsCreateArrayOffsetLinesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
124 : : {
125 : 0 : QgsFeatureList result = QgsFeatureList();
126 : :
127 : 0 : if ( feature.hasGeometry() )
128 : : {
129 : 0 : const QgsGeometry geometry = feature.geometry();
130 : 0 : const QgsAttributes attr = feature.attributes();
131 : :
132 : 0 : int count = mCount;
133 : 0 : if ( mDynamicCount )
134 : 0 : count = mCountProperty.valueAsInt( context.expressionContext(), count );
135 : 0 : result.reserve( count + 1 );
136 : :
137 : 0 : double offsetStep = mOffsetStep;
138 : 0 : if ( mDynamicOffset )
139 : 0 : offsetStep = mOffsetStepProperty.valueAsDouble( context.expressionContext(), offsetStep );
140 : :
141 : : {
142 : 0 : QgsFeature original = feature;
143 : 0 : original.setGeometry( geometry );
144 : 0 : QgsAttributes outAttrs = attr;
145 : 0 : outAttrs << QVariant( 0 ) << QVariant( 0 );
146 : 0 : original.setAttributes( outAttrs );
147 : 0 : result << original;
148 : 0 : }
149 : :
150 : 0 : double offset = 0;
151 : 0 : for ( int i = 0; i < count; ++i )
152 : : {
153 : 0 : offset += offsetStep;
154 : : // FIXME: shouldn't we use QgsVectorLayerUtils::createFeature?
155 : 0 : QgsFeature offsetFeature = feature;
156 : 0 : const QgsGeometry offsetGeometry = geometry.offsetCurve( offset, mSegments, mJoinStyle, mMiterLimit );
157 : 0 : offsetFeature.setGeometry( offsetGeometry );
158 : 0 : QgsAttributes outAttrs = attr;
159 : 0 : outAttrs << QVariant( i + 1 ) << QVariant( offset );
160 : 0 : offsetFeature.setAttributes( outAttrs );
161 : 0 : result << offsetFeature;
162 : 0 : }
163 : 0 : }
164 : : else
165 : : {
166 : 0 : result << feature;
167 : : }
168 : :
169 : 0 : return result;
170 : 0 : }
171 : :
172 : 0 : QgsFields QgsCreateArrayOffsetLinesAlgorithm::outputFields( const QgsFields &inputFields ) const
173 : : {
174 : 0 : QgsFields output = inputFields;
175 : 0 : output.append( QgsField( QStringLiteral( "instance" ), QVariant::Int ) );
176 : 0 : output.append( QgsField( QStringLiteral( "offset" ), QVariant::Double ) );
177 : 0 : return output;
178 : 0 : }
179 : :
180 : 0 : QgsFeatureSink::SinkFlags QgsCreateArrayOffsetLinesAlgorithm::sinkFlags() const
181 : : {
182 : 0 : return QgsFeatureSink::RegeneratePrimaryKey;
183 : : }
184 : :
185 : : ///@endcond
186 : :
187 : :
|