Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[processing][feature] Port 'offset lines' to c++, support dynamic off…
…set parameter

Adds data defined support for the offset line distance parameter.
  • Loading branch information
nyalldawson committed Jul 27, 2018
1 parent 76c84f1 commit d1d6840
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 133 deletions.
9 changes: 0 additions & 9 deletions python/plugins/processing/algs/help/qgis.yaml
Expand Up @@ -280,15 +280,6 @@ qgis:numberofuniquevaluesinclasses: >

The resulting layer contains the same features as the input layer, but with an additional attribute containing the count of unique values for that class.

qgis:offsetline: >
This algorithm offsets lines by a specified distance. Positive distances will offset lines to the left, and negative distances will offset to the right of lines.

The segments parameter controls the number of line segments to use to approximate a quarter circle when creating rounded offsets.

The join style parameter specifies whether round, miter or beveled joins should be used when offsetting corners in a line.

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

qgis:minimalenclosingcircle: >
This algorithm takes a vector layer and generate a new one with the minimum enclosing circle that covers all the input features.

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

This file was deleted.

2 changes: 0 additions & 2 deletions python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py
Expand Up @@ -86,7 +86,6 @@
from .LinesToPolygons import LinesToPolygons
from .MinimumBoundingGeometry import MinimumBoundingGeometry
from .NearestNeighbourAnalysis import NearestNeighbourAnalysis
from .OffsetLine import OffsetLine
from .Orthogonalize import Orthogonalize
from .PointDistance import PointDistance
from .PointsAlongGeometry import PointsAlongGeometry
Expand Down Expand Up @@ -201,7 +200,6 @@ def getAlgs(self):
LinesToPolygons(),
MinimumBoundingGeometry(),
NearestNeighbourAnalysis(),
OffsetLine(),
Orthogonalize(),
PointDistance(),
PointsAlongGeometry(),
Expand Down
Expand Up @@ -984,7 +984,7 @@ tests:
name: expected/reverse_multiline.gml
type: vector

- algorithm: qgis:offsetline
- algorithm: native:offsetline
name: Offset line positive
params:
DISTANCE: 1.0
Expand All @@ -1002,7 +1002,7 @@ tests:
geometry:
precision: 7

- algorithm: qgis:offsetline
- algorithm: native:offsetline
name: Offset line negative
params:
DISTANCE: -1.0
Expand All @@ -1020,7 +1020,7 @@ tests:
geometry:
precision: 7

- algorithm: qgis:offsetline
- algorithm: native:offsetline
name: Offset line miter
params:
DISTANCE: 1.0
Expand All @@ -1038,7 +1038,7 @@ tests:
geometry:
precision: 7

- algorithm: qgis:offsetline
- algorithm: native:offsetline
name: Offset line bevel
params:
DISTANCE: 1.0
Expand All @@ -1056,7 +1056,7 @@ tests:
geometry:
precision: 7

- algorithm: qgis:offsetline
- algorithm: native:offsetline
name: Offset multilines
params:
DISTANCE: 1.0
Expand Down
1 change: 1 addition & 0 deletions src/analysis/CMakeLists.txt
Expand Up @@ -58,6 +58,7 @@ SET(QGIS_ANALYSIS_SRCS
processing/qgsalgorithmminimumenclosingcircle.cpp
processing/qgsalgorithmmultiparttosinglepart.cpp
processing/qgsalgorithmmultiringconstantbuffer.cpp
processing/qgsalgorithmoffsetlines.cpp
processing/qgsalgorithmorderbyexpression.cpp
processing/qgsalgorithmorientedminimumboundingbox.cpp
processing/qgsalgorithmpackage.cpp
Expand Down
139 changes: 139 additions & 0 deletions src/analysis/processing/qgsalgorithmoffsetlines.cpp
@@ -0,0 +1,139 @@
/***************************************************************************
qgsalgorithmoffsetlines.cpp
---------------------
begin : July 2018
copyright : (C) 2018 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. *
* *
***************************************************************************/

#include "qgsalgorithmoffsetlines.h"

///@cond PRIVATE

QString QgsOffsetLinesAlgorithm::name() const
{
return QStringLiteral( "offsetline" );
}

QString QgsOffsetLinesAlgorithm::displayName() const
{
return QObject::tr( "Offset lines" );
}

QStringList QgsOffsetLinesAlgorithm::tags() const
{
return QObject::tr( "offset,linestring" ).split( ',' );
}

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

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

QString QgsOffsetLinesAlgorithm::outputName() const
{
return QObject::tr( "Offset" );
}

QString QgsOffsetLinesAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm offsets lines by a specified distance. Positive distances will offset lines to the left, and negative distances "
"will offset to the right of lines.\n\n"
"The segments parameter controls the number of line segments to use to approximate a quarter circle when creating rounded offsets.\n\n"
"The join style parameter specifies whether round, miter or beveled joins should be used when offsetting corners in a line.\n\n"
"The miter limit parameter is only applicable for miter join styles, and controls the maximum distance from the offset curve to "
"use when creating a mitered join." );
}

