tvaLib
Public Member Functions | Public Attributes | List of all members
lib.scene.Alignments Class Reference

Declare alignment object type. More...

Inheritance diagram for lib.scene.Alignments:

Public Member Functions

def __init__ (self, input, sidewalks=[], bikepaths=[], dimension=3, corridorMinProximity=5.0, corridorMinContinuousDistance=20.0, connectorSearchDistance=2.5, intersectionDistanceFactor=1.5, localString='Alignment')
 
def setup (self, kwargs)
 
def addItem (self, data, a_type=0)
 
def addAlignBB (self, boundingboxes)
 
def getAlignIndexByName (self, name)
 
def getLinks (self)
 
def getRestrictedAlignmentsByClassification (self, userType)
 
def getOrdinaryAlignIndeces (self)
 
def genOrdinaryAlignIndeces (self)
 
def genOpposingDirections (self, matching=0.90, angleThreshold=120.0)
 
def getOpposingDirections (self)
 
def genLinks (self, connectorSearchDistance=None, intersectionDistanceFactor=None, allowOpposingDirections=False)
 
def getCorridors (self)
 
def genCorridors (self, minProximity=None, minContinuousDistance=None, allowOpposingDirections=False)
 
def genRouteTree (self)
 
def getRouteTree (self)
 
def getRouteDistHorizonByPos (self, ax, ay, bx, by, distHorizonA, distHorizonB)
 
def getRouteDistHorizonByPreCalc (self, laneA, S_A, laneB, S_B, distHorizonA, distHorizonB)
 

Public Attributes

 ranBB
 
 corridorMinContinuousDistance
 
 corridorMinProximity
 
 connectorSearchDistance
 
 intersectionDistanceFactor
 
 SDR
 
 localString
 
 sidewalks
 
 bikepaths
 
 ordinaryAlignments
 
 opposingDirections
 
 links
 
 corridors
 
 route
 

Detailed Description

Declare alignment object type.

Definition at line 888 of file scene.py.

Constructor & Destructor Documentation

◆ __init__()

def lib.scene.Alignments.__init__ (   self,
  input,
  sidewalks = [],
  bikepaths = [],
  dimension = 3,
  corridorMinProximity = 5.0,
  corridorMinContinuousDistance = 20.0,
  connectorSearchDistance = 2.5,
  intersectionDistanceFactor = 1.5,
  localString = 'Alignment' 
)

Definition at line 889 of file scene.py.

889  def __init__(self, input, sidewalks=[], bikepaths=[], dimension=3, corridorMinProximity=5.0, corridorMinContinuousDistance=20.0, connectorSearchDistance=2.5, intersectionDistanceFactor=1.5, localString='Alignment'):
890  tvaLib.Constructors.SuperListParse.__init__(self, input, dimension=dimension, datatype='point')
891  self.ranBB = False
892  self.corridorMinContinuousDistance = corridorMinContinuousDistance
893  self.corridorMinProximity = corridorMinProximity
894  self.connectorSearchDistance = connectorSearchDistance
895  self.intersectionDistanceFactor = intersectionDistanceFactor
896  self.SDR = SDR(self.data)
897  self.localString = localString
898  self.sidewalks = tvaLib.Constructors.SuperListParse(sidewalks, dimension=1, datatype='int')
899  self.bikepaths = tvaLib.Constructors.SuperListParse(bikepaths, dimension=1, datatype='int')
900  #Set types in children
901  for aIx in self.sidewalks: self.data[int(aIx)].type=1
902  for aIx in self.bikepaths: self.data[int(aIx)].type=2
903  return
904 

Member Function Documentation

◆ addAlignBB()

def lib.scene.Alignments.addAlignBB (   self,
  boundingboxes 
)

Definition at line 916 of file scene.py.

