11

I have a point vector layer with "angle" field. How can I create line segments at these points with certain length and angle?

I did this with style options but I need this physically as lines vector layer:

enter image description here

Taras
  • 32,823
  • 4
  • 66
  • 137
Karol Daniluk
  • 313
  • 2
  • 6

2 Answers2

14

One possible tool is "Geometry by expression" in the Processing Toolbox > Vector geometry (search in the Processing Toolbox Ctrl+Alt+T).

enter image description here

A Geometry expression to create lines (length= 100 m) is as below:

make_line(project($geometry, 50, radians("angle")), project($geometry, 50, radians("angle"+180)))
  • project($geometry, 50, radians("angle")) part creates a new point by moving your points to "angle" direction by 50 meters.
  • project($geometry, 50, radians("angle"+180)) creates another point to the oposite direction.
  • make_line() ties the above two points, so the total line length is 100 meters.
  • project() function assumes that your "angle" is measured clockwise from north, so this expression may require edits depending on how your "angle" field is made.

enter image description here

NB. Do not forget saving created Modified geometry layer as a new dataset, otherwise it will be lost when you finish QGIS session.

Taras
  • 32,823
  • 4
  • 66
  • 137
Kazuhito
  • 30,746
  • 5
  • 69
  • 149
7

I put an example of solving the same task with a PyQGIS (3.2) standalone application.

Below is the Python code:

import sys
import math
from qgis.core import (QgsPointXY,
                       QgsApplication,
                       QgsVectorLayer,
                       QgsFeature,
                       QgsGeometry)
from PyQt5.QtWidgets import QApplication

def main(): print('Start program')

qgis_prefix_path = 'C:\\OSGeo4W64\\apps\\qgis'
app = QApplication(sys.argv)
QgsApplication.setPrefixPath(qgis_prefix_path, True)

QgsApplication.initQgis()

point_path = 'd:/Users/Bogomolov/Qgis/Test_prj/point.shp'
line_path = 'd:/Users/Bogomolov/Qgis/Test_prj/lines.shp'
point_layer = QgsVectorLayer(point_path, "pointlayer", "ogr")
layer = QgsVectorLayer(line_path, "linelayer", "ogr")


for feature in point_layer.getFeatures():
    geom: QgsGeometry = feature.geometry()
    pnt: QgsPointXY = geom.asPoint()
    length = feature['distance']
    bearing = feature['bearing']
    id = feature['id']
    print('id=', id)
    pnt0 = direct_geodetic_task(pnt, length / 2, bearing + 180)
    pnt1 = direct_geodetic_task(pnt, length / 2, bearing)
    points = []
    points.append(pnt0)
    points.append(pnt1)
    fields = layer.dataProvider().fields()
    feature = QgsFeature()
    feature.setGeometry(QgsGeometry.fromPolylineXY(points))
    feature.setFields(fields)
    feature.setAttribute('id', id)
    layer.dataProvider().addFeature(feature)

# layer.commitChanges()

QgsApplication.exitQgis()

def direct_geodetic_task(pnt, dist, bear): if bear > 360.0: bear = bear - 360 if bear < 0: bear = 360 + bear

deg = bear * math.pi / 180

dx = dist * math.sin(deg)
dy = dist * math.cos(deg)
x = pnt.x() + dx
y = pnt.y() + dy

return QgsPointXY(x, y)

if name == 'main': main()

The result is the same: enter image description here

Taras
  • 32,823
  • 4
  • 66
  • 137
Vadym
  • 811
  • 5
  • 8