1

Within a QGIS plugin I download data which is then converted into a list of QgsFeatures. My way of storing for a long time was to use addFeatures on the provider object, but now in QGIS 3.16 LTR, not all features of the list are stored into the memory layer and I can't find the error.

# the main part of the function body:
        # load data
        features = postats.getFeatures()
        print(len(features)) # 654
        # create layer
        crs = QgsCoordinateReferenceSystem(4326)
        vlout = QgsVectorLayer("Point?crs=%s"%crs.authid(), layername, "memory")
        ### AMR: missing features
        ### vlout.startEditing()
        ###
        pr = vlout.dataProvider()
        pr.addAttributes(postats.fields)
        vlout.updateFields()

        pr.addFeatures(features)
        vlout.updateExtents()
        
        ### AMR
        ### vlout.commitChanges()
        print(vlout.featureCount()) # 47
        ###
        
        # add layer to QGIS canvas
        QgsProject.instance().addMapLayer(vlout)
        # add a styele
        vlout.loadNamedStyle(os.path.join(self.local_dir, style))
        # turn on labeling
        vlout.setLabelsEnabled(True)
        self.layerRefresh(vlout)

        return vlout

As you can see, I commented out my first take to fix it: using startEditing()/commitChanges() I got no changes in my result: Only 47 of 654 features are stored in the layer.

Postat, by the way, is another module to fill the feature list and create the QgsFields

3
  • I have just seen that the data type of one field was inrorrect, and the relevant code isn't listed in my question. I used QVariant.Int for field called number, but my features contain strings for that field. This error was hard to find because adding the features happens without an exception. Now my question should be: Is there a way to check field types and feature attributes? May 8 at 16:59
  • What do you mean by checking feature attributes ?
    – JULESG
    May 19 at 10:56
  • My problem is that I choose a wrong data type for one field, int instead of string, but there is no error/exception when running the code. So I asked if there is a standard way to check if data and data types match before calling addFeatures. May 19 at 12:32
1

I don't know if there is a Standard way to check compatibility between attribute type and field type. If you have a version of QGIS superior to 3.14 you can try displayType.

Else you can use QgsField's methods isNumeric, precision and isDateOrTime to test your field type. Like in this code :

layer_fields_type = [] # list to keep the type of each field in order
fields = postats.fields()
for field in fields :
    if field.isNumeric(): # if the field is numeric
        if field.precision() == 0 : 
            layer_fields_type.append(int) # if the field is an integer add the integer type
        else :
            layer_fields_type.append(float) # else add the float type
    else :
        layer_fields_type.append(str) # if the field is not numeric it's a string, if you also have date you can add a condition with isDateOrTime

features = postats.getFeatures() 
for feature in features: 
    n = 0 # index of the field
    attributes = feature.attributes()
    for attribute in attributes :
        if isinstance(attribute, layer_fields_type[n]): # test if the value type equals the field type
            print("attribute type is the same as field type")
        else :
            if attribute == NULL : # NULL value is not the same type as the field type
                print("attribute value is NULL")
            else :
                print("attribute type is not the same as field type")
        n = n+1 # next field

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.