Skip to content

Commit

Permalink
Port merge lines and smooth to c++
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Sep 13, 2017
1 parent 7c5521e commit 8e8f3ed
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 180 deletions.
14 changes: 0 additions & 14 deletions python/plugins/processing/algs/help/qgis.yaml
Expand Up @@ -302,11 +302,6 @@ qgis:meancoordinates: >

If an attribute is selected in the <Unique ID field> parameters, features will be grouped according to values in this field. Instead of a single point with the center of mass of the whole layer, the output layer will contain a center of mass for the features in each category.

qgis:mergelines: >
This algorithm joins all connected parts of MultiLineString geometries into single LineString geometries.

If any parts of the input MultiLineString geometries are not connected, the resultant geometry will be a MultiLineString containing any lines which could be merged and any non-connected line parts.

qgis:mergevectorlayers: >
This algorithm combines multiple vector layers of the same geometry type into a single one.

Expand Down Expand Up @@ -547,15 +542,6 @@ qgis:singlesidedbuffer: >

The miter limit parameter is only applicable for miter join styles, and controls the maximum distance from the buffer to use when creating a mitered join.

qgis:smoothgeometry: >
This algorithm smooths the geometries in a line or polygon layer. It creates a new layer with the same features as the ones in the input layer, but with geometries containing a higher number of vertices and corners in the geometries smoothed out.

The iterations parameter dictates how many smoothing iterations will be applied to each geometry. A higher number of iterations results in smoother geometries with the cost of greater number of nodes in the geometries.

The offset parameter controls how "tightly" the smoothed geometries follow the original geometries. Smaller values results in a tighter fit, and larger values will create a looser fit.

The maximum angle parameter can be used to prevent smoothing of nodes with large angles. Any node where the angle of the segments to either side is larger than this will not be smoothed. For example, setting the maximum angle to 90 degrees or lower would preserve right angles in the geometry.

qgis:snapgeometries: >
This algorithm snaps the geometries in a layer. Snapping can be done either to the geometries from another layer, or to geometries within the same layer.

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

This file was deleted.

4 changes: 0 additions & 4 deletions python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Expand Up @@ -95,7 +95,6 @@
from .LinesToPolygons import LinesToPolygons
from .MeanCoords import MeanCoords
from .Merge import Merge
from .MergeLines import MergeLines
from .MinimumBoundingGeometry import MinimumBoundingGeometry
from .NearestNeighbourAnalysis import NearestNeighbourAnalysis
from .OffsetLine import OffsetLine
Expand Down Expand Up @@ -145,7 +144,6 @@
from .SimplifyGeometries import SimplifyGeometries
from .SingleSidedBuffer import SingleSidedBuffer
from .Slope import Slope
from .Smooth import Smooth
from .SnapGeometries import SnapGeometriesToLayer
from .SpatialiteExecuteSQL import SpatialiteExecuteSQL
from .SpatialIndex import SpatialIndex
Expand Down Expand Up @@ -235,7 +233,6 @@ def getAlgs(self):
LinesToPolygons(),
MeanCoords(),
Merge(),
MergeLines(),
MinimumBoundingGeometry(),
NearestNeighbourAnalysis(),
OffsetLine(),
Expand Down Expand Up @@ -285,7 +282,6 @@ def getAlgs(self):
SimplifyGeometries(),
SingleSidedBuffer(),
Slope(),
Smooth(),
SnapGeometriesToLayer(),
SpatialiteExecuteSQL(),
SpatialIndex(),
Expand Down
80 changes: 0 additions & 80 deletions python/plugins/processing/algs/qgis/Smooth.py

This file was deleted.

Expand Up @@ -588,7 +588,7 @@ tests:
geometry:
precision: 7

- algorithm: qgis:mergelines
- algorithm: native:mergelines
name: Merge lines algorithm
params:
INPUT:
Expand Down Expand Up @@ -1265,7 +1265,7 @@ tests:
geometry:
precision: 7

- algorithm: qgis:smoothgeometry
- algorithm: native:smoothgeometry
name: Smooth (lines)
params:
INPUT:
Expand All @@ -1279,7 +1279,7 @@ tests:
name: expected/smoothed_lines.gml
type: vector

