Skip to content

Commit

Permalink
Merge pull request #4868 from nyalldawson/nn
Browse files Browse the repository at this point in the history
Port Remove Null Geometries algorithm to c++/new API
  • Loading branch information
nyalldawson authored Jul 16, 2017
2 parents 261391d + 1342f4d commit 23a4d60
Show file tree
Hide file tree
Showing 13 changed files with 170 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ class QgsProcessingModelAlgorithm : QgsProcessingAlgorithm
%End

QList< QgsProcessingModelChildParameterSource > availableSourcesForChild( const QString &childId, const QStringList &parameterTypes = QStringList(),
const QStringList &outputTypes = QStringList(), const QList< int > dataTypes = QList< int >() ) const;
const QStringList &outputTypes = QStringList(), const QList< int > &dataTypes = QList< int >() ) const;
%Docstring
Returns a list of possible sources which can be used for the parameters for a child
algorithm in the model. Returned sources are those which match either one of the
Expand Down
15 changes: 15 additions & 0 deletions python/core/processing/qgsprocessingparameters.sip
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,21 @@ class QgsProcessingDestinationParameter : QgsProcessingParameterDefinition
:rtype: str
%End

bool createByDefault() const;
%Docstring
Returns true if the destination should be created by default. For optional parameters,
a return value of false indicates that the destination should not be created by default.
.. seealso:: setCreateByDefault()
:rtype: bool
%End

void setCreateByDefault( bool createByDefault );
%Docstring
Sets whether the destination should be created by default. For optional parameters,
a value of false indicates that the destination should not be created by default.
.. seealso:: createByDefault()
%End

};


Expand Down
2 changes: 0 additions & 2 deletions python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@
# from .Relief import Relief
# from .IdwInterpolation import IdwInterpolation
# from .TinInterpolation import TinInterpolation
# from .RemoveNullGeometry import RemoveNullGeometry
# from .ExtendLines import ExtendLines
# from .ExtractSpecificNodes import ExtractSpecificNodes
# from .GeometryByExpression import GeometryByExpression
Expand Down Expand Up @@ -220,7 +219,6 @@ def getAlgs(self):
# Slope(), Ruggedness(), Hillshade(),
# Relief(),
# IdwInterpolation(), TinInterpolation(),
# RemoveNullGeometry(),
# ExtendLines(), ExtractSpecificNodes(),
# GeometryByExpression(),
# PoleOfInaccessibility(),
Expand Down
76 changes: 0 additions & 76 deletions python/plugins/processing/algs/qgis/RemoveNullGeometry.py

This file was deleted.

2 changes: 1 addition & 1 deletion python/plugins/processing/gui/DestinationSelectionPanel.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def __init__(self, parameter, alg):
self.use_temporary = True

if hasattr(self.leText, 'setPlaceholderText'):
if parameter.flags() & QgsProcessingParameterDefinition.FlagOptional and parameter.defaultValue() is None:
if parameter.flags() & QgsProcessingParameterDefinition.FlagOptional and not parameter.createByDefault():
self.leText.setPlaceholderText(self.SKIP_OUTPUT)
self.use_temporary = False
elif isinstance(self.parameter, QgsProcessingParameterFeatureSink) \
Expand Down
22 changes: 11 additions & 11 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1258,17 +1258,17 @@ tests:
# #TRIANULATION_FILE:
# # name: expected/triangulation.gml
# # type: vector
#
# - algorithm: qgis:removenullgeometries
# name: Remove null geometries
# params:
# INPUT_LAYER:
# name: polys.gml
# type: vector
# results:
# OUTPUT_LAYER:
# name: expected/remove_null_polys.gml
# type: vector

- algorithm: native:removenullgeometries
name: Remove null geometries
params:
INPUT:
name: polys.gml
type: vector
results:
OUTPUT:
name: expected/remove_null_polys.gml
type: vector
#
- algorithm: native:extractbyexpression
name: Extract by Expression
Expand Down
2 changes: 1 addition & 1 deletion src/core/processing/models/qgsprocessingmodelalgorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ QgsExpressionContextScope *QgsProcessingModelAlgorithm::createExpressionContextS
return scope.release();
}

QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild( const QString &childId, const QStringList &parameterTypes, const QStringList &outputTypes, const QList<int> dataTypes ) const
QgsProcessingModelChildParameterSources QgsProcessingModelAlgorithm::availableSourcesForChild( const QString &childId, const QStringList &parameterTypes, const QStringList &outputTypes, const QList<int> &dataTypes ) const
{
QgsProcessingModelChildParameterSources sources;

Expand Down
2 changes: 1 addition & 1 deletion src/core/processing/models/qgsprocessingmodelalgorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
* sources to those with compatible data types for the parameter/outputs.
*/
QList< QgsProcessingModelChildParameterSource > availableSourcesForChild( const QString &childId, const QStringList &parameterTypes = QStringList(),
const QStringList &outputTypes = QStringList(), const QList< int > dataTypes = QList< int >() ) const;
const QStringList &outputTypes = QStringList(), const QList< int > &dataTypes = QList< int >() ) const;

/**
* Definition of a expression context variable available during model execution.
Expand Down
89 changes: 85 additions & 4 deletions src/core/processing/qgsnativealgorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
addAlgorithm( new QgsMultipartToSinglepartAlgorithm() );
addAlgorithm( new QgsSubdivideAlgorithm() );
addAlgorithm( new QgsTransformAlgorithm() );
addAlgorithm( new QgsRemoveNullGeometryAlgorithm() );
}

void QgsCentroidAlgorithm::initAlgorithm( const QVariantMap & )
Expand Down Expand Up @@ -787,8 +788,10 @@ void QgsExtractByExpressionAlgorithm::initAlgorithm( const QVariantMap & )
addParameter( new QgsProcessingParameterExpression( QStringLiteral( "EXPRESSION" ), QObject::tr( "Expression" ), QVariant(), QStringLiteral( "INPUT" ) ) );

addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Matching features" ) ) );
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "FAIL_OUTPUT" ), QObject::tr( "Non-matching" ),
QgsProcessing::TypeVectorAny, QVariant(), true ) );
QgsProcessingParameterFeatureSink *failOutput = new QgsProcessingParameterFeatureSink( QStringLiteral( "FAIL_OUTPUT" ), QObject::tr( "Non-matching" ),
QgsProcessing::TypeVectorAny, QVariant(), true );
failOutput->setCreateByDefault( false );
addParameter( failOutput );
}

QString QgsExtractByExpressionAlgorithm::shortHelpString() const
Expand Down Expand Up @@ -916,8 +919,10 @@ void QgsExtractByAttributeAlgorithm::initAlgorithm( const QVariantMap & )
addParameter( new QgsProcessingParameterString( QStringLiteral( "VALUE" ), QObject::tr( "Value" ), QVariant(), false, true ) );

addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Extracted (attribute)" ) ) );
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "FAIL_OUTPUT" ), QObject::tr( "Extracted (non-matching)" ),
QgsProcessing::TypeVectorAny, QVariant(), true ) );
QgsProcessingParameterFeatureSink *failOutput = new QgsProcessingParameterFeatureSink( QStringLiteral( "FAIL_OUTPUT" ), QObject::tr( "Extracted (non-matching)" ),
QgsProcessing::TypeVectorAny, QVariant(), true );
failOutput->setCreateByDefault( false );
addParameter( failOutput );
}

QString QgsExtractByAttributeAlgorithm::shortHelpString() const
Expand Down Expand Up @@ -1093,4 +1098,80 @@ QVariantMap QgsExtractByAttributeAlgorithm::processAlgorithm( const QVariantMap
return outputs;
}


void QgsRemoveNullGeometryAlgorithm::initAlgorithm( const QVariantMap & )
{
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );

addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Non null geometries" ),
QgsProcessing::TypeVectorAny, QVariant(), true ) );
QgsProcessingParameterFeatureSink *nullOutput = new QgsProcessingParameterFeatureSink( QStringLiteral( "NULL_OUTPUT" ), QObject::tr( "Null geometries" ),
QgsProcessing::TypeTable, QVariant(), true );
nullOutput->setCreateByDefault( false );
addParameter( nullOutput );
}

QString QgsRemoveNullGeometryAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm removes any features which do not have a geometry from a vector layer. "
"All other features will be copied unchanged.\n\n"
"Optionally, the features with null geometries can be saved to a separate output." );
}

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

QVariantMap QgsRemoveNullGeometryAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
{
std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
return QVariantMap();

QString nonNullSinkId;
std::unique_ptr< QgsFeatureSink > nonNullSink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, nonNullSinkId, source->fields(),
source->wkbType(), source->sourceCrs() ) );

QString nullSinkId;
std::unique_ptr< QgsFeatureSink > nullSink( parameterAsSink( parameters, QStringLiteral( "NULL_OUTPUT" ), context, nullSinkId, source->fields() ) );

long count = source->featureCount();
if ( count <= 0 )
return QVariantMap();

double step = 100.0 / count;
int current = 0;

QgsFeature f;
QgsFeatureIterator it = source->getFeatures();
while ( it.nextFeature( f ) )
{
if ( feedback->isCanceled() )
{
break;
}

if ( f.hasGeometry() && nonNullSink )
{
nonNullSink->addFeature( f, QgsFeatureSink::FastInsert );
}
else if ( !f.hasGeometry() && nullSink )
{
nullSink->addFeature( f, QgsFeatureSink::FastInsert );
}

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

QVariantMap outputs;
if ( nonNullSink )
outputs.insert( QStringLiteral( "OUTPUT" ), nonNullSinkId );
if ( nullSink )
outputs.insert( QStringLiteral( "NULL_OUTPUT" ), nullSinkId );
return outputs;
}


///@endcond
25 changes: 25 additions & 0 deletions src/core/processing/qgsnativealgorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,31 @@ class QgsMultipartToSinglepartAlgorithm : public QgsProcessingAlgorithm

};


/**
* Remove null geometry algorithm.
*/
class QgsRemoveNullGeometryAlgorithm : public QgsProcessingAlgorithm
{

public:

QgsRemoveNullGeometryAlgorithm() = default;
void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
QString name() const override { return QStringLiteral( "removenullgeometries" ); }
QString displayName() const override { return QObject::tr( "Remove null geometries" ); }
virtual QStringList tags() const override { return QObject::tr( "remove,drop,delete,empty,geometry" ).split( ',' ); }
QString group() const override { return QObject::tr( "Vector selection tools" ); }
QString shortHelpString() const override;
QgsRemoveNullGeometryAlgorithm *createInstance() const override SIP_FACTORY;

protected:

virtual QVariantMap processAlgorithm( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;

};

///@endcond PRIVATE

#endif // QGSNATIVEALGORITHMS_H
Expand Down
12 changes: 12 additions & 0 deletions src/core/processing/qgsprocessingparameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2917,13 +2917,15 @@ QVariantMap QgsProcessingDestinationParameter::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "supports_non_file_outputs" ), mSupportsNonFileBasedOutputs );
map.insert( QStringLiteral( "create_by_default" ), mCreateByDefault );
return map;
}

