QGIS 3.40.14 with Python 3.12.12
I created a custom QgsCustomDropHandler that reads lines and points from a text file (not .shp or any of the other supported formats) and want to display them on the map:
def handleFileDrop(self, file):
#Do all the checks (correct format,...) and read lines and points
print(len(ls),"lines")
self.vectorlayer = QgsVectorLayer("Point", "mylayer", "memory")
dataprovider = self.vectorlayer.dataProvider()
fields = QgsFields()
fields.append(QgsField('name',QVariant.String))
fields.append(QgsField('id', QVariant.Int))
fields.append(QgsField('date', QVariant.Int))
lines = []
for l in ls:
line = QgsFeature(fields)
points = []
for p in l.points:
points.append(QgsPoint(p.x,p.y,p.z))
line.setGeometry(QgsGeometry.fromPolyline(points))
line.setAttributes([l.name,l.id,l.date])
lines.append(line)
#dataprovider.addFeature(line) #Version 2
(result, newFeatures) = dataprovider.addFeatures(lines) #Version 1
print("result:",result,"-",len(newFeatures),"new features")
self.vectorlayer.updateExtents()
print(dataprovider.featureCount(),"features")
QgsProject.instance().addMapLayer(self.vectorlayer)
self.iface.mapCanvas().refresh()
Extra classes:
@dataclass
class Line:
name: str
id: int
date: int
points: list[Point]
@dataclass
class Point:
x: float
y: float
z: float
id: int
time: int
I adapted the code posted in this answer and I'm aware that this creates a new layer every time a valid file is dragged into QGIS (this is fine for now). The layer is created, there aren't any errors but nothing is drawn on the map.
Prints:
1 lines
result: False - 1 new features
0 features
So it does successfully find and read one line from the file (~ 50 points) but for some reason actually adding it fails. It doesn't matter if I use version 1 or 2, nothing is ever displayed on the map and right-click "show feature count" is always "[0]".
I also tested the version without QgsVectorDataProvider, as suggested here (I don't need any signals):
with edit(self.vectorlayer):
self.vectorlayer.addFeatures(lines)
result = self.vectorlayer.updateExtents()
print("result:",result)
This always prints: result: None
What am I missing?
Bonus question: Is my way of adding attributes for each line correct? There's probably no way to also add information to specific points (like the id or time), if it's even possible to select them in a polyline, is there?
Edit:
I can successfully add a single point with features:
fields = QgsFields()
fields.append(QgsField('id', QVariant.Int))
fields.append(QgsField('time', QVariant.Int))
dataprovider.addAttributes(fields)
self.vectorlayer.updateFields()
p1 = ls[0].points[0]
feature = QgsFeature(fields)
feature.setGeometry(QgsGeometry.fromPoint(QgsPoint(p1.x,p1.y,p1.z)))
feature.setAttributes([p1.id, p1.time])
(result, newFeatures) = dataprovider.addFeatures([feature])
print("result:",result,"-",len(newFeatures),"new features")
self.vectorlayer.updateExtents()
print(dataprovider.featureCount(),"features")
... and also all points within that line (1 point=1 feature in a list) but for some reason it always fails when I want to add a full polyline. Does QgsGeometry.fromPolyline require additional code (or something like that)?
dataprovider.addAttributes(fields)thenself.vectorlayer.updateFields(). If the feature attributes don't match the layer fields, the feature/s will not be successfully added.Falseand afterwards there aren't any features in the layer.QgsGeometry.fromPolylineis causing the problem?).