/// <summary> /// Recostrcucts Path from the list of candidate points /// </summary> /// <param name="matched">List of the candidate points</param> /// <returns>List of Polylines that represents matched path</returns> public List <Polyline <IPointGeo> > Reconstruct(IList <CandidatePoint> matched) { _points = new Dictionary <IPointGeo, PointEx>(); List <Polyline <IPointGeo> > result = new List <Polyline <IPointGeo> >(); for (int i = 0; i < matched.Count - 1; i++) { ConnectionGeometry wayGeometry = null; if (Calculations.GetDistance2D(matched[i + 1].MapPoint, matched[i].Road) < Calculations.EpsLength) { wayGeometry = matched[i].Road; } else if (Calculations.GetDistance2D(matched[i].MapPoint, matched[i + 1].Road) < Calculations.EpsLength) { wayGeometry = matched[i + 1].Road; } // both points are on the same road segment if (wayGeometry != null) { double length = double.PositiveInfinity; var pathSegments = _pathfinder.FindPath(matched[i], matched[i + 1], ref length); if (pathSegments != null) { //Console.WriteLine("pathSegment[0].id: " + pathSegments[0].Id); result.Add(CreateLine(matched[i].MapPoint, matched[i + 1].MapPoint, matched[i].Layer.TrackPoint.Time, matched[i + 1].Layer.TrackPoint.Time, wayGeometry, pathSegments[pathSegments.Count - 1].Id)); } } else { double length = double.PositiveInfinity; // find path between matched[i] and matched[i+1] var pathSegments = _pathfinder.FindPath(matched[i], matched[i + 1], ref length); if (pathSegments == null) { throw new ArgumentException(string.Format("Can not find path between points {0} and {1}", matched[i].MapPoint, matched[i + 1].MapPoint)); } if (pathSegments.Count > 1) { result.Add(CreateLine(pathSegments[0].From.MapPoint, pathSegments[0].To.MapPoint, matched[i].Layer.TrackPoint.Time, DateTime.MinValue, pathSegments[0].Road, pathSegments[0].Id)); for (int j = 1; j < pathSegments.Count - 1; j++) { result.Add(CreateLine(pathSegments[j].From.MapPoint, pathSegments[j].To.MapPoint, pathSegments[j].Road, pathSegments[j].Id)); } result.Add(CreateLine(pathSegments[pathSegments.Count - 1].From.MapPoint, pathSegments[pathSegments.Count - 1].To.MapPoint, DateTime.MinValue, matched[i + 1].Layer.TrackPoint.Time, pathSegments[pathSegments.Count - 1].Road, pathSegments[pathSegments.Count - 1].Id)); } else { result.Add(CreateLine(pathSegments[0].From.MapPoint, pathSegments[0].To.MapPoint, matched[i].Layer.TrackPoint.Time, matched[i + 1].Layer.TrackPoint.Time, pathSegments[0].Road, pathSegments[0].Id)); } } } return(result); }
/// <summary> /// Creates a new Polyline as part of the result /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="road"></param> /// <returns></returns> Polyline <IPointGeo> CreateLine(IPointGeo from, IPointGeo to, ConnectionGeometry road, long Id) { return(CreateLine(from, to, DateTime.MinValue, DateTime.MinValue, road, Id)); }
/// <summary> /// Creates a new Polyline as part of the result and assigns times for the start and end points /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="fromTime"></param> /// <param name="totime"></param> /// <param name="road"></param> /// <returns></returns> Polyline <IPointGeo> CreateLine(IPointGeo from, IPointGeo to, DateTime fromTime, DateTime totime, ConnectionGeometry road, long Id) { Polyline <IPointGeo> line = new Polyline <IPointGeo>() { WayID = road.WayID, Id = Id }; PointEx toAdd = GetOrCreatePointEx(from, fromTime); line.Nodes.Add(toAdd); var points = Topology.GetNodesBetweenPoints(from, to, road); foreach (var point in points) { line.Nodes.Add(GetOrCreatePointEx(point, DateTime.MinValue)); } toAdd = GetOrCreatePointEx(to, totime); line.Nodes.Add(toAdd); return(line); }
/// <summary> /// Builds road graph from map data /// </summary> /// <param name="map">OSMDB with preprocessed map data from OSM2Routing utility</param> public void Build(OSMDB map) { Dictionary <long, Node> usedNodes = new Dictionary <long, Node>(); foreach (var segment in map.Ways) { Node start = GetOrCreateNode(segment.Nodes[0], usedNodes); try { start.MapPoint = map.Nodes[segment.Nodes[0]]; } catch (ArgumentException) { continue; // If the start node was not found in the database, skip this path completely } Node end = GetOrCreateNode(segment.Nodes[segment.Nodes.Count - 1], usedNodes); try { end.MapPoint = map.Nodes[segment.Nodes[segment.Nodes.Count - 1]]; } catch (ArgumentException) { continue; // If the end node was not found in the database, skip this path completely } double speed = double.Parse(segment.Tags["speed"].Value, System.Globalization.CultureInfo.InvariantCulture); // Getting the average speed double avgSpeed = 0; if (segment.Tags.ContainsTag("avgSpeed")) { avgSpeed = double.Parse(segment.Tags["avgSpeed"].Value); } int wayId = int.Parse(segment.Tags["way-id"].Value, System.Globalization.CultureInfo.InvariantCulture); long id = segment.ID; ConnectionGeometry geometry = new ConnectionGeometry(); geometry.WayID = wayId; foreach (var n in segment.Nodes) { try { OSMNode mapPoint = map.Nodes[n]; geometry.Nodes.Add(mapPoint); //geometry.Nodes.Add(new PointGeo(mapPoint.Latitude, mapPoint.Longitude)); } catch (ArgumentException) { continue; // If an intermediate node was not found in the database, skip just that node } } _connectionGeometries.Add(geometry); if (segment.Tags["accessible"].Value == "yes") { Connection sc; if (segment.Tags.ContainsTag("traffic")) { var traffic = new HashSet <long>(segment.Tags["traffic"].Value.Split(',').Select(x => long.Parse(x))); sc = new Connection(start, end) { Speed = speed, Geometry = geometry, Traffic = traffic, Id = id, AvgSpeed = avgSpeed }; } else { sc = new Connection(start, end) { Speed = speed, Geometry = geometry, Traffic = new HashSet <long>(), Id = id, AvgSpeed = avgSpeed }; } geometry.Connections.Add(sc); _connections.Add(sc); } if (segment.Tags["accessible-reverse"].Value == "yes") { Connection sc; if (segment.Tags.ContainsTag("traffic")) { var traffic = new HashSet <long>(segment.Tags["traffic"].Value.Split(',').Select(x => long.Parse(x))); sc = new Connection(end, start) { Speed = speed, Geometry = geometry, Traffic = traffic, Id = id, AvgSpeed = avgSpeed }; } else { sc = new Connection(end, start) { Speed = speed, Geometry = geometry, Traffic = new HashSet <long>(), Id = id, AvgSpeed = avgSpeed }; } geometry.Connections.Add(sc); _connections.Add(sc); } } }