예제 #1
0
    def _point_edge_dist(self, lon, lat, edge):
        lat_origin = angle2radian(self.rd_nwk.nodes[edge[0]]['lat'])
        lon_origin = angle2radian(self.rd_nwk.nodes[edge[0]]['lon'])
        lat_dest = angle2radian(self.rd_nwk.nodes[edge[1]]['lat'])
        lon_dest = angle2radian(self.rd_nwk.nodes[edge[1]]['lon'])

        a = dist(angle2radian(lat), angle2radian(lon), lat_origin, lon_origin)
        b = dist(angle2radian(lat), angle2radian(lon), lat_dest, lon_dest)
        c = dist(lat_origin, lon_origin, lat_dest, lon_dest)

        # if origin point is the closest
        if b**2 > a**2 + c**2:
            return a, edge[0]  # distance, point

        # if destination point is the closest
        elif a**2 > b**2 + c**2:
            return b, edge[1]

        if c == 0:
            return a, edge[0]
        # otherwise, calculate the Vertical length
        p = (a + b + c) / 2
        s = math.sqrt(p * math.fabs(p - a) * math.fabs(p - b) *
                      math.fabs(p - c))
        return 2 * s / c, None
    def _preprocess(self):
        """
        removing points that are within 2 sigma_z of the previous included point
        The justification for this step is that until we see a point that is at least 2sigma_z away from
        its temporal predecessor, our confidence is low that the apparent movement is due to
        actual vehicle movement and not noise
        Returns:

        """

        new_traj = list()
        lat_r_pre = None  # latitude in radius
        lon_r_pre = None  # longitude in radius
        for i in range(len(self.trajectory)):
            # dist have lat before lon, however dataset provide lon before lat.
            lat_r, lon_r = angle2radian(self.trajectory[i][2]), angle2radian(
                self.trajectory[i][1])

            if lat_r_pre is None or dist(lat_r, lon_r, lat_r_pre,
                                         lon_r_pre) > 2 * self.sigma_z:
                # if distance > 2*sigma_z, take this point into calculation, otherwise remove it
                new_traj.append(self.trajectory[i])
                lat_r_pre = lat_r
                lon_r_pre = lon_r
        self.trajectory = np.vstack(new_traj)
    def _load_geo_and_rel(self):
        """
        加载.geo文件,格式[geo_id, type, coordinates, properties(若干列)]
        加载.rel文件,格式[rel_id, type, origin_id, destination_id, properties(若干列)],
        .rel文件用来表示路网数据

        Returns:
            self.rd_nwk: networkx.MultiDiGraph
        """
        # init road network, which is the result of this function
        self.rd_nwk = nx.DiGraph(name="road network")

        # load geo and rel file
        geofile = pd.read_csv(self.data_path + self.geo_file + '.geo')
        relfile = pd.read_csv(self.data_path + self.rel_file + '.rel')
        geo_num = geofile.shape[0]

        # check type geo in rel file and LineString in geo file
        if not ['geo'] == self.config['rel']['including_types']:
            raise ValueError('.rel file should include geo type in Map Matching task!')
        if not ['LineString'] == self.config['geo']['including_types']:
            raise ValueError('.geo file should include LineString type in Map Matching task!')

        # get properties
        columns = relfile.columns.tolist()[4:]

        # use UnionSet to get nodes
        node_set = UnionSet(2 * geo_num)
        for index, row in relfile.iterrows():
            # origin and destination
            from_id = int(row[2])
            to_id = int(row[3])
            node_set.union(from_id, to_id + geo_num)

        # generate MultiDigraph
        for index, row in geofile.iterrows():

            geo_id = int(row['geo_id'])
            coordinate = eval(row['coordinates'])
            origin_node = node_set.find(geo_id + geo_num)
            dest_node = node_set.find(geo_id)
            if origin_node not in self.rd_nwk.nodes:
                self.rd_nwk.add_node(origin_node, lon=coordinate[0][0], lat=coordinate[0][1])
            if dest_node not in self.rd_nwk.nodes:
                self.rd_nwk.add_node(dest_node, lon=coordinate[1][0], lat=coordinate[1][1])

            # add edge
            self.rd_nwk.add_edge(origin_node, dest_node)
            feature_dct = dict()
            for i, column in enumerate(columns):
                feature_dct[column] = row[i + 4]
            if 'distance' not in feature_dct.keys():
                feature_dct['distance'] = dist(
                    angle2radian(self.rd_nwk.nodes[origin_node]['lat']),
                    angle2radian(self.rd_nwk.nodes[origin_node]['lon']),
                    angle2radian(self.rd_nwk.nodes[dest_node]['lat']),
                    angle2radian(self.rd_nwk.nodes[dest_node]['lon'])
                )
            feature_dct['geo_id'] = geo_id
            self.rd_nwk.edges[origin_node, dest_node].update(feature_dct)

        # logger
        self._logger.info("Loaded file " + self.geo_file + '.geo' + ', num_nodes=' + str(geo_num))
        self._logger.info("Loaded file " + self.rel_file + '.rel, num_roads=' + str(len(self.rd_nwk)))
