1

I need to create a new field and calculate some values in a file (shapefile or gpkg) with more than 65_000 rows. The quickest way I found was using the processing module with the native:fieldcalculator tool :

from qgis.gui import *
from math import ceil
import processing

Function used to calculate the new field - the content is not important for this question

@qgsfunction(args='auto', group='Custom', referenced_columns=[]) def estimate_time_since_last_pert(pert_years, profile_year, feature, parent): pert_years = [float(t) for t in pert_years if t != NULL] if not pert_years: return 100 last_pert_year = max(pert_years) time_since_last_pert = profile_year - last_pert_year return int(5 * ceil((time_since_last_pert) / 5))

Args of the Field Calculator tool and running the tool

alg_params = { 'FIELD_LENGTH': 4, 'FIELD_NAME': 'TEMPSCoupe', 'FIELD_PRECISION': 0, 'FIELD_TYPE': 1, # Integrer 'NEW_FIELD': True, 'FORMULA': 'estimate_time_since_last_pert(array(AN_ORIGINE, AN_PERTURB), 2020)', 'INPUT': 'src_file.shp', 'OUTPUT': 'dst_file.shp', } processing.run('native:fieldcalculator', alg_params)

However, I can't find a way to modify my input file instead of having to create a new one. Is this possible ?

PolyGeo
  • 65,136
  • 29
  • 109
  • 338
Paulloed
  • 226
  • 1
  • 4
  • You've tired without Field Calculator using this kind of approach with a dictionary? – BERA Jun 16 '23 at 16:04
  • Check this: https://gis.stackexchange.com/a/412130/29431 – Kadir Şahbaz Jun 16 '23 at 16:56
  • 1
    @BERA I have tried with the dictionnary and .dataProvider().changeAttributeValues() but this option is much slower (4minutes) than the fieldcalculator (18 secondes) on my data. I will need to do this multiple times so there is a speed issue – Paulloed Jun 16 '23 at 17:43
  • @KadirŞahbaz the execute_in_place method does not work on a file but on a loaded layer -> QgsVectorLayer(file_path, 'name', 'ogr'). It will return an exception if the INPUT arg is a path : AttributeError: 'str' object has no attribute 'createExpressionContextScope'. So the modification are done in the memory and I need to save the layer object into a file (which comes back to the same thing but slower from the fieldcalculator from my testing :/ ) – Paulloed Jun 16 '23 at 18:03
  • https://gis.stackexchange.com/questions/462051/using-raster-valuelayer-band-point-function-in-pyqgis – BERA Jun 22 '23 at 12:16
  • Remember to add back the things that you have tried into the question (and not just the comments). If creating a new file is quickest method, and speed is critical, have you tried deleting the source file and rename the destination file to the source file name so that you end up with the same final result? – Tom Brennan Jul 09 '23 at 21:48

0 Answers0