QGIS API Documentation 3.99.0-Master (357b655ed83)
Loading...
Searching...
No Matches
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
25#include <QString>
26
27using namespace Qt::StringLiterals;
28
30
31//
32// QgsNetworkAnalysisAlgorithmBase
33//
34
35QString QgsNetworkAnalysisAlgorithmBase::group() const
36{
37 return QObject::tr( "Network analysis" );
38}
39
40QString QgsNetworkAnalysisAlgorithmBase::groupId() const
41{
42 return u"networkanalysis"_s;
43}
44
45Qgis::ProcessingAlgorithmFlags QgsNetworkAnalysisAlgorithmBase::flags() const
46{
47 // TODO -- remove the dependency on the project from these algorithms, it shouldn't be required
49}
50
51Qgis::ProcessingAlgorithmDocumentationFlags QgsNetworkAnalysisAlgorithmBase::documentationFlags() const
52{
54}
55
56void QgsNetworkAnalysisAlgorithmBase::addCommonParams()
57{
58 addParameter( new QgsProcessingParameterFeatureSource( u"INPUT"_s, QObject::tr( "Vector layer representing network" ), QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorLine ) ) );
59 addParameter( new QgsProcessingParameterEnum( u"STRATEGY"_s, QObject::tr( "Path type to calculate" ), QStringList() << QObject::tr( "Shortest" ) << QObject::tr( "Fastest" ), false, 0 ) );
60
61 auto directionField = std::make_unique<QgsProcessingParameterField>( u"DIRECTION_FIELD"_s, QObject::tr( "Direction field" ), QVariant(), u"INPUT"_s, Qgis::ProcessingFieldParameterDataType::Any, false, true );
62 directionField->setHelp( QObject::tr( "The attribute field specifying the direction of traffic flow for each segment." ) );
63 directionField->setFlags( directionField->flags() | Qgis::ProcessingParameterFlag::Advanced );
64 addParameter( directionField.release() );
65
66 auto forwardValue = std::make_unique<QgsProcessingParameterString>( u"VALUE_FORWARD"_s, QObject::tr( "Value for forward direction" ), QVariant(), false, true );
67 forwardValue->setHelp( QObject::tr( "The string value in the direction field that indicates one-way traffic in the digitized direction." ) );
68 forwardValue->setFlags( forwardValue->flags() | Qgis::ProcessingParameterFlag::Advanced );
69 addParameter( forwardValue.release() );
70
71 auto backwardValue = std::make_unique<QgsProcessingParameterString>( u"VALUE_BACKWARD"_s, QObject::tr( "Value for backward direction" ), QVariant(), false, true );
72 backwardValue->setHelp( QObject::tr( "The string value in the direction field that indicates one-way traffic opposite to the digitized direction." ) );
73 backwardValue->setFlags( backwardValue->flags() | Qgis::ProcessingParameterFlag::Advanced );
74 addParameter( backwardValue.release() );
75
76 auto bothValue = std::make_unique<QgsProcessingParameterString>( u"VALUE_BOTH"_s, QObject::tr( "Value for both directions" ), QVariant(), false, true );
77 bothValue->setHelp( QObject::tr( "The string value in the direction field that indicates two-way traffic." ) );
78 bothValue->setFlags( bothValue->flags() | Qgis::ProcessingParameterFlag::Advanced );
79 addParameter( bothValue.release() );
80
81 auto directionValue = std::make_unique<QgsProcessingParameterEnum>( u"DEFAULT_DIRECTION"_s, QObject::tr( "Default direction" ), QStringList() << QObject::tr( "Forward direction" ) << QObject::tr( "Backward direction" ) << QObject::tr( "Both directions" ), false, 2 );
82 directionValue->setFlags( directionValue->flags() | Qgis::ProcessingParameterFlag::Advanced );
83 addParameter( directionValue.release() );
84
85 auto speedField = std::make_unique<QgsProcessingParameterField>( u"SPEED_FIELD"_s, QObject::tr( "Speed field" ), QVariant(), u"INPUT"_s, Qgis::ProcessingFieldParameterDataType::Numeric, false, true );
86 speedField->setFlags( speedField->flags() | Qgis::ProcessingParameterFlag::Advanced );
87 addParameter( speedField.release() );
88
89 auto speed = std::make_unique<QgsProcessingParameterNumber>( u"DEFAULT_SPEED"_s, QObject::tr( "Default speed (km/h)" ), Qgis::ProcessingNumberParameterType::Double, 50, false, 0 );
90 speed->setFlags( speed->flags() | Qgis::ProcessingParameterFlag::Advanced );
91 addParameter( speed.release() );
92
93 std::unique_ptr<QgsProcessingParameterNumber> tolerance = std::make_unique<QgsProcessingParameterDistance>( u"TOLERANCE"_s, QObject::tr( "Topology tolerance" ), 0, u"INPUT"_s, false, 0 );
94 tolerance->setFlags( tolerance->flags() | Qgis::ProcessingParameterFlag::Advanced );
95 addParameter( tolerance.release() );
96}
97
98void QgsNetworkAnalysisAlgorithmBase::loadCommonParams( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
99{
100 Q_UNUSED( feedback )
101
102 mNetwork.reset( parameterAsSource( parameters, u"INPUT"_s, context ) );
103 if ( !mNetwork )
104 throw QgsProcessingException( invalidSourceError( parameters, u"INPUT"_s ) );
105
106 const int strategy = parameterAsInt( parameters, u"STRATEGY"_s, context );
107 const QString directionFieldName = parameterAsString( parameters, u"DIRECTION_FIELD"_s, context );
108 const QString forwardValue = parameterAsString( parameters, u"VALUE_FORWARD"_s, context );
109 const QString backwardValue = parameterAsString( parameters, u"VALUE_BACKWARD"_s, context );
110 const QString bothValue = parameterAsString( parameters, u"VALUE_BOTH"_s, context );
111 const QgsVectorLayerDirector::Direction defaultDirection = static_cast<QgsVectorLayerDirector::Direction>( parameterAsInt( parameters, u"DEFAULT_DIRECTION"_s, context ) );
112 const QString speedFieldName = parameterAsString( parameters, u"SPEED_FIELD"_s, context );
113 const double defaultSpeed = parameterAsDouble( parameters, u"DEFAULT_SPEED"_s, context );
114 const double tolerance = parameterAsDouble( parameters, u"TOLERANCE"_s, context );
115
116 int directionField = -1;
117 if ( !directionFieldName.isEmpty() )
118 {
119 directionField = mNetwork->fields().lookupField( directionFieldName );
120 }
121
122 int speedField = -1;
123 if ( !speedFieldName.isEmpty() )
124 {
125 speedField = mNetwork->fields().lookupField( speedFieldName );
126 }
127
128 mDirector = new QgsVectorLayerDirector( mNetwork.get(), directionField, forwardValue, backwardValue, bothValue, defaultDirection );
129
130 const Qgis::DistanceUnit distanceUnits = context.project()->crs().mapUnits();
132
133 if ( strategy )
134 {
135 mDirector->addStrategy( new QgsNetworkSpeedStrategy( speedField, defaultSpeed, mMultiplier * 1000.0 / 3600.0 ) );
136 mMultiplier = 3600;
137 }
138 else
139 {
140 mDirector->addStrategy( new QgsNetworkDistanceStrategy() );
141 }
142
143 mBuilder = std::make_unique<QgsGraphBuilder>( mNetwork->sourceCrs(), true, tolerance, context.ellipsoid() );
144}
145
146void QgsNetworkAnalysisAlgorithmBase::loadPoints( QgsFeatureSource *source, QVector<QgsPointXY> *points, QHash<int, QgsAttributes> *attributes, QgsProcessingContext &context, QgsProcessingFeedback *feedback, QHash<int, QgsFeature> *featureHash )
147{
148 feedback->pushInfo( QObject::tr( "Loading points…" ) );
149
150 QgsFeature feat;
151 int i = 0;
152 int pointId = 1;
153 const double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 0;
154 QgsFeatureIterator features = source->getFeatures( QgsFeatureRequest().setDestinationCrs( mNetwork->sourceCrs(), context.transformContext() ) );
155
156 while ( features.nextFeature( feat ) )
157 {
158 i++;
159 if ( feedback->isCanceled() )
160 {
161 break;
162 }
163
164 feedback->setProgress( i * step );
165 if ( !feat.hasGeometry() )
166 continue;
167
168 const QgsGeometry geom = feat.geometry();
170 while ( it != geom.vertices_end() )
171 {
172 if ( points )
173 points->push_back( QgsPointXY( *it ) );
174 if ( attributes )
175 attributes->insert( pointId, feat.attributes() );
176 if ( featureHash )
177 featureHash->insert( pointId, feat );
178 it++;
179 pointId++;
180 }
181 }
182}
183
@ VectorLine
Vector line layers.
Definition qgis.h:3606
DistanceUnit
Units of distance.
Definition qgis.h:5120
@ Meters
Meters.
Definition qgis.h:5121
@ Numeric
Accepts numeric fields.
Definition qgis.h:3889
@ RespectsEllipsoid
Algorithm respects the context's ellipsoid settings, and uses ellipsoidal based measurements.
Definition qgis.h:3692
QFlags< ProcessingAlgorithmFlag > ProcessingAlgorithmFlags
Flags indicating how and when an algorithm operates and should be exposed to users.
Definition qgis.h:3680
QFlags< ProcessingAlgorithmDocumentationFlag > ProcessingAlgorithmDocumentationFlags
Flags describing algorithm behavior for documentation purposes.
Definition qgis.h:3701
@ RequiresProject
The algorithm requires that a valid QgsProject is available from the processing context in order to e...
Definition qgis.h:3667
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
Definition qgis.h:3834
@ Double
Double/float values.
Definition qgis.h:3875
The vertex_iterator class provides an STL-style iterator for vertices.
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.
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:60
QgsAttributes attributes
Definition qgsfeature.h:69
QgsGeometry geometry
Definition qgsfeature.h:71
bool hasGeometry() const
Returns true if the feature has an associated geometry.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:55
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.
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.
Represents a 2D point.
Definition qgspointxy.h:62
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.
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:119
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
Determines creating a graph from a 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...