# name :  MergeEdges_script
# author: Theresa Lichtenberger
# date   : 22.10.2018
# description: merges edges with the same edgeid
#           and adds two attributes for speed limits on each lane 

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

#***********Constants*************#
EDGEID = 'edgeid'
FROM = 'from'
TO = 'to'
PRIORITY = 'priority'
LENGTH = 'length'
TIME = 'time'

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

ID = 'id'
VTO = 'vto'
VFROM = 'vfrom'
NODE1 = 'node1'
NODE2 = 'node2'
#*******************************#

# input parameters 
##Edges=vector
##Nodes=vector

inLayerEdges = processing.getObject(Edges)
inNodes = processing.getObject(Nodes)

crs = inLayerEdges.crs().toWkt()

# get field indices for inputlayer
idxEdgeId = inLayerEdges.fieldNameIndex(ID)
idxPriority = inLayerEdges.fieldNameIndex(PRIORITY)
idxLength  = inLayerEdges.fieldNameIndex(LENGTH)
idxTime    = inLayerEdges.fieldNameIndex(TIME)
idxFrom  = inLayerEdges.fieldNameIndex(FROM)
idxTo  = inLayerEdges.fieldNameIndex(TO)

idx_id = inNodes.fieldNameIndex(NODEID)
idx_x = inNodes.fieldNameIndex(COORD_X)
idx_y = inNodes.fieldNameIndex(COORD_Y)

# Create output layer and specify geometry type
outLayer = QgsVectorLayer('Linestring?crs=' + crs, 'merged_edges', '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(NODE1, QVariant.String),
                            QgsField(NODE2, QVariant.String),
                            QgsField(PRIORITY, QVariant.Int),
                            QgsField(VTO, QVariant.Double),
                            QgsField(VFROM, QVariant.Double)])
outLayer.updateFields()

# get field indices for outputlayer
outEdgeId = outdp.fieldNameIndex(EDGEID)
outNode1 = outdp.fieldNameIndex(NODE1)
outNode2 = outdp.fieldNameIndex(NODE2)
outPriority = outdp.fieldNameIndex(PRIORITY)
outVTo = outdp.fieldNameIndex(VTO)
outVFrom = outdp.fieldNameIndex(VFROM)

listOfEdgeIds = []
count = 0
flag = 0

# loop through edges of inLayerEdges and merge 
for feat in inLayerEdges.getFeatures():
    
    # create new edge (line) for outputLayer
    newEdge = QgsFeature(outLayer.pendingFields())
    
    currentPriority = feat.attributes()[idxPriority]
    currentEdgeId = feat.attributes()[idxEdgeId]
    
    if currentEdgeId.find('From') == -1:
        edgeIdTrimmed = currentEdgeId.replace('To', '')
    else:
        edgeIdTrimmed = currentEdgeId.replace('From', '')

    if edgeIdTrimmed in listOfEdgeIds:
        # if current edge id already processed -> skip it.
        #print "current edgeid already in list. Continue ..."
        continue
    
    else:      
        # if not, find all entries in the graph which share the same current edge id
        # and merge them
        listOfEdgeIds.append(edgeIdTrimmed)
        
        newEdge.setAttribute(EDGEID, edgeIdTrimmed)
        newEdge.setAttribute(PRIORITY, currentPriority)
        
        node1 = feat.attributes()[idxFrom]
        node2 = feat.attributes()[idxTo]
        newEdge.setAttribute(NODE1, node1)
        newEdge.setAttribute(NODE2, node2)

        # search for specific from_node by nodeID
        exp = QgsExpression('nodeID ILIKE \'' + node1 +'\' ')
        request = QgsFeatureRequest(exp)
        request.setLimit(1)
    
        for feat2 in inNodes.getFeatures(request):
            geomFrom = feat2.geometry()
            print geomFrom
        
        # search for specific to_node by nodeID
        exp = QgsExpression('nodeID ILIKE \'' + node2 +'\' ')
        request = QgsFeatureRequest(exp)
        request.setLimit(1)
    
        for feat2 in inNodes.getFeatures(request):
            geomTo = feat2.geometry()
            print geomTo

        # find all entries in the graph with current edge id
        exp = QgsExpression('id ILIKE \'' + edgeIdTrimmed + '%\' ')
        request = QgsFeatureRequest(exp)

        # loop through all egdes with the same current edgeids
        for feat1 in inLayerEdges.getFeatures(request):
            
            tempEdgeId = feat1.attributes()[idxEdgeId]
            
            length = feat1.attributes()[idxLength]
            time    = feat1.attributes()[idxTime]
            velocity = (length / time) * 3.6
        
            if tempEdgeId.find("From") is not -1:
                #print("Python found the string From!")
                newEdge.setAttribute(VFROM, velocity)
            elif tempEdgeId.find("To") is not -1:
                #print("Python found the string To!")
                newEdge.setAttribute(VTO, velocity)
            else:
                print("Python did NOT find the substring!")

        
        print "heyho"
        newEdge.setGeometry(QgsGeometry.fromPolyline([geomFrom.asPoint(),geomTo.asPoint()]))
        # add the feature to the layer
        (res, outFeats) = outdp.addFeatures([newEdge])
        
    
# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)
print "Done ... "
    
    



