PyQGIS – Getting Random Values from geometryType() in a Standalone PyQGIS Script

pyqgisqgis-processingstandalone

I am asking this question based on the result I received from this earlier post. The following script only works if I set geometryType() == 3 as that is what is being printed out in the Python console even though @nickves from the previous post mentioned that 0, 1 and 2 are for points, lines and polygons respectively.

Could someone point out my mistake please? Feel free to cross this post over to Stack Overflow, I only posted it here as the script is based on geometry data.

##Test=name
import os
import glob
from qgis.core import *
from os.path import expanduser
home = expanduser("~")

#   Folder path of the Results for shapefiles
path_dir = home + "\Desktop\Test\\"
path_res = path_dir + "Results\\"

def run():
#   Set directory and search for all polygon .shp files
    os.chdir(path_dir + "Shapefiles\\")
    for fname in glob.glob("*.shp"): 
        shapefile = QgsVectorLayer( os.chdir(path_dir + "Shapefiles\\"), fname, "ogr" )
#      print shapefile.geometryType()
        print shapefile.wkbType()

#   Clip .shp files with the polygon shapefile "Grid.shp" and save files to Result folder
#        if shapefile.wkbType() == 2:
#            polygon_output=processing.runalg("qgis:clip", path_dir + "Grid.shp", fname, path_res  + "/"+ fname)

#   Use Distance to nearest hub function on point.shp files with the polygon shapefile "Grid.shp" as Hub layer and save files to Result folder  
        if shapefile.wkbType() == 0:
            point_output=processing.runalg("qgis:distancetonearesthub", path_dir + "Grid.shp", fname, 'HubName', 0, 0, path_res  + "/"+ fname)
run()

Best Answer

The problem you are facing is due to not valid layers constructed by QgsVectorLayer(). If you print shapefile.isValid() you will be getting False for all layers.

This happens because you need to set the QGIS prefix path and initialize QgsApplication before using QgsVectorLayer in standalone scripts/apps.

The solution for your problem is to:

  • Add these two lines to your script (below the import section):

    QgsApplication.setPrefixPath("/usr", True) # Adjust it to your path
    QgsApplication.initQgis()
    
  • Adjust the arguments you are passing to QgsVectorLayer to:

    shapefile = QgsVectorLayer( path_dir + "Shapefiles\\" + fname, fname, "ogr" )
    

Now you could print the following layer properties and get appropriate results (0 for points, 1 for lines, and 2 for polygons):

print fname, shapefile.isValid(), shapefile.geometryType()