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 committed 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.
Expand Up @@ -293,7 +293,7 @@ class QgsProcessingModelAlgorithm : QgsProcessingAlgorithm
%End %End


QList< QgsProcessingModelChildParameterSource > availableSourcesForChild( const QString &childId, const QStringList &parameterTypes = QStringList(), 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 %Docstring
Returns a list of possible sources which can be used for the parameters for a child 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 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
Expand Up @@ -1636,6 +1636,21 @@ class QgsProcessingDestinationParameter : QgsProcessingParameterDefinition
:rtype: str :rtype: str
%End %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
Expand Up @@ -152,7 +152,6 @@
# from .Relief import Relief # from .Relief import Relief
# from .IdwInterpolation import IdwInterpolation # from .IdwInterpolation import IdwInterpolation
# from .TinInterpolation import TinInterpolation # from .TinInterpolation import TinInterpolation
# from .RemoveNullGeometry import RemoveNullGeometry
# from .ExtendLines import ExtendLines # from .ExtendLines import ExtendLines
# from .ExtractSpecificNodes import ExtractSpecificNodes # from .ExtractSpecificNodes import ExtractSpecificNodes
# from .GeometryByExpression import GeometryByExpression # from .GeometryByExpression import GeometryByExpression
Expand Down Expand Up @@ -220,7 +219,6 @@ def getAlgs(self):
# Slope(), Ruggedness(), Hillshade(), # Slope(), Ruggedness(), Hillshade(),
# Relief(), # Relief(),
# IdwInterpolation(), TinInterpolation(), # IdwInterpolation(), TinInterpolation(),
# RemoveNullGeometry(),
# ExtendLines(), ExtractSpecificNodes(), # ExtendLines(), ExtractSpecificNodes(),
# GeometryByExpression(), # GeometryByExpression(),
# PoleOfInaccessibility(), # 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
Expand Up @@ -72,7 +72,7 @@ def __init__(self, parameter, alg):
self.use_temporary = True self.use_temporary = True


if hasattr(self.leText, 'setPlaceholderText'): 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.leText.setPlaceholderText(self.SKIP_OUTPUT)
self.use_temporary = False self.use_temporary = False
elif isinstance(self.parameter, QgsProcessingParameterFeatureSink) \ elif isinstance(self.parameter, QgsProcessingParameterFeatureSink) \
Expand Down
22 changes: 11 additions & 11 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Expand Up @@ -1258,17 +1258,17 @@ tests:
# #TRIANULATION_FILE: # #TRIANULATION_FILE:
# # name: expected/triangulation.gml # # name: expected/triangulation.gml
# # type: vector # # type: vector
#
# - algorithm: qgis:removenullgeometries - algorithm: native:removenullgeometries
# name: Remove null geometries name: Remove null geometries
# params: params:
# INPUT_LAYER: INPUT:
# name: polys.gml name: polys.gml
# type: vector type: vector
# results: results:
# OUTPUT_LAYER: OUTPUT:
# name: expected/remove_null_polys.gml name: expected/remove_null_polys.gml
# type: vector type: vector
# #
- algorithm: native:extractbyexpression - algorithm: native:extractbyexpression
name: Extract by Expression name: Extract by Expression
Expand Down
2 changes: 1 addition & 1 deletion src/core/processing/models/qgsprocessingmodelalgorithm.cpp
Expand Up @@ -566,7 +566,7 @@ QgsExpressionContextScope *QgsProcessingModelAlgorithm::createExpressionContextS
return scope.release(); 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; QgsProcessingModelChildParameterSources sources;


Expand Down
2 changes: 1 addition & 1 deletion src/core/processing/models/qgsprocessingmodelalgorithm.h
Expand Up @@ -296,7 +296,7 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
* sources to those with compatible data types for the parameter/outputs. * sources to those with compatible data types for the parameter/outputs.
*/ */
QList< QgsProcessingModelChildParameterSource > availableSourcesForChild( const QString &childId, const QStringList &parameterTypes = QStringList(), 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. * Definition of a expression context variable available during model execution.
Expand Down
89 changes: 85 additions & 4 deletions src/core/processing/qgsnativealgorithms.cpp
Expand Up @@ -67,6 +67,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
addAlgorithm( new QgsMultipartToSinglepartAlgorithm() ); addAlgorithm( new QgsMultipartToSinglepartAlgorithm() );
addAlgorithm( new QgsSubdivideAlgorithm() ); addAlgorithm( new QgsSubdivideAlgorithm() );
addAlgorithm( new QgsTransformAlgorithm() ); addAlgorithm( new QgsTransformAlgorithm() );
addAlgorithm( new QgsRemoveNullGeometryAlgorithm() );
} }


void QgsCentroidAlgorithm::initAlgorithm( const QVariantMap & ) 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 QgsProcessingParameterExpression( QStringLiteral( "EXPRESSION" ), QObject::tr( "Expression" ), QVariant(), QStringLiteral( "INPUT" ) ) );


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


QString QgsExtractByExpressionAlgorithm::shortHelpString() const 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 QgsProcessingParameterString( QStringLiteral( "VALUE" ), QObject::tr( "Value" ), QVariant(), false, true ) );


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


QString QgsExtractByAttributeAlgorithm::shortHelpString() const QString QgsExtractByAttributeAlgorithm::shortHelpString() const
Expand Down Expand Up @@ -1093,4 +1098,80 @@ QVariantMap QgsExtractByAttributeAlgorithm::processAlgorithm( const QVariantMap
return outputs; 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 ///@endcond
25 changes: 25 additions & 0 deletions src/core/processing/qgsnativealgorithms.h
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 ///@endcond PRIVATE


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


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


Expand All @@ -2932,6 +2934,16 @@ QString QgsProcessingDestinationParameter::generateTemporaryDestination() const
return QgsProcessingUtils::generateTempFilename( name() + '.' + defaultFileExtension() ); 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 ) QgsProcessingParameterVectorDestination::QgsProcessingParameterVectorDestination( const QString &name, const QString &description, QgsProcessing::LayerType type, const QVariant &defaultValue, bool optional )
: QgsProcessingDestinationParameter( name, description, defaultValue, optional ) : QgsProcessingDestinationParameter( name, description, defaultValue, optional )
, mDataType( type ) , mDataType( type )
Expand Down
15 changes: 15 additions & 0 deletions src/core/processing/qgsprocessingparameters.h
Expand Up @@ -1555,9 +1555,24 @@ class CORE_EXPORT QgsProcessingDestinationParameter : public QgsProcessingParame
*/ */
virtual QString generateTemporaryDestination() const; 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: private:


bool mSupportsNonFileBasedOutputs = true; bool mSupportsNonFileBasedOutputs = true;
bool mCreateByDefault = true;


}; };


Expand Down

0 comments on commit 23a4d60

Please sign in to comment.