QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsalgorithmnetworkanalysisbase.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmnetworkanalysisbase.cpp
3  ---------------------
4  begin : July 2018
5  copyright : (C) 2018 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 
20 #include "qgsgraphanalyzer.h"
23 
25 
26 //
27 // QgsNetworkAnalysisAlgorithmBase
28 //
29 
30 QString QgsNetworkAnalysisAlgorithmBase::group() const
31 {
32  return QObject::tr( "Network analysis" );
33 }
34 
35 QString QgsNetworkAnalysisAlgorithmBase::groupId() const
36 {
37  return QStringLiteral( "networkanalysis" );
38 }
39 
40 QgsProcessingAlgorithm::Flags QgsNetworkAnalysisAlgorithmBase::flags() const
41 {
42  // TODO -- remove the dependency on the project from these algorithms, it shouldn't be required
43  return QgsProcessingAlgorithm::flags() | FlagRequiresProject;
44 }
45 
46 void QgsNetworkAnalysisAlgorithmBase::addCommonParams()
47 {
48  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Vector layer representing network" ), QList< int >() << QgsProcessing::TypeVectorLine ) );
49  addParameter( new QgsProcessingParameterEnum( QStringLiteral( "STRATEGY" ), QObject::tr( "Path type to calculate" ), QStringList() << QObject::tr( "Shortest" ) << QObject::tr( "Fastest" ), false, 0 ) );
50 
51  std::unique_ptr< QgsProcessingParameterField > directionField = qgis::make_unique< QgsProcessingParameterField >( QStringLiteral( "DIRECTION_FIELD" ),
52  QObject::tr( "Direction field" ), QVariant(), QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, false, true );
53  directionField->setFlags( directionField->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
54  addParameter( directionField.release() );
55 
56  std::unique_ptr< QgsProcessingParameterString > forwardValue = qgis::make_unique< QgsProcessingParameterString >( QStringLiteral( "VALUE_FORWARD" ),
57  QObject::tr( "Value for forward direction" ), QVariant(), false, true );
58  forwardValue->setFlags( forwardValue->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
59  addParameter( forwardValue.release() );
60 
61  std::unique_ptr< QgsProcessingParameterString > backwardValue = qgis::make_unique< QgsProcessingParameterString >( QStringLiteral( "VALUE_BACKWARD" ),
62  QObject::tr( "Value for backward direction" ), QVariant(), false, true );
63  backwardValue->setFlags( backwardValue->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
64  addParameter( backwardValue.release() );
65 
66  std::unique_ptr< QgsProcessingParameterString > bothValue = qgis::make_unique< QgsProcessingParameterString >( QStringLiteral( "VALUE_BOTH" ),
67  QObject::tr( "Value for both directions" ), QVariant(), false, true );
68  bothValue->setFlags( bothValue->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
69  addParameter( bothValue.release() );
70 
71  std::unique_ptr< QgsProcessingParameterEnum > directionValue = qgis::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "DEFAULT_DIRECTION" ),
72  QObject::tr( "Default direction" ), QStringList() << QObject::tr( "Forward direction" ) << QObject::tr( "Backward direction" ) << QObject::tr( "Both directions" ), false, 2 );
73  directionValue->setFlags( directionValue->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
74  addParameter( directionValue.release() );
75 
76  std::unique_ptr< QgsProcessingParameterField > speedField = qgis::make_unique< QgsProcessingParameterField >( QStringLiteral( "SPEED_FIELD" ),
77  QObject::tr( "Speed field" ), QVariant(), QStringLiteral( "INPUT" ), QgsProcessingParameterField::Numeric, false, true );
78  speedField->setFlags( speedField->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
79  addParameter( speedField.release() );
80 
81  std::unique_ptr< QgsProcessingParameterNumber > speed = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "DEFAULT_SPEED" ), QObject::tr( "Default speed (km/h)" ), QgsProcessingParameterNumber::Double, 50, false, 0 );
82  speed->setFlags( speed->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
83  addParameter( speed.release() );
84 
85  std::unique_ptr< QgsProcessingParameterNumber > tolerance = qgis::make_unique < QgsProcessingParameterDistance >( QStringLiteral( "TOLERANCE" ), QObject::tr( "Topology tolerance" ), 0, QStringLiteral( "INPUT" ), false, 0 );
86  tolerance->setFlags( tolerance->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
87  addParameter( tolerance.release() );
88 }
89 
90 void QgsNetworkAnalysisAlgorithmBase::loadCommonParams( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
91 {
92  Q_UNUSED( feedback )
93 
94  mNetwork.reset( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
95  if ( !mNetwork )
96  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
97 
98  int strategy = parameterAsInt( parameters, QStringLiteral( "STRATEGY" ), context );
99  QString directionFieldName = parameterAsString( parameters, QStringLiteral( "DIRECTION_FIELD" ), context );
100  QString forwardValue = parameterAsString( parameters, QStringLiteral( "VALUE_FORWARD" ), context );
101  QString backwardValue = parameterAsString( parameters, QStringLiteral( "VALUE_BACKWARD" ), context );
102  QString bothValue = parameterAsString( parameters, QStringLiteral( "VALUE_BOTH" ), context );
103  QgsVectorLayerDirector::Direction defaultDirection = static_cast< QgsVectorLayerDirector::Direction>( parameterAsInt( parameters, QStringLiteral( "DEFAULT_DIRECTION" ), context ) );
104  QString speedFieldName = parameterAsString( parameters, QStringLiteral( "SPEED_FIELD" ), context );
105  double defaultSpeed = parameterAsDouble( parameters, QStringLiteral( "DEFAULT_SPEED" ), context );
106  double tolerance = parameterAsDouble( parameters, QStringLiteral( "TOLERANCE" ), context );
107 
108  int directionField = -1;
109  if ( !directionFieldName.isEmpty() )
110  {
111  directionField = mNetwork->fields().lookupField( directionFieldName );
112  }
113 
114  int speedField = -1;
115  if ( !speedFieldName.isEmpty() )
116  {
117  speedField = mNetwork->fields().lookupField( speedFieldName );
118  }
119 
120  mDirector = new QgsVectorLayerDirector( mNetwork.get(), directionField, forwardValue, backwardValue, bothValue, defaultDirection );
121 
122  QgsUnitTypes::DistanceUnit distanceUnits = context.project()->crs().mapUnits();
124 
125  if ( strategy )
126  {
127  mDirector->addStrategy( new QgsNetworkSpeedStrategy( speedField, defaultSpeed, mMultiplier * 1000.0 / 3600.0 ) );
128  mMultiplier = 3600;
129  }
130  else
131  {
132  mDirector->addStrategy( new QgsNetworkDistanceStrategy() );
133  }
134 
135  mBuilder = qgis::make_unique< QgsGraphBuilder >( mNetwork->sourceCrs(), true, tolerance );
136 }
137 
138 void QgsNetworkAnalysisAlgorithmBase::loadPoints( QgsFeatureSource *source, QVector< QgsPointXY > &points, QHash< int, QgsAttributes > &attributes, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
139 {
140  feedback->pushInfo( QObject::tr( "Loading points…" ) );
141 
142  QgsFeature feat;
143  int i = 0;
144  int pointId = 1;
145  double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 0;
146  QgsFeatureIterator features = source->getFeatures( QgsFeatureRequest().setDestinationCrs( mNetwork->sourceCrs(), context.transformContext() ) );
147 
148  while ( features.nextFeature( feat ) )
149  {
150  i++;
151  if ( feedback->isCanceled() )
152  {
153  break;
154  }
155 
156  feedback->setProgress( i * step );
157  if ( !feat.hasGeometry() )
158  continue;
159 
160  QgsGeometry geom = feat.geometry();
162  while ( it != geom.vertices_end() )
163  {
164  points.push_back( QgsPointXY( *it ) );
165  attributes.insert( pointId, feat.attributes() );
166  it++;
167  pointId++;
168  }
169  }
170 }
171 
QgsNetworkSpeedStrategy
Strategy for calculating edge cost based on travel time.
Definition: qgsnetworkspeedstrategy.h:30
QgsFeedback::setProgress
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:62
QgsProcessingParameterNumber::Double
@ Double
Double/float values.
Definition: qgsprocessingparameters.h:1967
QgsCoordinateReferenceSystem::mapUnits
Q_GADGET QgsUnitTypes::DistanceUnit mapUnits
Definition: qgscoordinatereferencesystem.h:209
QgsProcessingParameterField::Numeric
@ Numeric
Accepts numeric fields.
Definition: qgsprocessingparameters.h:2624
QgsProcessingContext::project
QgsProject * project() const
Returns the project in which the algorithm is being executed.
Definition: qgsprocessingcontext.h:105
QgsProcessingFeedback
Base class for providing feedback from a processing algorithm.
Definition: qgsprocessingfeedback.h:38
qgsnetworkdistancestrategy.h
QgsProcessingFeedback::pushInfo
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
Definition: qgsprocessingfeedback.cpp:48
qgsnetworkspeedstrategy.h
qgsalgorithmnetworkanalysisbase.h
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:67
QgsFeatureSource
An interface for objects which provide features via a getFeatures method.
Definition: qgsfeaturesource.h:38
QgsProcessingParameterDefinition::FlagAdvanced
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
Definition: qgsprocessingparameters.h:423
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
QgsUnitTypes::DistanceUnit
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:68
QgsUnitTypes::fromUnitToUnitFactor
static Q_INVOKABLE double fromUnitToUnitFactor(QgsUnitTypes::DistanceUnit fromUnit, QgsUnitTypes::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
Definition: qgsunittypes.cpp:352
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:44
QgsFeatureSource::getFeatures
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const =0
Returns an iterator for the features in the source.
QgsUnitTypes::DistanceMeters
@ DistanceMeters
Meters.
Definition: qgsunittypes.h:69
QgsProcessingContext::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Definition: qgsprocessingcontext.h:149
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:65
QgsFeatureSource::featureCount
virtual long featureCount() const =0
Returns the number of features contained in the source, or -1 if the feature count is unknown.
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:44
QgsFeedback::isCanceled
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:53
QgsAbstractGeometry::vertex_iterator
The vertex_iterator class provides STL-style iterator for vertices.
Definition: qgsabstractgeometry.h:856
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
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
QgsVectorLayerDirector
Determine making the graph from vector line layer.
Definition: qgsvectorlayerdirector.h:34
qgsgraphanalyzer.h
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsGeometry::vertices_end
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
Definition: qgsgeometry.cpp:1843
QgsProcessingParameterEnum
An enum based parameter for processing algorithms, allowing for selection from predefined values.
Definition: qgsprocessingparameters.h:2256
QgsProcessingAlgorithm::flags
virtual Flags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users.
Definition: qgsprocessingalgorithm.cpp:88
QgsGeometry::vertices_begin
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
Definition: qgsgeometry.cpp:1836
QgsProcessingParameterField::Any
@ Any
Accepts any field.
Definition: qgsprocessingparameters.h:2623
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:265
QgsProject::crs
QgsCoordinateReferenceSystem crs
Definition: qgsproject.h:100
QgsProcessingException
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
QgsNetworkDistanceStrategy
Strategy for calculating edge cost based on its length.
Definition: qgsnetworkdistancestrategy.h:30
QgsVectorLayerDirector::Direction
Direction
Edge direction Edge can be one-way with direct flow (one can move only from the start point to the en...
Definition: qgsvectorlayerdirector.h:47