QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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 
QgsProject * project() const
Returns the project in which the algorithm is being executed.
Wrapper for iterator of features from vector data provider or vector layer.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
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.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry...
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
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:106
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
Strategy for calculating edge cost based on travel time.
An enum based parameter for processing algorithms, allowing for selection from predefined values...
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
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:53
An interface for objects which provide features via a getFeatures method.
An input feature source (such as vector layers) parameter for processing algorithms.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Vector line layers.
Definition: qgsprocessing.h:49
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
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.
Contains information about the context in which a processing algorithm is executed.
QgsAttributes attributes
Definition: qgsfeature.h:65
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
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...