2

enter image description here

I have layer of points of which I need to build lines. Points to path function doesn't suit me. I have data on time, but it does not reflect the order of connection that I need. I need to connect them by angle. That is, If the azimuth between two points is 30 degrees different from the azimuth of the first two points, then this point is the point I want, and it's connected . Is it possible?

     import math
     bestangle=pi/3
     #Functions defining points
    class Point:
    def __init__(self,x=0,y=0):
    self.x=x
    self.y=y
    def getx(self):
    return self.x
    def gety(self):
    return self.y 
    layer = iface.activeLayer()
    # creating an empty line layer for output connections
    line_layer = QgsVectorLayer("LineString?crs= 
    {}&index=yes".format(layer.crs().authid()), "Connected Points", 
    "memory")
    provider = line_layer.dataProvider()
    # adding new fields
    provider.addAttributes([QgsField("id", QVariant.Int),
            QgsField("from", QVariant.String),
            QgsField("to", QVariant.String),
            QgsField("length", QVariant.Double)])
    line_layer.updateFields()

    # converting point features into a list
    import numpy as np
    points_list = [QgsPointXY(feat.geometry().asPoint()) for feat in 
      layer.getFeatures()]
   a=np.array(points_list)
  
    p1=Point(15095691,4110672)
    # unction that connects points
   def shortest_line_recursion(points_as_list, i):
    if len(points_as_list) <= 1:
    return None
   else:
     # all possible point connections
    for i in range(len(points_as_list)):
     x1=a[0,0]
    x2=a[i,0]
    y1=a[0,1]
    y2=a[i,1]
    angle_list[i]=calc_angle(x1,y1,x2,y2)-bestangle
    # Closest angle
    min_angle= min(angle_line, key=lambda x: x.length())

    # changing the order in the previous list, thus the used starting 
    point will be deleted
       # and the ending point will become the new starting
    min_angle_points = list(shortest_line.vertices())

    point_from = shortest_line_points[0]
    point_to = shortest_line_points[-1]
  
    points_as_list.pop(points_as_list.index(point_from))
    points_as_list.insert(0, 
     points_as_list.pop(points_as_list.index(point_to)))

     #providing new geometry for a new line feature
    f = QgsFeature()
    f.setGeometry(min_angle)

     #providing values for new attributes
    f.setAttributes([i,
            list(points_dict.keys()) 
    [list(points_dict.values()).index(point_from)],\
            list(points_dict.keys()) 
    [list(points_dict.values()).index(point_to)],\
            round(min_angle.length(),4)])
    provider.addFeature(f)

    #running the same function again, i.e. recursion
    shortest_line_recursion(points_as_list, i + 1)

    # adding a new feature to the map
   QgsProject.instance().addMapLayer(line_layer)
  
    # running the function
    shortest_line_recursion(points_list, 1)

    #Angle calculation
     def calc_angle(x1,y1,x2,y2): 
    angle=0
     dy= y2-y1
    dx= x2-x1
    if dx==0 and dy>0:
    angle = 0
    if dx==0 and dy<0:
     angle = 180
    if dy==0 and dx>0:
     angle = 90
     if dy==0 and dx<0:
    angle = 270
    if dx>0 and dy>0:
     angle = math.atan(dx/dy)*180/math.pi
    elif dx<0 and dy>0:
     angle = 360 + math.atan(dx/dy)*180/math.pi
    elif dx<0 and dy<0: 
    angle = 180 + math.atan(dx/dy)*180/math.pi
       elif dx>0 and dy<0:
     angle = 180 + math.atan(dx/dy)*180/math.pi
      return angle
  • 1
    Welcome to Stack Exchange, an international Q&A site. Sorry, but the policy is to use English as the main language for communication. Since the original revision is already in English, consider rolling it back or editing it back to the English version. Thanks for your understanding. – Andrew T. Jul 26 at 10:14
  • 1
    Could you post a picture of the pint layer – neogeomat Jul 26 at 16:59
  • Can you edit your question and format your code correctly please. – user2856 Aug 1 at 3:03

Your Answer

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

Browse other questions tagged or ask your own question.