예제 #1
0
def test_find_nearest():

    # get graph and x/y coords to search
    G = ox.graph_from_point(location_point, dist=500, network_type="drive")
    Gp = ox.project_graph(G)
    points = ox.utils_geo.sample_points(ox.get_undirected(Gp), 5)
    X = points.x
    Y = points.y

    # get nearest node
    nn, d = ox.get_nearest_node(Gp, location_point, method="euclidean", return_dist=True)
    nn = ox.get_nearest_node(Gp, location_point, method="euclidean", return_dist=False)

    # get nearest nodes
    nn1, dist1 = ox.get_nearest_nodes(G, X, Y, return_dist=True)
    nn2, dist2 = ox.get_nearest_nodes(Gp, X, Y, method="kdtree", return_dist=True)
    nn3, dist3 = ox.get_nearest_nodes(G, X, Y, method="balltree", return_dist=True)
    nn4 = ox.get_nearest_nodes(G, X, Y)
    nn5 = ox.get_nearest_nodes(Gp, X, Y, method="kdtree")
    nn6 = ox.get_nearest_nodes(G, X, Y, method="balltree")

    # get nearest edge
    u, v, k, g, d = ox.get_nearest_edge(Gp, location_point, return_geom=True, return_dist=True)
    u, v, k, g = ox.get_nearest_edge(Gp, location_point, return_geom=True)
    u, v, k, d = ox.get_nearest_edge(Gp, location_point, return_dist=True)
    u, v, k = ox.get_nearest_edge(Gp, location_point)

    # get nearest edges
    ne0 = ox.distance.nearest_edges(Gp, X, Y, interpolate=50)
    ne1 = ox.get_nearest_edges(Gp, X, Y)
    ne2 = ox.get_nearest_edges(Gp, X, Y, method="kdtree")
    ne3 = ox.get_nearest_edges(G, X, Y, method="balltree", dist=0.0001)
예제 #2
0
def findPath(paths):
    startTime = time.time()

    punggol = (1.4041070, 103.9025242)  # Punggol Interchange as mid point
    distance = 3000
    G = ox.graph_from_point(punggol,
                            distance=distance,
                            network_type='drive_service')

    listOfNodes = []  # Stored as [ (lat, lon, BusStopCode) ] format
    listOfTuplesStartEndLatLon = [
    ]  # Stored as [ ((Start1 lat, Start1 lon) , (End2 lat, End2 lon)) ] format
    route = []  # Routes to travel from [Route Start1 to End 2]format

    with open('../../bus_data/Punggol_Bus_Stops.json') as bus_stop:
        data = json.load(bus_stop)

        for i in paths:
            for x in data['punggolBusStops']:
                if i == int(x['BusStopCode']):
                    tempTuple = (x['Latitude'], x['Longitude'],
                                 x['BusStopCode'])
                    listOfNodes.append(tempTuple)
                    break

    # Retriving the long and lat of the nodes
    for i in range(len(listOfNodes)):
        if i != (len(listOfNodes) - 1):
            listOfTuplesStartEndLatLon.append(
                ((float(listOfNodes[i][0]), float(listOfNodes[i][1])),
                 (float(listOfNodes[i + 1][0]), float(listOfNodes[i + 1][1]))))

    # Retriving of all routes(edges) to plot route
    for i in range(len(listOfTuplesStartEndLatLon)):
        route.extend(
            nx.shortest_path(G, (ox.get_nearest_edge(
                G, (listOfTuplesStartEndLatLon[i][0][0],
                    listOfTuplesStartEndLatLon[i][0][1])))[2],
                             (ox.get_nearest_edge(
                                 G,
                                 (listOfTuplesStartEndLatLon[i][1][0],
                                  listOfTuplesStartEndLatLon[i][1][1])))[2]))

    route = removeDupes(route)

    endTime = time.time()

    print("Bus Route Retrieval Takes: ", round((endTime - startTime), 2))

    return route, listOfTuplesStartEndLatLon
def osmnx_response(coordinates, type):
    dict = {}
    dict["type"] = "edges"
    edges = []
    touple = []

    if type == "loop":

        for i in range(0, len(coordinates), 2):
            nr_edge = ox.get_nearest_edge(
                G, (float(coordinates[i]), float(coordinates[i + 1])))

            touple.append([nr_edge[1], nr_edge[2]])

            for i in range(len(G[nr_edge[1]][nr_edge[2]])):
                if str(G[nr_edge[1]][nr_edge[2]][i]['geometry']) == str(
                        nr_edge[0]):
                    key = i
                    touple[-1].append(key)

            if len(touple) == 2:
                print("touple ", touple)
                edges.append(touple)
                touple = []

            polyline_string.update_polyline(nr_edge[0])

    else:

        for i in range(0, len(coordinates), 2):
            nr_edge = ox.get_nearest_edge(
                G, (float(coordinates[i]), float(coordinates[i + 1])))

            touple = [nr_edge[1], nr_edge[2]]

            for i in range(len(G[nr_edge[1]][nr_edge[2]])):
                if str(G[nr_edge[1]][nr_edge[2]][i]['geometry']) == str(
                        nr_edge[0]):
                    key = i
                    touple.insert(len(touple), key)

            edges.append(touple)
            G.remove_edge(nr_edge[1], nr_edge[2], key)
            touple = []

    dict["data"] = edges
    print(edges)

    return dict
예제 #4
0
        def get_nearestedge_node(osm_id, a, G):
            """
            Find the nearest node available in Open street map

            Parameters
            ----------
            osm_id : node ID
            a : plotting graph
            g : bus graph

            Returns
            -------
            temp_nearest_edge[1]/temp_nearest_edge[2] : nearest node to a way ID
            """
            temp_y = G.nodes.get(osm_id).get('y')
            temp_x = G.nodes.get(osm_id).get('x')
            temp_nearest_edge = ox.get_nearest_edge(a, (temp_y, temp_x))
            temp_1 = temp_nearest_edge[0].coords[0]
            temp_2 = temp_nearest_edge[0].coords[1]
            temp1_x = temp_1[0]
            temp1_y = temp_1[1]
            temp_1_distance = calculate_H(temp1_y, temp1_x, temp_y, temp_x)

            temp2_x = temp_2[0]
            temp2_y = temp_2[1]
            temp_2_distance = calculate_H(temp2_y, temp2_x, temp_y, temp_x)
            if temp_1_distance < temp_2_distance:
                return temp_nearest_edge[1]
            else:
                return temp_nearest_edge[2]
예제 #5
0
def LRTPathFinder(G, StartPt, EndStation):
    """To path find the StartStation to the Endstation, this will return a path or array of node to node edge function.
    In order for the Function to return the path, the path will find until the node is 50 metres from the endStation
    This Function uses Breadth-First Search but of queue, it utilises 2 arrays as there is only 2 direction that LRT can go"""
    firstLoop = False

    StartNode = ox.get_nearest_edge(G, StartPt)
    StartNode = StartNode[1]
    LRTRoute1 = []
    LRTRoute1.append(StartNode)
    LRTRoute2 = []
    LRTRoute2.append(StartNode)
    while True:
        if (firstLoop == False):
            for i in G[StartNode]:
                if (len(LRTRoute1) == 1):
                    LRTRoute1.append(i)

                elif (len(LRTRoute2) == 1):
                    LRTRoute2.append(i)

            firstLoop = True
        else:
            for nei, etc in G[LRTRoute1[-1]].items():
                if (nei not in LRTRoute1):
                    LRTRoute1.append(nei)
                    if (getDirectDistance(G, EndStation, nei) < 0.05):
                        return LRTRoute1
            for i in G[LRTRoute2[-1]]:
                if (i not in LRTRoute2):
                    LRTRoute2.append(i)
                    if (getDirectDistance(G, EndStation, i) < 0.05):
                        return LRTRoute2
