5

I am trying to create a new vector memory layer with attribute data populated as follows and cannot figure out why it works with integer or string typed data but silently does not populate any rows with double typed data.

def create_layer(columns: List[QgsField], data: List[Tuple]):
   layer = QgsVectorLayer('multipoint?crs=epsg:3347', "TEST", "memory")
   provider = layer.dataProvider()
   provider.addAttributes(columns)
   with edit(layer):
      for row in data:
         wkb, attrs = row[0], row[1:]
         geom = QgsGeometry()
         geom.fromWkb(bytearray(wkb))
         feature = QgsFeature()
         feature.setGeometry(geom)
         feature.setAttributes(list(attrs))
         provider.addFeatures([feature])
   return layer

assert create_layer(
   columns=[QgsField('weight', QVariant.Int)],
   data=list(zip(my_geoms, [int(w) for w in my_weights]))
).featureCount() > 0   # PASS

assert create_layer(
   columns=[QgsField('weight', QVariant.String)],
   data=list(zip(my_geoms, [str(w) for w in my_weights]))
).featureCount() > 0   # PASS

assert create_layer(
   columns=[QgsField('weight', QVariant.Double)],  # also tried QgsField('weight', QVariant.Double, 'double' , 8, 6)
   data=list(zip(my_geoms, [round(w, 2) for w in my_weights]))
).featureCount() > 0     # FAILS!

(The length of my_geoms & my_weights are the same & the values of my_weights are Python floats)

2
  • Could you share a sample of my_weights? What is QGIS Version? Do you get any error? Commented Jan 9, 2022 at 13:14
  • The weights are [0,1] valued: ex: 0.6828403472900391, with no exponentially tiny values.
    – eliangius
    Commented Jan 10, 2022 at 13:44

2 Answers 2

5

I am not sure if it works (because I couldn't produce the same issue), but sometimes you need to cast the value to float. So, try:

data=list(zip(my_geoms, [round(float(w), 2) for w in my_weights]))

or maybe:

data=list(zip(my_geoms, [float(round(w, 2)) for w in my_weights]))
1
  • Wow, this solved it! But not sure why the explicit float() casting is required. Thanks.
    – eliangius
    Commented Jan 10, 2022 at 13:42
3

As I could not see any obvious error in your code, I have implemented some code to test your implementation using QGIS 3.16.11. For the sake of simplicity, and as this seemed not the source of the issue, I tested using NULL geometry (i.e., commented out the call to geom.fromWkb(bytearray(wkb)) in create_layer(). The function test_create_layer() checks the number of features available in the vector layer and prints out the type and value of attributes of each feature:

def create_layer(columns, data):
   layer = QgsVectorLayer('multipoint?crs=epsg:3347', "TEST", "memory")
   provider = layer.dataProvider()
   provider.addAttributes(columns)
   with edit(layer):
      for row in data:
         wkb, attrs = row[0], row[1:]
         geom = QgsGeometry()
         #geom.fromWkb(bytearray(wkb))
         feature = QgsFeature()
         feature.setGeometry(geom)
         feature.setAttributes(list(attrs))
         provider.addFeatures([feature])
   return layer

def test_create_layer(columns_, data_):
    layer = create_layer(columns=columns_, data=data_)
    assert layer.featureCount() == len(data_)
    for f in layer.getFeatures():
        print(f"{f.id()}: {','.join([f'{type(el)}-{str(el)}' for el in f.attributes()])}")

my_geoms = [None, None, None, None] 
my_weights = [1.11111, 2.22222, 3.33333, 4.44444]

test_create_layer([QgsField('weight', QVariant.Int)], list(zip(my_geoms, [int(w) for w in my_weights])))
test_create_layer([QgsField('weight', QVariant.String)], list(zip(my_geoms, [str(w) for w in my_weights])))
test_create_layer([QgsField('weight', QVariant.Double)], list(zip(my_geoms, [round(w, 2) for w in my_weights])))

The code executes successfully and the following output is produced: Vector layers created with different type of attributes Overall, the code works fine in my case. Maybe something in my_weights or my_geoms causes the issue at your end.

1
  • Thanks @fastest for the diagnosis. Since it works as-is on your end, I take it its a glitch in my QGIS 3.18 version then.
    – eliangius
    Commented Jan 10, 2022 at 13:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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