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 "
43 "edges of a network line layer that can be reached within a distance "
44 "or a time, starting from features of a point layer. The distance and "
45 "the time (both referred to as \"travel cost\") must be specified "
46 "respectively in the network layer units or in hours." );
49 QgsServiceAreaFromLayerAlgorithm *QgsServiceAreaFromLayerAlgorithm::createInstance()
const
51 return new QgsServiceAreaFromLayerAlgorithm();
54 void QgsServiceAreaFromLayerAlgorithm::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')" ),
QgsProcessingParameterNumber::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< QgsProcessingParameterBoolean > includeBounds = std::make_unique< QgsProcessingParameterBoolean >( QStringLiteral(
"INCLUDE_BOUNDS" ), QObject::tr(
"Include upper/lower bound points" ),
false,
true );
68 addParameter( includeBounds.release() );
70 std::unique_ptr< QgsProcessingParameterFeatureSink > outputLines = std::make_unique< QgsProcessingParameterFeatureSink >( QStringLiteral(
"OUTPUT_LINES" ), QObject::tr(
"Service area (lines)" ),
72 outputLines->setCreateByDefault(
true );
73 addParameter( outputLines.release() );
75 std::unique_ptr< QgsProcessingParameterFeatureSink > outputPoints = std::make_unique< QgsProcessingParameterFeatureSink >( QStringLiteral(
"OUTPUT" ), QObject::tr(
"Service area (boundary nodes)" ),
77 outputPoints->setCreateByDefault(
false );
78 addParameter( outputPoints.release() );
83 loadCommonParams( parameters, context, feedback );
85 std::unique_ptr< QgsFeatureSource > startPoints( parameterAsSource( parameters, QStringLiteral(
"START_POINTS" ), context ) );
90 const bool useOldTravelCost = parameters.value( QStringLiteral(
"TRAVEL_COST" ) ).isValid();
91 double travelCost = parameterAsDouble( parameters, useOldTravelCost ? QStringLiteral(
"TRAVEL_COST" ) : QStringLiteral(
"TRAVEL_COST2" ), context );
93 int strategy = parameterAsInt( parameters, QStringLiteral(
"STRATEGY" ), context );
94 if ( strategy && !useOldTravelCost )
95 travelCost *= mMultiplier;
97 bool includeBounds =
true;
98 if ( parameters.contains( QStringLiteral(
"INCLUDE_BOUNDS" ) ) )
100 includeBounds = parameterAsBool( parameters, QStringLiteral(
"INCLUDE_BOUNDS" ), context );
103 QVector< QgsPointXY > points;
104 QHash< int, QgsAttributes > sourceAttributes;
105 loadPoints( startPoints.get(), points, sourceAttributes, context, feedback );
107 feedback->
pushInfo( QObject::tr(
"Building graph…" ) );
108 QVector< QgsPointXY > snappedPoints;
109 mDirector->makeGraph( mBuilder.get(), points, snappedPoints, feedback );
111 feedback->
pushInfo( QObject::tr(
"Calculating service areas…" ) );
112 QgsGraph *graph = mBuilder->graph();
114 QgsFields fields = startPoints->fields();
115 fields.
append(
QgsField( QStringLiteral(
"type" ), QVariant::String ) );
116 fields.
append(
QgsField( QStringLiteral(
"start" ), QVariant::String ) );
118 QString pointsSinkId;
119 std::unique_ptr< QgsFeatureSink > pointsSink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, pointsSinkId, fields,
123 std::unique_ptr< QgsFeatureSink > linesSink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT_LINES" ), context, linesSinkId, fields,
129 QVector< double > costs;
131 int inboundEdgeIndex;
132 double startVertexCost, endVertexCost;
139 int step = snappedPoints.size() > 0 ? 100.0 / snappedPoints.size() : 1;
140 for (
int i = 0; i < snappedPoints.size(); i++ )
147 idxStart = graph->
findVertex( snappedPoints.at( i ) );
148 origPoint = points.at( i ).toString();
154 QSet< int > vertices;
156 for (
int j = 0; j < costs.size(); j++ )
158 inboundEdgeIndex = tree.at( j );
160 if ( inboundEdgeIndex == -1 && j != idxStart )
166 startVertexCost = costs.at( j );
167 if ( startVertexCost > travelCost )
173 vertices.insert( j );
178 for (
int edgeId : outgoingEdges )
180 edge = graph->
edge( edgeId );
181 endVertexCost = startVertexCost + edge.
cost( 0 ).toDouble();
183 if ( endVertexCost <= travelCost )
187 lines.push_back(
QgsPolylineXY() << startPoint << endPoint );
193 endPoint.
x(), endPoint.
y(), endVertexCost, travelCost );
195 areaPoints.push_back( interpolatedEndPoint );
196 lines.push_back(
QgsPolylineXY() << startPoint << interpolatedEndPoint );
202 QList< int > verticesList = qgis::setToList( vertices );
203 areaPoints.reserve( verticesList.size() );
204 std::sort( verticesList.begin(), verticesList.end() );
205 for (
int v : verticesList )
207 areaPoints.push_back( graph->
vertex( v ).
point() );
214 attributes = sourceAttributes.value( i + 1 );
215 attributes << QStringLiteral(
"within" ) << origPoint;
222 QVector< int > nodes;
223 nodes.reserve( costs.size() );
226 for (
int v = 0; v < costs.size(); v++ )
228 if ( costs.at( v ) > travelCost && tree.at( v ) != -1 )
231 if ( costs.at( vertexId ) <= travelCost )
233 nodes.push_back( v );
238 for (
int n : std::as_const( nodes ) )
248 attributes = sourceAttributes.value( i + 1 );
249 attributes << QStringLiteral(
"upper" ) << origPoint;
254 attributes = sourceAttributes.value( i + 1 );
255 attributes << QStringLiteral(
"lower" ) << origPoint;
265 attributes = sourceAttributes.value( i + 1 );
266 attributes << QStringLiteral(
"lines" ) << origPoint;
277 outputs.insert( QStringLiteral(
"OUTPUT" ), pointsSinkId );
281 outputs.insert( QStringLiteral(
"OUTPUT_LINES" ), linesSinkId );
@ 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 setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool isCanceled() const SIP_HOLDGIL
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, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
static QgsPointXY interpolatePointOnLineByValue(double x1, double y1, double v1, double x2, double y2, double v2, double value) SIP_HOLDGIL
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 fromVertex() const
Returns the index of the vertex at the start of this 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.
QgsGraphEdgeIds outgoingEdges() const
Returns outgoing edge ids, i.e.
QgsPointXY point() const
Returns point associated with graph vertex.
Mathematical graph representation.
const QgsGraphVertex & vertex(int idx) const
Returns vertex at given index.
int findVertex(const QgsPointXY &pt) const
Find vertex by associated point.
const QgsGraphEdge & edge(int idx) const
Returns edge at given index.
A class to represent a 2D point.
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.
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
@ FlagHidden
Parameter is hidden and should not be shown to users.
An input feature source (such as vector layers) parameter for processing algorithms.
A numeric parameter for processing algorithms.
@ Double
Double/float values.
@ TypeVectorLine
Vector line layers.
@ TypeVectorPoint
Vector point layers.
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.