4

I wrote a simple plugin to retrieve and synchronize points from remote MongoDb into a generated scratch layer with all the attributes every time the project open, edit and commit but the attribute naming bothering me for sometimes.

Scratch layer is in-memory layer that does not preserve the features upon exit. However I can save the project together with the layer.

Whenever I load the project, the attributes name of scratch layer gets appended with :(0,0). E.g. the attribute changed from city to city:(0,0) why?

Edit:

Apparently it will only happened if the attributes created using python.

How to produce:

layer = iface.activeLayer()
from PyQt4.QtCore import QVariant
field = QgsField("test", QVariant.String)
layer.dataProvider().addAttributes([field])
layer.updateFields()
  1. Create Temporary Scratch Layer
  2. Run the code above in Python Console
  3. Save the layer edit and project into a .qgs file.
  4. Exit and reopen QGIS
  5. Reopen the saved project file
  6. Open the layer Properties > Fields
  7. The attribute name test will turns into test:(0,0)

I am using QGIS 2.18.2

Edit2:

I found that QGIS does not preserve the data type string into the project file when the field created using python. The project file .qgs xml content under qgs > projectlayers > maplayer > datasource is:

memory?geometry=None&field=test:(0,0)

but it should be:

memory?geometry=None&field=test:string(0,0)
10
  • I think that a snippet of your code could help to understand the problem. By now, it's really unclear what you are asking.
    – mgri
    Feb 6 '17 at 10:20
  • I just update, it only happened if the attributes created using python
    – CallMeLaNN
    Feb 6 '17 at 10:59
  • I can't reproduce the issue because I see test as attribute name in Properties > Field. Do you edit the scratch layer before saving it or it's keeped with NULL values?
    – mgri
    Feb 6 '17 at 11:15
  • I just turn off all plugins but still the same. I am not editing the scratch layer except using the python code above. Note that I save and reload the project. See the update above.
    – CallMeLaNN
    Feb 7 '17 at 6:33
  • 1
    I got it, I was able to reproduce your issue. I don't know if I'm wrong but, according to me, even if you still see the scratch layer when you reload the project, actually it has been deleted: in fact, you don't see its geometry displayed on the canvas, but there is only a reference to it in the Layers Panel. I don't know what you want to do with this layer, but probably you should create a new scratch layer every time you open the project. Otherwise, please specify the real situation you are working with.
    – mgri
    Feb 7 '17 at 9:54
3

Short answer

It needs to be specific of the third parameter, typeName like this:

QgsField("fieldName", QVariant.String, "string")

So that it will be properly serialized/deserialized in project file.

Long answer

Note the typeName is provider specific type unique to the source. It can be "string", "integer" or "double" based on the documentation. I tried "datetime" seems to work because that is a memory provider.

In order to know what is the typeName other than that, try to create the field manually (trough layer Properties > Fields), save and check the content of .qgs project file where the memory layer<datasource> defined.

Reference:

  1. Adding and Removing Fields and using Memory Provider was documented here but only use first two parameters of QgsField constructor.

  2. The above link and c++ QgsVectorLayer class detailed description also mentioned about the similar format defined in the project file:

field=name:type(length,precision) Defines an attribute of the layer. Multiple field parameters can be added to the data provider definition. type is one of "integer", "double", "string".

  1. The c++ QgsField class constructor shows about the typeName but does gives only SQL like example eg. text or varchar instead of string. I believe typeName is anything that the provider support. You can just try to save a data type and check the .qgs file like I mention above.

Issue:

This is definitely an issue, the field type information does not get serialized/deserialized properly into project file. Apart from that, the memory provider should also translate the QVariant.String into "string" or maybe state in documentation, the typeName parameter is compulsory.

Anyone has osgeo account, please file an issue here. It takes time to register & require approval by the admin.

1
  • Just stumbled across this issue too. The answer just saved my day. Can't believe that's still a problem after 5 years have passed.
    – CodeBard
    yesterday

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.