QString QgsOffsetLinesAlgorithm::shortDescription() const
{
return QObject::tr( "Offsets lines by a specified distance." );
}

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

void QgsOffsetLinesAlgorithm::initParameters( const QVariantMap & )
{
std::unique_ptr< QgsProcessingParameterDistance > offset = qgis::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "DISTANCE" ),
QObject::tr( "Distance" ),
10.0, QStringLiteral( "INPUT" ) );
offset->setIsDynamic( true );
offset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DISTANCE" ), QObject::tr( "Distance" ), QgsPropertyDefinition::Double ) );
offset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
addParameter( offset.release() );

auto segmentParam = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "SEGMENTS" ), QObject::tr( "Segments" ), QgsProcessingParameterNumber::Integer, 8, false, 1 );
addParameter( segmentParam.release() );

auto joinStyleParam = qgis::make_unique< QgsProcessingParameterEnum>( QStringLiteral( "JOIN_STYLE" ), QObject::tr( "Join style" ), QStringList() << QObject::tr( "Round" ) << QObject::tr( "Miter" ) << QObject::tr( "Bevel" ), false, 0 );
addParameter( joinStyleParam.release() );

auto miterLimitParam = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MITER_LIMIT" ), QObject::tr( "Miter limit" ), QgsProcessingParameterNumber::Double, 2, false, 1 );
addParameter( miterLimitParam.release() );
}

QList<int> QgsOffsetLinesAlgorithm::inputLayerTypes() const
{
return QList< int >() << QgsProcessing::TypeVectorLine;
}

QgsProcessing::SourceType QgsOffsetLinesAlgorithm::outputLayerType() const
{
return QgsProcessing::TypeVectorLine;
}

bool QgsOffsetLinesAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
{
mOffset = parameterAsDouble( parameters, QStringLiteral( "DISTANCE" ), context );
mDynamicOffset = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DISTANCE" ) );
if ( mDynamicOffset )
mOffsetProperty = parameters.value( QStringLiteral( "DISTANCE" ) ).value< QgsProperty >();

mSegments = parameterAsInt( parameters, QStringLiteral( "SEGMENTS" ), context );
mJoinStyle = static_cast< QgsGeometry::JoinStyle>( 1 + parameterAsInt( parameters, QStringLiteral( "JOIN_STYLE" ), context ) );
mMiterLimit = parameterAsDouble( parameters, QStringLiteral( "MITER_LIMIT" ), context );

return true;
}

QgsFeatureList QgsOffsetLinesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
{
if ( feature.hasGeometry() )
{
QgsFeature f = feature;
const QgsGeometry geometry = feature.geometry();

double offset = mOffset;
if ( mDynamicOffset )
offset = mOffsetProperty.valueAsDouble( context.expressionContext(), offset );

const QgsGeometry offsetGeometry = geometry.offsetCurve( offset, mSegments, mJoinStyle, mMiterLimit );
f.setGeometry( offsetGeometry );
return QgsFeatureList() << f;
}
else
{
return QgsFeatureList() << feature;
}
}

///@endcond


0 comments on commit d1d6840

Please sign in to comment.