def cal_candidate_point(raw_pt, rn, edge):
    """
    Get attributes of candidate point
    """
    u, v = edge
    coords = rn[u][v][
        'coords']  # GPS points in road segment, may be larger than 2
    candidates = [
        project_pt_to_segment(coords[i], coords[i + 1], raw_pt)
        for i in range(len(coords) - 1)
    ]
    idx, (projection, coor_rate, dist) = min(enumerate(candidates),
                                             key=lambda x: x[1][2])
    # enumerate return idx and (), x[1] --> () x[1][2] --> dist. get smallest error project edge
    offset = 0.0
    for i in range(idx):
        offset += distance(
            coords[i], coords[i + 1])  # make the road distance more accurately
    offset += distance(
        coords[idx],
        projection)  # distance of road start position and projected point
    if rn[u][v]['length'] == 0:
        rate = 0
        # print(u, v)
    else:
        rate = offset / rn[u][v][
            'length']  # rate of whole road, coor_rate is the rate of coords.
    return CandidatePoint(projection.lat, projection.lng, rn[u][v]['eid'],
                          dist, offset, rate)
Example #2
0
def check_dis_loss(predict, target, trg_len):
    """
    Calculate MAE and RMSE between predicted and targeted GPS sequence.
    Args:
    -----
        predict = [seq len, batch size, 2]
        target = [seq len, batch size, 2]
        trg_len = [batch size]  if not considering target length, the loss will smaller than the real one.
        predict and target have been removed sos 
    Returns:
    -------
        MAE of a batch in meter.
        RMSE of a batch in meter.
    """
    predict = predict.permute(1, 0, 2)  # [batch size, seq len, 2]
    target = target.permute(1, 0, 2)  # [batch size, seq len, 2]
    bs = predict.size(0)

    ls_dis = []
    for bs_i in range(bs):
        for len_i in range(trg_len[bs_i] - 1):
            pre = SPoint(predict[bs_i, len_i][0], predict[bs_i, len_i][1])
            trg = SPoint(target[bs_i, len_i][0], target[bs_i, len_i][1])
            dis = distance(pre, trg)
            ls_dis.append(dis)

    ls_dis = np.array(ls_dis)
    mae = ls_dis.mean()
    rmse = np.sqrt((ls_dis**2).mean())
    return mae, rmse
Example #3
0
 def get_distance(pt_list):
     dist = 0.0
     pre_pt = pt_list[0]
     for pt in pt_list[1:]:
         tmp_dist = distance(pre_pt, pt)
         dist += tmp_dist
         pre_pt = pt
     return dist
Example #4
0
    def get_interp_list(self, num_pts, cur_mm_pt, pre_mm_pt, ttl_dis,
                        two_points_eids, two_points_coords, rn_dict):
        interp_list = []
        unit_ts = (cur_mm_pt.time - pre_mm_pt.time) / (num_pts + 1)
        for n in range(int(num_pts)):
            new_time = pre_mm_pt.time + (n + 1) * unit_ts
            move_dis = (ttl_dis /
                        num_pts) * n + pre_mm_pt.data['candi_pt'].offset

            # get eid and offset
            pre_road_dist, road_dist = 0, 0
            for i in range(len(two_points_eids)):
                if i > 0:
                    pre_road_dist += rn_dict[two_points_eids[i - 1]]['length']
                road_dist += rn_dict[two_points_eids[i]]['length']
                if move_dis <= road_dist:
                    insert_eid = two_points_eids[i]
                    insert_offset = move_dis - pre_road_dist
                    break

            # get lat and lng
            dist, pre_dist = 0, 0
            for i in range(len(two_points_coords) - 1):
                if i > 0:
                    pre_dist += distance(two_points_coords[i - 1][0],
                                         two_points_coords[i][0])
                dist += distance(two_points_coords[i][0],
                                 two_points_coords[i + 1][0])
                if dist >= move_dis:
                    coor_rate = (move_dis - pre_dist) / distance(
                        two_points_coords[i][0], two_points_coords[i + 1][0])
                    project_pt = cal_loc_along_line(
                        two_points_coords[i][0], two_points_coords[i + 1][0],
                        coor_rate)
                    break
            data = {
                'candi_pt':
                CandidatePoint(project_pt.lat, project_pt.lng, insert_eid, 0,
                               insert_offset, 0)
            }
            interp_list.append(
                STPoint(project_pt.lat, project_pt.lng, new_time, data))

        return interp_list
