Skip to content

Commit

Permalink
[processing] port orthogonalize 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 aed17ba commit 9289d53
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 101 deletions.
7 changes: 0 additions & 7 deletions python/plugins/processing/algs/help/qgis.yaml
Expand Up @@ -289,13 +289,6 @@ qgis:minimalenclosingcircle: >

As an alternative, the output layer can contain not just a single circle, but one for each input feature, representing the minimum enclosing circle that covers each of them.

qgis:orthogonalize: >
This algorithm takes a line or polygon layer and attempts to orthogonalize all the geometries in the layer. This process shifts the nodes in the geometries to try to make every angle in the geometry either a right angle or a straight line.

The angle tolerance parameter is used to specify the maximum deviation from a right angle or straight line a node can have for it to be adjusted. Smaller tolerances mean that only nodes which are already closer to right angles will be adjusted, and larger tolerances mean that nodes which deviate further from right angles will also be adjusted.

The algorithm is iterative. Setting a larger number for the maximum iterations will result in a more orthogonal geometry at the cost of extra processing time.

qgis:pointsalonglines: >
Creates points at regular intervals along line or polygon geometries. Created points will have new attributes added for the distance along the geometry and the angle of the line at the point.

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

This file was deleted.

2 changes: 0 additions & 2 deletions python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py
Expand Up @@ -65,7 +65,6 @@
from .MeanAndStdDevPlot import MeanAndStdDevPlot
from .MinimumBoundingGeometry import MinimumBoundingGeometry
from .NearestNeighbourAnalysis import NearestNeighbourAnalysis
from .Orthogonalize import Orthogonalize
from .PointDistance import PointDistance
from .PointsDisplacement import PointsDisplacement
from .PointsFromLines import PointsFromLines
Expand Down Expand Up @@ -168,7 +167,6 @@ def getAlgs(self):
MeanAndStdDevPlot(),
MinimumBoundingGeometry(),
NearestNeighbourAnalysis(),
Orthogonalize(),
PointDistance(),
PointsDisplacement(),
PointsFromLines(),
Expand Down
Expand Up @@ -1107,7 +1107,7 @@ tests:
geometry:
precision: 7

- algorithm: qgis:orthogonalize
- algorithm: native:orthogonalize
name: Orthogonalize polys
params:
INPUT:
Expand All @@ -1121,7 +1121,7 @@ tests:
geometry:
precision: 7

