1 /***************************************************************************
2                          qgsalgorithmsimplify.cpp
3                          ---------------------
4     begin                : April 2017
5     copyright            : (C) 2017 by Nyall Dawson
6     email                : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "qgsalgorithmsimplify.h"
19 
20 ///@cond PRIVATE
21 
name() const22 QString QgsSimplifyAlgorithm::name() const
23 {
24   return QStringLiteral( "simplifygeometries" );
25 }
26 
displayName() const27 QString QgsSimplifyAlgorithm::displayName() const
28 {
29   return QObject::tr( "Simplify" );
30 }
31 
tags() const32 QStringList QgsSimplifyAlgorithm::tags() const
33 {
34   return QObject::tr( "simplify,generalize,douglas,peucker,visvalingam" ).split( ',' );
35 }
36 
group() const37 QString QgsSimplifyAlgorithm::group() const
38 {
39   return QObject::tr( "Vector geometry" );
40 }
41 
groupId() const42 QString QgsSimplifyAlgorithm::groupId() const
43 {
44   return QStringLiteral( "vectorgeometry" );
45 }
46 
outputName() const47 QString QgsSimplifyAlgorithm::outputName() const
48 {
49   return QObject::tr( "Simplified" );
50 }
51 
shortHelpString() const52 QString QgsSimplifyAlgorithm::shortHelpString() const
53 {
54   return QObject::tr( "This algorithm simplifies the geometries in a line or polygon layer. It creates a new layer "
55                       "with the same features as the ones in the input layer, but with geometries containing a lower number of vertices.\n\n"
56                       "The algorithm gives a choice of simplification methods, including distance based "
57                       "(the \"Douglas-Peucker\" algorithm), area based (\"Visvalingam\" algorithm) and snapping geometries to a grid." );
58 }
59 
createInstance() const60 QgsSimplifyAlgorithm *QgsSimplifyAlgorithm::createInstance() const
61 {
62   return new QgsSimplifyAlgorithm();
63 }
64 
inputLayerTypes() const65 QList<int> QgsSimplifyAlgorithm::inputLayerTypes() const
66 {
67   return QList<int>() << QgsProcessing::TypeVectorLine << QgsProcessing::TypeVectorPolygon;
68 }
69 
initParameters(const QVariantMap &)70 void QgsSimplifyAlgorithm::initParameters( const QVariantMap & )
71 {
72   QStringList methods;
73   methods << QObject::tr( "Distance (Douglas-Peucker)" )
74           << QObject::tr( "Snap to grid" )
75           << QObject::tr( "Area (Visvalingam)" );
76 
77   addParameter( new QgsProcessingParameterEnum(
78                   QStringLiteral( "METHOD" ),
79                   QObject::tr( "Simplification method" ),
80                   methods, false, 0 ) );
81   std::unique_ptr< QgsProcessingParameterDistance > tolerance = qgis::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "TOLERANCE" ),
82       QObject::tr( "Tolerance" ), 1.0, QStringLiteral( "INPUT" ), false, 0, 10000000.0 );
83   tolerance->setIsDynamic( true );
84   tolerance->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Tolerance" ), QObject::tr( "Tolerance distance" ), QgsPropertyDefinition::DoublePositive ) );
85   tolerance->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
86   addParameter( tolerance.release() );
87 }
88 
prepareAlgorithm(const QVariantMap & parameters,QgsProcessingContext & context,QgsProcessingFeedback *)89 bool QgsSimplifyAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
90 {
91   mTolerance = parameterAsDouble( parameters, QStringLiteral( "TOLERANCE" ), context );
92   mDynamicTolerance = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "TOLERANCE" ) );
93   if ( mDynamicTolerance )
94     mToleranceProperty = parameters.value( QStringLiteral( "TOLERANCE" ) ).value< QgsProperty >();
95 
96   mMethod = static_cast< QgsMapToPixelSimplifier::SimplifyAlgorithm >( parameterAsEnum( parameters, QStringLiteral( "METHOD" ), context ) );
97   if ( mMethod != QgsMapToPixelSimplifier::Distance )
98     mSimplifier.reset( new QgsMapToPixelSimplifier( QgsMapToPixelSimplifier::SimplifyGeometry, mTolerance, mMethod ) );
99 
100   return true;
101 }
102 
processFeature(const QgsFeature & feature,QgsProcessingContext & context,QgsProcessingFeedback *)103 QgsFeatureList QgsSimplifyAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
104 {
105   QgsFeature f = feature;
106   if ( f.hasGeometry() )
107   {
108     QgsGeometry inputGeometry = f.geometry();
109     QgsGeometry outputGeometry;
110     if ( mMethod == QgsMapToPixelSimplifier::Distance )
111     {
112       double tolerance = mTolerance;
113       if ( mDynamicTolerance )
114         tolerance = mToleranceProperty.valueAsDouble( context.expressionContext(), tolerance );
115       outputGeometry = inputGeometry.simplify( tolerance );
116     }
117     else
118     {
119       if ( !mDynamicTolerance )
120       {
121         outputGeometry = mSimplifier->simplify( inputGeometry );
122       }
123       else
124       {
125         double tolerance = mToleranceProperty.valueAsDouble( context.expressionContext(), mTolerance );
126         QgsMapToPixelSimplifier simplifier( QgsMapToPixelSimplifier::SimplifyGeometry, tolerance, mMethod );
127         outputGeometry = simplifier.simplify( inputGeometry );
128       }
129     }
130     f.setGeometry( outputGeometry );
131   }
132   return QgsFeatureList() << f;
133 }
134 
sourceFlags() const135 QgsProcessingFeatureSource::Flag QgsSimplifyAlgorithm::sourceFlags() const
136 {
137   return QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks;
138 }
139 
140 ///@endcond
141 
142 
143