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.– TJRCommented Oct 24, 2017 at 13:59
4 Answers
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.
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.
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".
##input_layer=vector
##distance=number
##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 )
return
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
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...
...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):
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:
resulting in
-
This works great! Thanks I would like to be able to generate these as line features eventually any suggestions. Commented Oct 21, 2017 at 17:37
-
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.
-
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. Commented Oct 18, 2017 at 21:40