예제 #6
0
def test_find_nearest():

    # get graph
    G = ox.graph_from_point(location_point, dist=500, network_type="drive")

    # get nearest node
    nn, d = ox.get_nearest_node(G, location_point, method="euclidean", return_dist=True)

    # get nearest nodes: haversine, kdtree, balltree
    gdf_nodes = ox.graph_to_gdfs(G, edges=False)
    X = gdf_nodes["x"].head()
    Y = gdf_nodes["y"].head()

    nn1, dist1 = ox.get_nearest_nodes(G, X, Y, return_dist=True)
    nn2, dist2 = ox.get_nearest_nodes(G, X, Y, method="kdtree", return_dist=True)
    nn3, dist3 = ox.get_nearest_nodes(G, X, Y, method="balltree", return_dist=True)
    nn4 = ox.get_nearest_nodes(G, X, Y)
    nn5 = ox.get_nearest_nodes(G, X, Y, method="kdtree")
    nn6 = ox.get_nearest_nodes(G, X, Y, method="balltree")

    # get nearest edge
    u, v, k, g, d = ox.get_nearest_edge(G, location_point, return_geom=True, return_dist=True)

    # get nearest edges: haversine, kdtree, balltree
    ne1 = ox.get_nearest_edges(G, X, Y)
    ne2 = ox.get_nearest_edges(G, X, Y, method="kdtree")
    ne3 = ox.get_nearest_edges(G, X, Y, method="balltree", dist=0.0001)
예제 #7
0
파일: test_osmnx.py 프로젝트: gboeing/osmnx
def test_nearest_edge():

    # test in closest edge section
    sheik_sayed_dubai = [25.09, 25.06, 55.16, 55.11]
    location_coordinates = (25.071764, 55.138978)
    G = ox.graph_from_bbox(*sheik_sayed_dubai, simplify=False, retain_all=True, network_type='drive')
    geometry, u, v = ox.get_nearest_edge(G, location_coordinates)
예제 #8
0
def test_nearest_edge():

    # test in closest edge section
    sheik_sayed_dubai = [25.09, 25.06, 55.16, 55.11]
    location_coordinates = (25.071764, 55.138978)
    G = ox.graph_from_bbox(*sheik_sayed_dubai, simplify=False, retain_all=True, network_type='drive')
    geometry, u, v = ox.get_nearest_edge(G, location_coordinates)
def nearest_edge(G, i):
    """

    :param G:       NetworkX graph.
                    Geographic scenario

    :param i:       tuple
                    collect point coordinates

    :param keys:    list
                    list with id of adjacent nodes

    :return:        tuple, list
                    tuple with coordinates of adjacent nodes
                    list with id of adjacent nodes
    """
    keys = [0, 0]

    keys[0], keys[1], key, shapely, distance_ = ox.get_nearest_edge(
        G, i, return_geom=True, return_dist=True)
    # edges_array = ox.get_nearest_nodes(G, np.array([i[1]]), np.array([i[0]]), method='kdtree')

    attribute_x = nx.get_node_attributes(G, 'x')
    attribute_y = nx.get_node_attributes(G, 'y')

    lon_node1 = attribute_x.get(keys[0])
    lat_node1 = attribute_y.get(keys[0])
    lon_node2 = attribute_x.get(keys[1])
    lat_node2 = attribute_y.get(keys[1])

    coordinates = [(lat_node1, lon_node1), (lat_node2, lon_node2)]

    return coordinates, keys
예제 #10
0
def test_find_nearest():

    # get graph
    G = ox.graph_from_point(location_point, dist=500, network_type="drive")

    # convert graph to node/edge GeoDataFrames and back again
    gdf_nodes, gdf_edges = ox.graph_to_gdfs(
        G, nodes=True, edges=True, node_geometry=True, fill_edge_geometry=True
    )
    assert len(gdf_nodes) == len(G)
    assert len(gdf_edges) == len(G.edges(keys=True))
    G = ox.graph_from_gdfs(gdf_nodes, gdf_edges)
    assert len(gdf_nodes) == len(G)
    assert len(gdf_edges) == len(G.edges(keys=True))

    # get nearest node
    nn, d = ox.get_nearest_node(G, location_point, method="euclidean", return_dist=True)

    # get nearest nodes: haversine, kdtree, balltree
    X = gdf_nodes["x"].head()
    Y = gdf_nodes["y"].head()
    nn1 = ox.get_nearest_nodes(G, X, Y)
    nn2 = ox.get_nearest_nodes(G, X, Y, method="kdtree")
    nn3 = ox.get_nearest_nodes(G, X, Y, method="balltree")

    # get nearest edge
    u, v, k, g, d = ox.get_nearest_edge(G, location_point, return_geom=True, return_dist=True)

    # get nearest edges: haversine, kdtree, balltree
    ne1 = ox.get_nearest_edges(G, X, Y)
    ne2 = ox.get_nearest_edges(G, X, Y, method="kdtree")
    ne3 = ox.get_nearest_edges(G, X, Y, method="balltree", dist=0.0001)
        def get_closest_node(self,G ):
            nodes, _ = ox.graph_to_gdfs(G)

            geom, u, v, marosca = ox.get_nearest_edge(G, (self.lat, self.lng))
            nn = min((u, v), key=lambda n: ox.great_circle_vec(self.lat, self.lng, G.nodes[n]['y'], G.nodes[n]['x']))

            return G.nodes[nn]['x'], G.nodes[nn]['y']
 def remove_edge(self, coords, time):
     nr_edge = ox.get_nearest_edge(self.graph, (coords[0], coords[1]))
     u, v = nr_edge[1], nr_edge[2]
     key_del = max(self.graph[u][v], key=int)
     edge_attributes = self.graph[u][v][key_del]
     self.graph.remove_edge(u, v, key=key_del)
     self.damaged_edges.append([(u, v, edge_attributes), time])
예제 #13
0
    def update_camera(self, name: str, latlon: Tuple[float, float],
                      metadata: Dict = {},
                      max_intersection_dist: float = 5,
                      max_lane_dist: float = 5) -> Tuple[bool, bool]:
        """
        return Tuple(a: bool, b: bool): a indicates whether the camera is
        successfully added to the road network. b indicates whether the
        topology has changed.
        """
        # We simply remove the existing camera and calculate the new
        # position. And topology_change is always true if success.
        # TODO: decide whether the topology actually changes.
        if name in self.cameraInfo:
            self.remove_camera(name)

        success = False
        nearest_node, dist = ox.get_nearest_node(self.G, latlon, return_dist=True)
        if dist < max_intersection_dist:
            self.node_camera.add_camera(nearest_node, name)
            success = True
        else:
            u, v, key, dist = ox.get_nearest_edge(self.G, latlon, return_dist=True)
            if dist < max_lane_dist:
                self.edge_camera.add_camera((u, v, key), name, latlon)
                success = True

        if success:
            self.cameraInfo[name] = {'latlon': latlon, 'meta': metadata}
        return success, success
예제 #14
0
 def line_to_nodes_precise(graph, tram_line):
     """
     Method uses line_to_nodes and adds not covered stops
     It turned out that line_to_nodes does not cover all the line
     This method fix this issue
     :param graph: MultiDiGraph
     :param tram_line: TramLine object
     :return: list of nodes
     """
     nodes = GraphConverter.line_to_nodes(graph, tram_line.default_route)
     sub_graph = graph.subgraph(nodes)
     # Make MultiLineString or LineString object (if MultiLineString can be merged)
     current_route = GraphConverter.route_to_line_string(sub_graph)
     stops = tram_line.stops
     # Check if current route contains stop
     for stop in stops:
         # If it does omit the rest
         if current_route.contains(stop):
             continue
         # If not get the nearest edge
         nr_edge = ox.get_nearest_edge(graph, (stop.y, stop.x))
         # If nearest edge from stops contains stop we can add nodes of this edge to the list
         # Note: If route is connected graph it is obvious that each stop is contained in one of the edges
         # but If route is not connected then nearest edge of the stop could return some unwanted edge
         if nr_edge[0].contains(stop):
             if nr_edge[1] not in nodes:
                 nodes.append(nr_edge[1])
             if nr_edge[2] not in nodes:
                 nodes.append(nr_edge[2])
     return nodes
