QGIS API Documentation 4.3.0-Master (ffcfc20b9b4)
Loading...
Searching...
No Matches
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
20#include "qgsvectorlayer.h"
21
22#include <QString>
23
24using namespace Qt::StringLiterals;
25
27
28QString QgsAddXYFieldsAlgorithm::name() const
29{
30 return u"addxyfields"_s;
31}
32
33QString QgsAddXYFieldsAlgorithm::displayName() const
34{
35 return QObject::tr( "Add X/Y fields to layer" );
36}
37
38QString QgsAddXYFieldsAlgorithm::shortHelpString() const
39{
40 return QObject::tr(
41 "This algorithm 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 "
42 "layer in a project CRS)."
43 );
44}
45
46QString QgsAddXYFieldsAlgorithm::shortDescription() const
47{
48 return QObject::tr( "Adds X and Y (or latitude/longitude) fields to a point layer." );
49}
50
51QStringList QgsAddXYFieldsAlgorithm::tags() const
52{
53 return QObject::tr( "add,create,latitude,longitude,columns,attributes" ).split( ',' );
54}
55
56QString QgsAddXYFieldsAlgorithm::group() const
57{
58 return QObject::tr( "Vector table" );
59}
60
61QString QgsAddXYFieldsAlgorithm::groupId() const
62{
63 return u"vectortable"_s;
64}
65
66QString QgsAddXYFieldsAlgorithm::outputName() const
67{
68 return QObject::tr( "Added fields" );
69}
70
71QList<int> QgsAddXYFieldsAlgorithm::inputLayerTypes() const
72{
73 return QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorPoint );
74}
75
76QgsAddXYFieldsAlgorithm *QgsAddXYFieldsAlgorithm::createInstance() const
77{
78 return new QgsAddXYFieldsAlgorithm();
79}
80
81Qgis::ProcessingFeatureSourceFlags QgsAddXYFieldsAlgorithm::sourceFlags() const
82{
84}
85
86void QgsAddXYFieldsAlgorithm::initParameters( const QVariantMap &configuration )
87{
88 mIsInPlace = configuration.value( u"IN_PLACE"_s ).toBool();
89
90 addParameter( new QgsProcessingParameterCrs( u"CRS"_s, QObject::tr( "Coordinate system" ), u"EPSG:4326"_s ) );
91
92 if ( !mIsInPlace )
93 addParameter( new QgsProcessingParameterString( u"PREFIX"_s, QObject::tr( "Field prefix" ), QVariant(), false, true ) );
94 else
95 {
96 addParameter( new QgsProcessingParameterField( u"FIELD_X"_s, QObject::tr( "X field" ), QVariant(), u"INPUT"_s ) );
97 addParameter( new QgsProcessingParameterField( u"FIELD_Y"_s, QObject::tr( "Y field" ), QVariant(), u"INPUT"_s ) );
98 }
99}
100
101QgsFields QgsAddXYFieldsAlgorithm::outputFields( const QgsFields &inputFields ) const
102{
103 if ( mIsInPlace )
104 {
105 mInPlaceXFieldIndex = inputFields.lookupField( mInPlaceXField );
106 mInPlaceYFieldIndex = inputFields.lookupField( mInPlaceYField );
107 return inputFields;
108 }
109 else
110 {
111 const QString xFieldName = mPrefix + 'x';
112 const QString yFieldName = mPrefix + 'y';
113
114 QgsFields newFields;
115 newFields.append( QgsField( xFieldName, QMetaType::Type::Double, QString(), 20, 10 ) );
116 newFields.append( QgsField( yFieldName, QMetaType::Type::Double, QString(), 20, 10 ) );
117 return QgsProcessingUtils::combineFields( inputFields, newFields );
118 }
119}
120
121QgsCoordinateReferenceSystem QgsAddXYFieldsAlgorithm::outputCrs( const QgsCoordinateReferenceSystem &inputCrs ) const
122{
123 mSourceCrs = inputCrs;
124 return inputCrs;
125}
126
127bool QgsAddXYFieldsAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
128{
129 if ( !mIsInPlace )
130 mPrefix = parameterAsString( parameters, u"PREFIX"_s, context );
131 else
132 {
133 mInPlaceXField = parameterAsString( parameters, u"FIELD_X"_s, context );
134 mInPlaceYField = parameterAsString( parameters, u"FIELD_Y"_s, context );
135 }
136
137 mCrs = parameterAsCrs( parameters, u"CRS"_s, context );
138 return true;
139}
140
141QgsFeatureList QgsAddXYFieldsAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
142{
143 QGS_MARK_ALGORITHM_SOURCE
144
145 if ( mTransformNeedsInitialization )
146 {
147 mTransform = QgsCoordinateTransform( mSourceCrs, mCrs, context.transformContext() );
148 mTransformNeedsInitialization = false;
149 }
150 if ( mIsInPlace && mInPlaceXFieldIndex == -1 )
151 {
152 throw QgsProcessingException( QObject::tr( "Destination field not found" ) );
153 }
154
155 QVariant x;
156 QVariant y;
157 if ( feature.hasGeometry() )
158 {
159 if ( feature.geometry().isMultipart() )
160 throw QgsProcessingException( QObject::tr( "Multipoint features are not supported - please convert to single point features first." ) );
161
162 const QgsPointXY point = feature.geometry().asPoint();
163 try
164 {
165 const QgsPointXY transformed = mTransform.transform( point );
166 x = transformed.x();
167 y = transformed.y();
168 }
169 catch ( QgsCsException & )
170 {
171 feedback->reportError( QObject::tr( "Could not transform point to destination CRS" ) );
172 }
173 }
174 QgsFeature f = feature;
175 QgsAttributes attributes = f.attributes();
176 if ( !mIsInPlace )
177 {
178 attributes << x << y;
179 }
180 else
181 {
182 attributes[mInPlaceXFieldIndex] = std::move( x );
183 attributes[mInPlaceYFieldIndex] = std::move( y );
184 }
185 f.setAttributes( attributes );
186 return QgsFeatureList() << f;
187}
188
189bool QgsAddXYFieldsAlgorithm::supportInPlaceEdit( const QgsMapLayer *layer ) const
190{
191 if ( const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( layer ) )
192 {
193 return vl->geometryType() == Qgis::GeometryType::Point;
194 }
195 return false;
196}
197
@ VectorPoint
Vector point layers.
Definition qgis.h:3750
@ Point
Points.
Definition qgis.h:380
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition qgis.h:3930
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition qgis.h:3941
A vector of attributes.
Represents a coordinate reference system (CRS).
Handles coordinate transforms between two coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
QgsAttributes attributes
Definition qgsfeature.h:64
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
QgsGeometry geometry
Definition qgsfeature.h:66
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:56
Container of fields for a vector layer.
Definition qgsfields.h:45
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Definition qgsfields.cpp:75
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
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:83
Represents a 2D point.
Definition qgspointxy.h:62
double y
Definition qgspointxy.h:66
double x
Definition qgspointxy.h:65
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.
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.
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB, const QString &fieldsBPrefix=QString())
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).
Represents a vector layer which manages a vector based dataset.
QList< QgsFeature > QgsFeatureList