22using namespace Qt::StringLiterals;
26QString QgsClimbAlgorithm::name()
const
28 return u
"climbalongline"_s;
31QString QgsClimbAlgorithm::displayName()
const
33 return QObject::tr(
"Climb along line" );
36QStringList QgsClimbAlgorithm::tags()
const
38 return QObject::tr(
"line,climb,descent,elevation" ).split(
',' );
41QString QgsClimbAlgorithm::group()
const
43 return QObject::tr(
"Vector analysis" );
46QString QgsClimbAlgorithm::groupId()
const
48 return u
"vectoranalysis"_s;
51QString QgsClimbAlgorithm::shortHelpString()
const
54 "This algorithm calculates the total climb and descent along line geometries.\n\n"
55 "Input layer must have Z values present. If Z values are not available, the \"Drape\" (set Z "
56 "value from raster) algorithm may be used to add Z values from a DEM layer.\n\n"
57 "The output layer is a copy of the input layer with additional fields that contain the total "
58 "climb, total descent, the minimum elevation and the maximum elevation for each line geometry."
59 "If the input layer contains fields with the same names as these added fields, they will be "
60 "renamed (field names will be altered to \"name_2\", \"name_3\", etc, finding the first "
61 "non-duplicate name)."
65QString QgsClimbAlgorithm::shortDescription()
const
67 return QObject::tr(
"Calculates the total climb and descent along line geometries with Z values." );
70QgsClimbAlgorithm *QgsClimbAlgorithm::createInstance()
const
72 return new QgsClimbAlgorithm();
75void QgsClimbAlgorithm::initAlgorithm(
const QVariantMap & )
88 QGS_MARK_ALGORITHM_SOURCE
90 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, u
"INPUT"_s, context ) );
98 throw QgsProcessingException( QObject::tr(
"The layer does not have Z values. If you have a DEM, use the Drape algorithm to extract Z values." ) );
101 QgsFields outputFields = source->fields();
103 newFields.
append(
QgsField( u
"climb"_s, QMetaType::Type::Double ) );
104 newFields.
append(
QgsField( u
"descent"_s, QMetaType::Type::Double ) );
105 newFields.
append(
QgsField( u
"minelev"_s, QMetaType::Type::Double ) );
106 newFields.
append(
QgsField( u
"maxelev"_s, QMetaType::Type::Double ) );
110 std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, u
"OUTPUT"_s, context, dest, outputFields, source->wkbType(), source->sourceCrs() ) );
114 double totalClimb = 0;
115 double totalDescent = 0;
116 double minElevation = std::numeric_limits<double>::max();
117 double maxElevation = -std::numeric_limits<double>::max();
119 QStringList noGeometry;
120 QStringList noZValue;
123 double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 1;
136 noGeometry.append( QObject::tr(
"Feature: %1" ).arg( f.
id() ) );
142 double minElev = std::numeric_limits<double>::max();
143 double maxElev = -std::numeric_limits<double>::max();
151 double previousZ = 0;
153 int vertexNumber = 0;
157 if ( std::isnan( z ) )
159 noZValue.append( QObject::tr(
"Feature: %1, part: %2, point: %3" ).arg( f.
id(), partNumber, vertexNumber ) );
171 double diff = z - previousZ;
180 minElev = std::min( minElev, z );
181 maxElev = std::max( maxElev, z );
186 totalDescent += descent;
190 attrs << climb << descent << minElev << maxElev;
201 minElevation = std::min( minElevation, minElev );
202 maxElevation = std::max( maxElevation, maxElev );
211 if ( !noGeometry.empty() )
213 feedback->
pushInfo( QObject::tr(
"The following features do not have geometry: %1" ).arg( noGeometry.join(
", "_L1 ) ) );
215 if ( !noZValue.empty() )
217 feedback->
pushInfo( QObject::tr(
"The following points do not have Z value: %1" ).arg( noZValue.join(
", "_L1 ) ) );
221 results.insert( u
"OUTPUT"_s, dest );
222 results.insert( u
"TOTALCLIMB"_s, totalClimb );
223 results.insert( u
"TOTALDESCENT"_s, totalDescent );
224 results.insert( u
"MINELEVATION"_s, minElevation );
225 results.insert( u
"MAXELEVATION"_s, maxElevation );
@ VectorLine
Vector line layers.
Abstract base class for all geometries.
vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
bool isCanceled() const
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
A geometry is the spatial representation of a feature.
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
Point geometry type, with support for z-dimension and m-values.
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
void featureAddedToSink(const QString &output)
Reports that a feature was added to the the sink associated with the specified algorithm output.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
void featureSinkFinalized(const QString &output)
Reports that a feature sink has been finalized.
A numeric output for processing algorithms.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB, const QString &fieldsBPrefix=QString())
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.