Skip to content

Commit 5324d7f

Browse files
alexbruynyalldawson
authored andcommittedNov 25, 2019
[processing] port points layer from table to C++
1 parent 9289d53 commit 5324d7f

File tree

8 files changed

+216
-157
lines changed

8 files changed

+216
-157
lines changed
 

‎python/plugins/processing/algs/help/qgis.yaml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,6 @@ qgis:pointsalonglines: >
297297
qgis:pointsdisplacement: >
298298
Offsets nearby point features by moving nearby points by a preset amount to minimize overlapping features.
299299

300-
qgis:pointslayerfromtable: >
301-
This algorithm generates a points layer based on the values from an input table.
302-
303-
The table must contain a field with the X coordinate of each point and another one with the Y coordinate. A CRS for the output layer has to be specified, and the coordinates in the table are assumed to be expressed in the units used by that CRS.
304-
305-
The attributes table of the resulting layer will be the input table.
306-
307300
qgis:pointstopath: >
308301
Converts a point layer to a line layer, by joining points in a defined order.
309302

‎python/plugins/processing/algs/qgis/PointsLayerFromTable.py

Lines changed: 0 additions & 147 deletions
This file was deleted.

‎python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@
7070
from .PointsFromLines import PointsFromLines
7171
from .PointsFromPolygons import PointsFromPolygons
7272
from .PointsInPolygon import PointsInPolygon
73-
from .PointsLayerFromTable import PointsLayerFromTable
7473
from .PointsToPaths import PointsToPaths
7574
from .PolarPlot import PolarPlot
7675
from .PoleOfInaccessibility import PoleOfInaccessibility
@@ -172,7 +171,6 @@ def getAlgs(self):
172171
PointsFromLines(),
173172
PointsFromPolygons(),
174173
PointsInPolygon(),
175-
PointsLayerFromTable(),
176174
PointsToPaths(),
177175
PolarPlot(),
178176
PoleOfInaccessibility(),

‎python/plugins/processing/tests/testdata/qgis_algorithm_tests2.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ tests:
670670
name: expected/delete_column.gml
671671
type: vector
672672

673-
- algorithm: qgis:createpointslayerfromtable
673+
- algorithm: native:createpointslayerfromtable
674674
name: Create points from table
675675
params:
676676
INPUT:

