Skip to content

Commit

Permalink
[processing] port points layer from table to C++
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbruy authored and nyalldawson committed Nov 25, 2019
1 parent 9289d53 commit 5324d7f
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 157 deletions.
7 changes: 0 additions & 7 deletions python/plugins/processing/algs/help/qgis.yaml
Expand Up @@ -297,13 +297,6 @@ qgis:pointsalonglines: >
qgis:pointsdisplacement: >
Offsets nearby point features by moving nearby points by a preset amount to minimize overlapping features.

qgis:pointslayerfromtable: >
This algorithm generates a points layer based on the values from an input table.

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.

The attributes table of the resulting layer will be the input table.

qgis:pointstopath: >
Converts a point layer to a line layer, by joining points in a defined order.

Expand Down
147 changes: 0 additions & 147 deletions python/plugins/processing/algs/qgis/PointsLayerFromTable.py

This file was deleted.

2 changes: 0 additions & 2 deletions python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py
Expand Up @@ -70,7 +70,6 @@
from .PointsFromLines import PointsFromLines
from .PointsFromPolygons import PointsFromPolygons
from .PointsInPolygon import PointsInPolygon
from .PointsLayerFromTable import PointsLayerFromTable
from .PointsToPaths import PointsToPaths
from .PolarPlot import PolarPlot
from .PoleOfInaccessibility import PoleOfInaccessibility
Expand Down Expand Up @@ -172,7 +171,6 @@ def getAlgs(self):
PointsFromLines(),
PointsFromPolygons(),
PointsInPolygon(),
PointsLayerFromTable(),
PointsToPaths(),
PolarPlot(),
PoleOfInaccessibility(),
Expand Down
Expand Up @@ -670,7 +670,7 @@ tests:
name: expected/delete_column.gml
type: vector