예제 #15
0
    def get_nearestedge_node(self, osm_id, rG, bG):
        """
        Using OMSNX data,
        get the coordinates from bus stop,
        get the nearest edge on the road,
        return the node of either end which is nearer to bus stop
        """
        # with the use of osmid get the nearest node to the start and end coordinates
        temp_y = bG.nodes.get(osm_id).get('y')
        temp_x = bG.nodes.get(osm_id).get('x')
        temp_nearest_edge = ox.get_nearest_edge(rG, (temp_y, temp_x))
        temp_1 = temp_nearest_edge[0].coords[0]
        temp_2 = temp_nearest_edge[0].coords[1]
        temp1_x = temp_1[0]
        temp1_y = temp_1[1]
        # calculate the distance by calling the haversine function with the haversine formula
        temp_1_distance = self.haversine(temp1_y, temp1_x, temp_y, temp_x)

        temp2_x = temp_2[0]
        temp2_y = temp_2[1]
        # calculate the distance by calling the haversine function with the haversine formula
        temp_2_distance = self.haversine(temp2_y, temp2_x, temp_y, temp_x)
        if temp_1_distance < temp_2_distance:
            return temp_nearest_edge[1]
        else:
            return temp_nearest_edge[2]
예제 #16
0
def findPath(G, paths):
    startTime = time.time()

    listOfNodes = []  # Stored as [ (lat, lon, BusStopCode) ] format
    listOfTuplesStartEndLatLon = [
    ]  # Stored as [ ((Start1 lat, Start1 lon) , (End2 lat, End2 lon)) ] format
    route = []  # Routes to travel from [Route Start1 to End 2]format

    with open('data/Punggol_Bus_Stops.json') as bus_stop:
        data = json.load(bus_stop)

        # Complexity of O(n^2) n number of paths, n number of busstops in .json
        for i in paths:
            for x in data['punggolBusStops']:
                if i == int(x['BusStopCode']):
                    tempTuple = (x['Latitude'], x['Longitude'],
                                 x['BusStopCode'])
                    listOfNodes.append(tempTuple)
                    break

    # Retriving the long and lat of the nodes
    # Complexity of O(n) n number of nodes
    for i in range(len(listOfNodes)):
        if i != (len(listOfNodes) - 1):
            listOfTuplesStartEndLatLon.append(
                ((float(listOfNodes[i][0]), float(listOfNodes[i][1])),
                 (float(listOfNodes[i + 1][0]), float(listOfNodes[i + 1][1]))))

    # Retriving of all routes(edges) to plot route
    # Complexity of O(n) n number of tuples of StartEnds
    for i in range(len(listOfTuplesStartEndLatLon)):
        route.extend(
            nx.shortest_path(G, (ox.get_nearest_edge(
                G, (listOfTuplesStartEndLatLon[i][0][0],
                    listOfTuplesStartEndLatLon[i][0][1])))[2],
                             (ox.get_nearest_edge(
                                 G,
                                 (listOfTuplesStartEndLatLon[i][1][0],
                                  listOfTuplesStartEndLatLon[i][1][1])))[2]))

    route = removeDupes(route)

    endTime = time.time()

    print("Bus Route Retrieval Takes: ", round((endTime - startTime), 2))

    return route
예제 #17
0
    def get_closest_node(self, lng, lat):

        geom, u, v, marosca = ox.get_nearest_edge(self.G, (lat, lng))
        nn = min((u, v),
                 key=lambda n: ox.great_circle_vec(lat, lng, self.G.nodes[n][
                     'y'], self.G.nodes[n]['x']))

        #print("random_point: "+lat+" , "+lng)

        return self.G.nodes[nn]['osmid']
예제 #18
0
def add_split_edge_to_graph(G, point):
    n_edge = ox.get_nearest_edge(G, (point.y, point.x))
    n_node = get_closest_point_on_line(n_edge[0], point)
    split_line = get_split_lines(n_edge[0], n_node)
    if (split_line[0].coords[0] == n_edge[0].coords[0]):
        G.add_edge(n_edge[1], 1, key=n_edge[3], geometry=split_line[0])
        G.add_edge(1, n_edge[2], key=n_edge[3], geometry=split_line[1])
    else:
        G.add_edge(n_edge[1], 1, key=n_edge[3], geometry=split_line[1])
        G.add_edge(1, n_edge[2], key=n_edge[3], geometry=split_line[0])
    return G, n_edge
예제 #19
0
 def _find_nearest_edges_ride(self, lats, lons):
     edge_prev = -2
     edge_list = []
     for lat, lon in zip(lats, lons):
         if edge_prev == -2:
             edge_prev = -1
             edge = osmnx.get_nearest_edge(self.graph, (lat, lon))[1:]
         else:
             if edge != edge_prev:
                 # get nodes of edge and its neighbors to induce relevant subgraph
                 nodes_list = [[node, *list(self.graph.neighbors(node))]
                               for node in edge]
                 # flatten list
                 nodes_list = set(
                     [node for sublist in nodes_list for node in sublist])
                 # find point on subgraph of neighbors of last point#
                 subgraph = self.graph.subgraph(nodes_list)
             edge_prev = edge
             edge = osmnx.get_nearest_edge(subgraph, (lat, lon))[1:]
         edge_list.append(edge)
     return pd.Series(edge_list)
예제 #20
0
    def get_random_node(self):
        nodes, _ = ox.graph_to_gdfs(self.G)
        lng = random.uniform(nodes['x'].min(), nodes['x'].max())
        lat = random.uniform(nodes['y'].min(), nodes['y'].max())

        geom, u, v, marosca = ox.get_nearest_edge(self.G, (lat, lng))
        nn = min((u, v),
                 key=lambda n: ox.great_circle_vec(lat, lng, self.G.nodes[n][
                     'y'], self.G.nodes[n]['x']))

        #print("random_point: "+lat+" , "+lng)

        return self.G.nodes[nn]['x'], self.G.nodes[nn]['y']
예제 #21
0
 def get_nearestedge_node(osm_id, y, x):
     temp_nearest_edge = ox.get_nearest_edge(G, (y, x))
     temp_1 = temp_nearest_edge[0].coords[0]
     temp_2 = temp_nearest_edge[0].coords[1]
     temp1_x = temp_1[0]
     temp1_y = temp_1[1]
     temp_1_distance = calculate_H(temp1_y, temp1_x, y, x)
     temp2_x = temp_2[0]
     temp2_y = temp_2[1]
     temp_2_distance = calculate_H(temp2_y, temp2_x, y, x)
     if temp_1_distance < temp_2_distance:
         return [temp_nearest_edge[1], temp_1_distance, temp1_x, temp1_y]
     else:
         return [temp_nearest_edge[2], temp_2_distance, temp2_x, temp2_y]
    def test_calculate_bypass(self):
        """
        Do:
            - Foreach route delete at least one edge (could be random)
            - calculate bypas for this route on modified graph
        Expected:
            - New route is displayed
            - User manualy verifies whether new route is correct or not
        """
        dl = DataLoader()
        G = dl.graph
        lines_table = dl.load_all_lines()

        for line in lines_table:
            # Create TramLine object
            tram_line = TramLine(str(line[0]), line[1], dl)
            tram_line.show()
            # Convert line to nodes in order to verify graph before edges deletion
            nodes = GraphConverter.line_to_nodes_precise(G, tram_line)
            sub_graph = G.subgraph(nodes)
            ox.plot_graph(sub_graph)
            # Get stops on this line
            stops = dl.load_tram_stops(
                tram_line.default_route)  # List of shapely objects
            # Get random stops
            # change range to increase or decrease number of deleted edges
            r_stops = [stops[randint(0, len(stops) - 1)] for i in range(3)]
            # Get nearest edges and delete them
            deleted_edges = list()
            for stop in r_stops:
                nr_edge = ox.get_nearest_edge(G, (stop.y, stop.x))
                G.remove_edge(nr_edge[1], nr_edge[2])
                deleted_edges.append(nr_edge)
            # Show route without edges
            sub_graph = G.subgraph(nodes)
            ox.plot_graph(sub_graph)
            # Now calculate bypas
            tram_line.current_route = SubstituteRoute.calculate_bypass(
                G, tram_line)
            print(type(tram_line.current_route))
            tram_line.show()
            for e in deleted_edges:
                G.add_edge(e[1], e[2], geometry=e[0])
        ox.plot_graph(G)
        self.assertTrue(True)
