Port boundary algorithm to c++

Also allow feature based algorithms to customise their appectable
input layers types and set suitable filters for all applicable
algorithms
This commit is contained in:
Nyall Dawson 2017-10-13 08:28:34 +10:00
parent 97c1b0d322
commit 2951afa324
22 changed files with 233 additions and 100 deletions

View File

@ -801,6 +801,14 @@ class QgsProcessingFeatureBasedAlgorithm : QgsProcessingAlgorithm
:rtype: str :rtype: str
%End %End
virtual QList<int> inputLayerTypes() const;
%Docstring
Returns the valid input layer types for the source layer for this algorithm.
By default vector layers with any geometry types (excluding non-spatial, geometryless layers)
are accepted.
:rtype: list of int
%End
virtual QgsProcessing::SourceType outputLayerType() const; virtual QgsProcessing::SourceType outputLayerType() const;
%Docstring %Docstring
Returns the layer type for layers generated by this algorithm, if Returns the layer type for layers generated by this algorithm, if

View File

@ -27,6 +27,7 @@ __revision__ = '$Format:%H$'
from qgis.PyQt.QtCore import QVariant from qgis.PyQt.QtCore import QVariant
from qgis.core import (QgsField, from qgis.core import (QgsField,
QgsProcessing,
QgsProcessingParameterString, QgsProcessingParameterString,
QgsProcessingParameterNumber, QgsProcessingParameterNumber,
QgsProcessingParameterEnum) QgsProcessingParameterEnum)
@ -72,6 +73,9 @@ class AddTableField(QgisFeatureBasedAlgorithm):
def outputName(self): def outputName(self):
return self.tr('Added') return self.tr('Added')
def inputLayerTypes(self):
return [QgsProcessing.TypeVector]
def prepareAlgorithm(self, parameters, context, feedback): def prepareAlgorithm(self, parameters, context, feedback):
field_type = self.parameterAsEnum(parameters, self.FIELD_TYPE, context) field_type = self.parameterAsEnum(parameters, self.FIELD_TYPE, context)
field_name = self.parameterAsString(parameters, self.FIELD_NAME, context) field_name = self.parameterAsString(parameters, self.FIELD_NAME, context)

View File

