0

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 &lt;'+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': '&quot;Date Logged (AET (+10:00))&quot;','length': 0,'name': 'Date Logged (AET (+10:00))','precision': 0,'type': 10},{'expression': '&quot;Date Received (AET (+10:00))&quot;','length': 0,'name': 'Date Received (AET (+10:00))','precision': 0,'type': 10},{'expression': '&quot;Log Reason&quot;','length': 0,'name': 'Log Reason','precision': 0,'type': 10},{'expression': '&quot;Transmission Delay(s)&quot;','length': 0,'name': 'Transmission Delay(s)','precision': 0,'type': 10},{'expression': '&quot;Latitude&quot;','length': 0,'name': 'Latitude','precision': 0,'type': 10},{'expression': '&quot;Longitude&quot;','length': 0,'name': 'Longitude','precision': 0,'type': 10},{'expression': '&quot;GPS Age&quot;','length': 0,'name': 'GPS Age','precision': 0,'type': 10},{'expression': '&quot;Speed KmH&quot;','length': 0,'name': 'Speed KmH','precision': 0,'type': 10},{'expression': '&quot;Used Speed Limit (KmH)&quot;','length': 0,'name': 'Used Speed Limit (KmH)','precision': 0,'type': 10},{'expression': '&quot;Speed Band&quot;','length': 0,'name': 'Speed Band','precision': 0,'type': 10},{'expression': '&quot;Speed Accuracy (KmH)&quot;','length': 0,'name': 'Speed Accuracy (KmH)','precision': 0,'type': 10},{'expression': '&quot;Heading Degrees&quot;','length': 0,'name': 'Heading Degrees','precision': 0,'type': 10},{'expression': '&quot;Altitude (m)&quot;','length': 0,'name': 'Altitude (m)','precision': 0,'type': 10},{'expression': '&quot;Position Accuracy (m)&quot;','length': 0,'name': 'Position Accuracy (m)','precision': 0,'type': 10},{'expression': '&quot;PDOP Raw&quot;','length': 0,'name': 'PDOP Raw','precision': 0,'type': 10},{'expression': '&quot;Ignition&quot;','length': 0,'name': 'Ignition','precision': 0,'type': 10},{'expression': '&quot;Gps Status Fix OK&quot;','length': 0,'name': 'Gps Status Fix OK','precision': 0,'type': 10},{'expression': '&quot;Gps Status Fix 3D&quot;','length': 0,'name': 'Gps Status Fix 3D','precision': 0,'type': 10},{'expression': '&quot;Digital Inputs&quot;','length': 0,'name': 'Digital Inputs','precision': 0,'type': 10},{'expression': '&quot;Digital Outputs&quot;','length': 0,'name': 'Digital Outputs','precision': 0,'type': 10},{'expression': '&quot;Driver Id Type&quot;','length': 0,'name': 'Driver Id Type','precision': 0,'type': 10},{'expression': '&quot;Driver Id Data&quot;','length': 0,'name': 'Driver Id Data','precision': 0,'type': 10},{'expression': '&quot;Trip Type Code&quot;','length': 0,'name': 'Trip Type Code','precision': 0,'type': 10},{'expression': '&quot;Project Code&quot;','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(&quot;^DeviceDataExport_(.*)_.*&quot;,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+&quot;//&quot;+fn+&quot;.tab&quot;
Clean_Mower_Data(in_file,out_file, max_speed, max_length)
print ('processed: %s --to--&gt; %s' % (file, fn))

print ('Completed')

GeorgeC
  • 8,228
  • 7
  • 52
  • 136
  • 2
    What if you simply add QgsProcessing to your list of imports from qgis.core? The error makes sense because you haven't actually imported the QgsProcessing class. – Ben W Aug 10 '22 at 05:21
  • 1
    So simple, I assumed it was part of the import processing later on. – GeorgeC Aug 10 '22 at 07:22
  • 1
    In fact I think it will also work if you just use the string 'TEMPORARY_OUTPUT' because the attribute QgsProcessing.TEMPORARY_OUTPUT just returns a QStringLiteral("TEMPORARY_OUTPUT") https://api.qgis.org/api/classQgsProcessing.html#a62584b5ed1558ebdf04a95d6f4a9d403 – Ben W Aug 10 '22 at 11:02
  • 1
    You could, but it is cleaner this way and safer against future changes. :) – bugmenot123 Aug 10 '22 at 11:21

0 Answers0