916  def addAlignBB(self, boundingboxes):
917  for align in range(len(self)):
918  self[align].pos_bb = deepcopy(self[align].pos)
919  removalList = []
920  appendList = []
921  plists = [range(len(self[align])),range(len(self[align]))]
922  plists[1].reverse()
923  for plist in plists:
924  lastPoint = None
925  for point in plist:
926  #Check if point has entered bounding boxes
927  for bb in range(len(boundingboxes)):
928  if(tvaLib.Geo.pip(self[align].pos_bb[point][0],self[align].pos_bb[point][1],boundingboxes[bb])):
929  #Attempt to generate a midpoint
930  if(lastPoint):
931  polyInter = tvaLib.Geo.polyInter(lastPoint,self[align].pos_bb[point],boundingboxes[bb])
932  if(polyInter): appendList.append(polyInter[0])
933  else: appendList.append(None)
934  else: appendList.append(None)
935  break
936  else:
937  removalList.append(point)
938  lastPoint = self[align][point]
939  continue
940  break
941 
942  self[align].pos_bb = tvaFilter.dropObjects(self[align].pos_bb, removalList)
943  if(appendList):
944  if(appendList[0]):
945  self[align].pos_bb.reverse()
946  self[align].pos_bb.append(appendList[0])
947  self[align].pos_bb.reverse()
948  if(appendList[1]): self[align].pos_bb.append(appendList[1])
949 
950  self.ranBB = True
951  return True
952 

◆ addItem()

def lib.scene.Alignments.addItem (   self,
  data,
  a_type = 0 
)

Definition at line 911 of file scene.py.

911  def addItem(self, data, a_type=0):
912  self.data.append(Alignment(data, a_type=a_type, id=len(self.data), localString='Alignment'))
913  return True
914 

◆ genCorridors()

def lib.scene.Alignments.genCorridors (   self,
  minProximity = None,
  minContinuousDistance = None,
  allowOpposingDirections = False 
)
Generate list of corridors containing the alignment indeces for the
    alignments which share minContinuousDistance continuous proximity.
    
    Generated:
    =======
    self.corridors -> [[align1,align2],...]
    
    Alignments that are facing each other in orientation of travel are
    ignored unless allowOpposingDirections is set to true.

Definition at line 1072 of file scene.py.

1072  def genCorridors(self, minProximity=None, minContinuousDistance=None, allowOpposingDirections=False):
1073  ''' Generate list of corridors containing the alignment indeces for the
1074  alignments which share minContinuousDistance continuous proximity.
1075 
1076  Generated:
1077  =======
1078  self.corridors -> [[align1,align2],...]
1079 
1080  Alignments that are facing each other in orientation of travel are
1081  ignored unless allowOpposingDirections is set to true.
1082  '''
1083  if(not minContinuousDistance): minContinuousDistance = self.corridorMinContinuousDistance
1084  if(not minProximity): minProximity = self.corridorMinProximity
1085 
1086  self.corridors = []
1087  alignments = self.data
1088  for alignA in range(len(alignments)):
1089  for alignB in range(len(alignments)):
1090  #Ignore opposing directions
1091  if(not allowOpposingDirections and ([alignA, alignB] in self.getOpposingDirections() or [alignB, alignA] in self.getOpposingDirections())): continue
1092  if(alignA >= alignB): continue
1093  result = tvaLib.Geo.searchSplineContinuousProximity(alignments[alignA], alignments[alignB], minProximity=minProximity, minContinuousDistance=minContinuousDistance)
1094  if(result): self.corridors.append([alignA,alignB])
1095  return True
1096 

◆ genLinks()

def lib.scene.Alignments.genLinks (   self,
  connectorSearchDistance = None,
  intersectionDistanceFactor = None,
  allowOpposingDirections = False 
)
Search through alignments for possible connectors within connectorSearchDistance

    Links stored one-by-one in self.links[] as:
      0      1       2        3        4          5            6             7          8        9
    [type, align, align-x, align-y, align_S, align-snap, align-snap-x, align-snap-y, align-snap_S, length]

    where:
type=0: leading connectors (Divergence from main branch)
type=1: trailing connectors (Convergence to main branch)
type=2: intertwining connectors (Convergence and divergence)

    Alignments that are facing each other in orientation of travel are
    ignored unless allowOpposingDirections is set to true.

Definition at line 1011 of file scene.py.

