I am using QGIS 2.18 and I need help finding a python script or tool which will allow me to programmatically draw a line from existing GPS (sometimes as many as 500 or more) points that is 250 feet long at a bearing listed in an azimuth attribute field for each point.

  • To create these lines as actual line features you will likely need to write your own python script. I wrote a script that you may be able to modify here gis.stackexchange.com/a/226117/56050 or at least use as a guide to get started. If I find the time I might write something for this specific situation, but QGIS documentation is down right now and I'm not that familiar with PyQGIS. – TJ Rockefeller Oct 24 '17 at 13:59

If you don't want to use expressions you may use vector field renderer for your purposes. I created a sample data set of five points with a bearing attribute...

enter image description here

...and with field calculator added an attribute length wich defines as 2500m for each feature (you may use different length values for each or use GPS speed for the length):

enter image description here

enter image description here

Then in Layer properties | Point Style I added a symbol layer of type 'vector field renderer' in wich you can define attributes for length and angle:

enter image description here

resulting in

enter image description here

| improve this answer | |
  • This works great! Thanks I would like to be able to generate these as line features eventually any suggestions. – Ed Hawkins Oct 21 '17 at 17:37
  • @EdHawkins My answer below generates line features – TJ Rockefeller Dec 21 '17 at 16:05

If you don't actually need a geometry and just need to draw the lines as described you can use QGIS's geometry builder.

If you do need the geometries, I have another answer on this same question that shows how to generate the geometries using a python script here.

enter image description here

Inside of the expression editor you would need something like this

make_line($geometry, make_point($x + 250*cos(radians("azimuth")), $y + 250*sin(radians("azimuth"))))

Breaking it down...

make_line takes two points and creates a line

$geometry the current geometry. If you have a point layer, this is the current point

make_point creates a point with a given x and y

$x the x value of the current geometry.

$y the y value of the current geometry.

250*cos(radians("azimuth")) x offset calculated from the azimuth. This assumes you are using a projected coordinate system, the distance is 250 units (Whatever the units are of your coordinate system. For most that would be meters), and the azimuth is stored in an attribute called azimuth and is stored in degrees, and the way it is written it is using a mathematical coordinate system, so 0 degrees is East increasing counter clockwise, so North is 90, West is 180 etc.

below is an example output.

enter image description here

| improve this answer | |

I was able to modify my script to create the geometries that you were looking to make. The distance should be in the units of your coordinate system. I would suggest transforming to an appropriate projected coordinate reference system that uses feet or meters.

To use this code open up the Processing toolbox, then expand Scripts, then expand Tools. Select "Create new script" and copy and paste the code below into the script window (use caution when copying and pasting python code since whitespace is syntactically significant. If you are having problems put the code into a text editor that shows whitespace and make sure that it copied correctly). Save it wherever you want and there is an execute script button at the top of the window. After you save it you can "Add script from file" and permanently have the script under "User scripts".

##output_layer=output vector

from qgis.core import QgsWKBTypes, QgsField, QgsVectorFileWriter, QgsFeature, QgsGeometry, QgsPoint
from PyQt4.QtCore import QVariant

def addLines( geometry, writer, inFeature ):
    coordinateSequence = geometry.coordinateSequence()
    for rings in coordinateSequence:
        for points in rings:
            for point in points:
                feature = QgsFeature( fields )
                azimuth = inFeature.attribute('azimuth')
                simplePoint = QgsPoint(point.x(), point.y())
                pointAtAngle = simplePoint.project(distance, azimuth)
                lineGeometry = QgsGeometry.fromPolyline([simplePoint, pointAtAngle])
                feature.setGeometry( QgsGeometry( lineGeometry ) )
                type = lineGeometry.wkbType()
                attributes = inFeature.attributes()
                feature.setAttributes( attributes )
                writer.addFeature( feature )

inlayer = processing.getObject( input_layer )
provider = inlayer.dataProvider()
fields = provider.fields()
geomType = QgsWKBTypes.Type(inlayer.wkbType())
outputGeomType = QgsWKBTypes.MultiLineString

writer = QgsVectorFileWriter( output_layer, 'UTF-8', fields,  outputGeomType , inlayer.crs() )

features = inlayer.getFeatures()
featureCount = inlayer.featureCount()
featureIndex = 0

for f in features:
    percent = ( featureIndex/float( featureCount ) ) * 100
    progress.setPercentage( percent )
    g = f.geometry().geometry()
    addLines( g, writer, f )
    featureIndex +=1

del writer
| improve this answer | |

Look into using https://plugins.qgis.org/plugins/qchainage/

Once you install the plugin you should be able to create those line.

This plugin takes line features and creates a new layer of points in provided distances on top of this Lines. Optionally you can set the startpoint (distance from the start of the line) and the endpoint (stop before reaching the end of the line) and automatically label the new points with the distances.

| improve this answer | |
  • Great tool but as I understand this tool it places points along a line, I need to draw a line beginning at the gps point that is 250 feet long and in a direction listed in the azimuth field of the gps point. Basically a line 250 feet long starting at the point and drawn at a 75 degree angle. – Ed Hawkins Oct 18 '17 at 21:40

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.