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()
2 Answers 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)
-
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– Emtomp2019年06月28日 14:02:27 +00:00Commented Jun 28, 2019 at 14:02
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()
vor_poly
is a path not Qgsvectorlayer you need access to processing output or create a QgsVectorlayer from voronoi path and then make a clipvor_poly
as a QGIS vector layer?