PyQGIS – Extending Only One End of Line

extendpyqgisqgis-3qgis-pluginsqgis-processing

From Shortening line with PyQGIS I was able to make a nice tool where the user can click one end of the line or the other and only that end will be shortened. the function is here:

def shorten_line(self, feat, len, point):
    '''Returns a linestring geometry shortened by the given length.
    Takes two arguments- a QgsFeature object and a double value'''
    g = feat.geometry()
    v = [v for v in g.vertices()]
    if QgsGeometry.fromPointXY(QgsPointXY(v[0])).equals(QgsGeometry.fromPointXY(point)):
        print("starting point chosen")
        reverse = QgsLineString(v[::-1])
        g = QgsGeometry(reverse)
        v = [v for v in g.vertices()]
    v.remove(v[-1])
    v.append(QgsPoint(g.interpolate(g.length()-len).asPoint()))
    n = QgsLineString(v)
    return QgsGeometry(n)

Where feat is the line feature, len is the length to be subtracted and point is the vertex that was clicked.
Now I want to make an extend line function that will do the same thing except it will add on to that end of the line instead of subtract. This attempt does not work:

def extend_line(self, feat, len, point):
    '''Returns a linestring geometry shortened by the given length.
    Takes two arguments- a QgsFeature object and a double value'''
    g = feat.geometry()
    v = [v for v in g.vertices()]
    if QgsGeometry.fromPointXY(QgsPointXY(v[0])).equals(QgsGeometry.fromPointXY(point)):
        print("starting point chosen")
        reverse = QgsLineString(v[::-1])
        g = QgsGeometry(reverse)
        v = [v for v in g.vertices()]
    v.remove(v[-1])
    v.append(QgsPoint(g.interpolate(g.length()+len).asPoint()))
    n = QgsLineString(v)
    return QgsGeometry(n)

How can I extend the end of the line that the user clicks?

Best Answer

You could use the method extendLine()

This particular implementation is untested (I have simply modified your function), but something like the following should work for you:

def extend_line(self, feat, length, point):
    g = feat.geometry()
    v = [v for v in g.vertices()]
    if QgsGeometry.fromPointXY(QgsPointXY(v[0])).equals(QgsGeometry.fromPointXY(point)):
        print("start point chosen")
        extended_line = g.extendLine(float(length), 0.0)
    elif QgsGeometry.fromPointXY(QgsPointXY(v[-1])).equals(QgsGeometry.fromPointXY(point)):
        print("end point chosen")
        extended_line = g.extendLine(0.0, float(length))
    # extendLine() returns a QgsGeometry object
    return extended_line