While digitizing a line with multiple segment, how to create a particular segment parallel to (or) Perpendicular to another feature using pyQgis?
1 Answer
It is a problem of analytical geometry and you can use vector algebra or the direction cosines, for example.
- for perpendicular lines, a solution is given in How to draw perpendicular lines in QGIS?
for parallel lines, you can use the solution of Draw a parallel line (normalized offset)
def pair(list): '''Iterate over pairs in a list -> iterate over pairs of segments of a line ''' for i in range(1, len(list)): yield list[i-1], list[i] import math # original line layer = qgis.utils.iface.activeLayer() # iterate over segments of the line for elem in layer.getFeatures(): line = elem.geometry().asPolyline() for seg_start, seg_end in pair(line): x1,y1 = QgsPoint(seg_start) x2,y2 = QgsPoint(seg_end) length = math.sqrt(line_start.sqrDist(line_end)) x1p = x1 + 1500 * ((y2-y1) / length) x2p = x2 + 1500 * ((y2-y1) / length) y1p = y1 + 1500 * ((x1-x2) / length) y2p = y2 + 1500 * ((x1-x2) / length) result= QgsGeometry.fromPolyline([ QgsPoint(x1p,y1p),QgsPoint(x2p,y2p)])
Result (original polyline in red, and if you preserve the original length of the segments, the resulting parallel segments, in green, intersects )
you can also use the direction cosines of the segments, starting from an original point: if the lines are parallels, they have the same orientation/direction (
azimuth
in PyQGIS):def cosdir(azim): az = math.radians(azim) cosa = math.sin(az) cosb = math.cos(az) return cosa,cosb # original point point = QgsPoint(147352.43, 94305.21) for elem in layer.getFeatures(): line = elem.geometry().asPolyline() for seg_start, seg_end in pair(line): line_start = QgsPoint(seg_start) line_end = QgsPoint(seg_end) length = math.sqrt(line_start.sqrDist(line_end)) # direction cosines from the azimuth cosa, cosb = cosdir(line_start.azimuth(line_end)) # generate the points in the same direction resulting_point = QgsPoint(point.x()+(length*cosa), point.y()+(length*cosb)) result= QgsGeometry.fromPolyline([point,resulting_point]) point = resulting_point