- algorithm: qgis:orthogonalize
- algorithm: native:orthogonalize
name: Orthogonalize lines
params:
INPUT:
Expand Down
1 change: 1 addition & 0 deletions src/analysis/CMakeLists.txt
Expand Up @@ -83,6 +83,7 @@ SET(QGIS_ANALYSIS_SRCS
processing/qgsalgorithmoffsetlines.cpp
processing/qgsalgorithmorderbyexpression.cpp
processing/qgsalgorithmorientedminimumboundingbox.cpp
processing/qgsalgorithmorthogonalize.cpp
processing/qgsalgorithmpackage.cpp
processing/qgsalgorithmarrayoffsetlines.cpp
processing/qgsalgorithmpolygonstolines.cpp
Expand Down
118 changes: 118 additions & 0 deletions src/analysis/processing/qgsalgorithmorthogonalize.cpp
@@ -0,0 +1,118 @@
/***************************************************************************
qgsalgorithmorthogonalize.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 "qgsalgorithmorthogonalize.h"
#include "qgsprocessing.h"

///@cond PRIVATE

QString QgsOrthogonalizeAlgorithm::name() const
{
return QStringLiteral( "orthogonalize" );
}

QString QgsOrthogonalizeAlgorithm::displayName() const
{
return QObject::tr( "Orthogonalize" );
}

QStringList QgsOrthogonalizeAlgorithm::tags() const
{
return QObject::tr( "rectangle,perpendicular,right,angles,square,quadrilateralise" ).split( ',' );
}

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

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

QString QgsOrthogonalizeAlgorithm::shortHelpString() const
{
return QObject::tr( "Takes a line or polygon layer and attempts to orthogonalize "
"all the geometries in the layer. This process shifts the nodes "
"in the geometries to try to make every angle in the geometry "
"either a right angle or a straight line.\n\n"
"The angle tolerance parameter is used to specify the maximum "
"deviation from a right angle or straight line a node can have "
"for it to be adjusted. Smaller tolerances mean that only nodes "
"which are already closer to right angles will be adjusted, and "
"larger tolerances mean that nodes which deviate further from "
"right angles will also be adjusted.\n\n"
"The algorithm is iterative. Setting a larger number for the maximum "
"iterations will result in a more orthogonal geometry at the cost of "
"extra processing time." );
}

QString QgsOrthogonalizeAlgorithm::outputName() const
{
return QObject::tr( "Orthogonalized" );
}

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

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

void QgsOrthogonalizeAlgorithm::initParameters( const QVariantMap & )
{
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "ANGLE_TOLERANCE" ), QObject::tr( "Maximum angle tolerance (degrees)" ),
QgsProcessingParameterNumber::Double, 15.0, false, 0.0, 45.0 ) );

std::unique_ptr< QgsProcessingParameterNumber> maxIterations = qgis::make_unique< QgsProcessingParameterNumber >(
QStringLiteral( "MAX_ITERATIONS" ),
QObject::tr( "Maximum algorithm iterations" ),
QgsProcessingParameterNumber::Integer,
1000, false, 1, 10000 );
maxIterations->setFlags( maxIterations->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
addParameter( maxIterations.release() );
}

bool QgsOrthogonalizeAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
{
mAngleTolerance = parameterAsDouble( parameters, QStringLiteral( "ANGLE_TOLERANCE" ), context );
mMaxIterations = parameterAsDouble( parameters, QStringLiteral( "MAX_ITERATIONS" ), context );

return true;
}

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

if ( f.hasGeometry() )
{
QgsGeometry outputGeometry = f.geometry().orthogonalize( 1.0e-8, mMaxIterations, mAngleTolerance );
if ( outputGeometry.isNull() )
throw QgsProcessingException( QObject::tr( "Error orthogonalizing geometry" ) );

f.setGeometry( outputGeometry );
}

return QgsFeatureList() << f;
}

///@endcond
64 changes: 64 additions & 0 deletions src/analysis/processing/qgsalgorithmorthogonalize.h
@@ -0,0 +1,64 @@
/***************************************************************************
qgsalgorithmorthogonalize.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 QGSALGORITHMORTHOGONALIZE_H
#define QGSALGORITHMORTHOGONALIZE_H

#define SIP_NO_FILE

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

///@cond PRIVATE

/**
* Native orthogonalize algorithm.
*/
class QgsOrthogonalizeAlgorithm : public QgsProcessingFeatureBasedAlgorithm
{

public:

QgsOrthogonalizeAlgorithm() = 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;
QList<int> inputLayerTypes() const override;
QgsOrthogonalizeAlgorithm *createInstance() const override SIP_FACTORY;
void initParameters( const QVariantMap &configuration = QVariantMap() ) override;

protected:

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

private:

double mMaxIterations = 0;
double mAngleTolerance = 0;

};

///@endcond PRIVATE

#endif // QGSALGORITHMORTHOGONALIZE_H


2 changes: 2 additions & 0 deletions src/analysis/processing/qgsnativealgorithms.cpp
Expand Up @@ -78,6 +78,7 @@
#include "qgsalgorithmoffsetlines.h"
#include "qgsalgorithmorderbyexpression.h"
#include "qgsalgorithmorientedminimumboundingbox.h"
#include "qgsalgorithmorthogonalize.h"
#include "qgsalgorithmpackage.h"
#include "qgsalgorithmarrayoffsetlines.h"
#include "qgsalgorithmpointonsurface.h"
Expand Down Expand Up @@ -244,6 +245,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
addAlgorithm( new QgsOffsetLinesAlgorithm() );
addAlgorithm( new QgsOrderByExpressionAlgorithm() );
addAlgorithm( new QgsOrientedMinimumBoundingBoxAlgorithm() );
addAlgorithm( new QgsOrthogonalizeAlgorithm() );
addAlgorithm( new QgsPackageAlgorithm() );
addAlgorithm( new QgsCreateArrayOffsetLinesAlgorithm() );
addAlgorithm( new QgsPointOnSurfaceAlgorithm() );
Expand Down

0 comments on commit 9289d53

Please sign in to comment.