I've coded the script below in PyQGIS 3
to get the azimuth of starting or ending points for a line layer that touches a border. It works fine, but I want to populate the azimuth field layer with the value from azDict and doesn't work.
from shapely.geometry import LineString, Point, Polygon, LinearRing
lLayer = QgsProject.instance().mapLayersByName('roads')[0]
pLayer = QgsProject.instance().mapLayersByName('aux_point')[0]
polLayer = QgsProject.instance().mapLayersByName('aux_boundary')[0]
feat = QgsFeature()
pr = pLayer.dataProvider()
vDict = {}
azDict = {}
# iterates in vertex lines to get dict = {Point1:Point2}
for road in lLayer.getFeatures():
if road.geometry() is not None:
line = road.geometry().asMultiPolyline()
for vrtx in line:
stp = QgsPointXY(line[0][0]) # start point
scp = QgsPointXY(line[0][1]) # second point
vDict[stp] = vDict.setdefault(stp, scp)
edp = QgsPointXY(line[-1][-1]) # end point
lbo = QgsPointXY(line[-1][-2]) # last but one point
vDict[edp] = vDict.setdefault(edp, lbo)
# iterates in vDict to calculates the azimuth
for k,v in vDict.items():
azim = k.azimuth(v)
azDict[k] = azDict.setdefault(k,azim) # gives a dict = {Point:Azimuth}
# begin the spatial filter
for polygon in polLayer.getFeatures(): # transforms my boundary in a shapely LinearRing
if polygon.geometry() is not None:
poly = polygon.geometry().asMultiPolygon()
pol = Polygon(poly[0][0]) # creates a shapely polygon
linearring = LinearRing(list(pol.exterior.coords))
# iterates in azDict to filter spatially
for k,v in azDict.items():
if linearring.distance(Point(k)) < 1:
orientation = pr.fieldNameIndex("azimuth")
feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(Point(k).x,Point(k).y)))
pr.addFeatures([feat])
# try to write the azimuth in the field but doesn't works
pLayer.startEditing()
pLayer.changeAttributeValue(feat.id(), orientation, v)
QgsProject.instance().addMapLayer(pLayer)
pLayer.triggerRepaint()
pLayer.commitChanges()
Am I losing something?
azDict
is a dictionary where the keys are QGSPointXY objects and the values are Azimuth values which are floating point numbers? Do you get an error? Do the fields not change? What if you dopLayer.changeAttributes(feat.id(), orientation, 99.9)
- does it change? That will tell you ifv
is the problem. Maybe its a QFloat, or a string, or some other weird type. Is it actually getting to that code or is theif
not true?v
and doesn't make any changes. I'll put all the code in question maybe it helps.feat.id()
,orientation
, andv
just before you trypLayer.changeAttributeValue
to check that line is being exeuted and what the values are.