25 QString QgsServiceAreaFromLayerAlgorithm::name()
const 27 return QStringLiteral(
"serviceareafromlayer" );
30 QString QgsServiceAreaFromLayerAlgorithm::displayName()
const 32 return QObject::tr(
"Service area (from layer)" );
35 QStringList QgsServiceAreaFromLayerAlgorithm::tags()
const 37 return QObject::tr(
"network,service,area,shortest,fastest" ).split(
',' );
40 QString QgsServiceAreaFromLayerAlgorithm::shortHelpString()
const 42 return QObject::tr(
"This algorithm creates a new vector with all the edges or parts of edges of a network line layer that can be reached within a distance or a time, starting from features of a point layer. The distance and the time (both referred to as \"travel cost\") must be specified respectively in the network layer units or in seconds." );
45 QgsServiceAreaFromLayerAlgorithm *QgsServiceAreaFromLayerAlgorithm::createInstance()
const 47 return new QgsServiceAreaFromLayerAlgorithm();
50 void QgsServiceAreaFromLayerAlgorithm::initAlgorithm(
const QVariantMap & )
54 addParameter(
new QgsProcessingParameterNumber( QStringLiteral(
"TRAVEL_COST" ), QObject::tr(
"Travel cost (distance for 'Shortest', time for 'Fastest')" ),
57 std::unique_ptr< QgsProcessingParameterBoolean > includeBounds = qgis::make_unique< QgsProcessingParameterBoolean >( QStringLiteral(
"INCLUDE_BOUNDS" ), QObject::tr(
"Include upper/lower bound points" ),
false, true );
59 addParameter( includeBounds.release() );
61 std::unique_ptr< QgsProcessingParameterFeatureSink > outputLines = qgis::make_unique< QgsProcessingParameterFeatureSink >( QStringLiteral(
"OUTPUT_LINES" ), QObject::tr(
"Service area (lines)" ),
63 outputLines->setCreateByDefault(
true );
64 addParameter( outputLines.release() );
66 std::unique_ptr< QgsProcessingParameterFeatureSink > outputPoints = qgis::make_unique< QgsProcessingParameterFeatureSink >( QStringLiteral(
"OUTPUT" ), QObject::tr(
"Service area (boundary nodes)" ),
68 outputPoints->setCreateByDefault(
false );
69 addParameter( outputPoints.release() );
74 loadCommonParams( parameters, context, feedback );
76 std::unique_ptr< QgsFeatureSource > startPoints( parameterAsSource( parameters, QStringLiteral(
"START_POINTS" ), context ) );
80 double travelCost = parameterAsDouble( parameters, QStringLiteral(
"TRAVEL_COST" ), context );
82 bool includeBounds =
true;
83 if ( parameters.contains( QStringLiteral(
"INCLUDE_BOUNDS" ) ) )
85 includeBounds = parameterAsBool( parameters, QStringLiteral(
"INCLUDE_BOUNDS" ), context );
88 QVector< QgsPointXY > points;
89 QHash< int, QgsAttributes > sourceAttributes;
90 loadPoints( startPoints.get(), points, sourceAttributes, context, feedback );
92 feedback->
pushInfo( QObject::tr(
"Building graph…" ) );
93 QVector< QgsPointXY > snappedPoints;
94 mDirector->makeGraph( mBuilder.get(), points, snappedPoints, feedback );
96 feedback->
pushInfo( QObject::tr(
"Calculating service areas…" ) );
100 fields.
append(
QgsField( QStringLiteral(
"type" ), QVariant::String ) );
101 fields.
append(
QgsField( QStringLiteral(
"start" ), QVariant::String ) );
103 QString pointsSinkId;
104 std::unique_ptr< QgsFeatureSink > pointsSink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, pointsSinkId, fields,
108 std::unique_ptr< QgsFeatureSink > linesSink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT_LINES" ), context, linesSinkId, fields,
114 QVector< double > costs;
116 int inboundEdgeIndex;
117 double startVertexCost, endVertexCost;
124 int step = snappedPoints.size() > 0 ? 100.0 / snappedPoints.size() : 1;
125 for (
int i = 0; i < snappedPoints.size(); i++ )
132 idxStart = graph->
findVertex( snappedPoints.at( i ) );
133 origPoint = points.at( i ).toString();
139 QSet< int > vertices;
141 for (
int j = 0; j < costs.size(); j++ )
143 inboundEdgeIndex = tree.at( j );
145 if ( inboundEdgeIndex == -1 && j != idxStart )
151 startVertexCost = costs.at( j );
152 if ( startVertexCost > travelCost )
158 vertices.insert( j );
163 for (
int edgeId : outgoingEdges )
165 edge = graph->
edge( edgeId );
166 endVertexCost = startVertexCost + edge.
cost( 0 ).toDouble();
168 if ( endVertexCost <= travelCost )
172 lines.push_back(
QgsPolylineXY() << startPoint << endPoint );
178 endPoint.
x(), endPoint.
y(), endVertexCost, travelCost );
180 areaPoints.push_back( interpolatedEndPoint );
181 lines.push_back(
QgsPolylineXY() << startPoint << interpolatedEndPoint );
187 QList< int > verticesList = vertices.toList();
188 areaPoints.reserve( verticesList.size() );
189 std::sort( verticesList.begin(), verticesList.end() );
190 for (
int v : verticesList )
192 areaPoints.push_back( graph->
vertex( v ).
point() );
199 attributes = sourceAttributes.value( i + 1 );
200 attributes << QStringLiteral(
"within" ) << origPoint;
207 QVector< int > nodes;
208 nodes.reserve( costs.size() );
211 for (
int v = 0; v < costs.size(); v++ )
213 if ( costs.at( v ) > travelCost && tree.at( v ) != -1 )
215 vertexId = graph->
edge( tree.at( v ) ).fromVertex();
216 if ( costs.at( vertexId ) <= travelCost )
218 nodes.push_back( v );
223 for (
int n : qgis::as_const( nodes ) )
225 upperBoundary.push_back( graph->
vertex( graph->
edge( tree.at( n ) ).toVertex() ).point() );
226 lowerBoundary.push_back( graph->
vertex( graph->
edge( tree.at( n ) ).fromVertex() ).point() );
233 attributes = sourceAttributes.value( i );
234 attributes << QStringLiteral(
"upper" ) << origPoint;
239 attributes = sourceAttributes.value( i );
240 attributes << QStringLiteral(
"lower" ) << origPoint;
250 attributes = sourceAttributes.value( i );
251 attributes << QStringLiteral(
"lines" ) << origPoint;
262 outputs.insert( QStringLiteral(
"OUTPUT" ), pointsSinkId );
266 outputs.insert( QStringLiteral(
"OUTPUT_LINES" ), linesSinkId );
const QgsGraphEdge & edge(int idx) const
Returns edge at given index.
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
Base class for providing feedback from a processing algorithm.
Parameter is an advanced parameter which should be hidden from users by default.
A class to represent a 2D point.
static QgsGeometry fromMultiPolylineXY(const QgsMultiPolylineXY &multiline)
Creates a new geometry from a QgsMultiPolylineXY object.
void setProgress(double progress)
Sets the current progress for the feedback object.
Container of fields for a vector layer.
QgsPointXY point() const
Returns point associated with graph vertex.
A geometry is the spatial representation of a feature.
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
static QgsGeometry fromMultiPointXY(const QgsMultiPointXY &multipoint)
Creates a new geometry from a QgsMultiPointXY object.
Custom exception class for processing related exceptions.
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false) ...
QgsGraphEdgeIds outgoingEdges() const
Returns outgoing edge ids, i.e.
int findVertex(const QgsPointXY &pt) const
Find vertex by associated point.
Encapsulate a field in an attribute table or data source.
A numeric parameter for processing algorithms.
QVariant cost(int strategyIndex) const
Returns edge cost calculated using specified strategy.
Mathematical graph representation.
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
int toVertex() const
Returns the index of the vertex at the end of this edge.
const QgsGraphVertex & vertex(int idx) const
Returns vertex at given index.
bool isCanceled() const
Tells whether the operation has been canceled already.
An input feature source (such as vector layers) parameter for processing algorithms.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Contains information about the context in which a processing algorithm is executed.
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).
This class implements a graph edge.
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.