Port simplify geometries to c++

This commit is contained in:
Nyall Dawson 2017-09-14 08:47:21 +10:00
parent 8e8f3edc55
commit d96a3f4dd4
6 changed files with 96 additions and 107 deletions

View File

@ -528,11 +528,6 @@ qgis:setzvalue: >
If Z values already exist in the layer, they will be overwritten with the new value. If no Z values exist, the geometry will be upgraded to include Z values and the specified value used as the initial Z value for all geometries.
qgis:simplifygeometries: >
This algorithm simplifies 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 lower number of vertices.
The algorithm gives a choice of simplification methods, including distance based (the "Douglas-Peucker" algorithm), area based ("Visvalingam" algorithm) and snapping geometries to grid.
qgis:singlesidedbuffer: >
This algorithm buffers lines by a specified distance on one side of the line only.

View File

@ -141,7 +141,6 @@ from .SetZValue import SetZValue
from .ShortestPathLayerToPoint import ShortestPathLayerToPoint
from .ShortestPathPointToLayer import ShortestPathPointToLayer
from .ShortestPathPointToPoint import ShortestPathPointToPoint
from .SimplifyGeometries import SimplifyGeometries
from .SingleSidedBuffer import SingleSidedBuffer
from .Slope import Slope
from .SnapGeometries import SnapGeometriesToLayer
@ -279,7 +278,6 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
ShortestPathLayerToPoint(),
ShortestPathPointToLayer(),
ShortestPathPointToPoint(),
SimplifyGeometries(),
SingleSidedBuffer(),
Slope(),
SnapGeometriesToLayer(),

View File