1011  def genLinks(self, connectorSearchDistance=None, intersectionDistanceFactor=None, allowOpposingDirections=False):
1012  ''' Search through alignments for possible connectors within connectorSearchDistance
1013 
1014  Links stored one-by-one in self.links[] as:
1015  0 1 2 3 4 5 6 7 8 9
1016  [type, align, align-x, align-y, align_S, align-snap, align-snap-x, align-snap-y, align-snap_S, length]
1017 
1018  where:
1019  type=0: leading connectors (Divergence from main branch)
1020  type=1: trailing connectors (Convergence to main branch)
1021  type=2: intertwining connectors (Convergence and divergence)
1022 
1023  Alignments that are facing each other in orientation of travel are
1024  ignored unless allowOpposingDirections is set to true.
1025  '''
1026  if(not connectorSearchDistance): connectorSearchDistance = self.connectorSearchDistance
1027  if(not intersectionDistanceFactor): intersectionDistanceFactor = self.intersectionDistanceFactor
1028 
1029  self.links = []
1030  alignments = self.data
1031  for align in range(len(alignments)):
1032  searchSplines = alignments[:align] + alignments[(align + 1):]
1033 
1034  resultLead = tvaLib.Geo.getNearestXYinSplineFromXY(alignments[align][0][0], alignments[align][0][1], searchSplines, searchPoint=-1, searchRadius=connectorSearchDistance)
1035  if(resultLead):
1036  match_align = resultLead[4]
1037  #Ignore corridors
1038  if([align, match_align] in self.getCorridors() or [match_align, align] in self.getCorridors()): continue
1039  #Ignore opposing directions
1040  if(not allowOpposingDirections and ([align, match_align] in self.getOpposingDirections() or [match_align, align] in self.getOpposingDirections())): continue
1041  if(match_align >= align): match_align += 1
1042  ss_spline_c = tvaLib.Geo.subsec_spline_dist_cumulative(alignments[align])
1043  self.links.append([0, align, alignments[align][0][0], alignments[align][0][1], 0, match_align, resultLead[1], resultLead[2], ss_spline_c[-1], resultLead[0]])
1044 
1045  resultTrail = tvaLib.Geo.getNearestXYinSplineFromXY(alignments[align][-1][0], alignments[align][-1][1], searchSplines, searchPoint=0, searchRadius=connectorSearchDistance)
1046  if(resultTrail):
1047  match_align = resultTrail[4]
1048  #Ignore corridors
1049  if([align, match_align] in self.getCorridors() or [match_align, align] in self.getCorridors()): continue
1050  #Ignore opposing directions
1051  if(not allowOpposingDirections and ([align, match_align] in self.getOpposingDirections() or [match_align, align] in self.getOpposingDirections())): continue
1052  if(match_align >= align): match_align += 1
1053  ss_spline_c = tvaLib.Geo.subsec_spline_dist_cumulative(alignments[align])
1054  self.links.append([1, align, alignments[align][-1][0], alignments[align][-1][1], ss_spline_c[-1], match_align, resultTrail[1], resultTrail[2], 0, resultTrail[0]])
1055 
1056  for alignB in range(len(alignments)):
1057  #Ignore corridors
1058  if([align, alignB] in self.getCorridors() or [alignB, align] in self.getCorridors()): continue
1059  #Ignore opposing directions
1060  if(not allowOpposingDirections and ([align, alignB] in self.getOpposingDirections() or [alignB, align] in self.getOpposingDirections())): continue
1061  if(align>=alignB): continue
1062  resultInter = tvaLib.Geo.searchSplineProximity(alignments[align], alignments[alignB], minProximity=connectorSearchDistance*intersectionDistanceFactor)
1063  if(resultInter): self.links.append([2, align, resultInter[1], resultInter[2], resultInter[3], alignB, resultInter[4], resultInter[5], resultInter[6], resultInter[0]])
1064 
1065  return True
1066 

◆ genOpposingDirections()

def lib.scene.Alignments.genOpposingDirections (   self,
  matching = 0.90,
  angleThreshold = 120.0 
)
Opposition of direction is defined by a matching percentage of
    alignment vector segment pairs with an angle threshold greater than
    angleThreshold. 

Definition at line 982 of file scene.py.

982  def genOpposingDirections(self, matching=0.90, angleThreshold=120.0):
983  ''' Opposition of direction is defined by a matching percentage of
984  alignment vector segment pairs with an angle threshold greater than
985  angleThreshold. '''
986 
987  self.opposingDirections = []
988  alignments = self.data
989  for align in range(len(alignments)):
990  for alignB in range(len(alignments)):
991  if(align <= alignB): continue
992  angles = []
993  for alignpIx in range(len(alignments[align])-1):
994  for alignBpIx in range(len(alignments[alignB])-1):
995  angles.append(tvaLib.Geo.vectorsToAngleDegCC(alignments[align][alignpIx+1][0]-alignments[align][alignpIx][0],
996  alignments[align][alignpIx+1][1]-alignments[align][alignpIx][1],
997  alignments[alignB][alignBpIx+1][0]-alignments[alignB][alignBpIx][0],
998  alignments[alignB][alignBpIx+1][1]-alignments[alignB][alignBpIx][1]))
999  # Convert large angles to inverse angles (355 -> 5)
1000  angles = [angle if angle<180.0 else 360.0-angle for angle in angles]
1001  # Check matching rate
1002  if(sum(angle > angleThreshold for angle in angles)/float(len(angles)) > matching): self.opposingDirections.append([align, alignB])
1003  return True
1004 

