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')" ),
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 const QgsPointXY startPoint = parameterAsPoint( parameters, QStringLiteral(
"START_POINT" ), context, mNetwork->sourceCrs() );
88 const bool useOldTravelCost = parameters.value( QStringLiteral(
"TRAVEL_COST" ) ).isValid();
89 double travelCost = parameterAsDouble( parameters, useOldTravelCost ? QStringLiteral(
"TRAVEL_COST" ) : QStringLiteral(
"TRAVEL_COST2" ), context );
91 const int strategy = parameterAsInt( parameters, QStringLiteral(
"STRATEGY" ), context );
92 if ( strategy && !useOldTravelCost )
93 travelCost *= mMultiplier;
95 bool includeBounds =
true;
96 if ( parameters.contains( QStringLiteral(
"INCLUDE_BOUNDS" ) ) )
98 includeBounds = parameterAsBool( parameters, QStringLiteral(
"INCLUDE_BOUNDS" ), context );
101 feedback->
pushInfo( QObject::tr(
"Building graph…" ) );
102 QVector< QgsPointXY > snappedPoints;
103 mDirector->makeGraph( mBuilder.get(), QVector< QgsPointXY >() << startPoint, snappedPoints, feedback );
105 feedback->
pushInfo( QObject::tr(
"Calculating service area…" ) );
106 std::unique_ptr< QgsGraph> graph( mBuilder->takeGraph() );
107 const int idxStart = graph->findVertex( snappedPoints[0] );
110 QVector< double > costs;
115 QSet< int > vertices;
117 int inboundEdgeIndex;
118 double startVertexCost, endVertexCost;
122 for (
int i = 0; i < costs.size(); i++ )
124 inboundEdgeIndex = tree.at( i );
125 if ( inboundEdgeIndex == -1 && i != idxStart )
131 startVertexCost = costs.at( i );
132 if ( startVertexCost > travelCost )
138 vertices.insert( i );
139 edgeStart = graph->vertex( i ).point();
142 const QList< int > outgoingEdges = graph->vertex( i ).outgoingEdges() ;
143 for (
const int edgeId : outgoingEdges )
145 edge = graph->edge( edgeId );
146 endVertexCost = startVertexCost + edge.
cost( 0 ).toDouble();
147 edgeEnd = graph->vertex( edge.
toVertex() ).point();
148 if ( endVertexCost <= travelCost )
158 edgeEnd.
x(), edgeEnd.
y(), endVertexCost, travelCost );
160 points.push_back( interpolatedEndPoint );
161 lines.push_back(
QgsPolylineXY() << edgeStart << interpolatedEndPoint );
167 QList< int > verticesList = qgis::setToList( vertices );
168 points.reserve( verticesList.size() );
169 std::sort( verticesList.begin(), verticesList.end() );
170 for (
const int v : verticesList )
172 points.push_back( graph->vertex( v ).point() );
175 feedback->
pushInfo( QObject::tr(
"Writing results…" ) );
180 fields.
append(
QgsField( QStringLiteral(
"type" ), QVariant::String ) );
181 fields.
append(
QgsField( QStringLiteral(
"start" ), QVariant::String ) );
186 QString pointsSinkId;
187 std::unique_ptr< QgsFeatureSink > pointsSink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, pointsSinkId, fields,
192 outputs.insert( QStringLiteral(
"OUTPUT" ), pointsSinkId );
198 throw QgsProcessingException( writeFeatureError( pointsSink.get(), parameters, QStringLiteral(
"OUTPUT" ) ) );
203 QVector< int > nodes;
206 for (
int i = 0; i < costs.size(); i++ )
208 if ( costs.at( i ) > travelCost && tree.at( i ) != -1 )
210 vertexId = graph->edge( tree.at( i ) ).fromVertex();
211 if ( costs.at( vertexId ) <= travelCost )
213 nodes.push_back( i );
218 upperBoundary.reserve( nodes.size() );
219 lowerBoundary.reserve( nodes.size() );
220 for (
const int i : nodes )
222 upperBoundary.push_back( graph->vertex( graph->edge( tree.at( i ) ).toVertex() ).point() );
223 lowerBoundary.push_back( graph->vertex( graph->edge( tree.at( i ) ).fromVertex() ).point() );
232 throw QgsProcessingException( writeFeatureError( pointsSink.get(), parameters, QStringLiteral(
"OUTPUT" ) ) );
237 throw QgsProcessingException( writeFeatureError( pointsSink.get(), parameters, QStringLiteral(
"OUTPUT" ) ) );
242 std::unique_ptr< QgsFeatureSink > linesSink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT_LINES" ), context, linesSinkId, fields,
247 outputs.insert( QStringLiteral(
"OUTPUT_LINES" ), linesSinkId );
252 throw QgsProcessingException( writeFeatureError( linesSink.get(), parameters, QStringLiteral(
"OUTPUT_LINES" ) ) );
@ MultiLineString
MultiLineString.
@ 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, 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)
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.
@ 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.
A numeric parameter for processing algorithms.
@ Double
Double/float values.
A point parameter for processing algorithms.
@ 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.