I wrote this code with the same proposal some time ago, maybe it can be useful for you, but you will need to fix some geometry parts manually because the code works from connecting nearest points with Pythagorean theorem.
First load the points layer to the project, then paste this code as a new pythonPython script in the QGIS python console and remember to set the layer name (not the path) in the code. If you want the line to start at a particular point you can select it.
import qgis.core
import math
layer_name = '' # put inside the quotes the layer name (not the layer path)
close_line = True # true if you want to close the line
project = QgsProject().instance()
layer = project.mapLayersByName(layer_name)[0]
connected_points = []
def nearest_p(p1_id):
p_distances = []
p1_geometry_as_point = layer.getFeature(p1_id).geometry().asPoint()
for feature in layer.getFeatures():
if feature.id() != p1_id and not feature.id() in connected_points:
p2_geometry_as_point = feature.geometry().asPoint()
x_dif = p1_geometry_as_point.x() - p2_geometry_as_point.x()
y_dif = p1_geometry_as_point.y() - p2_geometry_as_point.y()
distance = math.sqrt(x_dif ** 2 + y_dif ** 2)
p_distances.append([distance, feature.id()])
p_distances.sort(key=lambda a : a[0])
return p_distances[0][1]
if layer.selectedFeatureCount() > 0:
init_ids = layer.selectedFeatureIds()[0]
else:
init_ids = 1
connected_points.append(init_ids)
for i in range(1, layer.featureCount()):
init_ids = nearest_p(init_ids)
connected_points.append(init_ids)
XY_line = [layer.getFeature(feature_id).geometry().asPoint() for feature_id in connected_points]
if close_line:
XY_line.append(XY_line[0])
line_crs = layer.crs().authid().lower()
line = QgsVectorLayer('LineString?crs=' + line_crs, 'Line', 'memory')
line.startEditing()
feature = QgsFeature(0)
feature.setGeometry(QgsGeometry.fromPolylineXY(XY_line))
line.addFeature(feature)
line.endEditCommand()
line.commitChanges()
project.addMapLayer(line)