예제 #1
0
def test_finds_routes_between_created_OD_on_same_street(
        log, graph_handler: GraphHandler, routing_conf):
    # /paths/walk/quiet/60.214233,24.971411/60.213558,24.970785
    od_settings = routing.parse_od_settings(TravelMode.WALK,
                                            RoutingMode.GREEN,
                                            routing_conf,
                                            orig_lat='60.214233',
                                            orig_lon='24.971411',
                                            dest_lat='60.213558',
                                            dest_lon='24.970785',
                                            aqi_updater=None)

    ecount = graph_handler.graph.ecount()
    assert ecount == 16643

    od_nodes = routing.find_or_create_od_nodes(log, graph_handler, od_settings)
    path_set = routing.find_least_cost_paths(log, graph_handler, routing_conf,
                                             od_settings, od_nodes)
    path_FC, edge_FC = routing.process_paths_to_FC(log, graph_handler,
                                                   routing_conf, od_settings,
                                                   path_set)
    assert path_FC['type'] == 'FeatureCollection'
    assert edge_FC['type'] == 'FeatureCollection'
    assert ecount + 4 == graph_handler.graph.ecount()
    routing.delete_added_graph_features(graph_handler, od_nodes)
    graph_handler.reset_edge_cache()
예제 #2
0
def test_finds_routes_between_created_OD(log, graph_handler: GraphHandler,
                                         routing_conf, ensure_path_fc,
                                         ensure_edge_fc):
    # paths/walk/green/60.21352729760156,24.97086446863051/60.21128945130093,24.968455167858025

    od_settings = routing.parse_od_settings(TravelMode.WALK,
                                            RoutingMode.GREEN,
                                            routing_conf,
                                            orig_lat='60.21352729760156',
                                            orig_lon='24.97086446863051',
                                            dest_lat='60.21128945130093',
                                            dest_lon='24.968455167858025',
                                            aqi_updater=None)

    ecount = graph_handler.graph.ecount()
    assert ecount == 16643

    od_nodes = routing.find_or_create_od_nodes(log, graph_handler, od_settings)
    path_set = routing.find_least_cost_paths(log, graph_handler, routing_conf,
                                             od_settings, od_nodes)
    path_FC, edge_FC = routing.process_paths_to_FC(log, graph_handler,
                                                   routing_conf, od_settings,
                                                   path_set)
    ensure_path_fc(path_FC)
    ensure_edge_fc(edge_FC)
    assert ecount + 4 == graph_handler.graph.ecount()
    routing.delete_added_graph_features(graph_handler, od_nodes)
    graph_handler.reset_edge_cache()
예제 #3
0
def test_path_props_when_routing_with_created_OD_on_same_street(
        log, graph_handler: GraphHandler, routing_conf):
    # /paths/walk/quiet/60.214233,24.971411/60.213558,24.970785
    od_settings = routing.parse_od_settings(TravelMode.WALK,
                                            RoutingMode.GREEN,
                                            routing_conf,
                                            orig_lat='60.214233',
                                            orig_lon='24.971411',
                                            dest_lat='60.213558',
                                            dest_lon='24.970785',
                                            aqi_updater=None)
    od_nodes = routing.find_or_create_od_nodes(log, graph_handler, od_settings)
    path_set = routing.find_least_cost_paths(log, graph_handler, routing_conf,
                                             od_settings, od_nodes)
    path_FC, edge_FC = routing.process_paths_to_FC(log, graph_handler,
                                                   routing_conf, od_settings,
                                                   path_set)
    routing.delete_added_graph_features(graph_handler, od_nodes)
    graph_handler.reset_edge_cache()

    path_1 = path_FC['features'][0]
    props = path_1['properties']
    assert props['length'] == 82.8
    assert round(sum(props['noises'].values()), 1) == round(props['length'], 1)
    assert round(sum(props['gvi_cl_exps'].values()),
                 1) == round(props['length'], 1)
    assert round(sum(props['gvi_cl_pcts'].values()), 1) == 100.0
    # assert round(sum(props['aqi_cl_exps'].values()),1) == round(props['length'],1)
    # assert round(sum(props['aqi_cl_pcts'].values()),1) == 100.0
    assert round(sum(props['noise_range_exps'].values()),
                 1) == round(props['length'], 1)
    assert round(sum(props['noise_pcts'].values()), 1) == 100.0
    assert props['bike_time_cost'] == 82.8
    assert props['bike_safety_cost'] == 82.8
