QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsalgorithmaddxyfields.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmaddixyfields.cpp
3 -----------------------------------
4 begin : March 2019
5 copyright : (C) 2019 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#include "qgsvectorlayer.h"
20
22
23QString QgsAddXYFieldsAlgorithm::name() const
24{
25 return QStringLiteral( "addxyfields" );
26}
27
28QString QgsAddXYFieldsAlgorithm::displayName() const
29{
30 return QObject::tr( "Add X/Y fields to layer" );
31}
32
33QString QgsAddXYFieldsAlgorithm::shortHelpString() const
34{
35 return QObject::tr( "Adds X and Y (or latitude/longitude) fields to a point layer. The X/Y fields can be calculated in a different CRS to the layer (e.g. creating latitude/longitude fields for a layer in a project CRS)." );
36}
37
38QString QgsAddXYFieldsAlgorithm::shortDescription() const
39{
40 return QObject::tr( "Adds X and Y (or latitude/longitude) fields to a point layer." );
41}
42
43QStringList QgsAddXYFieldsAlgorithm::tags() const
44{
45 return QObject::tr( "add,create,latitude,longitude,columns,attributes" ).split( ',' );
46}
47
48QString QgsAddXYFieldsAlgorithm::group() const
49{
50 return QObject::tr( "Vector table" );
51}
52
53QString QgsAddXYFieldsAlgorithm::groupId() const
54{
55 return QStringLiteral( "vectortable" );
56}
57
58QString QgsAddXYFieldsAlgorithm::outputName() const
59{
60 return QObject::tr( "Added fields" );
61}
62
63QList<int> QgsAddXYFieldsAlgorithm::inputLayerTypes() const
64{
65 return QList<int>() << static_cast< int >( Qgis::ProcessingSourceType::VectorPoint );
66}
67
68QgsAddXYFieldsAlgorithm *QgsAddXYFieldsAlgorithm::createInstance() const
69{
70 return new QgsAddXYFieldsAlgorithm();
71}
72
73Qgis::ProcessingFeatureSourceFlags QgsAddXYFieldsAlgorithm::sourceFlags() const
74{
76}
77
78void QgsAddXYFieldsAlgorithm::initParameters( const QVariantMap &configuration )
79{
80 mIsInPlace = configuration.value( QStringLiteral( "IN_PLACE" ) ).toBool();
81
82 addParameter( new QgsProcessingParameterCrs( QStringLiteral( "CRS" ), QObject::tr( "Coordinate system" ), QStringLiteral( "EPSG:4326" ) ) );
83
84 if ( !mIsInPlace )
85 addParameter( new QgsProcessingParameterString( QStringLiteral( "PREFIX" ), QObject::tr( "Field prefix" ), QVariant(), false, true ) );
86 else
87 {
88 addParameter( new QgsProcessingParameterField( QStringLiteral( "FIELD_X" ), QObject::tr( "X field" ), QVariant(), QStringLiteral( "INPUT" ) ) );
89 addParameter( new QgsProcessingParameterField( QStringLiteral( "FIELD_Y" ), QObject::tr( "Y field" ), QVariant(), QStringLiteral( "INPUT" ) ) );
90 }
91}
92
93QgsFields QgsAddXYFieldsAlgorithm::outputFields( const QgsFields &inputFields ) const
94{
95 if ( mIsInPlace )
96 {
97 mInPlaceXFieldIndex = inputFields.lookupField( mInPlaceXField );
98 mInPlaceYFieldIndex = inputFields.lookupField( mInPlaceYField );
99 return inputFields;
100 }
101 else
102 {
103 const QString xFieldName = mPrefix + 'x';
104 const QString yFieldName = mPrefix + 'y';
105
106 QgsFields outFields = inputFields;
107 outFields.append( QgsField( xFieldName, QVariant::Double, QString(), 20, 10 ) );
108 outFields.append( QgsField( yFieldName, QVariant::Double, QString(), 20, 10 ) );
109 return outFields;
110 }
111}
112
114{
115 mSourceCrs = inputCrs;
116 return inputCrs;
117}
118
119bool QgsAddXYFieldsAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
120{
121 if ( !mIsInPlace )
122 mPrefix = parameterAsString( parameters, QStringLiteral( "PREFIX" ), context );
123 else
124 {
125 mInPlaceXField = parameterAsString( parameters, QStringLiteral( "FIELD_X" ), context );
126 mInPlaceYField = parameterAsString( parameters, QStringLiteral( "FIELD_Y" ), context );
127 }
128
129 mCrs = parameterAsCrs( parameters, QStringLiteral( "CRS" ), context );
130 return true;
131}
132
133QgsFeatureList QgsAddXYFieldsAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
134{
135 if ( mTransformNeedsInitialization )
136 {
137 mTransform = QgsCoordinateTransform( mSourceCrs, mCrs, context.transformContext() );
138 mTransformNeedsInitialization = false;
139 }
140 if ( mIsInPlace && mInPlaceXFieldIndex == -1 )
141 {
142 throw QgsProcessingException( QObject::tr( "Destination field not found" ) );
143 }
144
145 QVariant x;
146 QVariant y;
147 if ( feature.hasGeometry() )
148 {
149 if ( feature.geometry().isMultipart() )
150 throw QgsProcessingException( QObject::tr( "Multipoint features are not supported - please convert to single point features first." ) );
151
152 const QgsPointXY point = feature.geometry().asPoint();
153 try
154 {
155 const QgsPointXY transformed = mTransform.transform( point );
156 x = transformed.x();
157 y = transformed.y();
158 }
159 catch ( QgsCsException & )
160 {
161 feedback->reportError( QObject::tr( "Could not transform point to destination CRS" ) );
162 }
163 }
164 QgsFeature f = feature;
165 QgsAttributes attributes = f.attributes();
166 if ( !mIsInPlace )
167 {
168 attributes << x << y;
169 }
170 else
171 {
172 attributes[mInPlaceXFieldIndex] = x;
173 attributes[mInPlaceYFieldIndex] = y;
174 }
175 f.setAttributes( attributes );
176 return QgsFeatureList() << f;
177}
178
179bool QgsAddXYFieldsAlgorithm::supportInPlaceEdit( const QgsMapLayer *layer ) const
180{
181 if ( const QgsVectorLayer *vl = qobject_cast< const QgsVectorLayer * >( layer ) )
182 {
183 return vl->geometryType() == Qgis::GeometryType::Point;
184 }
185 return false;
186}
187
@ VectorPoint
Vector point layers.
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition: qgis.h:3011
A vector of attributes.
Definition: qgsattributes.h:59
This class represents a coordinate reference system (CRS).
Class for doing transforms between two map coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:67
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsAttributes attributes
Definition: qgsfeature.h:65
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:160
QgsGeometry geometry
Definition: qgsfeature.h:67
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:230
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:53
Container of fields for a vector layer.
Definition: qgsfields.h:45
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
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:359
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
Base class for all map layer types.
Definition: qgsmaplayer.h:75
A class to represent a 2D point.
Definition: qgspointxy.h:60
double y
Definition: qgspointxy.h:64
Q_GADGET double x
Definition: qgspointxy.h:63
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
Base class for providing feedback from a processing algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A coordinate reference system parameter for processing algorithms.
A vector layer or feature source field parameter for processing algorithms.
A string parameter for processing algorithms.
Represents a vector layer which manages a vector based data sets.
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:917
const QgsCoordinateReferenceSystem & outputCrs