QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsalgorithmarraytranslatedfeatures.cpp
Go to the documentation of this file.
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 
19 
21 
22 QString QgsArrayTranslatedFeaturesAlgorithm::name() const
23 {
24  return QStringLiteral( "arraytranslatedfeatures" );
25 }
26 
27 QString QgsArrayTranslatedFeaturesAlgorithm::displayName() const
28 {
29  return QObject::tr( "Array of translated features" );
30 }
31 
32 QStringList QgsArrayTranslatedFeaturesAlgorithm::tags() const
33 {
34  return QObject::tr( "translate,parallel,offset,duplicate,grid,spaced,moved,copy,features,objects,step,repeat" ).split( ',' );
35 }
36 
37 QString QgsArrayTranslatedFeaturesAlgorithm::group() const
38 {
39  return QObject::tr( "Vector creation" );
40 }
41 
42 QString QgsArrayTranslatedFeaturesAlgorithm::groupId() const
43 {
44  return QStringLiteral( "vectorcreation" );
45 }
46 
47 QString QgsArrayTranslatedFeaturesAlgorithm::outputName() const
48 {
49  return QObject::tr( "Translated" );
50 }
51 
52 QString QgsArrayTranslatedFeaturesAlgorithm::shortHelpString() const
53 {
54  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 QString QgsArrayTranslatedFeaturesAlgorithm::shortDescription() const
59 {
60  return QObject::tr( "Creates multiple translated copies of features in a layer." );
61 }
62 
63 QgsArrayTranslatedFeaturesAlgorithm *QgsArrayTranslatedFeaturesAlgorithm::createInstance() const
64 {
65  return new QgsArrayTranslatedFeaturesAlgorithm();
66 }
67 
68 void QgsArrayTranslatedFeaturesAlgorithm::initParameters( const QVariantMap & )
69 {
70  std::unique_ptr< QgsProcessingParameterNumber > count = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "COUNT" ),
71  QObject::tr( "Number of features to create" ), QgsProcessingParameterNumber::Integer,
72  10, false, 1 );
73  count->setIsDynamic( true );
74  count->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "COUNT" ), QObject::tr( "Number of features to create" ), QgsPropertyDefinition::IntegerPositiveGreaterZero ) );
75  count->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
76  addParameter( count.release() );
77 
78  std::unique_ptr< QgsProcessingParameterDistance > xOffset = qgis::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "DELTA_X" ),
79  QObject::tr( "Step distance (x-axis)" ),
80  0.0, QStringLiteral( "INPUT" ) );
81  xOffset->setIsDynamic( true );
82  xOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_X" ), QObject::tr( "Offset distance (x-axis)" ), QgsPropertyDefinition::Double ) );
83  xOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
84  addParameter( xOffset.release() );
85 
86  std::unique_ptr< QgsProcessingParameterDistance > yOffset = qgis::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "DELTA_Y" ),
87  QObject::tr( "Step distance (y-axis)" ),
88  0.0, QStringLiteral( "INPUT" ) );
89  yOffset->setIsDynamic( true );
90  yOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_Y" ), QObject::tr( "Offset distance (y-axis)" ), QgsPropertyDefinition::Double ) );
91  yOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
92  addParameter( yOffset.release() );
93 
94  std::unique_ptr< QgsProcessingParameterNumber > zOffset = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "DELTA_Z" ),
95  QObject::tr( "Step distance (z-axis)" ), QgsProcessingParameterNumber::Double,
96  0.0 );
97  zOffset->setIsDynamic( true );
98  zOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_Z" ), QObject::tr( "Offset distance (z-axis)" ), QgsPropertyDefinition::Double ) );
99  zOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
100  addParameter( zOffset.release() );
101 
102  std::unique_ptr< QgsProcessingParameterNumber > mOffset = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "DELTA_M" ),
103  QObject::tr( "Step distance (m values)" ), QgsProcessingParameterNumber::Double,
104  0.0 );
105  mOffset->setIsDynamic( true );
106  mOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_M" ), QObject::tr( "Offset distance (m values)" ), QgsPropertyDefinition::Double ) );
107  mOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
108  addParameter( mOffset.release() );
109 }
110 
111 bool QgsArrayTranslatedFeaturesAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
112 {
113  mCount = parameterAsInt( parameters, QStringLiteral( "COUNT" ), context );
114  mDynamicCount = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "COUNT" ) );
115  if ( mDynamicCount )
116  mCountProperty = parameters.value( QStringLiteral( "COUNT" ) ).value< QgsProperty >();
117 
118  mDeltaX = parameterAsDouble( parameters, QStringLiteral( "DELTA_X" ), context );
119  mDynamicDeltaX = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_X" ) );
120  if ( mDynamicDeltaX )
121  mDeltaXProperty = parameters.value( QStringLiteral( "DELTA_X" ) ).value< QgsProperty >();
122 
123  mDeltaY = parameterAsDouble( parameters, QStringLiteral( "DELTA_Y" ), context );
124  mDynamicDeltaY = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_Y" ) );
125  if ( mDynamicDeltaY )
126  mDeltaYProperty = parameters.value( QStringLiteral( "DELTA_Y" ) ).value< QgsProperty >();
127 
128  mDeltaZ = parameterAsDouble( parameters, QStringLiteral( "DELTA_Z" ), context );
129  mDynamicDeltaZ = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_Z" ) );
130  if ( mDynamicDeltaZ )
131  mDeltaZProperty = parameters.value( QStringLiteral( "DELTA_Z" ) ).value< QgsProperty >();
132 
133  mDeltaM = parameterAsDouble( parameters, QStringLiteral( "DELTA_M" ), context );
134  mDynamicDeltaM = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_M" ) );
135  if ( mDynamicDeltaM )
136  mDeltaMProperty = parameters.value( QStringLiteral( "DELTA_M" ) ).value< QgsProperty >();
137 
138  return true;
139 }
140 
141 QgsFeatureList QgsArrayTranslatedFeaturesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
142 {
143  QgsFeatureList result = QgsFeatureList();
144 
145  if ( feature.hasGeometry() )
146  {
147  QgsGeometry geometry = feature.geometry();
148  const QgsAttributes attr = feature.attributes();
149 
150  int count = mCount;
151  if ( mDynamicCount )
152  count = mCountProperty.valueAsInt( context.expressionContext(), count );
153  result.reserve( count + 1 );
154 
155  double deltaX = mDeltaX;
156  if ( mDynamicDeltaX )
157  deltaX = mDeltaXProperty.valueAsDouble( context.expressionContext(), deltaX );
158  double deltaY = mDeltaY;
159  if ( mDynamicDeltaY )
160  deltaY = mDeltaYProperty.valueAsDouble( context.expressionContext(), deltaY );
161  double deltaZ = mDeltaZ;
162  if ( mDynamicDeltaZ )
163  deltaZ = mDeltaZProperty.valueAsDouble( context.expressionContext(), deltaZ );
164  double deltaM = mDeltaM;
165  if ( mDynamicDeltaM )
166  deltaM = mDeltaMProperty.valueAsDouble( context.expressionContext(), deltaM );
167 
168  // we add the original feature only after adding initial z/m values if needed
169  if ( deltaZ != 0 && !geometry.constGet()->is3D() )
170  geometry.get()->addZValue( 0 );
171  if ( deltaM != 0 && !geometry.constGet()->isMeasure() )
172  geometry.get()->addMValue( 0 );
173 
174  {
175  QgsFeature original = feature;
176  original.setGeometry( geometry );
177  QgsAttributes outAttrs = attr;
178  outAttrs << QVariant( 0 );
179  original.setAttributes( outAttrs );
180  result << original;
181  }
182 
183  for ( int i = 0; i < count; ++i )
184  {
185  QgsFeature offsetFeature = feature;
186  geometry.translate( deltaX, deltaY, deltaZ, deltaM );
187  offsetFeature.setGeometry( geometry );
188  QgsAttributes outAttrs = attr;
189  outAttrs << QVariant( i + 1 );
190  offsetFeature.setAttributes( outAttrs );
191  result << offsetFeature;
192  }
193  }
194  else
195  {
196  result << feature;
197  }
198 
199  return result;
200 }
201 
202 QgsWkbTypes::Type QgsArrayTranslatedFeaturesAlgorithm::outputWkbType( QgsWkbTypes::Type inputWkbType ) const
203 {
204  QgsWkbTypes::Type wkb = inputWkbType;
205  if ( mDeltaZ != 0 )
206  wkb = QgsWkbTypes::addZ( wkb );
207  if ( mDeltaM != 0 )
208  wkb = QgsWkbTypes::addM( wkb );
209  return wkb;
210 }
211 
212 QgsFields QgsArrayTranslatedFeaturesAlgorithm::outputFields( const QgsFields &inputFields ) const
213 {
214  QgsFields output = inputFields;
215  output.append( QgsField( QStringLiteral( "instance" ), QVariant::Int ) );
216  return output;
217 }
218 
219 QgsFeatureSink::SinkFlags QgsArrayTranslatedFeaturesAlgorithm::sinkFlags() const
220 {
222 }
223 
225 
226 
QgsProcessingParameterNumber::Double
@ Double
Double/float values.
Definition: qgsprocessingparameters.h:1846
QgsProperty
A store for object properties.
Definition: qgsproperty.h:231
qgsalgorithmarraytranslatedfeatures.h
QgsAbstractGeometry::addZValue
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
QgsProcessingParameters::isDynamic
static bool isDynamic(const QVariantMap &parameters, const QString &name)
Returns true if the parameter with matching name is a dynamic parameter, and must be evaluated once f...
Definition: qgsprocessingparameters.cpp:111
QgsProcessingFeedback
Definition: qgsprocessingfeedback.h:37
QgsAbstractGeometry::addMValue
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
QgsFields
Definition: qgsfields.h:44
QgsPropertyDefinition::IntegerPositiveGreaterZero
@ IntegerPositiveGreaterZero
Non-zero positive integer values.
Definition: qgsproperty.h:57
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsPropertyDefinition::Double
@ Double
Double value (including negative values)
Definition: qgsproperty.h:58
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsFields::append
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
QgsWkbTypes::addM
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1163
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:137
QgsProcessingContext
Definition: qgsprocessingcontext.h:43
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:572
QgsPropertyDefinition
Definition for a property.
Definition: qgsproperty.h:47
QgsAbstractGeometry::is3D
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
Definition: qgsabstractgeometry.h:202
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsFeatureSink::RegeneratePrimaryKey
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
Definition: qgsfeaturesink.h:55
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:69
QgsProcessingParameterNumber::Integer
@ Integer
Integer values.
Definition: qgsprocessingparameters.h:1845
QgsWkbTypes::addZ
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1138
QgsGeometry::get
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:133
QgsGeometry
Definition: qgsgeometry.h:122
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
QgsProcessingContext::expressionContext
QgsExpressionContext & expressionContext()
Returns the expression context.
Definition: qgsprocessingcontext.h:119
QgsGeometry::translate
OperationResult translate(double dx, double dy, double dz=0.0, double dm=0.0)
Translates this geometry by dx, dy, dz and dm.
Definition: qgsgeometry.cpp:790
QgsProperty::valueAsDouble
double valueAsDouble(const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property and interprets it as a double.
Definition: qgsproperty.cpp:620
QgsAbstractGeometry::isMeasure
bool isMeasure() const
Returns true if the geometry contains m values.
Definition: qgsabstractgeometry.h:211
QgsAttributes
Definition: qgsattributes.h:57
QgsFeature
Definition: qgsfeature.h:55
QgsFeature::setAttributes
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:127
QgsField
Definition: qgsfield.h:49