QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 
QgsCurve
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
QgsProperty
A store for object properties.
Definition: qgsproperty.h:231
QgsProcessingParameters::isDynamic
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...
Definition: qgsprocessingparameters.cpp:111
qgsalgorithmlinesubstring.h
QgsProcessingFeedback
Definition: qgsprocessingfeedback.h:37
QgsGeometry::isMultipart
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
Definition: qgsgeometry.cpp:377
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsProcessing::TypeVectorLine
@ TypeVectorLine
Vector line layers.
Definition: qgsprocessing.h:49
QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks
@ FlagSkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition: qgsprocessingutils.h:475
QgsFeature::clearGeometry
void clearGeometry()
Removes any geometry associated with the feature.
Definition: qgsfeature.cpp:151
QgsGeometryCollection
Geometry collection.
Definition: qgsgeometrycollection.h:35
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:137
QgsProcessingContext
Definition: qgsprocessingcontext.h:43
QgsCurve::curveSubstring
virtual QgsCurve * curveSubstring(double startDistance, double endDistance) const =0
Returns a new curve representing a substring of this curve.
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:572
QgsPropertyDefinition
Definition for a property.
Definition: qgsproperty.h:47
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsProcessingFeatureSource::Flag
Flag
Flags controlling how QgsProcessingFeatureSource fetches features.
Definition: qgsprocessingutils.h:473
qgscurve.h
QgsGeometry
Definition: qgsgeometry.h:122
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
QgsProcessingContext::expressionContext
QgsExpressionContext & expressionContext()
Returns the expression context.
Definition: qgsprocessingcontext.h:119
QgsProperty::valueAsDouble
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.
Definition: qgsproperty.cpp:620
qgsgeometrycollection.h
QgsFeature
Definition: qgsfeature.h:55
QgsProcessing::SourceType
SourceType
Data source types enum.
Definition: qgsprocessing.h:44
QgsPropertyDefinition::DoublePositive
@ DoublePositive
Positive double value (including 0)
Definition: qgsproperty.h:59