◆ genOrdinaryAlignIndeces()

def lib.scene.Alignments.genOrdinaryAlignIndeces (   self)

Definition at line 978 of file scene.py.

978  def genOrdinaryAlignIndeces(self):
979  self.ordinaryAlignments = [x for x in range(len(self)) if (float(x) not in self.bikepaths and float(x) not in self.sidewalks)]
980  return self.ordinaryAlignments
981 

◆ genRouteTree()

def lib.scene.Alignments.genRouteTree (   self)

Definition at line 1097 of file scene.py.

1097  def genRouteTree(self):
1098  self.route = Route()
1099  self.route.startSearch(self.data, self.getLinks(), self.getCorridors())
1100  return True
1101 

◆ getAlignIndexByName()

def lib.scene.Alignments.getAlignIndexByName (   self,
  name 
)

Definition at line 953 of file scene.py.

953  def getAlignIndexByName(self, name):
954  for laneIx in range(len(self.data)):
955  if(self.data[laneIx].name == name): return laneIx
956  return False
957 

◆ getCorridors()

def lib.scene.Alignments.getCorridors (   self)
Returns the result of genCorridors() 

Definition at line 1067 of file scene.py.

1067  def getCorridors(self):
1068  ''' Returns the result of genCorridors() '''
1069  if(not hasattr(self, 'corridors')): self.genCorridors()
1070  return self.corridors
1071 

◆ getLinks()

def lib.scene.Alignments.getLinks (   self)

Definition at line 958 of file scene.py.

958  def getLinks(self):
959  if(not hasattr(self, 'links')): self.genLinks()
960  return self.links
961 

◆ getOpposingDirections()

def lib.scene.Alignments.getOpposingDirections (   self)
Returns the result of genOpposingDirections() 

Definition at line 1005 of file scene.py.

1005  def getOpposingDirections(self):
1006  ''' Returns the result of genOpposingDirections() '''
1007  if(not hasattr(self, 'opposingDirections')): self.genOpposingDirections()
1008  return self.opposingDirections
1009 
1010 

◆ getOrdinaryAlignIndeces()

def lib.scene.Alignments.getOrdinaryAlignIndeces (   self)

Definition at line 974 of file scene.py.

974  def getOrdinaryAlignIndeces(self):
975  try: return self.ordinaryAlignments
976  except: return self.genOrdinaryAlignIndeces()
977 

◆ getRestrictedAlignmentsByClassification()

def lib.scene.Alignments.getRestrictedAlignmentsByClassification (   self,
  userType 
)

Definition at line 962 of file scene.py.

962  def getRestrictedAlignmentsByClassification(self, userType):
963  if(userType and (self.sidewalks or self.bikepaths)):
964  #Pedestrians can only use pedestrian lanes
965  if(userType==2): return [self[int(align)] for align in self.sidewalks]
966  #Cyclists can use cycle tracks or roads
967 
968  elif(userType==4): return [self[int(align)] for align in self.bikepaths]+[self[align] for align in self.getOrdinaryAlignIndeces()]
969  #All other types can only use regular lanes
970  #TODO: becuase cyclists can't be tracked accuratly for the time being, we have to lump them together with cars
971  else: return [self[int(align)] for align in self.bikepaths]+[self[align] for align in self.getOrdinaryAlignIndeces()]
972  else: return [align for align in self]
973 

◆ getRouteDistHorizonByPos()

def lib.scene.Alignments.getRouteDistHorizonByPos (   self,
  ax,
  ay,
  bx,
  by,
  distHorizonA,
  distHorizonB 
)
Use this function to determine if the route tree of user a
    intersects with the route tree of user b to a certain depth for each
    user.
    
    This function is a data-collecting wrapper for the more efficient 
    getRouteDistHorizonByPreCalc()

Definition at line 1106 of file scene.py.

