26QString QgsShortestPathPointToLayerAlgorithm::name()
const
28 return QStringLiteral(
"shortestpathpointtolayer" );
31QString QgsShortestPathPointToLayerAlgorithm::displayName()
const
33 return QObject::tr(
"Shortest path (point to layer)" );
36QStringList QgsShortestPathPointToLayerAlgorithm::tags()
const
38 return QObject::tr(
"network,path,shortest,fastest" ).split(
',' );
41QString QgsShortestPathPointToLayerAlgorithm::shortHelpString()
const
43 return QObject::tr(
"This algorithm computes optimal (shortest or fastest) route between given start point and multiple end points defined by point vector layer." );
46QgsShortestPathPointToLayerAlgorithm *QgsShortestPathPointToLayerAlgorithm::createInstance()
const
48 return new QgsShortestPathPointToLayerAlgorithm();
51void QgsShortestPathPointToLayerAlgorithm::initAlgorithm(
const QVariantMap & )
57 std::unique_ptr< QgsProcessingParameterNumber > maxEndPointDistanceFromNetwork = std::make_unique < QgsProcessingParameterDistance >( QStringLiteral(
"POINT_TOLERANCE" ), QObject::tr(
"Maximum point distance from network" ), QVariant(), QStringLiteral(
"INPUT" ),
true, 0 );
59 maxEndPointDistanceFromNetwork->setHelp( QObject::tr(
"Specifies an optional limit on the distance from the start and end points to the network layer.If the start point is further from the network than this distance an error will be raised. If the end feature is further from the network than this distance it will be treated as non-routable." ) );
60 addParameter( maxEndPointDistanceFromNetwork.release() );
64 std::unique_ptr< QgsProcessingParameterFeatureSink > outputNonRoutable = std::make_unique< QgsProcessingParameterFeatureSink >( QStringLiteral(
"OUTPUT_NON_ROUTABLE" ), QObject::tr(
"Non-routable features" ),
66 outputNonRoutable->setHelp( QObject::tr(
"An optional output which will be used to store any input features which could not be routed (e.g. those which are too far from the network layer)." ) );
67 outputNonRoutable->setCreateByDefault(
false );
68 addParameter( outputNonRoutable.release() );
73 loadCommonParams( parameters, context, feedback );
75 const QgsPointXY startPoint = parameterAsPoint( parameters, QStringLiteral(
"START_POINT" ), context, mNetwork->sourceCrs() );
77 std::unique_ptr< QgsFeatureSource > endPoints( parameterAsSource( parameters, QStringLiteral(
"END_POINTS" ), context ) );
82 fields.
append(
QgsField( QStringLiteral(
"start" ), QMetaType::Type::QString ) );
83 fields.
append(
QgsField( QStringLiteral(
"end" ), QMetaType::Type::QString ) );
84 fields.
append(
QgsField( QStringLiteral(
"cost" ), QMetaType::Type::Double ) );
91 QString nonRoutableSinkId;
92 std::unique_ptr< QgsFeatureSink > nonRoutableSink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT_NON_ROUTABLE" ), context, nonRoutableSinkId, endPoints->fields(),
95 const double pointDistanceThreshold = parameters.value( QStringLiteral(
"POINT_TOLERANCE" ) ).isValid() ? parameterAsDouble( parameters, QStringLiteral(
"POINT_TOLERANCE" ), context ) : -1;
97 QVector< QgsPointXY > points;
98 points.push_front( startPoint );
99 QHash< int, QgsAttributes > sourceAttributes;
100 loadPoints( endPoints.get(), points, sourceAttributes, context, feedback );
102 feedback->
pushInfo( QObject::tr(
"Building graph…" ) );
103 QVector< QgsPointXY > snappedPoints;
104 mDirector->makeGraph( mBuilder.get(), points, snappedPoints, feedback );
106 const QgsPointXY snappedStartPoint = snappedPoints[0];
108 if ( pointDistanceThreshold >= 0 )
110 const double distanceStartPointToNetwork = mBuilder->distanceArea()->measureLine( startPoint, snappedStartPoint );
111 if ( distanceStartPointToNetwork > pointDistanceThreshold )
113 throw QgsProcessingException( QObject::tr(
"Start point is too far from the network layer (%1, maximum permitted is %2)" ).arg( distanceStartPointToNetwork ).arg( pointDistanceThreshold ) );
117 feedback->
pushInfo( QObject::tr(
"Calculating shortest paths…" ) );
118 std::unique_ptr< QgsGraph > graph( mBuilder->takeGraph() );
119 const int idxStart = graph->findVertex( snappedStartPoint );
123 QVector< double > costs;
126 QVector<QgsPointXY> route;
133 const double step = points.size() > 0 ? 100.0 / points.size() : 1;
134 for (
int i = 1; i < points.size(); i++ )
141 const QgsPointXY snappedPoint = snappedPoints.at( i );
142 const QgsPointXY originalPoint = points.at( i );
144 if ( pointDistanceThreshold >= 0 )
146 const double distancePointToNetwork = mBuilder->distanceArea()->measureLine( originalPoint, snappedPoint );
147 if ( distancePointToNetwork > pointDistanceThreshold )
149 feedback->
pushWarning( QObject::tr(
"Point is too far from the network layer (%1, maximum permitted is %2)" ).arg( distancePointToNetwork ).arg( pointDistanceThreshold ) );
150 if ( nonRoutableSink )
153 attributes = sourceAttributes.value( i );
156 throw QgsProcessingException( writeFeatureError( nonRoutableSink.get(), parameters, QStringLiteral(
"OUTPUT_NON_ROUTABLE" ) ) );
164 idxEnd = graph->findVertex( snappedPoint );
165 if ( tree.at( idxEnd ) == -1 )
167 feedback->
reportError( QObject::tr(
"There is no route from start point (%1) to end point (%2)." )
171 attributes = sourceAttributes.value( i );
172 attributes.append( QVariant() );
173 attributes.append( originalPoint.
toString() );
181 route.push_front( graph->vertex( idxEnd ).point() );
182 cost = costs.at( idxEnd );
183 while ( idxEnd != idxStart )
185 idxEnd = graph->edge( tree.at( idxEnd ) ).fromVertex();
186 route.push_front( graph->vertex( idxEnd ).point() );
192 attributes = sourceAttributes.value( i );
193 attributes.append( startPoint.
toString() );
194 attributes.append( originalPoint.
toString() );
195 attributes.append( cost / mMultiplier );
205 outputs.insert( QStringLiteral(
"OUTPUT" ), dest );
206 if ( nonRoutableSink )
208 outputs.insert( QStringLiteral(
"OUTPUT_NON_ROUTABLE" ), nonRoutableSinkId );
@ VectorPoint
Vector point layers.
@ VectorLine
Vector line layers.
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
void setFields(const QgsFields &fields, bool initAttributes=false)
Assigns a field map with the feature to allow attribute access by attribute name.
void clearGeometry()
Removes any geometry associated with the feature.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool isCanceled() const
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
A geometry is the spatial representation of a feature.
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
static void dijkstra(const QgsGraph *source, int startVertexIdx, int criterionNum, QVector< int > *resultTree=nullptr, QVector< double > *resultCost=nullptr)
Solve shortest path problem using Dijkstra algorithm.
A class to represent a 2D point.
QString toString(int precision=-1) const
Returns a string representation of the point (x, y) with a preset precision.
Contains information about the context in which a processing algorithm is executed.
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.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A point parameter for processing algorithms.