예제 #23
0
def get_path_data():
    # Define polyline lists
    train_polyline = []
    new_polyline = []
    walk_polyline = []
    bus_polyline = []
    info = ""
    transfer = ""

    # Get user input source and destination, mode of transport
    input_src = request.args.get('source', 0, type=str)
    input_dest = request.args.get('dest', 0, type=str)
    transport_mode = request.args.get('transport_mode', type=str)

    # Geocode source and destination to lat lon
    src = do_geocode(input_src)
    dest = do_geocode(input_dest)

    # Set start as list of source lat lon
    start = [src.latitude, src.longitude]
    end = [dest.latitude, dest.longitude]

    # Get nearest nodes for start and end for bus, train and walk
    start_walk = ox.get_nearest_node(G_walk, (src.latitude, src.longitude))
    end_walk = ox.get_nearest_node(G_walk, (dest.latitude, dest.longitude))
    start_train = ox.get_nearest_node(G_train, (src.latitude, src.longitude),
                                      return_dist=True)
    end_train = ox.get_nearest_node(G_train, (dest.latitude, dest.longitude),
                                    return_dist=True)
    start_bus = ox.get_nearest_node(G_bus, (src.latitude, src.longitude),
                                    return_dist=True)
    end_bus = ox.get_nearest_node(G_bus, (dest.latitude, dest.longitude),
                                  return_dist=True)
    # Find nearest start and end train stations
    start_station_det = findingStation((src.latitude, src.longitude))
    end_station_det = findingStation((dest.latitude, dest.longitude))

    # Check if train in same or different loops
    east_bound = 0
    west_bound = 0
    diff_loop = 0
    for n in mrt_nodes:
        mrt_id = n[2]
        # If start station in east loop
        if mrt_id == start_station_det[1] and start_station_det[1] in east:
            east_bound += 1
        # If start station in west loop
        elif mrt_id == start_station_det[1] and start_station_det[1] in west:
            west_bound += 1
        # If end station in east loop
        elif mrt_id == end_station_det[1] and end_station_det[1] in east:
            east_bound += 1
        # If end station in west loop
        elif mrt_id == end_station_det[1] and end_station_det[1] in west:
            west_bound += 1
        elif west_bound == 2 or east_bound == 2:  # both lrt station in the same lrt loop
            print("same loop")
            break
        elif west_bound == 1 and east_bound == 1:  # both lrt station in different lrt loop
            diff_loop = 1
            break
    # =========================================== ALL =========================================== #
    if transport_mode == "all":
        # Check that the nearest train station for both locations is not the same
        if start_station_det[1] != end_station_det[1]:
            # Check if start and end is Punggol (Still same station) -> only do bus or walk
            if (start_station_det[1] == 6587709456 and end_station_det[1]
                    == 6587709457) or (end_station_det[1] == 6587709456
                                       and start_station_det[1] == 6587709457):
                # ====================================== PURELY WALKING ====================================== #
                walk_polyline.append(
                    create_polyline(G_walk, start_walk, end_walk))
            else:
                # Will return heuristic, OSMid, y, x. E.g. (253.48788074253008, 1840734598, 1.4118877, 103.9003304)
                # Starting node always use start_u, for ending node always use end_v
                start_geom, start_u, start_v = ox.get_nearest_edge(
                    G_train, (start_station_det[2], start_station_det[3]))
                end_geom, end_u, end_v = ox.get_nearest_edge(
                    G_train, (end_station_det[2], end_station_det[3]))

                # =========================================== TRAIN =========================================== #
                # if both lrt station found in different loops
                if diff_loop == 1:
                    # retrieving path after running algo
                    path1 = dijkstra(train_edges, start_u, 6587709457)[1]
                    path2 = dijkstra(train_edges, 6587709457, end_v)[1]

                    # convert nodes to coords and appending the coordinate path into new_polyline array
                    swapOrder(ox.node_list_to_coordinate_lines(G_train, path1),
                              new_polyline)
                    swapOrder(ox.node_list_to_coordinate_lines(G_train, path2),
                              new_polyline)

                # if both lrt station found in same loop
                else:
                    # retrieving path after running algo
                    path = dijkstra(train_edges, start_u, end_v)[1]

                    # convert nodes to coords and appending the coordinate path into new_polyline array
                    swapOrder(ox.node_list_to_coordinate_lines(G_train, path),
                              new_polyline)

                # checking if start point is more than 200m from start lrt station
                if start_train[1] > 400:
                    # finding nearest bus stop at lrt start station
                    slrt_busstop = ox.get_nearest_node(
                        G_bus, (start_station_det[2], start_station_det[3]))

                    # run bus algo to take bus from start point to lrt start station
                    start_line, sbus_info, sbus_path = bus_route(
                        start_bus[0], slrt_busstop, 10)
                    for x in start_line:
                        for y in x:
                            list(y)
                    bus_polyline.append(start_line)

                    # check if start point to start point bus stop is more than 2m.
                    if start_bus[1] > 2:
                        startbuscoord = ()
                        # retrieving the nearest walk node to the bus stop
                        for n in bus_nodes:
                            if n[2] == start_bus[0]:
                                startbuscoord = (n[0], n[1])
                        swalkto_busstop = ox.get_nearest_node(
                            G_walk, startbuscoord)

                        # calculating and plotting walk from end point to bus stop
                        walk_polyline.append(
                            create_polyline(G_walk, start_walk,
                                            swalkto_busstop))

                # start point is less than 200m from start lrt station
                else:
                    # finding nearest walk node to start lrt station
                    slrt_walknode = ox.get_nearest_node(
                        G_walk, (start_station_det[2], start_station_det[3]))
                    walk_polyline.append(
                        create_polyline(G_walk, start_walk, slrt_walknode))

                # checking if end point is more than 200m from end lrt station
                if end_train[1] > 400:
                    # finding nearest bus stop at lrt end station
                    elrt_busstop = ox.get_nearest_node(
                        G_bus, (end_station_det[2], end_station_det[3]))

                    # run bus algo to take bus from end point to lrt end station
                    end_line, ebus_info, ebus_path = bus_route(
                        elrt_busstop, end_bus[0], 10)
                    for x in end_line:
                        for y in x:
                            list(y)
                    bus_polyline.append(end_line)

                    # check if end point to end point bus stop is more than 2m.
                    if end_bus[1] > 2:
                        endbuscoord = ()
                        # retrieving the nearest walk node to the bus stop
                        for n in bus_nodes:
                            if n[2] == end_bus[0]:
                                endbuscoord = (n[0], n[1])
                        ewalkto_busstop = ox.get_nearest_node(
                            G_walk, endbuscoord)

                        # calculating and plotting walk from end point to bus stop
                        walk_polyline.append(
                            create_polyline(G_walk, ewalkto_busstop, end_walk))

                # end point is less than 200m from start lrt station
                else:
                    # finding nearest walk node to end lrt station
                    elrt_walknode = ox.get_nearest_node(
                        G_walk, (end_station_det[2], end_station_det[3]))
                    walk_polyline.append(
                        create_polyline(G_walk, elrt_walknode, end_walk))

                # appending train plot
                train_polyline.append(new_polyline)

        # nearest start and end lrt station is the same, hence walk.
        else:
            walk_polyline.append(create_polyline(G_walk, start_walk, end_walk))
    # =========================================== WALK =========================================== #
    elif transport_mode == "walk":
        walk_polyline.append(create_polyline(G_walk, start_walk, end_walk))

    # =========================================== MRT =========================================== #
    elif transport_mode == "mrt":
        # Check that the nearest train station for both locations is not the same
        if start_station_det[1] != end_station_det[1]:
            # Check if start and end is Punggol (Still same station) -> only do bus or walk
            if (start_station_det[1] == 6587709456 and end_station_det[1]
                    == 6587709457) or (end_station_det[1] == 6587709456
                                       and start_station_det[1] == 6587709457):
                # ====================================== PURELY WALKING ====================================== #
                walk_polyline.append(
                    create_polyline(G_walk, start_walk, end_walk))
            else:
                start_geom, start_u, start_v = ox.get_nearest_edge(
                    G_train, (start_station_det[2], start_station_det[3]))
                end_geom, end_u, end_v = ox.get_nearest_edge(
                    G_train, (end_station_det[2], end_station_det[3]))
                # =========================================== TRAIN =========================================== #
                if diff_loop == 1:
                    path1 = dijkstra(train_edges, start_u, 6587709457)[1]
                    path2 = dijkstra(train_edges, 6587709457, end_v)[1]
                    train_coords1 = ox.node_list_to_coordinate_lines(
                        G_train, path1)
                    swapOrder(train_coords1, new_polyline)
                    train_coords2 = ox.node_list_to_coordinate_lines(
                        G_train, path2)
                    swapOrder(train_coords2, new_polyline)

                else:
                    path = dijkstra(train_edges, start_u, end_v)[1]
                    train_coords = ox.node_list_to_coordinate_lines(
                        G_train, path)
                    swapOrder(train_coords, new_polyline)

                # =========================================== WALK + MRT =========================================== #
                if start_train[1] > 10:
                    to_mrt = ox.get_nearest_node(
                        G_walk, (start_station_det[2], start_station_det[3]))
                    walk_polyline.append(
                        create_polyline(G_walk, start_walk, to_mrt))

                if end_train[1] > 10:
                    from_mrt = ox.get_nearest_node(
                        G_walk, (end_station_det[2], end_station_det[3]))
                    walk_polyline.append(
                        create_polyline(G_walk, from_mrt, end_walk))

                train_polyline.append(new_polyline)
        else:
            # ====================================== PURELY WALKING ====================================== #
            walk_polyline.append(create_polyline(G_walk, start_walk, end_walk))
    # =========================================== BUS =========================================== #
    elif transport_mode == "bus":
        # Get user input cost option for bus
        cost_option = request.args.get('cost_option', 0, type=str)

        # If user chooses to plot shortest path for bus
        if cost_option == "sp":
            cost = 0
        # User choose to plot bus with least transfers
        else:
            cost = 10

        # Check that the nearest bus stop for both locations is not the same
        if start_bus[0] != end_bus[0]:
            line_string, bus_info, bus_path = bus_route(
                start_bus[0], end_bus[0], cost)
            for x in line_string:
                for y in x:
                    list(y)
            bus_polyline.append(line_string)
            # =========================================== WALK + BUS =========================================== #
            if start_bus[1] > 5:
                for n in bus_nodes:
                    if n[2] == start_bus[0]:
                        to_bus = ox.get_nearest_node(G_walk, (n[0], n[1]))
                walk_polyline.append(
                    create_polyline(G_walk, start_walk, to_bus))

            if end_bus[1] > 5:
                for n in bus_nodes:
                    if n[2] == end_bus[0]:
                        from_bus = ox.get_nearest_node(G_walk, (n[0], n[1]))
                walk_polyline.append(
                    create_polyline(G_walk, from_bus, end_walk))
            info = "Number of transfers: " + str(
                bus_info[0][2] - 1) + "<br>Total Distance: " + str(
                    round((bus_info[0][1]), 2)) + "km"
            transfer = "<br>Bus Route:<br>"
            for x in bus_path:
                transfer += "Bus No.: " + x[0] + " " + x[1] + " " + x[
                    2] + "<br>"

        else:
            # ====================================== PURELY WALKING ====================================== #
            walk_polyline.append(create_polyline(G_walk, start_walk, end_walk))

    # Return coordinates, address and polyline for plotting
    return jsonify(start=start,
                   start_road=input_src,
                   end=end,
                   end_road=input_dest,
                   train_path=train_polyline,
                   walk_path=walk_polyline,
                   bus_path=[bus_polyline],
                   bus_info=info,
                   bus_transfer=transfer)
