I am moving a QGIS model to PyQGIS to be able to run it as part of a bat file in OSGEO Shell.
It's working fine in QGIS and if the data in each stage is written to a on disk file but I can't write to memory so that each part of the model can use model memory outputs.
The whole code is below. This is the error I get when run in OSGEO4W shell.
G:\Projects\192_Mowing_Automated_Reporting\Working>python3 2_Process_Mower_Data_Osgeo.py
'"Speed KmH" < 30'
Traceback (most recent call last):
File "G:\Projects\192_Mowing_Automated_Reporting\Working\2_Process_Mower_Data_Osgeo.py", line 136, in <module>
Clean_Mower_Data(in_file,out_file, max_speed, max_length)
File "G:\Projects\192_Mowing_Automated_Reporting\Working\2_Process_Mower_Data_Osgeo.py", line 34, in Clean_Mower_Data
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
NameError: name 'QgsProcessing' is not defined
G:\Projects\192_Mowing_Automated_Reporting\Working>pause
Press any key to continue . . .
I know we can have 'OUTPUT': 'memory' then how do we get a particular version of it like I get
outputs['CreatePointsLayerFromTable'] = processing.run('native:createpointslayerfromtable', alg_params)
then use this in the next process as
alg_params = {
'INPUT': outputs['CreatePointsLayerFromTable']['OUTPUT'],
==== code base ===
# create environment for qgis to run outside of the application as per https://gis.stackexchange.com/a/279937/2891
import sys
from qgis.core import (
QgsApplication,
QgsProcessingFeedback,
QgsVectorLayer
)
See https://gis.stackexchange.com/a/155852/4972 for details about the prefix
QgsApplication.setPrefixPath('C:\Program Files\QGIS\apps\qgis', True)
qgs = QgsApplication([], False)
qgs.initQgis()
Append the path where processing plugin can be found
sys.path.append('C:\Program Files\QGIS\apps\qgis\python\plugins')
import processing
from processing.core.Processing import Processing
Processing.initialize()
import os, glob, re
in_dir=r'G:\Projects\192_Mowing_Automated_Reporting\Input'
out_dir=r'G:\Projects\192_Mowing_Automated_Reporting\Working\Draft_Output'
os.chdir(in_dir)
def Clean_Mower_Data(in_file,out_file, max_speed, max_length):
# Extract by expression
outputs = {}
max_speed_alg=''"Speed KmH" < '+ str(max_speed)+'''
print (max_speed_alg)
alg_params = {
'EXPRESSION': '"Speed KmH" < '+ str(max_speed) +' AND"Ignition" = 'On'',
'INPUT': in_file,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['ExtractByExpression']=processing.run('native:extractbyexpression', alg_params)
print ('1_ExtractByExpression')
# Create points layer from table
alg_params = {
'INPUT': outputs['ExtractByExpression']['OUTPUT'],
'MFIELD': '',
'TARGET_CRS': QgsCoordinateReferenceSystem('EPSG:4326'),
'XFIELD': 'Longitude',
'YFIELD': 'Latitude',
'ZFIELD': '',
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['CreatePointsLayerFromTable'] = processing.run('native:createpointslayerfromtable', alg_params)
print ('2_CreatePointsLayerFromTable')
# Points to path
alg_params = {
'CLOSE_PATH': False,
'GROUP_EXPRESSION': '',
'INPUT': outputs['CreatePointsLayerFromTable']['OUTPUT'],
'NATURAL_SORT': False,
'ORDER_EXPRESSION': '',
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['PointsToPath'] = processing.run('native:pointstopath', alg_params)
print ('3_PointsToPath')
# Explode lines
alg_params = {
'INPUT': outputs['PointsToPath']['OUTPUT'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['ExplodeLines'] = processing.run('native:explodelines', alg_params)
print ('4_ExplodeLines')
# Extract by expression
alg_params = {
'EXPRESSION': '$length <'+str(max_length),
'INPUT': outputs['ExplodeLines']['OUTPUT'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['ExtractByExpression2']=processing.run('native:extractbyexpression', alg_params)
print ('5_Extracted')
# Join attributes by location
alg_params = {
'DISCARD_NONMATCHING': False,
'INPUT': outputs['ExtractByExpression2']['OUTPUT'],
'JOIN': outputs['CreatePointsLayerFromTable']['OUTPUT'],
'JOIN_FIELDS': [''],
'METHOD': 1, # Take attributes of the first matching feature only (one-to-one)
'PREDICATE': [0], # intersects
'PREFIX': '',
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
outputs['JoinAttributesByLocation'] = processing.run('native:joinattributesbylocation', alg_params, )
print ('6_Joined')
# Refactor fields
alg_params = {
'FIELDS_MAPPING': [{'expression': '"Date Logged (AET (+10:00))"','length': 0,'name': 'Date Logged (AET (+10:00))','precision': 0,'type': 10},{'expression': '"Date Received (AET (+10:00))"','length': 0,'name': 'Date Received (AET (+10:00))','precision': 0,'type': 10},{'expression': '"Log Reason"','length': 0,'name': 'Log Reason','precision': 0,'type': 10},{'expression': '"Transmission Delay(s)"','length': 0,'name': 'Transmission Delay(s)','precision': 0,'type': 10},{'expression': '"Latitude"','length': 0,'name': 'Latitude','precision': 0,'type': 10},{'expression': '"Longitude"','length': 0,'name': 'Longitude','precision': 0,'type': 10},{'expression': '"GPS Age"','length': 0,'name': 'GPS Age','precision': 0,'type': 10},{'expression': '"Speed KmH"','length': 0,'name': 'Speed KmH','precision': 0,'type': 10},{'expression': '"Used Speed Limit (KmH)"','length': 0,'name': 'Used Speed Limit (KmH)','precision': 0,'type': 10},{'expression': '"Speed Band"','length': 0,'name': 'Speed Band','precision': 0,'type': 10},{'expression': '"Speed Accuracy (KmH)"','length': 0,'name': 'Speed Accuracy (KmH)','precision': 0,'type': 10},{'expression': '"Heading Degrees"','length': 0,'name': 'Heading Degrees','precision': 0,'type': 10},{'expression': '"Altitude (m)"','length': 0,'name': 'Altitude (m)','precision': 0,'type': 10},{'expression': '"Position Accuracy (m)"','length': 0,'name': 'Position Accuracy (m)','precision': 0,'type': 10},{'expression': '"PDOP Raw"','length': 0,'name': 'PDOP Raw','precision': 0,'type': 10},{'expression': '"Ignition"','length': 0,'name': 'Ignition','precision': 0,'type': 10},{'expression': '"Gps Status Fix OK"','length': 0,'name': 'Gps Status Fix OK','precision': 0,'type': 10},{'expression': '"Gps Status Fix 3D"','length': 0,'name': 'Gps Status Fix 3D','precision': 0,'type': 10},{'expression': '"Digital Inputs"','length': 0,'name': 'Digital Inputs','precision': 0,'type': 10},{'expression': '"Digital Outputs"','length': 0,'name': 'Digital Outputs','precision': 0,'type': 10},{'expression': '"Driver Id Type"','length': 0,'name': 'Driver Id Type','precision': 0,'type': 10},{'expression': '"Driver Id Data"','length': 0,'name': 'Driver Id Data','precision': 0,'type': 10},{'expression': '"Trip Type Code"','length': 0,'name': 'Trip Type Code','precision': 0,'type': 10},{'expression': '"Project Code"','length': 0,'name': 'Project Code','precision': 0,'type': 10}],
'INPUT': outputs['JoinAttributesByLocation']['OUTPUT'],
'OUTPUT': out_file
}
outputs['RefactorFields'] = processing.run('native:refactorfields', alg_params)
print ('7_Refactored')
# Fix geometries
alg_params = {
'INPUT': outputs['RefactorFields']['OUTPUT'],
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
#
outputs['FixGeometries']=processing.run('native:fixgeometries', alg_params)
print ('8_FixedGeometry')
# Reproject layer
alg_params = {
'INPUT': outputs['FixGeometries']['OUTPUT'],
'OPERATION': '',
'TARGET_CRS': QgsCoordinateReferenceSystem('EPSG:28355'),
'OUTPUT': out_file
}
processing.run('native:reprojectlayer', alg_params)
print ('9_Reprojected')
filelist=glob.glob('*.csv')
for file in filelist:
#Process with speed/length limits
fn=os.path.splitext(file)[0]
max_speed=30
max_length =150
fn=s=re.findall("^DeviceDataExport_(.*)_.*",fn)
fn=re.sub('[^A-Za-z0-9]+', '', fn[0])+'__s'+str(max_speed)+'_l'+str(max_length)
in_file=os.path.join(in_dir,file)
out_file=out_dir+"//"+fn+".tab"
Clean_Mower_Data(in_file,out_file, max_speed, max_length)
print ('processed: %s --to--> %s' % (file, fn))
print ('Completed')
QgsProcessingto your list of imports fromqgis.core? The error makes sense because you haven't actually imported theQgsProcessingclass. – Ben W Aug 10 '22 at 05:21import processinglater on. – GeorgeC Aug 10 '22 at 07:22QgsProcessing.TEMPORARY_OUTPUTjust returns aQStringLiteral("TEMPORARY_OUTPUT")https://api.qgis.org/api/classQgsProcessing.html#a62584b5ed1558ebdf04a95d6f4a9d403 – Ben W Aug 10 '22 at 11:02