예제 #4
0
def test_creates_also_dest_node_if_origin_was_created(
        log, graph_handler: GraphHandler, routing_conf):
    # paths/walk/green/60.213859473184016,24.971143562116595/60.21210611561355,24.969360716643195
    od_settings = routing.parse_od_settings(TravelMode.WALK,
                                            RoutingMode.GREEN,
                                            routing_conf,
                                            orig_lat='60.213859473184016',
                                            orig_lon='24.971143562116595',
                                            dest_lat='60.21210611561355',
                                            dest_lon='24.969360716643195',
                                            aqi_updater=None)

    ecount = graph_handler.graph.ecount()
    assert ecount == 16643

    od_nodes = routing.find_or_create_od_nodes(log, graph_handler, od_settings)
    path_set = routing.find_least_cost_paths(log, graph_handler, routing_conf,
                                             od_settings, od_nodes)
    path_FC, edge_FC = routing.process_paths_to_FC(log, graph_handler,
                                                   routing_conf, od_settings,
                                                   path_set)
    assert path_FC['type'] == 'FeatureCollection'
    assert edge_FC['type'] == 'FeatureCollection'
    assert ecount + 4 == graph_handler.graph.ecount(
    )  # if origin was already created, then also dest is created
    routing.delete_added_graph_features(graph_handler, od_nodes)
    graph_handler.reset_edge_cache()
예제 #5
0
def test_finds_routes_between_existing_O_and_created_D_on_same_street(
        log, graph_handler: GraphHandler, routing_conf):
    # /paths/walk/green/60.212149138928254,24.969463681172613/60.213886742565194,24.971240777950726
    od_settings = routing.parse_od_settings(TravelMode.WALK,
                                            RoutingMode.GREEN,
                                            routing_conf,
                                            orig_lat='60.212149138928254',
                                            orig_lon='24.969463681172613',
                                            dest_lat='60.213886742565194',
                                            dest_lon='24.971240777950726',
                                            aqi_updater=None)

    ecount = graph_handler.graph.ecount()
    assert ecount == 16643

    od_nodes = routing.find_or_create_od_nodes(log, graph_handler, od_settings)
    path_set = routing.find_least_cost_paths(log, graph_handler, routing_conf,
                                             od_settings, od_nodes)
    path_FC, edge_FC = routing.process_paths_to_FC(log, graph_handler,
                                                   routing_conf, od_settings,
                                                   path_set)
    assert path_FC['type'] == 'FeatureCollection'
    assert edge_FC['type'] == 'FeatureCollection'
    assert ecount + 2 == graph_handler.graph.ecount()
    routing.delete_added_graph_features(graph_handler, od_nodes)
    graph_handler.reset_edge_cache()
예제 #6
0
def delete_added_graph_features(G: GraphHandler, od_nodes: OdData):
    """Keeps the graph clean by removing new nodes & edges created during routing from the graph.
    """
    delete_o_node = (
        od_nodes.orig_node.id, ) if od_nodes.orig_link_edges else ()
    delete_d_node = (
        od_nodes.dest_node.id, ) if od_nodes.dest_link_edges else ()
    G.drop_nodes_edges(delete_o_node + delete_d_node)
예제 #7
0
def __find_safest_path(G: GraphHandler, od_nodes: OdData) -> Path:
    return Path(path_id=PathType.SAFEST.value,
                path_type=PathType.SAFEST,
                edge_ids=G.get_least_cost_path(
                    od_nodes.orig_node.id,
                    od_nodes.dest_node.id,
                    weight=E.bike_safety_cost.value))
