Пример #1
0
def route_from_coord(request):
    """
        Responds with a route starting and ending in a certain coordinate

        This function uses the lightning rod (Stroobant) algorithm: it generates a
        rod through the city and then tries different paths going to that rod

        Query args:
        lat -- coordinate latitude
        lon -- coordinate longitude
        type -- the response type. See the geojson.respond_path function for more details
    """
    edge_tuple = get_edge_tuple(request, request.GET.get('lat'),
                                request.GET.get('lon'))
    if edge_tuple is None:
        # This happens when the requested coordinates are not within the Graph.
        return HttpResponseNotFound()
    (start, end) = edge_tuple
    config = routing_config.from_dict(DEFAULT_ROUTING_CONFIG,
                                      request.GET.dict())

    # Calculations
    tpexec = Executor(max_workers=NUM_THREADS)
    routes = []
    flist = []

    # Sometimes, routing gives a bad response. To fix this, the routing algorithm
    # is performed multiple times in an (a)synchronous way.
    for i in xrange(NUM_THREADS):
        flist.append(tpexec.submit(async_exec, GRAPH, start, end, config))

    for _i in xrange(NUM_THREADS * 10):
        sets = wait(flist, return_when=FIRST_COMPLETED)
        flist = list(sets.not_done)
        for fut in sets.done:
            routes = fut.result()
            if len(routes) > 0:
                break
            flist.append(tpexec.submit(async_exec, GRAPH, start, end, config))

    tpexec.shutdown(False)

    # Choose a random route from all possible routes.
    shuffle(routes)
    print path_length(GRAPH, routes[0])
    resp = respond_path(request.GET, routes[0], [routes[0][0]])
    if resp is None:
        return HttpResponseNotFound()
    return HttpResponse(into_json(resp))
Пример #2
0
def get_id_from_pos(request):
    """
        Respond with the node index closest to the given coordinate.

        Query args:
        lat -- coordinate latitude
        lon -- coordinate longitude
    """
    try:
        tup = get_edge_tuple(request, request.GET.get('lat'),
                             request.GET.get('lon'))
        if tup is None:
            return HttpResponseNotFound()
        return HttpResponse(into_json(tup))
    except BaseException:
        return HttpResponseBadRequest()
Пример #3
0
def get_node_from_pos(request):
    """
        Respond with the node data closest to the given coordinate.

        Query args:
        lat -- coordinate latitude
        lon -- coordinate longitude
    """
    try:
        tup = get_edge_tuple(request, request.GET.get('lat'),
                             request.GET.get('lon'))
    except BaseException:
        return HttpResponseBadRequest()
    if tup is None:
        return HttpResponse('[]')
    tup = map(city.GRAPH.get, tup)
    return HttpResponse(into_json(tup))
Пример #4
0
 def test_get_edge_tuple(self):
     util.get_edge_tuple(None, 51.0, 3.8)
Пример #5
0
def go_home(request):
    """
        Responds with a route leading the user back to his starting point.

        Query args:
        tag -- the route that the user used to run.
        lon, lat -- position of the user.
        distance -- The preferred distance to the starting point.
    """
    # Get path from request tag
    tag = request.GET.get('tag')
    path = from_string(GRAPH, tag)

    # Find nearest node
    (start, end) = get_edge_tuple(request, request.GET.get('lat'),
                                  request.GET.get('lon'))

    # Get the preferred distance to run from this point to starting position (0 means straight home)
    dist_arg = float(request.GET.get('distance'))
    if dist_arg == 0:
        dist = distance(serialize_node(GRAPH, end),
                        serialize_node(GRAPH, path[0]))
    else:
        dist = dist_arg
    print dist

    # Get index of current location and close rod to return
    if end not in path and start in path:
        (end, start) = (start, end)
    elif not (end in path or start in path):
        for node in serialize_node(GRAPH, end).connections + serialize_node(
                GRAPH, start).connections:
            if node.node in path:
                end = node.node
                break
    ind = path.index(end)

    # Nodes from starting to current position
    pois_path = path[ind:0:-1]
    dist = dist - path_length(GRAPH, pois_path)

    d = {k: v for k, v in request.GET.dict().items()}
    d['min_length'] = str(dist)
    d['max_length'] = str(dist + 1.0)
    config = routing_config.from_dict(DEFAULT_ROUTING_CONFIG, d)

    # Generate new random rod from starting position
    nodes = generate_rod(GRAPH, path[0], config)
    # Create new rod that will be used for the poisoning (starting from current position and contains starting pos)
    pois_path.extend(nodes)
    print "tag =", into_string(GRAPH, nodes)
    # Close the rod on the starting position
    routes = close_rod(GRAPH, end, pois_path, config, nodes)
    # Will result in the shortest route returned
    if dist_arg == 0:
        routes = sorted(routes, key=len)
    else:
        shuffle(routes)
    print path_length(GRAPH, routes[0])
    # Return the new route, i.e. the completed part + new part
    selected_route = path[0:ind] + routes[0][::-1]
    resp = respond_path(request.GET, selected_route, [selected_route[0]])
    if resp is None:
        return HttpResponseNotFound()
    return HttpResponse(into_json(resp))