QGIS API Documentation  3.6.0-Noosa (5873452)
qgsalgorithmlinesubstring.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmlinesubstring.cpp
3  ---------------------
4  begin : August 2018
5  copyright : (C) 2018 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 
19 #include "qgsgeometrycollection.h"
20 #include "qgscurve.h"
21 
23 
24 QString QgsLineSubstringAlgorithm::name() const
25 {
26  return QStringLiteral( "linesubstring" );
27 }
28 
29 QString QgsLineSubstringAlgorithm::displayName() const
30 {
31  return QObject::tr( "Line substring" );
32 }
33 
34 QStringList QgsLineSubstringAlgorithm::tags() const
35 {
36  return QObject::tr( "linestring,curve,split,shorten,shrink,portion,part,reference,referencing,distance,interpolate" ).split( ',' );
37 }
38 
39 QString QgsLineSubstringAlgorithm::group() const
40 {
41  return QObject::tr( "Vector geometry" );
42 }
43 
44 QString QgsLineSubstringAlgorithm::groupId() const
45 {
46  return QStringLiteral( "vectorgeometry" );
47 }
48 
49 QString QgsLineSubstringAlgorithm::outputName() const
50 {
51  return QObject::tr( "Substring" );
52 }
53 
54 QString QgsLineSubstringAlgorithm::shortHelpString() const
55 {
56  return QObject::tr( "This algorithm returns the portion of a line (or curve) which falls "
57  "between the specified start and end distances (measured from the "
58  "beginning of the line).\n\n"
59  "Z and M values are linearly interpolated from existing values.\n\n"
60  "If a multipart geometry is encountered, only the first part is considered when "
61  "calculating the substring." );
62 }
63 
64 QString QgsLineSubstringAlgorithm::shortDescription() const
65 {
66  return QObject::tr( "Returns the substring of lines which fall between start and end distances." );
67 }
68 
69 QList<int> QgsLineSubstringAlgorithm::inputLayerTypes() const
70 {
71  return QList<int>() << QgsProcessing::TypeVectorLine;
72 }
73 
74 QgsProcessing::SourceType QgsLineSubstringAlgorithm::outputLayerType() const
75 {
77 }
78 
79 QgsLineSubstringAlgorithm *QgsLineSubstringAlgorithm::createInstance() const
80 {
81  return new QgsLineSubstringAlgorithm();
82 }
83 
84 void QgsLineSubstringAlgorithm::initParameters( const QVariantMap & )
85 {
86  std::unique_ptr< QgsProcessingParameterDistance> startDistance = qgis::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "START_DISTANCE" ),
87  QObject::tr( "Start distance" ), 0.0, QStringLiteral( "INPUT" ), false, 0 );
88  startDistance->setIsDynamic( true );
89  startDistance->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Start Distance" ), QObject::tr( "Start distance" ), QgsPropertyDefinition::DoublePositive ) );
90  startDistance->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
91  addParameter( startDistance.release() );
92 
93  std::unique_ptr< QgsProcessingParameterDistance> endDistance = qgis::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "END_DISTANCE" ),
94  QObject::tr( "End distance" ), 1.0, QStringLiteral( "INPUT" ), false, 0 );
95  endDistance->setIsDynamic( true );
96  endDistance->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "End Distance" ), QObject::tr( "End distance" ), QgsPropertyDefinition::DoublePositive ) );
97  endDistance->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
98  addParameter( endDistance.release() );
99 }
100 
101 QgsProcessingFeatureSource::Flag QgsLineSubstringAlgorithm::sourceFlags() const
102 {
103  // skip geometry checks - this algorithm doesn't care about invalid geometries
105 }
106 
107 bool QgsLineSubstringAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
108 {
109  mStartDistance = parameterAsDouble( parameters, QStringLiteral( "START_DISTANCE" ), context );
110  mDynamicStartDistance = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "START_DISTANCE" ) );
111  if ( mDynamicStartDistance )
112  mStartDistanceProperty = parameters.value( QStringLiteral( "START_DISTANCE" ) ).value< QgsProperty >();
113 
114  mEndDistance = parameterAsDouble( parameters, QStringLiteral( "END_DISTANCE" ), context );
115  mDynamicEndDistance = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "END_DISTANCE" ) );
116  if ( mDynamicEndDistance )
117  mEndDistanceProperty = parameters.value( QStringLiteral( "END_DISTANCE" ) ).value< QgsProperty >();
118 
119  return true;
120 }
121 
122 QgsFeatureList QgsLineSubstringAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
123 {
124  QgsFeature f = feature;
125  if ( f.hasGeometry() )
126  {
127  const QgsGeometry geometry = f.geometry();
128  double startDistance = mStartDistance;
129  if ( mDynamicStartDistance )
130  startDistance = mStartDistanceProperty.valueAsDouble( context.expressionContext(), startDistance );
131 
132  double endDistance = mEndDistance;
133  if ( mDynamicEndDistance )
134  endDistance = mEndDistanceProperty.valueAsDouble( context.expressionContext(), endDistance );
135 
136  const QgsCurve *curve = nullptr;
137  if ( !geometry.isMultipart() )
138  curve = qgsgeometry_cast< const QgsCurve * >( geometry.constGet() );
139  else
140  {
141  if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( geometry.constGet() ) )
142  {
143  if ( collection->numGeometries() > 0 )
144  {
145  curve = qgsgeometry_cast< const QgsCurve * >( collection->geometryN( 0 ) );
146  }
147  }
148  }
149  if ( curve )
150  {
151  std::unique_ptr< QgsCurve > substring( curve->curveSubstring( startDistance, endDistance ) );
152  QgsGeometry result( std::move( substring ) );
153  f.setGeometry( result );
154  }
155  else
156  {
157  f.clearGeometry();
158  }
159  }
160  return QgsFeatureList() << f;
161 }
162 
164 
165 
Base class for providing feedback from a processing algorithm.
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:571
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:106
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
Positive double value (including 0)
Definition: qgsproperty.h:58
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
virtual QgsCurve * curveSubstring(double startDistance, double endDistance) const =0
Returns a new curve representing a substring of this curve.
Geometry collection.
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
A store for object properties.
Definition: qgsproperty.h:229
QgsExpressionContext & expressionContext()
Returns the expression context.
Definition for a property.
Definition: qgsproperty.h:46
Flag
Flags controlling how QgsProcessingFeatureSource fetches features.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
double valueAsDouble(const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property and interprets it as a double.
void clearGeometry()
Removes any geometry associated with the feature.
Definition: qgsfeature.cpp:151
Vector line layers.
Definition: qgsprocessing.h:49
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
SourceType
Data source types enum.
Definition: qgsprocessing.h:44
QgsGeometry geometry
Definition: qgsfeature.h:67
Contains information about the context in which a processing algorithm is executed.
static bool isDynamic(const QVariantMap &parameters, const QString &name)
Returns true if the parameter with matching name is a dynamic parameter, and must be evaluated once f...