Example #5
0
def rate2gps(rn_dict, eid, rate, parameters):
    """
    Convert road rate to GPS on the road segment.
    Since one road contains several coordinates, iteratively computing length can be more accurate.
    Args:
    -----
    rn_dict:
        dictionary of road network
    eid,rate:
        single value from model prediction
    Returns:
    --------
    project_pt:
        projected GPS point on the road segment.
    """
    eid = eid.tolist()  # convert tensor to normal value
    rate = rate.tolist()
    if eid <= 0 or rate < 0 or eid > (parameters.id_size - 1) or rate > 1:
        # force eid and rate in the right range
        return SPoint(0, 0)

    coords = rn_dict[eid]['coords']
    offset = rn_dict[eid]['length'] * rate
    dist = 0  # temp distance for coords
    pre_dist = 0  # coords distance is smaller than offset

    if rate == 1.0:
        return coords[-1]
    if rate == 0.0:
        return coords[0]

    for i in range(len(coords) - 1):
        if i > 0:
            pre_dist += distance(coords[i - 1], coords[i])
        dist += distance(coords[i], coords[i + 1])
        if dist >= offset:
            coor_rate = (offset - pre_dist) / distance(coords[i],
                                                       coords[i + 1])
            project_pt = cal_loc_along_line(coords[i], coords[i + 1],
                                            coor_rate)
            break

    return project_pt
Example #6
0
 def compute_transition_probabilities(self, prev_time_step, time_step, probabilities):
     linear_dist = distance(prev_time_step.observation, time_step.observation)
     for prev_candi_pt in prev_time_step.candidates:
         for cur_candi_pt in time_step.candidates:
             path_dist, path = find_shortest_path(self.rn, prev_candi_pt, cur_candi_pt, self.routing_weight)
             # invalid transition has no transition probability
             if path is not None:
                 time_step.add_road_path(prev_candi_pt, cur_candi_pt, path)
                 time_step.add_transition_log_probability(prev_candi_pt, cur_candi_pt,
                                                          probabilities.transition_log_probability(path_dist,
                                                                                                   linear_dist))
Example #7
0
    def filter(self, traj):
        pt_list = traj.pt_list
        if len(pt_list) <= 1:
            return None

        remove_inds = []
        for i in range(1, len(pt_list) - 1):
            time_span_pre = (pt_list[i].time -
                             pt_list[i - 1].time).total_seconds()
            dist_pre = distance(pt_list[i - 1], pt_list[i])
            time_span_next = (pt_list[i + 1].time -
                              pt_list[i].time).total_seconds()
            dist_next = distance(pt_list[i], pt_list[i + 1])
            speed_pre = dist_pre / time_span_pre
            speed_next = dist_next / time_span_next
            # the first point is outlier
            if i == 1 and speed_pre > self.max_speed > speed_next:
                remove_inds.append(0)
            # the last point is outlier
            elif i == len(
                    pt_list) - 2 and speed_next > self.max_speed >= speed_pre:
                remove_inds.append(len(pt_list) - 1)
            # middle point is outlier
            elif speed_pre > self.max_speed and speed_next > self.max_speed:
                remove_inds.append(i)

        clean_pt_list = []
        for j in range(len(pt_list)):
            if j in remove_inds:
                continue
            clean_pt_list.append(pt_list[j])

        if len(clean_pt_list) > 1:
            # return Trajectory(traj.oid, self.get_tid(traj.oid, pt_list), pt_list)
            return Trajectory(traj.oid, traj.tid, pt_list)
        else:
            return None
Example #8
0
    def filter(self, traj):
        """
        When previous speed and next speed both are larger than max speed, then considering it as outlier.
        Replace outlier with mean value. The range is defined by window size.
        consider about the boundary.
        make sure noise value is in the middle.

        Args:
        -----
        traj:
            Trajectory(). a single trajectory
        Returns:
        --------
        new_traj:
            Trajectory(). replace noise with mean or median
        """
        pt_list = traj.pt_list.copy()
        if len(pt_list) <= 1:
            return None
        for i in range(1, len(pt_list) - 1):
            time_span_pre = (pt_list[i].time -
                             pt_list[i - 1].time).total_seconds()
            dist_pre = distance(pt_list[i - 1], pt_list[i])
            time_span_next = (pt_list[i + 1].time -
                              pt_list[i].time).total_seconds()
            dist_next = distance(pt_list[i], pt_list[i + 1])
            # compute current speed
            speed_pre = dist_pre / time_span_pre
            speed_next = dist_next / time_span_next
            # if the first point is noise
            if i == 1 and speed_pre > self.max_speed > speed_next:
                lat = pt_list[i].lat * 2 - pt_list[i + 1].lat
                lng = pt_list[i].lng * 2 - pt_list[i + 1].lng
                pt_list[0] = STPoint(lat, lng, pt_list[0].time)
            # if the last point is noise
            elif i == len(
                    pt_list) - 2 and speed_next > self.max_speed >= speed_pre:
                lat = pt_list[i - 1].lat * 2 - pt_list[i - 2].lat
                lng = pt_list[i - 1].lng * 2 - pt_list[i - 2].lng
                pt_list[i + 1] = STPoint(lat, lng, pt_list[i].time)
            # if the middle point is noise
            elif speed_pre > self.max_speed and speed_next > self.max_speed:
                pt_list[i] = STPoint(0, 0, pt_list[i].time)
                lats, lngs = [], []
                # fix index bug. make sure index_i is in the middle.
                wind_size = self.win_size
                if self.win_size > i:
                    wind_size = i
                elif self.win_size > len(pt_list) - 1 - i:
                    wind_size = len(pt_list) - 1 - i
                for pt in pt_list[i - wind_size:i + wind_size + 1]:
                    lats.append(pt.lat)
                    lngs.append(pt.lng)

                lat = sum(lats) / (len(lats) - 1)
                lng = sum(lngs) / (len(lngs) - 1)
                pt_list[i] = STPoint(lat, lng, pt_list[i].time)

        if len(pt_list) > 1:
            # return Trajectory(traj.oid, self.get_tid(traj.oid, pt_list), pt_list)
            return Trajectory(traj.oid, traj.tid, pt_list)
        else:
            return None