- algorithm: qgis:smoothgeometry
- algorithm: native:smoothgeometry
name: Smooth (lines, with max angle)
params:
INPUT:
Expand Down
87 changes: 86 additions & 1 deletion src/core/processing/qgsnativealgorithms.cpp
Expand Up @@ -79,6 +79,8 @@ void QgsNativeAlgorithms::loadAlgorithms()
addAlgorithm( new QgsSelectByLocationAlgorithm() );
addAlgorithm( new QgsExtractByLocationAlgorithm() );
addAlgorithm( new QgsFixGeometriesAlgorithm() );
addAlgorithm( new QgsMergeLinesAlgorithm() );
addAlgorithm( new QgsSmoothAlgorithm() );
}

void QgsCentroidAlgorithm::initAlgorithm( const QVariantMap & )
Expand Down Expand Up @@ -1665,6 +1667,89 @@ QgsFeature QgsFixGeometriesAlgorithm::processFeature( const QgsFeature &feature,
return outputFeature;
}

///@endcond

QString QgsMergeLinesAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm joins all connected parts of MultiLineString geometries into single LineString geometries.\n\n"
"If any parts of the input MultiLineString geometries are not connected, the resultant "
"geometry will be a MultiLineString containing any lines which could be merged and any non-connected line parts." );
}

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

QgsFeature QgsMergeLinesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingFeedback *feedback )
{
if ( !feature.hasGeometry() )
return feature;

QgsFeature out = feature;
QgsGeometry outputGeometry = feature.geometry().mergeLines();
if ( !outputGeometry )
feedback->reportError( QObject::tr( "Error merging lines for feature %1" ).arg( feature.id() ) );

out.setGeometry( outputGeometry );
return out;
}

QString QgsSmoothAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm smooths the geometries in a line or polygon layer. It creates a new layer with the "
"same features as the ones in the input layer, but with geometries containing a higher number of vertices "
"and corners in the geometries smoothed out.\n\n"
"The iterations parameter dictates how many smoothing iterations will be applied to each "
"geometry. A higher number of iterations results in smoother geometries with the cost of "
"greater number of nodes in the geometries.\n\n"
"The offset parameter controls how \"tightly\" the smoothed geometries follow the original geometries. "
"Smaller values results in a tighter fit, and larger values will create a looser fit.\n\n"
"The maximum angle parameter can be used to prevent smoothing of "
"nodes with large angles. Any node where the angle of the segments to either "
"side is larger than this will not be smoothed. For example, setting the maximum "
"angle to 90 degrees or lower would preserve right angles in the geometry." );
}

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

void QgsSmoothAlgorithm::initParameters( const QVariantMap & )
{
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "ITERATIONS" ),
QObject::tr( "Iterations" ), QgsProcessingParameterNumber::Integer,
1, false, 1, 10 ) );
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "OFFSET" ),
QObject::tr( "Offset" ), QgsProcessingParameterNumber::Double,
0.25, false, 0.0, 0.5 ) );
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "MAX_ANGLE" ),
QObject::tr( "Maximum node angle to smooth" ), QgsProcessingParameterNumber::Double,
180.0, false, 0.0, 180.0 ) );
}

bool QgsSmoothAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
{
mIterations = parameterAsInt( parameters, QStringLiteral( "ITERATIONS" ), context );
mOffset = parameterAsDouble( parameters, QStringLiteral( "OFFSET" ), context );
mMaxAngle = parameterAsDouble( parameters, QStringLiteral( "MAX_ANGLE" ), context );
return true;
}

QgsFeature QgsSmoothAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingFeedback *feedback )
{
QgsFeature f = feature;
if ( f.hasGeometry() )
{
QgsGeometry outputGeometry = f.geometry().smooth( mIterations, mOffset, -1, mMaxAngle );
if ( !outputGeometry )
{
feedback->reportError( QObject::tr( "Error smoothing geometry %1" ).arg( feature.id() ) );
}
f.setGeometry( outputGeometry );
}
return f;
}

///@endcond

1 comment on commit 8e8f3ed

@nirvn
Copy link
Contributor

@nirvn nirvn commented on 8e8f3ed Sep 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Have you done some benchmarks to guesstimate the win of moving to c++?

I was thinking of writing a blog post comparing execution speed of 2.18 algorithms vs 3.0.

Please sign in to comment.