예제 #8
0
def test_removes_linking_edges_after_routing(log, graph_handler: GraphHandler,
                                             routing_conf):
    # paths/walk/green/60.21352729760156,24.97086446863051/60.21128945130093,24.968455167858025
    od_settings = routing.parse_od_settings(TravelMode.WALK.value,
                                            RoutingMode.GREEN.value,
                                            routing_conf,
                                            orig_lat='60.21352729760156',
                                            orig_lon='24.97086446863051',
                                            dest_lat='60.21128945130093',
                                            dest_lon='24.968455167858025',
                                            aqi_updater=None)
    ecount = graph_handler.graph.ecount()
    od_nodes = routing.find_or_create_od_nodes(log, graph_handler, od_settings)
    assert ecount + 4 == graph_handler.graph.ecount()
    routing.delete_added_graph_features(graph_handler, od_nodes)
    graph_handler.reset_edge_cache()
    assert ecount == graph_handler.graph.ecount()
예제 #9
0
def __find_fastest_path(G: GraphHandler, od_nodes: OdData,
                        fastest_path_cost_attr: E) -> Path:
    return Path(path_id=PathType.FASTEST.value,
                path_type=PathType.FASTEST,
                edge_ids=G.get_least_cost_path(
                    od_nodes.orig_node.id,
                    od_nodes.dest_node.id,
                    weight=fastest_path_cost_attr.value))
예제 #10
0
def get_orig_dest_nodes_and_linking_edges(G: GraphHandler, orig_point: Point,
                                          dest_point: Point) -> OdData:
    """Selects nearest nodes ad OD if they are "near enough", otherwise creates new nodes
    either on the nearest existing edges or on the previously created links (i.e. temporary) edges.
    """
    orig_link_edges = ()
    dest_link_edges = ()
    long_distance: bool = orig_point.distance(dest_point) > 5000

    try:
        orig_node = get_nearest_node(G,
                                     orig_point,
                                     avoid_node_creation=True,
                                     long_distance=long_distance)
    except Exception:
        raise RoutingException(ErrorKey.ORIGIN_NOT_FOUND.value)

    # add linking edges to graph if new node was created (on the nearest edge)
    if orig_node.link_to_edge_spec:
        orig_link_edges = get_link_edge_data(orig_node.id,
                                             orig_node.link_to_edge_spec,
                                             create_inbound_links=False,
                                             create_outbound_links=True)

    try:
        dest_node = get_nearest_node(G,
                                     dest_point,
                                     avoid_node_creation=not orig_link_edges,
                                     temp_link_edges=orig_link_edges,
                                     long_distance=long_distance)
    except Exception:
        raise RoutingException(ErrorKey.DESTINATION_NOT_FOUND.value)

    # add linking edges to graph if new node was created (on the nearest edge)
    if dest_node.link_to_edge_spec:
        dest_link_edges = get_link_edge_data(
            dest_node.id,
            dest_node.link_to_edge_spec,
            create_inbound_links=True,
            create_outbound_links=False,
        )

    G.add_new_edges_to_graph(orig_link_edges + dest_link_edges)

    return OdData(orig_node, dest_node, orig_link_edges, dest_link_edges)
예제 #11
0
def __find_exp_optimized_paths(G: GraphHandler, od_settings: OdSettings,
                               od_nodes: OdData):
    cost_prefix = cost_prefix_dict[od_settings.travel_mode][
        od_settings.routing_mode]
    return [
        Path(path_id=f'{cost_prefix}{sen}',
             path_type=path_type_by_routing_mode[od_settings.routing_mode],
             edge_ids=G.get_least_cost_path(od_nodes.orig_node.id,
                                            od_nodes.dest_node.id,
                                            weight=f'{cost_prefix}{sen}'),
             cost_coeff=sen) for sen in od_settings.sensitivities
    ]