@ -1,96 +0,0 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
SimplifyGeometries.py
---------------------
Date : August 2012
Copyright : (C) 2012 by Victor Olaya
Email : volayaf 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. *
* *
***************************************************************************
"""
__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsMapToPixelSimplifier,
QgsProcessingParameterEnum,
QgsProcessingParameterNumber)
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
class SimplifyGeometries(QgisFeatureBasedAlgorithm):
TOLERANCE = 'TOLERANCE'
METHOD = 'METHOD'
def icon(self):
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'simplify.png'))
def group(self):
return self.tr('Vector geometry')
def __init__(self):
super().__init__()
self.tolerance = None
self.method = None
self.simplifier = None
def initParameters(self, config=None):
self.methods = [self.tr('Distance (Douglas-Peucker)'),
'Snap to grid',
'Area (Visvalingam)']
self.addParameter(QgsProcessingParameterEnum(
self.METHOD,
self.tr('Simplification method'),
self.methods, defaultValue=0))
self.addParameter(QgsProcessingParameterNumber(self.TOLERANCE,
self.tr('Tolerance'), minValue=0.0, maxValue=10000000.0, defaultValue=1.0))
def name(self):
return 'simplifygeometries'
def displayName(self):
return self.tr('Simplify geometries')
def outputName(self):
return self.tr('Simplified')
def prepareAlgorithm(self, parameters, context, feedback):
self.tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)
self.method = self.parameterAsEnum(parameters, self.METHOD, context)
if self.method != 0:
self.simplifier = QgsMapToPixelSimplifier(QgsMapToPixelSimplifier.SimplifyGeometry, self.tolerance, self.method)
return True
def processFeature(self, feature, feedback):
if feature.hasGeometry():
input_geometry = feature.geometry()
if self.method == 0: # distance
output_geometry = input_geometry.simplify(self.tolerance)
else:
output_geometry = self.simplifier.simplify(input_geometry)
feature.setGeometry(output_geometry)
return feature

View File

@ -1209,7 +1209,7 @@ tests:
name: expected/extract_nodes_lines.gml
type: vector
- algorithm: qgis:simplifygeometries
- algorithm: native:simplifygeometries
name: Simplify (lines)
params:
INPUT:
@ -1221,7 +1221,7 @@ tests:
name: expected/simplify_lines.gml
type: vector
- algorithm: qgis:simplifygeometries
- algorithm: native:simplifygeometries
name: Simplify (multilines)
params:
INPUT:
@ -1233,7 +1233,7 @@ tests:
name: expected/simplify_multilines.gml
type: vector
- algorithm: qgis:simplifygeometries
- algorithm: native:simplifygeometries
name: Simplify (visval)
params:
INPUT:
@ -1249,7 +1249,7 @@ tests:
geometry:
precision: 7
- algorithm: qgis:simplifygeometries
- algorithm: native:simplifygeometries
name: Simplify (grid)
params:
INPUT:

View File

@ -81,6 +81,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
addAlgorithm( new QgsFixGeometriesAlgorithm() );
addAlgorithm( new QgsMergeLinesAlgorithm() );
addAlgorithm( new QgsSmoothAlgorithm() );
addAlgorithm( new QgsSimplifyAlgorithm() );
}
void QgsCentroidAlgorithm::initAlgorithm( const QVariantMap & )
@ -1751,5 +1752,66 @@ QgsFeature QgsSmoothAlgorithm::processFeature( const QgsFeature &feature, QgsPro
return f;
}
QString QgsSimplifyAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm simplifies 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 lower number of vertices.\n\n"
"The algorithm gives a choice of simplification methods, including distance based "
"(the \"Douglas-Peucker\" algorithm), area based (\"Visvalingam\" algorithm) and snapping geometries to a grid." );
}
QgsSimplifyAlgorithm *QgsSimplifyAlgorithm::createInstance() const
{
return new QgsSimplifyAlgorithm();
}
void QgsSimplifyAlgorithm::initParameters( const QVariantMap & )
{
QStringList methods;
methods << QObject::tr( "Distance (Douglas-Peucker)" )
<< QObject::tr( "Snap to grid" )
<< QObject::tr( "Area (Visvalingam)" );
addParameter( new QgsProcessingParameterEnum(
QStringLiteral( "METHOD" ),
QObject::tr( "Simplification method" ),
methods, false, 0 ) );
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "TOLERANCE" ),
QObject::tr( "Tolerance" ), QgsProcessingParameterNumber::Double,
1.0, false, 0, 10000000.0 ) );
}
bool QgsSimplifyAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
{
mTolerance = parameterAsDouble( parameters, QStringLiteral( "TOLERANCE" ), context );
mMethod = static_cast< QgsMapToPixelSimplifier::SimplifyAlgorithm >( parameterAsEnum( parameters, QStringLiteral( "METHOD" ), context ) );
if ( mMethod != QgsMapToPixelSimplifier::Distance )
mSimplifier.reset( new QgsMapToPixelSimplifier( QgsMapToPixelSimplifier::SimplifyGeometry, mTolerance, mMethod ) );
return true;
}
QgsFeature QgsSimplifyAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingFeedback * )
{
QgsFeature f = feature;
if ( f.hasGeometry() )
{
QgsGeometry inputGeometry = f.geometry();
QgsGeometry outputGeometry;
if ( mMethod == QgsMapToPixelSimplifier::Distance )
{
outputGeometry = inputGeometry.simplify( mTolerance );
}
else
{
outputGeometry = mSimplifier->simplify( inputGeometry );
}
f.setGeometry( outputGeometry );
}
return f;
}
///@endcond

View File

@ -24,6 +24,7 @@
#include "qgis.h"
#include "qgsprocessingalgorithm.h"
#include "qgsprocessingprovider.h"
#include "qgsmaptopixelgeometrysimplifier.h"
///@cond PRIVATE
@ -632,6 +633,35 @@ class QgsSmoothAlgorithm : public QgsProcessingFeatureBasedAlgorithm
double mMaxAngle = 0;
};
/**
* Native simplify algorithm.
*/
class QgsSimplifyAlgorithm : public QgsProcessingFeatureBasedAlgorithm
{
public:
QgsSimplifyAlgorithm() = default;
QString name() const override { return QStringLiteral( "simplifygeometries" ); }
QString displayName() const override { return QObject::tr( "Simplify geometries" ); }
virtual QStringList tags() const override { return QObject::tr( "simplify,generalize,douglas,peucker,visvalingam" ).split( ',' ); }
QString group() const override { return QObject::tr( "Vector geometry" ); }
QString shortHelpString() const override;
QgsSimplifyAlgorithm *createInstance() const override SIP_FACTORY;
void initParameters( const QVariantMap &configuration = QVariantMap() ) override;
protected:
QString outputName() const override { return QObject::tr( "Simplified" ); }
bool prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
QgsFeature processFeature( const QgsFeature &feature, QgsProcessingFeedback *feedback ) override;
private:
double mTolerance = 1.0;
QgsMapToPixelSimplifier::SimplifyAlgorithm mMethod = QgsMapToPixelSimplifier::Distance;
std::unique_ptr< QgsMapToPixelSimplifier > mSimplifier;
};
///@endcond PRIVATE
#endif // QGSNATIVEALGORITHMS_H