2

I have two layers, 'river (line)' and 'points' for a set of points laying on a line which is perpendicular to the river (for example red points in the first image).

enter image description here

Given an interval (5.0 m for example), how can I copy those points along the river (blue sets of points in the next image)? But every set of points must be perpendicular to the related segment of river.

enter image description here

But I have just the following result using the next script.

enter image description here

from numpy import arange

L = lambda name: QgsProject.instance().mapLayersByName(name)[0]

point_layer = L("points")
river_layer = L("river")

points = list(point_layer.getFeatures())
river_geom = list(river_layer.getFeatures())[0].geometry()

# Find the nearest point on the river to the points
# The points are laying on the same line perpendicular to the river,
# it's sufficient to use any point.
nearest_point = river_geom.nearestPoint(points[0].geometry())

interval = 5.0
start = river_geom.lineLocatePoint(nearest_point) % interval
end = int(river_geom.length()/interval)*interval + start
for i in arange(start, end + interval, interval):
    p = river_geom.interpolate(i)
    dx = p.asPoint().x() - nearest_point.asPoint().x()
    dy = p.asPoint().y() - nearest_point.asPoint().y()

    feats = []
    for point in points:
        feat = QgsFeature()
        geom = point.geometry()
        geom.translate(dx, dy)
        feat.setGeometry(geom)
        feats.append(feat)

    point_layer.dataProvider().addFeatures(feats)

point_layer.updateExtents()
iface.mapCanvas().refresh()
3

You're very close. Now, you just need to rotate your points in the inner for loop.

To know how many degrees, get these 2 angles:

# Before the for loops
n_p_angle = river_geom.interpolateAngle(river_geom.lineLocatePoint(nearest_point))

# Inside the outer for loop
a = river_geom.interpolateAngle(i) 

Now, make sure you import the module math and after the call to geom.translate() call:

geom.rotate(math.degrees(a-n_p_angle), p.asPoint())

You'll get something like this:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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