Exemple #1
0
    def calc_direction(self, start: Point, end: Point) -> float:
        dx = ox.great_circle_vec(start.lat, start.lon, start.lat,
                                 end.lon) * np.sign(end.lon - start.lon)

        dy = ox.great_circle_vec(start.lat, start.lon, end.lat,
                                 start.lon) * np.sign(end.lat - start.lat)

        return np.arctan2(dx, dy) * 180 / np.pi
Exemple #2
0
def distance_to_edge(network,
                     edge,
                     point,
                     method=EdgeDistanceMethod.farthest_node):
    """
    Calculate the distance of a given point to an edge of the network (road segment)

    Parameters
    ---------
    network : nx.MultiDiGraph
        street network

    edge : Edge
        network edge

    point : point
        point

    method : EdgeDistanceMethod
        metric used to compute distance to edge

    Returns
    -------
    float
        distance from point to edge according to distance metric
    """
    distance_node_from = ox.great_circle_vec(
        lat1=point.lat,
        lng1=point.lng,
        lat2=network.node[edge.u]['y'],
        lng2=network.node[edge.u]['x'],
        earth_radius=earth_radius(unit=Units.m))

    distance_node_to = ox.great_circle_vec(
        lat1=point.lat,
        lng1=point.lng,
        lat2=network.node[edge.v]['y'],
        lng2=network.node[edge.v]['x'],
        earth_radius=earth_radius(unit=Units.m))

    distances = [distance_node_to, distance_node_from]

    if method == EdgeDistanceMethod.closest_node:
        return min(distances)

    elif method == EdgeDistanceMethod.farthest_node:
        return max(distances)

    elif method == EdgeDistanceMethod.sum_of_distances:
        return sum(distances)

    elif method == EdgeDistanceMethod.mean_of_distances:
        return statistics.mean(distances)

    else:
        raise ValueError("Invalid method for computing edge distance")
Exemple #3
0
def as_lvector(origin, point):
    """
    Represents a Point as a vector in a (local) cartesian coordinate system, where another Point is the origin.

    Consider the case of a traffic camera and nearby nodes in the road network (junctions). A nearby node can be represented as a Point with polar coordinates (r,phi), where the camera is the origin, r is the distance between the camera and the node, and phi is the bearing between the two (basis used in navigation: the 0 degrees axis is drawn vertically upwards and the angle increases for clockwise rotations). Edges (roads) in the network can be represented by vector addition. For that purpose, the point is converted and returned in cartesian coordinates, in the standard basis.

    Parameters
    ----------
    origin : Point
        point used as origin in the new coordinate system

    point : Point
        target Point to be represented in the new coordinate system

    Returns
    -------
    np.ndarray
        vector representing the target Point in the new (local) cartesian coordinate system

    """
    r = ox.great_circle_vec(lat1=origin.lat,
                            lat2=point.lat,
                            lng1=origin.lng,
                            lng2=point.lng,
                            earth_radius=earth_radius(Units.m))

    phi = ox.get_bearing(origin, point)

    x = r * math.cos(np.deg2rad(90 - phi))
    y = r * math.sin(np.deg2rad(90 - phi))

    return np.array([x, y])
        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']
Exemple #5
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']
Exemple #6
0
def sort_by_dist(net, start_node, nodes):
    '''
    Function to sort the nodes as distance from the start node 
    '''
    dist_diff = lambda end_node: ox.great_circle_vec(
        net.nodes[start_node]['y'], net.nodes[start_node]['x'], net.nodes[
            end_node]['y'], net.nodes[end_node]['x'])

    G_sort = sorted(nodes, key=dist_diff)

    return G_sort
Exemple #7
0
    def __init__(self, start: Point, end: Point, length_start: float) -> None:
        self.start = start
        self.end = end
        self.length_start = length_start

        self.length: float = ox.great_circle_vec(start.lat, start.lon, end.lat,
                                                 end.lon)
        self.length_end = self.length_start + self.length
        self.vector = Point(lat=self.end.lat - self.start.lat,
                            lon=self.end.lon - self.start.lon)
        self.direction = self.calc_direction(start, end)
Exemple #8
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']
def compute_distance(source_coordinates: tuple, target_coordinates: tuple):
    """
    This method computes the double-precision floating-point straight-line distance between two nodes.
    :param source_coordinates: coordinates of the source node (longitude, latitude)
    :param target_coordinates: coordinates of the target node (longitude, latitude)
    :return: float
    """

    # extracting nodes coordinates
    source_longitude, source_latitude = source_coordinates
    target_longitude, target_latitude = target_coordinates

    # calculating the length of the edge
    return np.round(
        ox.great_circle_vec(source_latitude, source_longitude, target_latitude,
                            target_longitude), 2)
Exemple #10
0
def test_filter_by_address_and_get_local_coordinate_system():
    network = get_network(distance = 1000)
    address = "Pitt Street, Newcastle Upon Tyne, UK"
    point = core.Point(lat = 54.974537, lng = -1.625644)

    nn_ids, nn_distances = core.get_nodes_in_range(network, [point], 100)
    nn_edges = core.get_edges_in_range(network, nn_ids)[0]

    all_nodes = { edge[0] for edge in nn_edges } | \
                { edge[1] for edge in nn_edges }

    assert len(all_nodes) > len(nn_ids[0])

    candidate_edges = core.filter_by_address(network, nn_edges, address)

    assert len(candidate_edges) < len(nn_edges)

    candidate_nodes = { edge[0] for edge in candidate_edges } | \
                      { edge[1] for edge in candidate_edges }

    nodes_lvectors, edges_lvectors = \
        core.local_coordinate_system(
            network = network,
            origin = point,
            nodes = candidate_nodes,
            edges = candidate_edges)

    assert len(nodes_lvectors) == len(candidate_nodes)
    assert len(edges_lvectors) == len(candidate_edges)

    for id in candidate_nodes:
        ox_distance = ox.great_circle_vec(
            lat1 = network.node[id]['y'],
            lng1 = network.node[id]['x'],
            lat2 = point.lat,
            lng2 = point.lng)

        lvector = nodes_lvectors[id]
        lvector_distance = math.sqrt(lvector[0] ** 2 + lvector[1] ** 2)

        np.testing.assert_almost_equal(
            ox_distance,
            lvector_distance,
            decimal = 6)
Exemple #11
0
def get_partial_link_sequence(trip, graph, link_mapper):
    '''
    Function that takes a trip's GPS polyline vector and trasforms it into
    a list of corresponding links travelled as well as proportion of the link travelled.
    Uses most of the functions defined above.

    Parameters:
    -----------
    trip (pandas series): trip data
    graph (networkx multidigraph): road network of interest
    link_mapper (dictionary): see simple_link_mapper()

    Returns:
    --------
    simple_partial_link_sequence (array): sequence of simplified links traversed by the taxi for that trip

    '''
    gps_trip_list = json.loads(trip.POLYLINE)
    node_data = return_node_data(graph)
    edge_data = return_edge_data(graph)
    edges_in_graph = return_edges_in_graph(graph)
    # initialise array to store our partial link sequence
    partial_link_sequence = []
    # start off the algorithm with the first set of GPS points
    start_long = gps_trip_list[0][0]
    start_lat = gps_trip_list[0][1]
    prev_node_1, prev_node_2, prev_location = map_matcher(
        start_long, start_lat, edges_in_graph)
    if prev_node_1 == False:
        # means map_matching has failed
        return partial_link_sequence
    prev_link_dist = edge_data[get_edge_name(prev_node_1,
                                             prev_node_2)]['length']
    for gps_pair in gps_trip_list[1:]:
        longitude = gps_pair[0]
        latitude = gps_pair[1]
        # find where we are now
        current_node_1, current_node_2, current_location = map_matcher(
            longitude, latitude, edges_in_graph)
        if current_node_1 == False:
            # means map_matching has failed
            return return_simple_partial_link_sequence(partial_link_sequence,
                                                       link_mapper)
        # if we're still on the same link:
        if (current_node_1, current_node_2) == (prev_node_1, prev_node_2):
            lat1 = prev_location[1]
            lng1 = prev_location[0]
            lat2 = current_location[1]
            lng2 = current_location[0]
            distance_travelled = ox.great_circle_vec(lat1, lng1, lat2, lng2)
            # work out proportion of road travelled
            alpha = distance_travelled / prev_link_dist
            partial_link_sequence.append([
                (get_edge_name(current_node_1, current_node_2), alpha)
            ])
            # now just update previous values to be current ones in preparation for next GPS point
            prev_node_1, prev_node_2, prev_location = current_node_1, current_node_2, current_location
        elif set([current_node_1, current_node_2]) != set(
            [prev_node_1, prev_node_2]):
            # i.e. we are on a completely new non-adjacent link to the previous link
            link_sequence = []
            alpha = []
            # first work out how much we had to travel to leave previous link
            lat1 = prev_location[1]
            lng1 = prev_location[0]
            lat2 = node_data[prev_node_2]['lat']
            lng2 = node_data[prev_node_2]['long']
            lat3 = node_data[prev_node_1]['lat']
            lng3 = node_data[prev_node_1]['long']
            lat4 = current_location[1]
            lng4 = current_location[0]
            lat5 = node_data[current_node_1]['lat']
            lng5 = node_data[current_node_1]['long']
            # we don't know if the car left through prev_node_2 or prev_node_1
            # so we will estimate this by saying that the closest node to the current
            # location is the node that the taxi passed out the previous link from
            if ox.great_circle_vec(lat4, lng4, lat2,
                                   lng2) < ox.great_circle_vec(
                                       lat4, lng4, lat3, lng3):
                # means we went through prev_node_2
                distance_travelled_prev_link = ox.great_circle_vec(
                    lat1, lng1, lat2, lng2)
                alpha.append(distance_travelled_prev_link / prev_link_dist)
                link_sequence.append(get_edge_name(prev_node_1, prev_node_2))
                # work out links that must have been traversed from prev_node_2 to current_node_1
                try:
                    route = nx.shortest_path(graph,
                                             prev_node_2,
                                             current_node_1,
                                             weight='length')
                except nx.NetworkXNoPath:
                    # happens sometimes when we can't find a path - don't know why
                    route = []
                if len(route) > 0:
                    for node_index in range(0, len(route) - 1):
                        link = get_edge_name(route[node_index],
                                             route[node_index + 1])
                        link_sequence.append(link)
                        alpha.append(1)

                # Now deal with final link that's partially traversed
                link_sequence.append(
                    get_edge_name(current_node_1, current_node_2))
                current_link_dist = edge_data[get_edge_name(
                    current_node_1, current_node_2)]['length']
                distance_travelled = ox.great_circle_vec(
                    lat4, lng4, lat5, lng5)
                alpha.append(distance_travelled / current_link_dist)
                partial_link_sequence.append(list(zip(link_sequence, alpha)))
                # prev values update
                prev_node_1, prev_node_2, prev_location = current_node_1, current_node_2, current_location
                prev_link_dist = current_link_dist
            else:
                # means we went through prev_node_1
                distance_travelled_prev_link = ox.great_circle_vec(
                    lat1, lng1, lat3, lng3)
                alpha.append(distance_travelled_prev_link / prev_link_dist)
                link_sequence.append(get_edge_name(prev_node_1, prev_node_2))
                # work out links that must have been traversed from prev_node_1 to current_node_1
                try:
                    route = nx.shortest_path(graph,
                                             prev_node_2,
                                             current_node_1,
                                             weight='length')
                except nx.NetworkXNoPath:
                    # happens sometimes when we can't find a path - don't know why
                    route = []
                if len(route) > 0:
                    for node_index in range(0, len(route) - 1):
                        link = get_edge_name(route[node_index],
                                             route[node_index + 1])
                        link_sequence.append(link)
                        alpha.append(1)

                # Now deal with final link that's partially traversed
                link_sequence.append(
                    get_edge_name(current_node_1, current_node_2))
                current_link_dist = edge_data[get_edge_name(
                    current_node_1, current_node_2)]['length']
                distance_travelled = ox.great_circle_vec(
                    lat4, lng4, lat5, lng5)
                alpha.append(distance_travelled / current_link_dist)
                # prev values update
                prev_node_1, prev_node_2, prev_location = current_node_1, current_node_2, current_location
                prev_link_dist = current_link_dist

        else:
            # This means that car must now be on adjacent link to
            # previous link with common node current_node_1
            alpha = []
            # first calculate how much road was left to travel on previous link
            lat1 = prev_location[1]
            lng1 = prev_location[0]
            lat2 = node_data[current_node_1]['lat']
            lng2 = node_data[current_node_1]['long']
            distance_travelled_prev_link = ox.great_circle_vec(
                lat1, lng1, lat2, lng2)
            alpha.append(distance_travelled_prev_link / prev_link_dist)
            # now add how much was travelled in current link
            lat1 = current_location[1]
            lng1 = current_location[0]
            lat2 = node_data[current_node_1]['lat']
            lng2 = node_data[current_node_1]['long']
            current_link_dist = edge_data[get_edge_name(
                current_node_1, current_node_2)]['length']
            distance_travelled_current_link = ox.great_circle_vec(
                lat1, lng1, lat2, lng2)
            alpha.append(distance_travelled_current_link / current_link_dist)
            # now add these two to the partial link sequence
            partial_link_sequence.append([
                (get_edge_name(prev_node_1, prev_node_2), alpha[0]),
                (get_edge_name(current_node_1, current_node_2), alpha[1])
            ])
            # update prev values
            prev_node_1, prev_node_2, prev_location = current_node_1, current_node_2, current_location
            prev_link_dist = current_link_dist

    # now turn this partial link sequence into partial link sequence of the simple links of network
    simple_partial_link_sequence = return_simple_partial_link_sequence(
        partial_link_sequence, link_mapper)

    return simple_partial_link_sequence
def great_circle_vec_check_for_nan(y0, x0, y1, x1):
    dist = ox.great_circle_vec(y0, x0, y1, x1)
    if math.isnan(dist):
        dist = 0.0
    return dist
Exemple #13
0
ax.set_ylabel('Logitude')
ax.set_xlabel('Latitude')
ax.legend(['Route'])
fig.tight_layout()
fig

# In[10]:

# display the length of the path
route = nx.shortest_path_length(G, orig_node, dest_node, weight='length')
route

# In[11]:

# how far is it between these two nodes as the crow flies?
ox.great_circle_vec(30.72331046, 76.7449385, 30.70527403, 76.73457478)

# In[12]:

#save the graph
ox.save_graphml(G, filename='Chandigarh.graphml')

# In[13]:

#load the graph
G = ox.load_graphml('Chandigarh.graphml')

# In[18]:

#read the supply and demand points
file = 'demand2.xlsx'  #CHANGED: 'demand_compiled.xlsx'
Exemple #14
0
def haversine(lat1, lng1, lat2, lng2):
    dist = ox.great_circle_vec(lat1, lng1, lat2, lng2, earth_radius=6371009)
    return dist
                         MAX_emiss_key] > emiss_prob[MAX_emiss_key]:
                     # max_prob_node.append(MAX_trans_key)
                     max_prob_node.append(MAX_emiss_key)
                 else:
                     max_prob_node.append(MAX_trans_key)
             else:
                 if MAX_trans_key != MAX_emiss_key:
                     # max_prob_node.append(MAX_trans_key)
                     # distance between Max_key and the GPS track (in Km)
                     lat = float(
                         viasat.latitude[viasat.ID == track_list[i]])
                     lon = float(
                         viasat.longitude[viasat.ID == track_list[i]])
                     distance_MAX_key_to_track = ox.great_circle_vec(
                         lat1=grafo.nodes[MAX_emiss_key]['y'],
                         lng1=grafo.nodes[MAX_emiss_key]['x'],
                         lat2=lat,
                         lng2=lon) / 1000
                     max_prob_node.append(MAX_emiss_key)
                 else:
                     max_prob_node.append(MAX_trans_key)
         if MAX_trans_key not in adjacency_list[track_list[i + 1]]:
             break
 # check if the first GPS track is assigned to a node
 if track_list[i] == 0:
     if MAX_trans_key == 0 or MAX_emiss_key == 0:
         # get nearest node to the GPS track along the same edge
         lat = float(viasat.latitude[viasat.ID == track_list[i]])
         lon = float(viasat.longitude[viasat.ID == track_list[i]])
         point = (lat, lon)
         geom, u, v = ox.get_nearest_edge(grafo, point)
    def calculateBus(self, starttransit,endtransit, start_node, end_node, origin, dest, cost_per_transfer):
        startBsCode ,startname, startx, starty = starttransit[0], starttransit[1], starttransit[2], starttransit[3]
        endBsCode ,endname,endx,endy = endtransit[0], endtransit[1], endtransit[2], endtransit[3]
        #calculate busRoute using dijkstra for bus
        distances, transfers, path = dijkstra_for_bus(startBsCode,endBsCode,self.busedges, cost_per_transfer)
        #get bus stop coordinates
        bscoord = []
        directions = ""
        previous_service = ""
        #convert bus ID into coordinates and get directions append to directions variable
        for code, service in path: 
            try:
                bscoord.append([self.BusStops[code]['lat'],self.BusStops[code]['lon'],self.BusStops[code]['name']])
                if service == None:
                    directions +=  "\nBus:\nFrom " + self.BusStops[code]['name'] + ", Board bus " 
                else:
                    if endBsCode == code:
                        directions += "Alight at " + self.BusStops[code]['name'] + "\n"
                    elif previous_service == "" and service[0] != previous_service:
                        previous_service = service[0]
                        directions += service[0] + "\n" + self.BusStops[code]['name'] + "\n" 
                    elif service[0] != previous_service and previous_service != "":
                        previous_service = service[0]
                        directions += "\nSwitch to bus " + service[0] + " at " + self.BusStops[code]['name'] + "\n"
                    else:
                        directions += self.BusStops[code]['name'] + "\n"
            #check if node is in the graph, else continue. usually means node out of bounds from the area of punggol
            except KeyError as e:
                continue
        
        nearnode = []
        #get all nearest edges from busstops in IDs based on their coordinates in bscoord
        for item in bscoord:
            cod = (item[0],item[1])
            geom, u, v = ox.get_nearest_edge(self.G, cod)
            nn = min((u, v), key=lambda n: ox.great_circle_vec(cod[0],cod[1], self.G.nodes[n]['y'], self.G.nodes[n]['x']))
            nearnode.append(int(nn))
            
        osmid = []
        #Using osmnx library, connect all edges together to form a bus route
        for number in range(1, len(nearnode)):
            try:
                route = nx.shortest_path(self.drivegraph, source = nearnode[number-1], target = nearnode[number])
                #append array of id(route) into osmid
                osmid += route
            except:
                return [], [], [], "Bus goes out of map, Please try another method." , 0, 0
         
                
        converted_OSM_to_Coord = []
        #convert all id into coordinates
        for each in osmid:
            try:
                converted_OSM_to_Coord.append([self.Gnodes[each]['y'],self.Gnodes[each]['x']])
            except KeyError as e:
                continue 

        #get shortest path of first part walk from source to nearest busstop before switching graph
        bs_fh_coord = (startx,starty)
        bs_first_half = ox.get_nearest_node(self.walkgraph,bs_fh_coord, method = 'haversine')
        pathfirst, firsthalfdist = dijkstra(str(start_node),str(bs_first_half),self.walkedges,self.walknodes)
        #covert ID into readable addresses for directions
        firstHalfDirection = "Walk:\nHead towards " + convertToAddress(origin,bs_fh_coord,pathfirst, self.walknodes)
        #Convert all IDs into coordinates
        pathfirst = convertToCoord(pathfirst,self.walknodes)
        pathfirst.insert(0,list(origin))
        pathfirst.append(list(converted_OSM_to_Coord[0]))
        
         #get shortest path of Last part walk from End busstop to Destination
        bs_eh_coord = (endx,endy)
        bs_endhalf = ox.get_nearest_node(self.walkgraph,bs_eh_coord, method = 'haversine')
        endpath, secondhalfdist = dijkstra(str(bs_endhalf),str(end_node),self.walkedges,self.walknodes)
        secondHalfDirection = "\nWalk:\nContinue towards " + convertToAddress(bs_eh_coord,dest,endpath, self.walknodes)
        endpath = convertToCoord(endpath,self.walknodes)
        endpath.insert(0, list(converted_OSM_to_Coord[-1]))
        endpath.append(list(dest))

        #return coordinates for first part walk, bus coordinates, second part walk, directions, disntance and number of transfers
        return pathfirst, converted_OSM_to_Coord, endpath, firstHalfDirection + directions + secondHalfDirection , int((distances*1000) + firsthalfdist +secondhalfdist), transfers