using System.Collections.Generic; using HeuristicLab.Problems.RoutePlanning.Osm; namespace HeuristicLab.Problems.RoutePlanning.Graph { public class Graph { private IDataSource dataSource; private Dictionary> vertexEdges; private Dictionary> vertices; private Dictionary>>> resolvedList; public Graph(IDataSource ds) { dataSource = ds; vertexEdges = new Dictionary>(); vertices = new Dictionary>(); resolvedList = new Dictionary>>>(); } public Vertex GetVertex(long id) { return new Vertex(dataSource.GetNode(id)); } public List GetEdges(Vertex vertex) { return dataSource.GetWays(vertex.Node); } public Dictionary GetNeighbors(long id) { Vertex vertex = GetVertex(id); Dictionary neighbors = new Dictionary(); List edges = GetEdges(vertex); foreach (Way edge in edges) { //TODO: check if edge can be traversed (eg. highway tag for car roads, ...) // get all naighbours of current vertex on this edge List> vertices = GetNeighborVerticesOnEdge(edge, vertex); foreach (Vertex neighbor in vertices) { if (edge.CanBeTraversed(vertex.Node, neighbor.Node)) { float weight = GetWeight(edge, vertex, neighbor); neighbors[neighbor.Node.Id] = weight; } } } return neighbors; } public List> GetNeighborVerticesOnEdge(Way edge, Vertex vertex) { List> neighbors = new List>(); for (int i = 0; i < edge.Nodes.Count; i++) { Node node = edge.Nodes[i]; if (node.Id == vertex.Node.Id) { if (i > 0) { neighbors.Add(GetVertex(edge.Nodes[i - 1].Id)); } if (i < edge.Nodes.Count - 1) { neighbors.Add(GetVertex(edge.Nodes[i + 1].Id)); } } } return neighbors; } public float GetWeight(Way edge, Vertex source, Vertex target) { double distance = Utils.Distance(source.Node.Point, target.Node.Point); int speed = edge.GetMaxSpeed(); double weight = (distance / speed) * 3.6; return (float)weight; } public float EstimatedCosts(long sourceId, long targetId) { Vertex source = GetVertex(sourceId); Vertex target = GetVertex(targetId); return EstimatedCosts(source, target); } public float EstimatedCosts(Vertex source, Vertex target) { double distance = Utils.Distance(source.Node.Point, target.Node.Point); int speed = 130; double costs = (distance / speed) * 3.6; return (float)costs; } } }