예제 #12
0
def get_nearest_node(G: GraphHandler,
                     point: Point,
                     avoid_node_creation: bool,
                     temp_link_edges: Tuple[dict] = (),
                     long_distance: bool = False) -> OdNodeData:

    nearest_edge = G.find_nearest_edge(point)
    if not nearest_edge:
        raise Exception('Nearest edge not found')

    nearest_node: int = G.find_nearest_node(point)
    if not nearest_node:
        raise Exception('Nearest node not found')

    nearest_node_geom = G.get_node_point_geom(nearest_node)
    nearest_edge_point = __get_closest_point_on_line(
        nearest_edge.attrs[E.geometry.value], point)
    nearest_node_dist = nearest_node_geom.distance(point)

    od_as_nearest_node = __maybe_use_nearest_existing_node(
        avoid_node_creation, long_distance, nearest_node, nearest_node_dist,
        nearest_edge)
    if od_as_nearest_node:
        return od_as_nearest_node

    # still here, thus creating a new node to graph and linking edges for it

    nearest_edge = __select_nearest_edge(nearest_edge_point, nearest_edge,
                                         temp_link_edges)

    # create a new node on the nearest edge to the graph
    new_node = G.add_new_node_to_graph(nearest_edge_point)
    # new edges from the new node to existing nodes need to be created to the graph
    # hence return the geometry of the nearest edge and the nearest point on the nearest edge
    return OdNodeData(id=new_node,
                      is_temp_node=True,
                      link_to_edge_spec=LinkToEdgeSpec(
                          edge=nearest_edge.attrs,
                          snap_point=nearest_edge_point))
예제 #13
0
def test_path_props_when_routing_with_created_OD(log,
                                                 graph_handler: GraphHandler,
                                                 routing_conf):
    # paths/walk/green/60.21352729760156,24.97086446863051/60.21128945130093,24.968455167858025

    od_settings = routing.parse_od_settings(TravelMode.WALK,
                                            RoutingMode.GREEN,
                                            routing_conf,
                                            orig_lat='60.21352729760156',
                                            orig_lon='24.97086446863051',
                                            dest_lat='60.21128945130093',
                                            dest_lon='24.968455167858025',
                                            aqi_updater=None)

    od_nodes = routing.find_or_create_od_nodes(log, graph_handler, od_settings)
    path_set = routing.find_least_cost_paths(log, graph_handler, routing_conf,
                                             od_settings, od_nodes)
    path_FC, edge_FC = routing.process_paths_to_FC(log, graph_handler,
                                                   routing_conf, od_settings,
                                                   path_set)
    routing.delete_added_graph_features(graph_handler, od_nodes)
    graph_handler.reset_edge_cache()

    path_1 = path_FC['features'][0]
    props = path_1['properties']
    assert props['length'] == 291.97
    assert round(sum(props['noises'].values()), 1) == round(props['length'], 1)
    assert round(sum(props['gvi_cl_exps'].values()),
                 1) == round(props['length'], 1)
    assert round(sum(props['gvi_cl_pcts'].values()), 1) == 100.0
    # assert round(sum(props['aqi_cl_exps'].values()),1) == round(props['length'],1)
    # assert round(sum(props['aqi_cl_pcts'].values()),1) == 100.0
    assert round(sum(props['noise_range_exps'].values()),
                 1) == round(props['length'], 1)
    assert round(sum(props['noise_pcts'].values()), 1) == 100.0
    assert props['bike_time_cost'] == 291.93
    assert props['bike_safety_cost'] == 291.93