1106  def getRouteDistHorizonByPos(self, ax, ay, bx, by, distHorizonA, distHorizonB):
1107  ''' Use this function to determine if the route tree of user a
1108  intersects with the route tree of user b to a certain depth for each
1109  user.
1110 
1111  This function is a data-collecting wrapper for the more efficient
1112  getRouteDistHorizonByPreCalc()
1113  '''
1114  [laneA, _, _, _, _, S_A, _] = tvaLib.Geo.getSYfromXY(ax,ay,self.data)
1115  [laneB, _, _, _, _, S_B, _] = tvaLib.Geo.getSYfromXY(bx,by,self.data)
1116 
1117  return self.getRouteDistHorizonByPreCalc(laneA, S_A, laneB, S_B, distHorizonA, distHorizonB)
1118 

◆ getRouteDistHorizonByPreCalc()

def lib.scene.Alignments.getRouteDistHorizonByPreCalc (   self,
  laneA,
  S_A,
  laneB,
  S_B,
  distHorizonA,
  distHorizonB 
)
This function is a child of getRouteDistHorizonByPos()
    It can be called directly with correspdonging data to leverage
    memory instead of consuming CPU cycles snapping X,Y positions.

Definition at line 1119 of file scene.py.

1119  def getRouteDistHorizonByPreCalc(self, laneA, S_A, laneB, S_B, distHorizonA, distHorizonB):
1120  ''' This function is a child of getRouteDistHorizonByPos()
1121  It can be called directly with correspdonging data to leverage
1122  memory instead of consuming CPU cycles snapping X,Y positions.
1123  '''
1124  if(laneA == laneB or True in [laneA in x and laneB in x for x in self.getCorridors()]):
1125 
1127  if((S_B > S_A and S_B < S_A+distHorizonA) or (S_A > S_B and S_A < S_B+distHorizonB)): return True
1128  else: return False
1129  else:
1130  localTreeA = self.getRouteTree().goToChildPosition(laneA, S_A)
1131  localTreeB = self.getRouteTree().goToChildPosition(laneB, S_B)
1132  return localTreeA.intersectHorizon(localTreeB, distHorizonA, horizonMatch=distHorizonB)
1133 

◆ getRouteTree()

def lib.scene.Alignments.getRouteTree (   self)

Definition at line 1102 of file scene.py.

1102  def getRouteTree(self):
1103  if(not hasattr(self, 'route')): self.genRouteTree()
1104  return self.route
1105 

◆ setup()

def lib.scene.Alignments.setup (   self,
  kwargs 
)

Definition at line 905 of file scene.py.

905  def setup(self, **kwargs):
906  self.corridorMinContinuousDistance = kwargs.get('corridorMinContinuousDistance',20.0)
907  self.corridorMinProximity = kwargs.get('corridorMinProximity',5.0)
908  self.connectorSearchDistance = kwargs.get('connectorSearchDistance',2.5)
909  self.intersectionDistanceFactor = kwargs.get('intersectionDistanceFactor',1.5)
910 

Member Data Documentation

◆ bikepaths

lib.scene.Alignments.bikepaths

Definition at line 899 of file scene.py.

◆ connectorSearchDistance

lib.scene.Alignments.connectorSearchDistance

Definition at line 894 of file scene.py.

◆ corridorMinContinuousDistance

lib.scene.Alignments.corridorMinContinuousDistance

Definition at line 892 of file scene.py.

◆ corridorMinProximity

lib.scene.Alignments.corridorMinProximity

Definition at line 893 of file scene.py.

◆ corridors

lib.scene.Alignments.corridors

Definition at line 1086 of file scene.py.

◆ intersectionDistanceFactor

lib.scene.Alignments.intersectionDistanceFactor

Definition at line 895 of file scene.py.

◆ links

lib.scene.Alignments.links

Definition at line 1029 of file scene.py.

◆ localString

lib.scene.Alignments.localString

Definition at line 897 of file scene.py.

◆ opposingDirections

lib.scene.Alignments.opposingDirections

Definition at line 987 of file scene.py.

◆ ordinaryAlignments

lib.scene.Alignments.ordinaryAlignments

Definition at line 979 of file scene.py.

◆ ranBB

lib.scene.Alignments.ranBB

Definition at line 891 of file scene.py.

◆ route

lib.scene.Alignments.route

Definition at line 1098 of file scene.py.

◆ SDR

lib.scene.Alignments.SDR

Definition at line 896 of file scene.py.

◆ sidewalks

lib.scene.Alignments.sidewalks

Definition at line 898 of file scene.py.


The documentation for this class was generated from the following file: