Example #1
0
    def sub_end_matching(self, path):
        lgth = len(path)
        i = 0
        vmap = dict()
        for v in path:
            i += 1
            vmap[v] = i

        mlist = set()
        for i in range(0,lgth):
            begin = path.begin
            end = path.end
            beginc = path.c2
            endc = path.c1
            
            p1 = Path(self.graph, 3, beginc)
            p.add_vertex(begin)
            
            va = begin
            vertex = multigraph.get_vertex(va)
            color = 3
            alt_color = beginc

            while True:
                edge = vertex.get_neighbor_edge_by_color(color)
                if edge is None:
                    break

                vb = edge.get_another_vertex(va)
                if vb not in path:
                    break

                p.add_vertex(vb)
                va = vb
                vertex = self.graph.get_vertex(va)
                color, alt_color = alt_color, color

            p2 = Path(self.graph, 3, endc)
            p.add_vertex(end)
            
            va = end
            vertex = multigraph.get_vertex(va)
            color = 3
            alt_color = endc

            while True:
                edge = vertex.get_neighbor_edge_by_color(color)
                if edge is None:
                    break

                vb = edge.get_another_vertex(va)
                if vb not in path:
                    break

                p.add_vertex(vb)
                va = vb
                vertex = self.graph.get_vertex(va)
                color, alt_color = alt_color, color
Example #2
0
def construct_path(rn, mm_traj, routing_weight):
    """
    construct the path of the map matched trajectory
    Note: the enter time of the first path entity & the leave time of the last path entity is not accurate
    :param rn: the road network
    :param mm_traj: the map matched trajectory
    :param routing_weight: the attribute name to find the routing weight
    :return: a list of paths (Note: in case that the route is broken)
    """
    paths = []
    path = []
    mm_pt_list = mm_traj.pt_list
    start_idx = len(mm_pt_list) - 1
    # find the first matched point
    for i in range(len(mm_pt_list)):
        if mm_pt_list[i].data['candi_pt'] is not None:
            start_idx = i
            break
    pre_edge_enter_time = mm_pt_list[start_idx].time
    for i in range(start_idx + 1, len(mm_pt_list)):
        pre_mm_pt = mm_pt_list[i - 1]
        cur_mm_pt = mm_pt_list[i]
        # unmatched -> matched
        if pre_mm_pt.data['candi_pt'] is None:
            pre_edge_enter_time = cur_mm_pt.time
            continue
        # matched -> unmatched
        pre_candi_pt = pre_mm_pt.data['candi_pt']
        if cur_mm_pt.data['candi_pt'] is None:
            path.append(
                PathEntity(pre_edge_enter_time, pre_mm_pt.time,
                           pre_candi_pt.eid))
            if len(path) > 2:
                paths.append(
                    Path(mm_traj.oid, get_pid(mm_traj.oid, path), path))
            path = []
            continue
        # matched -> matched
        cur_candi_pt = cur_mm_pt.data['candi_pt']
        # if consecutive points are on the same road, cur_mm_pt doesn't bring new information
        if pre_candi_pt.eid != cur_candi_pt.eid:
            weight_p, p = find_shortest_path(rn, pre_candi_pt, cur_candi_pt,
                                             routing_weight)
            # cannot connect
            if p is None:
                path.append(
                    PathEntity(pre_edge_enter_time, pre_mm_pt.time,
                               pre_candi_pt.eid))
                if len(path) > 2:
                    paths.append(
                        Path(mm_traj.oid, get_pid(mm_traj.oid, path), path))
                path = []
                pre_edge_enter_time = cur_mm_pt.time
                continue
            # can connect
            if nx.is_directed(rn):
                dist_to_p_entrance = rn.edges[rn.edge_idx[
                    pre_candi_pt.eid]]['length'] - pre_candi_pt.offset
                dist_to_p_exit = cur_candi_pt.offset
            else:
                entrance_vertex = p[0]
                pre_edge_coords = rn.edges[rn.edge_idx[
                    pre_candi_pt.eid]]['coords']
                if (pre_edge_coords[0].lng,
                        pre_edge_coords[0].lat) == entrance_vertex:
                    dist_to_p_entrance = pre_candi_pt.offset
                else:
                    dist_to_p_entrance = rn.edges[rn.edge_idx[
                        pre_candi_pt.eid]]['length'] - pre_candi_pt.offset
                exit_vertex = p[-1]
                cur_edge_coords = rn.edges[rn.edge_idx[
                    cur_candi_pt.eid]]['coords']
                if (cur_edge_coords[0].lng,
                        cur_edge_coords[0].lat) == exit_vertex:
                    dist_to_p_exit = cur_candi_pt.offset
                else:
                    dist_to_p_exit = rn.edges[rn.edge_idx[
                        cur_candi_pt.eid]]['length'] - pre_candi_pt.offset
            if routing_weight == 'length':
                total_dist = weight_p
            else:
                dist_inner = 0.0
                for i in range(len(p) - 1):
                    start, end = p[i], p[i + 1]
                    dist_inner += rn[start][end]['length']
                total_dist = dist_inner + dist_to_p_entrance + dist_to_p_exit
            delta_time = (cur_mm_pt.time - pre_mm_pt.time).total_seconds()
            # two consecutive points matched to the same vertex
            if total_dist == 0:
                pre_edge_leave_time = cur_mm_pt.time
                path.append(
                    PathEntity(pre_edge_enter_time, pre_edge_leave_time,
                               pre_candi_pt.eid))
                cur_edge_enter_time = cur_mm_pt.time
            else:
                pre_edge_leave_time = pre_mm_pt.time + timedelta(
                    seconds=delta_time * (dist_to_p_entrance / total_dist))
                path.append(
                    PathEntity(pre_edge_enter_time, pre_edge_leave_time,
                               pre_candi_pt.eid))
                cur_edge_enter_time = cur_mm_pt.time - timedelta(
                    seconds=delta_time * (dist_to_p_exit / total_dist))
                sub_path = linear_interpolate_path(
                    p, total_dist - dist_to_p_entrance - dist_to_p_exit, rn,
                    pre_edge_leave_time, cur_edge_enter_time)
                path.extend(sub_path)
            pre_edge_enter_time = cur_edge_enter_time
    # handle last matched similar to (matched -> unmatched)
    if mm_pt_list[-1].data['candi_pt'] is not None:
        path.append(
            PathEntity(pre_edge_enter_time, mm_pt_list[-1].time,
                       mm_pt_list[-1].data['candi_pt'].eid))
        if len(path) > 2:
            paths.append(Path(mm_traj.oid, get_pid(mm_traj.oid, path), path))
    return paths