Exemple #1
0
 def findPointsOnLinks(self, pointX, pointY, radius, primaryRadius, secondaryRadius, prevPoints, limitClosestPoints = sys.maxint):
     """
     findPointsOnLinks searches through the graph and finds all PointOnLinks that are within the radius.
     Then, eligible links are proposed primaryRadius distance around the GTFS point, or secondaryRadius
     distance from the previous VISTA points.  Returns an empty list if none are found.  This corresponds
     with algorithm "FindPointsOnLinks" in Figure 1 of Perrine, et al. 2015.
     @type pointX: float
     @type pointY: float
     @type radius: float
     @type primaryRadius: float
     @type secondaryRadius: float
     @type prevPoints: list<PointOnLink>
     @type limitClosestPoints: int
     @rtype list<PointOnLink>
     """
     # TODO: This brute-force implementation can be more efficient with quad trees, etc. rather than
     # scanning through all elements.
     radiusSq = radius ** 2
     primaryRadiusSq = primaryRadius ** 2
     secondaryRadiusSq = secondaryRadius ** 2
     retSet = set()
     
     # Find perpendicular and non-perpendicular PointOnLinks that are within radius.
     for link in self.linkMap.values():
         "@type link: graph.GraphLink"
         (distSq, linkDist, perpendicular) = linear.pointDistSq(pointX, pointY, link.origNode.coordX, link.origNode.coordY,
                                                                link.destNode.coordX, link.destNode.coordY, link.distance)
         if distSq <= radiusSq:
             pointOnLink = PointOnLink(link, linkDist, not perpendicular, math.sqrt(distSq))
             
             # We are within the initial search radius.  Are we then within the primary radius?
             if distSq <= primaryRadiusSq:
                 # Yes, easy.  Add to the list:
                 retSet.add(pointOnLink)
             else:
                 # Check to see if the point is close to a previous point:
                 for prevPoint in prevPoints:
                     "@type prevPoint: PointOnLink"
                     distSq = linear.getNormSq(pointOnLink.pointX, pointOnLink.pointY, prevPoint.pointX, prevPoint.pointY)
                     if (distSq < secondaryRadiusSq):
                         # We have a winner:
                         retSet.add(pointOnLink)
                         break
                 
     ret = list(retSet)
     
     # TODO: If there is a nonperpendicular link and distance = 0, and there also exists in the set a link
     # that leads to the first link's parent node, then get rid of that first link.
     
     # Keep limited number of closest values 
     ret.sort(key = operator.attrgetter('refDist'))
     return ret[0:limitClosestPoints]