def check_segment( segment, roadmap, length_attr='length' ) : # a rare case where "static variable" is useful; # to prevent "costly" re-allocation of RoadAddress structure if not hasattr(check_segment, 'first' ) : check_segment.first = RoadAddress(None,None) if not hasattr(check_segment, 'second' ) : check_segment.second = RoadAddress(None,None) road = segment.road check_segment.first.road = road check_segment.first.coord = segment.first check_segment.second.road = road check_segment.second.coord = segment.second try : assert check_point( roadmap, check_segment.first, length_attr ) assert check_point( roadmap, check_segment.second, length_attr ) except AssertionError : return False return True
def minpath_on_road( p, q, road, roadmap, length_attr='length' ) : """ subroutine and useful utility: returns the path from p to q on road, if the direction of travel is admissible; if not, or if p and q are not co-'road'-al, returns empty path, implying non-existence """ edge, data = obtain_edge( roadmap, road, True ) i,j,key = edge path = [] # regular logic, NOT error catching try : assert p.road == road and check_point( roadmap, p, length_attr ) assert q.road == road and check_point( roadmap, q, length_attr ) assert p.coord < q.coord or not data.get( 'oneway', False ) path.append( RoadSegment( road, p.coord, q.coord ) ) except AssertionError : pass return path
def minpath_node_to_point( u, q, roadmap, length_attr='length' ) : """ subroutine and useful utility: returns the shortest-path distance from a node u to a point q, on digraph """ # some convenient static variables scope = minpath_node_to_point if not hasattr( scope, 'STATICS' ) : scope.STATICS = True scope.first = RoadAddress(None,None) scope.second = RoadAddress(None,None) scope.points = [ scope.first, scope.second ] # convenient non-static variables assert check_point( roadmap, q, length_attr ) road = q.road edge, data = obtain_edge( roadmap, road, True ) i,j,key = edge roadlen = data.get( length_attr, 1 ) # pre-load options with nopath; in case there are no feasible paths options = [ (np.inf, [] ) ] # possible paths are u->v->q, for v in endpoints of road of q scope.first.init(road,0.) scope.second.init(road,roadlen) for v, pp in zip( (i,j), scope.points ) : try : astarPath = astar_basic.astar_path( roadmap, u, v, None, weight=length_attr ) first = pathFromAStar( astarPath, roadmap, length_attr ) except nx.NetworkXNoPath : continue second = minpath_on_road( pp, q, road, roadmap, length_attr ) path = first + second options.append( (pathLength(path), path ) ) return min( options )[1]