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 a given start point " 
   44                      "and multiple end points defined by a point vector layer." );
 
   47QString QgsShortestPathPointToLayerAlgorithm::shortDescription()
 const 
   49  return QObject::tr( 
"Computes optimal (shortest or fastest) route between a given start point " 
   50                      "and multiple end points defined by a point vector layer." );
 
   58QgsShortestPathPointToLayerAlgorithm *QgsShortestPathPointToLayerAlgorithm::createInstance()
 const 
   60  return new QgsShortestPathPointToLayerAlgorithm();
 
   63void QgsShortestPathPointToLayerAlgorithm::initAlgorithm( 
const QVariantMap & )
 
   69  std::unique_ptr<QgsProcessingParameterNumber> maxEndPointDistanceFromNetwork = std::make_unique<QgsProcessingParameterDistance>( QStringLiteral( 
"POINT_TOLERANCE" ), QObject::tr( 
"Maximum point distance from network" ), QVariant(), QStringLiteral( 
"INPUT" ), 
true, 0 );
 
   71  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." ) );
 
   72  addParameter( maxEndPointDistanceFromNetwork.release() );
 
   76  auto outputNonRoutable = std::make_unique<QgsProcessingParameterFeatureSink>( QStringLiteral( 
"OUTPUT_NON_ROUTABLE" ), QObject::tr( 
"Non-routable features" ), 
Qgis::ProcessingSourceType::VectorPoint, QVariant(), 
true );
 
   77  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)." ) );
 
   78  outputNonRoutable->setCreateByDefault( 
false );
 
   79  addParameter( outputNonRoutable.release() );
 
   84  loadCommonParams( parameters, context, feedback );
 
   86  const QgsPointXY startPoint = parameterAsPoint( parameters, QStringLiteral( 
"START_POINT" ), context, mNetwork->sourceCrs() );
 
   88  std::unique_ptr<QgsFeatureSource> endPoints( parameterAsSource( parameters, QStringLiteral( 
"END_POINTS" ), context ) );
 
   93  newFields.
append( 
QgsField( QStringLiteral( 
"start" ), QMetaType::Type::QString ) );
 
   94  newFields.
append( 
QgsField( QStringLiteral( 
"end" ), QMetaType::Type::QString ) );
 
   95  newFields.
append( 
QgsField( QStringLiteral( 
"cost" ), QMetaType::Type::Double ) );
 
  103  QString nonRoutableSinkId;
 
  104  std::unique_ptr<QgsFeatureSink> nonRoutableSink( parameterAsSink( parameters, QStringLiteral( 
"OUTPUT_NON_ROUTABLE" ), context, nonRoutableSinkId, endPoints->fields(), 
Qgis::WkbType::Point, mNetwork->sourceCrs() ) );
 
  106  const double pointDistanceThreshold = parameters.value( QStringLiteral( 
"POINT_TOLERANCE" ) ).isValid() ? parameterAsDouble( parameters, QStringLiteral( 
"POINT_TOLERANCE" ), context ) : -1;
 
  108  QVector<QgsPointXY> points;
 
  109  points.push_front( startPoint );
 
  110  QHash<int, QgsAttributes> sourceAttributes;
 
  111  loadPoints( endPoints.get(), &points, &sourceAttributes, context, feedback, 
nullptr );
 
  113  feedback->
pushInfo( QObject::tr( 
"Building graph…" ) );
 
  114  QVector<QgsPointXY> snappedPoints;
 
  115  mDirector->makeGraph( mBuilder.get(), points, snappedPoints, feedback );
 
  117  const QgsPointXY snappedStartPoint = snappedPoints[0];
 
  119  if ( pointDistanceThreshold >= 0 )
 
  121    double distanceStartPointToNetwork = 0;
 
  124      distanceStartPointToNetwork = mBuilder->distanceArea()->measureLine( startPoint, snappedStartPoint );
 
  131    if ( distanceStartPointToNetwork > pointDistanceThreshold )
 
  133      throw QgsProcessingException( QObject::tr( 
"Start point is too far from the network layer (%1, maximum permitted is %2)" ).arg( distanceStartPointToNetwork ).arg( pointDistanceThreshold ) );
 
  137  feedback->
pushInfo( QObject::tr( 
"Calculating shortest paths…" ) );
 
  138  std::unique_ptr<QgsGraph> graph( mBuilder->takeGraph() );
 
  139  const int idxStart = graph->findVertex( snappedStartPoint );
 
  143  QVector<double> costs;
 
  146  QVector<QgsPointXY> route;
 
  153  const double step = points.size() > 0 ? 100.0 / points.size() : 1;
 
  154  for ( 
int i = 1; i < points.size(); i++ )
 
  161    const QgsPointXY snappedPoint = snappedPoints.at( i );
 
  162    const QgsPointXY originalPoint = points.at( i );
 
  164    if ( pointDistanceThreshold >= 0 )
 
  166      double distancePointToNetwork = 0;
 
  169        distancePointToNetwork = mBuilder->distanceArea()->measureLine( originalPoint, snappedPoint );
 
  176      if ( distancePointToNetwork > pointDistanceThreshold )
 
  178        feedback->
pushWarning( QObject::tr( 
"Point is too far from the network layer (%1, maximum permitted is %2)" ).arg( distancePointToNetwork ).arg( pointDistanceThreshold ) );
 
  179        if ( nonRoutableSink )
 
  182          attributes = sourceAttributes.value( i );
 
  185            throw QgsProcessingException( writeFeatureError( nonRoutableSink.get(), parameters, QStringLiteral( 
"OUTPUT_NON_ROUTABLE" ) ) );
 
  193    idxEnd = graph->findVertex( snappedPoint );
 
  194    if ( tree.at( idxEnd ) == -1 )
 
  196      feedback->
reportError( QObject::tr( 
"There is no route from start point (%1) to end point (%2)." )
 
  199      attributes = sourceAttributes.value( i );
 
  200      attributes.append( QVariant() );
 
  201      attributes.append( originalPoint.
toString() );
 
  209    route.push_front( graph->vertex( idxEnd ).point() );
 
  210    cost = costs.at( idxEnd );
 
  211    while ( idxEnd != idxStart )
 
  213      idxEnd = graph->edge( tree.at( idxEnd ) ).fromVertex();
 
  214      route.push_front( graph->vertex( idxEnd ).point() );
 
  220    attributes = sourceAttributes.value( i );
 
  221    attributes.append( startPoint.
toString() );
 
  222    attributes.append( originalPoint.
toString() );
 
  223    attributes.append( cost / mMultiplier );
 
  235  outputs.insert( QStringLiteral( 
"OUTPUT" ), dest );
 
  236  if ( nonRoutableSink )
 
  238    nonRoutableSink->finalize();
 
  239    outputs.insert( QStringLiteral( 
"OUTPUT_NON_ROUTABLE" ), nonRoutableSinkId );
 
@ VectorPoint
Vector point layers.
 
@ VectorLine
Vector line layers.
 
@ RegeneratesPrimaryKey
Algorithm always drops any existing primary keys or FID values and regenerates them in outputs.
 
QFlags< ProcessingAlgorithmDocumentationFlag > ProcessingAlgorithmDocumentationFlags
Flags describing algorithm behavior for documentation purposes.
 
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
 
Custom exception class for Coordinate Reference System related exceptions.
 
@ 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.
 
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.
 
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB, const QString &fieldsBPrefix=QString())
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).