QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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 void QgsNetworkAnalysisAlgorithmBase::addCommonParams()
41 {
42  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Vector layer representing network" ), QList< int >() << QgsProcessing::TypeVectorLine ) );
43  addParameter( new QgsProcessingParameterEnum( QStringLiteral( "STRATEGY" ), QObject::tr( "Path type to calculate" ), QStringList() << QObject::tr( "Shortest" ) << QObject::tr( "Fastest" ), false, 0 ) );
44 
45  std::unique_ptr< QgsProcessingParameterField > directionField = qgis::make_unique< QgsProcessingParameterField >( QStringLiteral( "DIRECTION_FIELD" ),
46  QObject::tr( "Direction field" ), QVariant(), QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, false, true );
47  directionField->setFlags( directionField->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
48  addParameter( directionField.release() );
49 
50  std::unique_ptr< QgsProcessingParameterString > forwardValue = qgis::make_unique< QgsProcessingParameterString >( QStringLiteral( "VALUE_FORWARD" ),
51  QObject::tr( "Value for forward direction" ), QVariant(), false, true );
52  forwardValue->setFlags( forwardValue->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
53  addParameter( forwardValue.release() );
54 
55  std::unique_ptr< QgsProcessingParameterString > backwardValue = qgis::make_unique< QgsProcessingParameterString >( QStringLiteral( "VALUE_BACKWARD" ),
56  QObject::tr( "Value for backward direction" ), QVariant(), false, true );
57  backwardValue->setFlags( backwardValue->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
58  addParameter( backwardValue.release() );
59 
60  std::unique_ptr< QgsProcessingParameterString > bothValue = qgis::make_unique< QgsProcessingParameterString >( QStringLiteral( "VALUE_BOTH" ),
61  QObject::tr( "Value for both directions" ), QVariant(), false, true );
62  bothValue->setFlags( bothValue->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
63  addParameter( bothValue.release() );
64 
65  std::unique_ptr< QgsProcessingParameterEnum > directionValue = qgis::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "DEFAULT_DIRECTION" ),
66  QObject::tr( "Default direction" ), QStringList() << QObject::tr( "Forward direction" ) << QObject::tr( "Backward direction" ) << QObject::tr( "Both directions" ), false, 2 );
67  directionValue->setFlags( directionValue->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
68  addParameter( directionValue.release() );
69 
70  std::unique_ptr< QgsProcessingParameterField > speedField = qgis::make_unique< QgsProcessingParameterField >( QStringLiteral( "SPEED_FIELD" ),
71  QObject::tr( "Speed field" ), QVariant(), QStringLiteral( "INPUT" ), QgsProcessingParameterField::Numeric, false, true );
72  speedField->setFlags( speedField->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
73  addParameter( speedField.release() );
74 
75  std::unique_ptr< QgsProcessingParameterNumber > speed = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "DEFAULT_SPEED" ), QObject::tr( "Default speed (km/h)" ), QgsProcessingParameterNumber::Double, 50, false, 0 );
76  speed->setFlags( speed->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
77  addParameter( speed.release() );
78 
79  std::unique_ptr< QgsProcessingParameterNumber > tolerance = qgis::make_unique < QgsProcessingParameterDistance >( QStringLiteral( "TOLERANCE" ), QObject::tr( "Topology tolerance" ), 0, QStringLiteral( "INPUT" ), false, 0 );
80  tolerance->setFlags( tolerance->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
81  addParameter( tolerance.release() );
82 }
83 
84 void QgsNetworkAnalysisAlgorithmBase::loadCommonParams( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
85 {
86  Q_UNUSED( feedback )
87 
88  mNetwork.reset( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
89  if ( !mNetwork )
90  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
91 
92  int strategy = parameterAsInt( parameters, QStringLiteral( "STRATEGY" ), context );
93  QString directionFieldName = parameterAsString( parameters, QStringLiteral( "DIRECTION_FIELD" ), context );
94  QString forwardValue = parameterAsString( parameters, QStringLiteral( "VALUE_FORWARD" ), context );
95  QString backwardValue = parameterAsString( parameters, QStringLiteral( "VALUE_BACKWARD" ), context );
96  QString bothValue = parameterAsString( parameters, QStringLiteral( "VALUE_BOTH" ), context );
97  QgsVectorLayerDirector::Direction defaultDirection = static_cast< QgsVectorLayerDirector::Direction>( parameterAsInt( parameters, QStringLiteral( "DEFAULT_DIRECTION" ), context ) );
98  QString speedFieldName = parameterAsString( parameters, QStringLiteral( "SPEED_FIELD" ), context );
99  double defaultSpeed = parameterAsDouble( parameters, QStringLiteral( "DEFAULT_SPEED" ), context );
100  double tolerance = parameterAsDouble( parameters, QStringLiteral( "TOLERANCE" ), context );
101 
102  int directionField = -1;
103  if ( !directionFieldName.isEmpty() )
104  {
105  directionField = mNetwork->fields().lookupField( directionFieldName );
106  }
107 
108  int speedField = -1;
109  if ( !speedFieldName.isEmpty() )
110  {
111  speedField = mNetwork->fields().lookupField( speedFieldName );
112  }
113 
114  mDirector = new QgsVectorLayerDirector( mNetwork.get(), directionField, forwardValue, backwardValue, bothValue, defaultDirection );
115 
116  QgsUnitTypes::DistanceUnit distanceUnits = context.project()->crs().mapUnits();
118 
119  if ( strategy )
120  {
121  mDirector->addStrategy( new QgsNetworkSpeedStrategy( speedField, defaultSpeed, mMultiplier * 1000.0 / 3600.0 ) );
122  mMultiplier = 3600;
123  }
124  else
125  {
126  mDirector->addStrategy( new QgsNetworkDistanceStrategy() );
127  }
128 
129  mBuilder = qgis::make_unique< QgsGraphBuilder >( mNetwork->sourceCrs(), true, tolerance );
130 }
131 
132 void QgsNetworkAnalysisAlgorithmBase::loadPoints( QgsFeatureSource *source, QVector< QgsPointXY > &points, QHash< int, QgsAttributes > &attributes, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
133 {
134  feedback->pushInfo( QObject::tr( "Loading points…" ) );
135 
136  QgsFeature feat;
137  int i = 0;
138  int pointId = 1;
139  double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 0;
140  QgsFeatureIterator features = source->getFeatures( QgsFeatureRequest().setDestinationCrs( mNetwork->sourceCrs(), context.transformContext() ) );
141 
142  while ( features.nextFeature( feat ) )
143  {
144  i++;
145  if ( feedback->isCanceled() )
146  {
147  break;
148  }
149 
150  feedback->setProgress( i * step );
151  if ( !feat.hasGeometry() )
152  continue;
153 
154  QgsGeometry geom = feat.geometry();
156  while ( it != geom.vertices_end() )
157  {
158  points.push_back( QgsPointXY( *it ) );
159  attributes.insert( pointId, feat.attributes() );
160  it++;
161  pointId++;
162  }
163  }
164 }
165 
Wrapper for iterator of features from vector data provider or vector layer.
Direction
Edge direction Edge can be one-way with direct flow (one can move only from the start point to the en...
Base class for providing feedback from a processing algorithm.
Parameter is an advanced parameter which should be hidden from users by default.
Determine making the graph from vector line layer.
A class to represent a 2D point.
Definition: qgspointxy.h:43
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:111
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
Strategy for calculating edge cost based on travel time.
QgsProject * project() const
Returns the project in which the algorithm is being executed.
An enum based parameter for processing algorithms, allowing for selection from predefined values...
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
QgsCoordinateReferenceSystem crs
Definition: qgsproject.h:95
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
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
The vertex_iterator class provides STL-style iterator for vertices.
Strategy for calculating edge cost based on its length.
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:54
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
An interface for objects which provide features via a getFeatures method.
An input feature source (such as vector layers) parameter for processing algorithms.
Vector line layers.
Definition: qgsprocessing.h:49
QgsGeometry geometry
Definition: qgsfeature.h:67
bool nextFeature(QgsFeature &f)
static Q_INVOKABLE double fromUnitToUnitFactor(QgsUnitTypes::DistanceUnit fromUnit, QgsUnitTypes::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry...
Contains information about the context in which a processing algorithm is executed.
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
QgsAttributes attributes
Definition: qgsfeature.h:65
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const =0
Returns an iterator for the features in the source.
virtual long featureCount() const =0
Returns the number of features contained in the source, or -1 if the feature count is unknown...