2

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()
Vince
20.5k16 gold badges49 silver badges65 bronze badges
asked Jun 19, 2019 at 19:52
3
  • 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 Commented Jun 20, 2019 at 7:29
  • Sorry, this is probably a simple answer, but how would I assign vor_poly as a QGIS vector layer? Commented Jun 24, 2019 at 11:29
  • I add an answer @Emtomp Commented Jun 24, 2019 at 14:45

2 Answers 2

2

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)
answered Jun 24, 2019 at 14:43
1
  • 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()): Commented Jun 28, 2019 at 14:02
1

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()
answered Jun 28, 2019 at 14:08
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.