QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
qgsalgorithmpointslayerfromtable.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmpointslayerfromtable.cpp
3  ---------------------
4  begin : November 2019
5  copyright : (C) 2019 by Alexander Bruy
6  email : alexander dot bruy 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 QgsPointsLayerFromTableAlgorithm::name() const
23 {
24  return QStringLiteral( "createpointslayerfromtable" );
25 }
26 
27 QString QgsPointsLayerFromTableAlgorithm::displayName() const
28 {
29  return QObject::tr( "Create points layer from table" );
30 }
31 
32 QStringList QgsPointsLayerFromTableAlgorithm::tags() const
33 {
34  return QObject::tr( "points,create,values,attributes" ).split( ',' );
35 }
36 
37 QString QgsPointsLayerFromTableAlgorithm::group() const
38 {
39  return QObject::tr( "Vector creation" );
40 }
41 
42 QString QgsPointsLayerFromTableAlgorithm::groupId() const
43 {
44  return QStringLiteral( "vectorcreation" );
45 }
46 
47 QString QgsPointsLayerFromTableAlgorithm::shortHelpString() const
48 {
49  return QObject::tr( "This algorithm generates a points layer based on the values from an input table." )
50  + QStringLiteral( "\n\n" )
51  + QObject::tr( "The table must contain a field with the X coordinate of each point and another "
52  "one with the Y coordinate, as well as optional fields with Z and M values. A CRS "
53  "for the output layer has to be specified, and the coordinates in the table are "
54  "assumed to be expressed in the units used by that CRS. The attributes table of "
55  "the resulting layer will be the input table." );
56 }
57 
58 QgsPointsLayerFromTableAlgorithm *QgsPointsLayerFromTableAlgorithm::createInstance() const
59 {
60  return new QgsPointsLayerFromTableAlgorithm();
61 }
62 
63 void QgsPointsLayerFromTableAlgorithm::initAlgorithm( const QVariantMap & )
64 {
65  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ),
66  QList< int >() << QgsProcessing::TypeVector ) );
67  addParameter( new QgsProcessingParameterField( QStringLiteral( "XFIELD" ), QObject::tr( "X field" ), QVariant(),
68  QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any ) );
69  addParameter( new QgsProcessingParameterField( QStringLiteral( "YFIELD" ), QObject::tr( "Y field" ), QVariant(),
70  QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any ) );
71  addParameter( new QgsProcessingParameterField( QStringLiteral( "ZFIELD" ), QObject::tr( "Z field" ), QVariant(),
72  QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, false, true ) );
73  addParameter( new QgsProcessingParameterField( QStringLiteral( "MFIELD" ), QObject::tr( "M field" ), QVariant(),
74  QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, false, true ) );
75  addParameter( new QgsProcessingParameterCrs( QStringLiteral( "TARGET_CRS" ), QObject::tr( "Target CRS" ), QStringLiteral( "EPSG:4326" ) ) );
76 
77  addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Points from table" ), QgsProcessing::TypeVectorPoint ) );
78 }
79 
80 QVariantMap QgsPointsLayerFromTableAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
81 {
82  std::unique_ptr< QgsProcessingFeatureSource > featureSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
83  if ( !featureSource )
84  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
85 
86  const QgsFields fields = featureSource->fields();
87  const int xFieldIndex = fields.lookupField( parameterAsString( parameters, QStringLiteral( "XFIELD" ), context ) );
88  const int yFieldIndex = fields.lookupField( parameterAsString( parameters, QStringLiteral( "YFIELD" ), context ) );
89 
90  QString fieldName = parameterAsString( parameters, QStringLiteral( "ZFIELD" ), context );
91  int zFieldIndex = -1;
92  if ( !fieldName.isEmpty() )
93  zFieldIndex = fields.lookupField( fieldName );
94 
95  fieldName = parameterAsString( parameters, QStringLiteral( "MFIELD" ), context );
96  int mFieldIndex = -1;
97  if ( !fieldName.isEmpty() )
98  mFieldIndex = fields.lookupField( fieldName );
99 
100  QgsWkbTypes::Type outputWkbType = QgsWkbTypes::Point;
101  if ( zFieldIndex >= 0 )
102  outputWkbType = QgsWkbTypes::addZ( outputWkbType );
103  if ( mFieldIndex >= 0 )
104  outputWkbType = QgsWkbTypes::addM( outputWkbType );
105 
106  const QgsCoordinateReferenceSystem crs = parameterAsCrs( parameters, QStringLiteral( "TARGET_CRS" ), context );
107 
108  QString dest;
109  std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, outputWkbType, crs, QgsFeatureSink::RegeneratePrimaryKey ) );
110  if ( !sink )
111  throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
112 
113  const double step = featureSource->featureCount() > 0 ? 100.0 / featureSource->featureCount() : 1;
114 
115  QgsFeatureRequest req;
118  QgsFeature f;
119  int current = 0;
120 
121  while ( fi.nextFeature( f ) )
122  {
123  if ( feedback->isCanceled() )
124  {
125  break;
126  }
127 
128  const QgsAttributes attrs = f.attributes();
129 
130  bool xOk = false;
131  bool yOk = false;
132  const double x = attrs.at( xFieldIndex ).toDouble( &xOk );
133  const double y = attrs.at( yFieldIndex ).toDouble( &yOk );
134 
135  if ( ! attrs.at( xFieldIndex ).isNull() && ! attrs.at( yFieldIndex ).isNull() && xOk && yOk )
136  {
137  QgsPoint point( x, y );
138 
139  if ( zFieldIndex >= 0 && ! attrs.at( zFieldIndex ).isNull() )
140  point.addZValue( attrs.at( zFieldIndex ).toDouble() );
141 
142  if ( mFieldIndex >= 0 && ! attrs.at( mFieldIndex ).isNull() )
143  point.addMValue( attrs.at( mFieldIndex ).toDouble() );
144 
145  f.setGeometry( QgsGeometry( point.clone() ) );
146  }
147 
148  if ( !sink->addFeature( f ) )
149  throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
150  feedback->setProgress( current * step );
151  current++;
152  }
153 
154  QVariantMap outputs;
155  outputs.insert( QStringLiteral( "OUTPUT" ), dest );
156  return outputs;
157 }
158 
A vector of attributes.
Definition: qgsattributes.h:58
This class represents a coordinate reference system (CRS).
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
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 setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:163
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
Container of fields for a vector layer.
Definition: qgsfields.h:45
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:344
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
@ FlagSkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Base class for providing feedback from a processing algorithm.
A coordinate reference system parameter for processing algorithms.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A vector layer or feature source field parameter for processing algorithms.
@ TypeVector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:54
@ TypeVectorPoint
Vector point layers.
Definition: qgsprocessing.h:49
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
static Type addZ(Type type) SIP_HOLDGIL
Adds the z dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1176
static Type addM(Type type) SIP_HOLDGIL
Adds the m dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1201
const QgsCoordinateReferenceSystem & crs