QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsalgorithmsnaptogrid.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmsnaptogrid.cpp
3  --------------------------
4  begin : October 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 "qgsalgorithmsnaptogrid.h"
19 
21 
22 QString QgsSnapToGridAlgorithm::name() const
23 {
24  return QStringLiteral( "snappointstogrid" );
25 }
26 
27 QString QgsSnapToGridAlgorithm::displayName() const
28 {
29  return QObject::tr( "Snap points to grid" );
30 }
31 
32 QStringList QgsSnapToGridAlgorithm::tags() const
33 {
34  return QObject::tr( "snapped,grid,simplify,round,precision" ).split( ',' );
35 }
36 
37 QString QgsSnapToGridAlgorithm::group() const
38 {
39  return QObject::tr( "Vector geometry" );
40 }
41 
42 QString QgsSnapToGridAlgorithm::groupId() const
43 {
44  return QStringLiteral( "vectorgeometry" );
45 }
46 
47 QString QgsSnapToGridAlgorithm::outputName() const
48 {
49  return QObject::tr( "Snapped" );
50 }
51 
52 QString QgsSnapToGridAlgorithm::shortHelpString() const
53 {
54  return QObject::tr( "This algorithm modifies the coordinates of geometries in a vector layer, so that all points "
55  "or vertices are snapped to the closest point of the grid.\n\n"
56  "If the snapped geometry cannot be calculated (or is totally collapsed) the feature's "
57  "geometry will be cleared.\n\n"
58  "Note that snapping to grid may generate an invalid geometry in some corner cases.\n\n"
59  "Snapping can be performed on the X, Y, Z or M axis. A grid spacing of 0 for any axis will "
60  "disable snapping for that axis." );
61 }
62 
63 QgsSnapToGridAlgorithm *QgsSnapToGridAlgorithm::createInstance() const
64 {
65  return new QgsSnapToGridAlgorithm();
66 }
67 
68 void QgsSnapToGridAlgorithm::initParameters( const QVariantMap & )
69 {
70  std::unique_ptr< QgsProcessingParameterDistance> hSpacing = qgis::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "HSPACING" ),
71  QObject::tr( "X Grid Spacing" ), 1, QStringLiteral( "INPUT" ), false, 0 );
72  hSpacing->setIsDynamic( true );
73  hSpacing->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "HSPACING" ), QObject::tr( "X Grid Spacing" ), QgsPropertyDefinition::DoublePositive ) );
74  hSpacing->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
75  addParameter( hSpacing.release() );
76 
77  std::unique_ptr< QgsProcessingParameterDistance> vSpacing = qgis::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "VSPACING" ),
78  QObject::tr( "Y Grid Spacing" ), 1, QStringLiteral( "INPUT" ), false, 0 );
79  vSpacing->setIsDynamic( true );
80  vSpacing->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "VSPACING" ), QObject::tr( "Y Grid Spacing" ), QgsPropertyDefinition::DoublePositive ) );
81  vSpacing->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
82  addParameter( vSpacing.release() );
83 
84  std::unique_ptr< QgsProcessingParameterNumber > zSpacing = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "ZSPACING" ),
85  QObject::tr( "Z Grid Spacing" ), QgsProcessingParameterNumber::Double,
86  0, false, 0 );
87  zSpacing->setIsDynamic( true );
88  zSpacing->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "ZSPACING" ), QObject::tr( "Z Grid Spacing" ), QgsPropertyDefinition::DoublePositive ) );
89  zSpacing->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
90  addParameter( zSpacing.release() );
91 
92  std::unique_ptr< QgsProcessingParameterNumber > mSpacing = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MSPACING" ),
93  QObject::tr( "M Grid Spacing" ), QgsProcessingParameterNumber::Double,
94  0, false, 0 );
95  mSpacing->setIsDynamic( true );
96  mSpacing->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "MSPACING" ), QObject::tr( "M Grid Spacing" ), QgsPropertyDefinition::DoublePositive ) );
97  mSpacing->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
98  addParameter( mSpacing.release() );
99 }
100 
101 bool QgsSnapToGridAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
102 {
103  mIntervalX = parameterAsDouble( parameters, QStringLiteral( "HSPACING" ), context );
104  mDynamicIntervalX = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "HSPACING" ) );
105  if ( mDynamicIntervalX )
106  mIntervalXProperty = parameters.value( QStringLiteral( "HSPACING" ) ).value< QgsProperty >();
107 
108  mIntervalY = parameterAsDouble( parameters, QStringLiteral( "VSPACING" ), context );
109  mDynamicIntervalY = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "VSPACING" ) );
110  if ( mDynamicIntervalY )
111  mIntervalYProperty = parameters.value( QStringLiteral( "VSPACING" ) ).value< QgsProperty >();
112 
113  mIntervalZ = parameterAsDouble( parameters, QStringLiteral( "ZSPACING" ), context );
114  mDynamicIntervalZ = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "ZSPACING" ) );
115  if ( mDynamicIntervalZ )
116  mIntervalZProperty = parameters.value( QStringLiteral( "ZSPACING" ) ).value< QgsProperty >();
117 
118  mIntervalM = parameterAsDouble( parameters, QStringLiteral( "MSPACING" ), context );
119  mDynamicIntervalM = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "MSPACING" ) );
120  if ( mDynamicIntervalM )
121  mIntervalMProperty = parameters.value( QStringLiteral( "MSPACING" ) ).value< QgsProperty >();
122 
123  return true;
124 }
125 
126 QgsFeatureList QgsSnapToGridAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
127 {
128  QgsFeature f = feature;
129  if ( f.hasGeometry() )
130  {
131  double intervalX = mIntervalX;
132  if ( mDynamicIntervalX )
133  intervalX = mIntervalXProperty.valueAsDouble( context.expressionContext(), intervalX );
134 
135  double intervalY = mIntervalY;
136  if ( mDynamicIntervalY )
137  intervalY = mIntervalYProperty.valueAsDouble( context.expressionContext(), intervalY );
138 
139  double intervalZ = mIntervalZ;
140  if ( mDynamicIntervalZ )
141  intervalZ = mIntervalZProperty.valueAsDouble( context.expressionContext(), intervalZ );
142 
143  double intervalM = mIntervalM;
144  if ( mDynamicIntervalM )
145  intervalM = mIntervalMProperty.valueAsDouble( context.expressionContext(), intervalM );
146 
147  QgsGeometry outputGeometry = f.geometry().snappedToGrid( intervalX, intervalY, intervalZ, intervalM );
148  if ( outputGeometry.isNull() )
149  {
150  feedback->reportError( QObject::tr( "Error snapping geometry %1" ).arg( feature.id() ) );
151  }
152  f.setGeometry( outputGeometry );
153  }
154  return QgsFeatureList() << f;
155 }
156 
157 QgsProcessingFeatureSource::Flag QgsSnapToGridAlgorithm::sourceFlags() const
158 {
160 }
161 
163 
164 
QgsFeatureId id
Definition: qgsfeature.h:64
Base class for providing feedback from a processing algorithm.
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:571
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:106
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
Positive double value (including 0)
Definition: qgsproperty.h:58
QgsGeometry snappedToGrid(double hSpacing, double vSpacing, double dSpacing=0, double mSpacing=0) const
Returns a new geometry with all points or vertices snapped to the closest point of the grid...
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.
A store for object properties.
Definition: qgsproperty.h:229
QgsExpressionContext & expressionContext()
Returns the expression context.
Definition for a property.
Definition: qgsproperty.h:46
Flag
Flags controlling how QgsProcessingFeatureSource fetches features.
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
QgsGeometry geometry
Definition: qgsfeature.h:67
Contains information about the context in which a processing algorithm is executed.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
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...