예제 #24
0
def get_cr_from_osm(coordinates):
    """ Get rolling coefficient (cr) from osm surface attribute

    1) Determine nearest osm edge for each coordinate
    2) Determine surface attribute for each osm edge
    3) Get rolling coefficient (cr) for the corresponding surface type from literature

    Hint: function will take some time when coordinates have a large spatial extent.

    Parameters
    ----------
    coordinates: list of tuples (latitude, longitude)
        coordinates

    Returns
    -------
    [cr, surface]: list of numpy arrays
        first array are rolling coefficient (cr) values and second array are surface attributes
    """

    # TODO: Improve performance
    # TODO: Check scientific literature for rolling coefficient values

    lats = [coordinate[0] for coordinate in coordinates]
    lngs = [coordinate[1] for coordinate in coordinates]

    min_y = np.min(lats)
    max_y = np.max(lats)
    min_x = np.min(lngs)
    max_x = np.max(lngs)

    ox.settings.useful_tags_way = ["surface"]

    print(
        'Get graph from bounding box: min_y={}, max_y={}, min_x={}, max_x={}'.
        format(min_y, max_y, min_x, max_x))
    graph = ox.graph_from_bbox(max_y,
                               min_y,
                               max_x,
                               min_x,
                               network_type='drive')

    surface = []
    cr = []
    i = 0

    print(
        'Find nearest osm edge and set rolling coefficient according to the surface type of the edge.'
    )
    for lat, lng in coordinates:

        x = ox.get_nearest_edge(graph, (lat, lng))
        p = [x[0], x[1]]
        a = ox.utils_graph.get_route_edge_attributes(graph, p)
        dic = a[0]

        if "surface" in dic:
            surface.append(dic["surface"])
        else:
            surface.append(None)

        # Get the rolling resistance coefficient
        # Sources
        # https://www.engineeringtoolbox.com/rolling-friction-resistance-d_1303.html
        # The Automotive Chassis book
        if surface[i] == "asphalt":
            cr.append(0.02)
        elif surface[i] == "cobblestone":
            cr.append(0.015)
        elif surface[i] == "paving_stones":
            cr.append(0.033)
        else:
            cr.append(0.02)
        i = i + 1

    return [np.array(cr), np.array(surface)]
예제 #25
0
import osmnx as ox
G = ox.graph_from_bbox(12.867853,
                       12.842623,
                       77.803543,
                       77.775726,
                       network_type='drive')
geom, u, v = ox.get_nearest_edge(G, (12.855777, 77.783582))
G_projected = ox.project_graph(G)

print(geom, u, v)
print(G_projected.edges())
ox.plot_graph(G_projected)
예제 #26
0
    return closest_point


def get_split_lines(line: LineString, point: Point) -> List[LineString]:
    """Splits a line at nearest intersecting point.
    Returns:
        A list containing two LineString objects.
    """
    snap_line = snap(line, point, 0.01)
    result = split(snap_line, point)
    if (len(result) < 2):
        print('Error in splitting line at point: only one line in the result')
    return result


n_edge = ox.get_nearest_edge(graph_proj,
                             (point.y, point.x))  #get nearest edge to poi

n_node = get_closest_point_on_line(n_edge[0],
                                   point)  #get nearest node on that edge

split_line = get_split_lines(n_edge[0],
                             n_node)  #split the edge at that node into 2 lines

fig, ax = ox.plot_graph(graph_proj,
                        node_color='#999999',
                        show=False,
                        close=False)
