QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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#include "qgsunittypes.h"
24
26
27//
28// QgsNetworkAnalysisAlgorithmBase
29//
30
31QString QgsNetworkAnalysisAlgorithmBase::group() const
32{
33 return QObject::tr( "Network analysis" );
34}
35
36QString QgsNetworkAnalysisAlgorithmBase::groupId() const
37{
38 return QStringLiteral( "networkanalysis" );
39}
40
41Qgis::ProcessingAlgorithmFlags QgsNetworkAnalysisAlgorithmBase::flags() const
42{
43 // TODO -- remove the dependency on the project from these algorithms, it shouldn't be required
45}
46
47void QgsNetworkAnalysisAlgorithmBase::addCommonParams()
48{
49 addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Vector layer representing network" ), QList< int >() << static_cast< int >( Qgis::ProcessingSourceType::VectorLine ) ) );
50 addParameter( new QgsProcessingParameterEnum( QStringLiteral( "STRATEGY" ), QObject::tr( "Path type to calculate" ), QStringList() << QObject::tr( "Shortest" ) << QObject::tr( "Fastest" ), false, 0 ) );
51
52 std::unique_ptr< QgsProcessingParameterField > directionField = std::make_unique< QgsProcessingParameterField >( QStringLiteral( "DIRECTION_FIELD" ),
53 QObject::tr( "Direction field" ), QVariant(), QStringLiteral( "INPUT" ), Qgis::ProcessingFieldParameterDataType::Any, false, true );
54 directionField->setFlags( directionField->flags() | Qgis::ProcessingParameterFlag::Advanced );
55 addParameter( directionField.release() );
56
57 std::unique_ptr< QgsProcessingParameterString > forwardValue = std::make_unique< QgsProcessingParameterString >( QStringLiteral( "VALUE_FORWARD" ),
58 QObject::tr( "Value for forward direction" ), QVariant(), false, true );
59 forwardValue->setFlags( forwardValue->flags() | Qgis::ProcessingParameterFlag::Advanced );
60 addParameter( forwardValue.release() );
61
62 std::unique_ptr< QgsProcessingParameterString > backwardValue = std::make_unique< QgsProcessingParameterString >( QStringLiteral( "VALUE_BACKWARD" ),
63 QObject::tr( "Value for backward direction" ), QVariant(), false, true );
64 backwardValue->setFlags( backwardValue->flags() | Qgis::ProcessingParameterFlag::Advanced );
65 addParameter( backwardValue.release() );
66
67 std::unique_ptr< QgsProcessingParameterString > bothValue = std::make_unique< QgsProcessingParameterString >( QStringLiteral( "VALUE_BOTH" ),
68 QObject::tr( "Value for both directions" ), QVariant(), false, true );
69 bothValue->setFlags( bothValue->flags() | Qgis::ProcessingParameterFlag::Advanced );
70 addParameter( bothValue.release() );
71
72 std::unique_ptr< QgsProcessingParameterEnum > directionValue = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "DEFAULT_DIRECTION" ),
73 QObject::tr( "Default direction" ), QStringList() << QObject::tr( "Forward direction" ) << QObject::tr( "Backward direction" ) << QObject::tr( "Both directions" ), false, 2 );
74 directionValue->setFlags( directionValue->flags() | Qgis::ProcessingParameterFlag::Advanced );
75 addParameter( directionValue.release() );
76
77 std::unique_ptr< QgsProcessingParameterField > speedField = std::make_unique< QgsProcessingParameterField >( QStringLiteral( "SPEED_FIELD" ),
78 QObject::tr( "Speed field" ), QVariant(), QStringLiteral( "INPUT" ), Qgis::ProcessingFieldParameterDataType::Numeric, false, true );
79 speedField->setFlags( speedField->flags() | Qgis::ProcessingParameterFlag::Advanced );
80 addParameter( speedField.release() );
81
82 std::unique_ptr< QgsProcessingParameterNumber > speed = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "DEFAULT_SPEED" ), QObject::tr( "Default speed (km/h)" ), Qgis::ProcessingNumberParameterType::Double, 50, false, 0 );
83 speed->setFlags( speed->flags() | Qgis::ProcessingParameterFlag::Advanced );
84 addParameter( speed.release() );
85
86 std::unique_ptr< QgsProcessingParameterNumber > tolerance = std::make_unique < QgsProcessingParameterDistance >( QStringLiteral( "TOLERANCE" ), QObject::tr( "Topology tolerance" ), 0, QStringLiteral( "INPUT" ), false, 0 );
87 tolerance->setFlags( tolerance->flags() | Qgis::ProcessingParameterFlag::Advanced );
88 addParameter( tolerance.release() );
89}
90
91void QgsNetworkAnalysisAlgorithmBase::loadCommonParams( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
92{
93 Q_UNUSED( feedback )
94
95 mNetwork.reset( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
96 if ( !mNetwork )
97 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
98
99 const int strategy = parameterAsInt( parameters, QStringLiteral( "STRATEGY" ), context );
100 const QString directionFieldName = parameterAsString( parameters, QStringLiteral( "DIRECTION_FIELD" ), context );
101 const QString forwardValue = parameterAsString( parameters, QStringLiteral( "VALUE_FORWARD" ), context );
102 const QString backwardValue = parameterAsString( parameters, QStringLiteral( "VALUE_BACKWARD" ), context );
103 const QString bothValue = parameterAsString( parameters, QStringLiteral( "VALUE_BOTH" ), context );
104 const QgsVectorLayerDirector::Direction defaultDirection = static_cast< QgsVectorLayerDirector::Direction>( parameterAsInt( parameters, QStringLiteral( "DEFAULT_DIRECTION" ), context ) );
105 const QString speedFieldName = parameterAsString( parameters, QStringLiteral( "SPEED_FIELD" ), context );
106 const double defaultSpeed = parameterAsDouble( parameters, QStringLiteral( "DEFAULT_SPEED" ), context );
107 const double tolerance = parameterAsDouble( parameters, QStringLiteral( "TOLERANCE" ), context );
108
109 int directionField = -1;
110 if ( !directionFieldName.isEmpty() )
111 {
112 directionField = mNetwork->fields().lookupField( directionFieldName );
113 }
114
115 int speedField = -1;
116 if ( !speedFieldName.isEmpty() )
117 {
118 speedField = mNetwork->fields().lookupField( speedFieldName );
119 }
120
121 mDirector = new QgsVectorLayerDirector( mNetwork.get(), directionField, forwardValue, backwardValue, bothValue, defaultDirection );
122
123 const Qgis::DistanceUnit distanceUnits = context.project()->crs().mapUnits();
125
126 if ( strategy )
127 {
128 mDirector->addStrategy( new QgsNetworkSpeedStrategy( speedField, defaultSpeed, mMultiplier * 1000.0 / 3600.0 ) );
129 mMultiplier = 3600;
130 }
131 else
132 {
133 mDirector->addStrategy( new QgsNetworkDistanceStrategy() );
134 }
135
136 mBuilder = std::make_unique< QgsGraphBuilder >( mNetwork->sourceCrs(), true, tolerance, context.ellipsoid() );
137}
138
139void QgsNetworkAnalysisAlgorithmBase::loadPoints( QgsFeatureSource *source, QVector< QgsPointXY > &points, QHash< int, QgsAttributes > &attributes, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
140{
141 feedback->pushInfo( QObject::tr( "Loading points…" ) );
142
143 QgsFeature feat;
144 int i = 0;
145 int pointId = 1;
146 const double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 0;
147 QgsFeatureIterator features = source->getFeatures( QgsFeatureRequest().setDestinationCrs( mNetwork->sourceCrs(), context.transformContext() ) );
148
149 while ( features.nextFeature( feat ) )
150 {
151 i++;
152 if ( feedback->isCanceled() )
153 {
154 break;
155 }
156
157 feedback->setProgress( i * step );
158 if ( !feat.hasGeometry() )
159 continue;
160
161 const QgsGeometry geom = feat.geometry();
163 while ( it != geom.vertices_end() )
164 {
165 points.push_back( QgsPointXY( *it ) );
166 attributes.insert( pointId, feat.attributes() );
167 it++;
168 pointId++;
169 }
170 }
171}
172
@ VectorLine
Vector line layers.
DistanceUnit
Units of distance.
Definition: qgis.h:4124
@ Numeric
Accepts numeric fields.
QFlags< ProcessingAlgorithmFlag > ProcessingAlgorithmFlags
Flags indicating how and when an algorithm operates and should be exposed to users.
Definition: qgis.h:2934
@ RequiresProject
The algorithm requires that a valid QgsProject is available from the processing context in order to e...
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
The vertex_iterator class provides STL-style iterator for vertices.
Q_GADGET Qgis::DistanceUnit mapUnits
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
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:230
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:53
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:61
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:162
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:60
virtual Qgis::ProcessingAlgorithmFlags 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.
QString ellipsoid() const
Returns the ellipsoid to use for distance and area calculations.
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.
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.
QgsCoordinateReferenceSystem crs
Definition: qgsproject.h:112
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::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...