Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsalgorithmarraytranslatedfeatures.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 "qgsalgorithmarraytranslatedfeatures.h"
19 : :
20 : : ///@cond PRIVATE
21 : :
22 : 0 : QString QgsArrayTranslatedFeaturesAlgorithm::name() const
23 : : {
24 : 0 : return QStringLiteral( "arraytranslatedfeatures" );
25 : : }
26 : :
27 : 0 : QString QgsArrayTranslatedFeaturesAlgorithm::displayName() const
28 : : {
29 : 0 : return QObject::tr( "Array of translated features" );
30 : : }
31 : :
32 : 0 : QStringList QgsArrayTranslatedFeaturesAlgorithm::tags() const
33 : : {
34 : 0 : return QObject::tr( "translate,parallel,offset,duplicate,grid,spaced,moved,copy,features,objects,step,repeat" ).split( ',' );
35 : 0 : }
36 : :
37 : 0 : QString QgsArrayTranslatedFeaturesAlgorithm::group() const
38 : : {
39 : 0 : return QObject::tr( "Vector creation" );
40 : : }
41 : :
42 : 0 : QString QgsArrayTranslatedFeaturesAlgorithm::groupId() const
43 : : {
44 : 0 : return QStringLiteral( "vectorcreation" );
45 : : }
46 : :
47 : 0 : QString QgsArrayTranslatedFeaturesAlgorithm::outputName() const
48 : : {
49 : 0 : return QObject::tr( "Translated" );
50 : : }
51 : :
52 : 0 : QString QgsArrayTranslatedFeaturesAlgorithm::shortHelpString() const
53 : : {
54 : 0 : return QObject::tr( "This algorithm creates copies of features in a layer, by creating multiple translated versions of each feature. "
55 : : "Each copy is incrementally displaced by a preset amount in the x/y/z/m axis." );
56 : : }
57 : :
58 : 0 : QString QgsArrayTranslatedFeaturesAlgorithm::shortDescription() const
59 : : {
60 : 0 : return QObject::tr( "Creates multiple translated copies of features in a layer." );
61 : : }
62 : :
63 : 0 : QgsArrayTranslatedFeaturesAlgorithm *QgsArrayTranslatedFeaturesAlgorithm::createInstance() const
64 : : {
65 : 0 : return new QgsArrayTranslatedFeaturesAlgorithm();
66 : 0 : }
67 : :
68 : 0 : void QgsArrayTranslatedFeaturesAlgorithm::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 > xOffset = std::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "DELTA_X" ),
79 : 0 : QObject::tr( "Step distance (x-axis)" ),
80 : 0 : 0.0, QStringLiteral( "INPUT" ) );
81 : 0 : xOffset->setIsDynamic( true );
82 : 0 : xOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_X" ), QObject::tr( "Offset distance (x-axis)" ), QgsPropertyDefinition::Double ) );
83 : 0 : xOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
84 : 0 : addParameter( xOffset.release() );
85 : :
86 : 0 : std::unique_ptr< QgsProcessingParameterDistance > yOffset = std::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "DELTA_Y" ),
87 : 0 : QObject::tr( "Step distance (y-axis)" ),
88 : 0 : 0.0, QStringLiteral( "INPUT" ) );
89 : 0 : yOffset->setIsDynamic( true );
90 : 0 : yOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_Y" ), QObject::tr( "Offset distance (y-axis)" ), QgsPropertyDefinition::Double ) );
91 : 0 : yOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
92 : 0 : addParameter( yOffset.release() );
93 : :
94 : 0 : std::unique_ptr< QgsProcessingParameterNumber > zOffset = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "DELTA_Z" ),
95 : 0 : QObject::tr( "Step distance (z-axis)" ), QgsProcessingParameterNumber::Double,
96 : 0 : 0.0 );
97 : 0 : zOffset->setIsDynamic( true );
98 : 0 : zOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_Z" ), QObject::tr( "Offset distance (z-axis)" ), QgsPropertyDefinition::Double ) );
99 : 0 : zOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
100 : 0 : addParameter( zOffset.release() );
101 : :
102 : 0 : std::unique_ptr< QgsProcessingParameterNumber > mOffset = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "DELTA_M" ),
103 : 0 : QObject::tr( "Step distance (m values)" ), QgsProcessingParameterNumber::Double,
104 : 0 : 0.0 );
105 : 0 : mOffset->setIsDynamic( true );
106 : 0 : mOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_M" ), QObject::tr( "Offset distance (m values)" ), QgsPropertyDefinition::Double ) );
107 : 0 : mOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
108 : 0 : addParameter( mOffset.release() );
109 : 0 : }
110 : :
111 : 0 : bool QgsArrayTranslatedFeaturesAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * )
112 : : {
113 : 0 : mCount = parameterAsInt( parameters, QStringLiteral( "COUNT" ), context );
114 : 0 : mDynamicCount = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "COUNT" ) );
115 : 0 : if ( mDynamicCount )
116 : 0 : mCountProperty = parameters.value( QStringLiteral( "COUNT" ) ).value< QgsProperty >();
117 : :
118 : 0 : mDeltaX = parameterAsDouble( parameters, QStringLiteral( "DELTA_X" ), context );
119 : 0 : mDynamicDeltaX = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_X" ) );
120 : 0 : if ( mDynamicDeltaX )
121 : 0 : mDeltaXProperty = parameters.value( QStringLiteral( "DELTA_X" ) ).value< QgsProperty >();
122 : :
123 : 0 : mDeltaY = parameterAsDouble( parameters, QStringLiteral( "DELTA_Y" ), context );
124 : 0 : mDynamicDeltaY = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_Y" ) );
125 : 0 : if ( mDynamicDeltaY )
126 : 0 : mDeltaYProperty = parameters.value( QStringLiteral( "DELTA_Y" ) ).value< QgsProperty >();
127 : :
128 : 0 : mDeltaZ = parameterAsDouble( parameters, QStringLiteral( "DELTA_Z" ), context );
129 : 0 : mDynamicDeltaZ = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_Z" ) );
130 : 0 : if ( mDynamicDeltaZ )
131 : 0 : mDeltaZProperty = parameters.value( QStringLiteral( "DELTA_Z" ) ).value< QgsProperty >();
132 : :
133 : 0 : mDeltaM = parameterAsDouble( parameters, QStringLiteral( "DELTA_M" ), context );
134 : 0 : mDynamicDeltaM = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_M" ) );
135 : 0 : if ( mDynamicDeltaM )
136 : 0 : mDeltaMProperty = parameters.value( QStringLiteral( "DELTA_M" ) ).value< QgsProperty >();
137 : :
138 : 0 : return true;
139 : 0 : }
140 : :
141 : 0 : QgsFeatureList QgsArrayTranslatedFeaturesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
142 : : {
143 : 0 : QgsFeatureList result = QgsFeatureList();
144 : :
145 : 0 : if ( feature.hasGeometry() )
146 : : {
147 : 0 : QgsGeometry geometry = feature.geometry();
148 : 0 : const QgsAttributes attr = feature.attributes();
149 : :
150 : 0 : int count = mCount;
151 : 0 : if ( mDynamicCount )
152 : 0 : count = mCountProperty.valueAsInt( context.expressionContext(), count );
153 : 0 : result.reserve( count + 1 );
154 : :
155 : 0 : double deltaX = mDeltaX;
156 : 0 : if ( mDynamicDeltaX )
157 : 0 : deltaX = mDeltaXProperty.valueAsDouble( context.expressionContext(), deltaX );
158 : 0 : double deltaY = mDeltaY;
159 : 0 : if ( mDynamicDeltaY )
160 : 0 : deltaY = mDeltaYProperty.valueAsDouble( context.expressionContext(), deltaY );
161 : 0 : double deltaZ = mDeltaZ;
162 : 0 : if ( mDynamicDeltaZ )
163 : 0 : deltaZ = mDeltaZProperty.valueAsDouble( context.expressionContext(), deltaZ );
164 : 0 : double deltaM = mDeltaM;
165 : 0 : if ( mDynamicDeltaM )
166 : 0 : deltaM = mDeltaMProperty.valueAsDouble( context.expressionContext(), deltaM );
167 : :
168 : : // we add the original feature only after adding initial z/m values if needed
169 : 0 : if ( deltaZ != 0 && !geometry.constGet()->is3D() )
170 : 0 : geometry.get()->addZValue( 0 );
171 : 0 : if ( deltaM != 0 && !geometry.constGet()->isMeasure() )
172 : 0 : geometry.get()->addMValue( 0 );
173 : :
174 : : {
175 : 0 : QgsFeature original = feature;
176 : 0 : original.setGeometry( geometry );
177 : 0 : QgsAttributes outAttrs = attr;
178 : 0 : outAttrs << QVariant( 0 );
179 : 0 : original.setAttributes( outAttrs );
180 : 0 : result << original;
181 : 0 : }
182 : :
183 : 0 : for ( int i = 0; i < count; ++i )
184 : : {
185 : 0 : QgsFeature offsetFeature = feature;
186 : 0 : geometry.translate( deltaX, deltaY, deltaZ, deltaM );
187 : 0 : offsetFeature.setGeometry( geometry );
188 : 0 : QgsAttributes outAttrs = attr;
189 : 0 : outAttrs << QVariant( i + 1 );
190 : 0 : offsetFeature.setAttributes( outAttrs );
191 : 0 : result << offsetFeature;
192 : 0 : }
193 : 0 : }
194 : : else
195 : : {
196 : 0 : result << feature;
197 : : }
198 : :
199 : 0 : return result;
200 : 0 : }
201 : :
202 : 0 : QgsWkbTypes::Type QgsArrayTranslatedFeaturesAlgorithm::outputWkbType( QgsWkbTypes::Type inputWkbType ) const
203 : : {
204 : 0 : QgsWkbTypes::Type wkb = inputWkbType;
205 : 0 : if ( mDeltaZ != 0 )
206 : 0 : wkb = QgsWkbTypes::addZ( wkb );
207 : 0 : if ( mDeltaM != 0 )
208 : 0 : wkb = QgsWkbTypes::addM( wkb );
209 : 0 : return wkb;
210 : : }
211 : :
212 : 0 : QgsFields QgsArrayTranslatedFeaturesAlgorithm::outputFields( const QgsFields &inputFields ) const
213 : : {
214 : 0 : QgsFields output = inputFields;
215 : 0 : output.append( QgsField( QStringLiteral( "instance" ), QVariant::Int ) );
216 : 0 : return output;
217 : 0 : }
218 : :
219 : 0 : QgsFeatureSink::SinkFlags QgsArrayTranslatedFeaturesAlgorithm::sinkFlags() const
220 : : {
221 : 0 : return QgsFeatureSink::RegeneratePrimaryKey;
222 : : }
223 : :
224 : : ///@endcond
225 : :
226 : :
|