@ -1,81 +0,0 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
Boundary.py
--------------
Date : July 2016
Copyright : (C) 2016 by Nyall Dawson
Email : nyall dot dawson 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. *
* *
***************************************************************************
"""
__author__ = 'Nyall Dawson'
__date__ = 'July 2016'
__copyright__ = '(C) 2016, Nyall Dawson'
# This will get replaced with a git SHA1 when you do a git archive323
__revision__ = '$Format:%H$'
import os
from qgis.core import (QgsGeometry,
QgsWkbTypes)
from qgis.PyQt.QtGui import QIcon
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
class Boundary(QgisFeatureBasedAlgorithm):
def __init__(self):
super().__init__()
def icon(self):
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'convex_hull.png'))
def group(self):
return self.tr('Vector geometry')
def name(self):
return 'boundary'
def displayName(self):
return self.tr('Boundary')
def outputName(self):
return self.tr('Boundary')
def outputWkbType(self, input_wkb):
if QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.LineGeometry:
output_wkb = QgsWkbTypes.MultiPoint
elif QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.PolygonGeometry:
output_wkb = QgsWkbTypes.MultiLineString
if QgsWkbTypes.hasZ(input_wkb):
output_wkb = QgsWkbTypes.addZ(output_wkb)
if QgsWkbTypes.hasM(input_wkb):
output_wkb = QgsWkbTypes.addM(output_wkb)
return output_wkb
def processFeature(self, feature, feedback):
input_geometry = feature.geometry()
if input_geometry:
output_geometry = QgsGeometry(input_geometry.geometry().boundary())
if not output_geometry:
feedback.reportError(self.tr('No boundary for feature {} (possibly a closed linestring?)').format(feature.id()))
feature.clearGeometry()
else:
feature.setGeometry(output_geometry)
return feature

View File

@ -25,7 +25,8 @@ __copyright__ = '(C) 2010, Michael Minn'
__revision__ = '$Format:%H$' __revision__ = '$Format:%H$'
from qgis.core import (QgsProcessingParameterField) from qgis.core import (QgsProcessingParameterField,
QgsProcessing)
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
@ -49,6 +50,9 @@ class DeleteColumn(QgisFeatureBasedAlgorithm):
self.tr('Fields to drop'), self.tr('Fields to drop'),
None, 'INPUT', QgsProcessingParameterField.Any, True)) None, 'INPUT', QgsProcessingParameterField.Any, True))
def inputLayerTypes(self):
return [QgsProcessing.TypeVector]
def name(self): def name(self):
return 'deletecolumn' return 'deletecolumn'

View File

@ -24,7 +24,8 @@ __copyright__ = '(C) 2015, Etienne Trimaille'
__revision__ = '$Format:%H$' __revision__ = '$Format:%H$'
from qgis.core import (QgsProcessingParameterNumber) from qgis.core import (QgsProcessingParameterNumber,
QgsProcessing)
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
@ -56,6 +57,9 @@ class DeleteHoles(QgisFeatureBasedAlgorithm):
def outputName(self): def outputName(self):
return self.tr('Cleaned') return self.tr('Cleaned')
def inputLayerTypes(self):
return [QgsProcessing.TypeVectorPolygon]
def prepareAlgorithm(self, parameters, context, feedback): def prepareAlgorithm(self, parameters, context, feedback):
self.min_area = self.parameterAsDouble(parameters, self.MIN_AREA, context) self.min_area = self.parameterAsDouble(parameters, self.MIN_AREA, context)
if self.min_area == 0.0: if self.min_area == 0.0:

View File

@ -28,7 +28,8 @@ __revision__ = '$Format:%H$'
import os import os
from qgis.core import (QgsProcessingParameterNumber) from qgis.core import (QgsProcessingParameterNumber,
QgsProcessing)
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
@ -61,6 +62,9 @@ class DensifyGeometries(QgisFeatureBasedAlgorithm):
def outputName(self): def outputName(self):
return self.tr('Densified') return self.tr('Densified')
def inputLayerTypes(self):
return [QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon]
def prepareAlgorithm(self, parameters, context, feedback): def prepareAlgorithm(self, parameters, context, feedback):
self.vertices = self.parameterAsInt(parameters, self.VERTICES, context) self.vertices = self.parameterAsInt(parameters, self.VERTICES, context)
return True return True

View File

@ -27,7 +27,8 @@ __copyright__ = '(C) 2012, Anita Graser'
__revision__ = '$Format:%H$' __revision__ = '$Format:%H$'
from qgis.core import (QgsProcessingParameterNumber) from qgis.core import (QgsProcessingParameterNumber,
QgsProcessing)
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
@ -57,6 +58,9 @@ class DensifyGeometriesInterval(QgisFeatureBasedAlgorithm):
def outputName(self): def outputName(self):
return self.tr('Densified') return self.tr('Densified')
def inputLayerTypes(self):
return [QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon]
def prepareAlgorithm(self, parameters, context, feedback): def prepareAlgorithm(self, parameters, context, feedback):
interval = self.parameterAsDouble(parameters, self.INTERVAL, context) interval = self.parameterAsDouble(parameters, self.INTERVAL, context)
return True return True

View File

@ -26,7 +26,8 @@ __copyright__ = '(C) 2016, Nyall Dawson'
__revision__ = '$Format:%H$' __revision__ = '$Format:%H$'
from qgis.core import (QgsProcessingParameterNumber, from qgis.core import (QgsProcessingParameterNumber,
QgsProcessingException) QgsProcessingException,
QgsProcessing)
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
@ -58,6 +59,9 @@ class ExtendLines(QgisFeatureBasedAlgorithm):
def outputName(self): def outputName(self):
return self.tr('Extended') return self.tr('Extended')
def inputLayerTypes(self):
return [QgsProcessing.TypeVectorLine]
def prepareAlgorithm(self, parameters, context, feedback): def prepareAlgorithm(self, parameters, context, feedback):
self.start_distance = self.parameterAsDouble(parameters, self.START_DISTANCE, context) self.start_distance = self.parameterAsDouble(parameters, self.START_DISTANCE, context)
self.end_distance = self.parameterAsDouble(parameters, self.END_DISTANCE, context) self.end_distance = self.parameterAsDouble(parameters, self.END_DISTANCE, context)

View File

@ -30,6 +30,7 @@ from qgis.core import (
QgsExpression, QgsExpression,
QgsField, QgsField,
QgsFields, QgsFields,
QgsProcessing,
QgsProcessingException, QgsProcessingException,
QgsProcessingParameterDefinition) QgsProcessingParameterDefinition)
@ -103,6 +104,9 @@ class FieldsMapper(QgisFeatureBasedAlgorithm):
def outputName(self): def outputName(self):
return self.tr('Refactored') return self.tr('Refactored')
def inputLayerTypes(self):
return [QgsProcessing.TypeVector]
def parameterAsFieldsMapping(self, parameters, name, context): def parameterAsFieldsMapping(self, parameters, name, context):
return parameters[name] return parameters[name]

View File

@ -74,6 +74,9 @@ class LinesToPolygons(QgisFeatureBasedAlgorithm):
def outputType(self): def outputType(self):
return QgsProcessing.TypeVectorPolygon return QgsProcessing.TypeVectorPolygon
def inputLayerTypes(self):
return [QgsProcessing.TypeVectorLine]
def outputWkbType(self, input_wkb_type): def outputWkbType(self, input_wkb_type):
return self.convertWkbToPolygons(input_wkb_type) return self.convertWkbToPolygons(input_wkb_type)

View File

@ -87,6 +87,9 @@ class OffsetLine(QgisFeatureBasedAlgorithm):
def outputName(self): def outputName(self):
return self.tr('Offset') return self.tr('Offset')
def inputLayerTypes(self):
return [QgsProcessing.TypeVectorLine]
def outputType(self): def outputType(self):
return QgsProcessing.TypeVectorLine return QgsProcessing.TypeVectorLine

View File

@ -25,7 +25,8 @@ __copyright__ = '(C) 2016, Nyall Dawson'
__revision__ = '$Format:%H$' __revision__ = '$Format:%H$'
from qgis.core import (QgsProcessingException, from qgis.core import (QgsProcessing,
QgsProcessingException,
QgsProcessingParameterDefinition, QgsProcessingParameterDefinition,
QgsProcessingParameterNumber) QgsProcessingParameterNumber)
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
@ -70,6 +71,9 @@ class Orthogonalize(QgisFeatureBasedAlgorithm):
def outputName(self): def outputName(self):
return self.tr('Orthogonalized') return self.tr('Orthogonalized')
def inputLayerTypes(self):
return [QgsProcessing.TypeVectorPolygon, QgsProcessing.TypeVectorLine]
def prepareAlgorithm(self, parameters, context, feedback): def prepareAlgorithm(self, parameters, context, feedback):
self.max_iterations = self.parameterAsInt(parameters, self.MAX_ITERATIONS, context) self.max_iterations = self.parameterAsInt(parameters, self.MAX_ITERATIONS, context)
self.angle_tolerance = self.parameterAsDouble(parameters, self.ANGLE_TOLERANCE, context) self.angle_tolerance = self.parameterAsDouble(parameters, self.ANGLE_TOLERANCE, context)

View File

@ -67,6 +67,9 @@ class PolygonsToLines(QgisFeatureBasedAlgorithm):
def outputType(self): def outputType(self):
return QgsProcessing.TypeVectorLine return QgsProcessing.TypeVectorLine
def inputLayerTypes(self):
return [QgsProcessing.TypeVectorPolygon]
def outputWkbType(self, input_wkb_type): def outputWkbType(self, input_wkb_type):
return self.convertWkbToLines(input_wkb_type) return self.convertWkbToLines(input_wkb_type)

View File

@ -44,7 +44,6 @@ from .AddTableField import AddTableField
from .Aggregate import Aggregate from .Aggregate import Aggregate
from .Aspect import Aspect from .Aspect import Aspect
from .BasicStatistics import BasicStatisticsForField from .BasicStatistics import BasicStatisticsForField
from .Boundary import Boundary
from .CheckValidity import CheckValidity from .CheckValidity import CheckValidity
from .ConcaveHull import ConcaveHull from .ConcaveHull import ConcaveHull
from .CreateAttributeIndex import CreateAttributeIndex from .CreateAttributeIndex import CreateAttributeIndex
@ -174,7 +173,6 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
Aggregate(), Aggregate(),
Aspect(), Aspect(),
BasicStatisticsForField(), BasicStatisticsForField(),
Boundary(),
CheckValidity(), CheckValidity(),
ConcaveHull(), ConcaveHull(),
CreateAttributeIndex(), CreateAttributeIndex(),

View File

@ -51,6 +51,9 @@ class ReverseLineDirection(QgisFeatureBasedAlgorithm):
def outputType(self): def outputType(self):
return QgsProcessing.TypeVectorLine return QgsProcessing.TypeVectorLine
def inputLayerTypes(self):
return [QgsProcessing.TypeVectorLine]
def processFeature(self, feature, feedback): def processFeature(self, feature, feedback):
if feature.geometry(): if feature.geometry():
inGeom = feature.geometry() inGeom = feature.geometry()

View File

@ -86,6 +86,9 @@ class SingleSidedBuffer(QgisFeatureBasedAlgorithm):
def outputName(self): def outputName(self):
return self.tr('Buffers') return self.tr('Buffers')
def inputLayerTypes(self):
return [QgsProcessing.TypeVectorLine]
def outputType(self): def outputType(self):
return QgsProcessing.TypeVectorPolygon return QgsProcessing.TypeVectorPolygon

View File

@ -27,6 +27,7 @@ __revision__ = '$Format:%H$'
from qgis.PyQt.QtCore import QVariant from qgis.PyQt.QtCore import QVariant
from qgis.core import (QgsField, from qgis.core import (QgsField,
QgsProcessing,
QgsProcessingParameterField) QgsProcessingParameterField)
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
@ -59,6 +60,9 @@ class TextToFloat(QgisFeatureBasedAlgorithm):
def outputName(self): def outputName(self):
return self.tr('Float from text') return self.tr('Float from text')
def inputLayerTypes(self):
return [QgsProcessing.TypeVector]
def outputFields(self, inputFields): def outputFields(self, inputFields):
self.field_idx = inputFields.lookupField(self.field_name) self.field_idx = inputFields.lookupField(self.field_name)
if self.field_idx >= 0: if self.field_idx >= 0:

View File

@ -665,7 +665,7 @@ tests:
name: expected/multipoint_bounds.gml name: expected/multipoint_bounds.gml
type: vector type: vector
- algorithm: qgis:boundary - algorithm: native:boundary
name: Polygon boundary name: Polygon boundary
params: params:
INPUT: INPUT:
@ -676,7 +676,7 @@ tests:
name: expected/poly_boundary.gml name: expected/poly_boundary.gml
type: vector type: vector
- algorithm: qgis:boundary - algorithm: native:boundary
name: Multipoly boundary name: Multipoly boundary
params: params:
INPUT: INPUT:
@ -687,7 +687,7 @@ tests:
name: expected/multipoly_boundary.gml name: expected/multipoly_boundary.gml
type: vector type: vector
- algorithm: qgis:boundary - algorithm: native:boundary
name: Line boundary name: Line boundary
params: params:
INPUT: INPUT:
@ -698,7 +698,7 @@ tests:
name: expected/lines_boundary.gml name: expected/lines_boundary.gml
type: vector type: vector
- algorithm: qgis:boundary - algorithm: native:boundary
name: Multiline boundary name: Multiline boundary
params: params:
INPUT: INPUT:

View File

@ -94,6 +94,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
addAlgorithm( new QgsJoinWithLinesAlgorithm() ); addAlgorithm( new QgsJoinWithLinesAlgorithm() );
addAlgorithm( new QgsAssignProjectionAlgorithm() ); addAlgorithm( new QgsAssignProjectionAlgorithm() );
addAlgorithm( new QgsAddIncrementalFieldAlgorithm() ); addAlgorithm( new QgsAddIncrementalFieldAlgorithm() );
addAlgorithm( new QgsBoundaryAlgorithm() );
} }
void QgsSaveSelectedFeatures::initAlgorithm( const QVariantMap & ) void QgsSaveSelectedFeatures::initAlgorithm( const QVariantMap & )
@ -707,6 +708,11 @@ QString QgsAddIncrementalFieldAlgorithm::shortHelpString() const
"The initial starting value for the incremental series can be specified." ); "The initial starting value for the incremental series can be specified." );
} }
QList<int> QgsAddIncrementalFieldAlgorithm::inputLayerTypes() const
{
return QList<int>() << QgsProcessing::TypeVector;
}
QgsAddIncrementalFieldAlgorithm *QgsAddIncrementalFieldAlgorithm::createInstance() const QgsAddIncrementalFieldAlgorithm *QgsAddIncrementalFieldAlgorithm::createInstance() const
{ {
return new QgsAddIncrementalFieldAlgorithm(); return new QgsAddIncrementalFieldAlgorithm();
@ -1834,6 +1840,11 @@ QString QgsMergeLinesAlgorithm::shortHelpString() const
"geometry will be a MultiLineString containing any lines which could be merged and any non-connected line parts." ); "geometry will be a MultiLineString containing any lines which could be merged and any non-connected line parts." );
} }
QList<int> QgsMergeLinesAlgorithm::inputLayerTypes() const
{
return QList<int>() << QgsProcessing::TypeVectorLine;
}
QgsMergeLinesAlgorithm *QgsMergeLinesAlgorithm::createInstance() const QgsMergeLinesAlgorithm *QgsMergeLinesAlgorithm::createInstance() const
{ {
return new QgsMergeLinesAlgorithm(); return new QgsMergeLinesAlgorithm();
@ -1874,6 +1885,11 @@ QgsSmoothAlgorithm *QgsSmoothAlgorithm::createInstance() const
return new QgsSmoothAlgorithm(); return new QgsSmoothAlgorithm();
} }
QList<int> QgsSmoothAlgorithm::inputLayerTypes() const
{
return QList<int>() << QgsProcessing::TypeVectorLine << QgsProcessing::TypeVectorPolygon;
}
void QgsSmoothAlgorithm::initParameters( const QVariantMap & ) void QgsSmoothAlgorithm::initParameters( const QVariantMap & )
{ {
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "ITERATIONS" ), addParameter( new QgsProcessingParameterNumber( QStringLiteral( "ITERATIONS" ),
@ -1923,6 +1939,11 @@ QgsSimplifyAlgorithm *QgsSimplifyAlgorithm::createInstance() const
return new QgsSimplifyAlgorithm(); return new QgsSimplifyAlgorithm();
} }
QList<int> QgsSimplifyAlgorithm::inputLayerTypes() const
{
return QList<int>() << QgsProcessing::TypeVectorLine << QgsProcessing::TypeVectorPolygon;
}
void QgsSimplifyAlgorithm::initParameters( const QVariantMap & ) void QgsSimplifyAlgorithm::initParameters( const QVariantMap & )
{ {
QStringList methods; QStringList methods;
@ -3174,5 +3195,72 @@ QVariantMap QgsJoinWithLinesAlgorithm::processAlgorithm( const QVariantMap &para
return outputs; return outputs;
} }
QString QgsBoundaryAlgorithm::shortHelpString() const
{
return QObject::tr( "Returns the closure of the combinatorial boundary of the input geometries (ie the "
"topological boundary of the geometry). For instance, a polygon geometry will have a "
"boundary consisting of the linestrings for each ring in the polygon. Only valid for "
"polygon or line layers." );
}
QList<int> QgsBoundaryAlgorithm::inputLayerTypes() const
{
return QList<int>() << QgsProcessing::TypeVectorLine << QgsProcessing::TypeVectorPolygon;
}
QgsBoundaryAlgorithm *QgsBoundaryAlgorithm::createInstance() const
{
return new QgsBoundaryAlgorithm();
}
QgsWkbTypes::Type QgsBoundaryAlgorithm::outputWkbType( QgsWkbTypes::Type inputWkbType ) const
{
QgsWkbTypes::Type outputWkb = QgsWkbTypes::Unknown;
switch ( QgsWkbTypes::geometryType( inputWkbType ) )
{
case QgsWkbTypes::LineGeometry:
outputWkb = QgsWkbTypes::MultiPoint;
break;
case QgsWkbTypes::PolygonGeometry:
outputWkb = QgsWkbTypes::MultiLineString;
break;
case QgsWkbTypes::PointGeometry:
case QgsWkbTypes::UnknownGeometry:
case QgsWkbTypes::NoGeometry:
outputWkb = QgsWkbTypes::NoGeometry;
break;
}
if ( QgsWkbTypes::hasZ( inputWkbType ) )
outputWkb = QgsWkbTypes::addZ( outputWkb );
if ( QgsWkbTypes::hasM( inputWkbType ) )
outputWkb = QgsWkbTypes::addM( outputWkb );
return outputWkb;
}
QgsFeature QgsBoundaryAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingFeedback *feedback )
{
QgsFeature outFeature = feature;
if ( feature.hasGeometry() )
{
QgsGeometry inputGeometry = feature.geometry();
QgsGeometry outputGeometry = QgsGeometry( inputGeometry.geometry()->boundary() );
if ( !outputGeometry )
{
feedback->reportError( QObject::tr( "No boundary for feature %1 (possibly a closed linestring?)'" ).arg( feature.id() ) );
outFeature.clearGeometry();
}
else
{
outFeature.setGeometry( outputGeometry );
}
}
return outFeature;
}
///@endcond ///@endcond

View File

@ -98,6 +98,30 @@ class QgsCentroidAlgorithm : public QgsProcessingFeatureBasedAlgorithm
QgsFeature processFeature( const QgsFeature &feature, QgsProcessingFeedback *feedback ) override; QgsFeature processFeature( const QgsFeature &feature, QgsProcessingFeedback *feedback ) override;
}; };
/**
* Native boundary algorithm.
*/
class QgsBoundaryAlgorithm : public QgsProcessingFeatureBasedAlgorithm
{
public:
QgsBoundaryAlgorithm() = default;
QString name() const override { return QStringLiteral( "boundary" ); }
QString displayName() const override { return QObject::tr( "Boundary" ); }
QStringList tags() const override { return QObject::tr( "boundary,ring,border,exterior" ).split( ',' ); }
QString group() const override { return QObject::tr( "Vector geometry" ); }
QString shortHelpString() const override;
QList<int> inputLayerTypes() const override;
QgsBoundaryAlgorithm *createInstance() const override SIP_FACTORY;
protected:
QString outputName() const override { return QObject::tr( "Boundary" ); }
QgsWkbTypes::Type outputWkbType( QgsWkbTypes::Type inputWkbType ) const override;
QgsFeature processFeature( const QgsFeature &feature, QgsProcessingFeedback *feedback ) override;
};
/** /**
* Native transform algorithm. * Native transform algorithm.
*/ */
@ -179,6 +203,7 @@ class QgsAddIncrementalFieldAlgorithm : public QgsProcessingFeatureBasedAlgorith
virtual QStringList tags() const override { return QObject::tr( "add,create,serial,primary,key,unique,field" ).split( ',' ); } virtual QStringList tags() const override { return QObject::tr( "add,create,serial,primary,key,unique,field" ).split( ',' ); }
QString group() const override { return QObject::tr( "Vector table" ); } QString group() const override { return QObject::tr( "Vector table" ); }
QString shortHelpString() const override; QString shortHelpString() const override;
QList<int> inputLayerTypes() const override;
QgsAddIncrementalFieldAlgorithm *createInstance() const override SIP_FACTORY; QgsAddIncrementalFieldAlgorithm *createInstance() const override SIP_FACTORY;
protected: protected:
@ -686,6 +711,7 @@ class QgsMergeLinesAlgorithm : public QgsProcessingFeatureBasedAlgorithm
virtual QStringList tags() const override { return QObject::tr( "line,merge,join,parts" ).split( ',' ); } virtual QStringList tags() const override { return QObject::tr( "line,merge,join,parts" ).split( ',' ); }
QString group() const override { return QObject::tr( "Vector geometry" ); } QString group() const override { return QObject::tr( "Vector geometry" ); }
QString shortHelpString() const override; QString shortHelpString() const override;
QList<int> inputLayerTypes() const override;
QgsMergeLinesAlgorithm *createInstance() const override SIP_FACTORY; QgsMergeLinesAlgorithm *createInstance() const override SIP_FACTORY;
protected: protected:
@ -711,6 +737,7 @@ class QgsSmoothAlgorithm : public QgsProcessingFeatureBasedAlgorithm
QString group() const override { return QObject::tr( "Vector geometry" ); } QString group() const override { return QObject::tr( "Vector geometry" ); }
QString shortHelpString() const override; QString shortHelpString() const override;
QgsSmoothAlgorithm *createInstance() const override SIP_FACTORY; QgsSmoothAlgorithm *createInstance() const override SIP_FACTORY;
QList<int> inputLayerTypes() const override;
void initParameters( const QVariantMap &configuration = QVariantMap() ) override; void initParameters( const QVariantMap &configuration = QVariantMap() ) override;
protected: protected:
@ -740,6 +767,7 @@ class QgsSimplifyAlgorithm : public QgsProcessingFeatureBasedAlgorithm
QString group() const override { return QObject::tr( "Vector geometry" ); } QString group() const override { return QObject::tr( "Vector geometry" ); }
QString shortHelpString() const override; QString shortHelpString() const override;
QgsSimplifyAlgorithm *createInstance() const override SIP_FACTORY; QgsSimplifyAlgorithm *createInstance() const override SIP_FACTORY;
QList<int> inputLayerTypes() const override;
void initParameters( const QVariantMap &configuration = QVariantMap() ) override; void initParameters( const QVariantMap &configuration = QVariantMap() ) override;
protected: protected:

View File

@ -629,11 +629,45 @@ bool QgsProcessingAlgorithm::createAutoOutputForParameter( QgsProcessingParamete
void QgsProcessingFeatureBasedAlgorithm::initAlgorithm( const QVariantMap &config ) void QgsProcessingFeatureBasedAlgorithm::initAlgorithm( const QVariantMap &config )
{ {
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) ); addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ), inputLayerTypes() ) );
initParameters( config ); initParameters( config );
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), outputName(), outputLayerType() ) ); addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), outputName(), outputLayerType() ) );
} }
QList<int> QgsProcessingFeatureBasedAlgorithm::inputLayerTypes() const
{
return QList<int>();
}
QgsProcessing::SourceType QgsProcessingFeatureBasedAlgorithm::outputLayerType() const
{
return QgsProcessing::TypeVectorAnyGeometry;
}
QgsProcessingFeatureSource::Flag QgsProcessingFeatureBasedAlgorithm::sourceFlags() const
{
return static_cast<QgsProcessingFeatureSource::Flag>( 0 );
}
QgsWkbTypes::Type QgsProcessingFeatureBasedAlgorithm::outputWkbType( QgsWkbTypes::Type inputWkbType ) const
{
return inputWkbType;
}
QgsFields QgsProcessingFeatureBasedAlgorithm::outputFields( const QgsFields &inputFields ) const
{
return inputFields;
}
QgsCoordinateReferenceSystem QgsProcessingFeatureBasedAlgorithm::outputCrs( const QgsCoordinateReferenceSystem &inputCrs ) const
{
return inputCrs;
}
void QgsProcessingFeatureBasedAlgorithm::initParameters( const QVariantMap & )
{
}
QgsCoordinateReferenceSystem QgsProcessingFeatureBasedAlgorithm::sourceCrs() const QgsCoordinateReferenceSystem QgsProcessingFeatureBasedAlgorithm::sourceCrs() const
{ {
if ( mSource ) if ( mSource )

View File

@ -790,16 +790,23 @@ class CORE_EXPORT QgsProcessingFeatureBasedAlgorithm : public QgsProcessingAlgor
*/ */
virtual QString outputName() const = 0; virtual QString outputName() const = 0;
/**
* Returns the valid input layer types for the source layer for this algorithm.
* By default vector layers with any geometry types (excluding non-spatial, geometryless layers)
* are accepted.
*/
virtual QList<int> inputLayerTypes() const;
/** /**
* Returns the layer type for layers generated by this algorithm, if * Returns the layer type for layers generated by this algorithm, if
* this is possible to determine in advance. * this is possible to determine in advance.
*/ */
virtual QgsProcessing::SourceType outputLayerType() const { return QgsProcessing::TypeVectorAnyGeometry; } virtual QgsProcessing::SourceType outputLayerType() const;
/** /**
* Returns the processing feature source flags to be used in the algorithm. * Returns the processing feature source flags to be used in the algorithm.
*/ */
virtual QgsProcessingFeatureSource::Flag sourceFlags() const { return static_cast<QgsProcessingFeatureSource::Flag>( 0 ); } virtual QgsProcessingFeatureSource::Flag sourceFlags() const;
/** /**
* Maps the input WKB geometry type (\a inputWkbType) to the corresponding * Maps the input WKB geometry type (\a inputWkbType) to the corresponding
@ -808,7 +815,7 @@ class CORE_EXPORT QgsProcessingFeatureBasedAlgorithm : public QgsProcessingAlgor
* This is called once by the base class when creating the output sink for the algorithm (i.e. it is * This is called once by the base class when creating the output sink for the algorithm (i.e. it is
* not called once per feature processed). * not called once per feature processed).
*/ */
virtual QgsWkbTypes::Type outputWkbType( QgsWkbTypes::Type inputWkbType ) const { return inputWkbType; } virtual QgsWkbTypes::Type outputWkbType( QgsWkbTypes::Type inputWkbType ) const;
/** /**
* Maps the input source fields (\a inputFields) to corresponding * Maps the input source fields (\a inputFields) to corresponding
@ -820,7 +827,7 @@ class CORE_EXPORT QgsProcessingFeatureBasedAlgorithm : public QgsProcessingAlgor
* This is called once by the base class when creating the output sink for the algorithm (i.e. it is * This is called once by the base class when creating the output sink for the algorithm (i.e. it is
* not called once per feature processed). * not called once per feature processed).
*/ */
virtual QgsFields outputFields( const QgsFields &inputFields ) const { return inputFields; } virtual QgsFields outputFields( const QgsFields &inputFields ) const;
/** /**
* Maps the input source coordinate reference system (\a inputCrs) to a corresponding * Maps the input source coordinate reference system (\a inputCrs) to a corresponding
@ -830,14 +837,14 @@ class CORE_EXPORT QgsProcessingFeatureBasedAlgorithm : public QgsProcessingAlgor
* This is called once by the base class when creating the output sink for the algorithm (i.e. it is * This is called once by the base class when creating the output sink for the algorithm (i.e. it is
* not called once per feature processed). * not called once per feature processed).
*/ */
virtual QgsCoordinateReferenceSystem outputCrs( const QgsCoordinateReferenceSystem &inputCrs ) const { return inputCrs; } virtual QgsCoordinateReferenceSystem outputCrs( const QgsCoordinateReferenceSystem &inputCrs ) const;
/** /**
* Initializes any extra parameters added by the algorithm subclass. There is no need * Initializes any extra parameters added by the algorithm subclass. There is no need
* to declare the input source or output sink, as these are automatically created by * to declare the input source or output sink, as these are automatically created by
* QgsProcessingFeatureBasedAlgorithm. * QgsProcessingFeatureBasedAlgorithm.
*/ */
virtual void initParameters( const QVariantMap &configuration = QVariantMap() ) { Q_UNUSED( configuration ); } virtual void initParameters( const QVariantMap &configuration = QVariantMap() );
/** /**
* Returns the source's coordinate reference system. This will only return a valid CRS when * Returns the source's coordinate reference system. This will only return a valid CRS when