def singlThruMaj(linkA, linkA_Ltype, linkB, linkB_Ltype, findLinkFromTurn, thru_offsp, thru_maj_offsp, links_df, nodes_df, shortlink_df): toNode = links_df.at[linkA, 'toNodeID_parade'] #first check: if any successor or predecessor link is an intersection #shortlink then through movement is likely signalized majMajThruNoIntrsction = True for inOut in ['predecessor', 'successor']: try: for i in nodes_df.at[toNode, inOut + 'Links'].split(): if (int(i) != linkA and int(i) != linkB and int(i) not in thru_offsp): #among the links incoming and outgoing at to-node if shortlink_df.iloc[int(i)].values[0] == True: #if any one of them is shortlink majMajThruNoIntrsction = False break except: pass #second check: if left and right successors are bidirectional and each of #them are major links and through link is also a major link if majorLinkChecker(linkA, links_df)==majorLinkChecker(linkB, links_df) \ and links_df.at[linkA, 'reverseID_parade']!=-1 \ and links_df.at[linkA, 'reverseID_parade']!=-1: for links in findLinkFromTurn[0:2]: for link in links: if majorLinkChecker(link, links_df) and \ links_df.at[link, 'reverseID_parade']!=-1: majMajThruNoIntrsction = False break single_thru_major = int(linkB) in findLinkFromTurn[3] and \ int(linkB) in thru_maj_offsp and \ linkA_Ltype == linkB_Ltype and majMajThruNoIntrsction return single_thru_major
def rightTurnBayEndCond(linkID, links_df): try: offspsrings = links_df.at[linkID, 'successors'].split() #should hv one offsp except (ValueError, AttributeError): offsp = None endNodeOK = False endNodeLtypeChk = False return offsp, endNodeOK, endNodeLtypeChk if len(offspsrings)==1: offsp = int(offspsrings[0]) thruSpouse = findThruSiblingOrSpouse(linkID, links_df, offsp, siblingOrSpouse='spouse') else: offsp = None endNodeOK = False endNodeLtypeChk = False return offsp, endNodeOK, endNodeLtypeChk if thruSpouse != None: #thru from parent thruSpouseChck = True lastSpOrien = links_df.at[linkID, 'lastOrientation(deg)'] offspOrien = links_df.at[offsp, 'firstOrientation(deg)'] if 0 < sin(radians(offspOrien - lastSpOrien)) < sin(radians(90)): rightMergeEnd = True else: rightMergeEnd = False endNodeLtypeChk = majorLinkChecker(offsp, links_df) and \ majorLinkChecker(thruSpouse, links_df) else: return offsp, False, False try: endNodeOK = rightMergeEnd and thruSpouseChck except UnboundLocalError: endNodeOK = False return offsp, endNodeOK, endNodeLtypeChk
def rightTurnBayStartCond(linkID, links_df): try: parents = links_df.at[linkID, 'predecessors'].split() #shd hv one parent except (ValueError, AttributeError): parent = None startNodeOK = False startNodeLtypeChck = False return parent, startNodeOK, startNodeLtypeChck if len(parents)==1: parent = int(parents[0]) thruSibl = findThruSiblingOrSpouse(linkID, links_df, parent) else: parent = None startNodeOK = False startNodeLtypeChck = False return parent, startNodeOK, startNodeLtypeChck if thruSibl != None: #thru from parent thruSiblingChck = True parOrien = links_df.at[parent, 'lastOrientation(deg)'] firsOrien = links_df.at[linkID, 'firstOrientation(deg)'] if 0 < sin(radians(firsOrien - parOrien)) < sin(radians(90)): rightDepartureStrt = True else: rightDepartureStrt = False startNodeLtypeChck = majorLinkChecker(parent, links_df) and \ majorLinkChecker(thruSibl, links_df) else: return parent, False, False try: startNodeOK = rightDepartureStrt and thruSiblingChck except UnboundLocalError: startNodeOK = False return parent, startNodeOK, startNodeLtypeChck
def bidirecVsDividedMajLeftTurnTypeX(linkID, links_df, nodes_df): ''' Typical example: linkID_parade 6046 and 24204 One major road is represented by overlapping lines and the other major road is represented by separate non-overlapping lines and has left turn lanes on opposite directions. ''' length = links_df.at[linkID, 'length(feet)'] <= 60 ltype = links_df.at[linkID, 'ltype'] major = majorLinkChecker(linkID, links_df) parentOrien = parentOffspringTurnBin(linkID, "predecessor", links_df) #check major thru parent with same ltype as current link if len(parentOrien[1]) == 1: thruPar = int(parentOrien[1][0]) thruMajPar = links_df.at[thruPar, 'ltype'] == ltype #check major left parent and get ltype for comparing with right sibling if len(parentOrien[2]) == 1: leftPar = int(parentOrien[2][0]) leftMajPar = majorLinkChecker(leftPar, links_df) if leftMajPar: leftParLtype = links_df.at[leftPar, 'ltype'] #check if one right sibling exists and the ltype of sibling matches with #left parent's to check major right sibling. Right sibling is also almost #on the same direction of the left parent sib = findSiblingOrSpouseLinks(linkID, links_df, nodes_df, 'sibling') rightSibling = findRightSpouseOrSibling(links_df, parentOrien, sib, SiblingOrSpouse='sibling') rightMajSib = links_df.at[rightSibling, 'ltype'].values[0] == leftParLtype #Check if major through offspring exists offsp = parentOffspringTurnBin(linkID, "successor", links_df) if len(offsp[1]) == 1: thruOffsp = int(offsp[1][0]) thruMajOffsp = links_df.at[thruOffsp, 'ltype'] == ltype #check opposite links meeting up from left and right at the end node spouse = findSiblingOrSpouseLinks(linkID, links_df, nodes_df, 'spouse') if len(spouse) >= 3: angleOrien = links_df.at[linkID, 'lastOrientation(deg)'] turns = [[], [], [], []] for sp in spouse: spAngleOrien = links_df.at[sp, 'firstOrientation(deg)'] turn = intersectionTurnType(angleOrien, (spAngleOrien + 180) % 360) turns[turn - 1].append(sp) leftTurnBaysMeet = len(turns[0]) == 1 and len(turns[1]) == 1 rightSpLtype = links_df.at[turns[0], 'ltype'].values[0] leftSpLtype = links_df.at[turns[1], 'ltype'].values[0] leftTurnBaysLtype = rightSpLtype == leftSpLtype == leftParLtype leftTurnBays = leftTurnBaysLtype and leftTurnBaysMeet return (length and major and thruMajPar and rightMajSib and thruMajOffsp and leftTurnBays)
def findDividedOrUndevidedMajNodeSpouseOffsp(linkID, links_df, nodes_df): '''find major divided or undivided spouse, offspring from the end node of the current link ''' toNode = links_df.at[linkID, 'toNodeID_parade'] offsp = nodes_df.at[toNode, 'successorLinks'].split() offspMaj = [ int(i) for i in offsp if majorLinkChecker(int(i), links_df) == True ] spouseEndNodeLinksAll = nodes_df.at[toNode, 'predecessorLinks'].split() spouseMaj = [ int(i) for i in spouseEndNodeLinksAll if majorLinkChecker(int(i), links_df) == True and int(i) != linkID ] return spouseMaj, offspMaj
def leftTurnMajLink(leftTurnTo, links_df): leftTurnLn = False if len(leftTurnTo) >= 1: for leftTurnLink in leftTurnTo: if majorLinkChecker(leftTurnLink, links_df) == True: leftTurnLn = True break return leftTurnLn
def checkComplexIntrsectionShrtlnk(linkID, links_df, nodes_df): reverseID = int(links_df.at[linkID, 'reverseID_parade']) try: restrSucc = [ int(i) for i in links_df.at[linkID, 'restrictedSuccessors'].split() ] except AttributeError: try: restrSucc = [int(links_df.at[linkID, 'restrictedSuccessors'])] except ValueError: restrSucc = [] try: restrPred = [ int(i) for i in links_df.at[linkID, 'restrictedPredecessors'].split() ] except AttributeError: try: restrPred = [int(links_df.at[linkID, 'restrictedPredecessors'])] except ValueError: restrPred = [] try: offspAll = links_df.at[linkID, 'successors'].split() offsp = [ int(i) for i in offspAll if int(i) not in restrSucc and int(i) != reverseID ] except AttributeError: offsp = [] try: parentAll = links_df.at[linkID, 'predecessors'].split() parent = [ int(i) for i in parentAll if int(i) not in restrPred and int(i) != reverseID ] except: parent = [] lengthCond = links_df.at[linkID, "length(feet)"] <= 100 majLinkCond = True if len(offsp) >= 0 and len(parent) != 0: for x in [offsp, parent, [linkID]]: for link in x: majLinkCond = majLinkCond and majorLinkChecker( int(link), links_df) else: majLinkCond = False shortlink = False typeC = len(restrPred) >= 1 and len(parent) == 1 and len(offsp) == 2 typeB = len(restrSucc) >= 1 and len(offsp) == 1 and len(parent) == 2 typeA = (len(restrPred) == len(restrSucc) == 1) and (len(offsp) == len(parent) == 1) if typeA or typeB or typeC: shortlink = majLinkCond and lengthCond return shortlink
def findMajNodeParentSiblingSpouseOffsp(linkID, links_df, nodes_df): '''find major spouse, parent, sibling, offspring from the end and start node of the current link ''' fromNode = links_df.at[linkID, 'fromNodeID_parade'] toNode = links_df.at[linkID, 'toNodeID_parade'] try: offsp = nodes_df.at[toNode, 'successorLinks'].split() offspMaj = [ int(i) for i in offsp if majorLinkChecker(int(i), links_df) == True and links_df.at[int(i), 'reverseID_parade'] == -1 ] except: offspMaj = [] try: spouseEndNodeLinksAll = nodes_df.at[toNode, 'predecessorLinks'].split() spouseMaj = [ int(i) for i in spouseEndNodeLinksAll if majorLinkChecker(int(i), links_df) == True and int(i) != linkID and links_df.at[int(i), 'reverseID_parade'] == -1 ] except: spouseMaj = [] reverseLinkID = links_df.at[int(linkID), 'reverseID_parade'] try: succLinks = links_df.at[linkID, 'successors'].split() except: succLinks = [] leftTurnTo = [ int(i) for i in succLinks if int(i) not in offspMaj and int(i) != reverseLinkID and intersectionTurnType(links_df.at[linkID, 'lastOrientation(deg)'], links_df.at[int(i), 'lastOrientation(deg)']) != 1 ] try: parentStrtNodeLinksAll = nodes_df.at[fromNode, 'predecessorLinks'].split() parentMajMin = [ int(i) for i in parentStrtNodeLinksAll if links_df.at[int(i), 'reverseID_parade'] == -1 ] parentMaj = [ i for i in parentMajMin if majorLinkChecker(i, links_df) == True ] except: parentMajMin = [] parentMaj = [] try: siblingEndNodeLinksAll = nodes_df.at[fromNode, 'successorLinks'].split() siblingMaj = [ int(i) for i in siblingEndNodeLinksAll if majorLinkChecker(int(i), links_df) == True and int(i) != linkID and links_df.at[int(i), 'reverseID_parade'] == -1 ] except: siblingMaj = [] if len(siblingMaj) == 0 and len(parentMajMin) == 1: singleParent = parentMajMin else: singleParent = [] return spouseMaj, parentMaj, offspMaj, siblingMaj, leftTurnTo, singleParent
def oppositeLink(findLinkFromTurn, links_df, shortlink_df): for link in findLinkFromTurn[2]: #u-turn link from linkA majorlinkChk = majorLinkChecker(int(link), links_df) if majorlinkChk: linkID_LType = links_df.at[int(link), 'ltype'] return upstreamLink(link, linkID_LType, links_df, shortlink_df)
def findConflictingLinks(linkA, links_df, nodes_df, shortlink_df): """ determines 1.1 the maneuver link pairs 1.2 turn type 1.3 conflicting links 1.4 ltype of the conflicting links 1.5 constant delays, if that applies for that maneuver 2. node subpath of the maneuver 3. link subpath of the maneuver Excludes these from being identified as valid maneuvers because these do not have any maneuver delay: 1. maneuver from one ramp link to the next ramp link 2. movement along curvy freeways links 3. single_thru_major 4. special case: major link to a left turn lane (detected as left turn link in previous step) Assumes, linkA to be a non-intersection-shortlink. So check for this condition before calling this function **args** -------- linkA: *int* linkID links_df: *pandas.DataFrame* Original link_wkt file converted to an DataFrame nodes_df: *pandas.DataFrame* Original node_wkt file converted to an DataFrame shortlink_df*pandas.DataFrame* Dataframe of the appended WKT file from step#1, using main_intersection_shortlink_filter() **returns** turn_pairs:*list of list* in each list element it holds the information about the maneuvers, 1.1~1.5 format: [[fromLink,toLink, turnType, fromLinkLtype,toLinkLtype, conflicting link1,conflicting link2, constant], ..., [..]] link_subpath_dict:*dict* sequence of nodes in the subpaths format: {fistNode_of_fromLink: {toLink1: [fistNode_of_fromLink, nodeP, nodeQ, ..., toNode_of_toLink1], toLink2: [fistNode_of_fromLink, nodeM, nodeN, ..., toNode_of_toLink2], ...}} node_subpath_dict:*dict* sequence of nodes in the subpaths format: {fromLink: {toLink1: [fromLink, linkP, linkQ,...,toLink], toLink2: [fromLink, linkM, linkN,...,toLink2], ...}} """ returned_tuple = linkPairBWithTurnTypeNodeLinkSeq(linkA, links_df, nodes_df, shortlink_df) pairB, findLinkFromTurn, findTurnForLink = returned_tuple[:3] node_subpath_dict, link_subpath_dict = returned_tuple[4:6] linkA_Ltype = links_df.at[int(linkA), 'ltype'] offsp = parentOffspringTurnBin(linkA, 'successor', links_df) thru_offsp = offsp[1] thru_maj_offsp = [ i for i in thru_offsp if majorLinkChecker(linkA, links_df) == True ] turn_pairs = [] for linkB in pairB: linkB_Ltype = links_df.at[int(linkB), 'ltype'] TurnBetnMinorsNotAcrossMajor = checkMinorToMinorAcrossMajor( linkA_Ltype, linkB_Ltype, linkA, linkB, links_df, nodes_df) turnBetnRamps = (linkA_Ltype == linkB_Ltype == 3) moveBetnFreeways = (linkA_Ltype == linkB_Ltype == 1) single_thru_major = singlThruMaj(linkA, linkA_Ltype, linkB, linkB_Ltype, findLinkFromTurn, thru_offsp, thru_maj_offsp, links_df, nodes_df, shortlink_df) if not (turnBetnRamps or moveBetnFreeways or single_thru_major): confLinkX, confLinkY, const = confLinkPair( linkA, linkA_Ltype, int(linkB), linkB_Ltype, findLinkFromTurn, findTurnForLink, TurnBetnMinorsNotAcrossMajor, links_df, shortlink_df) turn_pairs.append([int(linkA), int(linkB), findTurnForLink[int(linkB)], \ linkA_Ltype, linkB_Ltype, \ confLinkX, confLinkY, const]) else: del node_subpath_dict[node_subpath_dict.keys()[0]][linkB] del link_subpath_dict[link_subpath_dict.keys()[0]][linkB] return (turn_pairs, node_subpath_dict, link_subpath_dict)