Branch data Line data Source code
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 : :
18 : : #include "qgsalgorithmpointslayerfromtable.h"
19 : :
20 : : ///@cond PRIVATE
21 : :
22 : 0 : QString QgsPointsLayerFromTableAlgorithm::name() const
23 : : {
24 : 0 : return QStringLiteral( "createpointslayerfromtable" );
25 : : }
26 : :
27 : 0 : QString QgsPointsLayerFromTableAlgorithm::displayName() const
28 : : {
29 : 0 : return QObject::tr( "Create points layer from table" );
30 : : }
31 : :
32 : 0 : QStringList QgsPointsLayerFromTableAlgorithm::tags() const
33 : : {
34 : 0 : return QObject::tr( "points,create,values,attributes" ).split( ',' );
35 : 0 : }
36 : :
37 : 0 : QString QgsPointsLayerFromTableAlgorithm::group() const
38 : : {
39 : 0 : return QObject::tr( "Vector creation" );
40 : : }
41 : :
42 : 0 : QString QgsPointsLayerFromTableAlgorithm::groupId() const
43 : : {
44 : 0 : return QStringLiteral( "vectorcreation" );
45 : : }
46 : :
47 : 0 : QString QgsPointsLayerFromTableAlgorithm::shortHelpString() const
48 : : {
49 : 0 : return QObject::tr( "This algorithm generates a points layer based on the values from an input table." )
50 : 0 : + QStringLiteral( "\n\n" )
51 : 0 : + 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 : 0 : }
57 : :
58 : 0 : QgsPointsLayerFromTableAlgorithm *QgsPointsLayerFromTableAlgorithm::createInstance() const
59 : : {
60 : 0 : return new QgsPointsLayerFromTableAlgorithm();
61 : : }
62 : :
63 : 0 : void QgsPointsLayerFromTableAlgorithm::initAlgorithm( const QVariantMap & )
64 : : {
65 : 0 : addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ),
66 : 0 : QList< int >() << QgsProcessing::TypeVector ) );
67 : 0 : addParameter( new QgsProcessingParameterField( QStringLiteral( "XFIELD" ), QObject::tr( "X field" ), QVariant(),
68 : 0 : QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any ) );
69 : 0 : addParameter( new QgsProcessingParameterField( QStringLiteral( "YFIELD" ), QObject::tr( "Y field" ), QVariant(),
70 : 0 : QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any ) );
71 : 0 : addParameter( new QgsProcessingParameterField( QStringLiteral( "ZFIELD" ), QObject::tr( "Z field" ), QVariant(),
72 : 0 : QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, false, true ) );
73 : 0 : addParameter( new QgsProcessingParameterField( QStringLiteral( "MFIELD" ), QObject::tr( "M field" ), QVariant(),
74 : 0 : QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, false, true ) );
75 : 0 : addParameter( new QgsProcessingParameterCrs( QStringLiteral( "TARGET_CRS" ), QObject::tr( "Target CRS" ), QStringLiteral( "EPSG:4326" ) ) );
76 : :
77 : 0 : addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Points from table" ), QgsProcessing::TypeVectorPoint ) );
78 : 0 : }
79 : :
80 : 0 : QVariantMap QgsPointsLayerFromTableAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
81 : : {
82 : 0 : std::unique_ptr< QgsProcessingFeatureSource > featureSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
83 : 0 : if ( !featureSource )
84 : 0 : throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
85 : :
86 : 0 : QgsFields fields = featureSource->fields();
87 : 0 : int xFieldIndex = fields.lookupField( parameterAsString( parameters, QStringLiteral( "XFIELD" ), context ) );
88 : 0 : int yFieldIndex = fields.lookupField( parameterAsString( parameters, QStringLiteral( "YFIELD" ), context ) );
89 : :
90 : 0 : QString fieldName = parameterAsString( parameters, QStringLiteral( "ZFIELD" ), context );
91 : 0 : int zFieldIndex = -1;
92 : 0 : if ( !fieldName.isEmpty() )
93 : 0 : zFieldIndex = fields.lookupField( fieldName );
94 : :
95 : 0 : fieldName = parameterAsString( parameters, QStringLiteral( "MFIELD" ), context );
96 : 0 : int mFieldIndex = -1;
97 : 0 : if ( !fieldName.isEmpty() )
98 : 0 : mFieldIndex = fields.lookupField( fieldName );
99 : :
100 : 0 : QgsWkbTypes::Type outputWkbType = QgsWkbTypes::Point;
101 : 0 : if ( zFieldIndex >= 0 )
102 : 0 : outputWkbType = QgsWkbTypes::addZ( outputWkbType );
103 : 0 : if ( mFieldIndex >= 0 )
104 : 0 : outputWkbType = QgsWkbTypes::addM( outputWkbType );
105 : :
106 : 0 : QgsCoordinateReferenceSystem crs = parameterAsCrs( parameters, QStringLiteral( "TARGET_CRS" ), context );
107 : :
108 : 0 : QString dest;
109 : 0 : std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, outputWkbType, crs, QgsFeatureSink::RegeneratePrimaryKey ) );
110 : 0 : if ( !sink )
111 : 0 : throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
112 : :
113 : 0 : double step = featureSource->featureCount() > 0 ? 100.0 / featureSource->featureCount() : 1;
114 : :
115 : 0 : QgsFeatureRequest req;
116 : 0 : req.setFlags( QgsFeatureRequest::NoGeometry );
117 : 0 : QgsFeatureIterator fi = featureSource->getFeatures( req, QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks );
118 : 0 : QgsFeature f;
119 : 0 : int current = 0;
120 : :
121 : 0 : while ( fi.nextFeature( f ) )
122 : : {
123 : 0 : if ( feedback->isCanceled() )
124 : : {
125 : 0 : break;
126 : : }
127 : :
128 : 0 : QgsAttributes attrs = f.attributes();
129 : :
130 : 0 : bool xOk = false;
131 : 0 : bool yOk = false;
132 : 0 : double x = attrs.at( xFieldIndex ).toDouble( &xOk );
133 : 0 : double y = attrs.at( yFieldIndex ).toDouble( &yOk );
134 : :
135 : 0 : if ( ! attrs.at( xFieldIndex ).isNull() && ! attrs.at( yFieldIndex ).isNull() && xOk && yOk )
136 : : {
137 : 0 : QgsPoint point( x, y );
138 : :
139 : 0 : if ( zFieldIndex >= 0 && ! attrs.at( zFieldIndex ).isNull() )
140 : 0 : point.addZValue( attrs.at( zFieldIndex ).toDouble() );
141 : :
142 : 0 : if ( mFieldIndex >= 0 && ! attrs.at( mFieldIndex ).isNull() )
143 : 0 : point.addMValue( attrs.at( mFieldIndex ).toDouble() );
144 : :
145 : 0 : f.setGeometry( QgsGeometry( point.clone() ) );
146 : 0 : }
147 : :
148 : 0 : sink->addFeature( f );
149 : 0 : feedback->setProgress( current * step );
150 : 0 : current++;
151 : 0 : }
152 : :
153 : 0 : QVariantMap outputs;
154 : 0 : outputs.insert( QStringLiteral( "OUTPUT" ), dest );
155 : 0 : return outputs;
156 : 0 : }
157 : :
158 : : ///@endcond
|