I have a vector file (point shape file). In this vector, there are 4 points. I want to get least cost path between these points. I have a raster file (actually slope), which I want to use as a cost raster layer. I followed these this article to get my result: https://greggsaldutti-jr.medium.com/multiple-step-least-cost-path-analysis-with-qgis-and-python-892feef692f6#:~:text=LCP%20analysis%20is%20a%20GIS,then%20be%20used%20for%20visualization.

I directly used QGIS for two vector points. Now I want to get shortest path within a loop for more than 2 vector points.

I tried both standalone script with python and Python console in QGIS. Neither worked. Would anyone please help me to solve this issue?

import pandas as pd
import numpy as np
import os

#importing the necessary libraries
import sys
from qgis import processing
from qgis.analysis import QgsNativeAlgorithms
from qgis.core import *
from PyQt5.QtCore import QVariant 
from qgis.analysis import QgsNativeAlgorithms
#from processing.core.Processing import Processing
from qgis.gui import *
from qgis.PyQt.QtWidgets import *
#import processing
from qgis.analysis import QgsNativeAlgorithms

#setting working directory
path="/path/to/vector/file/ALBA-1.shp"
rast_fp="/path/to/raster/file/slope.tif"
output_path="path/to/OUTPUT/"

def lcp_series(points, rast_fp, output_path):
   
    '''
    A function that runs least cost path analysis algorithim on a series of points. 
    points: a path to shapefile containing a layer with  points
    rast_fp: a file path to a cost raster
    out_path: a file path where results should be saved
    The to and from points require a column 'order' with the ordered points 1..2..3..etc.
    This uses the Cost distance analysis:Least Cost Path plugin algorithm, but allows a stepwise calculation, 
    eg, A to B, B to C, etc.
    '''
    
    #read in points vector
    points = QgsVectorLayer(points, "points", "ogr")
    QgsProject.instance().addMapLayer(points)
    
    #read in raster layer
    rast = QgsRasterLayer(rast_fp, 'rast')
    QgsProject.instance().addMapLayer(rast)

    #retrieve points as feature
    iterFrom = points.getFeatures()
    
    #start iteration counts
    i = 1
    j = 2

    for feature in iterFrom: 
      #create and name virtual origin layer
        from_temp_layer = points.materialize(QgsFeatureRequest().setFilterFids(points.selectedFeatureIds()))
        from_temp_layer.setName('from_temp_layer')
      #create and name virtual destinatoin layer
        to_temp_layer = points.materialize(QgsFeatureRequest().setFilterFids(points.selectedFeatureIds()))
        to_temp_layer.setName('to_temp_layer')    
      
      #call i feature and create a point, set as origin
        if feature['Cable_Poin'] == i :
            from_pt = feature
        #get feature from poitns    
        iterTwo = points.getFeatures()
        #call j feature and create a point, set as destination
        for feat in iterTwo :
            if feat['Cable_Poin'] == j:
                to_pt = feat
        #create empty temp layers
        from_vpr = from_temp_layer.dataProvider()
        to_vpr = to_temp_layer.dataProvider()
        
        #populate empty temp layers with points: origin
        from_vpr.addFeatures([from_pt])
        from_temp_layer.updateExtents()
        #populate empty temp layers with points: destination  
        to_vpr.addFeatures([to_pt])
        to_temp_layer.updateExtents()
        
        #run algorithm 
        processing.runAndLoadResults("Cost distance analysis:Least Cost Path", 
        {'BOOLEAN_FIND_LEAST_PATH_TO_ALL_ENDS' : False, 
        'BOOLEAN_OUTPUT_LINEAR_REFERENCE' : False, 
        'INPUT_COST_RASTER' : rast,
        'INPUT_END_LAYER' : to_temp_layer,
        'INPUT_RASTER_BAND' : 1, 
        'INPUT_START_LAYER' : from_temp_layer,
        'OUTPUT' : output_path + str(i) + "_" + str(j) 
        })
        #reset counts
        i = i +1
        j = j+ 1

I got the error as

{
    "name": "AttributeError",
    "message": "module 'qgis.processing' has no attribute 'run'",
    "stack": "---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[8], line 37
     34 to_temp_layer.updateExtents()
     36 #run algorithm 
---> 37 processing.run(\"qgis:leastcostpath\", 
     38 {'BOOLEAN_FIND_LEAST_PATH_TO_ALL_ENDS' : False, 
     39 'BOOLEAN_OUTPUT_LINEAR_REFERENCE' : False, 
     40 'INPUT_COST_RASTER' : rast,
     41 'INPUT_END_LAYER' : to_temp_layer,
     42 'INPUT_RASTER_BAND' : 1, 
     43 'INPUT_START_LAYER' : from_temp_layer,
     44 'OUTPUT' : output_path + str(i) + \"_\" + str(j) 
     45 })
     46 #reset counts
     47 i = i +1

AttributeError: module 'qgis.processing' has no attribute 'run'"
}

I can import processing. In that case , there is no algorithm found.

1

There are 1 best solutions below

0
Ahmed Hamed On

I suggest you to make sure the QGIS processing framework is initialized at the start of your script. Also, takecare that for QGIS 3.x, the correct way to call a processing algorithm is through processing.run() or processing.runAndLoadResults() functions.

Please also try to include error handling to catch exceptions thrown by processing algorithms and share it here. This can help in debugging and understanding what goes wrong when the script is executed.