QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsalgorithmsumlinelength.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmsumlinelength.cpp
3  ---------------------
4  begin : November 2019
5  copyright : (C) 2019 by Alexander Bruy
6  email : alexander dot bruy 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 "qgsprocessing.h"
20 #include "qgsgeometryengine.h"
21 #include "qgsvectorlayer.h"
22 #include "qgsapplication.h"
23 
25 
26 QString QgsSumLineLengthAlgorithm::name() const
27 {
28  return QStringLiteral( "sumlinelengths" );
29 }
30 
31 QString QgsSumLineLengthAlgorithm::displayName() const
32 {
33  return QObject::tr( "Sum line lengths" );
34 }
35 
36 QStringList QgsSumLineLengthAlgorithm::tags() const
37 {
38  return QObject::tr( "line,intersects,intersecting,sum,length,count" ).split( ',' );
39 }
40 
41 QString QgsSumLineLengthAlgorithm::svgIconPath() const
42 {
43  return QgsApplication::iconPath( QStringLiteral( "/algorithms/mAlgorithmSumLengthLines.svg" ) );
44 }
45 
46 QIcon QgsSumLineLengthAlgorithm::icon() const
47 {
48  return QgsApplication::getThemeIcon( QStringLiteral( "/algorithms/mAlgorithmSumLengthLines.svg" ) );
49 }
50 
51 QString QgsSumLineLengthAlgorithm::group() const
52 {
53  return QObject::tr( "Vector analysis" );
54 }
55 
56 QString QgsSumLineLengthAlgorithm::groupId() const
57 {
58  return QStringLiteral( "vectoranalysis" );
59 }
60 
61 QString QgsSumLineLengthAlgorithm::shortHelpString() const
62 {
63  return QObject::tr( "This algorithm takes a polygon layer and a line layer and "
64  "measures the total length of lines and the total number of "
65  "them that cross each polygon.\n\n"
66  "The resulting layer has the same features as the input polygon "
67  "layer, but with two additional attributes containing the length "
68  "and count of the lines across each polygon. The names of these "
69  "two fields can be configured in the algorithm parameters." );
70 }
71 
72 QgsSumLineLengthAlgorithm *QgsSumLineLengthAlgorithm::createInstance() const
73 {
74  return new QgsSumLineLengthAlgorithm();
75 }
76 
77 QList<int> QgsSumLineLengthAlgorithm::inputLayerTypes() const
78 {
79  return QList< int >() << QgsProcessing::TypeVectorPolygon;
80 }
81 
82 QgsProcessing::SourceType QgsSumLineLengthAlgorithm::outputLayerType() const
83 {
85 }
86 
88 {
89  mCrs = inputCrs;
90  mDa.setSourceCrs( mCrs, mTransformContext );
91  return mCrs;
92 }
93 
94 QString QgsSumLineLengthAlgorithm::inputParameterName() const
95 {
96  return QStringLiteral( "POLYGONS" );
97 }
98 
99 QString QgsSumLineLengthAlgorithm::inputParameterDescription() const
100 {
101  return QObject::tr( "Polygons" );
102 }
103 
104 QString QgsSumLineLengthAlgorithm::outputName() const
105 {
106  return QObject::tr( "Line length" );
107 }
108 
109 void QgsSumLineLengthAlgorithm::initParameters( const QVariantMap & )
110 {
111  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "LINES" ),
112  QObject::tr( "Lines" ), QList< int > () << QgsProcessing::TypeVectorLine ) );
113  addParameter( new QgsProcessingParameterString( QStringLiteral( "LEN_FIELD" ),
114  QObject::tr( "Lines length field name" ), QStringLiteral( "LENGTH" ) ) );
115  addParameter( new QgsProcessingParameterString( QStringLiteral( "COUNT_FIELD" ),
116  QObject::tr( "Lines count field name" ), QStringLiteral( "COUNT" ) ) );
117 }
118 
119 bool QgsSumLineLengthAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
120 {
121  mLengthFieldName = parameterAsString( parameters, QStringLiteral( "LEN_FIELD" ), context );
122  mCountFieldName = parameterAsString( parameters, QStringLiteral( "COUNT_FIELD" ), context );
123 
124  mLinesSource.reset( parameterAsSource( parameters, QStringLiteral( "LINES" ), context ) );
125  if ( !mLinesSource )
126  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "LINES" ) ) );
127 
128  if ( mLinesSource->hasSpatialIndex() == QgsFeatureSource::SpatialIndexNotPresent )
129  feedback->reportError( QObject::tr( "No spatial index exists for lines layer, performance will be severely degraded" ) );
130 
131  mDa.setEllipsoid( context.ellipsoid() );
132  mTransformContext = context.transformContext();
133 
134  return true;
135 }
136 
137 QgsFields QgsSumLineLengthAlgorithm::outputFields( const QgsFields &inputFields ) const
138 {
139  QgsFields outFields = inputFields;
140  mLengthFieldIndex = inputFields.lookupField( mLengthFieldName );
141  if ( mLengthFieldIndex < 0 )
142  outFields.append( QgsField( mLengthFieldName, QVariant::Double ) );
143 
144  mCountFieldIndex = inputFields.lookupField( mCountFieldName );
145  if ( mCountFieldIndex < 0 )
146  outFields.append( QgsField( mCountFieldName, QVariant::Double ) );
147 
148  mFields = outFields;
149  return outFields;
150 }
151 
152 QgsFeatureList QgsSumLineLengthAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
153 {
154  QgsFeature outputFeature = feature;
155  if ( !feature.hasGeometry() )
156  {
157  QgsAttributes attrs = feature.attributes();
158  if ( mLengthFieldIndex < 0 )
159  attrs.append( 0 );
160  else
161  attrs[mLengthFieldIndex] = 0;
162 
163  if ( mCountFieldIndex < 0 )
164  attrs.append( 0 );
165  else
166  attrs[mCountFieldIndex] = 0;
167 
168  outputFeature.setAttributes( attrs );
169  return QList< QgsFeature > () << outputFeature;
170  }
171  else
172  {
173  const QgsGeometry polyGeom = feature.geometry();
174  std::unique_ptr< QgsGeometryEngine > engine( QgsGeometry::createGeometryEngine( polyGeom.constGet() ) );
175  engine->prepareGeometry();
176 
178  req.setSubsetOfAttributes( QList< int >() );
179  QgsFeatureIterator it = mLinesSource->getFeatures( req );
180 
181  double count = 0;
182  double length = 0;
183 
184  QgsFeature lineFeature;
185  while ( it.nextFeature( lineFeature ) )
186  {
187  if ( feedback->isCanceled() )
188  break;
189 
190  if ( engine->intersects( lineFeature.geometry().constGet() ) )
191  {
192  QgsGeometry outGeom = polyGeom.intersection( lineFeature.geometry() );
193  length += mDa.measureLength( outGeom );
194  count++;
195  }
196  }
197 
198  QgsAttributes attrs = feature.attributes();
199  if ( mLengthFieldIndex < 0 )
200  attrs.append( length );
201  else
202  attrs[mLengthFieldIndex] = length;
203 
204  if ( mCountFieldIndex < 0 )
205  attrs.append( count );
206  else
207  attrs[mCountFieldIndex] = count;
208 
209  outputFeature.setAttributes( attrs );
210  return QList< QgsFeature >() << outputFeature;
211  }
212 }
213 
outputCrs
const QgsCoordinateReferenceSystem & outputCrs
Definition: qgswfsgetfeature.cpp:61
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Definition: qgsapplication.cpp:626
QgsProcessingFeedback
Base class for providing feedback from a processing algorithm.
Definition: qgsprocessingfeedback.h:38
QgsFeatureSource::SpatialIndexNotPresent
@ SpatialIndexNotPresent
No spatial index exists for the source.
Definition: qgsfeaturesource.h:190
QgsProcessingFeedback::reportError
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
Definition: qgsprocessingfeedback.cpp:39
QgsProcessing::TypeVectorPolygon
@ TypeVectorPolygon
Vector polygon layers.
Definition: qgsprocessing.h:50
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:45
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:67
qgsalgorithmsumlinelength.h
QgsProcessing::TypeVectorLine
@ TypeVectorLine
Vector line layers.
Definition: qgsprocessing.h:49
QgsProcessingParameterFeatureSource
An input feature source (such as vector layers) parameter for processing algorithms.
Definition: qgsprocessingparameters.h:2734
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:185
QgsFields::append
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
QgsApplication::iconPath
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
Definition: qgsapplication.cpp:615
QgsGeometry::intersection
QgsGeometry intersection(const QgsGeometry &geometry) const
Returns a geometry representing the points shared by this geometry and other.
Definition: qgsgeometry.cpp:2380
qgsapplication.h
QgsFeatureRequest::setFilterRect
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Definition: qgsfeaturerequest.cpp:92
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
qgsgeometryengine.h
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:44
QgsProcessingContext::ellipsoid
QString ellipsoid() const
Returns the ellipsoid to use for distance and area calculations.
Definition: qgsprocessingcontext.cpp:131
QgsProcessingParameterString
A string parameter for processing algorithms.
Definition: qgsprocessingparameters.h:2324
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:583
QgsProcessingContext::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Definition: qgsprocessingcontext.h:149
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:65
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:206
qgsvectorlayer.h
QgsFeedback::isCanceled
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:53
QgsGeometry::createGeometryEngine
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine.
Definition: qgsgeometry.cpp:3636
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
qgsprocessing.h
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:199
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:996
QgsAttributes
A vector of attributes.
Definition: qgsattributes.h:58
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsFeatureRequest::setDestinationCrs
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
Definition: qgsfeaturerequest.cpp:258
QgsFeature::setAttributes
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:129
QgsFields::lookupField
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:344
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:265
QgsProcessing::SourceType
SourceType
Data source types enum.
Definition: qgsprocessing.h:45
QgsProcessingException
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
QgsField
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:50