I have a set of points that I'd like to have rotated toward nearest line by adding an attribute column angle.
Original points with no rotation
Points rotated toward line object
I have found and tweaked this script to somewhat achieve what I want. The only problem is that this method only does a search using a rectangular box which sometimes gives me a less satisfying result. Is there a way to do the search using a circle instead?
Here's my tweaked script:
from math import atan2
get layers
buildings = QgsProject.instance().mapLayersByName('buildings')[0]
roads = QgsProject.instance().mapLayersByName('roads')[0]
create angle field
fieldname = "angle"
buildings.dataProvider().addAttributes([QgsField(fieldname,QVariant.Int)])
buildings.updateFields()
get fieldindex
fni = buildings.fields().indexFromName('angle')
initializations
tolerance = 30 # search tolerance
buildings.startEditing()
loop over all buildings
for building in buildings.getFeatures():
x = building.geometry().asPoint().x()
y = building.geometry().asPoint().y()
# get the rectangular search area
searchRect = QgsRectangle(x - tolerance, y - tolerance, x + tolerance, y + tolerance)
# find roads
for road in roads.getFeatures(QgsFeatureRequest().setFilterRect(searchRect)):
# get the nearest vertex on road and the one before and after
pnt, v, b, a, d = road.geometry().closestVertex(building.geometry().asPoint())
p1 = road.geometry().vertexAt(v)
# when vertex before exists look back, otherwise look forward
if v>-1 and b>-1:
p2 = road.geometry().vertexAt(b)
elif v>-1 and a>-1:
p2 = road.geometry().vertexAt(a)
# calculate azimuth
angle = atan2(p2.x() - p1.x(), p2.y() - p1.y()) / 0.017453
building[fni] = angle
buildings.updateFeature(building)
save changes and stop editing
buildings.commitChanges()

