Я пытаюсь создать новый слой векторной памяти с данными атрибутов, заполненными следующим образом, и не могу понять, почему он работает с целочисленными или строковыми данными, но молча не заполняет строки данными с двойным типом.

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!

(Длина my_geoms и my_weights одинакова, а значения my_weights являются числами с плавающей запятой Python)

2
Kadir Şahbaz 9 Янв 2022 в 16:21
Спасибо, что отметили. Исправлено, чтобы отразить проблему.
 – 
eliangius
9 Янв 2022 в 07:07
Не могли бы вы поделиться образцом my_weights? Что такое версия QGIS? Вы получаете какую-либо ошибку?
 – 
Kadir Şahbaz
9 Янв 2022 в 16:14

2 ответа

Поскольку я не увидел в вашем коде какой-либо очевидной ошибки, я реализовал некоторый код для проверки вашей реализации с помощью QGIS 3.16.11. Для простоты, и поскольку это не казалось источником проблемы, я тестировал с использованием геометрии NULL (т. е. закомментировал вызов geom.fromWkb(bytearray(wkb)) в create_layer(). Функция test_create_layer() проверяет количество объектов, доступных в векторном слое, и выводит тип и значение атрибутов каждого объекта:

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])))

Код выполняется успешно, и выдается следующий вывод: Векторные слои, созданные с различными типами атрибутов В целом, код работает нормально в моем случае. Возможно, что-то в my_weights или my_geoms вызывает проблему на вашем конце.

1
fastest 9 Янв 2022 в 15:31

Я не уверен, что это работает (потому что я не мог создать ту же проблему), но иногда вам нужно привести значение к float. Так что постарайтесь:

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

Или, может быть:

data=list(zip(my_geoms, [float(round(w, 2)) for w in my_weights]))
1
Kadir Şahbaz 9 Янв 2022 в 23:58