QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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  if ( context.project() )
132  {
133  mDa.setEllipsoid( context.project()->ellipsoid() );
134  }
135  mTransformContext = context.transformContext();
136 
137  return true;
138 }
139 
140 QgsFields QgsSumLineLengthAlgorithm::outputFields( const QgsFields &inputFields ) const
141 {
142  QgsFields outFields = inputFields;
143  mLengthFieldIndex = inputFields.lookupField( mLengthFieldName );
144  if ( mLengthFieldIndex < 0 )
145  outFields.append( QgsField( mLengthFieldName, QVariant::Double ) );
146 
147  mCountFieldIndex = inputFields.lookupField( mCountFieldName );
148  if ( mCountFieldIndex < 0 )
149  outFields.append( QgsField( mCountFieldName, QVariant::Double ) );
150 
151  mFields = outFields;
152  return outFields;
153 }
154 
155 QgsFeatureList QgsSumLineLengthAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
156 {
157  QgsFeature outputFeature = feature;
158  if ( !feature.hasGeometry() )
159  {
160  QgsAttributes attrs = feature.attributes();
161  if ( mLengthFieldIndex < 0 )
162  attrs.append( 0 );
163  else
164  attrs[mLengthFieldIndex] = 0;
165 
166  if ( mCountFieldIndex < 0 )
167  attrs.append( 0 );
168  else
169  attrs[mCountFieldIndex] = 0;
170 
171  outputFeature.setAttributes( attrs );
172  return QList< QgsFeature > () << outputFeature;
173  }
174  else
175  {
176  const QgsGeometry polyGeom = feature.geometry();
177  std::unique_ptr< QgsGeometryEngine > engine( QgsGeometry::createGeometryEngine( polyGeom.constGet() ) );
178  engine->prepareGeometry();
179 
181  req.setSubsetOfAttributes( QList< int >() );
182  QgsFeatureIterator it = mLinesSource->getFeatures( req );
183 
184  double count = 0;
185  double length = 0;
186 
187  QgsFeature lineFeature;
188  while ( it.nextFeature( lineFeature ) )
189  {
190  if ( feedback->isCanceled() )
191  break;
192 
193  if ( engine->intersects( lineFeature.geometry().constGet() ) )
194  {
195  QgsGeometry outGeom = polyGeom.intersection( lineFeature.geometry() );
196  length += mDa.measureLength( outGeom );
197  count++;
198  }
199  }
200 
201  QgsAttributes attrs = feature.attributes();
202  if ( mLengthFieldIndex < 0 )
203  attrs.append( length );
204  else
205  attrs[mLengthFieldIndex] = length;
206 
207  if ( mCountFieldIndex < 0 )
208  attrs.append( count );
209  else
210  attrs[mCountFieldIndex] = count;
211 
212  outputFeature.setAttributes( attrs );
213  return QList< QgsFeature >() << outputFeature;
214  }
215 }
216 
outputCrs
const QgsCoordinateReferenceSystem & outputCrs
Definition: qgswfsgetfeature.cpp:115
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Definition: qgsapplication.cpp:605
QgsProcessingContext::project
QgsProject * project() const
Returns the project in which the algorithm is being executed.
Definition: qgsprocessingcontext.h:99
QgsProcessingFeedback
Definition: qgsprocessingfeedback.h:37
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
Definition: qgsfields.h:44
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
qgsalgorithmsumlinelength.h
QgsProcessing::TypeVectorLine
@ TypeVectorLine
Vector line layers.
Definition: qgsprocessing.h:49
QgsProcessingParameterFeatureSource
Definition: qgsprocessingparameters.h:2612
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:190
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:594
QgsGeometry::intersection
QgsGeometry intersection(const QgsGeometry &geometry) const
Returns a geometry representing the points shared by this geometry and other.
Definition: qgsgeometry.cpp:2395
qgsapplication.h
QgsFeatureRequest::setFilterRect
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Definition: qgsfeaturerequest.cpp:97
QgsFeatureRequest
Definition: qgsfeaturerequest.h:75
qgsgeometryengine.h
QgsProcessingContext
Definition: qgsprocessingcontext.h:43
QgsProcessingParameterString
Definition: qgsprocessingparameters.h:2202
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:572
QgsProcessingContext::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Definition: qgsprocessingcontext.h:135
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:69
QgsCoordinateReferenceSystem
Definition: qgscoordinatereferencesystem.h:206
qgsvectorlayer.h
QgsFeedback::isCanceled
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:66
QgsGeometry::createGeometryEngine
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine.
Definition: qgsgeometry.cpp:3659
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:373
qgsprocessing.h
QgsGeometry
Definition: qgsgeometry.h:122
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:962
QgsAttributes
Definition: qgsattributes.h:57
QgsFeature
Definition: qgsfeature.h:55
QgsFeatureRequest::setDestinationCrs
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
Definition: qgsfeaturerequest.cpp:263
QgsFeature::setAttributes
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:127
QgsFields::lookupField
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:324
QgsFeatureIterator
Definition: qgsfeatureiterator.h:263
QgsProject::ellipsoid
QString ellipsoid
Definition: qgsproject.h:100
QgsProcessing::SourceType
SourceType
Data source types enum.
Definition: qgsprocessing.h:44
QgsProcessingException
Definition: qgsexception.h:82
QgsField
Definition: qgsfield.h:49