4

I have written a python script which should calculate the azimuth for a line (with two given points). But every time I run the script, I am getting the following error message: enter image description here

If I click OK, QGIS closes down. I tried to debug my script with print Messages and I have figured out where it stops, but I cannot explain why and how I can solve this problem:

# name :  CalculatesNorthboundAzimuth_script
# date   : 29.12.2017
# description: calculates northbound-azimuth for lines of input line-layer

from qgis.core import *
from PyQt4.QtCore import *
from math import degrees

#***********Constants*************#
AZIMUTH = 'azimuth'

NODEID = 'nodeID'
COORD_X = 'x'
COORD_Y = 'y'

EDGEID = 'id'
FROM_NODE = 'from'
TO_NODE  = 'to'
PRIORITY = 'priority'
LENGTH = 'length'
TIME = 'time'
#*******************************#

# input parameters 
##Nodes=vector
##Graph=vector

inputNodes = processing.getObject(Nodes)
inputGraph = processing.getObject(Graph)
crs = inputNodes.crs().toWkt()

# Create the output layer
# Specify the geometry type
outLayer = QgsVectorLayer('Linestring?crs='+ crs, 'graph_with_azimuth' , 
        'memory')

# Set the provider to accept the data source
outdp = outLayer.dataProvider()

# define attributes and add them to the vector layer
outdp.addAttributes([QgsField(EDGEID, QVariant.String),
                        QgsField(FROM_NODE, QVariant.String),
                        QgsField(TO_NODE, QVariant.String),
                        QgsField(PRIORITY, QVariant.Int),
                        QgsField(LENGTH, QVariant.Double),
                        QgsField(TIME, QVariant.Double),
                        QgsField(AZIMUTH, QVariant.Double)])
outLayer.updateFields()

#**define field indexes**#
idx_id = inputNodes.fieldNameIndex(NODEID)
idx_x = inputNodes.fieldNameIndex(COORD_X)
idx_y = inputNodes.fieldNameIndex(COORD_Y)

idx_edgeid = inputGraph.fieldNameIndex(EDGEID)
idx_from = inputGraph.fieldNameIndex(FROM_NODE)
idx_to = inputGraph.fieldNameIndex(TO_NODE)
idx_priority = inputGraph.fieldNameIndex(PRIORITY)
idx_length = inputGraph.fieldNameIndex(LENGTH)
idx_time = inputGraph.fieldNameIndex(TIME)
idx_azimuth = inputGraph.fieldNameIndex(AZIMUTH)

feats = processing.features(inputGraph)
n = len(feats)
# loop through graph layer and find node coordinates for from/to nodes
for i, feat1 in enumerate(feats):
   progress.setPercentage(int(100 * i / n))

   fromNode = feat1.attributes()[idx_from]
   toNode = feat1.attributes()[idx_to]

   # search for specific from_node by nodeID
   exp = QgsExpression('nodeID ILIKE \'' + fromNode +'\' ')
   request = QgsFeatureRequest(exp)
   request.setLimit(1)

   for feat2 in inputNodes.getFeatures(request):
       geomFrom = feat2.geometry()

       # search for specific to_node by nodeID
       exp = QgsExpression('nodeID ILIKE \'' + toNode +'\' ')
       request = QgsFeatureRequest(exp)
       request.setLimit(1)

   for feat2 in inputNodes.getFeatures(request):
       geomTo = feat2.geometry()

# calculate azimuth for given edge and store result in attribut "azimuth"
newLine = QgsFeature(outLayer.pendingFields())
newLine.setAttribute(EDGEID, feat1.attributes()[idx_edgeid])
newLine.setAttribute(FROM_NODE, feat1.attributes()[idx_from])
newLine.setAttribute(TO_NODE, feat1.attributes()[idx_to])
newLine.setAttribute(PRIORITY, feat1.attributes()[idx_priority])
newLine.setAttribute(LENGTH, feat1.attributes()[idx_length])
newLine.setAttribute(TIME, feat1.attributes()[idx_time])
newLine.setAttribute(AZIMUTH, geomFrom.asPoint().azimuth(geomTo.asPoint()))

newLine.setGeometry(QgsGeometry.fromPolyline([geomFrom.asPoint(),
                                                  geomTo.asPoint()]))

#add the feature to the layer
(res, outFeats) = outdp.addFeatures([newLine])

# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)
print "Done .. "

I am quite sure that the following line is causing the problem:

newLine.setAttribute(AZIMUTH, geomFrom.asPoint().azimuth(geomTo.asPoint()))

In this line, I am calculating the azimuth angle with two given points. As you can see in the code above, I am receiving those two points from the "inputNodes"-layer.

For your better understanding, the python script loops through the objects of the inputGraph layer (which consists of lines). For each line will the azimuth be calculated, but for this, I need the start- and end-node of the line which is stored in the nodes layer (point-layer). For each line, I am searching the node-layer for start- and end-node by nodeID and store their geometry (geomFrom, geomTo). Both variables are needed for the azimuth calculation.

Any suggestions on what causes the error and how to fix it?

  • 1
    if put a=geomFrom.asPoint().azimuth(geomTo.asPoint())and after newLine.setAttribute(AZIMUTH, a),have a minidump ? – Fran Raga Jan 5 '18 at 9:56
  • And you can explore this minidump file using for example WinDbg for show the trace. – Fran Raga Jan 5 '18 at 10:00
  • Duplicated gis.stackexchange.com/questions/267023/… – Fran Raga Jan 8 '18 at 9:31
  • Could you provide a test shapefile so that people could try out the script? – Joseph Jan 26 '18 at 11:02

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.