‎src/analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ SET(QGIS_ANALYSIS_SRCS
9090
processing/qgsalgorithmpointonsurface.cpp
9191
processing/qgsalgorithmpointtolayer.cpp
9292
processing/qgsalgorithmpointsalonggeometry.cpp
93+
processing/qgsalgorithmpointslayerfromtable.cpp
9394
processing/qgsalgorithmprojectpointcartesian.cpp
9495
processing/qgsalgorithmpromotetomultipart.cpp
9596
processing/qgsalgorithmrasterlayeruniquevalues.cpp
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
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+
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. A CRS for the output layer has to be specified, and "
53+
"the coordinates in the table are assumed to be expressed in the units used by "
54+
"that CRS. The attributes table of the resulting layer will be the input table." );
55+
}
56+
57+
QgsPointsLayerFromTableAlgorithm *QgsPointsLayerFromTableAlgorithm::createInstance() const
58+
{
59+
return new QgsPointsLayerFromTableAlgorithm();
60+
}
61+
62+
void QgsPointsLayerFromTableAlgorithm::initAlgorithm( const QVariantMap & )
63+
{
64+
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ),
65+
QList< int >() << QgsProcessing::TypeVector ) );
66+
addParameter( new QgsProcessingParameterField( QStringLiteral( "XFIELD" ), QObject::tr( "X field" ), QVariant(),
67+
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any ) );
68+
addParameter( new QgsProcessingParameterField( QStringLiteral( "YFIELD" ), QObject::tr( "Y field" ), QVariant(),
69+
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any ) );
70+
addParameter( new QgsProcessingParameterField( QStringLiteral( "ZFIELD" ), QObject::tr( "Z field" ), QVariant(),
71+
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, false, true ) );
72+
addParameter( new QgsProcessingParameterField( QStringLiteral( "MFIELD" ), QObject::tr( "M field" ), QVariant(),
73+
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, false, true ) );
74+
addParameter( new QgsProcessingParameterCrs( QStringLiteral( "TARGET_CRS" ), QObject::tr( "Target CRS" ), QStringLiteral( "EPSG:4326" ) ) );
75+
76+
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Points from table" ), QgsProcessing::TypeVectorPoint ) );
77+
}
78+
79+
QVariantMap QgsPointsLayerFromTableAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
80+
{
81+
std::unique_ptr< QgsProcessingFeatureSource > featureSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
82+
if ( !featureSource )
83+
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
84+
85+
QgsFields fields = featureSource->fields();
86+
int xFieldIndex = fields.lookupField( parameterAsString( parameters, QStringLiteral( "XFIELD" ), context ) );
87+
int yFieldIndex = fields.lookupField( parameterAsString( parameters, QStringLiteral( "YFIELD" ), context ) );
88+
89+
QString fieldName = parameterAsString( parameters, QStringLiteral( "ZFIELD" ), context );
90+
int zFieldIndex = -1;
91+
if ( !fieldName.isEmpty() )
92+
zFieldIndex = fields.lookupField( fieldName );
93+
94+
fieldName = parameterAsString( parameters, QStringLiteral( "MFIELD" ), context );
95+
int mFieldIndex = -1;
96+
if ( !fieldName.isEmpty() )
97+
mFieldIndex = fields.lookupField( fieldName );
98+
99+
QgsWkbTypes::Type outputWkbType = QgsWkbTypes::Point;
100+
if ( zFieldIndex >= 0 )
101+
outputWkbType = QgsWkbTypes::addZ( outputWkbType );
102+
if ( mFieldIndex >= 0 )
103+
outputWkbType = QgsWkbTypes::addM( outputWkbType );
104+
105+
QgsCoordinateReferenceSystem crs = parameterAsCrs( parameters, QStringLiteral( "TARGET_CRS" ), context );
106+
107+
QString dest;
108+
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, outputWkbType, crs, QgsFeatureSink::RegeneratePrimaryKey ) );
109+
if ( !sink )
110+
throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
111+
112+
double step = featureSource->featureCount() > 0 ? 100.0 / featureSource->featureCount() : 1;
113+
114+
QgsFeatureRequest req;
115+
req.setFlags( QgsFeatureRequest::NoGeometry );
116+
QgsFeatureIterator fi = featureSource->getFeatures( req, QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks );
117+
QgsFeature f;
118+
int current = 0;
119+
120+
while ( fi.nextFeature( f ) )
121+
{
122+
if ( feedback->isCanceled() )
123+
{
124+
break;
125+
}
126+
127+
QgsAttributes attrs = f.attributes();
128+
129+
bool xOk = false;
130+
bool yOk = false;
131+
double x = attrs.at( xFieldIndex ).toDouble( &xOk );
132+
double y = attrs.at( yFieldIndex ).toDouble( &yOk );
133+
134+
if ( xOk && yOk )
135+
{
136+
QgsPoint point( x, y );
137+
138+
if ( zFieldIndex >= 0 )
139+
point.addZValue( attrs.at( zFieldIndex ).toDouble() );
140+
141+
if ( mFieldIndex >= 0 )
142+
point.addMValue( attrs.at( mFieldIndex ).toDouble() );
143+
144+
f.setGeometry( QgsGeometry( point.clone() ) );
145+
}
146+
147+
sink->addFeature( f );
148+
feedback->setProgress( current * step );
149+
current++;
150+
}
151+
152+
QVariantMap outputs;
153+
outputs.insert( QStringLiteral( "OUTPUT" ), dest );
154+
return outputs;
155+
}
156+
157+
///@endcond

0 commit comments

Comments
 (0)
Please sign in to comment.