0

I have 2 vector layers, "pipes" and "fibres". The lines in the pipes layer are already drawn. Now i want to draw a line in the fibres layer from a start point to an endpoint, but the line should trace the shortest line in the pipes layer.

In QGIS i would enable the tracing tool, click on the start- and endpoint in the fibres layer and the new line would snap into the "pipes".

Is there an easy way to implement this in PyQGIS?

Edit: here are some pictures for explanation

This is the pipe layer. pipes layer

I want to connect the startpoint (green square) with the endpoint(s) (green circle(s)) connections

This should be the outcome in the fibres layer. fibres

3
  • 1
    Can you use Shortest path?
    – Bera
    Commented Apr 17, 2023 at 12:01
  • 1
    This looks promising, i'll try that and give feedback here.
    – André
    Commented Apr 17, 2023 at 12:12
  • 1
    I managed to get this working. It's not an elegant solution, but it works. So thanks for the hint. I provided the sample code as answer in case someone else needs this.
    – André
    Commented Apr 17, 2023 at 15:38

1 Answer 1

0

As Bera pointed out, Shortest Path is one solution, but there are some hurdles to take. The Shortest Path processing algorithm accepts only 2 points and puts the result in a layer which contains one single feature. To get all my lines, i copied the results from each processing into a list and then created the geometry in my destination layer.

from qgis.core import QgsProject, QgsFeature
from qgis import processing
pipes = QgsProject.instance().mapLayersByName('<my_pipes>')[0]
fibres = QgsProject.instance().mapLayersByName('<my_fibres>')[0]
startpoint = [x 
              for x in QgsProject.instance().mapLayersByName('<my_points>')[0].getFeatures() 
              if x['<field>'] == '<condition>'][0].geometry()
endpoint_list = [end_point 
                 for end_point in QgsProject.instance().mapLayersByName('<my_points>')[0].getFeatures() 
                 if end_point['<field>'] == '<condition>']
result_geometry = []
for endpoint in endpoint_list:
    endpoint_geometry = endpoint.geometry()
    params = { 'INPUT': pipes, 
                'STRATEGY': 0,
                'START_POINT': startpoint,
                'END_POINT': endpoint_geometry,
                'TOLERANCE': 0.01,
                'OUTPUT': 'TEMPORARY_OUTPUT'
            }
    result  = processing.run("native:shortestpathpointtopoint", params)
    result_layer = result['OUTPUT']
    # gather results
    result_geometry.extend(feature.geometry() for feature in result_layer.getFeatures())
    del result_layer
# create new features in destination layer
fibres.startEditing()
for geom in result_geometry:
    new_feature = QgsFeature(fibres.fields())
    fibres.addFeature(new_feature)
    new_feature.setGeometry(geom)
    fibres.updateFeature(new_feature)
fibres.commitChanges() 

  

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.