25QString QgsServiceAreaFromPointAlgorithm::name()
 const 
   27  return QStringLiteral( 
"serviceareafrompoint" );
 
   30QString QgsServiceAreaFromPointAlgorithm::displayName()
 const 
   32  return QObject::tr( 
"Service area (from point)" );
 
   35QStringList QgsServiceAreaFromPointAlgorithm::tags()
 const 
   37  return QObject::tr( 
"network,service,area,shortest,fastest" ).split( 
',' );
 
   40QString QgsServiceAreaFromPointAlgorithm::shortHelpString()
 const 
   42  return QObject::tr( 
"This algorithm creates a new vector with all the edges or parts of edges " 
   43                      "of a network line layer that can be reached within a distance or a time, " 
   44                      "starting from a point feature. The distance and the time (both referred to " 
   45                      "as \"travel cost\") must be specified respectively in the network layer " 
   46                      "units or in hours." );
 
   49QgsServiceAreaFromPointAlgorithm *QgsServiceAreaFromPointAlgorithm::createInstance()
 const 
   51  return new QgsServiceAreaFromPointAlgorithm();
 
   54void QgsServiceAreaFromPointAlgorithm::initAlgorithm( 
const QVariantMap & )
 
   59  std::unique_ptr< QgsProcessingParameterNumber > travelCost = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( 
"TRAVEL_COST" ), QObject::tr( 
"Travel cost (distance for 'Shortest', time for 'Fastest')" ), 
Qgis::ProcessingNumberParameterType::Double, 0, 
true, 0 );
 
   61  addParameter( travelCost.release() );
 
   63  addParameter( 
new QgsProcessingParameterNumber( QStringLiteral( 
"TRAVEL_COST2" ), QObject::tr( 
"Travel cost (distance for 'Shortest', time for 'Fastest')" ),
 
   66  std::unique_ptr< QgsProcessingParameterNumber > maxPointDistanceFromNetwork = std::make_unique < QgsProcessingParameterDistance >( QStringLiteral( 
"POINT_TOLERANCE" ), QObject::tr( 
"Maximum point distance from network" ), QVariant(), QStringLiteral( 
"INPUT" ), 
true, 0 );
 
   68  maxPointDistanceFromNetwork->setHelp( QObject::tr( 
"Specifies an optional limit on the distance from the point to the network layer. If the point is further from the network than this distance an error will be raised." ) );
 
   69  addParameter( maxPointDistanceFromNetwork.release() );
 
   71  std::unique_ptr< QgsProcessingParameterBoolean > includeBounds = std::make_unique< QgsProcessingParameterBoolean >( QStringLiteral( 
"INCLUDE_BOUNDS" ), QObject::tr( 
"Include upper/lower bound points" ), 
false, 
true );
 
   73  addParameter( includeBounds.release() );
 
   75  std::unique_ptr< QgsProcessingParameterFeatureSink > outputLines = std::make_unique< QgsProcessingParameterFeatureSink >( QStringLiteral( 
"OUTPUT_LINES" ),  QObject::tr( 
"Service area (lines)" ),
 
   77  outputLines->setCreateByDefault( 
true );
 
   78  addParameter( outputLines.release() );
 
   80  std::unique_ptr< QgsProcessingParameterFeatureSink > outputPoints = std::make_unique< QgsProcessingParameterFeatureSink >( QStringLiteral( 
"OUTPUT" ),  QObject::tr( 
"Service area (boundary nodes)" ),
 
   82  outputPoints->setCreateByDefault( 
false );
 
   83  addParameter( outputPoints.release() );
 
   88  loadCommonParams( parameters, context, feedback );
 
   90  const QgsPointXY startPoint = parameterAsPoint( parameters, QStringLiteral( 
"START_POINT" ), context, mNetwork->sourceCrs() );
 
   93  const bool useOldTravelCost = parameters.value( QStringLiteral( 
"TRAVEL_COST" ) ).isValid();
 
   94  double travelCost = parameterAsDouble( parameters, useOldTravelCost ? QStringLiteral( 
"TRAVEL_COST" ) : QStringLiteral( 
"TRAVEL_COST2" ), context );
 
   96  const int strategy = parameterAsInt( parameters, QStringLiteral( 
"STRATEGY" ), context );
 
   97  if ( strategy && !useOldTravelCost )
 
   98    travelCost *= mMultiplier;
 
  100  bool includeBounds = 
true;  
 
  101  if ( parameters.contains( QStringLiteral( 
"INCLUDE_BOUNDS" ) ) )
 
  103    includeBounds = parameterAsBool( parameters, QStringLiteral( 
"INCLUDE_BOUNDS" ), context );
 
  106  feedback->
pushInfo( QObject::tr( 
"Building graph…" ) );
 
  107  QVector< QgsPointXY > snappedPoints;
 
  108  mDirector->makeGraph( mBuilder.get(), { startPoint }, snappedPoints, feedback );
 
  109  const QgsPointXY snappedStartPoint = snappedPoints[0];
 
  112  if ( parameters.value( QStringLiteral( 
"POINT_TOLERANCE" ) ).isValid() )
 
  114    const double pointDistanceThreshold = parameterAsDouble( parameters, QStringLiteral( 
"POINT_TOLERANCE" ), context );
 
  116    const double distancePointToNetwork = mBuilder->distanceArea()->measureLine( startPoint, snappedStartPoint );
 
  117    if ( distancePointToNetwork > pointDistanceThreshold )
 
  119      throw QgsProcessingException( QObject::tr( 
"Point is too far from the network layer (%1, maximum permitted is %2)" ).arg( distancePointToNetwork ).arg( pointDistanceThreshold ) );
 
  123  feedback->
pushInfo( QObject::tr( 
"Calculating service area…" ) );
 
  124  std::unique_ptr< QgsGraph> graph( mBuilder->takeGraph() );
 
  125  const int idxStart = graph->findVertex( snappedStartPoint );
 
  128  QVector< double > costs;
 
  133  QSet< int > vertices;
 
  135  int inboundEdgeIndex;
 
  136  double startVertexCost, endVertexCost;
 
  140  for ( 
int i = 0; i < costs.size(); i++ )
 
  142    inboundEdgeIndex = tree.at( i );
 
  143    if ( inboundEdgeIndex == -1 && i != idxStart )
 
  149    startVertexCost = costs.at( i );
 
  150    if ( startVertexCost > travelCost )
 
  156    vertices.insert( i );
 
  157    edgeStart = graph->vertex( i ).point();
 
  160    const QList< int > outgoingEdges = graph->vertex( i ).outgoingEdges() ;
 
  161    for ( 
const int edgeId : outgoingEdges )
 
  163      edge = graph->edge( edgeId );
 
  164      endVertexCost = startVertexCost + edge.
cost( 0 ).toDouble();
 
  165      edgeEnd = graph->vertex( edge.
toVertex() ).point();
 
  166      if ( endVertexCost <= travelCost )
 
  176                                                edgeEnd.
x(), edgeEnd.
y(), endVertexCost, travelCost );
 
  178        points.push_back( interpolatedEndPoint );
 
  179        lines.push_back( 
QgsPolylineXY() << edgeStart << interpolatedEndPoint );
 
  185  QList< int > verticesList = qgis::setToList( vertices );
 
  186  points.reserve( verticesList.size() );
 
  187  std::sort( verticesList.begin(), verticesList.end() );
 
  188  for ( 
const int v : verticesList )
 
  190    points.push_back( graph->vertex( v ).point() );
 
  193  feedback->
pushInfo( QObject::tr( 
"Writing results…" ) );
 
  198  fields.
append( 
QgsField( QStringLiteral( 
"type" ), QMetaType::Type::QString ) );
 
  199  fields.
append( 
QgsField( QStringLiteral( 
"start" ), QMetaType::Type::QString ) );
 
  204  QString pointsSinkId;
 
  205  std::unique_ptr< QgsFeatureSink > pointsSink( parameterAsSink( parameters, QStringLiteral( 
"OUTPUT" ), context, pointsSinkId, fields,
 
  210    outputs.insert( QStringLiteral( 
"OUTPUT" ), pointsSinkId );
 
  216      throw QgsProcessingException( writeFeatureError( pointsSink.get(), parameters, QStringLiteral( 
"OUTPUT" ) ) );
 
  221      QVector< int > nodes;
 
  224      for ( 
int i = 0; i < costs.size(); i++ )
 
  226        if ( costs.at( i ) > travelCost && tree.at( i ) != -1 )
 
  228          vertexId = graph->edge( tree.at( i ) ).fromVertex();
 
  229          if ( costs.at( vertexId ) <= travelCost )
 
  231            nodes.push_back( i );
 
  236      upperBoundary.reserve( nodes.size() );
 
  237      lowerBoundary.reserve( nodes.size() );
 
  238      for ( 
const int i : nodes )
 
  240        upperBoundary.push_back( graph->vertex( graph->edge( tree.at( i ) ).toVertex() ).point() );
 
  241        lowerBoundary.push_back( graph->vertex( graph->edge( tree.at( i ) ).fromVertex() ).point() );
 
  250        throw QgsProcessingException( writeFeatureError( pointsSink.get(), parameters, QStringLiteral( 
"OUTPUT" ) ) );
 
  255        throw QgsProcessingException( writeFeatureError( pointsSink.get(), parameters, QStringLiteral( 
"OUTPUT" ) ) );
 
  260  std::unique_ptr< QgsFeatureSink > linesSink( parameterAsSink( parameters, QStringLiteral( 
"OUTPUT_LINES" ), context, linesSinkId, fields,
 
  265    outputs.insert( QStringLiteral( 
"OUTPUT_LINES" ), linesSinkId );
 
  270      throw QgsProcessingException( writeFeatureError( linesSink.get(), parameters, QStringLiteral( 
"OUTPUT_LINES" ) ) );
 
@ VectorPoint
Vector point layers.
 
@ VectorLine
Vector line layers.
 
@ MultiLineString
MultiLineString.
 
@ Hidden
Parameter is hidden and should not be shown to users.
 
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
 
@ Double
Double/float values.
 
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
 
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 setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
 
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.
 
static QgsPointXY interpolatePointOnLineByValue(double x1, double y1, double v1, double x2, double y2, double v2, double value)
Interpolates the position of a point along the line from (x1, y1) to (x2, y2).
 
A geometry is the spatial representation of a feature.
 
static QgsGeometry fromMultiPolylineXY(const QgsMultiPolylineXY &multiline)
Creates a new geometry from a QgsMultiPolylineXY object.
 
static QgsGeometry fromMultiPointXY(const QgsMultiPointXY &multipoint)
Creates a new geometry from a QgsMultiPointXY 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.
 
This class implements a graph edge.
 
int toVertex() const
Returns the index of the vertex at the end of this edge.
 
QVariant cost(int strategyIndex) const
Returns edge cost calculated using specified strategy.
 
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.
 
A numeric parameter for processing algorithms.
 
A point parameter for processing algorithms.
 
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
 
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
 
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.