def generate_speed_data(traj_dir, grid_idx, feature_path): MIN_DISTANCE_IN_METER = 5 MAX_DISTANCE_IN_METER = 300 speed_data = np.zeros((grid_idx.row_num, grid_idx.col_num, 1), dtype=np.float) cnt_data = np.zeros((grid_idx.row_num, grid_idx.col_num, 1), dtype=np.float) for filename in tqdm(os.listdir(traj_dir)): if not filename.endswith('.txt'): continue traj_list = parse_traj_file(os.path.join(traj_dir, filename)) for traj in traj_list: for i in range(len(traj.pt_list) - 1): cur_pt, next_pt = traj.pt_list[i], traj.pt_list[i + 1] delta_time = (next_pt.time - cur_pt.time).total_seconds() if MIN_DISTANCE_IN_METER < distance(cur_pt, next_pt) < MAX_DISTANCE_IN_METER: try: row_idx, col_idx = grid_idx.get_matrix_idx(cur_pt.lat, cur_pt.lng) speed = distance(next_pt, cur_pt) / delta_time # 120 km/h if speed > 34: continue speed_data[row_idx, col_idx, 0] += speed cnt_data[row_idx, col_idx, 0] += 1 except IndexError: continue speed_data = np.divide(speed_data, cnt_data, out=np.zeros_like(speed_data), where=cnt_data != 0) np.save(os.path.join(feature_path, 'speed.npy'), speed_data)
def remove_similar_links(self, rn, edge_virtual_links): new_edge_virtual_links = copy.copy(edge_virtual_links) o = edge_virtual_links[0].end_node stable = False while not stable: stable = True for i in range(len(new_edge_virtual_links) - 1): link_a = new_edge_virtual_links[i] a = cal_loc_along_line(rn.edges[link_a.target_segment]['coords'][link_a.split_edge_idx], rn.edges[link_a.target_segment]['coords'][link_a.split_edge_idx + 1], link_a.split_edge_offset) for j in range(i + 1, len(new_edge_virtual_links)): link_b = new_edge_virtual_links[j] b = cal_loc_along_line(rn.edges[link_b.target_segment]['coords'][link_b.split_edge_idx], rn.edges[link_b.target_segment]['coords'][link_b.split_edge_idx + 1], link_b.split_edge_offset) # if small angle if angle(o, a, o, b) < self.SIMILAR_DIRECTION_THRESHOLD: # delete longer edge if distance(o, a) < distance(o, b): new_edge_virtual_links.remove(new_edge_virtual_links[j]) else: new_edge_virtual_links.remove(new_edge_virtual_links[i]) stable = False break if not stable: break return new_edge_virtual_links
def generate_transition_view(traj_dir, grid_idx, nbhd_size, nbhd_dist, feature_path): MIN_DISTANCE_IN_METER = 5 MAX_DISTANCE_IN_METER = 300 meters_per_grid = grid_idx.lat_interval / LAT_PER_METER radius = int(nbhd_dist / meters_per_grid) transit_data = np.zeros((grid_idx.row_num, grid_idx.col_num, nbhd_size, nbhd_size, 2), dtype=np.uint8) for filename in tqdm(os.listdir(traj_dir)): if not filename.endswith('.txt'): continue traj_list = parse_traj_file(os.path.join(traj_dir, filename)) for traj in traj_list: for idx in range(len(traj.pt_list) - 1): cur_pt = traj.pt_list[idx] next_pt = traj.pt_list[idx + 1] if MIN_DISTANCE_IN_METER < distance(cur_pt, next_pt) < MAX_DISTANCE_IN_METER: try: global_cur_i, global_cur_j = grid_idx.get_matrix_idx(cur_pt.lat, cur_pt.lng) local_idx = get_local_idx(global_cur_i, global_cur_j, radius, grid_idx, nbhd_dist) local_next_i, local_next_j = local_idx.get_matrix_idx(next_pt.lat, next_pt.lng) transit_data[global_cur_i, global_cur_j, local_next_i, local_next_j, 0] = 1 global_next_i, global_next_j = grid_idx.get_matrix_idx(next_pt.lat, next_pt.lng) local_idx = get_local_idx(global_next_i, global_next_j, radius, grid_idx, nbhd_dist) local_cur_i, local_cur_j = local_idx.get_matrix_idx(cur_pt.lat, cur_pt.lng) transit_data[global_next_i, global_next_j, local_cur_i, local_cur_j, 1] = 1 except IndexError: continue np.save(os.path.join(feature_path, 'transition.npy'), transit_data)
def generate_line_image(traj_dir, grid_idx, feature_path): MIN_DISTANCE_IN_METER = 5 MAX_DISTANCE_IN_METER = 300 traj_line_img = np.zeros((grid_idx.row_num, grid_idx.col_num), dtype=np.uint8) for filename in tqdm(os.listdir(traj_dir)): if not filename.endswith('.txt'): continue traj_list = parse_traj_file(os.path.join(traj_dir, filename)) for traj in traj_list: one_traj_line_img = np.zeros((grid_idx.row_num, grid_idx.col_num), dtype=np.uint8) for j in range(len(traj.pt_list) - 1): cur_pt, next_pt = traj.pt_list[j], traj.pt_list[j + 1] if MIN_DISTANCE_IN_METER < distance( cur_pt, next_pt) < MAX_DISTANCE_IN_METER: try: y1, x1 = grid_idx.get_matrix_idx( cur_pt.lat, cur_pt.lng) y2, x2 = grid_idx.get_matrix_idx( next_pt.lat, next_pt.lng) cv2.line(one_traj_line_img, (x1, y1), (x2, y2), 16, 1, lineType=cv2.LINE_AA) except IndexError: continue traj_line_img = cv2.add(traj_line_img, one_traj_line_img) cv2.imwrite(os.path.join(feature_path, 'line.png'), traj_line_img)
def extension_intersection(self, o, f, target_coords): min_dist = float('inf') split_edge_idx = float('inf') split_edge_offset = float('inf') # check whether internal edge has intersection (if multiple intersections, select the shortest) for i in range(0, len(target_coords) - 1): a = target_coords[i] b = target_coords[i + 1] result = line_ray_intersection_test(o, f, a, b) if result is None or result[0] < 0 or result[0] > 1: continue else: dist_tmp = distance(o, result[1]) if dist_tmp < self.radius and dist_tmp < min_dist: nearest_node_with_offset = (target_coords[i], 0.0) if result[0] < 0.5 else \ (target_coords[i + 1], 1.0) min_dist = dist_tmp split_edge_idx = i # prefer link to existing nodes if too short if distance(nearest_node_with_offset[0], result[1]) < self.NO_NEW_VERTEX_OFFSET: split_edge_offset = nearest_node_with_offset[1] else: split_edge_offset = result[0] # doesn't have internal intersection, check whether has smooth transition if split_edge_idx == float('inf'): # check start node tmp_dist = distance(target_coords[0], o) if tmp_dist < self.radius and \ angle_between((o.lng - f.lng, o.lat - f.lat), (target_coords[0].lng - o.lng, target_coords[0].lat - o.lat)) <= 0.5 * np.pi: min_dist = tmp_dist split_edge_idx = 0 split_edge_offset = 0.0 # check end node tmp_dist = distance(target_coords[-1], o) if tmp_dist < self.radius and \ angle_between((o.lng - f.lng, o.lat - f.lat), (target_coords[-1].lng - o.lng, target_coords[-1].lat - o.lat)) <= 0.5 * np.pi: if tmp_dist < min_dist: split_edge_idx = len(target_coords) - 2 split_edge_offset = 1.0 return split_edge_idx, split_edge_offset
def perpendicular_intersection(self, o, target_coords, rn, opposite_of_o, target_segment): split_edge_idx = float('inf') split_edge_offset = float('inf') o_min_dist, o_split_edge_idx, o_split_edge_offset = self.cal_projection(o, target_coords) other_min_dist, other_split_edge_idx, other_split_edge_offset = self.cal_projection(opposite_of_o, target_coords) if o_min_dist < other_min_dist: split_edge_idx = o_split_edge_idx split_edge_offset = o_split_edge_offset # no internal intersection if split_edge_idx == float('inf'): # the target segment is also a short isolated one if rn.edges[target_segment]['length'] < self.NO_NEW_VERTEX_OFFSET and \ rn.degree(target_segment[0]) == 1 and rn.degree(target_segment[1]) == 1: a = SPoint(target_segment[0][1], target_segment[0][0]) b = SPoint(target_segment[1][1], target_segment[1][0]) dead_end_to_target_dist = min(distance(o, a), distance(o, b)) opposite_to_target_dist = min(distance(opposite_of_o, a), distance(opposite_of_o, b)) # current dead end is shorter to the target than opposite, link with the nearest vertex if dead_end_to_target_dist < opposite_to_target_dist and dead_end_to_target_dist < self.radius: target = a if distance(o, a) < distance(o, b) else b if target == target_coords[0]: split_edge_idx = 0 split_edge_offset = 0.0 else: split_edge_idx = len(target_coords) - 2 split_edge_offset = 1.0 return split_edge_idx, split_edge_offset
def generate_dir_dist_data(traj_dir, grid_idx, feature_path): MIN_DISTANCE_IN_METER = 5 MAX_DISTANCE_IN_METER = 300 dir_data = np.zeros((grid_idx.row_num, grid_idx.col_num, 8), dtype=np.uint8) for filename in tqdm(os.listdir(traj_dir)): if not filename.endswith('.txt'): continue traj_list = parse_traj_file(os.path.join(traj_dir, filename)) for traj in traj_list: for i in range(len(traj.pt_list) - 1): cur_pt, next_pt = traj.pt_list[i], traj.pt_list[i + 1] if MIN_DISTANCE_IN_METER < distance(cur_pt, next_pt) < MAX_DISTANCE_IN_METER: try: row_idx, col_idx = grid_idx.get_matrix_idx(cur_pt.lat, cur_pt.lng) direction = int(((bearing(cur_pt, next_pt) + 22.5) % 360) // 45) dir_data[row_idx, col_idx, direction] += 1 except IndexError: continue np.save(os.path.join(feature_path, 'direction.npy'), dir_data)
def update_link(self, linked_rn, from_pt, to_pt, coords, avail_eid): """ make sure two link will not have too similar direction """ is_valid = True link_dist = distance(from_pt, to_pt) # if the new edge is shorter, add new edge and delete old edge # check from pt links_with_from = [edge for edge in list(linked_rn.edges((from_pt.lng, from_pt.lat))) if linked_rn.edges[edge]['type'] == 'virtual'] edges_to_delete = [] for u, v in links_with_from: other_node = v if u[0] == from_pt.lng and u[1] == from_pt.lat else u ang = angle(from_pt, to_pt, from_pt, SPoint(other_node[1], other_node[0])) if ang < self.SIMILAR_DIRECTION_THRESHOLD: if link_dist >= linked_rn[u][v]['length']: is_valid = False break else: edges_to_delete.append((u, v)) # check to pt links_with_to = [edge for edge in list(linked_rn.edges((to_pt.lng, to_pt.lat))) if linked_rn.edges[edge]['type'] == 'virtual'] for u, v in links_with_to: other_node = v if u[0] == to_pt.lng and u[1] == to_pt.lat else u ang = angle(to_pt, from_pt, to_pt, SPoint(other_node[1], other_node[0])) if ang < self.SIMILAR_DIRECTION_THRESHOLD: if link_dist >= linked_rn[u][v]['length']: is_valid = False break else: edges_to_delete.append((u, v)) if is_valid: linked_rn.add_edge((from_pt.lng, from_pt.lat), (to_pt.lng, to_pt.lat), coords=coords, eid=avail_eid, type='virtual') for u, v in edges_to_delete: if linked_rn.has_edge(u, v): # didn't destroy the connectivity if linked_rn.degree(u) == 2 or linked_rn.degree(v) == 2: continue linked_rn.remove_edge(u, v)
def is_valid(self, coords): dist = 0.0 for i in range(len(coords) - 1): dist += distance(coords[i], coords[i + 1]) return dist > self.min_road_dist