Tôi đề xuất một cách tiếp cận chỉ lặp lại với một trình tạo hình học và một hàm tùy chỉnh.
Trước khi bắt đầu, tôi muốn nhấn mạnh rằng tôi sẽ tập trung chú ý vào phần giải thích những điều tối thiểu cần làm để tái tạo kết quả mong muốn: điều này có nghĩa là một số thông số nhỏ khác (như kích thước, chiều rộng, v.v.) nên được điều chỉnh dễ dàng bởi bạn để phù hợp hơn với nhu cầu của bạn.
Do đó, giải pháp này hoạt động cho cả Hệ thống tham chiếu địa lý và dự kiến: sau đây, tôi giả sử sử dụng CRS dự kiến (nghĩa là đơn vị đo là mét), nhưng bạn có thể thay đổi chúng theo CRS của mình.
Bối cảnh
Giả sử bắt đầu từ lớp vectơ linestring này đại diện cho các dây (nhãn đại diện cho số lượng dây chồng chéo (trùng khớp):

Giải pháp
Đầu tiên, đi đến Layer Properties | Stylevà sau đó chọn Single symboltrình kết xuất.
Từ Symbol selectorhộp thoại, chọn Geometry generatorkiểu lớp biểu tượng và Linestring / MultiLinestringkiểu hình học. Sau đó, nhấp vào Function Editortab:

Sau đó, bấm vào New filevà gõ draw_wiresnhư tên của chức năng mới:

Bạn sẽ thấy rằng một chức năng mới đã được tạo và nó được liệt kê ở phía bên trái của hộp thoại. Bây giờ, nhấp vào tên của hàm và thay thế mặc định @qgsfunctionbằng mã sau đây (đừng quên thêm tất cả các thư viện được đính kèm tại đây):
from qgis.core import *
from qgis.gui import *
from math import sin, cos, radians
@qgsfunction(args='auto', group='Custom')
def draw_wires(angle, percentage, curr_feat, layer_name, feature, parent):
    def wires(polyline, new_angle, percentage):
        for x in range(0, len(polyline)-1):
            vertices = []
            first_point = polyline[x]
            second_point = polyline[x +1]
            seg = QgsGeometry.fromPolyline([first_point, second_point])
            len_feat = seg.length()
            frac_len = percentage * len_feat
            limb = frac_len/cos(radians(new_angle))
            tmp_azim = first_point.azimuth(second_point)
            angle_1 = radians(90 - (tmp_azim+new_angle))
            dist_x, dist_y = (limb * cos(angle_1), limb * sin(angle_1))
            point_1 = QgsPoint(first_point[0] + dist_x, first_point[1] + dist_y)
            angle_2 = radians(90 - (tmp_azim-new_angle))
            dist_x, dist_y = (limb * cos(angle_2), limb * sin(angle_2))
            point_2 = QgsPoint(second_point[0] - dist_x, second_point[1] - dist_y)
            tmp_azim = second_point.azimuth(first_point)
            angle_3 = radians(90 - (tmp_azim+new_angle))
            dist_x, dist_y = (limb * cos(angle_3), limb * sin(angle_3))
            point_3 = QgsPoint(second_point[0] + dist_x, second_point[1] + dist_y)
            angle_4 = radians(90 - (tmp_azim-new_angle))
            dist_x, dist_y = (limb * cos(angle_4), limb * sin(angle_4))
            point_4 = QgsPoint(first_point[0] - dist_x, first_point[1] - dist_y)
            vertices.extend([first_point, point_1, point_2, second_point, point_3, point_4, first_point])
            tempGeom = QgsGeometry.fromPolyline(vertices)
            num.append(tempGeom)
        return num
    layer = QgsMapLayerRegistry.instance().mapLayersByName(layer_name)[0]
    all_feats = {}
    index = QgsSpatialIndex()
    for ft in layer.getFeatures():
        index.insertFeature(ft)
        all_feats[ft.id()] = ft
    first = True
    tmp_geom = curr_feat.geometry()
    polyline = tmp_geom.asPolyline()
    idsList = index.intersects(tmp_geom.boundingBox())
    occurrences = 0
    for id in idsList:
        test_feat = all_feats[id]
        test_geom = test_feat.geometry()
        if tmp_geom.equals(test_geom):
            occurrences += 1
    if occurrences & 0x1:
        num = [tmp_geom]
    else:
        num = []
    rapp = occurrences/2
    i=2
    new_angle = angle
    while i <= occurrences:
        draw=wires(polyline, new_angle, percentage)
        i += 2
        new_angle -= new_angle/rapp
    first = True
    for h in num:
        if first:
            geom = QgsGeometry(h)
            first = False
        else:
            geom = geom.combine(h)
    return geom
Một khi bạn đã làm điều này, bấm vào Loadnút và bạn sẽ có thể thấy chức năng từ CustomMenu của Expressionhộp thoại.
Bây giờ, nhập biểu thức này (xem hình ảnh dưới đây để tham khảo):
draw_wires(40, 0.3, $currentfeature, @layer_name)

Bạn vừa chạy một chức năng đang nói, theo một cách tưởng tượng:
  "Đối với lớp hiện tại ( @layer_name ) và tính năng hiện tại ( $ currentfeature ), hiển thị các dây với nhau bằng cách mở tối đa ban đầu 40 độ và thay đổi hướng ở khoảng cách 0,3 lần chiều dài của đoạn hiện tại."
Điều duy nhất bạn cần thay đổi là giá trị của hai tham số đầu tiên mà bạn muốn, nhưng rõ ràng là theo cách hợp lý (để lại các tham số chức năng khác như được cung cấp).
Cuối cùng, bấm vào Applynút để áp dụng các thay đổi.
Bạn sẽ thấy một cái gì đó như thế này:

như mong đợi.
BIÊN TẬP
Theo một yêu cầu cụ thể được OP đưa ra trong một bình luận:
  "Có thể chỉ tạo mẫu này giữa đầu và cuối của mỗi đa tuyến thay vì giữa mỗi đỉnh không?"
Tôi hơi chỉnh sửa mã. Hàm sau sẽ trả về kết quả mong đợi:
from qgis.core import *
from qgis.gui import *
from math import sin, cos, radians
@qgsfunction(args='auto', group='Custom')
def draw_wires(angle, percentage, curr_feat, layer_name, feature, parent):
    def wires(polyline, new_angle, percentage):
        vertices = []
        len_feat = polyline.length()
        frac_len = percentage * len_feat
        limb = frac_len/cos(radians(new_angle))
        tmp_azim = first_point.azimuth(second_point)
        angle_1 = radians(90 - (tmp_azim+new_angle))
        dist_x, dist_y = (limb * cos(angle_1), limb * sin(angle_1))
        point_1 = QgsPoint(first_point[0] + dist_x, first_point[1] + dist_y)
        angle_2 = radians(90 - (tmp_azim-new_angle))
        dist_x, dist_y = (limb * cos(angle_2), limb * sin(angle_2))
        point_2 = QgsPoint(second_point[0] - dist_x, second_point[1] - dist_y)
        tmp_azim = second_point.azimuth(first_point)
        angle_3 = radians(90 - (tmp_azim+new_angle))
        dist_x, dist_y = (limb * cos(angle_3), limb * sin(angle_3))
        point_3 = QgsPoint(second_point[0] + dist_x, second_point[1] + dist_y)
        angle_4 = radians(90 - (tmp_azim-new_angle))
        dist_x, dist_y = (limb * cos(angle_4), limb * sin(angle_4))
        point_4 = QgsPoint(first_point[0] - dist_x, first_point[1] - dist_y)
        vertices.extend([first_point, point_1, point_2, second_point, point_3, point_4, first_point])
        tempGeom = QgsGeometry.fromPolyline(vertices)
        num.append(tempGeom)
    layer = QgsMapLayerRegistry.instance().mapLayersByName(layer_name)[0]
    all_feats = {}
    index = QgsSpatialIndex()
    for ft in layer.getFeatures():
        index.insertFeature(ft)
        all_feats[ft.id()] = ft
    first = True
    tmp_geom = curr_feat.geometry()
    coords = tmp_geom.asMultiPolyline()
    if coords:
        new_coords = [QgsPoint(x, y) for x, y in z for z in coords]
    else:
        coords = tmp_geom.asPolyline()
        new_coords = [QgsPoint(x, y) for x, y in coords]
    first_point = new_coords[0]
    second_point = new_coords[-1]
    polyline=QgsGeometry.fromPolyline([first_point, second_point])
    idsList = index.intersects(tmp_geom.boundingBox())
    occurrences = 0
    for id in idsList:
        test_feat = all_feats[id]
        test_geom = test_feat.geometry()
        if tmp_geom.equals(test_geom):
            occurrences += 1
    if occurrences & 0x1:
        num = [polyline]
    else:
        num = []
    rapp = occurrences/2
    i=2
    new_angle = angle
    while i <= occurrences:
        draw=wires(polyline, new_angle, percentage)
        i += 2
        new_angle -= new_angle/rapp
    first = True
    for h in num:
        if first:
            geom = QgsGeometry(h)
            first = False
        else:
            geom = geom.combine(h)
    return geom