/// <summary> /// calculate route distance by search the shortest route between the from vertex of the two edges /// this method may be not accurate. /// <returns></returns> private Edgespp RouteDistance(Point p1, Edge e1, Point p2, Edge e2, Graph g) { double routeDis = 0; Point p1_prj = e1.projectFrom(p1); Vertex e1_to = e1.To; double dis1 = p1_prj.DistanceFrom(e1_to.toPoint()); Point p2_prj = e2.projectFrom(p2); Vertex e2_from = e2.From; double dis2 = p2_prj.DistanceFrom(e2_from.toPoint()); if (e1 == e2) { return(new Edgespp(p1_prj.DistanceFrom(p2_prj), new List <Edge>() { e1 })); } else if (e1_to.ID == e2_from.ID) { routeDis = dis1 + dis2; return(new Edgespp(routeDis, new List <Edge>() { e1, e2 })); } else { Dijkstra dij = new Dijkstra(g); LinkedList <Vertex> shortestPath_vertices = dij.ShortestPath_ScoreValue(e1_to, e2_from, _distance_limit); //Route rs = getminRoute(F, e1.ID, e2.ID, p1, p2); if (shortestPath_vertices == null) { return(null); } List <Edge> shortestPath_edges = dij.MakeShortestPath_EdgeList(); //List<Edge> shortestPath_edges = rs.getPath_EdgeList(m_graph); for (int i = 0; i < shortestPath_edges.Count; i++) { routeDis += shortestPath_edges[i].Length; } if (shortestPath_edges.Contains(e1)) { routeDis -= dis1; shortestPath_edges.Remove(e1); } else { routeDis += dis1; } if (shortestPath_edges.Contains(e2)) { routeDis -= dis2; shortestPath_edges.Remove(e2); } else { routeDis += dis2; } return(new Edgespp(routeDis, shortestPath_edges)); } }
private void GetCompletePath(List <Road_Time> cands, ref List <Road_Time> result) { result.Add(cands[0]); Road_Time rt = new Road_Time(); bool flag = true; for (int i = 0; i < cands.Count - 1; i++) { if (flag == true) { rt = cands[i]; } Road_Time rt_next = cands[i + 1]; Edge e = cands[i].road; Edge next = cands[i + 1].road; int eid = e.ID; int nextid = next.ID; if (eid == nextid) { flag = false; continue; } flag = true; if (e.isConnectedTo(next) == true) { result.Add(rt_next); continue; } else { //all possible roads in the iterative search procedure. //int: the roadID //int: the last roadID adjacent to the roadID Dictionary <Edge, Edge> possibles = new Dictionary <Edge, Edge>(); //the roads are searched out by adjacency in the last round Dictionary <Edge, Edge> lastNewEdges = new Dictionary <Edge, Edge>(); possibles.Add(e, null); lastNewEdges.Add(e, null); Dictionary <Edge, Edge> newEdges = new Dictionary <Edge, Edge>(); int times = 0; //record the loop times. while (true) { times++; newEdges.Clear(); foreach (Edge key in lastNewEdges.Keys) { SearchEdgesForEdge1(key, possibles, ref newEdges); } if (newEdges.ContainsKey(next)) { Edge theE = null; newEdges.TryGetValue(next, out theE); possibles.Add(next, theE); break; } lastNewEdges.Clear(); foreach (var item in newEdges) { lastNewEdges.Add(item.Key, item.Value); possibles.Add(item.Key, item.Value); } } //if there are n roads between e and next, then divide the timespan (between e and next) into n intervals averagely TimeSpan ts = rt_next.T - rt.T; int seconds = ts.Seconds; TimeSpan time_interval = TimeSpan.FromSeconds(seconds / times); List <Road_Time> newConnectedEdges = new List <Road_Time>(); //Edge edge = nextid; //DateTime lastT = next.T; Edge current_edge = next; DateTime lastT = rt_next.T; while (true) { Edge next_edge; possibles.TryGetValue(current_edge, out next_edge); if (next_edge == e) { break; } else { DateTime t = lastT.Subtract(time_interval); Road_Time theRT = new Road_Time(); theRT.road = next_edge; theRT.T = t; theRT.strength = 0; newConnectedEdges.Add(theRT); current_edge = next_edge; lastT = t; } } newConnectedEdges.Reverse(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////connected mapped edges of two adjacent gps points can not exceed the max distance the vehicle traveled double total_distance = 0; for (int j = 0; j < newConnectedEdges.Count; j++) { Road_Time theRT = newConnectedEdges[j]; Edge theRoad = theRT.road; total_distance += theRoad.Length; } if ((rt_next.T - rt.T).TotalSeconds * 80 < total_distance) { if (i == 0) //the first gps point may be mapped wrong, need the further check { } else { cands.RemoveAt(i + 1); i = i - 1; continue; } } else { result.AddRange(newConnectedEdges); result.Add(rt_next); } } } }
public void Mapmatching_HMM(Graph G) { m_graph = G; string patha = @"F:\map matching\frechet dictance\trajectories\traindata\clean.txt"; Program.writetxt(_trj, patha); if (_trj == null || _trj.Count == 0) { throw new ArgumentOutOfRangeException("trajectory", "Number of points in trajectory should be higher than zero."); } int edge_num = G.getEdge().Count; //the first edge is from edge of the transition, the second edge is the to edge Dictionary <int, Dictionary <Edge, Dictionary <Edge, double> > > transition_from_to = new Dictionary <int, Dictionary <Edge, Dictionary <Edge, double> > >(); //the first edge is to edge of the transition, the second edge is the from edge Dictionary <int, Dictionary <Edge, Dictionary <Edge, double> > > transition_to_from = new Dictionary <int, Dictionary <Edge, Dictionary <Edge, double> > >(); //存储相邻GPS点的候选路径之间的路径 Dictionary <Edge, Dictionary <Edge, List <Edge> > > e1_e2_edges = new Dictionary <Edge, Dictionary <Edge, List <Edge> > >(); Dictionary <Edge, Dictionary <int, double> > emission = new Dictionary <Edge, Dictionary <int, double> >(); Dictionary <int, List <Edge> > id_candidate = new Dictionary <int, List <Edge> >(); Dictionary <Edge, double> initial = new Dictionary <Edge, double>(); double minmum_radius = 40; // GPS point must be within the 40m of any road segment, or it is regarded as noise double maximum_radius = 100; //we calculate transition probability, for any point, we find at least 3 road segments for candidate //if we can not find 3 points within 100 meters, stop searching double search_radius = 30; //we start search within 20 meters, if the start search radius is too large, there are two many edges are selected //calculating transition probability will cost a lot of time. double step = 10; double angle_threshod = 360; //regard points far away from edges as noise, although it may be due to the low accuracy of the road networks #region delete points which are far away from road segments for (int i = _trj.Count - 1; i >= 0; i--) { Point p = _trj[i]; HashSet <Edge> cands_check_good_point = new HashSet <Edge>(); searchEdgeWithinRadiusOneStep(G._rtree_edge, p, cands_check_good_point, minmum_radius); if (cands_check_good_point.Count == 0) { _trj.Remove(p); } } if (_trj.Count <= 1) //must have least two points to calculate the transition prob; { return; } #endregion #region calculate initial probability foreach (int id in G.getEdge().Keys) { Edge e = G.getEdge(id); initial.Add(e, 1); } #endregion #region calculate emission probability for (int i = 0; i < _trj.Count; i++) { HashSet <Edge> cands = new HashSet <Edge>(); Point p = _trj[i]; searchEdgeWithMaximumRadiusAngle(G._rtree_edge, p, cands, search_radius, step, leastNum, maximum_radius, angle_threshod); foreach (Edge e in cands) { Stopwatch st1 = new Stopwatch(); st1.Start();//开始计时 double measurementProb = MeasurementProbability(p, e, 0, 20, 0, 30); st1.Stop();//终止计时 emis_time += st1.ElapsedMilliseconds; if (emission.ContainsKey(e)) { Dictionary <int, double> pt_prob = emission[e]; if (pt_prob.ContainsKey(i)) { pt_prob[i] = measurementProb; } else { pt_prob.Add(i, measurementProb); } } else { Dictionary <int, double> pt_prob = new Dictionary <int, double>(); pt_prob.Add(i, measurementProb); emission.Add(e, pt_prob); } //存储每个GPS点搜索到的candidate if (id_candidate.ContainsKey(i)) { id_candidate[i].Add(e); } else { List <Edge> candis = new List <Edge>(); candis.Add(e); id_candidate.Add(i, candis); } } } #endregion #region calculate transition probability //the transition matrix is alway changed with time t (p1.t, p2.t) //when at t = p1.t, based on krum_HMM, there is a transition probability in the matrix //when at t = p2.t, based on krum_HMM, there is another transition probability in the matrix for (int i = 0; i < _trj.Count - 1; i++) { Point p1 = _trj[i]; Point p2 = _trj[i + 1]; List <Edge> cands1 = null; List <Edge> cands2 = null; if (id_candidate.ContainsKey(i)) { cands1 = id_candidate[i]; } if (id_candidate.ContainsKey(i + 1)) { cands2 = id_candidate[i + 1]; } //searchEdgeWithMaximumRadiusAngle(G._rtree_edge, p1, cands1, search_radius, step, leastNum, maximum_radius, angle_threshod); //searchEdgeWithMaximumRadiusAngle(G._rtree_edge, p2, cands2, search_radius, step, leastNum, maximum_radius, angle_threshod); if (cands1 == null || cands2 == null) { continue; } bool transition_prob_flag = false; foreach (Edge e1 in cands1) { foreach (Edge e2 in cands2) { Stopwatch st2 = new Stopwatch(); st2.Start();//开始计时 double transitionProb = TransitionProbability(p1, e1, p2, e2, G, 0.894, e1_e2_edges); st2.Stop();//终止计时 tran_time += st2.ElapsedMilliseconds; if (transitionProb == 0) { continue; } else { transition_prob_flag = true; } #region containner for to from transition if (transition_to_from.ContainsKey(i)) { Dictionary <Edge, Dictionary <Edge, double> > e_e_prob = transition_to_from[i]; if (e_e_prob.ContainsKey(e2)) { Dictionary <Edge, double> e_prob = e_e_prob[e2]; if (e_prob.ContainsKey(e1)) { e_prob[e1] = transitionProb; } else { e_prob.Add(e1, transitionProb); } } else { Dictionary <Edge, double> e_prob = new Dictionary <Edge, double>(); e_prob.Add(e1, transitionProb); e_e_prob.Add(e2, e_prob); } } else { Dictionary <Edge, Dictionary <Edge, double> > e_e_prob = new Dictionary <Edge, Dictionary <Edge, double> >(); Dictionary <Edge, double> e_prob = new Dictionary <Edge, double>(); e_prob.Add(e1, transitionProb); e_e_prob.Add(e2, e_prob); transition_to_from.Add(i, e_e_prob); } #endregion } } if (transition_prob_flag == false) { break; } } #endregion Stopwatch st3 = new Stopwatch(); st3.Start();//开始计时 HMM hmm = new HMM(transition_to_from, emission, initial); double prob; Edge[] sequence = hmm.Viertbi(false, out prob); st3.Stop();//终止计时 viterbi_time = st3.ElapsedMilliseconds; if (sequence == null) { return; } for (int i = 0; i < sequence.GetLength(0) - 1; i++) { if (sequence[i].Equals(sequence[i + 1])) { continue; } complete_route.Add(sequence[i]); if (!sequence[i].isConnectedTo(sequence[i + 1])) { if (e1_e2_edges.ContainsKey(sequence[i])) { if (e1_e2_edges[sequence[i]].ContainsKey(sequence[i + 1])) { if (e1_e2_edges[sequence[i]][sequence[i + 1]].Count > 0) { complete_route.AddRange(e1_e2_edges[sequence[i]][sequence[i + 1]]); } } } } } complete_route.Add(sequence[sequence.GetLength(0) - 1]); #region convert sequence to road segment with time //complete_road_t = new List<Road_Time>(); //if (sequence != null) //{ // List<Road_Time> final_road_t = new List<Road_Time>(); // List<Road_Time> road_t = new List<Road_Time>(); // for (int i = 0; i < sequence.GetLength(0); i++) // { // Road_Time rt = new Road_Time(); // rt.road = sequence[i]; // rt.T = _trj[i].T; // road_t.Add(rt); // } // GetCompletePath(road_t, ref complete_road_t); // if (complete_road_t.Count > 0) // { // int the_last_road_id = complete_road_t[0].road.ID; // Road_Time rt1 = new Road_Time(); // rt1.road = complete_road_t[0].road; // rt1.T = complete_road_t[0].T; // final_road_t.Add(rt1); // for (int i = 1; i < complete_road_t.Count; i++) // { // if (complete_road_t[i].road.ID != the_last_road_id) // { // Road_Time rt = new Road_Time(); // rt.road = complete_road_t[i].road; // rt.T = complete_road_t[i].T; // the_last_road_id = complete_road_t[i].road.ID; // final_road_t.Add(rt); // } // } // } // complete_road_t.Clear(); // complete_road_t.AddRange(final_road_t); //} #endregion }