예제 #4
0
 def _score_matrix(self):
     sub_static_matrices = list()
     # for every GPS sample
     for i in range(len(self.candidates)):
         # current candidates: self.candidates[i]
         # prev candidates: self.candidates[j]
         # no current candidates
         if i == 0:
             continue
         if len(self.candidates[i]) == 0:
             sub_static_matrix = np.zeros((1, 1))
             sub_static_matrices.append(sub_static_matrix)
             continue
         # if there are current candidates, find prev index j
         j = i - 1
         while j >= 0 and len(self.candidates[j]) == 0:
             j -= 1
         # j >= 0, calculate score of candidates of GPS sample i
         if j < 0:
             sub_static_matrix = np.zeros((1, 1))
             sub_static_matrices.append(sub_static_matrix)
             continue
         sub_static_matrix = np.zeros((len(self.candidates[j].items()),
                                       len(self.candidates[i].items())))
         n = 0
         for edge, dct in self.candidates[i].items():
             m = 0
             for edge_pre, dct_pre in self.candidates[j].items():
                 sub_static_matrix[m][n] = dct['N'] * dct_pre['V'][edge] * (
                     1 if 'T' not in dct_pre.keys() else dct_pre['T'][edge])
                 m += 1
             n += 1
         sub_static_matrices.append(sub_static_matrix)
     traj_lon_lat = self.trajectory[:, 1:3]
     self.traj_points = []
     for i in range(len(traj_lon_lat)):
         W = []
         j = 0
         while j < len(traj_lon_lat):
             if i == j:
                 j += 1
                 continue
             lon_i, lat_i = traj_lon_lat[i, :]
             lon_j, lat_j = traj_lon_lat[j, :]
             euclid_distance = dist(angle2radian(lat_i),
                                    angle2radian(lon_i),
                                    angle2radian(lat_j),
                                    angle2radian(lon_j))
             W.append(pow(math.e, -(euclid_distance**2 / self.beta**2)))
             j += 1
         fai = []
         self.sub_static_matrices = sub_static_matrices
         self.W = W
         for k in range(len(W)):
             fai.append(sub_static_matrices[k] * W[k])
         traj_point = {
             "time": self.trajectory[i][0],
             "lon": self.trajectory[i][1],
             "lat": self.trajectory[i][2],
             "fai": fai,
             "candidates": self.candidates[i]
         }
         self.traj_points.append(
             traj_point)  # Φ(fai) is the weighted score matrix
