Skip to content

Commit

Permalink
[processing] port set M value algorithm 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 5324d7f commit 9411d96
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 114 deletions.
5 changes: 0 additions & 5 deletions python/plugins/processing/algs/help/qgis.yaml
Expand Up @@ -447,11 +447,6 @@ qgis:selectbyexpression: >

For more information about expressions see the <a href ="{qgisdocs}/user_manual/working_with_vector/expression.html">user manual</a>

qgis:setmvalue: >
This algorithm sets the M value for geometries in a layer.

If M values already exist in the layer, they will be overwritten with the new value. If no M values exist, the geometry will be upgraded to include M values and the specified value used as the initial M value for all geometries.

qgis:setstyleforrasterlayer: >
This algorithm sets the style of a raster layer. The style must be defined in a QML file.

Expand Down
2 changes: 0 additions & 2 deletions python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py
Expand Up @@ -94,7 +94,6 @@
from .Relief import Relief
from .SelectByAttribute import SelectByAttribute
from .SelectByExpression import SelectByExpression
from .SetMValue import SetMValue
from .SetRasterStyle import SetRasterStyle
from .SetVectorStyle import SetVectorStyle
from .SetZValue import SetZValue
Expand Down Expand Up @@ -195,7 +194,6 @@ def getAlgs(self):
Relief(),
SelectByAttribute(),
SelectByExpression(),
SetMValue(),
SetRasterStyle(),
SetVectorStyle(),
SetZValue(),
Expand Down
106 changes: 0 additions & 106 deletions python/plugins/processing/algs/qgis/SetMValue.py

This file was deleted.

Expand Up @@ -865,7 +865,7 @@ tests:
name: expected/multiline_boundary.gml
type: vector

