2

The label toolbar uses fields in the attribute table of vector layers to fine tune labeling (Data defined labeling). That's the main reason i'm looking for that, but it may have more applications.

I'd like to automatically add some format columns instead of adding them manually every time.

Do you know a plugin or a way to do this manipulation automatically on multiples layers ?

I tried to get the QGIS tool "Add a field to attribute table" into a quick model which works properly, but it creates a new memory layer. And I'd like just new fields.

##Add_ETIKT_Field=name
##myvlayer=vector
##myvlayer=output vector
outputs_QGISADDFIELDTOATTRIBUTESTABLE_2=processing.runalg('qgis:addfieldtoattributestable', myvlayer,'ETIKT_Y',1,15.0,4.0,None)
outputs_QGISADDFIELDTOATTRIBUTESTABLE_1=processing.runalg('qgis:addfieldtoattributestable', outputs_QGISADDFIELDTOATTRIBUTESTABLE_2['OUTPUT_LAYER'],'ETIKT_X',1,15.0,5.0,myvlayer)

What I'm looking to automate is :

  • Open the attribute table
  • Edit button
  • Field Calculator button
  • Add Column + Type + length + Precision

It seems there's some ideas in QGIS manual, but I'd love to avoid coding anything, or at least at minimum go through the modeler.

Adding and Removing Fields

To add fields (attributes), you need to specify a list of field definitions. For deletion of fields just provide a list of field indexes.

if caps & QgsVectorDataProvider.AddAttributes:
    res = layer.dataProvider().addAttributes([QgsField("mytext", QVariant.String), QgsField("myint", QVariant.Int)])

if caps & QgsVectorDataProvider.DeleteAttributes:
    res = layer.dataProvider().deleteAttributes([0])
3

Within the graphical modeler (processing > grapical modeler) add 'vector layer' as input. There you can choose if it has to be a point-, line- or polygonlayer or that it does not mather (=any)

Choose 'add field to attribute table' as many times as you need extra fields. In the last algorithm you add a description under 'Added OutputVector'.

enter image description here

Here you can set the fieldname, type, length and precision.

Once you added all fields with their corresponding properties give your model a name and set a group. Save it. You'll find it under C:\Users\username.qgis2\processing\models.

Once saved, the model shows up in the processing toolbox under 'Models'. Doubleclick it to open the dialogue. In the top right corner you can select 'Run as batch process'.

enter image description here

A new dialogue appears where you can select all the layers you want to add new fields. You have to give them a new name and location to save them as a shapefile (else they would appear as a temporary layer in your project)

enter image description here

  • thanks for your long answer... but I already did that (see my message and the content of my model). The main problem is that you have to create new layers. I just want to add fields to my existing layer and alas the algorithm add_fields_to_layer adds fields + creates a new layer. I could do that, but I'm looking for a way not not create those layers (see Arcgis tool i'm trying to mimic : pro.arcgis.com/en/pro-app/tool-reference/data-management/…). Plugin Table Manager does something similar but it duplicates the layer too. – gisnside Aug 23 '16 at 14:03
  • The Table Manager Plugin does not automatically want a new layer. I assume it is dependent on the file type. – AndreJ Aug 23 '16 at 18:10
  • Actually, unless i misunderstood what it does, it seems the Table manager does creates a new layer, but what happens is that it backups the previous layer and reloads a new layer with the same name and symbology then the old one, except it has done the task one asked for with the fields. It's just managed by the plugin in a nice and invisible way for the user :) – gisnside Aug 24 '16 at 9:17
  • So you would have to do the same in your model, if the graphic modeler allows it. If not, it would be worth a feature request. – AndreJ Aug 24 '16 at 14:40
2

Considering your question and na answer given to a different question (https://gis.stackexchange.com/a/226966/68235), I created the following lines:

from PyQt4.QtCore import QVariant

for layer in QgsMapLayerRegistry.instance().mapLayers().values(): 

if layer.name() == "whatever_the_name_of_layer_is": #you could remove this condition if you want to add the fields to all layers (NOT TESTED)

    with edit(layer):
        layer.dataProvider().addAttributes( [ QgsField("txt_Field1_name", QVariant.String, "text", 600) ] )
        layer.dataProvider().addAttributes( [ QgsField("txt_Field2_name", QVariant.String, "text", 600) ] )
        layer.dataProvider().addAttributes( [ QgsField("decimal_Field1_name", QVariant.Double, "double", 10, 3) ] )

else:
    pass

There are plenty of examples with similar codes that you could be used to change the type of field to be added. Not exactly what you were looking for, but it may be helpful to other users who eventually find your question.

1

I finally made up the following code that will do the trick on your choice of loaded layers in QGIS interface. The script can be adapted quite easily to fit any other field types. It's quite basic but it fits my needs.

It can be much more improved if need but it's a first for me. You can add some loops to check if the column name doesn't exist, etc. I would also like to have a refreshed attribute table because the display doesn't refresh and I need to reload the layers to see the changes.

How to use it :

  • Create an empty text file in your script folder with a .py extension. On my computer, it's C:\Users[mylogin].qgis2\processing\scripts and paste the following coding
  • In the processing panel, go to "Scripts", then "Tools", then "Add script from file"
  • Choose the script your created
##Perso=group
##Add_Labelling_Fields=name

##layer=multiple vector
##Field_ETIKT_X=string ETIKT_X
##Field_ETIKT_Y=string ETIKT_Y
##Field_ETIKT_ROT=string ETIKT_ROTATE

from osgeo import ogr

layers= layer.split(";")

for i in layers:
    driver = ogr.GetDriverByName('ESRI Shapefile')
    dataSource = driver.Open(i, 1) #1 is read/write

    #define 3 floating point fields :
    fldDef_X = ogr.FieldDefn(str(Field_ETIKT_X), ogr.OFTReal)
    fldDef_Y = ogr.FieldDefn(str(Field_ETIKT_Y), ogr.OFTReal)
    fldDef_ROT = ogr.FieldDefn(str(Field_ETIKT_ROT), ogr.OFTReal)

    #get layer and add the 3 fields:
    vlayer = dataSource.GetLayer()
    vlayer.CreateField(fldDef_X)
    vlayer.CreateField(fldDef_Y)
    vlayer.CreateField(fldDef_ROT)
    progress.setInfo(i+' OK')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.