예제 #14
0
def test_path_props_when_routing_with_created_D(log,
                                                graph_handler: GraphHandler,
                                                routing_conf):
    # origin is existing node, destination is new
    # paths/walk/quiet/60.212103883291405,24.969382893894505/60.21390217111113,24.971206858808813
    od_settings = routing.parse_od_settings(TravelMode.WALK,
                                            RoutingMode.GREEN,
                                            routing_conf,
                                            orig_lat='60.212103883291405',
                                            orig_lon='24.969382893894505',
                                            dest_lat='60.21390217111113',
                                            dest_lon='24.971206858808813',
                                            aqi_updater=None)
    od_nodes = routing.find_or_create_od_nodes(log, graph_handler, od_settings)
    path_set = routing.find_least_cost_paths(log, graph_handler, routing_conf,
                                             od_settings, od_nodes)
    path_FC, edge_FC = routing.process_paths_to_FC(log, graph_handler,
                                                   routing_conf, od_settings,
                                                   path_set)
    routing.delete_added_graph_features(graph_handler, od_nodes)
    graph_handler.reset_edge_cache()

    path_1 = path_FC['features'][0]
    props = path_1['properties']
    assert props['length'] == 218.58
    assert round(sum(props['noises'].values()), 1) == round(props['length'], 1)
    assert round(sum(props['gvi_cl_exps'].values()),
                 1) == round(props['length'], 1)
    assert round(sum(props['gvi_cl_pcts'].values()), 1) == 100.0
    # assert round(sum(props['aqi_cl_exps'].values()),1) == round(props['length'],1)
    # assert round(sum(props['aqi_cl_pcts'].values()),1) == 100.0
    assert round(sum(props['noise_range_exps'].values()),
                 1) == round(props['length'], 1)
    assert round(sum(props['noise_pcts'].values()), 1) == 100.0
    assert props['bike_time_cost'] == 218.52
    assert props['bike_safety_cost'] == 218.52
예제 #15
0
 def set_path_edges(self, G: GraphHandler) -> None:
     """Iterates through the path's edge IDs and loads edge attributes from a graph.
     """
     self.edges = G.get_path_edges_by_ids(self.edge_ids)
    - Set graph_file to 'graphs/kumpula.graphml' in src/conf.py
    - Start Green Paths routing app to handle routing requests at localhost:5000

"""

from gp_server.app.graph_handler import GraphHandler
from gp_server.app.types import PathEdge
from gp_server.app.logger import Logger
import gp_server.app.noise_exposures as noise_exps
from typing import List, Tuple, Union
import requests
import traceback


# initialize graph handler for fetching edge data after routing
G = GraphHandler(Logger(), 'graphs/kumpula.graphml')


# define example ODs
od_list = [
    ((60.21743, 24.96996), (60.2123, 24.95978)),
    ((60.21743, 24.96996), (60.2118, 24.95952)),
    ((60.20151, 24.96206), (60.2102, 24.96887)),
    ((60.21495, 24.97971), (60.20166, 24.968))
]


def get_od_paths(od_coords: Tuple[Tuple[float, float]]) -> Union[dict, None]:
    """Returns paths from local Green Paths routing API. If routing fails, returns None. 
    """
    od_request_coords = f'{od_coords[0][0]},{od_coords[0][1]}/{od_coords[1][0]},{od_coords[1][1]}'
예제 #17
0
def graph_handler(log):
    patch_conf = patch('gp_server.conf.conf', test_conf)
    with patch_conf:
        yield GraphHandler(log, test_conf.graph_file,
                           routing.get_routing_conf())
예제 #18
0
app = Flask(__name__)
CORS(app)

# set logging to use gunicorn logger & logging level
if __name__ != '__main__':
    gunicorn_logger = logging.getLogger('gunicorn.error')
    app.logger.handlers = gunicorn_logger.handlers
    app.logger.setLevel(gunicorn_logger.level)

log = Logger(app_logger=app.logger, b_printing=False)

routing_conf = routing.get_routing_conf()

# initialize graph
G = GraphHandler(log, conf.graph_file, routing_conf)

if conf.clean_paths_enabled:
    aqi_updater = GraphAqiUpdater(log, G, r'aqi_updates/', routing_conf)
else:
    aqi_updater = None

# start AQI map data service
aqi_map_data_api = get_aqi_map_data_api(log, r'aqi_updates/')
aqi_map_data_api.start()


@app.route('/')
def hello_world():
    return 'Keep calm and walk green paths.'