QGIS API Documentation  3.12.1-București (121cc00ff0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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  return mCrs;
91 }
92 
93 QString QgsSumLineLengthAlgorithm::inputParameterName() const
94 {
95  return QStringLiteral( "POLYGONS" );
96 }
97 
98 QString QgsSumLineLengthAlgorithm::inputParameterDescription() const
99 {
100  return QObject::tr( "Polygons" );
101 }
102 
103 QString QgsSumLineLengthAlgorithm::outputName() const
104 {
105  return QObject::tr( "Line length" );
106 }
107 
108 void QgsSumLineLengthAlgorithm::initParameters( const QVariantMap & )
109 {
110  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "LINES" ),
111  QObject::tr( "Lines" ), QList< int > () << QgsProcessing::TypeVectorLine ) );
112  addParameter( new QgsProcessingParameterString( QStringLiteral( "LEN_FIELD" ),
113  QObject::tr( "Lines length field name" ), QStringLiteral( "LENGTH" ) ) );
114  addParameter( new QgsProcessingParameterString( QStringLiteral( "COUNT_FIELD" ),
115  QObject::tr( "Lines count field name" ), QStringLiteral( "COUNT" ) ) );
116 }
117 
118 bool QgsSumLineLengthAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
119 {
120  mLengthFieldName = parameterAsString( parameters, QStringLiteral( "LEN_FIELD" ), context );
121  mCountFieldName = parameterAsString( parameters, QStringLiteral( "COUNT_FIELD" ), context );
122 
123  mLinesSource.reset( parameterAsSource( parameters, QStringLiteral( "LINES" ), context ) );
124  if ( !mLinesSource )
125  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "LINES" ) ) );
126 
127  if ( mLinesSource->hasSpatialIndex() == QgsFeatureSource::SpatialIndexNotPresent )
128  feedback->reportError( QObject::tr( "No spatial index exists for lines layer, performance will be severely degraded" ) );
129 
130  if ( context.project() )
131  {
132  mDa.setEllipsoid( context.project()->ellipsoid() );
133  }
134  mDa.setSourceCrs( mCrs, context.transformContext() );
135 
136  return true;
137 }
138 
139 QgsFields QgsSumLineLengthAlgorithm::outputFields( const QgsFields &inputFields ) const
140 {
141  QgsFields outFields = inputFields;
142  mLengthFieldIndex = inputFields.lookupField( mLengthFieldName );
143  if ( mLengthFieldIndex < 0 )
144  outFields.append( QgsField( mLengthFieldName, QVariant::Double ) );
145 
146  mCountFieldIndex = inputFields.lookupField( mCountFieldName );
147  if ( mCountFieldIndex < 0 )
148  outFields.append( QgsField( mCountFieldName, QVariant::Double ) );
149 
150  mFields = outFields;
151  return outFields;
152 }
153 
154 QgsFeatureList QgsSumLineLengthAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
155 {
156  QgsFeature outputFeature = feature;
157  if ( !feature.hasGeometry() )
158  {
159  QgsAttributes attrs = feature.attributes();
160  if ( mLengthFieldIndex < 0 )
161  attrs.append( 0 );
162  else
163  attrs[mLengthFieldIndex] = 0;
164 
165  if ( mCountFieldIndex < 0 )
166  attrs.append( 0 );
167  else
168  attrs[mCountFieldIndex] = 0;
169 
170  outputFeature.setAttributes( attrs );
171  return QList< QgsFeature > () << outputFeature;
172  }
173  else
174  {
175  const QgsGeometry polyGeom = feature.geometry();
176  std::unique_ptr< QgsGeometryEngine > engine( QgsGeometry::createGeometryEngine( polyGeom.constGet() ) );
177  engine->prepareGeometry();
178 
179  QgsFeatureRequest req = QgsFeatureRequest().setFilterRect( polyGeom.boundingBox() ).setDestinationCrs( mCrs, context.transformContext() );
180  req.setSubsetOfAttributes( QList< int >() );
181  QgsFeatureIterator it = mLinesSource->getFeatures( req );
182 
183  double count = 0;
184  double length = 0;
185 
186  QgsFeature lineFeature;
187  while ( it.nextFeature( lineFeature ) )
188  {
189  if ( feedback->isCanceled() )
190  break;
191 
192  if ( engine->intersects( lineFeature.geometry().constGet() ) )
193  {
194  QgsGeometry outGeom = polyGeom.intersection( lineFeature.geometry() );
195  length += mDa.measureLength( outGeom );
196  count++;
197  }
198  }
199 
200  QgsAttributes attrs = feature.attributes();
201  if ( mLengthFieldIndex < 0 )
202  attrs.append( length );
203  else
204  attrs[mLengthFieldIndex] = length;
205 
206  if ( mCountFieldIndex < 0 )
207  attrs.append( count );
208  else
209  attrs[mCountFieldIndex] = count;
210 
211  outputFeature.setAttributes( attrs );
212  return QList< QgsFeature >() << outputFeature;
213  }
214 }
215 
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:324
Wrapper for iterator of features from vector data provider or vector layer.
No spatial index exists for the source.
Base class for providing feedback from a processing algorithm.
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:571
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Container of fields for a vector layer.
Definition: qgsfields.h:42
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:122
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
void setAttributes(const QgsAttributes &attrs)
Sets the feature&#39;s attributes.
Definition: qgsfeature.cpp:127
QgsGeometry intersection(const QgsGeometry &geometry) const
Returns a geometry representing the points shared by this geometry and other.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
QString ellipsoid
Definition: qgsproject.h:99
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
QgsProject * project() const
Returns the project in which the algorithm is being executed.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
Custom exception class for processing related exceptions.
Definition: qgsexception.h:82
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
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
Vector polygon layers.
Definition: qgsprocessing.h:50
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:49
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:55
An input feature source (such as vector layers) parameter for processing algorithms.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
This class represents a coordinate reference system (CRS).
Vector line layers.
Definition: qgsprocessing.h:49
SourceType
Data source types enum.
Definition: qgsprocessing.h:44
const QgsCoordinateReferenceSystem & outputCrs
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
QgsGeometry geometry
Definition: qgsfeature.h:67
bool nextFeature(QgsFeature &f)
A vector of attributes.
Definition: qgsattributes.h:57
Contains information about the context in which a processing algorithm is executed.
A string parameter for processing algorithms.
QgsAttributes attributes
Definition: qgsfeature.h:65