- algorithm: qgis:setmvalue
- algorithm: native:setmvalue
name: Set M Value
params:
INPUT:
Expand Down
1 change: 1 addition & 0 deletions src/analysis/CMakeLists.txt
Expand Up @@ -111,6 +111,7 @@ SET(QGIS_ANALYSIS_SRCS
processing/qgsalgorithmsegmentize.cpp
processing/qgsalgorithmserviceareafromlayer.cpp
processing/qgsalgorithmserviceareafrompoint.cpp
processing/qgsalgorithmsetmvalue.cpp
processing/qgsalgorithmshortestpathlayertopoint.cpp
processing/qgsalgorithmshortestpathpointtolayer.cpp
processing/qgsalgorithmshortestpathpointtopoint.cpp
Expand Down
128 changes: 128 additions & 0 deletions src/analysis/processing/qgsalgorithmsetmvalue.cpp
@@ -0,0 +1,128 @@
/***************************************************************************
qgsalgorithmsetmvalue.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 "qgsalgorithmsetmvalue.h"
#include "qgsvectorlayer.h"

///@cond PRIVATE

QString QgsSetMValueAlgorithm::name() const
{
return QStringLiteral( "setmvalue" );
}

QString QgsSetMValueAlgorithm::displayName() const
{
return QObject::tr( "Set M value" );
}

QStringList QgsSetMValueAlgorithm::tags() const
{
return QObject::tr( "set,add,m,measure,values" ).split( ',' );
}

QString QgsSetMValueAlgorithm::group() const
{
return QObject::tr( "Vector geometry" );
}

QString QgsSetMValueAlgorithm::groupId() const
{
return QStringLiteral( "vectorgeometry" );
}

QString QgsSetMValueAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm sets the M value for geometries in a layer.\n\n"
"If M values already exist in the layer, they will be overwritten "
"with the new value. If no M values exist, the geometry will be "
"upgraded to include M values and the specified value used as "
"the initial M value for all geometries." );
}

QString QgsSetMValueAlgorithm::outputName() const
{
return QObject::tr( "M Added" );
}

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

bool QgsSetMValueAlgorithm::supportInPlaceEdit( const QgsMapLayer *l ) const
{
const QgsVectorLayer *layer = qobject_cast< const QgsVectorLayer * >( l );
if ( !layer )
return false;

return QgsProcessingFeatureBasedAlgorithm::supportInPlaceEdit( l ) && QgsWkbTypes::hasM( layer->wkbType() );
}

QgsProcessingFeatureSource::Flag QgsSetMValueAlgorithm::sourceFlags() const
{
return QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks;
}

QgsWkbTypes::Type QgsSetMValueAlgorithm::outputWkbType( QgsWkbTypes::Type type ) const
{
return QgsWkbTypes::addM( type );
}

void QgsSetMValueAlgorithm::initParameters( const QVariantMap & )
{
auto mValueParam = qgis::make_unique < QgsProcessingParameterNumber >( QStringLiteral( "M_VALUE" ), QObject::tr( "M Value" ), QgsProcessingParameterNumber::Double, 0.0 );
mValueParam->setIsDynamic( true );
mValueParam->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "M_VALUE" ), QObject::tr( "M Value" ), QgsPropertyDefinition::Double ) );
mValueParam->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
addParameter( mValueParam.release() );
}

bool QgsSetMValueAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
{
mMValue = parameterAsDouble( parameters, QStringLiteral( "M_VALUE" ), context );
mDynamicMValue = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "M_VALUE" ) );
if ( mDynamicMValue )
mMValueProperty = parameters.value( QStringLiteral( "M_VALUE" ) ).value< QgsProperty >();

return true;
}

QgsFeatureList QgsSetMValueAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
{
QgsFeature f = feature;

if ( f.hasGeometry() )
{
std::unique_ptr< QgsAbstractGeometry > newGeometry( f.geometry().constGet()->clone() );
// addMValue won't alter existing M values, so drop them first
if ( QgsWkbTypes::hasM( newGeometry->wkbType() ) )
newGeometry->dropMValue();

double m = mMValue;
if ( mDynamicMValue )
m = mMValueProperty.valueAsDouble( context.expressionContext(), m );

newGeometry->addMValue( m );

f.setGeometry( QgsGeometry( std::move( newGeometry ) ) );
}

return QgsFeatureList() << f;
}

///@endcond
65 changes: 65 additions & 0 deletions src/analysis/processing/qgsalgorithmsetmvalue.h
@@ -0,0 +1,65 @@
/***************************************************************************
qgsalgorithmsetmvalue.h
---------------------
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. *
* *
***************************************************************************/

#ifndef QGSALGORITHMSETMVALUE_H
#define QGSALGORITHMSETMVALUE_H

#define SIP_NO_FILE

#include "qgis_sip.h"
#include "qgsprocessingalgorithm.h"

///@cond PRIVATE

/**
* Native set M value algorithm.
*/
class QgsSetMValueAlgorithm : public QgsProcessingFeatureBasedAlgorithm
{

public:

QgsSetMValueAlgorithm() = default;
QString name() const override;
QString displayName() const override;
QStringList tags() const override;
QString group() const override;
QString groupId() const override;
QString shortHelpString() const override;
QgsSetMValueAlgorithm *createInstance() const override SIP_FACTORY;

protected:

void initParameters( const QVariantMap &configuration = QVariantMap() ) override;
QString outputName() const override;
QgsWkbTypes::Type outputWkbType( QgsWkbTypes::Type inputWkbType ) const override;
QgsProcessingFeatureSource::Flag sourceFlags() const override;
bool supportInPlaceEdit( const QgsMapLayer *l ) const override;

bool prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
QgsFeatureList processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;

private:

double mMValue = 0.0;
bool mDynamicMValue = false;
QgsProperty mMValueProperty;
};

///@endcond PRIVATE

#endif // QGSALGORITHMSETMVALUE_H
2 changes: 2 additions & 0 deletions src/analysis/processing/qgsnativealgorithms.cpp
Expand Up @@ -105,6 +105,7 @@
#include "qgsalgorithmsegmentize.h"
#include "qgsalgorithmserviceareafromlayer.h"
#include "qgsalgorithmserviceareafrompoint.h"
#include "qgsalgorithmsetmvalue.h"
#include "qgsalgorithmshortestpathlayertopoint.h"
#include "qgsalgorithmshortestpathpointtolayer.h"
#include "qgsalgorithmshortestpathpointtopoint.h"
Expand Down Expand Up @@ -279,6 +280,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
addAlgorithm( new QgsSelectByLocationAlgorithm() );
addAlgorithm( new QgsServiceAreaFromLayerAlgorithm() );
addAlgorithm( new QgsServiceAreaFromPointAlgorithm() );
addAlgorithm( new QgsSetMValueAlgorithm() );
addAlgorithm( new QgsShortestPathLayerToPointAlgorithm() );
addAlgorithm( new QgsShortestPathPointToLayerAlgorithm() );
addAlgorithm( new QgsShortestPathPointToPointAlgorithm() );
Expand Down

0 comments on commit 9411d96

Please sign in to comment.