Example #9
0
def check_rn_dis_loss(predict_gps, predict_id, predict_rate, target_gps,
                      target_id, target_rate, trg_len, rn, raw_rn_dict,
                      new2raw_rid_dict):
    """
    Calculate road network based MAE and RMSE between predicted and targeted GPS sequence.
    Args:
    -----
        predict_gps = [seq len, batch size, 2]
        predict_id = [seq len, batch size, id one hot output dim]
        predict_rates = [seq len, batch size]
        target_gps = [seq len, batch size, 2]
        target_id = [seq len, batch size]
        target_rates = [seq len, batch size]
        trg_len = [batch size]  if not considering target length, the loss will smaller than the real one.
        
        predict and target have been removed sos 
    Returns:
    -------
        MAE of a batch in meter.
        RMSE of a batch in meter.
    """
    seq_len = target_id.size(0)
    batch_size = target_id.size(1)
    predict_gps = predict_gps.permute(1, 0, 2)
    predict_id = predict_id.permute(1, 0, 2)
    predict_rate = predict_rate.permute(1, 0)
    target_gps = target_gps.permute(1, 0, 2)
    target_id = target_id.permute(1, 0)
    target_rate = target_rate.permute(1, 0)

    ls_dis, rn_ls_dis = [], []
    for bs in range(batch_size):
        for len_i in range(trg_len[bs] - 1):  # don't calculate padding points
            pre_rid = predict_id[bs, len_i].argmax()
            convert_pre_rid = new2raw_rid_dict[pre_rid.tolist()]
            pre_rate = predict_rate[bs, len_i]
            pre_offset = raw_rn_dict[convert_pre_rid]['length'] * pre_rate
            pre_candi_pt = CandidatePoint(predict_gps[bs, len_i][0],
                                          predict_gps[bs, len_i][1],
                                          convert_pre_rid, 0, pre_offset,
                                          pre_rate)

            trg_rid = target_id[bs, len_i]
            convert_trg_rid = new2raw_rid_dict[trg_rid.tolist()]
            trg_rate = target_rate[bs, len_i]
            trg_offset = raw_rn_dict[convert_trg_rid]['length'] * trg_rate
            trg_candi_pt = CandidatePoint(target_gps[bs, len_i][0],
                                          target_gps[bs, len_i][1],
                                          convert_trg_rid, 0, trg_offset,
                                          trg_rate)

            if pre_candi_pt.lat == trg_candi_pt.lat and pre_candi_pt.lng == trg_candi_pt.lng:
                rn_dis = 0
                dis = 0
            else:
                rn_dis, _ = min(
                    find_shortest_path(rn, pre_candi_pt, trg_candi_pt),
                    find_shortest_path(rn, trg_candi_pt, pre_candi_pt))
                if type(rn_dis) is not float:
                    rn_dis = rn_dis.tolist()
                dis = distance(pre_candi_pt, trg_candi_pt)

            if rn_dis == np.inf:
                rn_dis = 1000
            rn_ls_dis.append(rn_dis)
            ls_dis.append(dis)

    ls_dis = np.array(ls_dis)
    rn_ls_dis = np.array(rn_ls_dis)

    mae = ls_dis.mean()
    rmse = np.sqrt((ls_dis**2).mean())
    rn_mae = rn_ls_dis.mean()
    rn_rmse = np.sqrt((rn_ls_dis**2).mean())
    return mae, rmse, rn_mae, rn_rmse
Example #10
0
def heuristic(node1, node2):
    return distance(SPoint(node1[1], node1[0]), SPoint(node2[1], node2[0]))