bool QgsProcessingDestinationParameter::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mSupportsNonFileBasedOutputs = map.value( QStringLiteral( "supports_non_file_outputs" ) ).toBool();
mCreateByDefault = map.value( QStringLiteral( "create_by_default" ), QStringLiteral( "1" ) ).toBool();
return true;
}

Expand All @@ -2932,6 +2934,16 @@ QString QgsProcessingDestinationParameter::generateTemporaryDestination() const
return QgsProcessingUtils::generateTempFilename( name() + '.' + defaultFileExtension() );
}

bool QgsProcessingDestinationParameter::createByDefault() const
{
return mCreateByDefault;
}

void QgsProcessingDestinationParameter::setCreateByDefault( bool createByDefault )
{
mCreateByDefault = createByDefault;
}

QgsProcessingParameterVectorDestination::QgsProcessingParameterVectorDestination( const QString &name, const QString &description, QgsProcessing::LayerType type, const QVariant &defaultValue, bool optional )
: QgsProcessingDestinationParameter( name, description, defaultValue, optional )
, mDataType( type )
Expand Down
15 changes: 15 additions & 0 deletions src/core/processing/qgsprocessingparameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -1555,9 +1555,24 @@ class CORE_EXPORT QgsProcessingDestinationParameter : public QgsProcessingParame
*/
virtual QString generateTemporaryDestination() const;

/**
* Returns true if the destination should be created by default. For optional parameters,
* a return value of false indicates that the destination should not be created by default.
* \see setCreateByDefault()
*/
bool createByDefault() const;

/**
* Sets whether the destination should be created by default. For optional parameters,
* a value of false indicates that the destination should not be created by default.
* \see createByDefault()
*/
void setCreateByDefault( bool createByDefault );

private:

bool mSupportsNonFileBasedOutputs = true;
bool mCreateByDefault = true;

};

Expand Down
Loading

0 comments on commit 23a4d60

Please sign in to comment.