1

I am using the QGIS Python Console to automate some bulk processing. I want to create a Voronoi polygon layer from point data (solved this part) and then from a folder of shapefiles clip the Voronoi polygon layer with any of the shapefiles that intersect it. but I am getting the error: AttributeError: 'str' object has no attribute 'geometry'

I am used to ArcPy and have really been struggling with understanding QGIS's Python. I feel like the cookbook and API resources are a little overwhelming for me (a beginner python-er)

Any advice?

import os
from qgis.gui import *
from qgis.core import *
import processing

#------------------------------------------------------
# User Variables:

#path to data location
soil_path = "D:\\soil\\soildata"
shp_path = "D:\\soil\\field_boundaries"
print ("Soil data: " + soil_path)
print ("Field Boundaries: " + shp_path)


#-------------------------------------------------------

def get_data(path, ending):
    data_list = []

    for root, dirs, files in os.walk(path):

        for data in sorted(files):
            if data.endswith(ending):
                data_list.append(os.path.join(root, data))

    return data_list
    print (str(len(data_list)) + " shapefiles found")



def clip(vor_poly):
    clipped_data = []
    shp_data = get_data(shp_path, ".shp")
    print (str(len(shp_data)) + " field boundaries found")
    for f in shp_data:
        print (f)
        print (vor_poly)
        if f.geometry().intersects(vor_poly.geometry()):

            OUTPUT = os.path.splitext(polygons)[0] + os.path.basename(f) + ".shp"

            processing.runalg('qgis:clip', vor_poly, f, OUTPUT)

            print ("clipped " + OUTPUT)

            clipped_data.append(OUTPUT)
    return clipped_data



def qgisprocess(soilpts):

    #voronoi polygons with 0 size buffer

    print("Voronoi Polygons")

    for f in soilpts:
        split_path = os.path.splitext(f)[0]
        inlayer = f
        outlayer = split_path + "_vor_poly.shp"

        processing.run("qgis:voronoipolygons", { 'INPUT':inlayer, 'BUFFER': 0, 'OUTPUT': outlayer})

        clippedpolys = clip(outlayer)


def main():
    #list of data
    soil_data = get_data(soil_path, ".shp")

    print("running QGIS processes")
    qgisprocess(soil_data)


if __name__ == '__console__':
    main()
  • 1
    vor_poly is a path not Qgsvectorlayer you need access to processing output or create a QgsVectorlayer from voronoi path and then make a clip – Fran Raga Jun 20 at 7:29
  • Sorry, this is probably a simple answer, but how would I assign vor_poly as a QGIS vector layer? – Emtomp Jun 24 at 11:29
  • I add an answer @Emtomp – Fran Raga Jun 24 at 14:45
1

You can get the processing result or create a qgsvectorlayer from shp.

you can:

result = processing.run("qgis:voronoipolygons", { 'INPUT':inlayer, 'BUFFER': 0, 'OUTPUT': outlayer})

clippedpolys = clip(result['OUTPUT'])

or if you prefer make this:

outlayer = split_path + "_vor_poly.shp"

processing.run("qgis:voronoipolygons", { 'INPUT':inlayer, 'BUFFER': 0, 'OUTPUT': outlayer})

layer = QgsVectorLayer(outlayer,"vor_poly")

clippedpolys = clip(layer)
  • I still get the same error but now in a different place at least! I'm going to add the updated code as an answer. I get the error here now: if layer.geometry().intersects(vor_poly.geometry()): – Emtomp Jun 28 at 14:02
0

This is my newest attempt, still getting an error but now it is at least in the clip function instead of earlier on

import os
from qgis.gui import *
from qgis.core import *
import processing

#------------------------------------------------------
# User Variables:

#path to data location
soil_path = "D:\\soil\\soildata"
shp_path = "D:\\soil\\field_boundaries"
print ("Soil data: " + soil_path)
print ("Field Boundaries: " + shp_path)


#-------------------------------------------------------

def get_data(path, ending):
    data_list = []

    for root, dirs, files in os.walk(path):

        for data in sorted(files):
            if data.endswith(ending):
                data_list.append(os.path.join(root, data))

    return data_list
    print (str(len(data_list)) + " shapefiles found")



def clip(vor_poly):
    clipped_data = []

    shp_data = get_data(shp_path, ".shp")

    print (str(len(shp_data)) + " field boundaries found")

    for f in shp_data:

        print (f)
        print (vor_poly)

        layer = QgsVectorLayer(f,"clip_poly")

        #ERROR IS NOW HAPPENING BELOW (AttributeError: 'QgsVectorLayer' object has no attribute 'geometry')

        if layer.geometry().intersects(vor_poly.geometry()):

            OUTPUT = os.path.splitext(polygons)[0] + os.path.basename(f) + ".shp"

            processing.runalg('qgis:clip', vor_poly, f, OUTPUT)

            print ("clipped " + OUTPUT)

            clipped_data.append(OUTPUT)

    return clipped_data



def qgisprocess(soilpts):

    #voronoi polygons with 0 size buffer
    print("Voronoi Polygons")
    for f in soilpts:
        split_path = os.path.splitext(f)[0]
        inlayer = f
        outlayer = split_path + "_vor_poly.shp"

        processing.run("qgis:voronoipolygons", { 'INPUT':inlayer, 'BUFFER': 0, 'OUTPUT': outlayer})

        layer = QgsVectorLayer(outlayer,"vor_poly")

        clippedpolys = clip(layer)


def main():
    #list of data
    soil_data = get_data(soil_path, ".shp")

    print("running QGIS processes")
    qgisprocess(soil_data)


if __name__ == '__console__':
    main()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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