- algorithm: qgis:createpointslayerfromtable
- algorithm: native:createpointslayerfromtable
name: Create points from table
params:
INPUT:
Expand Down
1 change: 1 addition & 0 deletions src/analysis/CMakeLists.txt
Expand Up @@ -90,6 +90,7 @@ SET(QGIS_ANALYSIS_SRCS
processing/qgsalgorithmpointonsurface.cpp
processing/qgsalgorithmpointtolayer.cpp
processing/qgsalgorithmpointsalonggeometry.cpp
processing/qgsalgorithmpointslayerfromtable.cpp
processing/qgsalgorithmprojectpointcartesian.cpp
processing/qgsalgorithmpromotetomultipart.cpp
processing/qgsalgorithmrasterlayeruniquevalues.cpp
Expand Down
157 changes: 157 additions & 0 deletions src/analysis/processing/qgsalgorithmpointslayerfromtable.cpp
@@ -0,0 +1,157 @@
/***************************************************************************
qgsalgorithmpointslayerfromtable.cpp
---------------------
begin : November 2019
copyright : (C) 2019 by Alexander Bruy
email : alexander dot bruy at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsalgorithmpointslayerfromtable.h"

///@cond PRIVATE

QString QgsPointsLayerFromTableAlgorithm::name() const
{
return QStringLiteral( "createpointslayerfromtable" );
}

QString QgsPointsLayerFromTableAlgorithm::displayName() const
{
return QObject::tr( "Create points layer from table" );
}

QStringList QgsPointsLayerFromTableAlgorithm::tags() const
{
return QObject::tr( "points,create,values,attributes" ).split( ',' );
}

QString QgsPointsLayerFromTableAlgorithm::group() const
{
return QObject::tr( "Vector creation" );
}

QString QgsPointsLayerFromTableAlgorithm::groupId() const
{
return QStringLiteral( "vectorcreation" );
}

QString QgsPointsLayerFromTableAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm generates a points layer based on the values from an input table." )
+ QStringLiteral( "\n\n" )
+ QObject::tr( "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. The attributes table of the resulting layer will be the input table." );
}

QgsPointsLayerFromTableAlgorithm *QgsPointsLayerFromTableAlgorithm::createInstance() const
{
return new QgsPointsLayerFromTableAlgorithm();
}

void QgsPointsLayerFromTableAlgorithm::initAlgorithm( const QVariantMap & )
{
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ),
QList< int >() << QgsProcessing::TypeVector ) );
addParameter( new QgsProcessingParameterField( QStringLiteral( "XFIELD" ), QObject::tr( "X field" ), QVariant(),
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any ) );
addParameter( new QgsProcessingParameterField( QStringLiteral( "YFIELD" ), QObject::tr( "Y field" ), QVariant(),
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any ) );
addParameter( new QgsProcessingParameterField( QStringLiteral( "ZFIELD" ), QObject::tr( "Z field" ), QVariant(),
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, false, true ) );
addParameter( new QgsProcessingParameterField( QStringLiteral( "MFIELD" ), QObject::tr( "M field" ), QVariant(),
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, false, true ) );
addParameter( new QgsProcessingParameterCrs( QStringLiteral( "TARGET_CRS" ), QObject::tr( "Target CRS" ), QStringLiteral( "EPSG:4326" ) ) );

addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Points from table" ), QgsProcessing::TypeVectorPoint ) );
}

QVariantMap QgsPointsLayerFromTableAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
{
std::unique_ptr< QgsProcessingFeatureSource > featureSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !featureSource )
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );

QgsFields fields = featureSource->fields();
int xFieldIndex = fields.lookupField( parameterAsString( parameters, QStringLiteral( "XFIELD" ), context ) );
int yFieldIndex = fields.lookupField( parameterAsString( parameters, QStringLiteral( "YFIELD" ), context ) );

QString fieldName = parameterAsString( parameters, QStringLiteral( "ZFIELD" ), context );
int zFieldIndex = -1;
if ( !fieldName.isEmpty() )
zFieldIndex = fields.lookupField( fieldName );

fieldName = parameterAsString( parameters, QStringLiteral( "MFIELD" ), context );
int mFieldIndex = -1;
if ( !fieldName.isEmpty() )
mFieldIndex = fields.lookupField( fieldName );

QgsWkbTypes::Type outputWkbType = QgsWkbTypes::Point;
if ( zFieldIndex >= 0 )
outputWkbType = QgsWkbTypes::addZ( outputWkbType );
if ( mFieldIndex >= 0 )
outputWkbType = QgsWkbTypes::addM( outputWkbType );

QgsCoordinateReferenceSystem crs = parameterAsCrs( parameters, QStringLiteral( "TARGET_CRS" ), context );

QString dest;
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, outputWkbType, crs, QgsFeatureSink::RegeneratePrimaryKey ) );
if ( !sink )
throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );

double step = featureSource->featureCount() > 0 ? 100.0 / featureSource->featureCount() : 1;

QgsFeatureRequest req;
req.setFlags( QgsFeatureRequest::NoGeometry );
QgsFeatureIterator fi = featureSource->getFeatures( req, QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks );
QgsFeature f;
int current = 0;

while ( fi.nextFeature( f ) )
{
if ( feedback->isCanceled() )
{
break;
}

QgsAttributes attrs = f.attributes();

bool xOk = false;
bool yOk = false;
double x = attrs.at( xFieldIndex ).toDouble( &xOk );
double y = attrs.at( yFieldIndex ).toDouble( &yOk );

if ( xOk && yOk )
{
QgsPoint point( x, y );

if ( zFieldIndex >= 0 )
point.addZValue( attrs.at( zFieldIndex ).toDouble() );

if ( mFieldIndex >= 0 )
point.addMValue( attrs.at( mFieldIndex ).toDouble() );

f.setGeometry( QgsGeometry( point.clone() ) );
}

sink->addFeature( f );
feedback->setProgress( current * step );
current++;
}

QVariantMap outputs;
outputs.insert( QStringLiteral( "OUTPUT" ), dest );
return outputs;
}

///@endcond

0 comments on commit 5324d7f

Please sign in to comment.