ax.scatter(point.x, point.y, c='r', marker='x')
ax.scatter(nn.x, nn.y, c='g', marker='x')
#un-comment any 1 of the 3 below to visualize that line
#x, y = n_edge[0].xy
예제 #27
0
    def fuel_consumption(car:car, osmbox:BboxSelector, track_df = gpd.GeoDataFrame()):
        # Request elevation values from an open source (opentopodata.org)
        url = 'https://api.opentopodata.org/v1/eudem25m?locations='
        tracks = pd.DataFrame(columns=track_df.columns)

        # Add surface in get attribute method
        ox.settings.useful_tags_way = ['bridge', 'tunnel', 'oneway', 'lanes', 'ref', 'name','highway', 'maxspeed', 'service', 'access', 'area','landuse', 'width', 'est_width', 'junction', 'surface']
        # get the osm graph for the same area
        G = ox.graph_from_bbox(osmbox.max_y, osmbox.min_y, osmbox.max_x, osmbox.min_x, network_type='drive')  

        # get the number of routes in the dataframe
        n = 0
        a = track_df['track.id'].value_counts()
        for i in a:
            n+=1
        # loop through the dataframe and get the elevation from open source for each record in each routes   
        for i in range (0,n):
            one_track_id = track_df['track.id'].unique()[i]
            one_track = track_df[track_df['track.id'] == one_track_id]
            # estimate the len of data
            batch = [int(len(one_track)/100),len(one_track)%100]
            elevation=[]
            # get elevation
            for i in range(batch[0]+1):
                #create requeest 100 parameter
                s = i*100
                e = (i+1)*100
                if i<batch[0]+1:
                    --e
                else:
                    e= e+batch[1]
                #check the parameters (s) not excced the lenght of the track
                if s >= len(one_track):
                    break
                #creat the request
                parms= generate_parms(one_track,s,e)
                #send the request and get the results
                access= url+parms
                part = request(access)
                if part==None:
                    part=[np.nan]*(e+1-s)
                #put the results in a list
                elevation.extend(part)
                time.sleep(1)
            one_track['elevation']=elevation
            # Filterout the null value and use GPS altitude to fill them
            temp=one_track[one_track['elevation'].isnull()==True]
            if len(temp)> 0:
                for i in temp.index:
                    one_track.loc[i,'elevation']=one_track.loc[i,'GPS Altitude.value']
            # Match the graph with osm and get maxspeed & surface attriubutes
            ox.settings.useful_tags_way = ["maxspeed","surface"]
            for i in one_track.index:
                lat= one_track.loc[i,'geometry'].y
                lng= one_track.loc[i,'geometry'].x
                x = (ox.get_nearest_edge(G, (lat, lng)))
                p = [x[0],x[1]]
                a = ox.utils_graph.get_route_edge_attributes(G, p)
                dic = a[0]
                # check if the edge has maximum speed value if not then use the value of previous point
                if "maxspeed" in dic:
                    one_track.loc[i,"maxspeed"] = dic["maxspeed"]
                else:
                    if i > 0:
                        m = one_track.loc[i-1,"maxspeed"]
                        one_track.loc[i,"maxspeed"] = m
                        
                # check if the edge has a surface value, if not then use the value of previous point    
                if "surface" in dic:
                    one_track.loc[i,"surface"] = dic["surface"]
                else:
                    if i > 0:
                        s = one_track.loc[i-1,"surface"]
                        one_track.loc[i,"surface"] =  s
                    

                # get the rolling resistance cofficient
                if one_track.loc[i, 'surface'] == "asphalt":
                    one_track.loc[i, 'rolling_resistance'] = 0.02 # source: engineeringtoolbox.com
                elif one_track.loc[i, 'surface'] == "cobblestone":
                    one_track.loc[i, 'rolling_resistance'] = 0.015 # source: engineeringtoolbox.com
                elif one_track.loc[i, 'surface'] == "paving_stones":
                    one_track.loc[i, 'rolling_resistance'] = 0.033 # source: The Automotive Chassis book
                else:
                    one_track.loc[i, 'rolling_resistance'] = 0.02 
            #loop through the dataframe and calculate the gradient
            for i in one_track.index:
                if (i == len(one_track)-1):
                    break
                # Get the coordinates of each point
                lat1= one_track.loc[i,'geometry'].y
                lat2= one_track.loc[i+1,'geometry'].y
                lon1= one_track.loc[i,'geometry'].x
                lon2= one_track.loc[i+1,'geometry'].x

                #calculate the elevation difference between the two points
                heightdiff = one_track.loc[i+1,'elevation'] - one_track.loc[i,'elevation']

                #calculate the distance between the two points/ and the accumulated distance
                one_track.loc[i+1,'seg_distance']= distance(lon1,lon2,lat1,lat2)
                if i == 0:
                    one_track.loc[i,'total_distance'] = 0
                    one_track.loc[i+1,'total_distance'] = one_track.loc[i+1,'seg_distance']
                else:
                    one_track.loc[i+1,'total_distance']= one_track.loc[i+1,'seg_distance'] + one_track.loc[i,'total_distance']
                grade = gradient(heightdiff,one_track.loc[i+1,'seg_distance'])
                one_track.loc[i,'gradient']= grade

            ## Add interval time
            #get the timestamp column from the track
            track_time = one_track[['time']]
            #convert the timestamp column to sereis
            time_track = track_time.iloc[:,0]
            #convert the timestamp to data time
            x = pd.to_datetime(time_track)
            x_list = x.tolist()
            #calculate the time difference in second, and put it in a list
            time_interval = []
            for i in range(len(x_list)):
                if i == 0 :
                    time_in_second = 0
                    one_track.loc[i,'accumulate_time_interval'] = time_in_second
                else:
                    time_in_second = ((x_list[i] - x_list[i-1]).total_seconds())
                    one_track.loc[i,'accumulate_time_interval'] = time_in_second + one_track.loc[i-1,'accumulate_time_interval']
                    
                time_interval.append(time_in_second)
            # add the time interval list to the track
            one_track['time_interval']=time_interval
        
            # Convert the speed unit to m/s
            for i in one_track.index:
                one_track.loc[i, 'speed'] = one_track.loc[i, 'GPS Speed.value'] / 3.6

            # calculate the acceleration

            for i in one_track.index:
                if (i == len(one_track)-1):
                    break
                else:
                    one_track.loc[i, 'Acceleration'] = (one_track.loc[i+1, 'speed'] - one_track.loc[i, 'speed'])/one_track.loc[i,'time_interval']

            ## Calculates Engine Power for general car
            for i in one_track.index:
                ep = engine_power(car,one_track.rolling_resistance[i],one_track.gradient[i],one_track.speed[i],one_track.Acceleration[i])
                if ep[0] < 0:
                    one_track.loc[i, 'engine_power'] = car.P_idle
                    one_track.loc[i, 'driving_resistance'] = ep[1]
                else:
                    one_track.loc[i, 'engine_power'] = ep[0]
                    one_track.loc[i, 'driving_resistance'] = ep[1]
            ## Driving resistance
            for i in one_track.index:
                res = one_track.loc[i, 'driving_resistance']
                if (res >= 2000 or res <= -2000):
                    one_track.loc[i,'efficiency'] = 0.3
                else:
                    one_track.loc[i, 'efficiency'] = interpolation(res)

            ## Fuel consumption/CO2 emissions for General car (gasoline)
            for i in one_track.index:
                car_cons = fuel_consumptions(one_track.engine_power[i],car, one_track.loc[i,'efficiency'])
                one_track.loc[i, 'Consumption_Gasoline'] = car_cons   ## liters / hour
                one_track.loc[i, 'CO2_Gasoline'] = car_cons * car.H_g      ## kg Co2 / hour
            
            tracks = pd.concat([tracks, one_track])
            tracks = tracks[['elevation','accumulate_time_interval','maxspeed','Acceleration','surface','rolling_resistance','gradient','efficiency','Consumption_Gasoline','CO2_Gasoline']]

            
        return tracks
예제 #28
0
 def get_nearest_edge(self, coord):
     return ox.get_nearest_edge(self.graph, coord[::-1])