예제 #5
0
    def _transmission_probability(self):
        """

        Returns:

        """
        i = 1
        while i < len(self.candidates):
            # j and k
            j = i - 1
            if len(self.candidates[i]) == 0:
                k = i + 1
                while len(
                        self.candidates[k]) == 0 and k < len(self.candidates):
                    k += 1
                if k == len(self.candidates):
                    break
            else:
                k = i
            d = dist(angle2radian(self.trajectory[j][2]),
                     angle2radian(self.trajectory[j][1]),
                     angle2radian(self.trajectory[k][2]),
                     angle2radian(self.trajectory[k][1]))
            for edge_j, dct_j in self.candidates[j].items():
                for edge_k, dct_k in self.candidates[k].items():
                    brng_jk = init_bearing(angle2radian(self.trajectory[j][2]),
                                           angle2radian(self.trajectory[j][1]),
                                           angle2radian(self.trajectory[k][2]),
                                           angle2radian(self.trajectory[k][1]))
                    brng_edge_j = init_bearing(
                        angle2radian(self.rd_nwk.nodes[edge_j[0]]['lat']),
                        angle2radian(self.rd_nwk.nodes[edge_j[0]]['lon']),
                        angle2radian(self.rd_nwk.nodes[edge_j[1]]['lat']),
                        angle2radian(self.rd_nwk.nodes[edge_j[1]]['lon']),
                    )
                    try:
                        if dct_j['node'] is not None and dct_k[
                                'node'] is not None:
                            result = d / nx.astar_path_length(
                                self.rd_nwk,
                                dct_j['node'],
                                dct_k['node'],
                                weight='distance')
                        elif dct_j['node'] is not None:
                            nd2_origin = edge_k[0]
                            lon, lat = self.rd_nwk.nodes[nd2_origin][
                                'lon'], self.rd_nwk.nodes[nd2_origin]['lat']
                            path_len = nx.astar_path_length(self.rd_nwk,
                                                            dct_j['node'],
                                                            nd2_origin,
                                                            weight='distance')
                            path_len += math.sqrt(
                                math.fabs(
                                    dist(angle2radian(self.trajectory[k][2]),
                                         angle2radian(self.trajectory[k][1]),
                                         angle2radian(lat), angle2radian(lon))
                                    **2 - dct_k['distance']**2))
                            if edge_j[1] == dct_j['edge']:
                                path_len += self.rd_nwk[edge_j[0]][
                                    edge_j[1]]['distance'] * 2
                            result = d / path_len

                        elif dct_k['node'] is not None:
                            nd1_destination = edge_j[1]
                            lon, lat = self.rd_nwk.nodes[nd1_destination][
                                'lon'], self.rd_nwk.nodes[nd1_destination][
                                    'lat']
                            path_len = nx.astar_path_length(self.rd_nwk,
                                                            nd1_destination,
                                                            dct_k['node'],
                                                            weight='distance')
                            path_len += math.sqrt(
                                math.fabs(
                                    dist(angle2radian(self.trajectory[j][2]),
                                         angle2radian(self.trajectory[j][1]),
                                         angle2radian(lat), angle2radian(lon))
                                    **2 - dct_j['distance']**2))
                            if edge_k[1] == dct_k['node']:
                                path_len += self.rd_nwk[edge_k[0]][
                                    edge_k[1]]['distance'] * 2
                            result = d / path_len
                        else:
                            if edge_j == edge_k and math.fabs(brng_edge_j -
                                                              brng_jk) < 90:
                                result = 1
                            else:
                                nd1_destination = edge_j[1]
                                lon1, lat1 = self.rd_nwk.nodes[nd1_destination]['lon'], \
                                    self.rd_nwk.nodes[nd1_destination]['lat']
                                nd2_origin = edge_k[0]
                                lon2, lat2 = self.rd_nwk.nodes[nd2_origin][
                                    'lon'], self.rd_nwk.nodes[nd2_origin][
                                        'lat']
                                result = d / (nx.astar_path_length(
                                    self.rd_nwk,
                                    nd1_destination,
                                    nd2_origin,
                                    weight='distance'
                                ) + math.sqrt(
                                    math.fabs(
                                        dist(
                                            angle2radian(self.trajectory[j][2]),
                                            angle2radian(self.trajectory[j][1]
                                                         ), angle2radian(lat1),
                                            angle2radian(lon1))**2 -
                                        dct_j['distance']**2)
                                ) + math.sqrt(
                                    math.fabs(
                                        dist(
                                            angle2radian(self.trajectory[k][2]),
                                            angle2radian(self.trajectory[k][1]
                                                         ), angle2radian(lat2),
                                            angle2radian(lon2))**2 -
                                        dct_k['distance']**2)))
                        if 'V' in dct_j.keys():
                            dct_j['V'][edge_k] = min(result, 1)
                        else:
                            dct_j['V'] = {edge_k: min(result, 1)}
                    except:
                        if 'V' in dct_j.keys():
                            dct_j['V'][edge_k] = 0
                        else:
                            dct_j['V'] = {edge_k: 0}
            i += 1