QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 = std::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 = std::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 = std::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 = std::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 = std::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 = std::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 = std::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 = std::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  const int strategy = parameterAsInt( parameters, QStringLiteral( "STRATEGY" ), context );
99  const QString directionFieldName = parameterAsString( parameters, QStringLiteral( "DIRECTION_FIELD" ), context );
100  const QString forwardValue = parameterAsString( parameters, QStringLiteral( "VALUE_FORWARD" ), context );
101  const QString backwardValue = parameterAsString( parameters, QStringLiteral( "VALUE_BACKWARD" ), context );
102  const QString bothValue = parameterAsString( parameters, QStringLiteral( "VALUE_BOTH" ), context );
103  const QgsVectorLayerDirector::Direction defaultDirection = static_cast< QgsVectorLayerDirector::Direction>( parameterAsInt( parameters, QStringLiteral( "DEFAULT_DIRECTION" ), context ) );
104  const QString speedFieldName = parameterAsString( parameters, QStringLiteral( "SPEED_FIELD" ), context );
105  const double defaultSpeed = parameterAsDouble( parameters, QStringLiteral( "DEFAULT_SPEED" ), context );
106  const 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  const 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 = std::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  const 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  const 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 
The vertex_iterator class provides STL-style iterator for vertices.
Q_GADGET QgsUnitTypes::DistanceUnit mapUnits
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
An interface for objects which provide features via a getFeatures method.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const =0
Returns an iterator for the features in the source.
virtual long long featureCount() const =0
Returns the number of features contained in the source, or -1 if the feature count is unknown.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsAttributes attributes
Definition: qgsfeature.h:65
QgsGeometry geometry
Definition: qgsfeature.h:67
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:223
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
Strategy for calculating edge cost based on its length.
Strategy for calculating edge cost based on travel time.
A class to represent a 2D point.
Definition: qgspointxy.h:59
virtual Flags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users.
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
QgsProject * project() const
Returns the project in which the algorithm is being executed.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
Base class for providing feedback from a processing algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
An input feature source (such as vector layers) parameter for processing algorithms.
@ Numeric
Accepts numeric fields.
@ TypeVectorLine
Vector line layers.
Definition: qgsprocessing.h:50
QgsCoordinateReferenceSystem crs
Definition: qgsproject.h:106
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:68
@ DistanceMeters
Meters.
Definition: qgsunittypes.h:69
static Q_INVOKABLE double fromUnitToUnitFactor(QgsUnitTypes::DistanceUnit fromUnit, QgsUnitTypes::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
Determine making the graph from vector line layer.
Direction
Edge direction Edge can be one-way with direct flow (one can move only from the start point to the en...