예제 #29
0
def lrt_bus_walk(graph, initial, dest, lrt_graph):

    # DISCLAIMER: function deprecated, leaving here for history's sake
    """
    :param graph: NetworkX multigraph for walking.
    :param initial: Starting node in X Y tuple. Pretty much is always punggol mrt.
    :param dest: Destination node in X Y tuple.
    :param lrt_graph: NetworkX multigraph consisting of only LRT nodes and edges.
    :return: returns finalRoues[] which consists of multiple (just 2) routes in an array
    """
    """
    essentially a redo of lrt movement, but with bus
    adds a bus route should the an additional taking of bus from the LRT is required
    movement pseudo:
    Start > LRT_start > LRT_end
    if distance to destination > some_distance
        LRT_end > bus_start > bus_end > walk to destination
    else
        LRT_end > walk to destination
    """

    finalRoutes = []  # will return this.

    # CURRENT LAYER: foot
    # now, we are at Punggol MRT.
    # We want to look for the closest LRT to the destination.

    endLRT = 0
    endLRTXY = 0
    lowest_dist = 5000  # dummy value.

    # loop through the LRT map and find the node that is closest to the destination with distance()
    for stn, d in lrt_graph.nodes(data=True):
        if 'ref' in d:
            # look at only valid stops - i.e nodes with a 'ref'
            stnXY = (lrt_graph.nodes[stn]['x'], lrt_graph.nodes[stn]['y'])
            print("|TEST| - Right now at Station ", stn, " coordinates: ",
                  stnXY)
            curr_dist = distance(stnXY, dest)

            if curr_dist < lowest_dist:
                endLRT = stn
                endLRTXY = stnXY
                lowest_dist = curr_dist

    # CURRENT LAYER: lrt stations (real)
    # we know what LRT we want to go to
    # but real lrt stations are not actually connected together (in the graph)
    # so instead, we go to the closest connected node to it

    print("|TEST| - Closest real station to destination: ", endLRT, "at ",
          endLRTXY)
    closestEndLrt = ox.get_nearest_edge(lrt_graph, (endLRTXY[1], endLRTXY[0]))
    print("|TEST| - Connected ending node is : ",
          closestEndLrt[1])  # this is the node that's actually in the network
    # if using 103.9064504, 1.3988214 as end node, this should be Cove LRT
    # if using 103.9164448, 1.399601, this should be Kadaloor LRT
    wayID = 0

    # get id of the LRT route we are in
    for (u, v, d) in lrt_graph.edges(data=True):
        if u == closestEndLrt[1]:
            wayID = d['osmid']
            break

    print("|TEST| - OSM-ID of the proper LRT route is : ", wayID)

    # way ID of the LRT route we want to take has been acquired.

    # CURRENT LAYER: lrt stations (fake)
    # we now have a good connected dest. we now want to travel to that node.
    # but we need to figure out which connected node to start from (in Punggol)
    # that node must be in the same graph as the dest node
    # Punggol station is NOT a connected node. there are multiple nodes in Punggol station itself

    closestStartLrt = 0
    lowest_dist = 5000

    for (u, v, d) in lrt_graph.edges(data=True):
        if d['osmid'] == wayID:
            # get XY of the node in the lrt route
            stnXY = (lrt_graph.nodes[u]['x'], lrt_graph.nodes[u]['y'])
            curr_dist = distance(stnXY, initial)

            if curr_dist < lowest_dist:
                closestStartLrt = u
                # closestStartLrtXY = stnXY
                lowest_dist = curr_dist

    print("|TEST| - Connected starting node is: ", closestStartLrt)

    # traverse to that node from startLRT to endLRT
    lrt_g = Graph()

    for i in lrt_graph.edges.data():
        length = i[2].get('length')
        lrt_g.add_edge(*(i[0], i[1], length))  # node1, node2, length

    lrtRoute = dijsktra(lrt_g, closestStartLrt, closestEndLrt[1])[0]

    # to do - figure out how to make sure correct LRT route is taken for dijkstra
    print("|TEST| - Now taking LRT from ", closestStartLrt, " to ",
          closestEndLrt[1])

    print("|TEST| - LRT route: ", lrtRoute)
    lrtRouteYX = getRouteInYX(lrt_graph, lrtRoute)
    print("|TEST| - LRT route in YX (returns this): ", lrtRouteYX)

    finalRoutes.append(lrtRouteYX)

    # CURRENT LAYER: lrt stations (fake)
    # user has now ARRIVED at the connected lrt node.
    # we still have the real LRT destination node in endLRT (and endLRTXY for coord)
    # pop the user to the closest foot node.
    # start dijkstra from that foot node.

    # but if destination is still a good distance away (3200m, 400m, etc)
    # have the user take a bus instead
    if (distance(endLRTXY, dest) > 100):  # if dest is far enough
        # endLRTXY = (endLRTXY[1], endLRTXY[0])
        busRoute = []
        #busRoute = walk_bus_algor(endLRTXY, dest)  # DEPRECATED, no longer used, this code exists in walk_bus.py
        print("Bus route: ", busRoute)
        for x in busRoute:
            finalRoutes.append(x)
        return finalRoutes
    else:
        walkingStart = ox.get_nearest_node(graph, (endLRTXY[1], endLRTXY[0]))
        print("|TEST| - Now walking from: ", walkingStart,
              "(LRT) to destination ", dest)

        cGraph = Graph()

        for i in graph.edges.data():
            length = i[2].get('length')
            cGraph.add_edge(*(i[0], i[1], length))

        destID = ox.get_nearest_node(graph, (dest[1], dest[0]))

        walkingRoute = dijsktra(cGraph, walkingStart, destID)[0]
        print("|TEST| - Walking route: ", walkingRoute)
        print("|TEST| - End: ", destID, dest)

        finalRoutes.append(walkingRoute)
        return finalRoutes
