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