예제 #30
0
def get_lrt_route(graph, initial, dest, lrt_graph, lrt_exits):
    """
    :param graph: NetworkX multigraph for walking.
    :param initial: Starting node in X Y tuple. Pretty much is always punggol mrt.
    :param dest: Destination node in X Y tuple.
    :param lrt_graph: NetworkX multigraph consisting of only LRT nodes and edges.
    :return: returns finalRoues[] which consists of multiple (just 2) routes in an array
    """
    """
    essentially a redo of lrt movement, but with bus
    by right supposed to check for bus if node is far enough, but most nodes aren't far enough lol
    """

    # CURRENT LAYER: foot
    # now, we are at Punggol MRT.
    # We want to look for the closest LRT to the destination.

    endLRT = 0
    endLRTXY = 0
    lowest_dist = 5000  # dummy value.

    # loop through the LRT map and find the node that is closest to the destination with distance()
    for stn, d in lrt_graph.nodes(data=True):
        if 'ref' in d:
            # look at only valid stops - i.e nodes with a 'ref'
            stnXY = (lrt_graph.nodes[stn]['x'], lrt_graph.nodes[stn]['y'])
            print("|TEST| - Right now at Station ", stn, " coordinates: ",
                  stnXY)
            curr_dist = distance(stnXY, dest)

            if curr_dist < lowest_dist:
                endLRT = stn
                endLRTXY = stnXY
                lowest_dist = curr_dist

    # CURRENT LAYER: lrt stations (real)
    # we know what LRT we want to go to
    # but real lrt stations are not actually connected together (in the graph)
    # so instead, we go to the closest connected node to it

    print("|TEST| - Closest real station to destination: ", endLRT, "at ",
          endLRTXY)
    closestEndLrt = ox.get_nearest_edge(lrt_graph, (endLRTXY[1], endLRTXY[0]))
    print("|TEST| - Connected ending node is : ",
          closestEndLrt[1])  # this is the node that's actually in the network
    # if using 103.9064504, 1.3988214 as end node, this should be Cove LRT
    # if using 103.9164448, 1.399601, this should be Kadaloor LRT
    wayID = 0

    # get id of the LRT route we are in
    for (u, v, d) in lrt_graph.edges(data=True):
        if u == closestEndLrt[1]:
            wayID = d['osmid']
            break

    print("|TEST| - OSM-ID of the proper LRT route is : ", wayID)

    # way ID of the LRT route we want to take has been acquired.

    # CURRENT LAYER: lrt stations
    # we now have a good connected dest. we now want to travel to that node.
    # but we need to figure out which connected node to start from (in Punggol)
    # that node must be in the same graph as the dest node

    closestStartLrt = 0
    lowest_dist = 5000

    for (u, v, d) in lrt_graph.edges(data=True):
        if d['osmid'] == wayID:
            # get XY of the node in the lrt route
            stnXY = (lrt_graph.nodes[u]['x'], lrt_graph.nodes[u]['y'])
            curr_dist = distance(stnXY, initial)

            if curr_dist < lowest_dist:
                closestStartLrt = u
                # closestStartLrtXY = stnXY
                lowest_dist = curr_dist

    print("|TEST| - Connected starting node is: ", closestStartLrt)

    # traverse to that node from startLRT to endLRT
    lrt_g = Graph()

    for i in lrt_graph.edges.data():
        length = i[2].get('length')
        lrt_g.add_edge(*(i[0], i[1], length))  # node1, node2, length

    # use dijkstra to acquire the best
    # graph is simple so dijkstra is not immediately the most useful
    lrtRoute = dijsktra(lrt_g, closestStartLrt, closestEndLrt[1])[0]

    # time complexity of dijkstra is O(n^2), where n is the amount of nodes.
    # the amount of LRT stations in punggol is negligible, so performance isn't a big issue.

    # to do - figure out how to make sure correct LRT route is taken for dijkstra
    print("|TEST| - Now taking LRT from ", closestStartLrt, " to ",
          closestEndLrt[1])

    print("|TEST| - LRT route: ", lrtRoute)
    lrtRouteYX = getRouteInYX(lrt_graph, lrtRoute)
    print("|TEST| - LRT route in XY (returns this): ", lrtRouteYX)

    # CURRENT LAYER: lrt stations
    # user has now ARRIVED at the lrt node.
    # we want to now bring the user to the closest foot path

    # most LRTs have a 'bridge' that connects to ground level via stairs/bridges
    # greedily find the closest bridge-end/stairs to the LRT
    # if distance() shows that the bridge is too far, (e.g Sam Kee station has no bridges)
    #   it's not considered to be an immediately linked bridge.
    # but if it is,
    #   then add XY to the paths array.

    exit = ox.get_nearest_node(lrt_exits, (endLRTXY[1], endLRTXY[0]))
    exitXY = (lrt_exits.nodes[exit]['x'], lrt_exits.nodes[exit]['y'])

    # after this, the user will be ready to start walking towards their destination

    if distance(exitXY, (endLRTXY)) > 100:
        # too far. just use current XY as last stop.
        print("|TEST| - Exit of ", exitXY, " is too far ,",
              distance(exitXY, (endLRTXY)), " disregarding exit.")
        return lrtRouteYX
    else:
        # use the exit as the last XY for routing purposes. flips exitXY to match the program.
        lrtRouteYX.append((exitXY[1], exitXY[0]))
        print("|TEST| - Adding X,Y of exit ", (exitXY[1], exitXY[0]),
              " to LRT route.")

    return lrtRouteYX
def load_PEMS(num_train=250, dtype=np.float64):
    #unzip daata
    with zipfile.ZipFile('data/PEMS.zip', 'r') as zip_ref:
        zip_ref.extractall('data')
    # Data reading
    with open('data/PEMS/adj_mx_bay.pkl', 'rb') as f:
        sensor_ids, sensor_id_to_ind, _ = pickle.load(f, encoding='latin1')
    all_signals = pd.read_hdf('data/PEMS/pems-bay.h5')
    coords = pd.read_csv('data/PEMS/graph_sensor_locations_bay.csv',
                         header=None)

    # Loading real world graph of roads
    north, south, east, west = 37.450, 37.210, -121.80, -122.10
    if not os.path.isfile('data/PEMS/bay_graph.pkl'):
        cf = '["highway"~"motorway|motorway_link"]'  # Road filter, we don't use small ones.
        G = osmnx.graph_from_bbox(north=north,
                                  south=south,
                                  east=east,
                                  west=west,
                                  simplify=True,
                                  custom_filter=cf)
        with open(
                'data/PEMS/bay_graph.pkl',
                'wb') as f:  # frequent loading of maps leads to a temporal ban
            pickle.dump(G, f)
    else:
        with open('data/PEMS/bay_graph.pkl', 'rb') as f:
            G = pickle.load(f)

    G = osmnx.get_undirected(G)  # Matern GP supports only undirected graphs.

    # Graph cleaning up
    for _ in range(2):
        out_degree = G.degree
        to_remove = [node for node in G.nodes if out_degree[node] == 1]
        G.remove_nodes_from(to_remove)
    G = nx.convert_node_labels_to_integers(G)
    G.remove_nodes_from([372, 286])
    G = nx.convert_node_labels_to_integers(G)

    num_points = len(sensor_ids)

    np_coords = np.zeros((num_points, 2))  # Vector of sensors coordinates.
    for i in range(num_points):
        sensor_id, x, y = coords.iloc[i]
        ind = sensor_id_to_ind[str(int(sensor_id))]
        np_coords[ind][0], np_coords[ind][1] = x, y
    coords = np_coords

    sensor_ind_to_node = {}
    # Inserting sensors into a graph. During insertion, the edge containing the sensor is cut
    for point_id in range(num_points):
        sensor_ind_to_node[point_id] = len(G)  # adding new vertex at the end
        sensor_point = Point(coords[point_id, 1], coords[point_id, 0])
        u, v, key, geom = osmnx.get_nearest_edge(
            G, (sensor_point.y, sensor_point.x), return_geom=True)
        edge = G.edges[(u, v, key)]
        G.remove_edge(u, v, key)
        edge_1_geom, edge_2_geom = cut(geom, geom.project(sensor_point))
        l_ratio = geom.project(sensor_point, normalized=True)
        l_1, l_2 = l_ratio * edge['length'], (1 - l_ratio) * edge['length']
        new_vertex = nearest_points(geom, sensor_point)[0]
        G.add_node(len(G), x=new_vertex.x, y=new_vertex.y)
        G.add_edge(u, len(G) - 1, length=l_1, geometry=edge_1_geom)
        G.add_edge(len(G) - 1, v, length=l_2, geometry=edge_2_geom)

    # Weights are inversely proportional to the length of the road
    lengths = nx.get_edge_attributes(G, 'length')
    lengths_list = [length for length in lengths.values()]
    mean_length = np.mean(lengths_list)
    weights = {}
    for edge, length in lengths.items():
        weights[edge] = mean_length / length
    nx.set_edge_attributes(G, values=weights, name='weight')

    # Sorry for that,
    # sensor_ind - sensor id in California database, sensor_id - local numeration (from 1 to num of sensors)
    sensor_id_to_node = {}
    for sensor_ind, node in sensor_ind_to_node.items():
        sensor_id = sensor_ids[sensor_ind]
        sensor_id_to_node[sensor_id] = node

    # Selecting signals at some moment
    signals = all_signals[(all_signals.index.weekday == 0)
                          & (all_signals.index.hour == 17) &
                          (all_signals.index.minute == 30)]

    # Dataset creation
    x, y = [], []
    for i in range(len(signals)):
        for sensor_id in sensor_ids:
            if sensor_id_to_node.get(sensor_id) is not None:
                node = sensor_id_to_node[sensor_id]
                signal = signals.iloc[i][int(sensor_id)]
                x.append([i, node])
                y.append([signal])

    x, y = np.asarray(x, dtype=dtype), np.asarray(y, dtype=dtype)
    x, y = x[:num_points, 1:], y[:num_points]

    # Splitting data into train and test
    random_perm = np.random.permutation(np.arange(x.shape[0]))
    train_vertex, test_vertex = random_perm[:num_train], random_perm[
        num_train:]
    x_train, x_test = x[train_vertex], x[test_vertex]
    y_train, y_test = y[train_vertex], y[test_vertex]

    return G, (x_train, y_train), (x_test, y_test), (x, y)